diff --git a/server/lib/api-tests/src/Test/Databases/Postgres/ArraySpec.hs b/server/lib/api-tests/src/Test/Databases/Postgres/ArraySpec.hs index 4af19d011d1..1e7c685ae04 100644 --- a/server/lib/api-tests/src/Test/Databases/Postgres/ArraySpec.hs +++ b/server/lib/api-tests/src/Test/Databases/Postgres/ArraySpec.hs @@ -105,7 +105,9 @@ cockroachFixture = } setup :: Text -setup = "create type \"_made_up_type\" as enum ('a', 'b', 'c');" +setup = + "create type \"_made_up_type\" as enum ('a', 'b', 'c');\n" + <> "create type \"TypeWithInterestingCapitalization\" as enum ('a', 'b', 'c');" -------------------------------------------------------------------------------- -- Schema @@ -146,6 +148,15 @@ enumArrayType = Schema.bstCockroach = Just "_made_up_type[]" } +interestingArrayType :: Schema.ScalarType +interestingArrayType = + Schema.TCustomType + $ Schema.defaultBackendScalarType + { Schema.bstPostgres = Just "\"TypeWithInterestingCapitalization\"[]", + Schema.bstCitus = Just "\"TypeWithInterestingCapitalization\"[]", + Schema.bstCockroach = Just "\"TypeWithInterestingCapitalization\"[]" + } + schema :: [Schema.Table] schema = [ (Schema.table "author") @@ -155,7 +166,10 @@ schema = Schema.column "emails" textArrayType, Schema.column "grid" nestedIntArrayType, Schema.column "jsons" jsonArrayType, - Schema.column "made_up" enumArrayType + Schema.column "made_up" enumArrayType, + (Schema.column "interesting" interestingArrayType) + { Schema.columnNullable = True + } ], Schema.tablePrimaryKey = ["id"] } @@ -192,7 +206,8 @@ singleArrayTests = do emails: "{ash@ash.com, ash123@ash.com}", grid: "{}", jsons: "{}", - made_up: "{}" + made_up: "{}", + interesting: "{}" } ] ) { @@ -610,6 +625,22 @@ introspectionTests = do } } }, + { + "name": "interesting", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "TypeWithInterestingCapitalization", + "ofType": null + } + } + } + }, { "name": "jsons", "type": { @@ -736,9 +767,8 @@ introspectionWithDisabledFeatureTests = do } } }, - { - "name": "id", - "type": { + {"name": "id", + "type": { "kind": "NON_NULL", "name": null, "ofType": { @@ -748,6 +778,13 @@ introspectionWithDisabledFeatureTests = do } } }, + {"name": "interesting", + "type" : { + "kind": "SCALAR", + "name": "_TypeWithInterestingCapitalization", + "ofType": null + } + }, { "name": "jsons", "type": { diff --git a/server/src-lib/Hasura/Backends/Postgres/SQL/Types.hs b/server/src-lib/Hasura/Backends/Postgres/SQL/Types.hs index 5c8abf3064c..7a68bda0916 100644 --- a/server/src-lib/Hasura/Backends/Postgres/SQL/Types.hs +++ b/server/src-lib/Hasura/Backends/Postgres/SQL/Types.hs @@ -468,6 +468,8 @@ pgScalarTypeToText = \case PGLtree -> "ltree" PGLquery -> "lquery" PGLtxtquery -> "ltxtquery" + -- It's not really clear that this case is actually used for anything, since + -- arrays seem to always require special handling for callers of this function. PGArray t -> pgScalarTypeToText t <> "[]" PGUnknown t -> t PGCompositeScalar t -> t @@ -554,11 +556,19 @@ instance HasCodec PGScalarType where instance ToSQL PGScalarType where toSQL = - TB.text . \case - -- Format enum type names as identifiers to preserve case sensitivity - -- https://github.com/hasura/graphql-engine/issues/4014 - PGEnumScalar t -> pgFmtIdentifier t - scalarType -> pgScalarTypeToText scalarType + TB.text . quoteType + where + -- Custom types may use non-lower casing and characters that do not belong to + -- identifiers lexicographically and thus need to be quoted. + quoteType :: PGScalarType -> Text + quoteType = + \case + -- Quoting an array type is e.g. '"MyType"[]', not '"MyType[]"', which necessitates this somewhat awkward recursion. + PGArray t -> quoteType t <> "[]" + PGUnknown t -> dquote t + PGCompositeScalar t -> dquote t + PGEnumScalar t -> dquote t + t -> pgScalarTypeToText t instance ToJSON PGScalarType where toJSON = String . pgScalarTypeToText