mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-11-10 10:29:12 +03:00
server: fix bug when executing a custom function with a row type argument
GitOrigin-RevId: d3a1fa8c9f6b420f4c88eb60c92019c8d0fdc58d
This commit is contained in:
parent
3fad5f6678
commit
d7ccf81526
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
(Add entries below in the order of: server, console, cli, docs, others)
|
(Add entries below in the order of: server, console, cli, docs, others)
|
||||||
|
|
||||||
|
- server: fix query execution of custom function containing a composite argument type
|
||||||
- server: fix a bug in query validation that would cause some queries using default variable values to be rejected (fix #6867)
|
- server: fix a bug in query validation that would cause some queries using default variable values to be rejected (fix #6867)
|
||||||
- server: custom URI schemes are now supported in CORS config (fix #5818) (#5940)
|
- server: custom URI schemes are now supported in CORS config (fix #5818) (#5940)
|
||||||
- console: read-only modify page for mssql
|
- console: read-only modify page for mssql
|
||||||
|
@ -285,6 +285,7 @@ data PGScalarType
|
|||||||
| PGLquery
|
| PGLquery
|
||||||
| PGLtxtquery
|
| PGLtxtquery
|
||||||
| PGUnknown !Text
|
| PGUnknown !Text
|
||||||
|
| PGCompositeScalar !Text
|
||||||
deriving (Show, Eq, Ord, Generic, Data)
|
deriving (Show, Eq, Ord, Generic, Data)
|
||||||
instance NFData PGScalarType
|
instance NFData PGScalarType
|
||||||
instance Hashable PGScalarType
|
instance Hashable PGScalarType
|
||||||
@ -292,34 +293,35 @@ instance Cacheable PGScalarType
|
|||||||
|
|
||||||
instance ToSQL PGScalarType where
|
instance ToSQL PGScalarType where
|
||||||
toSQL = \case
|
toSQL = \case
|
||||||
PGSmallInt -> "smallint"
|
PGSmallInt -> "smallint"
|
||||||
PGInteger -> "integer"
|
PGInteger -> "integer"
|
||||||
PGBigInt -> "bigint"
|
PGBigInt -> "bigint"
|
||||||
PGSerial -> "serial"
|
PGSerial -> "serial"
|
||||||
PGBigSerial -> "bigserial"
|
PGBigSerial -> "bigserial"
|
||||||
PGFloat -> "real"
|
PGFloat -> "real"
|
||||||
PGDouble -> "float8"
|
PGDouble -> "float8"
|
||||||
PGNumeric -> "numeric"
|
PGNumeric -> "numeric"
|
||||||
PGMoney -> "money"
|
PGMoney -> "money"
|
||||||
PGBoolean -> "boolean"
|
PGBoolean -> "boolean"
|
||||||
PGChar -> "bpchar"
|
PGChar -> "bpchar"
|
||||||
PGVarchar -> "varchar"
|
PGVarchar -> "varchar"
|
||||||
PGText -> "text"
|
PGText -> "text"
|
||||||
PGCitext -> "citext"
|
PGCitext -> "citext"
|
||||||
PGDate -> "date"
|
PGDate -> "date"
|
||||||
PGTimeStamp -> "timestamp"
|
PGTimeStamp -> "timestamp"
|
||||||
PGTimeStampTZ -> "timestamptz"
|
PGTimeStampTZ -> "timestamptz"
|
||||||
PGTimeTZ -> "timetz"
|
PGTimeTZ -> "timetz"
|
||||||
PGJSON -> "json"
|
PGJSON -> "json"
|
||||||
PGJSONB -> "jsonb"
|
PGJSONB -> "jsonb"
|
||||||
PGGeometry -> "geometry"
|
PGGeometry -> "geometry"
|
||||||
PGGeography -> "geography"
|
PGGeography -> "geography"
|
||||||
PGRaster -> "raster"
|
PGRaster -> "raster"
|
||||||
PGUUID -> "uuid"
|
PGUUID -> "uuid"
|
||||||
PGLtree -> "ltree"
|
PGLtree -> "ltree"
|
||||||
PGLquery -> "lquery"
|
PGLquery -> "lquery"
|
||||||
PGLtxtquery -> "ltxtquery"
|
PGLtxtquery -> "ltxtquery"
|
||||||
PGUnknown t -> TB.text t
|
PGUnknown t -> TB.text t
|
||||||
|
PGCompositeScalar t -> TB.text t
|
||||||
|
|
||||||
instance ToJSON PGScalarType where
|
instance ToJSON PGScalarType where
|
||||||
toJSON = String . toSQLTxt
|
toJSON = String . toSQLTxt
|
||||||
@ -509,12 +511,7 @@ typeToTable (QualifiedPGType sch n _) =
|
|||||||
mkFunctionArgScalarType :: QualifiedPGType -> PGScalarType
|
mkFunctionArgScalarType :: QualifiedPGType -> PGScalarType
|
||||||
mkFunctionArgScalarType (QualifiedPGType _schema name type') =
|
mkFunctionArgScalarType (QualifiedPGType _schema name type') =
|
||||||
case type' of
|
case type' of
|
||||||
-- When the function argument is a row type argument
|
-- The suffix `_scalar` is added in
|
||||||
-- then it's possible that there can be an object type
|
-- the @mkScalarTypeName@ function.
|
||||||
-- with the table name depending upon whether the table
|
PGKindComposite -> PGCompositeScalar $ toTxt name
|
||||||
-- is tracked or not. As a result, we get a conflict between
|
|
||||||
-- both these types (scalar and object type with same name).
|
|
||||||
-- To avoid this, we suffix the table name with `_scalar`
|
|
||||||
-- and create a new scalar type
|
|
||||||
PGKindComposite -> PGUnknown $ toTxt name <> "_scalar"
|
|
||||||
_ -> name
|
_ -> name
|
||||||
|
@ -202,6 +202,8 @@ parsePGValue ty val = case (ty, val) of
|
|||||||
PGLtxtquery -> PGValLtxtquery <$> parseJSON val
|
PGLtxtquery -> PGValLtxtquery <$> parseJSON val
|
||||||
PGUnknown tyName ->
|
PGUnknown tyName ->
|
||||||
fail $ "A string is expected for type: " ++ T.unpack tyName
|
fail $ "A string is expected for type: " ++ T.unpack tyName
|
||||||
|
PGCompositeScalar tyName ->
|
||||||
|
fail $ "A string is expected for type: " ++ T.unpack tyName
|
||||||
|
|
||||||
txtEncodedVal :: PGScalarValue -> TxtEncodedVal
|
txtEncodedVal :: PGScalarValue -> TxtEncodedVal
|
||||||
txtEncodedVal = \case
|
txtEncodedVal = \case
|
||||||
@ -243,34 +245,35 @@ txtEncodedVal = \case
|
|||||||
|
|
||||||
pgTypeOid :: PGScalarType -> PQ.Oid
|
pgTypeOid :: PGScalarType -> PQ.Oid
|
||||||
pgTypeOid = \case
|
pgTypeOid = \case
|
||||||
PGSmallInt -> PTI.int2
|
PGSmallInt -> PTI.int2
|
||||||
PGInteger -> PTI.int4
|
PGInteger -> PTI.int4
|
||||||
PGBigInt -> PTI.int8
|
PGBigInt -> PTI.int8
|
||||||
PGSerial -> PTI.int4
|
PGSerial -> PTI.int4
|
||||||
PGBigSerial -> PTI.int8
|
PGBigSerial -> PTI.int8
|
||||||
PGFloat -> PTI.float4
|
PGFloat -> PTI.float4
|
||||||
PGDouble -> PTI.float8
|
PGDouble -> PTI.float8
|
||||||
PGNumeric -> PTI.numeric
|
PGNumeric -> PTI.numeric
|
||||||
PGMoney -> PTI.numeric
|
PGMoney -> PTI.numeric
|
||||||
PGBoolean -> PTI.bool
|
PGBoolean -> PTI.bool
|
||||||
PGChar -> PTI.char
|
PGChar -> PTI.char
|
||||||
PGVarchar -> PTI.varchar
|
PGVarchar -> PTI.varchar
|
||||||
PGText -> PTI.text
|
PGText -> PTI.text
|
||||||
PGCitext -> PTI.text -- Explict type cast to citext needed, See also Note [Type casting prepared params]
|
PGCitext -> PTI.text -- Explict type cast to citext needed, See also Note [Type casting prepared params]
|
||||||
PGDate -> PTI.date
|
PGDate -> PTI.date
|
||||||
PGTimeStamp -> PTI.timestamp
|
PGTimeStamp -> PTI.timestamp
|
||||||
PGTimeStampTZ -> PTI.timestamptz
|
PGTimeStampTZ -> PTI.timestamptz
|
||||||
PGTimeTZ -> PTI.timetz
|
PGTimeTZ -> PTI.timetz
|
||||||
PGJSON -> PTI.json
|
PGJSON -> PTI.json
|
||||||
PGJSONB -> PTI.jsonb
|
PGJSONB -> PTI.jsonb
|
||||||
PGGeometry -> PTI.text -- we are using the ST_GeomFromGeoJSON($i) instead of $i
|
PGGeometry -> PTI.text -- we are using the ST_GeomFromGeoJSON($i) instead of $i
|
||||||
PGGeography -> PTI.text
|
PGGeography -> PTI.text
|
||||||
PGRaster -> PTI.text -- we are using the ST_RastFromHexWKB($i) instead of $i
|
PGRaster -> PTI.text -- we are using the ST_RastFromHexWKB($i) instead of $i
|
||||||
PGUUID -> PTI.uuid
|
PGUUID -> PTI.uuid
|
||||||
PGLtree -> PTI.text
|
PGLtree -> PTI.text
|
||||||
PGLquery -> PTI.text
|
PGLquery -> PTI.text
|
||||||
PGLtxtquery -> PTI.text
|
PGLtxtquery -> PTI.text
|
||||||
(PGUnknown _) -> PTI.auto
|
(PGUnknown _) -> PTI.auto
|
||||||
|
PGCompositeScalar _ -> PTI.auto
|
||||||
|
|
||||||
binEncoder :: PGScalarValue -> Q.PrepArg
|
binEncoder :: PGScalarValue -> Q.PrepArg
|
||||||
binEncoder = \case
|
binEncoder = \case
|
||||||
|
@ -392,6 +392,17 @@ mkScalarTypeName PG.PGBoolean = pure boolScalar
|
|||||||
mkScalarTypeName PG.PGFloat = pure floatScalar
|
mkScalarTypeName PG.PGFloat = pure floatScalar
|
||||||
mkScalarTypeName PG.PGText = pure stringScalar
|
mkScalarTypeName PG.PGText = pure stringScalar
|
||||||
mkScalarTypeName PG.PGVarchar = pure stringScalar
|
mkScalarTypeName PG.PGVarchar = pure stringScalar
|
||||||
|
mkScalarTypeName (PG.PGCompositeScalar compositeScalarType) =
|
||||||
|
-- When the function argument is a row type argument
|
||||||
|
-- then it's possible that there can be an object type
|
||||||
|
-- with the table name depending upon whether the table
|
||||||
|
-- is tracked or not. As a result, we get a conflict between
|
||||||
|
-- both these types (scalar and object type with same name).
|
||||||
|
-- To avoid this, we suffix the table name with `_scalar`
|
||||||
|
-- and create a new scalar type
|
||||||
|
(<> $$(G.litName "_scalar")) <$> G.mkName compositeScalarType `onNothing` throw400 ValidationFailed
|
||||||
|
("cannot use SQL type " <> compositeScalarType <<> " in the GraphQL schema because its name is not a "
|
||||||
|
<> "valid GraphQL identifier")
|
||||||
mkScalarTypeName scalarType = G.mkName (toSQLTxt scalarType) `onNothing` throw400 ValidationFailed
|
mkScalarTypeName scalarType = G.mkName (toSQLTxt scalarType) `onNothing` throw400 ValidationFailed
|
||||||
("cannot use SQL type " <> scalarType <<> " in the GraphQL schema because its name is not a "
|
("cannot use SQL type " <> scalarType <<> " in the GraphQL schema because its name is not a "
|
||||||
<> "valid GraphQL identifier")
|
<> "valid GraphQL identifier")
|
||||||
|
@ -38,3 +38,20 @@
|
|||||||
kind
|
kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- description: Execute the tracked function with a composite row type argument
|
||||||
|
url: /v1/graphql
|
||||||
|
status: 200
|
||||||
|
query:
|
||||||
|
query: |
|
||||||
|
query {
|
||||||
|
search_post_by_test (args: {t: "(1, hasura,311cf381-71e7-449b-bac5-86cd6deafd5b)"}) {
|
||||||
|
title
|
||||||
|
content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response:
|
||||||
|
data:
|
||||||
|
search_post_by_test:
|
||||||
|
- title: post by hasura
|
||||||
|
content: content for post
|
||||||
|
Loading…
Reference in New Issue
Block a user