-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix json/jsonb columns as String values in nested returning of a mutation (fix #3365) #3375
fix json/jsonb columns as String values in nested returning of a mutation (fix #3365) #3375
Conversation
Deploy preview for hasura-docs ready! Built with commit cab14f0 |
Review app for commit e8fa447 deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
e8fa447
to
40315d2
Compare
Review app for commit 40315d2 deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
40315d2
to
ac1c5c9
Compare
Review app for commit ac1c5c9 deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
ac1c5c9
to
541da03
Compare
541da03
to
3117edd
Compare
Review app for commit 3117edd deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
Review app for commit 58b4a0a deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
mkSelCTEFromColVals qt allCols colVals = | ||
=> (PGColumnType -> Value -> m (WithScalarType PGScalarValue)) | ||
-> QualifiedTable -> [PGColumnInfo] -> [ColVals] -> m S.CTE | ||
mkSelCTEFromColVals parseFn qt allCols colVals = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for my own understanding: could you explain to me from a high-level what this function is doing? When I was first looking through this diff, I was slightly confused, because it seems like we’re parsing the values (using parseFn
) but then immediately re-encoding them (using toTxtValue
). It seems like mutateAndSel
is doing that as part of some kind of two-pass query strategy, but it’s not quite clicking for me what the reason for doing that is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, this diff is not so informative. I'll give you a bit of context.
toTxtValue
will encode any PGScalarValue
to literal values. I thought it is enough and went for #3198. In case of json/jsonb values, the json string we're getting, let's say some String t
where t
is json string, is parsed into PGScalarValue
as PGValJSON (String t)
. The toTxtValue
converts PGValJSON (String t)
to json encoding of a string value. The {"age": 23}
is converted to something like "{\"age\": 23}"
which is causing the bug. In mutateAndSel
function, I'm enforcing all String t
to PGValText t
irrespective of what type it is, hence toTxtValue
encodes correctly for json/jsonb values.
I hope you understand the above explanation. I'm happy to know any improvements to the current fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That definitely is helpful, so thank you for that explanation, but it actually doesn’t answer my original question (which is only semi-related to this pull request). Specifically, I’m trying to understand what mkSelCTEFromColVals
is doing in the first place, from a high level. 🙂 Sorry if I didn’t make that very clear!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay 🙂 . The mkSelCTEFromColVals
will generate a SELECT
query, that is used inside a WITH ....
statement. The SELECT
statement look like
SELECT * FROM VALUES ((col1-val, col2-val, col3-val), .....) AS "table_name" (col1, col2, col3)
The parseFn
converts JSON value
to col-val
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I probably should have been more clear: I can mostly make out what it does, but what I’m less sure about is why. If mutateAndFetchCols
does the actual mutation query, and it returns a bunch of values, why don’t we parse them directly from that result? Why do we send them back through Postgres another time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The (1) is possible only if we have the context of array types which #2243 is meant to solve. I think this PR is solving (2). We're fetching column values as Strings (except for geometry/geography types) and storing them as PGValText
. The parseJSONStringAsLiteral
is doing the job.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this PR is solving (2). We're fetching column values as Strings (except for geometry/geography types) and storing them as
PGValText
. TheparseJSONStringAsLiteral
is doing the job.
Okay, I think that helps me to understand better what’s going on. A followup question: why are we treating the geometry/geography types differently? They have a textual representation as well, right? So it seems as though we ought to be able to treat everything uniformly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can use the textual representation for geometry/geography columns. Ideally, the returned columns are HashMap PGCol Text
. I'll make the necessary change in next commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now geometry/geography values are stored as Strings via 0f484df. Please approve if everything is OK. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lexi-lambda Updated the PR with the latest master. Please review. 🙂
Review app for commit fdb6852 deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
Review app for commit 281e5df deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
Review app for commit 340b63f deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
Review app for commit 980ddac deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
Review app for commit 60da288 deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the long delay on getting this merged!
Review app for commit cab14f0 deployed to Heroku: https://hge-ci-pull-3375.herokuapp.com |
Review app https://hge-ci-pull-3375.herokuapp.com is deleted |
Description
PR #3198 caused the JSON/JSONB values returning as Strings when a mutation is performed with returning nested fields.
query:-
Response:-
This PR fixes the same.
Affected components
Related Issues
Fix #3365
Solution and Design
The
parsePGScalarValue
is used to parse the Postgres column values correctly. The change in #3198 is made to select the mutated columns as Text values except for geometry/geography types. JSON/JSONB column values are parsed as JSON Strings and not as Postgres literals, which gives those values as Strings. A specialparseJSONStringAsLiteral
function is introduced, which forces all String values as Postgres literals.Server checklist
Catalog upgrade
Does this PR change Hasura Catalog version?
Metadata
Does this PR add a new Metadata feature?
run_sql
auto manages the new metadata through schema diffing?run_sql
auto manages the definitions of metadata on renaming?export_metadata
/replace_metadata
supports the new metadata added?GraphQL
Breaking changes
No Breaking changes
There are breaking changes:
Metadata API
Existing
query
types:args
payload which is not backward compatibleJSON
schemaGraphQL API
Schema Generation:
NamedType
Schema Resolve:-
null
value for any input fieldsLogging
JSON
schema has changedtype
names have changedSteps to test and verify
Reproduce #3365, the json/jsonb columns shouldn't be returned as strings.
Limitations, known bugs & workarounds