Open Majed6 opened 1 year ago
As a summary of the conversation we had in gitter:
allViewsKeyDependencies
queryYou mentioned that DB logging wasn't possible from your end and that you can modify and build the source code, so an alternative would be to debug each step of the Schema Cache creation using Debug.Trace
. You'll have to modify the steps in this file:
You should have something like:
-- Immediately after all the imports
import Debug.Trace as BUG
-- ...
querySchemaCache :: [Schema] -> [Schema] -> Bool -> SQL.Transaction SchemaCache
querySchemaCache schemas extraSearchPath prepared = do
SQL.sql "set local schema ''" -- This voids the search path. The following queries need this for getting the fully qualified name(schema.name) of every db object
pgVer <- BUG.trace "Querying pgVer:" $ SQL.statement mempty pgVersionStatement
tabs <- BUG.trace "Querying tabs:" $ SQL.statement schemas $ allTables pgVer prepared
-- complete for the rest...
That should show you where it's failing, then you can verify which SQL query is the culprit after running PostgREST against your database.
15/Oct/2022:05:19:14 +0000: Listening on port 3000
15/Oct/2022:05:19:14 +0000: Attempting to connect to the database...
15/Oct/2022:05:19:14 +0000: Connection successful
Querying pgVer
Querying tabs
15/Oct/2022:05:19:15 +0000: An error ocurred when loading the schema cache
15/Oct/2022:05:19:15 +0000: {"code":"PGRSTX00","details":null,"hint":null,"message":"RowError 0 8 (ValueError \"End of input\")"}
15/Oct/2022:05:19:15 +0000: Attempting to connect to the database...
15/Oct/2022:05:19:15 +0000: Connection successful
15/Oct/2022:05:19:16 +0000: An error ocurred when loading the schema cache
15/Oct/2022:05:19:16 +0000: {"code":"PGRSTX00","details":null,"hint":null,"message":"RowError 0 8 (ValueError \"End of input\")"}
15/Oct/2022:05:19:16 +0000: Attempting to connect to the database..
As for allViewsKeyDependencies query I have removed the conditions and n.nspname = ANY($1 || $2)
and where view_schema = ANY ($1)
to get a result since ['public','public']
has no result.
PS: I'm not sure If I did this right but I created
tracer :: a -> [Text]
tracer obj = do
s <- unsafePerformIO (Gs.whoCreated obj)
return (show s::Text)
and
toJSON (SQL.ResultError resultError) = JSON.object [
"code" .= InternalErrorCode00,
"messages" .= tracer resultError,
"message" .= (show resultError :: Text),
"details" .= JSON.Null,
"hint" .= JSON.Null]
and that resulted in
{"code":"PGRSTX00","details":"[]","hint":null,"message":"RowError 0 8 (ValueError \"End of input\")","messages":["\"Main.main (main/Main.hs:(18,1)-(21,52))\"","\"PostgREST.CLI.main (src/PostgREST/CLI.hs:(36,1)-(51,72))\"","\"PostgREST.CLI.main.\\\\ (src/PostgREST/CLI.hs:(46,19)-(51,71))\"","\"PostgREST.App.run (src/PostgREST/App.hs:(67,1)-(90,50))\"","\"PostgREST.Workers.connectionWorker (src/PostgREST/Workers.hs:(72,1)-(111,60))\"","\"PostgREST.Workers.connectionWorker.runExclusively (src/PostgREST/Workers.hs:(77,5)-(80,54))\"","\"PostgREST.Workers.connectionWorker.work (src/PostgREST/Workers.hs:(81,5)-(111,60))\"","\"PostgREST.Workers.loadSchemaCache (src/PostgREST/Workers.hs:(166,1)-(195,21))\"","\"PostgREST.AppState.usePool (src/PostgREST/AppState.hs:109:1-40)\"","\"Hasql.Pool.use (library/Hasql/Pool.hs:(95,1)-(149,48))\"","\"Hasql.Pool.use.onConn (library/Hasql/Pool.hs:(128,5)-(149,48))\"","\"Hasql.Private.Session.run (library/Hasql/Private/Session.hs:(24,1)-(26,30))\"","\"PostgREST.Workers.loadSchemaCache.transaction (src/PostgREST/Workers.hs:169:9-103)\"","\"PostgREST.SchemaCache.querySchemaCache (src/PostgREST/SchemaCache.hs:(89,1)-(105,5))\"","\"PostgREST.SchemaCache.allTables (src/PostgREST/SchemaCache.hs:(438,1)-(441,35))\"","\"PostgREST.SchemaCache.decodeTables (src/PostgREST/SchemaCache.hs:(143,1)-(163,40))\"","\"Hasql.Private.Decoders.rowList (library/Hasql/Private/Decoders.hs:91:1-33)\"","\"Hasql.Private.Decoders.foldrRows (library/Hasql/Private/Decoders.hs:66:1-84)\"","\"Hasql.Private.Decoders.Result.foldr (library/Hasql/Private/Decoders/Result.hs:(202,3)-(219,33))\""]}
OK, both the Debug.Trace
and your tracer
confirm that the error is in the decodeTables
function, which parses the tablesSqlQuery
query. RowError 0 8
means the conflict is in the first row (0+1) and ninth column (8+1), so, maybe there's a problem with cols_agg.columns
?
Try querying the tablesSqlQuery
function and check if that returns the 9 columns (the last one should be called columns
). As a reference, in my case, the generated SQL for that function is the following (you may need to change ANY('{api}')
to ANY('{public}')
):
Here is the result using Datagrip:
I fail to see the problem in your results... perhaps it's another query or maybe Hasql has a problem with the size of the column's result (a wild guess). Just to confirm, older PostgREST versions do not work either, right? Could you try doing a backup of your database and restoring it in another machine (e. g. your local system) to see if it also fails there?
Just noting: The error is actually thrown somewhere in here: https://hackage.haskell.org/package/binary-parser-0.5.7.2/docs/src/BinaryParser.html - we can tell from the "End of Input" string.
Here is the result using Datagrip:
The result looks like the pk_cols
column has some NULL
values. Is that correct? According to our sourcecode, I would expect empty arrays {}
in those empty cells. Can you confirm in your SQL query, that those values are indeed NULL
?
That could certainly break the arrayColumn
decoder, because that expects non-nullable columns:
It would be helpful indeed, if you could try to reproduce this on a dump of the database - and then start removing pieces of your schema until the error disappears. Maybe it's related to some special object you have in your schema, that we're not parsing correctly from the catalogs. I would start removing arrival_duration_rating
and conformity_rating
and then see whether that changes the error message?
perhaps it's another query
The tracer showed that the decodeTables
is the reason.
or maybe Hasql has a problem with the size of the column's result (a wild guess).
That's not the case because slicing columns https://github.com/PostgREST/postgrest/blob/0fbb116dd27af860a3095a6a2499c76fbae3ab6b/src/PostgREST/SchemaCache.hs#L500-L507 to one by
(array_agg(
row (info.column_name, info.description, info.is_nullable::boolean, info.data_type, info.character_maximum_length, info.column_default, coalesce(enum_info.vals, '{}'))
order by info.position))[1:1] as columns
still produces the same exception.
Just to confirm, older PostgREST versions do not work either, right?
I just tried docker versions:
and none of them work. Older versions don't support postgres 14.5 so I didn't try them.
Could you try doing a backup of your database and restoring it in another machine (e. g. your local system) to see if it also fails there?
With a pg_dump
version it doesn't fail sadly. A pg_dumpall
will take quite a while to acquire since it's a multi tenet cluster and exporting everything needs to be approved.
Just noting: The error is actually thrown somewhere in here: https://hackage.haskell.org/package/binary-parser-0.5.7.2/docs/src/BinaryParser.html - we can tell from the "End of Input" string.
I can confirm this from my testing too.
Here is the result using Datagrip:
The result looks like the
pk_cols
column has someNULL
values. Is that correct? According to our sourcecode, I would expect empty arrays{}
in those empty cells. Can you confirm in your SQL query, that those values are indeedNULL
?
I'm so sorry they must've been removed during my markdown conversion. They are indeed {}
and NOT NULL
.
That could certainly break the
arrayColumn
decoder, because that expects non-nullable columns:
They are {}
. Sorry :p .
It would be helpful indeed, if you could try to reproduce this on a dump of the database - and then start removing pieces of your schema until the error disappears. Maybe it's related to some special object you have in your schema, that we're not parsing correctly from the catalogs. I would start removing
arrival_duration_rating
andconformity_rating
and then see whether that changes the error message?
I have been doing the pieces removal with the script below (apologies for the mess in advance :p) :
Notice the slicing of columns and the limiting to one record at the end. It only works when , tableColumns :: [Column]
is made into a , tableColumns :: Text
along with the mapping.
With a pg_dump version it doesn't fail sadly.
Ok, that's very valuable information. In that case it's not a problem with any of the database objects specifically.
It's more likely to be a problem with some server, database or user settings.
Please check the following:
\l
SELECT name, setting, source FROM pg_settings WHERE source !='default';`
Maybe any settings stand out - and changing them in your restored backup produces the same failure?
It only works when
, tableColumns :: [Column]
is made into a, tableColumns :: Text
along with the mapping.
Ah, interesting, too. That suggests the problem is inside the column decoding. Can you try to remove fields of Column
1-by-1 and see which one is causing the error? Of course, you'll need to remove it from the decoder and from the columns_agg
CTE, too.
Thank you all for your support and prompt responses. I'm putting this side issue on pause until I get back from my leave in a month. I wrote a reply to your questions but I feared a bit of inaccuracy in the results, so I decided not to submit the reply not to waste anyone's time.
I greatly appreciate you @laurenceisla and @wolfgangwalther for your interest in the side issue. I also appreciate all of PostgREST community for this amazing product that has served us for years.
Looking forward to getting back to this side issue with more details and replies to your requests and questions. (Fingers crossed, it fixes itself somehow xD ) .
I'm back. DB admins deleted the DB on my leave because it was "consuming connections". I'll get things back on track and restore the staging DB. Thanks again for your interest.
During my talk with the db admins heimdall, sprung up as a culprit for the data corruption during transit. In order to save your time I'll work with heimdall team to make sure it is not the culprit. If it is, I'll post what I gather in a separate reply.
Environment
Description of issue
Expected: {"code":"PGRSTX00","details":"select * from something;","hint":null,"message":"RowError 0 8 (ValueError \"End of input\")"}
Actual: {"code":"PGRSTX00","details":null,"hint":null,"message":"RowError 0 8 (ValueError \"End of input\")"}
Steps to reproduce: 1- start postgrest with config:
2- Observer :
Note
It would make my life easier to know which query is causing hasql to fail so that I could write a proper report to the community here about the edge case.
I'm here to ask for the query inclusion enhancement . As for the case I don't mind sharing a pcap with a maintainer directly.