Add column scalar type information Data Connector query API request [GDC-493]

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/6433
GitOrigin-RevId: c5f5e0c2e25c6820d9f73a1e90699cf18dc4cd47
This commit is contained in:
Daniel Chambers 2022-10-20 14:23:37 +11:00 committed by hasura-bot
parent 1c745959b9
commit 84b84a78e1
37 changed files with 397 additions and 292 deletions

View File

@ -318,11 +318,13 @@ and here is the resulting query request payload:
"fields": {
"ArtistId": {
"type": "column",
"column": "ArtistId"
"column": "ArtistId",
"column_type": "number"
},
"Name": {
"type": "column",
"column": "Name"
"column": "Name",
"column_type": "string"
}
}
}
@ -339,7 +341,7 @@ Let's break down the request:
- The `where` field tells us that there is currently no (interesting) predicate being applied to the rows of the data set (just an empty conjunction, which ought to return every row).
- The `order_by` field tells us that there is no particular ordering to use, and that we can return data in its natural order.
- The `limit` and `offset` fields tell us that there is no pagination required.
- The `fields` field tells us that we ought to return two fields per row (`ArtistId` and `Name`), and that these fields should be fetched from the columns with the same names.
- The `fields` field tells us that we ought to return two fields per row (`ArtistId` and `Name`), and that these fields should be fetched from the columns with the same names. The scalar types of the columns are also denoted with `column_type`.
#### Response Body Structure
@ -376,13 +378,13 @@ The `where` field contains a recursive expression data structure which should be
Each node of this recursive expression structure is tagged with a `type` property, which indicates the type of that node, and the node will contain one or more additional fields depending on that type. The valid expression types are enumerated below, along with these additional fields:
| type | Additional fields | Description |
|-----------------|--------------------------------|-------------|
|-----------------|----------------------------------------------|-------------|
| `and` | `expressions` | A conjunction of several subexpressions |
| `or` | `expressions` | A disjunction of several subexpressions |
| `not` | `expression` | The negation of a single subexpression |
| `exists` | `in_table`, `where` | Test if a row exists that matches the `where` subexpression in the specified table (`in_table`) |
| `binary_op` | `operator`, `column`, `value` | Test the specified `column` against a single `value` using a particular binary comparison `operator` |
| `binary_arr_op` | `operator`, `column`, `values` | Test the specified `column` against an array of `values` using a particular binary comparison `operator` |
| `binary_arr_op` | `operator`, `column`, `values`, `value_type` | Test the specified `column` against an array of `values` using a particular binary comparison `operator` where the type of each value is a `value_type` |
| `unary_op` | `operator`, `column` | Test the specified `column` against a particular unary comparison `operator` |
The value of the `in_table` property of the `exists` expression is an object that describes which table to look for rows in. The object is tagged with a `type` property:
@ -423,7 +425,7 @@ Values (as used in `value` in `binary_op` and the `values` array in `binary_arr_
| `scalar` | `value` | A scalar `value` to compare against |
| `column` | `column` | A `column` in the current table being queried to compare against |
Columns (as used in `column` fields in `binary_op`, `binary_arr_op`, `unary_op` and in `column`-typed Values) are specified as a column `name`, as well as optionally a `path` to the table that contains the column. If the `path` property is missing/null or an empty array, then the column is on the current table. However, if the path is `["$"]`, then the column is on the table involved in the Query that the whole `where` expression is from. At this point in time, these are the only valid values of `path`.
Columns (as used in `column` fields in `binary_op`, `binary_arr_op`, `unary_op` and in `column`-typed Values) are specified as a column `name`, a `column_type` to denote the scalar type of the column, as well as optionally a `path` to the table that contains the column. If the `path` property is missing/null or an empty array, then the column is on the current table. However, if the path is `["$"]`, then the column is on the table involved in the Query that the whole `where` expression is from. At this point in time, these are the only valid values of `path`.
Here is a simple example, which correponds to the predicate "`first_name` is John and `last_name` is Smith":
@ -435,22 +437,26 @@ Here is a simple example, which correponds to the predicate "`first_name` is Joh
"type": "binary_op",
"operator": "equal",
"column": {
"name": "first_name"
"name": "first_name",
"column_type": "string"
},
"value": {
"type": "scalar",
"value": "John"
"value": "John",
"value_type": "string"
}
},
{
"type": "binary_op",
"operator": "equal",
"column": {
"name": "last_name"
"name": "last_name",
"column_type": "string"
},
"value": {
"type": "scalar",
"value": "John"
"value": "John",
"value_type": "string"
}
}
]
@ -464,12 +470,14 @@ Here's another example, which corresponds to the predicate "`first_name` is the
"type": "binary_op",
"operator": "equal",
"column": {
"name": "first_name"
"name": "first_name",
"column_type": "string"
},
"value": {
"type": "column",
"column": {
"name": "last_name"
"name": "last_name",
"column_type": "string"
}
}
}
@ -488,11 +496,13 @@ In this example, a person table is filtered by whether or not that person has an
"type": "binary_op",
"operator": "greater_than_or_equal",
"column": {
"name": "age"
"name": "age",
"column_type": "number"
},
"value": {
"type": "scalar",
"value": 18
"value": 18,
"value_type": "number"
}
}
}
@ -511,13 +521,15 @@ In this example, a person table is filtered by whether or not that person has an
"type": "binary_op",
"operator": "equal",
"column": {
"name": "first_name" // This column refers to the child's name
"name": "first_name", // This column refers to the child's name,
"column_type": "string"
},
"value": {
"type": "column",
"column": {
"path": ["$"],
"name": "first_name" // This column refers to the parent's name
"name": "first_name", // This column refers to the parent's name
"column_type": "string"
}
}
}
@ -543,13 +555,15 @@ Exists expressions can be nested, but the `["$"]` path always refers to the quer
"type": "binary_op",
"operator": "equal",
"column": {
"name": "first_name" // This column refers to the children's friend's name
"name": "first_name", // This column refers to the children's friend's name
"column_type": "string"
},
"value": {
"type": "column",
"column": {
"path": ["$"],
"name": "first_name" // This column refers to the parent's name
"name": "first_name", // This column refers to the parent's name
"column_type": "string"
}
}
}
@ -570,11 +584,13 @@ In this example, a table is filtered by whether or not an unrelated administrato
"type": "binary_op",
"operator": "equal",
"column": {
"name": "username"
"name": "username",
"column_type": "string"
},
"value": {
"type": "scalar",
"value": "superuser"
"value": "superuser",
"value_type": "string"
}
}
}
@ -647,14 +663,16 @@ This will generate the following JSON query if the agent supports relationships:
"fields": {
"Title": {
"type": "column",
"column": "Title"
"column": "Title",
"column_type": "string"
}
}
}
},
"Name": {
"type": "column",
"column": "Name"
"column": "Name",
"column_type": "string"
}
}
}
@ -678,7 +696,8 @@ Note the `Albums` field in particular, which traverses the `Artists` -> `Albums`
"fields": {
"Title": {
"type": "column",
"column": "Title"
"column": "Title",
"column_type": "string"
}
}
}
@ -836,23 +855,28 @@ We would get the following query request JSON:
"fields": {
"Country": {
"type": "column",
"column": "Country"
"column": "Country",
"column_type": "string"
},
"CustomerId": {
"type": "column",
"column": "CustomerId"
"column": "CustomerId",
"column_type": "number"
},
"FirstName": {
"type": "column",
"column": "FirstName"
"column": "FirstName",
"column_type": "string"
},
"LastName": {
"type": "column",
"column": "LastName"
"column": "LastName",
"column_type": "string"
},
"SupportRepId": {
"type": "column",
"column": "SupportRepId"
"column": "SupportRepId",
"column_type": "number"
}
},
"where": {
@ -868,13 +892,15 @@ We would get the following query request JSON:
"type": "binary_op",
"operator": "equal",
"column": {
"name": "Country"
"name": "Country",
"column_type": "string"
},
"value": {
"type": "column",
"column": {
"path": ["$"],
"name": "Country"
"name": "Country",
"column_type": "string"
}
}
}
@ -976,23 +1002,28 @@ We would get the following query request JSON:
"fields": {
"Country": {
"type": "column",
"column": "Country"
"column": "Country",
"column_type": "string"
},
"CustomerId": {
"type": "column",
"column": "CustomerId"
"column": "CustomerId",
"column_type": "number"
},
"FirstName": {
"type": "column",
"column": "FirstName"
"column": "FirstName",
"column_type": "string"
},
"LastName": {
"type": "column",
"column": "LastName"
"column": "LastName",
"column_type": "string"
},
"SupportRepId": {
"type": "column",
"column": "SupportRepId"
"column": "SupportRepId",
"column_type": "number"
}
},
"where": {
@ -1008,22 +1039,26 @@ We would get the following query request JSON:
"type": "binary_op",
"operator": "equal",
"column": {
"name": "EmployeeId"
"name": "EmployeeId",
"column_type": "number"
},
"value": {
"type": "scalar",
"value": 2
"value": 2,
"value_type": "number"
}
},
{
"type": "binary_op",
"operator": "equal",
"column": {
"name": "City"
"name": "City",
"column_type": "string"
},
"value": {
"type": "scalar",
"value": "Calgary"
"value": "Calgary",
"value_type": "string"
}
}
]
@ -1162,22 +1197,26 @@ The `nodes` part of the query ends up as standard `fields` in the `Query`, and t
"fields": {
"nodes_ArtistId": {
"type": "column",
"column": "ArtistId"
"column": "ArtistId",
"column_type": "number"
},
"nodes_Name": {
"type": "column",
"column": "Name"
"column": "Name",
"column_type": "string"
}
},
"where": {
"type": "binary_op",
"operator": "greater_than",
"column": {
"name": "Name"
"name": "Name",
"column_type": "string"
},
"value": {
"type": "scalar",
"value": "Z"
"value": "Z",
"value_type": "string"
}
}
},
@ -1249,7 +1288,8 @@ This would generate the following `QueryRequest`:
},
"Name": {
"type": "column",
"column": "Name"
"column": "Name",
"column_type": "string"
}
},
"limit": 2,
@ -1295,7 +1335,8 @@ The `order_by` field can either be null, which means no particular ordering is r
"target_path": [],
"target": {
"type": "column",
"column": "last_name"
"column": "last_name",
"column_type": "string"
},
"order_direction": "asc"
},
@ -1303,7 +1344,8 @@ The `order_by` field can either be null, which means no particular ordering is r
"target_path": [],
"target": {
"type": "column",
"column": "first_name"
"column": "first_name",
"column_type": "string"
},
"order_direction": "desc"
}
@ -1344,7 +1386,7 @@ Here's an example of applying an ordering by a related table; the Album table is
],
"query": {
"fields": {
"Title": { "type": "column", "column": "Title" }
"Title": { "type": "column", "column": "Title", "column_type": "string" }
},
"order_by": {
"relations": {
@ -1419,7 +1461,7 @@ For example, here's a query that retrieves artists ordered descending by the cou
],
"query": {
"fields": {
"Name": { "type": "column", "column": "Name" }
"Name": { "type": "column", "column": "Name", "column_type": "string" }
},
"order_by": {
"relations": {
@ -1428,11 +1470,13 @@ For example, here's a query that retrieves artists ordered descending by the cou
"type": "binary_op",
"operator": "greater_than",
"column": {
"name": "Title"
"name": "Title",
"column_type": "string"
},
"value": {
"type": "scalar",
"value": "T"
"value": "T",
"value_type": "string"
}
},
"subrelations": {}

View File

@ -1,6 +1,6 @@
{
"name": "@hasura/dc-api-types",
"version": "0.11.0",
"version": "0.12.0",
"description": "Hasura GraphQL Engine Data Connector Agent API types",
"author": "Hasura (https://github.com/hasura/graphql-engine)",
"license": "Apache-2.0",

View File

@ -1043,6 +1043,9 @@
"column": {
"type": "string"
},
"column_type": {
"$ref": "#/components/schemas/ScalarType"
},
"type": {
"enum": [
"column"
@ -1052,6 +1055,7 @@
},
"required": [
"column",
"column_type",
"type"
],
"type": "object"
@ -1296,6 +1300,9 @@
},
"ComparisonColumn": {
"properties": {
"column_type": {
"$ref": "#/components/schemas/ScalarType"
},
"name": {
"description": "The name of the column",
"type": "string"
@ -1310,7 +1317,8 @@
}
},
"required": [
"name"
"name",
"column_type"
],
"type": "object"
},
@ -1328,6 +1336,9 @@
],
"type": "string"
},
"value_type": {
"$ref": "#/components/schemas/ScalarType"
},
"values": {
"items": {
"additionalProperties": true
@ -1339,6 +1350,7 @@
"operator",
"column",
"values",
"value_type",
"type"
],
"type": "object"
@ -1428,10 +1440,14 @@
},
"value": {
"additionalProperties": true
},
"value_type": {
"$ref": "#/components/schemas/ScalarType"
}
},
"required": [
"value",
"value_type",
"type"
],
"type": "object"

View File

@ -4,11 +4,13 @@
import type { BinaryArrayComparisonOperator } from './BinaryArrayComparisonOperator';
import type { ComparisonColumn } from './ComparisonColumn';
import type { ScalarType } from './ScalarType';
export type ApplyBinaryArrayComparisonOperator = {
column: ComparisonColumn;
operator: BinaryArrayComparisonOperator;
type: 'binary_arr_op';
value_type: ScalarType;
values: Array<any>;
};

View File

@ -2,8 +2,11 @@
/* tslint:disable */
/* eslint-disable */
import type { ScalarType } from './ScalarType';
export type ColumnField = {
column: string;
column_type: ScalarType;
type: 'column';
};

View File

@ -2,7 +2,10 @@
/* tslint:disable */
/* eslint-disable */
import type { ScalarType } from './ScalarType';
export type ComparisonColumn = {
column_type: ScalarType;
/**
* The name of the column
*/

View File

@ -2,8 +2,11 @@
/* tslint:disable */
/* eslint-disable */
import type { ScalarType } from './ScalarType';
export type ScalarValueComparison = {
type: 'scalar';
value: any;
value_type: ScalarType;
};

View File

@ -24,7 +24,7 @@
},
"dc-api-types": {
"name": "@hasura/dc-api-types",
"version": "0.11.0",
"version": "0.12.0",
"license": "Apache-2.0",
"devDependencies": {
"@tsconfig/node16": "^1.0.3",
@ -631,7 +631,7 @@
"license": "Apache-2.0",
"dependencies": {
"@fastify/cors": "^7.0.0",
"@hasura/dc-api-types": "0.11.0",
"@hasura/dc-api-types": "0.12.0",
"fastify": "^3.29.0",
"mathjs": "^11.0.0",
"pino-pretty": "^8.0.0",
@ -1389,7 +1389,7 @@
"license": "Apache-2.0",
"dependencies": {
"@fastify/cors": "^8.1.0",
"@hasura/dc-api-types": "0.11.0",
"@hasura/dc-api-types": "0.12.0",
"fastify": "^4.4.0",
"fastify-metrics": "^9.2.1",
"nanoid": "^3.3.4",
@ -3122,7 +3122,7 @@
"version": "file:reference",
"requires": {
"@fastify/cors": "^7.0.0",
"@hasura/dc-api-types": "0.11.0",
"@hasura/dc-api-types": "0.12.0",
"@tsconfig/node16": "^1.0.3",
"@types/node": "^16.11.49",
"@types/xml2js": "^0.4.11",
@ -3613,7 +3613,7 @@
"version": "file:sqlite",
"requires": {
"@fastify/cors": "^8.1.0",
"@hasura/dc-api-types": "0.11.0",
"@hasura/dc-api-types": "0.12.0",
"@tsconfig/node16": "^1.0.3",
"@types/node": "^16.11.49",
"@types/sqlite3": "^3.1.8",

View File

@ -10,7 +10,7 @@
"license": "Apache-2.0",
"dependencies": {
"@fastify/cors": "^7.0.0",
"@hasura/dc-api-types": "0.11.0",
"@hasura/dc-api-types": "0.12.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.11.0",
"version": "0.12.0",
"license": "Apache-2.0",
"devDependencies": {
"@tsconfig/node16": "^1.0.3",

View File

@ -22,7 +22,7 @@
},
"dependencies": {
"@fastify/cors": "^7.0.0",
"@hasura/dc-api-types": "0.11.0",
"@hasura/dc-api-types": "0.12.0",
"fastify": "^3.29.0",
"mathjs": "^11.0.0",
"pino-pretty": "^8.0.0",

View File

@ -236,7 +236,7 @@ const buildQueryForPathedOrderByElement = (orderByElement: OrderByElement, order
case "column":
return {
fields: {
[orderByElement.target.column]: { type: "column", column: orderByElement.target.column }
[orderByElement.target.column]: { type: "column", column: orderByElement.target.column, column_type: "unknown" } // Unknown column type here is a hack because we don't actually know what the column type is and we don't care
}
};
case "single_column_aggregate":
@ -387,14 +387,16 @@ const createFilterExpressionForRelationshipJoin = (row: Record<string, ScalarVal
return outerValue !== null;
})
.map(([outerValue, innerColumnName]) => {
const unknownScalarType = "unknown"; // We don't know what the type is and don't care since we never look at it anyway
return {
type: "binary_op",
operator: "equal",
column: {
path: [],
name: innerColumnName,
column_type: unknownScalarType,
},
value: { type: "scalar", value: outerValue }
value: { type: "scalar", value: outerValue, value_type: unknownScalarType }
};
});

View File

@ -10,7 +10,7 @@
"license": "Apache-2.0",
"dependencies": {
"@fastify/cors": "^8.1.0",
"@hasura/dc-api-types": "0.11.0",
"@hasura/dc-api-types": "0.12.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.11.0",
"version": "0.12.0",
"license": "Apache-2.0",
"devDependencies": {
"@tsconfig/node16": "^1.0.3",

View File

@ -22,7 +22,7 @@
},
"dependencies": {
"@fastify/cors": "^8.1.0",
"@hasura/dc-api-types": "0.11.0",
"@hasura/dc-api-types": "0.12.0",
"fastify-metrics": "^9.2.1",
"fastify": "^4.4.0",
"nanoid": "^3.3.4",

View File

@ -163,8 +163,8 @@ tests opts = describe "Aggregate Query Tests" $ do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "ArtistIds_Id", API.ColumnField (API.ColumnName "ArtistId")),
(API.FieldName "ArtistNames_Name", API.ColumnField (API.ColumnName "Name")),
[ (API.FieldName "ArtistIds_Id", API.ColumnField (API.ColumnName "ArtistId") API.NumberTy),
(API.FieldName "ArtistNames_Name", API.ColumnField (API.ColumnName "Name") API.StringTy),
( API.FieldName "nodes_Albums",
API.RelField
( API.RelationshipField
@ -173,7 +173,7 @@ tests opts = describe "Aggregate Query Tests" $ do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "nodes_Title", API.ColumnField (API.ColumnName "Title"))
[ (API.FieldName "nodes_Title", API.ColumnField (API.ColumnName "Title") API.StringTy)
],
_qAggregates = Nothing,
_qLimit = Nothing,

View File

@ -148,8 +148,8 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId")),
(API.FieldName "title", API.ColumnField (API.ColumnName "Title"))
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy),
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy)
],
_qAggregates = Nothing,
_qLimit = Just 1,
@ -210,8 +210,8 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId")),
(API.FieldName "title", API.ColumnField (API.ColumnName "Title"))
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy),
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy)
],
_qAggregates = Nothing,
_qLimit = Just 3,
@ -269,7 +269,7 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "CustomerId", API.ColumnField (API.ColumnName "CustomerId"))
[ (API.FieldName "CustomerId", API.ColumnField (API.ColumnName "CustomerId") API.NumberTy)
],
_qAggregates = Nothing,
_qLimit = Nothing,
@ -279,8 +279,8 @@ tests opts = do
API.Exists (API.UnrelatedTable $ API.TableName ("Employee" :| [])) $
API.ApplyBinaryComparisonOperator
API.Equal
(API.ComparisonColumn API.CurrentTable (API.ColumnName "EmployeeId"))
(API.ScalarValue (Aeson.Number 1)),
(API.ComparisonColumn API.CurrentTable (API.ColumnName "EmployeeId") API.NumberTy)
(API.ScalarValue (Aeson.Number 1) API.NumberTy),
_qOrderBy = Nothing
}
}

View File

@ -102,8 +102,8 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId")),
(API.FieldName "title", API.ColumnField (API.ColumnName "Title"))
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy),
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy)
],
_qAggregates = Nothing,
_qLimit = Just 1,

View File

@ -212,7 +212,7 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name")),
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy),
( API.FieldName "Genre",
API.RelField
( API.RelationshipField
@ -221,7 +221,7 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name"))
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy)
],
_qAggregates = Nothing,
_qLimit = Nothing,
@ -239,7 +239,7 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name"))
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy)
],
_qAggregates = Nothing,
_qLimit = Nothing,
@ -342,7 +342,7 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name")),
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy),
( API.FieldName "Album",
API.RelField
( API.RelationshipField
@ -359,7 +359,7 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name"))
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy)
],
_qAggregates = Nothing,
_qLimit = Nothing,
@ -475,7 +475,7 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "EmployeeId", API.ColumnField (API.ColumnName "EmployeeId"))
[ (API.FieldName "EmployeeId", API.ColumnField (API.ColumnName "EmployeeId") API.NumberTy)
],
_qAggregates = Nothing,
_qLimit = Just 1,
@ -485,8 +485,8 @@ tests opts = do
API.Exists (API.RelatedTable $ API.RelationshipName "SupportRepForCustomers") $
API.ApplyBinaryComparisonOperator
API.Equal
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country"))
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country"))),
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") API.StringTy)
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") API.StringTy)),
_qOrderBy =
Just $
API.OrderBy
@ -497,8 +497,8 @@ tests opts = do
API.Exists (API.RelatedTable $ API.RelationshipName "SupportRep") $
API.ApplyBinaryComparisonOperator
API.Equal
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country"))
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country")))
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") API.StringTy)
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") API.StringTy))
)
mempty
)

View File

@ -143,8 +143,8 @@ tests opts = do
{ _qFields =
Just $
HashMap.fromList
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId")),
(API.FieldName "title", API.ColumnField (API.ColumnName "Title"))
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy),
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy)
],
_qAggregates = Nothing,
_qLimit = Just 1,

View File

@ -16,6 +16,7 @@ where
import Autodocodec.Extended
import Autodocodec.OpenAPI ()
import Control.DeepSeq (NFData)
import Control.Lens ((^.), _1, _2, _3, _4)
import Data.Aeson (FromJSON, ToJSON, Value)
import Data.Data (Data)
import Data.HashMap.Strict qualified as HashMap
@ -26,6 +27,7 @@ import Data.Tuple.Extra
import GHC.Generics (Generic)
import Hasura.Backends.DataConnector.API.V0.Column qualified as API.V0
import Hasura.Backends.DataConnector.API.V0.Relationships qualified as API.V0
import Hasura.Backends.DataConnector.API.V0.Scalar qualified as API.V0
import Hasura.Backends.DataConnector.API.V0.Table qualified as API.V0
import Prelude
@ -121,7 +123,7 @@ data Expression
-- 'BinaryArrayComparisonOperator' against an array of 'ComparisonValue's.
-- The result of this application will return "true" or "false" depending
-- on the 'BinaryArrayComparisonOperator' that's being applied.
ApplyBinaryArrayComparisonOperator BinaryArrayComparisonOperator ComparisonColumn [Value]
ApplyBinaryArrayComparisonOperator BinaryArrayComparisonOperator ComparisonColumn [Value] API.V0.ScalarType
| -- | Apply a 'UnaryComparisonOperator' that evaluates a column with the
-- 'UnaryComparisonOperator'; the result of this application will return "true" or
-- "false" depending on the 'UnaryComparisonOperator' that's being applied.
@ -148,10 +150,11 @@ instance HasCodec Expression where
<*> requiredField' "column" .= snd3
<*> requiredField' "value" .= thd3
binaryArrayOperatorCodec =
(,,)
<$> requiredField' "operator" .= fst3
<*> requiredField' "column" .= snd3
<*> requiredField' "values" .= thd3
(,,,)
<$> requiredField' "operator" .= (^. _1)
<*> requiredField' "column" .= (^. _2)
<*> requiredField' "values" .= (^. _3)
<*> requiredField' "value_type" .= (^. _4)
unaryOperatorCodec =
(,)
<$> requiredField' "operator" .= fst
@ -164,8 +167,8 @@ instance HasCodec Expression where
("exists", mapToEncoder (inTable, where') existsCodec)
ApplyBinaryComparisonOperator o c v ->
("binary_op", mapToEncoder (o, c, v) binaryOperatorCodec)
ApplyBinaryArrayComparisonOperator o c vs ->
("binary_arr_op", mapToEncoder (o, c, vs) binaryArrayOperatorCodec)
ApplyBinaryArrayComparisonOperator o c vs scalarType ->
("binary_arr_op", mapToEncoder (o, c, vs, scalarType) binaryArrayOperatorCodec)
ApplyUnaryComparisonOperator o c ->
("unary_op", mapToEncoder (o, c) unaryOperatorCodec)
dec =
@ -185,7 +188,7 @@ instance HasCodec Expression where
),
( "binary_arr_op",
( "ApplyBinaryArrayComparisonOperator",
mapToDecoder (uncurry3 ApplyBinaryArrayComparisonOperator) binaryArrayOperatorCodec
mapToDecoder (uncurry4 ApplyBinaryArrayComparisonOperator) binaryArrayOperatorCodec
)
),
( "unary_op",
@ -194,6 +197,7 @@ instance HasCodec Expression where
)
)
]
uncurry4 fn (a, b, c, d) = fn a b c d
-- | Which table should be subqueried to satisfy the 'Exists' expression
data ExistsInTable
@ -227,7 +231,9 @@ data ComparisonColumn = ComparisonColumn
{ -- | The path to the table that contains the specified column.
_ccPath :: ColumnPath,
-- | The name of the column
_ccName :: API.V0.ColumnName
_ccName :: API.V0.ColumnName,
-- | The scalar type of the column
_ccColumnType :: API.V0.ScalarType
}
deriving stock (Eq, Ord, Show, Generic, Data)
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec ComparisonColumn
@ -239,6 +245,7 @@ instance HasCodec ComparisonColumn where
ComparisonColumn
<$> optionalFieldWithOmittedDefault "path" CurrentTable "The path to the table that contains the specified column. Missing or empty array means the current table. [\"$\"] means the query table. No other values are supported at this time." .= _ccPath
<*> requiredField "name" "The name of the column" .= _ccName
<*> requiredField "column_type" "The scalar type of the column" .= _ccColumnType
-- | Describes what table a column is located on. This may either be the "current" table
-- (which would be query table, or the table specified by the closest ancestor 'Exists'
@ -275,7 +282,7 @@ instance HasCodec ColumnPath where
data ComparisonValue
= -- | Allows a comparison to a column on the current table or another table
AnotherColumn ComparisonColumn
| ScalarValue Value
| ScalarValue Value API.V0.ScalarType
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Hashable, NFData)
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec ComparisonValue
@ -286,12 +293,15 @@ instance HasCodec ComparisonValue where
discriminatedUnionCodec "type" enc dec
where
columnCodec = requiredField' "column"
scalarValueCodec = requiredField' "value"
scalarValueCodec =
(,)
<$> requiredField' "value" .= fst
<*> requiredField' "value_type" .= snd
enc = \case
AnotherColumn c -> ("column", mapToEncoder c columnCodec)
ScalarValue v -> ("scalar", mapToEncoder v scalarValueCodec)
ScalarValue value scalarType -> ("scalar", mapToEncoder (value, scalarType) scalarValueCodec)
dec =
HashMap.fromList
[ ("column", ("AnotherColumnComparison", mapToDecoder AnotherColumn columnCodec)),
("scalar", ("ScalarValueComparison", mapToDecoder ScalarValue scalarValueCodec))
("scalar", ("ScalarValueComparison", mapToDecoder (uncurry ScalarValue) scalarValueCodec))
]

View File

@ -51,6 +51,7 @@ import Hasura.Backends.DataConnector.API.V0.Column qualified as API.V0
import Hasura.Backends.DataConnector.API.V0.Expression qualified as API.V0
import Hasura.Backends.DataConnector.API.V0.OrderBy qualified as API.V0
import Hasura.Backends.DataConnector.API.V0.Relationships qualified as API.V0
import Hasura.Backends.DataConnector.API.V0.Scalar qualified as API.V0
import Hasura.Backends.DataConnector.API.V0.Table qualified as API.V0
import Servant.API (HasStatus (..))
import Prelude
@ -142,7 +143,7 @@ relationshipFieldObjectCodec =
-- 2. a "relationship", which indicates that the field is the result of
-- a subquery
data Field
= ColumnField API.V0.ColumnName
= ColumnField API.V0.ColumnName API.V0.ScalarType
| RelField RelationshipField
deriving stock (Eq, Ord, Show, Generic, Data)
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec Field
@ -153,13 +154,16 @@ instance HasCodec Field where
object "Field" $
discriminatedUnionCodec "type" enc dec
where
columnCodec = requiredField' "column"
columnCodec =
(,)
<$> requiredField' "column" .= fst
<*> requiredField' "column_type" .= snd
enc = \case
ColumnField columnName -> ("column", mapToEncoder columnName columnCodec)
ColumnField columnName scalarType -> ("column", mapToEncoder (columnName, scalarType) columnCodec)
RelField relField -> ("relationship", mapToEncoder relField relationshipFieldObjectCodec)
dec =
HashMap.fromList
[ ("column", ("ColumnField", mapToDecoder ColumnField columnCodec)),
[ ("column", ("ColumnField", mapToDecoder (uncurry ColumnField) columnCodec)),
("relationship", ("RelationshipField", mapToDecoder RelField relationshipFieldObjectCodec))
]

View File

@ -322,11 +322,15 @@ data TestData = TestData
_tdGenresTableName :: API.TableName,
_tdGenresRows :: [HashMap API.FieldName API.FieldValue],
_tdGenresTableRelationships :: API.TableRelationships,
-- = Scalar Types
_tdStringType :: API.ScalarType,
_tdIntType :: API.ScalarType,
_tdFloatType :: API.ScalarType,
-- = Utility functions
_tdColumnName :: Text -> API.ColumnName,
_tdColumnField :: Text -> API.Field,
_tdQueryComparisonColumn :: Text -> API.ComparisonColumn,
_tdCurrentComparisonColumn :: Text -> API.ComparisonColumn,
_tdColumnField :: Text -> API.ScalarType -> API.Field,
_tdQueryComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn,
_tdCurrentComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn,
_tdOrderByColumn :: [API.RelationshipName] -> Text -> API.OrderDirection -> API.OrderByElement
}
@ -372,6 +376,9 @@ mkTestData TestConfig {..} =
_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)
@ -479,14 +486,14 @@ _ColumnFieldString = API._ColumnFieldValue . _String
_ColumnFieldBoolean :: Traversal' API.FieldValue Bool
_ColumnFieldBoolean = API._ColumnFieldValue . _Bool
columnField :: Text -> API.Field
columnField = API.ColumnField . API.ColumnName
columnField :: Text -> API.ScalarType -> API.Field
columnField name scalarType = API.ColumnField (API.ColumnName name) scalarType
queryComparisonColumn :: Text -> API.ComparisonColumn
queryComparisonColumn columnName = API.ComparisonColumn API.QueryTable $ API.ColumnName columnName
queryComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn
queryComparisonColumn columnName scalarType = API.ComparisonColumn API.QueryTable (API.ColumnName columnName) scalarType
currentComparisonColumn :: Text -> API.ComparisonColumn
currentComparisonColumn columnName = API.ComparisonColumn API.CurrentTable $ API.ColumnName columnName
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 targetPath columnName orderDirection =

View File

@ -18,13 +18,13 @@ spec TestData {..} api sourceName config _capabilities = describe "Basic Queries
where
brokenQueryRequest :: QueryRequest
brokenQueryRequest =
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId"), ("Name", _tdColumnField "Name")]
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
query =
Data.emptyQuery
& qFields ?~ fields
& qWhere
?~ ApplyBinaryComparisonOperator
(CustomBinaryComparisonOperator "FOOBAR")
(ComparisonColumn CurrentTable (ColumnName "ArtistId"))
(ScalarValue "1")
(ComparisonColumn CurrentTable (ColumnName "ArtistId") NumberTy)
(ScalarValue "1" StringTy)
in QueryRequest _tdArtistsTableName [] query

View File

@ -24,6 +24,6 @@ spec TestData {..} api sourceName config _ = do
where
artistsQueryRequest :: QueryRequest
artistsQueryRequest =
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId"), ("Name", _tdColumnField "Name")]
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdArtistsTableName [] query

View File

@ -35,7 +35,7 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
Data.responseRows response `rowsShouldBe` []
it "counts all rows, after applying filters" $ do
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCity") (ScalarValue (String "Oslo"))
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCity" _tdStringType) (ScalarValue (String "Oslo") _tdStringType)
let aggregates = Data.mkFieldsMap [("count_all", StarCount)]
let queryRequest = invoicesQueryRequest aggregates & qrQuery . qWhere ?~ where'
response <- guardedQuery api sourceName config queryRequest
@ -70,7 +70,7 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
Data.responseRows response `rowsShouldBe` []
it "can count all rows with non-null values in a column, after applying pagination and filtering" $ do
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId") (ScalarValue (Number 380))
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" _tdIntType) (ScalarValue (Number 380) _tdIntType)
let aggregates = Data.mkFieldsMap [("count_cols", ColumnCount $ ColumnCountAggregate (_tdColumnName "BillingState") False)]
let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qLimit ?~ 20 >>> qWhere ?~ where')
response <- guardedQuery api sourceName config queryRequest
@ -99,7 +99,7 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
Data.responseRows response `rowsShouldBe` []
it "can count all rows with distinct non-null values in a column, after applying pagination and filtering" $ do
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId") (ScalarValue (Number 380))
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" _tdIntType) (ScalarValue (Number 380) _tdIntType)
let aggregates = Data.mkFieldsMap [("count_cols", ColumnCount $ ColumnCountAggregate (_tdColumnName "BillingState") True)]
let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qLimit ?~ 20 >>> qWhere ?~ where')
response <- guardedQuery api sourceName config queryRequest
@ -130,7 +130,7 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
Data.responseRows response `rowsShouldBe` []
it "can get the max total from all rows, after applying pagination, filtering and ordering" $ do
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry") (ScalarValue (String "USA"))
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" _tdStringType) (ScalarValue (String "USA") _tdStringType)
let orderBy = OrderBy mempty $ _tdOrderByColumn [] "BillingPostalCode" Descending :| [_tdOrderByColumn [] "InvoiceId" Ascending]
let aggregates = Data.mkFieldsMap [("max", SingleColumn $ SingleColumnAggregate Max (_tdColumnName "Total"))]
let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qLimit ?~ 20 >>> qWhere ?~ where' >>> qOrderBy ?~ orderBy)
@ -169,7 +169,7 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
Data.responseRows response `rowsShouldBe` []
it "aggregates over empty row lists results in nulls" $ do
let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "ArtistId") (ScalarValue (Number 0))
let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "ArtistId" _tdIntType) (ScalarValue (Number 0) _tdIntType)
let aggregates = Data.mkFieldsMap [("min", SingleColumn $ SingleColumnAggregate Min (_tdColumnName "Name"))]
let queryRequest = artistsQueryRequest aggregates & qrQuery . qWhere ?~ where'
response <- guardedQuery api sourceName config queryRequest
@ -228,10 +228,10 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
it "can also query for the rows involved in the aggregate" $ do
let fields =
Data.mkFieldsMap
[ ("InvoiceId", _tdColumnField "InvoiceId"),
("BillingCountry", _tdColumnField "BillingCountry")
[ ("InvoiceId", _tdColumnField "InvoiceId" _tdIntType),
("BillingCountry", _tdColumnField "BillingCountry" _tdStringType)
]
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry") (ScalarValue (String "Canada"))
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" _tdStringType) (ScalarValue (String "Canada") _tdStringType)
let orderBy = OrderBy mempty $ _tdOrderByColumn [] "BillingAddress" Ascending :| [_tdOrderByColumn [] "InvoiceId" Ascending]
let aggregates = Data.mkFieldsMap [("min", SingleColumn $ SingleColumnAggregate Min (_tdColumnName "Total"))]
let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qFields ?~ fields >>> qLimit ?~ 30 >>> qWhere ?~ where' >>> qOrderBy ?~ orderBy)
@ -279,8 +279,8 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
it "can query aggregates via an array relationship and include the rows in that relationship" $ do
let albumFields =
Data.mkFieldsMap
[ ("AlbumId", _tdColumnField "AlbumId"),
("Title", _tdColumnField "Title")
[ ("AlbumId", _tdColumnField "AlbumId" _tdIntType),
("Title", _tdColumnField "Title" _tdStringType)
]
let query = artistsWithAlbumsQuery (qFields ?~ albumFields) & qrQuery . qLimit ?~ 5
receivedArtists <- guardedQuery api sourceName config query
@ -366,8 +366,8 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
albumsSubquery = Data.emptyQuery & qAggregates ?~ albumAggregates & modifySubquery
artistFields =
Data.mkFieldsMap
[ ("ArtistId", _tdColumnField "ArtistId"),
("Name", _tdColumnField "Name"),
[ ("ArtistId", _tdColumnField "ArtistId" _tdIntType),
("Name", _tdColumnField "Name" _tdStringType),
("Albums", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery)
]
artistOrderBy = OrderBy mempty $ _tdOrderByColumn [] "ArtistId" Ascending :| []
@ -410,33 +410,33 @@ spec TestData {..} api sourceName config relationshipCapabilities = describe "Ag
deeplyNestedArtistsQuery =
let invoiceLinesAggregates = Data.mkFieldsMap [("aggregate_sum_Quantity", SingleColumn $ SingleColumnAggregate Sum (_tdColumnName "Quantity"))]
invoiceLinesSubquery = Data.emptyQuery & qAggregates ?~ invoiceLinesAggregates
mediaTypeFields = Data.mkFieldsMap [("Name", _tdColumnField "Name")]
mediaTypeFields = Data.mkFieldsMap [("Name", _tdColumnField "Name" _tdStringType)]
mediaTypeSubquery = Data.emptyQuery & qFields ?~ mediaTypeFields
tracksFields =
Data.mkFieldsMap
[ ("nodes_Name", _tdColumnField "Name"),
[ ("nodes_Name", _tdColumnField "Name" _tdStringType),
("nodes_MediaType", RelField $ RelationshipField _tdMediaTypeRelationshipName mediaTypeSubquery),
("nodes_InvoiceLines_aggregate", RelField $ RelationshipField _tdInvoiceLinesRelationshipName invoiceLinesSubquery)
]
tracksAggregates = Data.mkFieldsMap [("aggregate_count", StarCount)]
tracksWhere = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Milliseconds") (ScalarValue $ Number 300000)
tracksWhere = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Milliseconds" _tdIntType) (ScalarValue (Number 300000) _tdIntType)
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"),
[ ("nodes_Title", _tdColumnField "Title" _tdStringType),
("nodes_Tracks_aggregate", RelField $ RelationshipField _tdTracksRelationshipName tracksSubquery)
]
albumsSubquery = Data.emptyQuery & qFields ?~ albumsFields
artistFields =
Data.mkFieldsMap
[ ("Name", _tdColumnField "Name"),
[ ("Name", _tdColumnField "Name" _tdStringType),
("Albums_aggregate", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery)
]
artistWhere =
And
[ ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name") (ScalarValue $ String "A"),
ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Name") (ScalarValue $ String "B")
[ ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "A") _tdStringType),
ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "B") _tdStringType)
]
artistOrderBy = OrderBy mempty $ _tdOrderByColumn [] "Name" Descending :| []
artistQuery = Query (Just artistFields) Nothing (Just 3) (Just 1) (Just artistWhere) (Just artistOrderBy)

View File

@ -24,7 +24,7 @@ spec TestData {..} api 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"), ("Title", _tdColumnField "Title")]
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
let query = albumsQueryRequest & qrQuery . qFields ?~ fields
receivedAlbums <- Data.sortResponseRowsBy "Title" <$> guardedQuery api sourceName config query
@ -36,7 +36,7 @@ spec TestData {..} api 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"), ("Artist_Name", _tdColumnField "Name")]
let fields = Data.mkFieldsMap [("Artist_Id", _tdColumnField "ArtistId" _tdIntType), ("Artist_Name", _tdColumnField "Name" _tdStringType)]
let query = artistsQueryRequest & qrQuery . qFields ?~ fields
receivedArtists <- Data.sortResponseRowsBy "ArtistId" <$> guardedQuery api sourceName config query
@ -67,12 +67,12 @@ spec TestData {..} api sourceName config = describe "Basic Queries" $ do
where
artistsQueryRequest :: QueryRequest
artistsQueryRequest =
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId"), ("Name", _tdColumnField "Name")]
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdArtistsTableName [] query
albumsQueryRequest :: QueryRequest
albumsQueryRequest =
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId"), ("ArtistId", _tdColumnField "ArtistId"), ("Title", _tdColumnField "Title")]
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdAlbumsTableName [] query

View File

@ -20,7 +20,7 @@ import Prelude
spec :: TestData -> Client IO (NamedRoutes Routes) -> SourceName -> Config -> Maybe ComparisonCapabilities -> Spec
spec TestData {..} api sourceName config comparisonCapabilities = describe "Filtering in Queries" $ do
it "can filter using an equality expression" $ do
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 2))
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType)
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -31,7 +31,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can filter using an inequality expression" $ do
let where' = Not (ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 2)))
let where' = Not (ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType))
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -42,7 +42,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can filter using an in expression" $ do
let where' = ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId") [Number 2, Number 3]
let where' = ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" _tdIntType) [Number 2, Number 3] _tdIntType
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -53,7 +53,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can negate an in expression filter using a not expression" $ do
let where' = Not (ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId") [Number 2, Number 3])
let where' = Not (ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" _tdIntType) [Number 2, Number 3] _tdIntType)
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -64,8 +64,8 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can combine filters using an and expression" $ do
let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "ArtistId") (ScalarValue (Number 58))
let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title") (ScalarValue (String "Stormbringer"))
let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "ArtistId" _tdIntType) (ScalarValue (Number 58) _tdIntType)
let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "Stormbringer") _tdStringType)
let where' = And [where1, where2]
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -89,8 +89,8 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can combine filters using an or expression" $ do
let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 2))
let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 3))
let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType)
let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 3) _tdIntType)
let where' = Or [where1, where2]
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -110,7 +110,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can filter by applying the greater than operator" $ do
let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 300))
let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 300) _tdIntType)
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -121,7 +121,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can filter by applying the greater than or equal operator" $ do
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 300))
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 300) _tdIntType)
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -132,7 +132,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can filter by applying the less than operator" $ do
let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 100))
let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 100) _tdIntType)
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -143,7 +143,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can filter by applying the less than or equal operator" $ do
let where' = ApplyBinaryComparisonOperator LessThanOrEqual (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 100))
let where' = ApplyBinaryComparisonOperator LessThanOrEqual (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 100) _tdIntType)
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -154,7 +154,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can filter using a greater than operator with a column comparison" $ do
let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId") (AnotherColumn (_tdCurrentComparisonColumn "ArtistId"))
let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (AnotherColumn (_tdCurrentComparisonColumn "ArtistId" _tdIntType))
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -171,7 +171,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
it "returns all rows if matching rows exist" $ do
let where' =
Exists (UnrelatedTable _tdEmployeesTableName) $
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId") (ScalarValue (Number 1))
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType)
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -183,7 +183,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
it "returns no rows if matching rows do not exist" $ do
let where' =
Exists (UnrelatedTable _tdEmployeesTableName) $
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId") (ScalarValue (Number 0))
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 0) _tdIntType)
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -195,8 +195,8 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
let where' =
Exists (UnrelatedTable _tdEmployeesTableName) $
And
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId") (ScalarValue (Number 1)),
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City") (ScalarValue (String "Edmonton"))
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType),
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" _tdStringType) (ScalarValue (String "Edmonton") _tdStringType)
]
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -210,8 +210,8 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
let where' =
Exists (UnrelatedTable _tdEmployeesTableName) $
And
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId") (ScalarValue (Number 1)),
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City") (ScalarValue (String "Calgary"))
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType),
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" _tdStringType) (ScalarValue (String "Calgary") _tdStringType)
]
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> guardedQuery api sourceName config query
@ -224,7 +224,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
it "can filter by comparing against rows in a related table" $ do
let where' =
Exists (RelatedTable _tdArtistRelationshipName) $
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name") (ScalarValue (String "AC/DC"))
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "AC/DC") _tdStringType)
let query =
albumsQueryRequest
& qrTableRelationships .~ [Data.onlyKeepRelationships [_tdArtistRelationshipName] _tdAlbumsTableRelationships]
@ -247,7 +247,7 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
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") (ScalarValue (String "Metal"))
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "Metal") _tdStringType)
let query =
artistsQueryRequest
& qrTableRelationships
@ -285,8 +285,8 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
let where' =
Exists (RelatedTable _tdAlbumsRelationshipName) $
And
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId") (ScalarValue (Number 1)),
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title") (ScalarValue (String "Let There Be Rock"))
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 1) _tdIntType),
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "Let There Be Rock") _tdStringType)
]
let query =
artistsQueryRequest
@ -308,12 +308,12 @@ spec TestData {..} api sourceName config comparisonCapabilities = describe "Filt
where
artistsQueryRequest :: QueryRequest
artistsQueryRequest =
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId"), ("Name", _tdColumnField "Name")]
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdArtistsTableName [] query
albumsQueryRequest :: QueryRequest
albumsQueryRequest =
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId"), ("ArtistId", _tdColumnField "ArtistId"), ("Title", _tdColumnField "Title")]
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdAlbumsTableName [] query

View File

@ -74,7 +74,7 @@ spec TestData {..} api sourceName config Capabilities {..} = describe "Order By
_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") (ScalarValue $ String "N")
let artistTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "N") _tdStringType)
let orderByRelations = HashMap.fromList [(_tdArtistRelationshipName, OrderByRelation (Just artistTableFilter) mempty)]
let orderBy = OrderBy orderByRelations $ _tdOrderByColumn [_tdArtistRelationshipName] "Name" Ascending :| []
let query =
@ -168,7 +168,7 @@ spec TestData {..} api sourceName config Capabilities {..} = describe "Order By
_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") (ScalarValue $ String "N")
let albumTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "N") _tdStringType)
let orderByRelations = HashMap.fromList [(_tdAlbumsRelationshipName, OrderByRelation (Just albumTableFilter) mempty)]
let orderBy = OrderBy orderByRelations $ OrderByElement [_tdAlbumsRelationshipName] OrderByStarCountAggregate Descending :| []
let query =
@ -238,19 +238,19 @@ spec TestData {..} api sourceName config Capabilities {..} = describe "Order By
where
albumsQueryRequest :: QueryRequest
albumsQueryRequest =
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId"), ("ArtistId", _tdColumnField "ArtistId"), ("Title", _tdColumnField "Title")]
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdAlbumsTableName [] query
artistsQueryRequest :: QueryRequest
artistsQueryRequest =
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId"), ("Name", _tdColumnField "Name")]
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdArtistsTableName [] query
tracksQueryRequest :: QueryRequest
tracksQueryRequest =
let fields = Data.mkFieldsMap [("TrackId", _tdColumnField "TrackId"), ("Name", _tdColumnField "Name")]
let fields = Data.mkFieldsMap [("TrackId", _tdColumnField "TrackId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdTracksTableName [] query

View File

@ -76,8 +76,8 @@ spec TestData {..} api sourceName config subqueryComparisonCapabilities = descri
Exists (RelatedTable _tdSupportRepRelationshipName) $
ApplyBinaryComparisonOperator
Equal
(_tdCurrentComparisonColumn "Country")
(AnotherColumn (_tdQueryComparisonColumn "Country"))
(_tdCurrentComparisonColumn "Country" _tdStringType)
(AnotherColumn (_tdQueryComparisonColumn "Country" _tdStringType))
let query = customersWithSupportRepQuery id & qrQuery . qWhere ?~ where'
receivedCustomers <- Data.sortResponseRowsBy "CustomerId" <$> guardedQuery api sourceName config query
@ -104,8 +104,8 @@ spec TestData {..} api sourceName config subqueryComparisonCapabilities = descri
Exists (RelatedTable _tdSupportRepForCustomersRelationshipName) $
ApplyBinaryComparisonOperator
Equal
(_tdCurrentComparisonColumn "Country")
(AnotherColumn (_tdQueryComparisonColumn "Country"))
(_tdCurrentComparisonColumn "Country" _tdStringType)
(AnotherColumn (_tdQueryComparisonColumn "Country" _tdStringType))
let query = employeesWithCustomersQuery id & qrQuery . qWhere ?~ where'
receivedEmployees <- Data.sortResponseRowsBy "EmployeeId" <$> guardedQuery api sourceName config query
@ -135,17 +135,17 @@ spec TestData {..} api sourceName config subqueryComparisonCapabilities = descri
And
[ ( ApplyBinaryComparisonOperator
GreaterThan
(_tdCurrentComparisonColumn "FirstName")
(AnotherColumn (_tdCurrentComparisonColumn "LastName"))
(_tdCurrentComparisonColumn "FirstName" _tdStringType)
(AnotherColumn (_tdCurrentComparisonColumn "LastName" _tdStringType))
),
(Not (ApplyUnaryComparisonOperator IsNull (_tdCurrentComparisonColumn "EmployeeId")))
(Not (ApplyUnaryComparisonOperator IsNull (_tdCurrentComparisonColumn "EmployeeId" _tdIntType)))
]
let employeesWhere =
ApplyBinaryComparisonOperator
GreaterThan
(_tdCurrentComparisonColumn "FirstName")
(AnotherColumn (_tdCurrentComparisonColumn "LastName"))
(_tdCurrentComparisonColumn "FirstName" _tdStringType)
(AnotherColumn (_tdCurrentComparisonColumn "LastName" _tdStringType))
let query = customersWithSupportRepQuery (\q -> q & qWhere ?~ employeesWhere) & qrQuery . qWhere ?~ customersWhere
receivedCustomers <- Data.sortResponseRowsBy "CustomerId" <$> guardedQuery api sourceName config query
@ -173,8 +173,8 @@ spec TestData {..} api sourceName config subqueryComparisonCapabilities = descri
let artistsSubquery = modifySubquery artistsQuery
fields =
Data.mkFieldsMap
[ ("AlbumId", _tdColumnField "AlbumId"),
("Title", _tdColumnField "Title"),
[ ("AlbumId", _tdColumnField "AlbumId" _tdIntType),
("Title", _tdColumnField "Title" _tdStringType),
("Artist", RelField $ RelationshipField _tdArtistRelationshipName artistsSubquery)
]
query = albumsQuery & qFields ?~ fields
@ -182,13 +182,13 @@ spec TestData {..} api sourceName config subqueryComparisonCapabilities = descri
artistsWithAlbumsQuery :: (Query -> Query) -> QueryRequest
artistsWithAlbumsQuery modifySubquery =
let albumFields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId"), ("Title", _tdColumnField "Title")]
let albumFields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
albumsSort = OrderBy mempty $ _tdOrderByColumn [] "AlbumId" Ascending :| []
albumsSubquery = albumsQuery & qFields ?~ albumFields & qOrderBy ?~ albumsSort & modifySubquery
fields =
Data.mkFieldsMap
[ ("ArtistId", _tdColumnField "ArtistId"),
("Name", _tdColumnField "Name"),
[ ("ArtistId", _tdColumnField "ArtistId" _tdIntType),
("Name", _tdColumnField "Name" _tdStringType),
("Albums", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery)
]
query = artistsQuery & qFields ?~ fields
@ -219,23 +219,23 @@ spec TestData {..} api sourceName config subqueryComparisonCapabilities = descri
artistsQuery :: Query
artistsQuery =
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId"), ("Name", _tdColumnField "Name")]
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
in Data.emptyQuery & qFields ?~ fields
albumsQuery :: Query
albumsQuery =
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId"), ("ArtistId", _tdColumnField "ArtistId"), ("Title", _tdColumnField "Title")]
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
in Data.emptyQuery & qFields ?~ fields
customersQuery :: Query
customersQuery =
let fields =
Data.mkFieldsMap
[ ("CustomerId", _tdColumnField "CustomerId"),
("FirstName", _tdColumnField "FirstName"),
("LastName", _tdColumnField "LastName"),
("Country", _tdColumnField "Country"),
("SupportRepId", _tdColumnField "SupportRepId")
[ ("CustomerId", _tdColumnField "CustomerId" _tdIntType),
("FirstName", _tdColumnField "FirstName" _tdStringType),
("LastName", _tdColumnField "LastName" _tdStringType),
("Country", _tdColumnField "Country" _tdStringType),
("SupportRepId", _tdColumnField "SupportRepId" _tdIntType)
]
in Data.emptyQuery & qFields ?~ fields
@ -243,10 +243,10 @@ spec TestData {..} api sourceName config subqueryComparisonCapabilities = descri
employeesQuery =
let fields =
Data.mkFieldsMap
[ ("EmployeeId", _tdColumnField "EmployeeId"),
("FirstName", _tdColumnField "FirstName"),
("LastName", _tdColumnField "LastName"),
("Country", _tdColumnField "Country")
[ ("EmployeeId", _tdColumnField "EmployeeId" _tdIntType),
("FirstName", _tdColumnField "FirstName" _tdStringType),
("LastName", _tdColumnField "LastName" _tdStringType),
("Country", _tdColumnField "Country" _tdStringType)
]
in Data.emptyQuery & qFields ?~ fields

View File

@ -1,6 +1,10 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Hasura.Backends.DataConnector.Adapter.Backend (CustomBooleanOperator (..)) where
module Hasura.Backends.DataConnector.Adapter.Backend
( CustomBooleanOperator (..),
columnTypeToScalarType,
)
where
import Data.Aeson qualified as J
import Data.Aeson.Extended (ToJSONKeyValue (..))
@ -16,6 +20,7 @@ import Hasura.Incremental
import Hasura.Prelude
import Hasura.RQL.IR.BoolExp
import Hasura.RQL.Types.Backend (Backend (..), ComputedFieldReturnType, SupportedNamingCase (..), XDisable, XEnable)
import Hasura.RQL.Types.Column (ColumnType (..))
import Hasura.RQL.Types.ResizePool (ServerReplicas)
import Hasura.SQL.Backend (BackendType (DataConnector))
import Language.GraphQL.Draft.Syntax qualified as G
@ -158,3 +163,8 @@ parseValue type' val =
-- For custom scalar types we don't know what subset of JSON values
-- they accept, so we just accept any value.
(DC.CustomTy _, value) -> pure value
columnTypeToScalarType :: ColumnType 'DataConnector -> DC.ScalarType
columnTypeToScalarType = \case
ColumnScalar scalarType -> scalarType
ColumnEnumReference _ -> DC.StringTy

View File

@ -20,6 +20,7 @@ import Data.Text.Extended (toTxt, (<<>), (<>>))
import Hasura.Backends.DataConnector.API (capabilitiesCase, errorResponseSummary, schemaCase)
import Hasura.Backends.DataConnector.API qualified as API
import Hasura.Backends.DataConnector.API.V0.ErrorResponse (_crDetails)
import Hasura.Backends.DataConnector.Adapter.Backend (columnTypeToScalarType)
import Hasura.Backends.DataConnector.Adapter.ConfigTransform (transformConnSourceConfig)
import Hasura.Backends.DataConnector.Adapter.Types qualified as DC
import Hasura.Backends.DataConnector.Agent.Client (AgentClientContext (..), runAgentClientT)
@ -377,8 +378,8 @@ parseCollectableType' collectableType = \case
| HSU.isSessionVariable t -> pure $ mkTypedSessionVar collectableType $ mkSessionVariable t
| HSU.isReqUserId t -> pure $ mkTypedSessionVar collectableType HSU.userIdHeader
val -> case collectableType of
CollectableTypeScalar scalarType ->
PSESQLExp . DC.ValueLiteral <$> RQL.T.C.parseScalarValueColumnType scalarType val
CollectableTypeScalar columnType ->
PSESQLExp . DC.ValueLiteral (columnTypeToScalarType columnType) <$> RQL.T.C.parseScalarValueColumnType columnType val
CollectableTypeArray _ ->
throw400 NotSupported "Array types are not supported by the Data Connector backend"
@ -389,11 +390,5 @@ mkTypedSessionVar ::
mkTypedSessionVar columnType =
PSESessVar (columnTypeToScalarType <$> columnType)
columnTypeToScalarType :: RQL.T.C.ColumnType 'DataConnector -> DC.ScalarType
columnTypeToScalarType = \case
RQL.T.C.ColumnScalar scalarType -> scalarType
-- NOTE: This should be unreachable:
RQL.T.C.ColumnEnumReference _ -> DC.StringTy
errorAction :: MonadError QErr m => API.ErrorResponse -> m a
errorAction e = throw400WithDetail DataConnectorError (errorResponseSummary e) (_crDetails e)

View File

@ -13,7 +13,7 @@ import Data.List.NonEmpty qualified as NE
import Data.Text.Casing (GQLNameIdentifier, fromCustomName)
import Data.Text.Extended ((<<>))
import Hasura.Backends.DataConnector.API.V0.Capabilities (lookupComparisonInputObjectDefinition)
import Hasura.Backends.DataConnector.Adapter.Backend (CustomBooleanOperator (..))
import Hasura.Backends.DataConnector.Adapter.Backend (CustomBooleanOperator (..), columnTypeToScalarType)
import Hasura.Backends.DataConnector.Adapter.Types qualified as DC
import Hasura.Base.Error
import Hasura.GraphQL.Parser.Class
@ -194,7 +194,7 @@ comparisonExps' sourceInfo columnType = P.memoizeOn 'comparisonExps' (dataConnec
mkListLiteral :: [RQL.ColumnValue 'DataConnector] -> IR.UnpreparedValue 'DataConnector
mkListLiteral columnValues =
IR.UVLiteral . DC.ArrayLiteral $ RQL.cvValue <$> columnValues
IR.UVLiteral $ DC.ArrayLiteral (columnTypeToScalarType columnType) (RQL.cvValue <$> columnValues)
mkCustomOperators ::
NamingCase ->

View File

@ -291,8 +291,8 @@ data CountAggregate
--------------------------------------------------------------------------------
data Literal
= ValueLiteral J.Value
| ArrayLiteral [J.Value]
= ValueLiteral ScalarType J.Value
| ArrayLiteral ScalarType [J.Value]
deriving stock (Eq, Show, Generic, Ord)
deriving anyclass (Cacheable, Hashable, NFData, ToJSON)

View File

@ -292,7 +292,7 @@ mkPlan session (SourceConfig {}) ir = do
AFColumn colField ->
-- TODO: make sure certain fields in colField are not in use, since we don't
-- support them
pure . Just . API.ColumnField . Witch.from $ _acfColumn colField
pure . Just $ API.ColumnField (Witch.from $ _acfColumn colField) (Witch.from . columnTypeToScalarType $ _acfType colField)
AFObjectRelation objRel -> do
let targetTable = Witch.from $ _aosTableFrom (_aarAnnSelect objRel)
let relationshipName = mkRelationshipName $ _aarRelationshipName objRel
@ -432,7 +432,7 @@ mkPlan session (SourceConfig {}) ir = do
UnpreparedValue 'DataConnector ->
m Literal
prepareLiterals (UVLiteral literal) = pure $ literal
prepareLiterals (UVParameter _ e) = pure (ValueLiteral (cvValue e))
prepareLiterals (UVParameter _ e) = pure (ValueLiteral (columnTypeToScalarType $ cvType e) (cvValue e))
prepareLiterals UVSession = throw400 NotSupported "prepareLiterals: UVSession"
prepareLiterals (UVSessionVar sessionVarType sessionVar) = do
textValue <-
@ -445,16 +445,16 @@ mkPlan session (SourceConfig {}) ir = do
case varType of
CollectableTypeScalar scalarType ->
case scalarType of
StringTy -> pure . ValueLiteral $ J.String varValue
NumberTy -> parseValue (ValueLiteral . J.Number) "number value"
BoolTy -> parseValue (ValueLiteral . J.Bool) "boolean value"
CustomTy customTypeName -> parseValue ValueLiteral (customTypeName <> " JSON value")
StringTy -> pure . ValueLiteral scalarType $ J.String varValue
NumberTy -> parseValue (ValueLiteral scalarType . J.Number) "number value"
BoolTy -> parseValue (ValueLiteral scalarType . J.Bool) "boolean value"
CustomTy customTypeName -> parseValue (ValueLiteral scalarType) (customTypeName <> " JSON value")
CollectableTypeArray scalarType ->
case scalarType of
StringTy -> parseValue (ArrayLiteral . fmap J.String) "JSON array of strings"
NumberTy -> parseValue (ArrayLiteral . fmap J.Number) "JSON array of numbers"
BoolTy -> parseValue (ArrayLiteral . fmap J.Bool) "JSON array of booleans"
CustomTy customTypeName -> parseValue ArrayLiteral ("JSON array of " <> customTypeName <> " JSON values")
StringTy -> parseValue (ArrayLiteral scalarType . fmap J.String) "JSON array of strings"
NumberTy -> parseValue (ArrayLiteral scalarType . fmap J.Number) "JSON array of numbers"
BoolTy -> parseValue (ArrayLiteral scalarType . fmap J.Bool) "JSON array of booleans"
CustomTy customTypeName -> parseValue (ArrayLiteral scalarType) ("JSON array of " <> customTypeName <> " JSON values")
where
parseValue :: J.FromJSON a => (a -> Literal) -> Text -> m Literal
parseValue toLiteral description =
@ -483,7 +483,7 @@ mkPlan session (SourceConfig {}) ir = do
BoolNot x ->
API.Not <$> (translateBoolExp sourceTableName) x
BoolField (AVColumn c xs) ->
lift $ mkIfZeroOrMany API.And <$> traverse (translateOp (Witch.from $ ciColumn c)) xs
lift $ mkIfZeroOrMany API.And <$> traverse (translateOp (Witch.from $ ciColumn c) (Witch.from . columnTypeToScalarType $ ciType c)) xs
BoolField (AVRelationship relationshipInfo boolExp) -> do
(relationshipName, API.Relationship {..}) <- recordTableRelationshipFromRelInfo sourceTableName relationshipInfo
API.Exists (API.RelatedTable relationshipName) <$> translateBoolExp _rTargetTable boolExp
@ -512,34 +512,35 @@ mkPlan session (SourceConfig {}) ir = do
translateOp ::
API.ColumnName ->
API.ScalarType ->
OpExpG 'DataConnector (UnpreparedValue 'DataConnector) ->
m API.Expression
translateOp columnName opExp = do
translateOp columnName columnType opExp = do
preparedOpExp <- traverse prepareLiterals $ opExp
case preparedOpExp of
AEQ _ (ValueLiteral value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.Equal value
AEQ _ (ArrayLiteral _array) ->
AEQ _ (ValueLiteral scalarType value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.Equal value scalarType
AEQ _ (ArrayLiteral _scalarType _array) ->
throw400 NotSupported "Array literals not supported for AEQ operator"
ANE _ (ValueLiteral value) ->
pure . API.Not $ mkApplyBinaryComparisonOperatorToScalar API.Equal value
ANE _ (ArrayLiteral _array) ->
ANE _ (ValueLiteral scalarType value) ->
pure . API.Not $ mkApplyBinaryComparisonOperatorToScalar API.Equal value scalarType
ANE _ (ArrayLiteral _scalarType _array) ->
throw400 NotSupported "Array literals not supported for ANE operator"
AGT (ValueLiteral value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.GreaterThan value
AGT (ArrayLiteral _array) ->
AGT (ValueLiteral scalarType value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.GreaterThan value scalarType
AGT (ArrayLiteral _scalarType _array) ->
throw400 NotSupported "Array literals not supported for AGT operator"
ALT (ValueLiteral value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.LessThan value
ALT (ArrayLiteral _array) ->
ALT (ValueLiteral scalarType value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.LessThan value scalarType
ALT (ArrayLiteral _scalarType _array) ->
throw400 NotSupported "Array literals not supported for ALT operator"
AGTE (ValueLiteral value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.GreaterThanOrEqual value
AGTE (ArrayLiteral _array) ->
AGTE (ValueLiteral scalarType value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.GreaterThanOrEqual value scalarType
AGTE (ArrayLiteral _scalarType _array) ->
throw400 NotSupported "Array literals not supported for AGTE operator"
ALTE (ValueLiteral value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.LessThanOrEqual value
ALTE (ArrayLiteral _array) ->
ALTE (ValueLiteral scalarType value) ->
pure $ mkApplyBinaryComparisonOperatorToScalar API.LessThanOrEqual value scalarType
ALTE (ArrayLiteral _scalarType _array) ->
throw400 NotSupported "Array literals not supported for ALTE operator"
ANISNULL ->
pure $ API.ApplyUnaryComparisonOperator API.IsNull currentComparisonColumn
@ -569,31 +570,31 @@ mkPlan session (SourceConfig {}) ir = do
Nothing -> pure $ API.ApplyUnaryComparisonOperator (API.CustomUnaryComparisonOperator _cboName) currentComparisonColumn
Just (Left rootOrCurrentColumn) ->
pure $ mkApplyBinaryComparisonOperatorToAnotherColumn (API.CustomBinaryComparisonOperator _cboName) rootOrCurrentColumn
Just (Right (ValueLiteral value)) ->
pure $ mkApplyBinaryComparisonOperatorToScalar (API.CustomBinaryComparisonOperator _cboName) value
Just (Right (ArrayLiteral array)) ->
pure $ API.ApplyBinaryArrayComparisonOperator (API.CustomBinaryArrayComparisonOperator _cboName) currentComparisonColumn array
Just (Right (ValueLiteral scalarType value)) ->
pure $ mkApplyBinaryComparisonOperatorToScalar (API.CustomBinaryComparisonOperator _cboName) value scalarType
Just (Right (ArrayLiteral scalarType array)) ->
pure $ API.ApplyBinaryArrayComparisonOperator (API.CustomBinaryArrayComparisonOperator _cboName) currentComparisonColumn array (Witch.from scalarType)
where
currentComparisonColumn :: API.ComparisonColumn
currentComparisonColumn = API.ComparisonColumn API.CurrentTable columnName
currentComparisonColumn = API.ComparisonColumn API.CurrentTable columnName columnType
mkApplyBinaryComparisonOperatorToAnotherColumn :: API.BinaryComparisonOperator -> RootOrCurrentColumn 'DataConnector -> API.Expression
mkApplyBinaryComparisonOperatorToAnotherColumn operator (RootOrCurrentColumn rootOrCurrent otherColumnName) =
let columnPath = case rootOrCurrent of
IsRoot -> API.QueryTable
IsCurrent -> API.CurrentTable
in API.ApplyBinaryComparisonOperator operator currentComparisonColumn (API.AnotherColumn . API.ComparisonColumn columnPath $ Witch.from otherColumnName)
in API.ApplyBinaryComparisonOperator operator currentComparisonColumn (API.AnotherColumn $ API.ComparisonColumn columnPath (Witch.from otherColumnName) columnType)
inOperator :: Literal -> API.Expression
inOperator literal =
let values = case literal of
ArrayLiteral array -> array
ValueLiteral value -> [value]
in API.ApplyBinaryArrayComparisonOperator API.In currentComparisonColumn values
let (values, scalarType) = case literal of
ArrayLiteral scalarType' array -> (array, scalarType')
ValueLiteral scalarType' value -> ([value], scalarType')
in API.ApplyBinaryArrayComparisonOperator API.In currentComparisonColumn values (Witch.from scalarType)
mkApplyBinaryComparisonOperatorToScalar :: API.BinaryComparisonOperator -> J.Value -> API.Expression
mkApplyBinaryComparisonOperatorToScalar operator value =
API.ApplyBinaryComparisonOperator operator currentComparisonColumn (API.ScalarValue value)
mkApplyBinaryComparisonOperatorToScalar :: API.BinaryComparisonOperator -> J.Value -> ScalarType -> API.Expression
mkApplyBinaryComparisonOperatorToScalar operator value scalarType =
API.ApplyBinaryComparisonOperator operator currentComparisonColumn (API.ScalarValue value (Witch.from scalarType))
-- | Validate if a 'API.QueryRequest' contains any relationships.
queryHasRelations :: API.QueryRequest -> Bool

View File

@ -5,7 +5,7 @@ module Hasura.Backends.DataConnector.API.V0.ColumnSpec (spec, genColumnName, gen
import Data.Aeson.QQ.Simple (aesonQQ)
import Hasura.Backends.DataConnector.API.V0
import Hasura.Backends.DataConnector.API.V0.ScalarSpec (genType)
import Hasura.Backends.DataConnector.API.V0.ScalarSpec (genScalarType)
import Hasura.Generator.Common (defaultRange, genArbitraryAlphaNumText)
import Hasura.Prelude
import Hedgehog
@ -47,6 +47,6 @@ genColumnInfo :: MonadGen m => m ColumnInfo
genColumnInfo =
ColumnInfo
<$> genColumnName
<*> genType
<*> genScalarType
<*> Gen.bool
<*> Gen.maybe (genArbitraryAlphaNumText defaultRange)

View File

@ -16,6 +16,7 @@ import Data.Aeson.QQ.Simple (aesonQQ)
import Hasura.Backends.DataConnector.API.V0
import Hasura.Backends.DataConnector.API.V0.ColumnSpec (genColumnName)
import Hasura.Backends.DataConnector.API.V0.RelationshipsSpec (genRelationshipName)
import Hasura.Backends.DataConnector.API.V0.ScalarSpec (genScalarType)
import Hasura.Backends.DataConnector.API.V0.TableSpec (genTableName)
import Hasura.Generator.Common (defaultRange, genArbitraryAlphaNumText)
import Hasura.Prelude
@ -67,8 +68,8 @@ spec = do
describe "ComparisonColumn" $ do
testToFromJSONToSchema
(ComparisonColumn QueryTable (ColumnName "column_name"))
[aesonQQ|{"path": ["$"], "name": "column_name"}|]
(ComparisonColumn QueryTable (ColumnName "column_name") StringTy)
[aesonQQ|{"path": ["$"], "name": "column_name", "column_type": "string"}|]
jsonOpenApiProperties genComparisonColumn
@ -82,12 +83,12 @@ spec = do
describe "ComparisonValue" $ do
describe "AnotherColumn" $
testToFromJSONToSchema
(AnotherColumn $ ComparisonColumn CurrentTable (ColumnName "my_column_name"))
[aesonQQ|{"type": "column", "column": {"name": "my_column_name"}}|]
(AnotherColumn $ ComparisonColumn CurrentTable (ColumnName "my_column_name") StringTy)
[aesonQQ|{"type": "column", "column": {"name": "my_column_name", "column_type": "string"}}|]
describe "ScalarValue" $
testToFromJSONToSchema
(ScalarValue $ String "scalar value")
[aesonQQ|{"type": "scalar", "value": "scalar value"}|]
(ScalarValue (String "scalar value") StringTy)
[aesonQQ|{"type": "scalar", "value": "scalar value", "value_type": "string"}|]
jsonOpenApiProperties genComparisonValue
@ -111,8 +112,8 @@ spec = do
jsonOpenApiProperties genExistsInTable
describe "Expression" $ do
let comparisonColumn = ComparisonColumn CurrentTable (ColumnName "my_column_name")
let scalarValue = ScalarValue $ String "scalar value"
let comparisonColumn = ComparisonColumn CurrentTable (ColumnName "my_column_name") StringTy
let scalarValue = ScalarValue (String "scalar value") StringTy
let scalarValues = [String "scalar value"]
let unaryComparisonExpression = ApplyUnaryComparisonOperator IsNull comparisonColumn
@ -126,7 +127,7 @@ spec = do
{
"type": "unary_op",
"operator": "is_null",
"column": { "name": "my_column_name" }
"column": { "name": "my_column_name", "column_type": "string" }
}
]
}
@ -142,7 +143,7 @@ spec = do
{
"type": "unary_op",
"operator": "is_null",
"column": { "name": "my_column_name" }
"column": { "name": "my_column_name", "column_type": "string" }
}
]
}
@ -157,7 +158,7 @@ spec = do
"expression": {
"type": "unary_op",
"operator": "is_null",
"column": { "name": "my_column_name" }
"column": { "name": "my_column_name", "column_type": "string" }
}
}
|]
@ -175,7 +176,7 @@ spec = do
"where": {
"type": "unary_op",
"operator": "is_null",
"column": { "name": "my_column_name" }
"column": { "name": "my_column_name", "column_type": "string" }
}
}
|]
@ -187,20 +188,21 @@ spec = do
{
"type": "binary_op",
"operator": "equal",
"column": { "name": "my_column_name" },
"value": {"type": "scalar", "value": "scalar value"}
"column": { "name": "my_column_name", "column_type": "string" },
"value": {"type": "scalar", "value": "scalar value", "value_type": "string"}
}
|]
describe "BinaryArrayComparisonOperator" $ do
testToFromJSONToSchema
(ApplyBinaryArrayComparisonOperator In comparisonColumn scalarValues)
(ApplyBinaryArrayComparisonOperator In comparisonColumn scalarValues StringTy)
[aesonQQ|
{
"type": "binary_arr_op",
"operator": "in",
"column": { "name": "my_column_name" },
"values": ["scalar value"]
"column": { "name": "my_column_name", "column_type": "string" },
"values": ["scalar value"],
"value_type": "string"
}
|]
@ -211,7 +213,7 @@ spec = do
{
"type": "unary_op",
"operator": "is_null",
"column": { "name": "my_column_name" }
"column": { "name": "my_column_name", "column_type": "string" }
}
|]
@ -243,6 +245,7 @@ genComparisonColumn =
ComparisonColumn
<$> genColumnPath
<*> genColumnName
<*> genScalarType
genColumnPath :: MonadGen m => m ColumnPath
genColumnPath =
@ -252,7 +255,7 @@ genComparisonValue :: MonadGen m => m ComparisonValue
genComparisonValue =
Gen.choice
[ AnotherColumn <$> genComparisonColumn,
ScalarValue <$> genValue
ScalarValue <$> genValue <*> genScalarType
]
genExistsInTable :: MonadGen m => m ExistsInTable
@ -267,7 +270,7 @@ genExpression =
Gen.recursive
Gen.choice
[ ApplyBinaryComparisonOperator <$> genBinaryComparisonOperator <*> genComparisonColumn <*> genComparisonValue,
ApplyBinaryArrayComparisonOperator <$> genBinaryArrayComparisonOperator <*> genComparisonColumn <*> (Gen.list defaultRange genValue),
ApplyBinaryArrayComparisonOperator <$> genBinaryArrayComparisonOperator <*> genComparisonColumn <*> (Gen.list defaultRange genValue) <*> genScalarType,
ApplyUnaryComparisonOperator <$> genUnaryComparisonOperator <*> genComparisonColumn
]
[ And <$> genExpressions,

View File

@ -12,6 +12,7 @@ import Hasura.Backends.DataConnector.API.V0.ColumnSpec (genColumnName)
import Hasura.Backends.DataConnector.API.V0.ExpressionSpec (genExpression)
import Hasura.Backends.DataConnector.API.V0.OrderBySpec (genOrderBy)
import Hasura.Backends.DataConnector.API.V0.RelationshipsSpec (genRelationshipName, genTableRelationships)
import Hasura.Backends.DataConnector.API.V0.ScalarSpec (genScalarType)
import Hasura.Backends.DataConnector.API.V0.TableSpec (genTableName)
import Hasura.Generator.Common (defaultRange, genArbitraryAlphaNumText)
import Hasura.Prelude
@ -25,10 +26,11 @@ spec = do
describe "Field" $ do
describe "ColumnField" $
testToFromJSONToSchema
(ColumnField $ ColumnName "my_column_name")
(ColumnField (ColumnName "my_column_name") StringTy)
[aesonQQ|
{ "type": "column",
"column": "my_column_name"
"column": "my_column_name",
"column_type": "string"
}
|]
describe "RelationshipField" $ do
@ -46,7 +48,7 @@ spec = do
describe "Query" $ do
let query =
Query
{ _qFields = Just $ HashMap.fromList [(FieldName "my_field_alias", ColumnField $ ColumnName "my_field_name")],
{ _qFields = Just $ HashMap.fromList [(FieldName "my_field_alias", ColumnField (ColumnName "my_field_name") StringTy)],
_qAggregates = Just $ HashMap.fromList [(FieldName "my_aggregate", StarCount)],
_qLimit = Just 10,
_qOffset = Just 20,
@ -56,7 +58,7 @@ spec = do
testToFromJSONToSchema
query
[aesonQQ|
{ "fields": {"my_field_alias": {"type": "column", "column": "my_field_name"}},
{ "fields": {"my_field_alias": {"type": "column", "column": "my_field_name", "column_type": "string"}},
"aggregates": { "my_aggregate": { "type": "star_count" } },
"limit": 10,
"offset": 20,
@ -145,7 +147,7 @@ genField :: MonadGen m => m Field
genField =
Gen.recursive
Gen.choice
[ColumnField <$> genColumnName]
[ColumnField <$> genColumnName <*> genScalarType]
[RelField <$> genRelationshipField]
genFieldName :: MonadGen m => m FieldName

View File

@ -1,6 +1,6 @@
{-# LANGUAGE QuasiQuotes #-}
module Hasura.Backends.DataConnector.API.V0.ScalarSpec (spec, genType) where
module Hasura.Backends.DataConnector.API.V0.ScalarSpec (spec, genScalarType) where
import Data.Aeson.QQ.Simple (aesonQQ)
import Hasura.Backends.DataConnector.API.V0.Scalar
@ -13,7 +13,7 @@ import Test.Hspec
spec :: Spec
spec = do
describe "Type" $ do
describe "ScalarType" $ do
describe "StringTy" $
testToFromJSONToSchema StringTy [aesonQQ|"string"|]
describe "NumberTy" $
@ -22,8 +22,8 @@ spec = do
testToFromJSONToSchema BoolTy [aesonQQ|"bool"|]
describe "CustomTy" $
testToFromJSONToSchema (CustomTy "foo") [aesonQQ|"foo"|]
jsonOpenApiProperties genType
jsonOpenApiProperties genScalarType
genType :: MonadGen m => m ScalarType
genType =
genScalarType :: MonadGen m => m ScalarType
genScalarType =
Gen.choice [pure StringTy, pure NumberTy, pure BoolTy, CustomTy <$> genArbitraryAlphaNumText defaultRange]