From a9f77acb325e94f4eafe0903523d7436e80eed9b Mon Sep 17 00:00:00 2001 From: David Overton Date: Wed, 11 Jan 2023 13:36:03 +1100 Subject: [PATCH] Remove builtin scalar types from Data Connector backend PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7167 Co-authored-by: Daniel Chambers <1214352+daniel-chambers@users.noreply.github.com> GitOrigin-RevId: 926e7282b908e3a9669ac39d625aa54971e11c37 --- dc-agents/README.md | 22 +-- dc-agents/dc-api-types/package.json | 2 +- dc-agents/dc-api-types/src/agent.openapi.json | 15 +- .../dc-api-types/src/models/ScalarType.ts | 3 +- dc-agents/package-lock.json | 10 +- dc-agents/reference/package-lock.json | 4 +- dc-agents/reference/package.json | 2 +- dc-agents/reference/src/capabilities.ts | 22 ++- dc-agents/sqlite/package-lock.json | 4 +- dc-agents/sqlite/package.json | 2 +- dc-agents/sqlite/src/capabilities.ts | 18 +- .../MockAgent/AggregateQuerySpec.hs | 6 +- .../DataConnector/MockAgent/BasicQuerySpec.hs | 14 +- .../MockAgent/CustomScalarsSpec.hs | 48 +++--- .../Test/DataConnector/MockAgent/ErrorSpec.hs | 4 +- .../MockAgent/QueryRelationshipsSpec.hs | 20 +-- .../MockAgent/TransformedConfigurationSpec.hs | 4 +- .../Backends/DataConnector/API/V0/Scalar.hs | 36 +--- server/lib/dc-api/test/Main.hs | 5 +- server/lib/dc-api/test/Test/AgentClient.hs | 1 + server/lib/dc-api/test/Test/Data.hs | 53 +++--- server/lib/dc-api/test/Test/DataExport.hs | 2 +- .../lib/dc-api/test/Test/Specs/ErrorSpec.hs | 9 +- .../lib/dc-api/test/Test/Specs/ExplainSpec.hs | 2 +- .../Test/Specs/QuerySpec/AggregatesSpec.hs | 45 +++-- .../test/Test/Specs/QuerySpec/BasicSpec.hs | 8 +- .../Specs/QuerySpec/CustomOperatorsSpec.hs | 4 +- .../Test/Specs/QuerySpec/FilteringSpec.hs | 58 ++++--- .../test/Test/Specs/QuerySpec/OrderBySpec.hs | 15 +- .../Test/Specs/QuerySpec/RelationshipsSpec.hs | 61 ++++--- .../DataConnector/Chinook/Reference.hs | 14 ++ .../Backend/DataConnector/Chinook/Sqlite.hs | 25 ++- .../Backend/DataConnector/Mock/Server.hs | 163 ++++++++++-------- server/lib/test-harness/test-harness.cabal | 1 + .../Backends/DataConnector/Adapter/Backend.hs | 19 +- .../DataConnector/Adapter/Metadata.hs | 4 + .../Backends/DataConnector/Adapter/Schema.hs | 36 ++-- .../Backends/DataConnector/Adapter/Types.hs | 34 +--- .../Hasura/Backends/DataConnector/Plan.hs | 23 +-- .../DataConnector/API/V0/CapabilitiesSpec.hs | 6 +- .../DataConnector/API/V0/ColumnSpec.hs | 4 +- .../DataConnector/API/V0/ExpressionSpec.hs | 12 +- .../DataConnector/API/V0/MutationsSpec.hs | 10 +- .../DataConnector/API/V0/QuerySpec.hs | 4 +- .../DataConnector/API/V0/ScalarSpec.hs | 19 +- .../DataConnector/API/V0/TableSpec.hs | 4 +- 46 files changed, 448 insertions(+), 429 deletions(-) diff --git a/dc-agents/README.md b/dc-agents/README.md index bb71e412934..f4fb65407dd 100644 --- a/dc-agents/README.md +++ b/dc-agents/README.md @@ -165,7 +165,7 @@ The `GET /capabilities` endpoint is used by `graphql-engine` to discover the cap The `capabilities` section describes the _capabilities_ of the service. This includes - `data_schema`: What sorts of features the agent supports when describing its data schema - `relationships`: whether or not the agent supports relationships -- `scalar_types`: custom scalar types and the operations they support. See [Scalar types capabilities](#scalar-type-capabilities). +- `scalar_types`: scalar types and the operations they support. See [Scalar types capabilities](#scalar-type-capabilities). The `config_schema` property contains an [OpenAPI 3 Schema](https://swagger.io/specification/#schema-object) object that represents the schema of the configuration object. It can use references (`$ref`) to refer to other schemas defined in the `other_schemas` object by name. @@ -178,23 +178,23 @@ If the agent only supports table columns that are always nullable, then it shoul #### Scalar type capabilities -The agent is expected to support a default set of scalar types (`Number`, `String`, `Bool`) and a default set of [comparison operators](#filters) on these types. -Agents may optionally declare support for their own custom scalar types, along with custom comparison operators and aggregate functions on those types. -The agent may optionally specify how to parse values of custom scalar types by associating them with one of the built-in GraphQL types (`Int`, `Float`, `String`, `Boolean` or `ID`) +Agents should declare the scalar types they support, along with the comparison operators and aggregate functions on those types. +The agent may optionally specify how to parse values of scalar type by associating it with one of the built-in GraphQL types (`Int`, `Float`, `String`, `Boolean` or `ID`) -Custom scalar types are declared by adding a property to the `scalar_types` section of the [capabilities](#capabilities-and-configuration-schema). +Scalar types are declared by adding a property to the `scalar_types` section of the [capabilities](#capabilities-and-configuration-schema). -Custom comparison types can be defined by adding a `comparison_operators` property to the scalar type capabilities object. +Comparison operators can be defined by adding a `comparison_operators` property to the scalar type capabilities object. The `comparison_operators` property is an object where each key specifies a comparison operator name. The operator name must be a valid GraphQL name. The value associated with each key should be a string specifying the argument type, which must be a valid scalar type. +All scalar types must also support the built-in comparison operators `eq`, `gt`, `gte`, `lt` and `lte`. -Custom aggregate functions can be defined by adding an `aggregate_functions` property to the scalar type capabilities object. +Aggregate functions can be defined by adding an `aggregate_functions` property to the scalar type capabilities object. The `aggregate_functions` property must be an object mapping aggregate function names to their result types. Aggregate function names must be must be valid GraphQL names. Result types must be valid scalar types. -The `graphql_type` property can be used to tell Hasura GraphQL Engine to parse values of the custom scalar type as though they were one of the built-in GraphQL scalar types `Int`, `Float`, `String`, `Boolean`, or `ID`. +The `graphql_type` property can be used to tell Hasura GraphQL Engine to parse values of the scalar type as though they were one of the built-in GraphQL scalar types `Int`, `Float`, `String`, `Boolean`, or `ID`. Example: @@ -210,10 +210,10 @@ capabilities: graphql_type: String ``` -This example declares a custom scalar type `DateTime` which should be parsed as though it were a GraphQL `String`. +This example declares a scalar type `DateTime` which should be parsed as though it were a GraphQL `String`. The type supports a comparison operator `in_year`, which takes an argument of type `Number`. -An example GraphQL query using the custom comparison operator might look like below: +An example GraphQL query using the comparison operator might look like below: ```graphql query MyQuery { Employee(where: {BirthDate: {in_year: 1962}}) { @@ -223,7 +223,7 @@ query MyQuery { } ``` In this query we have an `Employee` field with a `BirthDate` property of type `DateTime`. -The `in_year` custom comparison operator is being used to request all employees with a birth date in the year 1962. +The `in_year` comparison operator is being used to request all employees with a birth date in the year 1962. The example also defines two aggregate functions `min` and `max`, both of which have a result type of `DateTime`. diff --git a/dc-agents/dc-api-types/package.json b/dc-agents/dc-api-types/package.json index ef252a50804..58420777ea1 100644 --- a/dc-agents/dc-api-types/package.json +++ b/dc-agents/dc-api-types/package.json @@ -1,6 +1,6 @@ { "name": "@hasura/dc-api-types", - "version": "0.19.0", + "version": "0.20.0", "description": "Hasura GraphQL Engine Data Connector Agent API types", "author": "Hasura (https://github.com/hasura/graphql-engine)", "license": "Apache-2.0", diff --git a/dc-agents/dc-api-types/src/agent.openapi.json b/dc-agents/dc-api-types/src/agent.openapi.json index 1daaa3db416..64405264a52 100644 --- a/dc-agents/dc-api-types/src/agent.openapi.json +++ b/dc-agents/dc-api-types/src/agent.openapi.json @@ -502,20 +502,7 @@ }, "SubscriptionCapabilities": {}, "ScalarType": { - "additionalProperties": true, - "anyOf": [ - { - "enum": [ - "string", - "number", - "bool" - ], - "type": "string" - }, - { - "type": "string" - } - ] + "type": "string" }, "ComparisonOperators": { "additionalProperties": { diff --git a/dc-agents/dc-api-types/src/models/ScalarType.ts b/dc-agents/dc-api-types/src/models/ScalarType.ts index 370081f78bb..7b3bee17998 100644 --- a/dc-agents/dc-api-types/src/models/ScalarType.ts +++ b/dc-agents/dc-api-types/src/models/ScalarType.ts @@ -2,5 +2,4 @@ /* tslint:disable */ /* eslint-disable */ -export type ScalarType = ('string' | 'number' | 'bool' | string); - +export type ScalarType = string; diff --git a/dc-agents/package-lock.json b/dc-agents/package-lock.json index 047d29e15e5..ca587b03789 100644 --- a/dc-agents/package-lock.json +++ b/dc-agents/package-lock.json @@ -24,7 +24,7 @@ }, "dc-api-types": { "name": "@hasura/dc-api-types", - "version": "0.19.0", + "version": "0.20.0", "license": "Apache-2.0", "devDependencies": { "@tsconfig/node16": "^1.0.3", @@ -1197,7 +1197,7 @@ "license": "Apache-2.0", "dependencies": { "@fastify/cors": "^7.0.0", - "@hasura/dc-api-types": "0.19.0", + "@hasura/dc-api-types": "0.20.0", "fastify": "^3.29.0", "mathjs": "^11.0.0", "pino-pretty": "^8.0.0", @@ -1781,7 +1781,7 @@ "license": "Apache-2.0", "dependencies": { "@fastify/cors": "^8.1.0", - "@hasura/dc-api-types": "0.19.0", + "@hasura/dc-api-types": "0.20.0", "fastify": "^4.4.0", "fastify-metrics": "^9.2.1", "nanoid": "^3.3.4", @@ -3125,7 +3125,7 @@ "version": "file:reference", "requires": { "@fastify/cors": "^7.0.0", - "@hasura/dc-api-types": "0.19.0", + "@hasura/dc-api-types": "0.20.0", "@tsconfig/node16": "^1.0.3", "@types/node": "^16.11.49", "@types/xml2js": "^0.4.11", @@ -3514,7 +3514,7 @@ "version": "file:sqlite", "requires": { "@fastify/cors": "^8.1.0", - "@hasura/dc-api-types": "0.19.0", + "@hasura/dc-api-types": "0.20.0", "@tsconfig/node16": "^1.0.3", "@types/node": "^16.11.49", "@types/sqlite3": "^3.1.8", diff --git a/dc-agents/reference/package-lock.json b/dc-agents/reference/package-lock.json index 1d48cfac250..ec39c860cb6 100644 --- a/dc-agents/reference/package-lock.json +++ b/dc-agents/reference/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@fastify/cors": "^7.0.0", - "@hasura/dc-api-types": "0.19.0", + "@hasura/dc-api-types": "0.20.0", "fastify": "^3.29.0", "mathjs": "^11.0.0", "pino-pretty": "^8.0.0", @@ -44,7 +44,7 @@ } }, "node_modules/@hasura/dc-api-types": { - "version": "0.19.0", + "version": "0.20.0", "license": "Apache-2.0", "devDependencies": { "@tsconfig/node16": "^1.0.3", diff --git a/dc-agents/reference/package.json b/dc-agents/reference/package.json index fac25839911..411461ad9b3 100644 --- a/dc-agents/reference/package.json +++ b/dc-agents/reference/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@fastify/cors": "^7.0.0", - "@hasura/dc-api-types": "0.19.0", + "@hasura/dc-api-types": "0.20.0", "fastify": "^3.29.0", "mathjs": "^11.0.0", "pino-pretty": "^8.0.0", diff --git a/dc-agents/reference/src/capabilities.ts b/dc-agents/reference/src/capabilities.ts index 1f9f3e76658..08695f55ef0 100644 --- a/dc-agents/reference/src/capabilities.ts +++ b/dc-agents/reference/src/capabilities.ts @@ -16,14 +16,32 @@ const dateTimeCapabilities: ScalarTypeCapabilities = { const stringCapabilities: ScalarTypeCapabilities = { aggregate_functions: { longest: 'string', - shortest: 'string' + shortest: 'string', + min: 'string', + max: 'string' }, graphql_type: 'String' } +const numberCapabilities: ScalarTypeCapabilities = { + aggregate_functions: { + max: 'number', + min: 'number', + stddev: 'number', + stddev_pop: 'number', + stddev_samp: 'number', + sum: 'number', + var_pop: 'number', + var_samp: 'number', + variance: 'number' + }, + graphql_type: 'Float' +} + const scalarTypes: ScalarTypesCapabilities = { DateTime: dateTimeCapabilities, - string: stringCapabilities + string: stringCapabilities, + number: numberCapabilities } const capabilities: Capabilities = { diff --git a/dc-agents/sqlite/package-lock.json b/dc-agents/sqlite/package-lock.json index 98c1379b369..ed1626c0295 100644 --- a/dc-agents/sqlite/package-lock.json +++ b/dc-agents/sqlite/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@fastify/cors": "^8.1.0", - "@hasura/dc-api-types": "0.19.0", + "@hasura/dc-api-types": "0.20.0", "fastify": "^4.4.0", "fastify-metrics": "^9.2.1", "nanoid": "^3.3.4", @@ -54,7 +54,7 @@ "license": "MIT" }, "node_modules/@hasura/dc-api-types": { - "version": "0.19.0", + "version": "0.20.0", "license": "Apache-2.0", "devDependencies": { "@tsconfig/node16": "^1.0.3", diff --git a/dc-agents/sqlite/package.json b/dc-agents/sqlite/package.json index fafb75ecdac..fc5cecd338e 100644 --- a/dc-agents/sqlite/package.json +++ b/dc-agents/sqlite/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@fastify/cors": "^8.1.0", - "@hasura/dc-api-types": "0.19.0", + "@hasura/dc-api-types": "0.20.0", "fastify-metrics": "^9.2.1", "fastify": "^4.4.0", "nanoid": "^3.3.4", diff --git a/dc-agents/sqlite/src/capabilities.ts b/dc-agents/sqlite/src/capabilities.ts index ff973c66bf0..0b63c331e14 100644 --- a/dc-agents/sqlite/src/capabilities.ts +++ b/dc-agents/sqlite/src/capabilities.ts @@ -55,19 +55,33 @@ const scalar_types: Record = { _glob: 'string', // _regexp: 'string', // TODO: Detect if REGEXP is supported ...standardOperators('string') + }, + aggregate_functions: { + max: 'string', + min: 'string' } }, // TODO: Why do we need a seperate 'decimal' type? decimal: { comparison_operators: { - _modulus_is_zero: 'number', - ...standardOperators('number') + _modulus_is_zero: 'decimal', + ...standardOperators('decimal') + }, + aggregate_functions: { + max: 'decimal', + min: 'decimal', + sum: 'decimal' } }, number: { comparison_operators: { _modulus_is_zero: 'number', ...standardOperators('number') + }, + aggregate_functions: { + max: 'number', + min: 'number', + sum: 'number' } }, bool: { diff --git a/server/lib/api-tests/src/Test/DataConnector/MockAgent/AggregateQuerySpec.hs b/server/lib/api-tests/src/Test/DataConnector/MockAgent/AggregateQuerySpec.hs index 874e7a41d3f..7846426a977 100644 --- a/server/lib/api-tests/src/Test/DataConnector/MockAgent/AggregateQuerySpec.hs +++ b/server/lib/api-tests/src/Test/DataConnector/MockAgent/AggregateQuerySpec.hs @@ -162,8 +162,8 @@ tests opts = describe "Aggregate Query Tests" $ do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "ArtistIds_Id", API.ColumnField (API.ColumnName "ArtistId") API.NumberTy), - (API.FieldName "ArtistNames_Name", API.ColumnField (API.ColumnName "Name") API.StringTy), + [ (API.FieldName "ArtistIds_Id", API.ColumnField (API.ColumnName "ArtistId") (API.ScalarType "number")), + (API.FieldName "ArtistNames_Name", API.ColumnField (API.ColumnName "Name") (API.ScalarType "string")), ( API.FieldName "nodes_Albums", API.RelField ( API.RelationshipField @@ -172,7 +172,7 @@ tests opts = describe "Aggregate Query Tests" $ do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "nodes_Title", API.ColumnField (API.ColumnName "Title") API.StringTy) + [ (API.FieldName "nodes_Title", API.ColumnField (API.ColumnName "Title") (API.ScalarType "string")) ], _qAggregates = Nothing, _qLimit = Nothing, diff --git a/server/lib/api-tests/src/Test/DataConnector/MockAgent/BasicQuerySpec.hs b/server/lib/api-tests/src/Test/DataConnector/MockAgent/BasicQuerySpec.hs index fcbbd84f059..21f8a2a800c 100644 --- a/server/lib/api-tests/src/Test/DataConnector/MockAgent/BasicQuerySpec.hs +++ b/server/lib/api-tests/src/Test/DataConnector/MockAgent/BasicQuerySpec.hs @@ -145,8 +145,8 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy), - (API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy) + [ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") (API.ScalarType "number")), + (API.FieldName "title", API.ColumnField (API.ColumnName "Title") (API.ScalarType "string")) ], _qAggregates = Nothing, _qLimit = Just 1, @@ -207,8 +207,8 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy), - (API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy) + [ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"), + (API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string") ], _qAggregates = Nothing, _qLimit = Just 3, @@ -266,7 +266,7 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "CustomerId", API.ColumnField (API.ColumnName "CustomerId") API.NumberTy) + [ (API.FieldName "CustomerId", API.ColumnField (API.ColumnName "CustomerId") $ API.ScalarType "number") ], _qAggregates = Nothing, _qLimit = Nothing, @@ -276,8 +276,8 @@ tests opts = do API.Exists (API.UnrelatedTable $ API.TableName ("Employee" :| [])) $ API.ApplyBinaryComparisonOperator API.Equal - (API.ComparisonColumn API.CurrentTable (API.ColumnName "EmployeeId") API.NumberTy) - (API.ScalarValue (Aeson.Number 1) API.NumberTy), + (API.ComparisonColumn API.CurrentTable (API.ColumnName "EmployeeId") $ API.ScalarType "number") + (API.ScalarValue (Aeson.Number 1) $ API.ScalarType "number"), _qOrderBy = Nothing } } diff --git a/server/lib/api-tests/src/Test/DataConnector/MockAgent/CustomScalarsSpec.hs b/server/lib/api-tests/src/Test/DataConnector/MockAgent/CustomScalarsSpec.hs index 072ebb7ca1c..a2828882240 100644 --- a/server/lib/api-tests/src/Test/DataConnector/MockAgent/CustomScalarsSpec.hs +++ b/server/lib/api-tests/src/Test/DataConnector/MockAgent/CustomScalarsSpec.hs @@ -94,12 +94,12 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "MyIntColumn", API.ColumnField (API.ColumnName "MyIntColumn") $ API.CustomTy "MyInt"), - (API.FieldName "MyFloatColumn", API.ColumnField (API.ColumnName "MyFloatColumn") $ API.CustomTy "MyFloat"), - (API.FieldName "MyStringColumn", API.ColumnField (API.ColumnName "MyStringColumn") $ API.CustomTy "MyString"), - (API.FieldName "MyBooleanColumn", API.ColumnField (API.ColumnName "MyBooleanColumn") $ API.CustomTy "MyBoolean"), - (API.FieldName "MyIDColumn", API.ColumnField (API.ColumnName "MyIDColumn") $ API.CustomTy "MyID"), - (API.FieldName "MyAnythingColumn", API.ColumnField (API.ColumnName "MyAnythingColumn") $ API.CustomTy "MyAnything") + [ (API.FieldName "MyIntColumn", API.ColumnField (API.ColumnName "MyIntColumn") $ API.ScalarType "MyInt"), + (API.FieldName "MyFloatColumn", API.ColumnField (API.ColumnName "MyFloatColumn") $ API.ScalarType "MyFloat"), + (API.FieldName "MyStringColumn", API.ColumnField (API.ColumnName "MyStringColumn") $ API.ScalarType "MyString"), + (API.FieldName "MyBooleanColumn", API.ColumnField (API.ColumnName "MyBooleanColumn") $ API.ScalarType "MyBoolean"), + (API.FieldName "MyIDColumn", API.ColumnField (API.ColumnName "MyIDColumn") $ API.ScalarType "MyID"), + (API.FieldName "MyAnythingColumn", API.ColumnField (API.ColumnName "MyAnythingColumn") $ API.ScalarType "MyAnything") ], _qAggregates = Nothing, _qLimit = Just 1, @@ -159,12 +159,12 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "MyIntColumn", API.ColumnField (API.ColumnName "MyIntColumn") $ API.CustomTy "MyInt"), - (API.FieldName "MyFloatColumn", API.ColumnField (API.ColumnName "MyFloatColumn") $ API.CustomTy "MyFloat"), - (API.FieldName "MyStringColumn", API.ColumnField (API.ColumnName "MyStringColumn") $ API.CustomTy "MyString"), - (API.FieldName "MyBooleanColumn", API.ColumnField (API.ColumnName "MyBooleanColumn") $ API.CustomTy "MyBoolean"), - (API.FieldName "MyIDColumn", API.ColumnField (API.ColumnName "MyIDColumn") $ API.CustomTy "MyID"), - (API.FieldName "MyAnythingColumn", API.ColumnField (API.ColumnName "MyAnythingColumn") $ API.CustomTy "MyAnything") + [ (API.FieldName "MyIntColumn", API.ColumnField (API.ColumnName "MyIntColumn") $ API.ScalarType "MyInt"), + (API.FieldName "MyFloatColumn", API.ColumnField (API.ColumnName "MyFloatColumn") $ API.ScalarType "MyFloat"), + (API.FieldName "MyStringColumn", API.ColumnField (API.ColumnName "MyStringColumn") $ API.ScalarType "MyString"), + (API.FieldName "MyBooleanColumn", API.ColumnField (API.ColumnName "MyBooleanColumn") $ API.ScalarType "MyBoolean"), + (API.FieldName "MyIDColumn", API.ColumnField (API.ColumnName "MyIDColumn") $ API.ScalarType "MyID"), + (API.FieldName "MyAnythingColumn", API.ColumnField (API.ColumnName "MyAnythingColumn") $ API.ScalarType "MyAnything") ], _qAggregates = Nothing, _qLimit = Just 1, @@ -174,28 +174,28 @@ tests opts = do And [ ApplyBinaryComparisonOperator Equal - (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyBooleanColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyBoolean"}}) - (ScalarValue (Aeson.Bool True) (CustomTy {getCustomTy = "MyBoolean"})), + (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyBooleanColumn"}, _ccColumnType = ScalarType "MyBoolean"}) + (ScalarValue (Aeson.Bool True) (ScalarType "MyBoolean")), ApplyBinaryComparisonOperator Equal - (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyFloatColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyFloat"}}) - (ScalarValue (Aeson.Number 3.14) (CustomTy {getCustomTy = "MyFloat"})), + (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyFloatColumn"}, _ccColumnType = ScalarType "MyFloat"}) + (ScalarValue (Aeson.Number 3.14) (ScalarType "MyFloat")), ApplyBinaryComparisonOperator Equal - (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyStringColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyString"}}) - (ScalarValue (Aeson.String "foo") (CustomTy {getCustomTy = "MyString"})), + (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyStringColumn"}, _ccColumnType = ScalarType "MyString"}) + (ScalarValue (Aeson.String "foo") (ScalarType "MyString")), ApplyBinaryComparisonOperator Equal - (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyIDColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyID"}}) - (ScalarValue (Aeson.String "x") (CustomTy {getCustomTy = "MyID"})), + (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyIDColumn"}, _ccColumnType = ScalarType "MyID"}) + (ScalarValue (Aeson.String "x") (ScalarType "MyID")), ApplyBinaryComparisonOperator Equal - (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyIntColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyInt"}}) - (ScalarValue (Aeson.Number 42.0) (CustomTy {getCustomTy = "MyInt"})), + (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyIntColumn"}, _ccColumnType = ScalarType "MyInt"}) + (ScalarValue (Aeson.Number 42.0) (ScalarType "MyInt")), ApplyBinaryComparisonOperator Equal - (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyAnythingColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyAnything"}}) - (ScalarValue (Aeson.Object mempty) (CustomTy {getCustomTy = "MyAnything"})) + (ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyAnythingColumn"}, _ccColumnType = ScalarType "MyAnything"}) + (ScalarValue (Aeson.Object mempty) (ScalarType "MyAnything")) ], _qOrderBy = Nothing } diff --git a/server/lib/api-tests/src/Test/DataConnector/MockAgent/ErrorSpec.hs b/server/lib/api-tests/src/Test/DataConnector/MockAgent/ErrorSpec.hs index af8bf50359e..7050952927d 100644 --- a/server/lib/api-tests/src/Test/DataConnector/MockAgent/ErrorSpec.hs +++ b/server/lib/api-tests/src/Test/DataConnector/MockAgent/ErrorSpec.hs @@ -99,8 +99,8 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy), - (API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy) + [ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"), + (API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string") ], _qAggregates = Nothing, _qLimit = Just 1, diff --git a/server/lib/api-tests/src/Test/DataConnector/MockAgent/QueryRelationshipsSpec.hs b/server/lib/api-tests/src/Test/DataConnector/MockAgent/QueryRelationshipsSpec.hs index 353e6a83525..5475cc196e5 100644 --- a/server/lib/api-tests/src/Test/DataConnector/MockAgent/QueryRelationshipsSpec.hs +++ b/server/lib/api-tests/src/Test/DataConnector/MockAgent/QueryRelationshipsSpec.hs @@ -209,7 +209,7 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy), + [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string"), ( API.FieldName "Genre", API.RelField ( API.RelationshipField @@ -218,7 +218,7 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy) + [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string") ], _qAggregates = Nothing, _qLimit = Nothing, @@ -236,7 +236,7 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy) + [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string") ], _qAggregates = Nothing, _qLimit = Nothing, @@ -339,7 +339,7 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy), + [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string"), ( API.FieldName "Album", API.RelField ( API.RelationshipField @@ -356,7 +356,7 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy) + [ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string") ], _qAggregates = Nothing, _qLimit = Nothing, @@ -472,7 +472,7 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "EmployeeId", API.ColumnField (API.ColumnName "EmployeeId") API.NumberTy) + [ (API.FieldName "EmployeeId", API.ColumnField (API.ColumnName "EmployeeId") $ API.ScalarType "number") ], _qAggregates = Nothing, _qLimit = Just 1, @@ -482,8 +482,8 @@ tests opts = do API.Exists (API.RelatedTable $ API.RelationshipName "SupportRepForCustomers") $ API.ApplyBinaryComparisonOperator API.Equal - (API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") API.StringTy) - (API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") API.StringTy)), + (API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") $ API.ScalarType "string") + (API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") $ API.ScalarType "string")), _qOrderBy = Just $ API.OrderBy @@ -494,8 +494,8 @@ tests opts = do API.Exists (API.RelatedTable $ API.RelationshipName "SupportRep") $ API.ApplyBinaryComparisonOperator API.Equal - (API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") API.StringTy) - (API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") API.StringTy)) + (API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") $ API.ScalarType "string") + (API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") $ API.ScalarType "string")) ) mempty ) diff --git a/server/lib/api-tests/src/Test/DataConnector/MockAgent/TransformedConfigurationSpec.hs b/server/lib/api-tests/src/Test/DataConnector/MockAgent/TransformedConfigurationSpec.hs index 7cc2488a358..e38c625ef1e 100644 --- a/server/lib/api-tests/src/Test/DataConnector/MockAgent/TransformedConfigurationSpec.hs +++ b/server/lib/api-tests/src/Test/DataConnector/MockAgent/TransformedConfigurationSpec.hs @@ -140,8 +140,8 @@ tests opts = do { _qFields = Just $ HashMap.fromList - [ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy), - (API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy) + [ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"), + (API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string") ], _qAggregates = Nothing, _qLimit = Just 1, diff --git a/server/lib/dc-api/src/Hasura/Backends/DataConnector/API/V0/Scalar.hs b/server/lib/dc-api/src/Hasura/Backends/DataConnector/API/V0/Scalar.hs index 11094c4cd7e..67f550ae3c1 100644 --- a/server/lib/dc-api/src/Hasura/Backends/DataConnector/API/V0/Scalar.hs +++ b/server/lib/dc-api/src/Hasura/Backends/DataConnector/API/V0/Scalar.hs @@ -1,10 +1,8 @@ {-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE OverloadedLists #-} -- module Hasura.Backends.DataConnector.API.V0.Scalar ( ScalarType (..), - scalarTypeToText, ) where @@ -24,41 +22,13 @@ import Prelude -------------------------------------------------------------------------------- -data ScalarType - = StringTy - | NumberTy - | BoolTy - | CustomTy {getCustomTy :: Text} +newtype ScalarType = ScalarType {getScalarType :: Text} deriving stock (Eq, Generic, Ord, Show) deriving anyclass (Hashable, NFData) + deriving newtype (FromJSONKey, ToJSONKey) deriving (FromJSON, ToJSON, ToSchema) via Autodocodec ScalarType -instance ToJSONKey ScalarType where - toJSONKey = ToJSONKeyText (Key.fromText . scalarTypeToText) (Encoding.text . scalarTypeToText) - -instance FromJSONKey ScalarType where - fromJSONKey = FromJSONKeyText textToScalarType - -scalarTypeToText :: ScalarType -> Text -scalarTypeToText = \case - StringTy -> "string" - NumberTy -> "number" - BoolTy -> "bool" - CustomTy t -> t - -textToScalarType :: Text -> ScalarType -textToScalarType t - | t == "string" = StringTy - | t == "number" = NumberTy - | t == "bool" = BoolTy - | otherwise = CustomTy t - instance HasCodec ScalarType where codec = named "ScalarType" $ - matchChoiceCodec - (stringConstCodec [(StringTy, "string"), (NumberTy, "number"), (BoolTy, "bool")]) - (dimapCodec CustomTy getCustomTy textCodec) - \case - ty@CustomTy {} -> Right ty - ty -> Left ty + dimapCodec ScalarType getScalarType textCodec diff --git a/server/lib/dc-api/test/Main.hs b/server/lib/dc-api/test/Main.hs index 43023365ea9..38e46a1c0e5 100644 --- a/server/lib/dc-api/test/Main.hs +++ b/server/lib/dc-api/test/Main.hs @@ -10,7 +10,7 @@ import Hasura.Backends.DataConnector.API (openApiSchema) import Hasura.Backends.DataConnector.API qualified as API import Servant.Client ((//)) import System.Environment (withArgs) -import Test.AgentClient (AgentIOClient (..), guardCapabilitiesResponse, introduceAgentClient, mkAgentClientConfig, mkAgentIOClient) +import Test.AgentClient (AgentIOClient (..), guardCapabilitiesResponse, guardSchemaResponse, introduceAgentClient, mkAgentClientConfig, mkAgentIOClient) import Test.Data (TestData, mkTestData) import Test.DataExport (exportData) import Test.Sandwich (runSandwichWithCommandLineArgs) @@ -49,9 +49,10 @@ main = do Test TestOptions {..} (SandwichArguments arguments) -> withArgs arguments $ do (AgentIOClient agentClient) <- mkAgentIOClient _toSensitiveOutputHandling _toAgentOptions agentCapabilities <- (agentClient // API._capabilities) >>= guardCapabilitiesResponse + schemaResponse <- (agentClient // API._schema) testSourceName (_aoAgentConfig _toAgentOptions) >>= guardSchemaResponse agentClientConfig <- mkAgentClientConfig _toSensitiveOutputHandling _toAgentOptions - let testData = mkTestData _toTestConfig + let testData = mkTestData schemaResponse _toTestConfig runSandwichWithCommandLineArgs Sandwich.defaultOptions $ introduceAgentClient agentClientConfig $ tests testData testSourceName (_aoAgentConfig _toAgentOptions) agentCapabilities diff --git a/server/lib/dc-api/test/Test/AgentClient.hs b/server/lib/dc-api/test/Test/AgentClient.hs index fe733992125..9451a0a1fcf 100644 --- a/server/lib/dc-api/test/Test/AgentClient.hs +++ b/server/lib/dc-api/test/Test/AgentClient.hs @@ -15,6 +15,7 @@ module Test.AgentClient guardCapabilitiesResponse, getHealth, getSchemaGuarded, + guardSchemaResponse, queryGuarded, queryExpectError, explain, diff --git a/server/lib/dc-api/test/Test/Data.hs b/server/lib/dc-api/test/Test/Data.hs index f3b32dd0f0d..ab7d1fc14e6 100644 --- a/server/lib/dc-api/test/Test/Data.hs +++ b/server/lib/dc-api/test/Test/Data.hs @@ -65,7 +65,7 @@ schemaTables :: [API.TableInfo] schemaTables = sortOn API._tiName . either error id . eitherDecodeStrict $ schemaBS numericColumns :: [API.ColumnName] -numericColumns = schemaTables >>= (API._tiColumns >>> mapMaybe (\API.ColumnInfo {..} -> if _ciType == API.NumberTy then Just _ciName else Nothing)) +numericColumns = schemaTables >>= (API._tiColumns >>> mapMaybe (\API.ColumnInfo {..} -> if _ciType == API.ScalarType "number" then Just _ciName else Nothing)) chinookXmlBS :: ByteString chinookXmlBS = $(makeRelativeToProject "test/Test/Data/ChinookData.xml.gz" >>= embedFile) @@ -344,19 +344,17 @@ data TestData = TestData _tdGenresRows :: [HashMap API.FieldName API.FieldValue], _tdGenresTableRelationships :: API.TableRelationships, -- = Scalar Types - _tdStringType :: API.ScalarType, - _tdIntType :: API.ScalarType, - _tdFloatType :: API.ScalarType, + _tdFindColumnScalarType :: API.TableName -> Text -> API.ScalarType, -- = Utility functions _tdColumnName :: Text -> API.ColumnName, - _tdColumnField :: Text -> API.ScalarType -> API.Field, + _tdColumnField :: API.TableName -> Text -> API.Field, _tdQueryComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn, _tdCurrentComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn, _tdOrderByColumn :: [API.RelationshipName] -> Text -> API.OrderDirection -> API.OrderByElement } -mkTestData :: TestConfig -> TestData -mkTestData TestConfig {..} = +mkTestData :: API.SchemaResponse -> TestConfig -> TestData +mkTestData schemaResponse TestConfig {..} = TestData { _tdSchemaTables = formatTableInfo <$> schemaTables, _tdArtistsTableName = formatTableName artistsTableName, @@ -395,14 +393,12 @@ mkTestData TestConfig {..} = _tdGenresTableName = formatTableName genresTableName, _tdGenresRows = genresRows, _tdGenresTableRelationships = formatTableRelationships genresTableRelationships, - _tdColumnName = API.ColumnName . applyNameCasing _tcColumnNameCasing, - _tdColumnField = columnField . applyNameCasing _tcColumnNameCasing, - _tdStringType = API.StringTy, - _tdIntType = API.NumberTy, - _tdFloatType = API.NumberTy, - _tdQueryComparisonColumn = queryComparisonColumn . applyNameCasing _tcColumnNameCasing, - _tdCurrentComparisonColumn = currentComparisonColumn . applyNameCasing _tcColumnNameCasing, - _tdOrderByColumn = \targetPath name -> orderByColumn targetPath (applyNameCasing _tcColumnNameCasing name) + _tdColumnName = formatColumnName . API.ColumnName, + _tdColumnField = columnField, + _tdFindColumnScalarType = \tableName name -> findColumnScalarType schemaResponse tableName (formatColumnName $ API.ColumnName name), + _tdQueryComparisonColumn = API.ComparisonColumn API.QueryTable . formatColumnName . API.ColumnName, + _tdCurrentComparisonColumn = API.ComparisonColumn API.CurrentTable . formatColumnName . API.ColumnName, + _tdOrderByColumn = \targetPath name -> orderByColumn targetPath (formatColumnName $ API.ColumnName name) } where formatTableName :: API.TableName -> API.TableName @@ -431,6 +427,13 @@ mkTestData TestConfig {..} = >>> API.cColumnMapping %~ (HashMap.toList >>> fmap (bimap formatColumnName formatColumnName) >>> HashMap.fromList) ) + columnField :: API.TableName -> Text -> API.Field + columnField tableName columnName = + API.ColumnField columnName' scalarType + where + columnName' = formatColumnName $ API.ColumnName columnName + scalarType = findColumnScalarType schemaResponse tableName columnName' + applyTableNamePrefix :: [Text] -> API.TableName -> API.TableName applyTableNamePrefix prefix tableName@(API.TableName rawTableName) = case NonEmpty.nonEmpty prefix of @@ -443,6 +446,13 @@ applyNameCasing casing text = case casing of Lowercase -> Text.toLower text Uppercase -> Text.toUpper text +findColumnScalarType :: API.SchemaResponse -> API.TableName -> API.ColumnName -> API.ScalarType +findColumnScalarType API.SchemaResponse {..} tableName columnName = + maybe (error $ "Can't find the scalar type of column " <> show columnName <> " in table " <> show tableName) API._ciType columnInfo + where + tableInfo = find (\API.TableInfo {..} -> _tiName == tableName) _srTables + columnInfo = find (\API.ColumnInfo {..} -> _ciName == columnName) =<< API._tiColumns <$> tableInfo + emptyQuery :: API.Query emptyQuery = API.Query Nothing Nothing Nothing Nothing Nothing Nothing @@ -511,15 +521,6 @@ _ColumnFieldBoolean = API._ColumnFieldValue . _Bool _RelationshipFieldRows :: Traversal' API.FieldValue [HashMap API.FieldName API.FieldValue] _RelationshipFieldRows = API._RelationshipFieldValue . API.qrRows . _Just -columnField :: Text -> API.ScalarType -> API.Field -columnField name scalarType = API.ColumnField (API.ColumnName name) scalarType - -queryComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn -queryComparisonColumn columnName scalarType = API.ComparisonColumn API.QueryTable (API.ColumnName columnName) scalarType - -currentComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn -currentComparisonColumn columnName scalarType = API.ComparisonColumn API.CurrentTable (API.ColumnName columnName) scalarType - -orderByColumn :: [API.RelationshipName] -> Text -> API.OrderDirection -> API.OrderByElement +orderByColumn :: [API.RelationshipName] -> API.ColumnName -> API.OrderDirection -> API.OrderByElement orderByColumn targetPath columnName orderDirection = - API.OrderByElement targetPath (API.OrderByColumn $ API.ColumnName columnName) orderDirection + API.OrderByElement targetPath (API.OrderByColumn columnName) orderDirection diff --git a/server/lib/dc-api/test/Test/DataExport.hs b/server/lib/dc-api/test/Test/DataExport.hs index 4cd7ec540e8..5279f4e5b91 100644 --- a/server/lib/dc-api/test/Test/DataExport.hs +++ b/server/lib/dc-api/test/Test/DataExport.hs @@ -63,7 +63,7 @@ formatDateColumnsInRow dateTimeFormatString TableInfo {..} row = ) where dateFields = fmap (\ColumnInfo {..} -> FieldName $ unColumnName _ciName) $ filter (\ColumnInfo {..} -> _ciType == dateTimeScalarType) _tiColumns - dateTimeScalarType = CustomTy "DateTime" + dateTimeScalarType = ScalarType "DateTime" tryFormatDate fieldValue = case deserializeAsColumnFieldValue fieldValue of J.String value -> do (zonedTime :: ZonedTime) <- iso8601ParseM $ Text.unpack value diff --git a/server/lib/dc-api/test/Test/Specs/ErrorSpec.hs b/server/lib/dc-api/test/Test/Specs/ErrorSpec.hs index b2c7e68013a..4544a294cc1 100644 --- a/server/lib/dc-api/test/Test/Specs/ErrorSpec.hs +++ b/server/lib/dc-api/test/Test/Specs/ErrorSpec.hs @@ -1,6 +1,7 @@ module Test.Specs.ErrorSpec (spec) where import Control.Lens ((&), (?~)) +import Data.Aeson (Value (..)) import Hasura.Backends.DataConnector.API import Test.AgentClient (queryExpectError) import Test.Data (TestData (..)) @@ -16,13 +17,15 @@ spec TestData {..} sourceName config _capabilities = describe "Error Protocol" d where brokenQueryRequest :: QueryRequest brokenQueryRequest = - let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)] + let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")] query = Data.emptyQuery & qFields ?~ fields & qWhere ?~ ApplyBinaryComparisonOperator (CustomBinaryComparisonOperator "FOOBAR") - (ComparisonColumn CurrentTable (ColumnName "ArtistId") NumberTy) - (ScalarValue "1" StringTy) + (_tdCurrentComparisonColumn "ArtistId" artistIdScalarType) + (ScalarValue (Number 1) $ artistIdScalarType) in QueryRequest _tdArtistsTableName [] query + + artistIdScalarType = _tdFindColumnScalarType _tdArtistsTableName "ArtistId" diff --git a/server/lib/dc-api/test/Test/Specs/ExplainSpec.hs b/server/lib/dc-api/test/Test/Specs/ExplainSpec.hs index 4418b848775..6c7809ca838 100644 --- a/server/lib/dc-api/test/Test/Specs/ExplainSpec.hs +++ b/server/lib/dc-api/test/Test/Specs/ExplainSpec.hs @@ -24,6 +24,6 @@ spec TestData {..} sourceName config _ = do where artistsQueryRequest :: QueryRequest artistsQueryRequest = - let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)] + let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")] query = Data.emptyQuery & qFields ?~ fields in QueryRequest _tdArtistsTableName [] query diff --git a/server/lib/dc-api/test/Test/Specs/QuerySpec/AggregatesSpec.hs b/server/lib/dc-api/test/Test/Specs/QuerySpec/AggregatesSpec.hs index 668c20c2823..752a30015a9 100644 --- a/server/lib/dc-api/test/Test/Specs/QuerySpec/AggregatesSpec.hs +++ b/server/lib/dc-api/test/Test/Specs/QuerySpec/AggregatesSpec.hs @@ -39,7 +39,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg Data.responseRows response `rowsShouldBe` [] it "counts all rows, after applying filters" $ do - let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCity" _tdStringType) (ScalarValue (String "Oslo") _tdStringType) + let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCity" billingCityScalarType) (ScalarValue (String "Oslo") billingCityScalarType) let aggregates = Data.mkFieldsMap [("count_all", StarCount)] let queryRequest = invoicesQueryRequest aggregates & qrQuery . qWhere ?~ where' response <- queryGuarded sourceName config queryRequest @@ -77,7 +77,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg it "can count all rows with non-null values in a column, after applying pagination and filtering" $ do let limit = 50 - let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" _tdIntType) (ScalarValue (Number 380) _tdIntType) + let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" invoiceIdScalarType) (ScalarValue (Number 380) invoiceIdScalarType) let aggregates = Data.mkFieldsMap [("count_cols", ColumnCount $ ColumnCountAggregate (_tdColumnName "BillingState") False)] let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qLimit ?~ limit >>> qWhere ?~ where') response <- queryGuarded sourceName config queryRequest @@ -107,7 +107,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg it "can count all rows with distinct non-null values in a column, after applying pagination and filtering" $ do let limit = 20 - let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" _tdIntType) (ScalarValue (Number 380) _tdIntType) + let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" invoiceIdScalarType) (ScalarValue (Number 380) invoiceIdScalarType) -- It is important to add an explicit order by for this query as different database engines will order implicitly resulting in incorrect results let orderBy = OrderBy mempty $ _tdOrderByColumn [] "InvoiceId" Ascending :| [] let aggregates = Data.mkFieldsMap [("count_cols", ColumnCount $ ColumnCountAggregate (_tdColumnName "BillingState") True)] @@ -141,7 +141,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg it "can get the max total from all rows, after applying pagination, filtering and ordering" $ do let limit = 20 - let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" _tdStringType) (ScalarValue (String "USA") _tdStringType) + let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" billingCountryScalarType) (ScalarValue (String "USA") billingCountryScalarType) let orderBy = OrderBy mempty $ _tdOrderByColumn [] "BillingPostalCode" Descending :| [_tdOrderByColumn [] "InvoiceId" Ascending] let aggregates = Data.mkFieldsMap [("max", singleColumnAggregateMax (_tdColumnName "Total"))] let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qLimit ?~ limit >>> qWhere ?~ where' >>> qOrderBy ?~ orderBy) @@ -180,7 +180,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg Data.responseRows response `rowsShouldBe` [] it "aggregates over empty row lists results in nulls" $ do - let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "ArtistId" _tdIntType) (ScalarValue (Number 0) _tdIntType) + let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "ArtistId" artistIdScalarType) (ScalarValue (Number 0) artistIdScalarType) let aggregates = Data.mkFieldsMap [("min", singleColumnAggregateMin (_tdColumnName "Name"))] let queryRequest = artistsQueryRequest aggregates & qrQuery . qWhere ?~ where' response <- queryGuarded sourceName config queryRequest @@ -240,10 +240,10 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg let limit = 30 let fields = Data.mkFieldsMap - [ ("InvoiceId", _tdColumnField "InvoiceId" _tdIntType), - ("BillingCountry", _tdColumnField "BillingCountry" _tdStringType) + [ ("InvoiceId", _tdColumnField _tdInvoicesTableName "InvoiceId"), + ("BillingCountry", _tdColumnField _tdInvoicesTableName "BillingCountry") ] - let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" _tdStringType) (ScalarValue (String "Canada") _tdStringType) + let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" billingCountryScalarType) (ScalarValue (String "Canada") billingCountryScalarType) let orderBy = OrderBy mempty $ _tdOrderByColumn [] "BillingAddress" Ascending :| [_tdOrderByColumn [] "InvoiceId" Ascending] let aggregates = Data.mkFieldsMap [("min", singleColumnAggregateMin (_tdColumnName "Total"))] let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qFields ?~ fields >>> qLimit ?~ limit >>> qWhere ?~ where' >>> qOrderBy ?~ orderBy) @@ -293,8 +293,8 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg let limit = 5 let albumFields = Data.mkFieldsMap - [ ("AlbumId", _tdColumnField "AlbumId" _tdIntType), - ("Title", _tdColumnField "Title" _tdStringType) + [ ("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), + ("Title", _tdColumnField _tdAlbumsTableName "Title") ] let query = artistsWithAlbumsQuery (qFields ?~ albumFields) & qrQuery . qLimit ?~ limit receivedArtists <- queryGuarded sourceName config query @@ -494,8 +494,8 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg albumsSubquery = Data.emptyQuery & qAggregates ?~ albumAggregates & modifySubquery artistFields = Data.mkFieldsMap - [ ("ArtistId", _tdColumnField "ArtistId" _tdIntType), - ("Name", _tdColumnField "Name" _tdStringType), + [ ("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), + ("Name", _tdColumnField _tdArtistsTableName "Name"), ("Albums", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery) ] artistOrderBy = OrderBy mempty $ _tdOrderByColumn [] "ArtistId" Ascending :| [] @@ -538,34 +538,34 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg deeplyNestedArtistsQuery = let invoiceLinesAggregates = Data.mkFieldsMap [("aggregate_sum_Quantity", singleColumnAggregateSum (_tdColumnName "Quantity"))] invoiceLinesSubquery = Data.emptyQuery & qAggregates ?~ invoiceLinesAggregates - mediaTypeFields = Data.mkFieldsMap [("Name", _tdColumnField "Name" _tdStringType)] + mediaTypeFields = Data.mkFieldsMap [("Name", _tdColumnField _tdMediaTypesTableName "Name")] mediaTypeSubquery = Data.emptyQuery & qFields ?~ mediaTypeFields tracksFields = Data.mkFieldsMap - [ ("nodes_Name", _tdColumnField "Name" _tdStringType), + [ ("nodes_Name", _tdColumnField _tdTracksTableName "Name"), ("nodes_MediaType", RelField $ RelationshipField _tdMediaTypeRelationshipName mediaTypeSubquery), ("nodes_InvoiceLines_aggregate", RelField $ RelationshipField _tdInvoiceLinesRelationshipName invoiceLinesSubquery) ] tracksAggregates = Data.mkFieldsMap [("aggregate_count", StarCount)] - tracksWhere = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Milliseconds" _tdIntType) (ScalarValue (Number 300000) _tdIntType) + tracksWhere = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Milliseconds" millisecondsScalarType) (ScalarValue (Number 300000) millisecondsScalarType) tracksOrderBy = OrderBy mempty $ _tdOrderByColumn [] "Name" Descending :| [] tracksSubquery = Query (Just tracksFields) (Just tracksAggregates) Nothing Nothing (Just tracksWhere) (Just tracksOrderBy) albumsFields = Data.mkFieldsMap - [ ("nodes_Title", _tdColumnField "Title" _tdStringType), + [ ("nodes_Title", _tdColumnField _tdAlbumsTableName "Title"), ("nodes_Tracks_aggregate", RelField $ RelationshipField _tdTracksRelationshipName tracksSubquery) ] albumsOrderBy = OrderBy mempty $ _tdOrderByColumn [] "Title" Ascending :| [] albumsSubquery = Data.emptyQuery & qFields ?~ albumsFields & qOrderBy ?~ albumsOrderBy artistFields = Data.mkFieldsMap - [ ("Name", _tdColumnField "Name" _tdStringType), + [ ("Name", _tdColumnField _tdArtistsTableName "Name"), ("Albums_aggregate", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery) ] artistWhere = And - [ ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "A") _tdStringType), - ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "B") _tdStringType) + [ ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "A") artistNameScalarType), + ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "B") artistNameScalarType) ] artistOrderBy = OrderBy mempty $ _tdOrderByColumn [] "Name" Descending :| [] artistQuery = Query (Just artistFields) Nothing (Just 3) (Just 1) (Just artistWhere) (Just artistOrderBy) @@ -607,3 +607,10 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg singleColumnAggregateSum :: ColumnName -> Aggregate singleColumnAggregateSum = SingleColumn . SingleColumnAggregate (SingleColumnAggregateFunction [G.name|sum|]) + + billingCityScalarType = _tdFindColumnScalarType _tdInvoicesTableName "BillingCity" + billingCountryScalarType = _tdFindColumnScalarType _tdInvoicesTableName "BillingCountry" + invoiceIdScalarType = _tdFindColumnScalarType _tdInvoicesTableName "InvoiceId" + artistIdScalarType = _tdFindColumnScalarType _tdArtistsTableName "ArtistId" + artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name" + millisecondsScalarType = _tdFindColumnScalarType _tdTracksTableName "Milliseconds" diff --git a/server/lib/dc-api/test/Test/Specs/QuerySpec/BasicSpec.hs b/server/lib/dc-api/test/Test/Specs/QuerySpec/BasicSpec.hs index 4f020bd5311..a2a827382ce 100644 --- a/server/lib/dc-api/test/Test/Specs/QuerySpec/BasicSpec.hs +++ b/server/lib/dc-api/test/Test/Specs/QuerySpec/BasicSpec.hs @@ -24,7 +24,7 @@ spec TestData {..} sourceName config = describe "Basic Queries" $ do _qrAggregates receivedArtists `jsonShouldBe` Nothing it "can query for a list of albums with a subset of columns" $ do - let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)] + let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")] let query = albumsQueryRequest & qrQuery . qFields ?~ fields receivedAlbums <- Data.sortResponseRowsBy "Title" <$> queryGuarded sourceName config query @@ -36,7 +36,7 @@ spec TestData {..} sourceName config = describe "Basic Queries" $ do _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can project columns into fields with different names" $ do - let fields = Data.mkFieldsMap [("Artist_Id", _tdColumnField "ArtistId" _tdIntType), ("Artist_Name", _tdColumnField "Name" _tdStringType)] + let fields = Data.mkFieldsMap [("Artist_Id", _tdColumnField _tdArtistsTableName "ArtistId"), ("Artist_Name", _tdColumnField _tdArtistsTableName "Name")] let query = artistsQueryRequest & qrQuery . qFields ?~ fields receivedArtists <- Data.sortResponseRowsBy "ArtistId" <$> queryGuarded sourceName config query @@ -67,12 +67,12 @@ spec TestData {..} sourceName config = describe "Basic Queries" $ do where artistsQueryRequest :: QueryRequest artistsQueryRequest = - let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)] + let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")] query = Data.emptyQuery & qFields ?~ fields in QueryRequest _tdArtistsTableName [] query albumsQueryRequest :: QueryRequest albumsQueryRequest = - let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)] + let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")] query = Data.emptyQuery & qFields ?~ fields in QueryRequest _tdAlbumsTableName [] query diff --git a/server/lib/dc-api/test/Test/Specs/QuerySpec/CustomOperatorsSpec.hs b/server/lib/dc-api/test/Test/Specs/QuerySpec/CustomOperatorsSpec.hs index e06db67712e..76e5c2bc4db 100644 --- a/server/lib/dc-api/test/Test/Specs/QuerySpec/CustomOperatorsSpec.hs +++ b/server/lib/dc-api/test/Test/Specs/QuerySpec/CustomOperatorsSpec.hs @@ -34,7 +34,7 @@ spec TestData {..} sourceName config (ScalarTypesCapabilities scalarTypesCapabil forM_ (HashMap.toList items) \((operatorName, columnType), (columnName, tableName, argColumnName, argType)) -> do -- Perform a select using the operator in a where clause let queryRequest = - let fields = Data.mkFieldsMap [(unColumnName columnName, _tdColumnField (unColumnName columnName) columnType)] + let fields = Data.mkFieldsMap [(unColumnName columnName, _tdColumnField tableName (unColumnName columnName))] query' = Data.emptyQuery & qFields ?~ fields in QueryRequest tableName [] query' where' = @@ -46,7 +46,7 @@ spec TestData {..} sourceName config (ScalarTypesCapabilities scalarTypesCapabil queryRequest & qrQuery . qWhere ?~ where' & qrQuery . qLimit ?~ 1 -- No need to test actual results - it (Text.unpack $ "ComparisonOperator " <> unName operatorName <> ": " <> scalarTypeToText columnType <> " executes without an error") do + it (Text.unpack $ "ComparisonOperator " <> unName operatorName <> ": " <> getScalarType columnType <> " executes without an error") do result <- queryGuarded sourceName config query -- Check that you get a success response Data.responseRows result `shouldBe` take 1 (Data.responseRows result) diff --git a/server/lib/dc-api/test/Test/Specs/QuerySpec/FilteringSpec.hs b/server/lib/dc-api/test/Test/Specs/QuerySpec/FilteringSpec.hs index 4434faa7819..954c7cd24e0 100644 --- a/server/lib/dc-api/test/Test/Specs/QuerySpec/FilteringSpec.hs +++ b/server/lib/dc-api/test/Test/Specs/QuerySpec/FilteringSpec.hs @@ -20,7 +20,7 @@ import Prelude spec :: TestData -> SourceName -> Config -> Maybe ComparisonCapabilities -> AgentTestSpec spec TestData {..} sourceName config comparisonCapabilities = describe "Filtering in Queries" $ do it "can filter using an equality expression" $ do - let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType) + let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 2) albumIdScalarType) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -31,7 +31,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can filter using an inequality expression" $ do - let where' = Not (ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType)) + let where' = Not (ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 2) albumIdScalarType)) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -42,7 +42,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can filter using an in expression" $ do - let where' = ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" _tdIntType) [Number 2, Number 3] _tdIntType + let where' = ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) [Number 2, Number 3] albumIdScalarType let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -53,7 +53,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can negate an in expression filter using a not expression" $ do - let where' = Not (ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" _tdIntType) [Number 2, Number 3] _tdIntType) + let where' = Not (ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) [Number 2, Number 3] albumIdScalarType) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -64,8 +64,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can combine filters using an and expression" $ do - let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "ArtistId" _tdIntType) (ScalarValue (Number 58) _tdIntType) - let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "Stormbringer") _tdStringType) + let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "ArtistId" artistIdScalarType) (ScalarValue (Number 58) artistIdScalarType) + let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" albumTitleScalarType) (ScalarValue (String "Stormbringer") albumTitleScalarType) let where' = And [where1, where2] let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -89,8 +89,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can combine filters using an or expression" $ do - let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType) - let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 3) _tdIntType) + let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 2) albumIdScalarType) + let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 3) albumIdScalarType) let where' = Or [where1, where2] let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -110,7 +110,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can filter by applying the greater than operator" $ do - let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 300) _tdIntType) + let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 300) albumIdScalarType) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -121,7 +121,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can filter by applying the greater than or equal operator" $ do - let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 300) _tdIntType) + let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 300) albumIdScalarType) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -132,7 +132,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can filter by applying the less than operator" $ do - let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 100) _tdIntType) + let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 100) albumIdScalarType) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -143,7 +143,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can filter by applying the less than or equal operator" $ do - let where' = ApplyBinaryComparisonOperator LessThanOrEqual (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 100) _tdIntType) + let where' = ApplyBinaryComparisonOperator LessThanOrEqual (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 100) albumIdScalarType) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -154,7 +154,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can filter using a greater than operator with a column comparison" $ do - let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (AnotherColumn (_tdCurrentComparisonColumn "ArtistId" _tdIntType)) + let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (AnotherColumn (_tdCurrentComparisonColumn "ArtistId" albumIdScalarType)) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -171,7 +171,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin it "returns all rows if matching rows exist" $ do let where' = Exists (UnrelatedTable _tdEmployeesTableName) $ - ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType) + ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType) (ScalarValue (Number 1) employeeIdScalarType) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -183,7 +183,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin it "returns no rows if matching rows do not exist" $ do let where' = Exists (UnrelatedTable _tdEmployeesTableName) $ - ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 0) _tdIntType) + ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType) (ScalarValue (Number 0) employeeIdScalarType) let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -195,8 +195,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin let where' = Exists (UnrelatedTable _tdEmployeesTableName) $ And - [ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType), - ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" _tdStringType) (ScalarValue (String "Edmonton") _tdStringType) + [ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType) (ScalarValue (Number 1) employeeIdScalarType), + ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" employeeCityScalarType) (ScalarValue (String "Edmonton") employeeCityScalarType) ] let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -210,8 +210,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin let where' = Exists (UnrelatedTable _tdEmployeesTableName) $ And - [ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType), - ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" _tdStringType) (ScalarValue (String "Calgary") _tdStringType) + [ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType) (ScalarValue (Number 1) employeeIdScalarType), + ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" employeeCityScalarType) (ScalarValue (String "Calgary") employeeCityScalarType) ] let query = albumsQueryRequest & qrQuery . qWhere ?~ where' receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -224,7 +224,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin it "can filter by comparing against rows in a related table" $ do let where' = Exists (RelatedTable _tdArtistRelationshipName) $ - ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "AC/DC") _tdStringType) + ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "AC/DC") artistNameScalarType) let query = albumsQueryRequest & qrTableRelationships .~ [Data.onlyKeepRelationships [_tdArtistRelationshipName] _tdAlbumsTableRelationships] @@ -247,7 +247,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin it "can filter by comparing against rows in a deeply related table" $ do let where' = Exists (RelatedTable _tdAlbumsRelationshipName) . Exists (RelatedTable _tdTracksRelationshipName) . Exists (RelatedTable _tdGenreRelationshipName) $ - ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "Metal") _tdStringType) + ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" genreNameScalarType) (ScalarValue (String "Metal") genreNameScalarType) let query = artistsQueryRequest & qrTableRelationships @@ -285,8 +285,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin let where' = Exists (RelatedTable _tdAlbumsRelationshipName) $ And - [ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 1) _tdIntType), - ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "Let There Be Rock") _tdStringType) + [ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 1) albumIdScalarType), + ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" albumTitleScalarType) (ScalarValue (String "Let There Be Rock") albumTitleScalarType) ] let query = artistsQueryRequest @@ -308,12 +308,20 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin where artistsQueryRequest :: QueryRequest artistsQueryRequest = - let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)] + let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")] query = Data.emptyQuery & qFields ?~ fields in QueryRequest _tdArtistsTableName [] query albumsQueryRequest :: QueryRequest albumsQueryRequest = - let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)] + let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")] query = Data.emptyQuery & qFields ?~ fields in QueryRequest _tdAlbumsTableName [] query + + albumIdScalarType = _tdFindColumnScalarType _tdAlbumsTableName "AlbumId" + albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title" + artistIdScalarType = _tdFindColumnScalarType _tdArtistsTableName "ArtistId" + artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name" + employeeIdScalarType = _tdFindColumnScalarType _tdEmployeesTableName "EmployeeId" + employeeCityScalarType = _tdFindColumnScalarType _tdEmployeesTableName "City" + genreNameScalarType = _tdFindColumnScalarType _tdGenresTableName "Name" diff --git a/server/lib/dc-api/test/Test/Specs/QuerySpec/OrderBySpec.hs b/server/lib/dc-api/test/Test/Specs/QuerySpec/OrderBySpec.hs index 830b9952a66..c3987ecc951 100644 --- a/server/lib/dc-api/test/Test/Specs/QuerySpec/OrderBySpec.hs +++ b/server/lib/dc-api/test/Test/Specs/QuerySpec/OrderBySpec.hs @@ -115,7 +115,7 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can order results by a column in a related table where the related table is filtered" $ do - let artistTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "N") _tdStringType) + let artistTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "N") artistNameScalarType) let orderByRelations = HashMap.fromList [(_tdArtistRelationshipName, OrderByRelation (Just artistTableFilter) mempty)] let orderBy = OrderBy orderByRelations $ @@ -285,7 +285,7 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q _qrAggregates receivedArtists `jsonShouldBe` Nothing it "can order results by an aggregate of a related table where the related table is filtered" $ do - let albumTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "N") _tdStringType) + let albumTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Title" albumTitleScalarType) (ScalarValue (String "N") albumTitleScalarType) let orderByRelations = HashMap.fromList [(_tdAlbumsRelationshipName, OrderByRelation (Just albumTableFilter) mempty)] let orderBy = OrderBy orderByRelations $ @@ -360,7 +360,7 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q where albumsQuery :: Query albumsQuery = - let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)] + let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")] in Data.emptyQuery & qFields ?~ fields albumsQueryRequest :: QueryRequest @@ -369,13 +369,13 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q artistsQueryRequest :: QueryRequest artistsQueryRequest = - let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)] + let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")] query = Data.emptyQuery & qFields ?~ fields in QueryRequest _tdArtistsTableName [] query tracksQuery :: Query tracksQuery = - let fields = Data.mkFieldsMap [("TrackId", _tdColumnField "TrackId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)] + let fields = Data.mkFieldsMap [("TrackId", _tdColumnField _tdTracksTableName "TrackId"), ("Name", _tdColumnField _tdTracksTableName "Name")] in Data.emptyQuery & qFields ?~ fields tracksQueryRequest :: QueryRequest @@ -384,10 +384,13 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q invoicesQueryRequest :: QueryRequest invoicesQueryRequest = - let fields = Data.mkFieldsMap [("InvoiceId", _tdColumnField "InvoiceId" _tdIntType), ("BillingState", _tdColumnField "BillingState" _tdStringType)] + let fields = Data.mkFieldsMap [("InvoiceId", _tdColumnField _tdInvoicesTableName "InvoiceId"), ("BillingState", _tdColumnField _tdInvoicesTableName "BillingState")] query = Data.emptyQuery & qFields ?~ fields in QueryRequest _tdInvoicesTableName [] query + albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title" + artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name" + data NullableOrdered a = NullFirst | Some a diff --git a/server/lib/dc-api/test/Test/Specs/QuerySpec/RelationshipsSpec.hs b/server/lib/dc-api/test/Test/Specs/QuerySpec/RelationshipsSpec.hs index b6f79f7b7bf..39baaeb5f0f 100644 --- a/server/lib/dc-api/test/Test/Specs/QuerySpec/RelationshipsSpec.hs +++ b/server/lib/dc-api/test/Test/Specs/QuerySpec/RelationshipsSpec.hs @@ -67,7 +67,7 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " _qrAggregates receivedArtists `jsonShouldBe` Nothing it "can filter in object relationships" $ do - let artistWhere = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "H") _tdStringType) + let artistWhere = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "H") artistNameScalarType) let query = albumsWithArtistQuery (qWhere ?~ artistWhere) receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query @@ -85,7 +85,7 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " _qrAggregates receivedAlbums `jsonShouldBe` Nothing it "can filter in array relationships" $ do - let albumsWhere = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "O") _tdStringType) + let albumsWhere = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "Title" albumTitleScalarType) (ScalarValue (String "O") albumTitleScalarType) let query = artistsWithAlbumsQuery (qWhere ?~ albumsWhere) receivedArtists <- Data.sortResponseRowsBy "ArtistId" <$> queryGuarded sourceName config query @@ -114,8 +114,8 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " Exists (RelatedTable _tdSupportRepRelationshipName) $ ApplyBinaryComparisonOperator Equal - (_tdCurrentComparisonColumn "Country" _tdStringType) - (AnotherColumn (_tdQueryComparisonColumn "Country" _tdStringType)) + (_tdCurrentComparisonColumn "Country" employeeCountryScalarType) + (AnotherColumn (_tdQueryComparisonColumn "Country" employeeCountryScalarType)) let query = customersWithSupportRepQuery id & qrQuery . qWhere ?~ where' receivedCustomers <- Data.sortResponseRowsBy "CustomerId" <$> queryGuarded sourceName config query @@ -142,8 +142,8 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " Exists (RelatedTable _tdSupportRepForCustomersRelationshipName) $ ApplyBinaryComparisonOperator Equal - (_tdCurrentComparisonColumn "Country" _tdStringType) - (AnotherColumn (_tdQueryComparisonColumn "Country" _tdStringType)) + (_tdCurrentComparisonColumn "Country" employeeCountryScalarType) + (AnotherColumn (_tdQueryComparisonColumn "Country" employeeCountryScalarType)) let query = employeesWithCustomersQuery id & qrQuery . qWhere ?~ where' receivedEmployees <- Data.sortResponseRowsBy "EmployeeId" <$> queryGuarded sourceName config query @@ -173,17 +173,17 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " And [ ( ApplyBinaryComparisonOperator GreaterThan - (_tdCurrentComparisonColumn "FirstName" _tdStringType) - (AnotherColumn (_tdCurrentComparisonColumn "LastName" _tdStringType)) + (_tdCurrentComparisonColumn "FirstName" employeeFirstNameScalarType) + (AnotherColumn (_tdCurrentComparisonColumn "LastName" employeeLastNameScalarType)) ), - (Not (ApplyUnaryComparisonOperator IsNull (_tdCurrentComparisonColumn "EmployeeId" _tdIntType))) + (Not (ApplyUnaryComparisonOperator IsNull (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType))) ] let employeesWhere = ApplyBinaryComparisonOperator GreaterThan - (_tdCurrentComparisonColumn "FirstName" _tdStringType) - (AnotherColumn (_tdCurrentComparisonColumn "LastName" _tdStringType)) + (_tdCurrentComparisonColumn "FirstName" employeeFirstNameScalarType) + (AnotherColumn (_tdCurrentComparisonColumn "LastName" employeeLastNameScalarType)) let query = customersWithSupportRepQuery (\q -> q & qWhere ?~ employeesWhere) & qrQuery . qWhere ?~ customersWhere receivedCustomers <- Data.sortResponseRowsBy "CustomerId" <$> queryGuarded sourceName config query @@ -211,8 +211,8 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " let artistsSubquery = modifySubquery artistsQuery fields = Data.mkFieldsMap - [ ("AlbumId", _tdColumnField "AlbumId" _tdIntType), - ("Title", _tdColumnField "Title" _tdStringType), + [ ("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), + ("Title", _tdColumnField _tdAlbumsTableName "Title"), ("Artist", RelField $ RelationshipField _tdArtistRelationshipName artistsSubquery) ] query = albumsQuery & qFields ?~ fields @@ -220,13 +220,13 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " artistsWithAlbumsQuery :: (Query -> Query) -> QueryRequest artistsWithAlbumsQuery modifySubquery = - let albumFields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)] + let albumFields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")] albumsSort = OrderBy mempty $ _tdOrderByColumn [] "AlbumId" Ascending :| [] albumsSubquery = albumsQuery & qFields ?~ albumFields & qOrderBy ?~ albumsSort & modifySubquery fields = Data.mkFieldsMap - [ ("ArtistId", _tdColumnField "ArtistId" _tdIntType), - ("Name", _tdColumnField "Name" _tdStringType), + [ ("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), + ("Name", _tdColumnField _tdArtistsTableName "Name"), ("Albums", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery) ] query = artistsQuery & qFields ?~ fields @@ -257,23 +257,23 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " artistsQuery :: Query artistsQuery = - let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)] + let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")] in Data.emptyQuery & qFields ?~ fields albumsQuery :: Query albumsQuery = - let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)] + let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")] in Data.emptyQuery & qFields ?~ fields customersQuery :: Query customersQuery = let fields = Data.mkFieldsMap - [ ("CustomerId", _tdColumnField "CustomerId" _tdIntType), - ("FirstName", _tdColumnField "FirstName" _tdStringType), - ("LastName", _tdColumnField "LastName" _tdStringType), - ("Country", _tdColumnField "Country" _tdStringType), - ("SupportRepId", _tdColumnField "SupportRepId" _tdIntType) + [ ("CustomerId", _tdColumnField _tdCustomersTableName "CustomerId"), + ("FirstName", _tdColumnField _tdCustomersTableName "FirstName"), + ("LastName", _tdColumnField _tdCustomersTableName "LastName"), + ("Country", _tdColumnField _tdCustomersTableName "Country"), + ("SupportRepId", _tdColumnField _tdCustomersTableName "SupportRepId") ] in Data.emptyQuery & qFields ?~ fields @@ -281,10 +281,10 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " employeesQuery = let fields = Data.mkFieldsMap - [ ("EmployeeId", _tdColumnField "EmployeeId" _tdIntType), - ("FirstName", _tdColumnField "FirstName" _tdStringType), - ("LastName", _tdColumnField "LastName" _tdStringType), - ("Country", _tdColumnField "Country" _tdStringType) + [ ("EmployeeId", _tdColumnField _tdEmployeesTableName "EmployeeId"), + ("FirstName", _tdColumnField _tdEmployeesTableName "FirstName"), + ("LastName", _tdColumnField _tdEmployeesTableName "LastName"), + ("Country", _tdColumnField _tdEmployeesTableName "Country") ] in Data.emptyQuery & qFields ?~ fields @@ -294,3 +294,10 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe " subqueryRows :: Traversal' FieldValue (HashMap FieldName FieldValue) subqueryRows = _RelationshipFieldValue . qrRows . _Just . traverse + + albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title" + artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name" + employeeIdScalarType = _tdFindColumnScalarType _tdEmployeesTableName "EmployeeId" + employeeCountryScalarType = _tdFindColumnScalarType _tdEmployeesTableName "Country" + employeeFirstNameScalarType = _tdFindColumnScalarType _tdEmployeesTableName "FirstName" + employeeLastNameScalarType = _tdFindColumnScalarType _tdEmployeesTableName "LastName" diff --git a/server/lib/test-harness/src/Harness/Backend/DataConnector/Chinook/Reference.hs b/server/lib/test-harness/src/Harness/Backend/DataConnector/Chinook/Reference.hs index a1ff19c984f..d37b20d1ddf 100644 --- a/server/lib/test-harness/src/Harness/Backend/DataConnector/Chinook/Reference.hs +++ b/server/lib/test-harness/src/Harness/Backend/DataConnector/Chinook/Reference.hs @@ -44,9 +44,23 @@ backendTypeMetadata = max: DateTime min: DateTime graphql_type: String + number: + aggregate_functions: + max: number + min: number + stddev: number + stddev_pop: number + stddev_samp: number + sum: number + var_pop: number + var_samp: number + variance: number + graphql_type: Float string: aggregate_functions: longest: string + max: string + min: string shortest: string graphql_type: String |], diff --git a/server/lib/test-harness/src/Harness/Backend/DataConnector/Chinook/Sqlite.hs b/server/lib/test-harness/src/Harness/Backend/DataConnector/Chinook/Sqlite.hs index 2de3fecef1a..3cd93b0637e 100644 --- a/server/lib/test-harness/src/Harness/Backend/DataConnector/Chinook/Sqlite.hs +++ b/server/lib/test-harness/src/Harness/Backend/DataConnector/Chinook/Sqlite.hs @@ -51,15 +51,22 @@ backendTypeMetadata = _lt: string _lte: string _neq: string + aggregate_functions: + min: string + max: string decimal: comparison_operators: - _modulus_is_zero: number - _eq: number - _gt: number - _gte: number - _lt: number - _lte: number - _neq: number + _modulus_is_zero: decimal + _eq: decimal + _gt: decimal + _gte: decimal + _lt: decimal + _lte: decimal + _neq: decimal + aggregate_functions: + min: decimal + max: decimal + sum: decimal number: comparison_operators: _modulus_is_zero: number @@ -69,6 +76,10 @@ backendTypeMetadata = _lt: number _lte: number _neq: number + aggregate_functions: + min: number + max: number + sum: number bool: comparison_operators: _and: bool diff --git a/server/lib/test-harness/src/Harness/Backend/DataConnector/Mock/Server.hs b/server/lib/test-harness/src/Harness/Backend/DataConnector/Mock/Server.hs index af832f45f3e..c7672752737 100644 --- a/server/lib/test-harness/src/Harness/Backend/DataConnector/Mock/Server.hs +++ b/server/lib/test-harness/src/Harness/Backend/DataConnector/Mock/Server.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE QuasiQuotes #-} + -- | Mock Agent Warp server backend module Harness.Backend.DataConnector.Mock.Server ( MockConfig (..), @@ -15,6 +17,7 @@ import Data.Proxy import Data.SOP.BasicFunctors qualified as SOP import Hasura.Backends.DataConnector.API qualified as API import Hasura.Prelude +import Language.GraphQL.Draft.Syntax.QQ qualified as G import Network.Wai.Handler.Warp qualified as Warp import Servant @@ -79,15 +82,27 @@ capabilities = scalarTypesCapabilities = API.ScalarTypesCapabilities $ HashMap.fromList - [ mkScalarTypeCapability "MyInt" $ Just API.GraphQLInt, - mkScalarTypeCapability "MyFloat" $ Just API.GraphQLFloat, - mkScalarTypeCapability "MyString" $ Just API.GraphQLString, - mkScalarTypeCapability "MyBoolean" $ Just API.GraphQLBoolean, - mkScalarTypeCapability "MyID" $ Just API.GraphQLID, - mkScalarTypeCapability "MyAnything" $ Nothing + [ mkScalarTypeCapability "number" minMaxFunctions $ Just API.GraphQLFloat, + mkScalarTypeCapability "string" minMaxFunctions $ Just API.GraphQLString, + mkScalarTypeCapability "MyInt" mempty $ Just API.GraphQLInt, + mkScalarTypeCapability "MyFloat" mempty $ Just API.GraphQLFloat, + mkScalarTypeCapability "MyString" mempty $ Just API.GraphQLString, + mkScalarTypeCapability "MyBoolean" mempty $ Just API.GraphQLBoolean, + mkScalarTypeCapability "MyID" mempty $ Just API.GraphQLID, + mkScalarTypeCapability "MyAnything" mempty Nothing ] - mkScalarTypeCapability :: Text -> Maybe API.GraphQLType -> (API.ScalarType, API.ScalarTypeCapabilities) - mkScalarTypeCapability name gqlType = (API.CustomTy name, mempty {API._stcGraphQLType = gqlType}) + mkScalarTypeCapability :: Text -> (API.ScalarType -> API.AggregateFunctions) -> Maybe API.GraphQLType -> (API.ScalarType, API.ScalarTypeCapabilities) + mkScalarTypeCapability name aggregateFunctions gqlType = + (scalarType, API.ScalarTypeCapabilities mempty (aggregateFunctions scalarType) gqlType) + where + scalarType = API.ScalarType name + + minMaxFunctions :: API.ScalarType -> API.AggregateFunctions + minMaxFunctions resultType = + API.AggregateFunctions $ + HashMap.fromList $ + (,resultType) + <$> [[G.name|min|], [G.name|max|]] -- | Stock Schema for a Chinook Agent schema :: API.SchemaResponse @@ -100,7 +115,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "ArtistId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Artist primary key identifier", API._ciInsertable = True, @@ -108,7 +123,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Name", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The name of the artist", API._ciInsertable = True, @@ -128,7 +143,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "AlbumId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Album primary key identifier", API._ciInsertable = True, @@ -136,7 +151,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Title", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = False, API._ciDescription = Just "The title of the album", API._ciInsertable = True, @@ -144,7 +159,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "ArtistId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "The ID of the artist that created the album", API._ciInsertable = True, @@ -166,7 +181,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "CustomerId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Customer primary key identifier", API._ciInsertable = True, @@ -174,7 +189,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "FirstName", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = False, API._ciDescription = Just "The customer's first name", API._ciInsertable = True, @@ -182,7 +197,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "LastName", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = False, API._ciDescription = Just "The customer's last name", API._ciInsertable = True, @@ -190,7 +205,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Company", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The customer's company name", API._ciInsertable = True, @@ -198,7 +213,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Address", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The customer's address line (street number, street)", API._ciInsertable = True, @@ -206,7 +221,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "City", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The customer's address city", API._ciInsertable = True, @@ -214,7 +229,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "State", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The customer's address state", API._ciInsertable = True, @@ -222,7 +237,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Country", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The customer's address country", API._ciInsertable = True, @@ -230,7 +245,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "PostalCode", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The customer's address postal code", API._ciInsertable = True, @@ -238,7 +253,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Phone", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The customer's phone number", API._ciInsertable = True, @@ -246,7 +261,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Fax", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The customer's fax number", API._ciInsertable = True, @@ -254,7 +269,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Email", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = False, API._ciDescription = Just "The customer's email address", API._ciInsertable = True, @@ -262,7 +277,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "SupportRepId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = True, API._ciDescription = Just "The ID of the Employee who is this customer's support representative", API._ciInsertable = True, @@ -284,7 +299,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "EmployeeId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Employee primary key identifier", API._ciInsertable = True, @@ -292,7 +307,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "LastName", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = False, API._ciDescription = Just "The employee's last name", API._ciInsertable = True, @@ -300,7 +315,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "FirstName", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = False, API._ciDescription = Just "The employee's first name", API._ciInsertable = True, @@ -308,7 +323,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Title", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's job title", API._ciInsertable = True, @@ -316,7 +331,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "ReportsTo", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = True, API._ciDescription = Just "The employee's report", API._ciInsertable = True, @@ -324,7 +339,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "BirthDate", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's birth date", API._ciInsertable = True, @@ -332,7 +347,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "HireDate", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's hire date", API._ciInsertable = True, @@ -340,7 +355,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Address", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's address line (street number, street)", API._ciInsertable = True, @@ -348,7 +363,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "City", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's address city", API._ciInsertable = True, @@ -356,7 +371,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "State", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's address state", API._ciInsertable = True, @@ -364,7 +379,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Country", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's address country", API._ciInsertable = True, @@ -372,7 +387,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "PostalCode", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's address postal code", API._ciInsertable = True, @@ -380,7 +395,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Phone", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's phone number", API._ciInsertable = True, @@ -388,7 +403,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Fax", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's fax number", API._ciInsertable = True, @@ -396,7 +411,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Email", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The employee's email address", API._ciInsertable = True, @@ -418,7 +433,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "GenreId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Genre primary key identifier", API._ciInsertable = True, @@ -426,7 +441,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Name", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The name of the genre", API._ciInsertable = True, @@ -446,7 +461,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "InvoiceId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Invoice primary key identifier", API._ciInsertable = True, @@ -454,7 +469,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "CustomerId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "ID of the customer who bought the music", API._ciInsertable = True, @@ -462,7 +477,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "InvoiceDate", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = False, API._ciDescription = Just "Date of the invoice", API._ciInsertable = True, @@ -470,7 +485,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "BillingAddress", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The invoice's billing address line (street number, street)", API._ciInsertable = True, @@ -478,7 +493,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "BillingCity", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The invoice's billing address city", API._ciInsertable = True, @@ -486,7 +501,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "BillingState", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The invoice's billing address state", API._ciInsertable = True, @@ -494,7 +509,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "BillingCountry", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The invoice's billing address country", API._ciInsertable = True, @@ -502,7 +517,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "BillingPostalCode", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The invoice's billing address postal code", API._ciInsertable = True, @@ -510,7 +525,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Total", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "The total amount due on the invoice", API._ciInsertable = True, @@ -533,7 +548,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "InvoiceLineId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Invoice Line primary key identifier", API._ciInsertable = True, @@ -541,7 +556,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "InvoiceId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "ID of the invoice the line belongs to", API._ciInsertable = True, @@ -549,7 +564,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "TrackId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "ID of the music track being purchased", API._ciInsertable = True, @@ -557,7 +572,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "UnitPrice", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Price of each individual track unit", API._ciInsertable = True, @@ -565,7 +580,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Quantity", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Quantity of the track purchased", API._ciInsertable = True, @@ -590,7 +605,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "MediaTypeId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "Media Type primary key identifier", API._ciInsertable = True, @@ -598,7 +613,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Name", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The name of the media type format", API._ciInsertable = True, @@ -618,7 +633,7 @@ schema = API._tiColumns = [ API.ColumnInfo { API._ciName = API.ColumnName "TrackId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "The ID of the track", API._ciInsertable = True, @@ -626,7 +641,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Name", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = False, API._ciDescription = Just "The name of the track", API._ciInsertable = True, @@ -634,7 +649,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "AlbumId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = True, API._ciDescription = Just "The ID of the album the track belongs to", API._ciInsertable = True, @@ -642,7 +657,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "MediaTypeId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "The ID of the media type the track is encoded with", API._ciInsertable = True, @@ -650,7 +665,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "GenreId", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = True, API._ciDescription = Just "The ID of the genre of the track", API._ciInsertable = True, @@ -658,7 +673,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Composer", - API._ciType = API.StringTy, + API._ciType = API.ScalarType "string", API._ciNullable = True, API._ciDescription = Just "The name of the composer of the track", API._ciInsertable = True, @@ -666,7 +681,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Milliseconds", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "The length of the track in milliseconds", API._ciInsertable = True, @@ -674,7 +689,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "Bytes", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = True, API._ciDescription = Just "The size of the track in bytes", API._ciInsertable = True, @@ -682,7 +697,7 @@ schema = }, API.ColumnInfo { API._ciName = API.ColumnName "UnitPrice", - API._ciType = API.NumberTy, + API._ciType = API.ScalarType "number", API._ciNullable = False, API._ciDescription = Just "The price of the track", API._ciInsertable = True, @@ -706,12 +721,12 @@ schema = { API._tiName = mkTableName "MyCustomScalarsTable", API._tiType = API.Table, API._tiColumns = - [ API.ColumnInfo (API.ColumnName "MyIntColumn") (API.CustomTy "MyInt") False Nothing True True, - API.ColumnInfo (API.ColumnName "MyFloatColumn") (API.CustomTy "MyFloat") False Nothing True True, - API.ColumnInfo (API.ColumnName "MyStringColumn") (API.CustomTy "MyString") False Nothing True True, - API.ColumnInfo (API.ColumnName "MyBooleanColumn") (API.CustomTy "MyBoolean") False Nothing True True, - API.ColumnInfo (API.ColumnName "MyIDColumn") (API.CustomTy "MyID") False Nothing True True, - API.ColumnInfo (API.ColumnName "MyAnythingColumn") (API.CustomTy "MyAnything") False Nothing True True + [ API.ColumnInfo (API.ColumnName "MyIntColumn") (API.ScalarType "MyInt") False Nothing True True, + API.ColumnInfo (API.ColumnName "MyFloatColumn") (API.ScalarType "MyFloat") False Nothing True True, + API.ColumnInfo (API.ColumnName "MyStringColumn") (API.ScalarType "MyString") False Nothing True True, + API.ColumnInfo (API.ColumnName "MyBooleanColumn") (API.ScalarType "MyBoolean") False Nothing True True, + API.ColumnInfo (API.ColumnName "MyIDColumn") (API.ScalarType "MyID") False Nothing True True, + API.ColumnInfo (API.ColumnName "MyAnythingColumn") (API.ScalarType "MyAnything") False Nothing True True ], API._tiPrimaryKey = [], API._tiDescription = Nothing, diff --git a/server/lib/test-harness/test-harness.cabal b/server/lib/test-harness/test-harness.cabal index 1618eed65d9..c66226dd6bf 100644 --- a/server/lib/test-harness/test-harness.cabal +++ b/server/lib/test-harness/test-harness.cabal @@ -19,6 +19,7 @@ library , ekg-core , fast-logger , graphql-engine + , graphql-parser , haskell-src-meta , hasura-prelude , hedgehog diff --git a/server/src-lib/Hasura/Backends/DataConnector/Adapter/Backend.hs b/server/src-lib/Hasura/Backends/DataConnector/Adapter/Backend.hs index 789addd25ff..d771c0a824e 100644 --- a/server/src-lib/Hasura/Backends/DataConnector/Adapter/Backend.hs +++ b/server/src-lib/Hasura/Backends/DataConnector/Adapter/Backend.hs @@ -82,15 +82,10 @@ instance Backend 'DataConnector where type HealthCheckTest 'DataConnector = Void isComparableType :: ScalarType 'DataConnector -> Bool - isComparableType = \case - DC.NumberTy -> True - DC.StringTy -> True - DC.BoolTy -> False - DC.CustomTy _ _ -> False + isComparableType = const False isNumType :: ScalarType 'DataConnector -> Bool - isNumType DC.NumberTy = True - isNumType _ = False + isNumType = const False getCustomAggregateOperators :: DC.SourceConfig -> HashMap G.Name (HashMap DC.ScalarType DC.ScalarType) getCustomAggregateOperators DC.SourceConfig {..} = @@ -180,10 +175,7 @@ parseValue :: DC.ScalarType -> J.Value -> J.Parser J.Value parseValue type' val = case (type', val) of (_, J.Null) -> pure J.Null - (DC.StringTy, value) -> J.String <$> J.parseJSON value - (DC.BoolTy, value) -> J.Bool <$> J.parseJSON value - (DC.NumberTy, value) -> J.Number <$> J.parseJSON value - (DC.CustomTy _ graphQLType, value) -> case graphQLType of + (DC.ScalarType _ graphQLType, value) -> case graphQLType of Nothing -> pure value Just DC.GraphQLInt -> (J.Number . fromIntegral) <$> J.parseJSON @Int value Just DC.GraphQLFloat -> (J.Number . fromFloatDigits) <$> J.parseJSON @Double value @@ -196,4 +188,7 @@ parseValue type' val = columnTypeToScalarType :: ColumnType 'DataConnector -> DC.ScalarType columnTypeToScalarType = \case ColumnScalar scalarType -> scalarType - ColumnEnumReference _ -> DC.StringTy + -- Data connectors does not yet support enum tables. + -- If/when we add this support, we probably want to + -- embed the enum scalar type name within the `EnumReference` record type + ColumnEnumReference _ -> error "columnTypeToScalarType got enum" diff --git a/server/src-lib/Hasura/Backends/DataConnector/Adapter/Metadata.hs b/server/src-lib/Hasura/Backends/DataConnector/Adapter/Metadata.hs index ee5f431d045..a7b86d64a47 100644 --- a/server/src-lib/Hasura/Backends/DataConnector/Adapter/Metadata.hs +++ b/server/src-lib/Hasura/Backends/DataConnector/Adapter/Metadata.hs @@ -64,7 +64,11 @@ instance BackendMetadata 'DataConnector where parseBoolExpOperations = parseBoolExpOperations' parseCollectableType = parseCollectableType' buildComputedFieldInfo = error "buildComputedFieldInfo: not implemented for the Data Connector backend." + + -- If/when we implement enums for Data Connector backend, we will also need to fix columnTypeToScalarType function + -- in Hasura.Backends.DataConnector.Adapter.Backend. See note there for more information. fetchAndValidateEnumValues = error "fetchAndValidateEnumValues: not implemented for the Data Connector backend." + buildFunctionInfo = error "buildFunctionInfo: not implemented for the Data Connector backend." updateColumnInEventTrigger = error "updateColumnInEventTrigger: not implemented for the Data Connector backend." postDropSourceHook _sourceConfig _tableTriggerMap = pure () diff --git a/server/src-lib/Hasura/Backends/DataConnector/Adapter/Schema.hs b/server/src-lib/Hasura/Backends/DataConnector/Adapter/Schema.hs index 2a0691d7235..65404843a10 100644 --- a/server/src-lib/Hasura/Backends/DataConnector/Adapter/Schema.hs +++ b/server/src-lib/Hasura/Backends/DataConnector/Adapter/Schema.hs @@ -76,7 +76,13 @@ instance BackendSchema 'DataConnector where comparisonExps = comparisonExps' countTypeInput = countTypeInput' - aggregateOrderByCountType = DC.NumberTy + + -- aggregateOrderByCountType is only used when generating Relay schemas, and Data Connector backends do not yet support Relay + -- If/when we want to support this we would need to add something to Capabilities to tell HGE what (integer-like) scalar + -- type should be used to represent the result of a count aggregate in relay order-by queries. + aggregateOrderByCountType = + error "aggregateOrderByCountType: not implemented for Data Connector backend" + computedField = error "computedField: not implemented for the Data Connector backend." @@ -173,24 +179,20 @@ columnParser' :: GQL.Nullability -> GS.C.SchemaT r m (P.Parser 'P.Both n (IR.ValueWithOrigin (RQL.ColumnValue 'DataConnector))) columnParser' columnType nullability = case columnType of - RQL.ColumnScalar scalarType -> + RQL.ColumnScalar scalarType@(DC.ScalarType name graphQLType) -> P.memoizeOn 'columnParser' (scalarType, nullability) $ GS.C.peelWithOrigin . fmap (RQL.ColumnValue columnType) . possiblyNullable' scalarType nullability - <$> case scalarType of - DC.StringTy -> pure $ J.String <$> P.string - DC.NumberTy -> pure $ J.Number <$> P.scientific - DC.BoolTy -> pure $ J.Bool <$> P.boolean - DC.CustomTy name graphQLType -> do - gqlName <- - GQL.mkName name - `onNothing` throw400 ValidationFailed ("The column type name " <> name <<> " is not a valid GraphQL name") - pure $ case graphQLType of - Nothing -> P.jsonScalar gqlName (Just "A custom scalar type") - Just DC.GraphQLInt -> (J.Number . fromIntegral) <$> P.namedInt gqlName - Just DC.GraphQLFloat -> (J.Number . fromFloatDigits) <$> P.namedFloat gqlName - Just DC.GraphQLString -> J.String <$> P.namedString gqlName - Just DC.GraphQLBoolean -> J.Bool <$> P.namedBoolean gqlName - Just DC.GraphQLID -> J.String <$> P.namedIdentifier gqlName + <$> do + gqlName <- + GQL.mkName name + `onNothing` throw400 ValidationFailed ("The column type name " <> name <<> " is not a valid GraphQL name") + pure $ case graphQLType of + Nothing -> P.jsonScalar gqlName (Just "A custom scalar type") + Just DC.GraphQLInt -> (J.Number . fromIntegral) <$> P.namedInt gqlName + Just DC.GraphQLFloat -> (J.Number . fromFloatDigits) <$> P.namedFloat gqlName + Just DC.GraphQLString -> J.String <$> P.namedString gqlName + Just DC.GraphQLBoolean -> J.Bool <$> P.namedBoolean gqlName + Just DC.GraphQLID -> J.String <$> P.namedIdentifier gqlName RQL.ColumnEnumReference (RQL.EnumReference tableName enumValues customTableName) -> case nonEmpty (Map.toList enumValues) of Just enumValuesList -> diff --git a/server/src-lib/Hasura/Backends/DataConnector/Adapter/Types.hs b/server/src-lib/Hasura/Backends/DataConnector/Adapter/Types.hs index c446614052c..f0029638a1d 100644 --- a/server/src-lib/Hasura/Backends/DataConnector/Adapter/Types.hs +++ b/server/src-lib/Hasura/Backends/DataConnector/Adapter/Types.hs @@ -48,7 +48,6 @@ import Data.Text.NonEmpty (NonEmptyText, mkNonEmptyTextUnsafe) import Hasura.Backends.DataConnector.API qualified as API import Hasura.Base.ErrorValue qualified as ErrorValue import Hasura.Base.ToErrorValue (ToErrorValue (..)) -import Hasura.GraphQL.Parser.Name.TypeSystem (_Boolean, _Float, _Int, _String) import Hasura.Metadata.DTO.Placeholder (placeholderCodecViaJSON) import Hasura.Prelude import Language.GraphQL.Draft.Syntax qualified as GQL @@ -329,43 +328,28 @@ instance Witch.From OrderDirection API.OrderDirection where -------------------------------------------------------------------------------- data ScalarType - = StringTy - | NumberTy - | BoolTy - | CustomTy Text (Maybe API.GraphQLType) + = ScalarType Text (Maybe API.GraphQLType) deriving stock (Eq, Generic, Ord, Show) deriving anyclass (FromJSON, FromJSONKey, Hashable, NFData, ToJSON, ToJSONKey) instance ToTxt ScalarType where - toTxt = tshow + toTxt (ScalarType name _) = name instance ToErrorValue ScalarType where - toErrorValue = ErrorValue.squote . tshow + toErrorValue = ErrorValue.squote . toTxt instance Witch.From ScalarType API.ScalarType where - from = \case - StringTy -> API.StringTy - NumberTy -> API.NumberTy - BoolTy -> API.BoolTy - CustomTy name _ -> API.CustomTy name + from (ScalarType name _) = API.ScalarType name mkScalarType :: API.Capabilities -> API.ScalarType -> ScalarType -mkScalarType API.Capabilities {..} apiType = case apiType of - API.StringTy -> StringTy - API.NumberTy -> NumberTy - API.BoolTy -> BoolTy - API.CustomTy name -> CustomTy name graphQLType - where - graphQLType = HashMap.lookup apiType (API.unScalarTypesCapabilities _cScalarTypes) >>= API._stcGraphQLType +mkScalarType API.Capabilities {..} apiType@(API.ScalarType name) = + ScalarType name graphQLType + where + graphQLType = HashMap.lookup apiType (API.unScalarTypesCapabilities _cScalarTypes) >>= API._stcGraphQLType fromGQLType :: GQL.Name -> API.ScalarType fromGQLType typeName = - if - | typeName == _String -> API.StringTy - | typeName == _Int -> API.NumberTy - | typeName == _Float -> API.NumberTy - | typeName == _Boolean -> API.BoolTy - | otherwise -> API.CustomTy $ GQL.unName typeName + API.ScalarType $ GQL.unName typeName -------------------------------------------------------------------------------- diff --git a/server/src-lib/Hasura/Backends/DataConnector/Plan.hs b/server/src-lib/Hasura/Backends/DataConnector/Plan.hs index 277c9644787..9be2c5185a7 100644 --- a/server/src-lib/Hasura/Backends/DataConnector/Plan.hs +++ b/server/src-lib/Hasura/Backends/DataConnector/Plan.hs @@ -436,28 +436,15 @@ mkPlan session (SourceConfig {}) ir = do parseSessionVariable :: SessionVariable -> SessionVarType 'DataConnector -> Text -> m Literal parseSessionVariable varName varType varValue = do case varType of - CollectableTypeScalar scalarType -> - case scalarType of - -- Special case for string: uses literal session variable value rather than trying to parse a JSON string - StringTy -> pure . ValueLiteral scalarType $ J.String varValue - NumberTy -> parseBuiltinValue (ValueLiteral scalarType . J.Number) "number value" - BoolTy -> parseBuiltinValue (ValueLiteral scalarType . J.Bool) "boolean value" - CustomTy customTypeName _ -> parseCustomValue scalarType (customTypeName <> " JSON value") - CollectableTypeArray scalarType -> - case scalarType of - StringTy -> parseBuiltinValue (ArrayLiteral scalarType . fmap J.String) "JSON array of strings" - NumberTy -> parseBuiltinValue (ArrayLiteral scalarType . fmap J.Number) "JSON array of numbers" - BoolTy -> parseBuiltinValue (ArrayLiteral scalarType . fmap J.Bool) "JSON array of booleans" - CustomTy customTypeName _ -> parseCustomArray scalarType ("JSON array of " <> customTypeName <> " JSON values") + CollectableTypeScalar scalarType@(ScalarType customTypeName _) -> + parseCustomValue scalarType (customTypeName <> " JSON value") + CollectableTypeArray scalarType@(ScalarType customTypeName _) -> + parseCustomArray scalarType ("JSON array of " <> customTypeName <> " JSON values") where - parseBuiltinValue :: J.FromJSON a => (a -> Literal) -> Text -> m Literal - parseBuiltinValue = - parseValue' J.parseJSON - parseCustomValue :: ScalarType -> Text -> m Literal parseCustomValue scalarType description = case scalarType of - CustomTy _ (Just GraphQLString) -> + ScalarType _ (Just GraphQLString) -> -- Special case for string: uses literal session variable value rather than trying to parse a JSON string pure . ValueLiteral scalarType $ J.String varValue _ -> diff --git a/server/src-test/Hasura/Backends/DataConnector/API/V0/CapabilitiesSpec.hs b/server/src-test/Hasura/Backends/DataConnector/API/V0/CapabilitiesSpec.hs index 6a6d890f3cf..4275bdbd289 100644 --- a/server/src-test/Hasura/Backends/DataConnector/API/V0/CapabilitiesSpec.hs +++ b/server/src-test/Hasura/Backends/DataConnector/API/V0/CapabilitiesSpec.hs @@ -27,11 +27,11 @@ spec = do (CapabilitiesResponse (defaultCapabilities {_cRelationships = Just RelationshipCapabilities {}}) emptyConfigSchemaResponse Nothing Nothing) [aesonQQ|{"capabilities": {"relationships": {}}, "config_schemas": {"config_schema": {}, "other_schemas": {}}}|] describe "ScalarTypesCapabilities" $ do - testToFromJSONToSchema (ScalarTypesCapabilities (HashMap.singleton StringTy (ScalarTypeCapabilities mempty mempty Nothing))) [aesonQQ|{"string": {}}|] + testToFromJSONToSchema (ScalarTypesCapabilities (HashMap.singleton (ScalarType "string") (ScalarTypeCapabilities mempty mempty Nothing))) [aesonQQ|{"string": {}}|] jsonOpenApiProperties genScalarTypesCapabilities describe "ScalarTypeCapabilities" $ do - let comparisonOperators = ComparisonOperators $ HashMap.fromList [([G.name|same_day_as|], CustomTy "DateTime")] - let aggregateFunctions = AggregateFunctions $ HashMap.fromList [([G.name|max|], CustomTy "DateTime")] + let comparisonOperators = ComparisonOperators $ HashMap.fromList [([G.name|same_day_as|], ScalarType "DateTime")] + let aggregateFunctions = AggregateFunctions $ HashMap.fromList [([G.name|max|], ScalarType "DateTime")] let graphQLType = Just GraphQLString let json = [aesonQQ|{ diff --git a/server/src-test/Hasura/Backends/DataConnector/API/V0/ColumnSpec.hs b/server/src-test/Hasura/Backends/DataConnector/API/V0/ColumnSpec.hs index f0595654e29..2e7fa2e1b1f 100644 --- a/server/src-test/Hasura/Backends/DataConnector/API/V0/ColumnSpec.hs +++ b/server/src-test/Hasura/Backends/DataConnector/API/V0/ColumnSpec.hs @@ -21,7 +21,7 @@ spec = do describe "ColumnInfo" $ do describe "minimal" $ testFromJSON - (ColumnInfo (ColumnName "my_column_name") StringTy False Nothing False False) + (ColumnInfo (ColumnName "my_column_name") (ScalarType "string") False Nothing False False) [aesonQQ| { "name": "my_column_name", "type": "string", @@ -30,7 +30,7 @@ spec = do |] describe "non-minimal" $ testToFromJSONToSchema - (ColumnInfo (ColumnName "my_column_name") NumberTy True (Just "My column description") True True) + (ColumnInfo (ColumnName "my_column_name") (ScalarType "number") True (Just "My column description") True True) [aesonQQ| { "name": "my_column_name", "type": "number", diff --git a/server/src-test/Hasura/Backends/DataConnector/API/V0/ExpressionSpec.hs b/server/src-test/Hasura/Backends/DataConnector/API/V0/ExpressionSpec.hs index e37b37ba189..d2ccc86bc82 100644 --- a/server/src-test/Hasura/Backends/DataConnector/API/V0/ExpressionSpec.hs +++ b/server/src-test/Hasura/Backends/DataConnector/API/V0/ExpressionSpec.hs @@ -68,7 +68,7 @@ spec = do describe "ComparisonColumn" $ do testToFromJSONToSchema - (ComparisonColumn QueryTable (ColumnName "column_name") StringTy) + (ComparisonColumn QueryTable (ColumnName "column_name") (ScalarType "string")) [aesonQQ|{"path": ["$"], "name": "column_name", "column_type": "string"}|] jsonOpenApiProperties genComparisonColumn @@ -83,11 +83,11 @@ spec = do describe "ComparisonValue" $ do describe "AnotherColumn" $ testToFromJSONToSchema - (AnotherColumn $ ComparisonColumn CurrentTable (ColumnName "my_column_name") StringTy) + (AnotherColumn $ ComparisonColumn CurrentTable (ColumnName "my_column_name") (ScalarType "string")) [aesonQQ|{"type": "column", "column": {"name": "my_column_name", "column_type": "string"}}|] describe "ScalarValue" $ testToFromJSONToSchema - (ScalarValue (String "scalar value") StringTy) + (ScalarValue (String "scalar value") (ScalarType "string")) [aesonQQ|{"type": "scalar", "value": "scalar value", "value_type": "string"}|] jsonOpenApiProperties genComparisonValue @@ -112,8 +112,8 @@ spec = do jsonOpenApiProperties genExistsInTable describe "Expression" $ do - let comparisonColumn = ComparisonColumn CurrentTable (ColumnName "my_column_name") StringTy - let scalarValue = ScalarValue (String "scalar value") StringTy + let comparisonColumn = ComparisonColumn CurrentTable (ColumnName "my_column_name") (ScalarType "string") + let scalarValue = ScalarValue (String "scalar value") (ScalarType "string") let scalarValues = [String "scalar value"] let unaryComparisonExpression = ApplyUnaryComparisonOperator IsNull comparisonColumn @@ -195,7 +195,7 @@ spec = do describe "BinaryArrayComparisonOperator" $ do testToFromJSONToSchema - (ApplyBinaryArrayComparisonOperator In comparisonColumn scalarValues StringTy) + (ApplyBinaryArrayComparisonOperator In comparisonColumn scalarValues (ScalarType "string")) [aesonQQ| { "type": "binary_arr_op", diff --git a/server/src-test/Hasura/Backends/DataConnector/API/V0/MutationsSpec.hs b/server/src-test/Hasura/Backends/DataConnector/API/V0/MutationsSpec.hs index 9cb5cfa705a..38a9c7d52de 100644 --- a/server/src-test/Hasura/Backends/DataConnector/API/V0/MutationsSpec.hs +++ b/server/src-test/Hasura/Backends/DataConnector/API/V0/MutationsSpec.hs @@ -46,7 +46,7 @@ spec = do describe "InsertFieldSchema" $ do describe "ColumnInsert" $ do testToFromJSONToSchema - (ColumnInsert (ColumnInsertSchema (ColumnName "my_column") NumberTy)) + (ColumnInsert (ColumnInsertSchema (ColumnName "my_column") (ScalarType "number"))) [aesonQQ| { "type": "column", "column": "my_column", @@ -70,7 +70,7 @@ spec = do jsonOpenApiProperties genInsertFieldSchema describe "MutationOperation" $ do - let returningFields = [(FieldName "field", ColumnField (ColumnName "my_column") StringTy)] + let returningFields = [(FieldName "field", ColumnField (ColumnName "my_column") (ScalarType "string"))] describe "InsertOperation" $ do testToFromJSONToSchema (InsertOperation (InsertMutationOperation (TableName ["my_table"]) [] returningFields)) @@ -172,7 +172,7 @@ spec = do describe "RowUpdate" $ do describe "IncrementColumnRowUpdate" $ testToFromJSONToSchema - (IncrementColumn $ RowColumnValue (ColumnName "my_column") (Number 10) NumberTy) + (IncrementColumn $ RowColumnValue (ColumnName "my_column") (Number 10) (ScalarType "number")) [aesonQQ| { "type": "increment", "column": "my_column", @@ -181,7 +181,7 @@ spec = do |] describe "SetColumnRowUpdate" $ testToFromJSONToSchema - (SetColumn $ RowColumnValue (ColumnName "my_column") (Number 10) NumberTy) + (SetColumn $ RowColumnValue (ColumnName "my_column") (Number 10) (ScalarType "number")) [aesonQQ| { "type": "set", "column": "my_column", @@ -192,7 +192,7 @@ spec = do describe "RowColumnValue" $ do testToFromJSONToSchema - (RowColumnValue (ColumnName "my_column") (String "a value") StringTy) + (RowColumnValue (ColumnName "my_column") (String "a value") (ScalarType "string")) [aesonQQ| { "column": "my_column", "value": "a value", diff --git a/server/src-test/Hasura/Backends/DataConnector/API/V0/QuerySpec.hs b/server/src-test/Hasura/Backends/DataConnector/API/V0/QuerySpec.hs index 27ff41c3b39..27b62ab4d6f 100644 --- a/server/src-test/Hasura/Backends/DataConnector/API/V0/QuerySpec.hs +++ b/server/src-test/Hasura/Backends/DataConnector/API/V0/QuerySpec.hs @@ -33,7 +33,7 @@ spec = do describe "Field" $ do describe "ColumnField" $ testToFromJSONToSchema - (ColumnField (ColumnName "my_column_name") StringTy) + (ColumnField (ColumnName "my_column_name") (ScalarType "string")) [aesonQQ| { "type": "column", "column": "my_column_name", @@ -55,7 +55,7 @@ spec = do describe "Query" $ do let query = Query - { _qFields = Just $ HashMap.fromList [(FieldName "my_field_alias", ColumnField (ColumnName "my_field_name") StringTy)], + { _qFields = Just $ HashMap.fromList [(FieldName "my_field_alias", ColumnField (ColumnName "my_field_name") (ScalarType "string"))], _qAggregates = Just $ HashMap.fromList [(FieldName "my_aggregate", StarCount)], _qLimit = Just 10, _qOffset = Just 20, diff --git a/server/src-test/Hasura/Backends/DataConnector/API/V0/ScalarSpec.hs b/server/src-test/Hasura/Backends/DataConnector/API/V0/ScalarSpec.hs index af89d480217..de31540039b 100644 --- a/server/src-test/Hasura/Backends/DataConnector/API/V0/ScalarSpec.hs +++ b/server/src-test/Hasura/Backends/DataConnector/API/V0/ScalarSpec.hs @@ -7,29 +7,16 @@ import Hasura.Backends.DataConnector.API.V0.Scalar import Hasura.Generator.Common (defaultRange, genArbitraryAlphaNumTextExcluding) import Hasura.Prelude import Hedgehog -import Hedgehog.Gen qualified as Gen import Test.Aeson.Utils import Test.Hspec spec :: Spec spec = do describe "ScalarType" $ do - describe "StringTy" $ - testToFromJSONToSchema StringTy [aesonQQ|"string"|] - describe "NumberTy" $ - testToFromJSONToSchema NumberTy [aesonQQ|"number"|] - describe "BoolTy" $ - testToFromJSONToSchema BoolTy [aesonQQ|"bool"|] - describe "CustomTy" $ - testToFromJSONToSchema (CustomTy "foo") [aesonQQ|"foo"|] + testToFromJSONToSchema (ScalarType "foo") [aesonQQ|"foo"|] jsonOpenApiProperties genScalarType genScalarType :: (MonadGen m, GenBase m ~ Identity) => m ScalarType genScalarType = - Gen.choice - [ pure StringTy, - pure NumberTy, - pure BoolTy, - CustomTy - <$> genArbitraryAlphaNumTextExcluding ["string", "number", "bool"] defaultRange - ] + ScalarType + <$> genArbitraryAlphaNumTextExcluding ["string", "number", "bool"] defaultRange diff --git a/server/src-test/Hasura/Backends/DataConnector/API/V0/TableSpec.hs b/server/src-test/Hasura/Backends/DataConnector/API/V0/TableSpec.hs index eb2dff4caf3..7625ce2471c 100644 --- a/server/src-test/Hasura/Backends/DataConnector/API/V0/TableSpec.hs +++ b/server/src-test/Hasura/Backends/DataConnector/API/V0/TableSpec.hs @@ -34,7 +34,7 @@ spec = do ( TableInfo (TableName ["my_table_name"]) View - [ColumnInfo (ColumnName "id") StringTy False Nothing False False] + [ColumnInfo (ColumnName "id") (ScalarType "string") False Nothing False False] [ColumnName "id"] (ForeignKeys mempty) (Just "my description") @@ -58,7 +58,7 @@ spec = do ( TableInfo (TableName ["my_table_name"]) Table - [ColumnInfo (ColumnName "id") StringTy False Nothing False False] + [ColumnInfo (ColumnName "id") (ScalarType "string") False Nothing False False] [ColumnName "id"] (ForeignKeys $ HashMap.singleton (ConstraintName "Artist") (Constraint (TableName ["artist_table"]) (HashMap.singleton (ColumnName "ArtistId") (ColumnName "ArtistId")))) (Just "my description")