mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-08-16 22:21:06 +03:00
Support joins on nested fields for MongoDB
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/10345 GitOrigin-RevId: 1a4886b7ac5110ddf9233596068810963bde3371
This commit is contained in:
parent
04e21a34af
commit
82fa13db6e
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hasura/dc-api-types",
|
||||
"version": "0.42.0",
|
||||
"version": "0.43.0",
|
||||
"description": "Hasura GraphQL Engine Data Connector Agent API types",
|
||||
"author": "Hasura (https://github.com/hasura/graphql-engine)",
|
||||
"license": "Apache-2.0",
|
||||
|
@ -1334,11 +1334,42 @@
|
||||
"Constraint": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The columns on which you want want to define the foreign key.",
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
],
|
||||
"description": "The columns on which you want want to define the foreign key."
|
||||
},
|
||||
"foreign_table": {
|
||||
"$ref": "#/components/schemas/TableName"
|
||||
@ -1845,11 +1876,42 @@
|
||||
"Relationship": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "A mapping between columns on the source table to columns on the target table",
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
],
|
||||
"description": "A mapping between columns on the source table to columns on the target table"
|
||||
},
|
||||
"relationship_type": {
|
||||
"$ref": "#/components/schemas/RelationshipType"
|
||||
@ -2068,19 +2130,18 @@
|
||||
"$ref": "#/components/schemas/ScalarType"
|
||||
},
|
||||
"name": {
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The name of the column",
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "The name of the column"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"default": [],
|
||||
@ -2620,16 +2681,15 @@
|
||||
"OrderByColumn": {
|
||||
"properties": {
|
||||
"column": {
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -10,7 +10,7 @@ export type ComparisonColumn = {
|
||||
/**
|
||||
* The name of the column
|
||||
*/
|
||||
name: (string | Array<string>);
|
||||
name: (Array<string> | string);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
@ -8,7 +8,7 @@ export type Constraint = {
|
||||
/**
|
||||
* The columns on which you want want to define the foreign key.
|
||||
*/
|
||||
column_mapping: Record<string, string>;
|
||||
column_mapping: Record<string, (Array<string> | string)>;
|
||||
foreign_table: TableName;
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
import type { RedactionExpressionName } from './RedactionExpressionName';
|
||||
|
||||
export type OrderByColumn = {
|
||||
column: (string | Array<string>);
|
||||
column: (Array<string> | string);
|
||||
redaction_expression?: RedactionExpressionName;
|
||||
type: 'column';
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ export type Relationship = {
|
||||
/**
|
||||
* A mapping between columns on the source table to columns on the target table
|
||||
*/
|
||||
column_mapping: Record<string, string>;
|
||||
column_mapping: Record<string, (Array<string> | string)>;
|
||||
relationship_type: RelationshipType;
|
||||
target: Target;
|
||||
};
|
||||
|
10
dc-agents/package-lock.json
generated
10
dc-agents/package-lock.json
generated
@ -24,7 +24,7 @@
|
||||
},
|
||||
"dc-api-types": {
|
||||
"name": "@hasura/dc-api-types",
|
||||
"version": "0.42.0",
|
||||
"version": "0.43.0",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
@ -2227,7 +2227,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.42.0",
|
||||
"@hasura/dc-api-types": "0.43.0",
|
||||
"fastify": "^4.13.0",
|
||||
"mathjs": "^11.0.0",
|
||||
"pino-pretty": "^8.0.0",
|
||||
@ -2547,7 +2547,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.42.0",
|
||||
"@hasura/dc-api-types": "0.43.0",
|
||||
"fastify": "^4.13.0",
|
||||
"fastify-metrics": "^9.2.1",
|
||||
"nanoid": "^3.3.4",
|
||||
@ -2868,7 +2868,7 @@
|
||||
"version": "file:reference",
|
||||
"requires": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.42.0",
|
||||
"@hasura/dc-api-types": "0.43.0",
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
"@types/node": "^16.11.49",
|
||||
"@types/xml2js": "^0.4.11",
|
||||
@ -3080,7 +3080,7 @@
|
||||
"version": "file:sqlite",
|
||||
"requires": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.42.0",
|
||||
"@hasura/dc-api-types": "0.43.0",
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
"@types/node": "^16.11.49",
|
||||
"@types/sqlite3": "^3.1.8",
|
||||
|
4
dc-agents/reference/package-lock.json
generated
4
dc-agents/reference/package-lock.json
generated
@ -10,7 +10,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.42.0",
|
||||
"@hasura/dc-api-types": "0.43.0",
|
||||
"fastify": "^4.13.0",
|
||||
"mathjs": "^11.0.0",
|
||||
"pino-pretty": "^8.0.0",
|
||||
@ -52,7 +52,7 @@
|
||||
"integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ=="
|
||||
},
|
||||
"node_modules/@hasura/dc-api-types": {
|
||||
"version": "0.42.0",
|
||||
"version": "0.43.0",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.42.0",
|
||||
"@hasura/dc-api-types": "0.43.0",
|
||||
"fastify": "^4.13.0",
|
||||
"mathjs": "^11.0.0",
|
||||
"pino-pretty": "^8.0.0",
|
||||
|
@ -175,7 +175,7 @@ export const getSchema = (store: Record<string, StaticData>, config: Config, req
|
||||
? mapObjectValues(table.foreign_keys, constraint => ({
|
||||
...constraint,
|
||||
foreign_table: prefixSchemaToTableName(constraint.foreign_table.map(applyTableNameCasing)),
|
||||
column_mapping: mapObject(constraint.column_mapping, ([outer, inner]) => [applyColumnNameCasing(outer), applyColumnNameCasing(inner)])
|
||||
column_mapping: mapObject(constraint.column_mapping as Record<string, string>, ([outer, inner]) => [applyColumnNameCasing(outer), applyColumnNameCasing(inner)])
|
||||
}))
|
||||
: table.foreign_keys,
|
||||
columns: table.columns?.map(column => ({
|
||||
|
@ -484,7 +484,7 @@ const makeApplyRedaction = (
|
||||
const createFilterExpressionForRelationshipJoin = (row: Record<string, RawScalarValue>, relationship: Relationship): Expression | null => {
|
||||
const columnMappings = Object.entries(relationship.column_mapping);
|
||||
const filterConditions: Expression[] = columnMappings
|
||||
.map(([outerColumnName, innerColumnName]): [RawScalarValue, string] => [row[outerColumnName], innerColumnName])
|
||||
.map(([outerColumnName, innerColumnName]): [RawScalarValue, string] => [row[outerColumnName], innerColumnName as string])
|
||||
.filter((x): x is [RawScalarValue, string] => {
|
||||
const [outerValue, _] = x;
|
||||
return outerValue !== null;
|
||||
|
4
dc-agents/sqlite/package-lock.json
generated
4
dc-agents/sqlite/package-lock.json
generated
@ -10,7 +10,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.42.0",
|
||||
"@hasura/dc-api-types": "0.43.0",
|
||||
"fastify": "^4.13.0",
|
||||
"fastify-metrics": "^9.2.1",
|
||||
"nanoid": "^3.3.4",
|
||||
@ -57,7 +57,7 @@
|
||||
"integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ=="
|
||||
},
|
||||
"node_modules/@hasura/dc-api-types": {
|
||||
"version": "0.42.0",
|
||||
"version": "0.43.0",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.42.0",
|
||||
"@hasura/dc-api-types": "0.43.0",
|
||||
"fastify-metrics": "^9.2.1",
|
||||
"fastify": "^4.13.0",
|
||||
"nanoid": "^3.3.4",
|
||||
|
@ -234,7 +234,7 @@ function generateRelationshipJoinComparisonFragments(relationship: Relationship,
|
||||
return Object
|
||||
.entries(relationship.column_mapping)
|
||||
.map(([sourceColumnName, targetColumnName]) =>
|
||||
`${sourceTablePrefix}${escapeIdentifier(sourceColumnName)} = ${targetTableAlias}.${escapeIdentifier(targetColumnName)}`);
|
||||
`${sourceTablePrefix}${escapeIdentifier(sourceColumnName)} = ${targetTableAlias}.${escapeIdentifier(targetColumnName as string)}`);
|
||||
}
|
||||
|
||||
function generateComparisonColumnFragment(comparisonColumn: ComparisonColumn, queryTableAlias: string, currentTableAlias: string): string {
|
||||
@ -419,7 +419,7 @@ function target_query( // TODO: Rename as `target_query`
|
||||
function relationship(ts: Relationships[], r: Relationship, field: RelationshipField, sourceTableAlias: string): string {
|
||||
const relationshipJoinInfo = {
|
||||
sourceTableAlias,
|
||||
columnMapping: r.column_mapping,
|
||||
columnMapping: r.column_mapping as Record<string, string>,
|
||||
};
|
||||
|
||||
// We force a limit of 1 for object relationships in case the user has configured a manual
|
||||
@ -638,7 +638,7 @@ function generateOrderByAggregateTargetJoinInfo(
|
||||
default: unreachable(element.target["type"]);
|
||||
}
|
||||
});
|
||||
const joinColumns = Object.values(relationship.column_mapping).map(escapeIdentifier);
|
||||
const joinColumns = Object.values(relationship.column_mapping as Record<string, string>).map(escapeIdentifier);
|
||||
const selectColumns = [...joinColumns, aggregateColumnsFragments];
|
||||
const whereClause = whereExpression ? `WHERE ${where_clause(allTableRelationships, whereExpression, relationship.target, subqueryTableAlias)}` : "";
|
||||
const aggregateSubquery = `SELECT ${selectColumns.join(", ")} FROM ${escapeTargetName(relationship.target)} AS ${subqueryTableAlias} ${whereClause} GROUP BY ${joinColumns.join(", ")}`
|
||||
|
@ -965,10 +965,21 @@
|
||||
"BigqueryRelManualNativeQueryConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -991,10 +1002,21 @@
|
||||
"BigqueryRelManualTableConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -1946,10 +1968,21 @@
|
||||
"CitusRelManualNativeQueryConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -1972,10 +2005,21 @@
|
||||
"CitusRelManualTableConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -2954,10 +2998,21 @@
|
||||
"CockroachRelManualNativeQueryConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -2980,10 +3035,21 @@
|
||||
"CockroachRelManualTableConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -3733,7 +3799,17 @@
|
||||
"properties": {
|
||||
"columns": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -3753,7 +3829,17 @@
|
||||
"DataconnectorArrRelUsingFKeyOnSingleColumn": {
|
||||
"properties": {
|
||||
"column": {
|
||||
"type": "string"
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"table": {
|
||||
"items": {
|
||||
@ -4055,7 +4141,17 @@
|
||||
"properties": {
|
||||
"columns": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -4075,7 +4171,17 @@
|
||||
"DataconnectorObjRelRemoteTableSingleColumn": {
|
||||
"properties": {
|
||||
"column": {
|
||||
"type": "string"
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"table": {
|
||||
"items": {
|
||||
@ -4112,10 +4218,41 @@
|
||||
"DataconnectorRelManualNativeQueryConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -4138,10 +4275,41 @@
|
||||
"DataconnectorRelManualTableConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -5825,10 +5993,21 @@
|
||||
"MssqlRelManualNativeQueryConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -5851,10 +6030,21 @@
|
||||
"MssqlRelManualTableConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -7208,10 +7398,21 @@
|
||||
"PostgresRelManualNativeQueryConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -7234,10 +7435,21 @@
|
||||
"PostgresRelManualTableConfig": {
|
||||
"properties": {
|
||||
"column_mapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"insertion_order": {
|
||||
"enum": [
|
||||
@ -7933,12 +8145,28 @@
|
||||
"properties": {
|
||||
"foreign_key_constraint_on": {
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
|
@ -177,7 +177,7 @@ tests = describe "Aggregate Query Tests" $ do
|
||||
API.Relationship
|
||||
{ _rTarget = mkTableTarget "Album",
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ArtistId", API.mkColumnSelector $ API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
@ -300,7 +300,7 @@ tests = describe "Aggregate Query Tests" $ do
|
||||
API.Relationship
|
||||
{ _rTarget = mkTableTarget "InvoiceLine",
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "InvoiceId", API.ColumnName "InvoiceId")]
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "InvoiceId", API.mkColumnSelector $ API.ColumnName "InvoiceId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -18,7 +18,7 @@ import Harness.Test.BackendType qualified as BackendType
|
||||
import Harness.Test.Fixture qualified as Fixture
|
||||
import Harness.TestEnvironment (GlobalTestEnvironment, TestEnvironment)
|
||||
import Harness.Yaml (shouldBeYaml)
|
||||
import Hasura.Backends.DataConnector.API (ColumnName (..), ScalarType (..), ScalarValue (..))
|
||||
import Hasura.Backends.DataConnector.API (ColumnName (..), ScalarType (..), ScalarValue (..), mkColumnSelector)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Backends.DataConnector.API.V0.Expression
|
||||
import Hasura.Prelude
|
||||
|
@ -189,7 +189,7 @@ tests = do
|
||||
API.Relationship
|
||||
{ API._rTarget = mkTableTarget "Artist",
|
||||
API._rRelationshipType = API.ObjectRelationship,
|
||||
API._rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
API._rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ArtistId", API.mkColumnSelector $ API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
@ -298,7 +298,7 @@ tests = do
|
||||
API.Relationship
|
||||
{ API._rTarget = mkTableTarget "Artist",
|
||||
API._rRelationshipType = API.ObjectRelationship,
|
||||
API._rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
API._rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ArtistId", API.mkColumnSelector $ API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -181,7 +181,7 @@ tests = do
|
||||
API.Relationship
|
||||
{ API._rTarget = mkTableTarget "Artist",
|
||||
API._rRelationshipType = API.ObjectRelationship,
|
||||
API._rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
API._rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ArtistId", API.mkColumnSelector $ API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -200,7 +200,7 @@ tests = describe "Order By Tests" $ do
|
||||
API.Relationship
|
||||
{ _rTarget = mkTableTarget "Album",
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ArtistId", API.mkColumnSelector $ API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -228,7 +228,7 @@ tests = describe "Object Relationships Tests" $ do
|
||||
API.Relationship
|
||||
{ _rTarget = mkTableTarget "Genre",
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "GenreId", API.ColumnName "GenreId")]
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "GenreId", API.mkColumnSelector $ API.ColumnName "GenreId")]
|
||||
}
|
||||
),
|
||||
( API.RelationshipName "MediaType",
|
||||
@ -236,8 +236,9 @@ tests = describe "Object Relationships Tests" $ do
|
||||
{ _rTarget = mkTableTarget "MediaType",
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping =
|
||||
HashMap.fromList
|
||||
[(API.ColumnName "MediaTypeId", API.ColumnName "MediaTypeId")]
|
||||
API.ColumnPathMapping
|
||||
$ HashMap.fromList
|
||||
[(API.mkColumnSelector $ API.ColumnName "MediaTypeId", API.mkColumnSelector $ API.ColumnName "MediaTypeId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
@ -354,7 +355,9 @@ tests = describe "Object Relationships Tests" $ do
|
||||
API.Relationship
|
||||
{ _rTarget = mkTableTarget "Album",
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "AlbumId", API.ColumnName "AlbumId")]
|
||||
_rColumnMapping =
|
||||
API.ColumnPathMapping
|
||||
$ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "AlbumId", API.mkColumnSelector $ API.ColumnName "AlbumId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
@ -368,7 +371,9 @@ tests = describe "Object Relationships Tests" $ do
|
||||
API.Relationship
|
||||
{ _rTarget = mkTableTarget "Artist",
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
_rColumnMapping =
|
||||
API.ColumnPathMapping
|
||||
$ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ArtistId", API.mkColumnSelector $ API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
@ -449,7 +454,7 @@ tests = describe "Object Relationships Tests" $ do
|
||||
API.Relationship
|
||||
{ _rTarget = mkTableTarget "Employee",
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "SupportRepId", API.ColumnName "EmployeeId")]
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "SupportRepId", API.mkColumnSelector $ API.ColumnName "EmployeeId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
@ -463,7 +468,7 @@ tests = describe "Object Relationships Tests" $ do
|
||||
API.Relationship
|
||||
{ _rTarget = mkTableTarget "Customer",
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "EmployeeId", API.ColumnName "SupportRepId")]
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "EmployeeId", API.mkColumnSelector $ API.ColumnName "SupportRepId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -203,7 +203,7 @@ tests = do
|
||||
API.Relationship
|
||||
{ API._rTarget = mkTableTarget "Genre",
|
||||
API._rRelationshipType = API.ObjectRelationship,
|
||||
API._rColumnMapping = HashMap.fromList [(API.ColumnName "GenreId", API.ColumnName "GenreId")]
|
||||
API._rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "GenreId", API.mkColumnSelector $ API.ColumnName "GenreId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
@ -394,7 +394,7 @@ tests = do
|
||||
API.Relationship
|
||||
{ API._rTarget = mkTableTarget "Genre",
|
||||
API._rRelationshipType = API.ObjectRelationship,
|
||||
API._rColumnMapping = HashMap.fromList [(API.ColumnName "GenreId", API.ColumnName "GenreId")]
|
||||
API._rColumnMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "GenreId", API.mkColumnSelector $ API.ColumnName "GenreId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
module Hasura.Backends.DataConnector.API.V0.Column
|
||||
( ColumnName (..),
|
||||
ColumnSelector (..),
|
||||
mkColumnSelector,
|
||||
ColumnType (..),
|
||||
ColumnInfo (..),
|
||||
ciName,
|
||||
@ -13,19 +15,24 @@ module Hasura.Backends.DataConnector.API.V0.Column
|
||||
ciUpdatable,
|
||||
ciValueGenerated,
|
||||
ColumnValueGenerationStrategy (..),
|
||||
ColumnPathMapping (..),
|
||||
)
|
||||
where
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
import Autodocodec
|
||||
import Autodocodec.Extended
|
||||
import Autodocodec.OpenAPI ()
|
||||
import Control.DeepSeq (NFData)
|
||||
import Control.Lens.TH (makeLenses)
|
||||
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
|
||||
import Data.Bitraversable (bitraverse)
|
||||
import Data.Data (Data)
|
||||
import Data.Either.Extra (maybeToEither)
|
||||
import Data.HashMap.Strict (HashMap)
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.Hashable (Hashable)
|
||||
import Data.List.NonEmpty (NonEmpty (..))
|
||||
import Data.OpenApi (ToSchema)
|
||||
import Data.Text (Text)
|
||||
import GHC.Generics (Generic)
|
||||
@ -46,6 +53,31 @@ instance HasCodec ColumnName where
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
data ColumnSelector
|
||||
= ColumnSelectorPath (NonEmpty ColumnName)
|
||||
| ColumnSelectorColumn (ColumnName)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec ColumnSelector
|
||||
deriving anyclass (Hashable, NFData)
|
||||
|
||||
instance HasCodec ColumnSelector where
|
||||
codec = disjointMatchChoiceCodec pathCodec columnCodec chooser
|
||||
where
|
||||
pathCodec = dimapCodec ColumnSelectorPath id (codec @(NonEmpty ColumnName))
|
||||
columnCodec = dimapCodec ColumnSelectorColumn id (codec @ColumnName)
|
||||
chooser = \case
|
||||
ColumnSelectorPath p -> Left p
|
||||
ColumnSelectorColumn c -> Right c
|
||||
|
||||
instance FromJSONKey ColumnSelector
|
||||
|
||||
instance ToJSONKey ColumnSelector
|
||||
|
||||
mkColumnSelector :: ColumnName -> ColumnSelector
|
||||
mkColumnSelector = ColumnSelectorColumn
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
data ColumnType
|
||||
= ColumnTypeScalar API.V0.Scalar.ScalarType
|
||||
| ColumnTypeObject G.Name
|
||||
@ -135,3 +167,33 @@ instance HasCodec ColumnValueGenerationStrategy where
|
||||
]
|
||||
|
||||
$(makeLenses ''ColumnInfo)
|
||||
|
||||
newtype ColumnPathMapping = ColumnPathMapping {unColumnPathMapping :: HashMap ColumnSelector ColumnSelector}
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
deriving newtype (NFData, Hashable)
|
||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec ColumnPathMapping
|
||||
|
||||
-- If all keys in the ColumnPathMapping are ColumnSelectors with a single column then we
|
||||
-- want to represent the mapping as a JSON object with the source columns as properties
|
||||
-- (using `codec @(HashMap ColumnName ColumnSelector)).
|
||||
-- This is required for backwards compatibility of the DC API.
|
||||
-- If some of the keys are not singletons then we can't use a JSON object so we use
|
||||
-- an array of pairs instead, as provided by `codec @(HashMap ColumnSelector ColumnSelector)`.
|
||||
instance HasCodec ColumnPathMapping where
|
||||
codec =
|
||||
matchChoiceCodec
|
||||
(dimapCodec ColumnPathMapping unColumnPathMapping $ codec @(HashMap ColumnSelector ColumnSelector))
|
||||
(dimapCodec columnMappingToColumnPathMapping id $ codec @(HashMap ColumnName ColumnSelector))
|
||||
\m -> maybeToEither m (tryColumnPathMappingToColumnMapping m)
|
||||
where
|
||||
columnMappingToColumnPathMapping :: HashMap ColumnName ColumnSelector -> ColumnPathMapping
|
||||
columnMappingToColumnPathMapping = ColumnPathMapping . HashMap.mapKeys mkColumnSelector
|
||||
|
||||
tryColumnPathMappingToColumnMapping :: ColumnPathMapping -> Maybe (HashMap ColumnName ColumnSelector)
|
||||
tryColumnPathMappingToColumnMapping =
|
||||
fmap HashMap.fromList . traverse (bitraverse tryColumnSelectorToColumnName pure) . HashMap.toList . unColumnPathMapping
|
||||
|
||||
tryColumnSelectorToColumnName :: ColumnSelector -> Maybe ColumnName
|
||||
tryColumnSelectorToColumnName = \case
|
||||
ColumnSelectorColumn columnName -> Just columnName
|
||||
_ -> Nothing
|
||||
|
@ -14,8 +14,6 @@ module Hasura.Backends.DataConnector.API.V0.Expression
|
||||
ccColumnType,
|
||||
ccRedactionExpression,
|
||||
ColumnPath (..),
|
||||
ColumnSelector (..),
|
||||
mkColumnSelector,
|
||||
ComparisonValue (..),
|
||||
TargetRedactionExpressions (..),
|
||||
RedactionExpressionName (..),
|
||||
@ -32,8 +30,6 @@ import Data.Data (Data)
|
||||
import Data.HashMap.Strict (HashMap)
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.Hashable (Hashable)
|
||||
import Data.List.NonEmpty (NonEmpty (..))
|
||||
import Data.List.NonEmpty qualified as NonEmpty
|
||||
import Data.OpenApi (ToSchema)
|
||||
import Data.Set (Set)
|
||||
import Data.Text (Text)
|
||||
@ -258,7 +254,7 @@ data ComparisonColumn = ComparisonColumn
|
||||
{ -- | The path to the table that contains the specified column.
|
||||
_ccPath :: ColumnPath,
|
||||
-- | The name of the column
|
||||
_ccName :: ColumnSelector,
|
||||
_ccName :: API.V0.ColumnSelector,
|
||||
-- | The scalar type of the column
|
||||
_ccColumnType :: API.V0.ScalarType,
|
||||
-- | If present, the name of the redaction expression to evaluate.
|
||||
@ -309,20 +305,6 @@ instance HasCodec ColumnPath where
|
||||
CurrentTable -> []
|
||||
QueryTable -> ["$"]
|
||||
|
||||
newtype ColumnSelector = ColumnSelector {unColumnSelector :: NonEmpty API.V0.ColumnName}
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec ColumnSelector
|
||||
deriving anyclass (Hashable, NFData)
|
||||
|
||||
instance HasCodec ColumnSelector where
|
||||
codec = bimapCodec dec enc oneOrManyCodec
|
||||
where
|
||||
dec = maybe (Left "Unexpected empty list in ColumnSelector") (Right . ColumnSelector) . NonEmpty.nonEmpty
|
||||
enc = NonEmpty.toList . unColumnSelector
|
||||
|
||||
mkColumnSelector :: API.V0.ColumnName -> ColumnSelector
|
||||
mkColumnSelector = ColumnSelector . NonEmpty.singleton
|
||||
|
||||
-- | A serializable representation of comparison values used in comparisons inside 'Expression's.
|
||||
data ComparisonValue
|
||||
= -- | Allows a comparison to a column on the current table or another table
|
||||
|
@ -30,6 +30,7 @@ import Data.List.NonEmpty (NonEmpty)
|
||||
import Data.OpenApi (ToSchema)
|
||||
import GHC.Generics (Generic)
|
||||
import Hasura.Backends.DataConnector.API.V0.Aggregate qualified as API.V0
|
||||
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.Relationships qualified as API.V0
|
||||
import Prelude
|
||||
|
@ -33,6 +33,7 @@ module Hasura.Backends.DataConnector.API.V0.Query
|
||||
qrAggregates,
|
||||
qrInterpolatedQueries,
|
||||
FieldValue,
|
||||
unFieldValue,
|
||||
mkColumnFieldValue,
|
||||
mkRelationshipFieldValue,
|
||||
mkNestedObjFieldValue,
|
||||
@ -299,7 +300,7 @@ instance HasStatus QueryResponse where
|
||||
-- field values (mainly for testing purposes), we must compare them using 'QueryResponse',
|
||||
-- since raw JSON comparisons will show up immaterial differences between null properties
|
||||
-- and missing properties (which we consider to be the same thing here).
|
||||
newtype FieldValue = FieldValue J.Value
|
||||
newtype FieldValue = FieldValue {unFieldValue :: J.Value}
|
||||
deriving (ToJSON, FromJSON, ToSchema) via Autodocodec FieldValue
|
||||
|
||||
instance Eq FieldValue where
|
||||
|
@ -30,6 +30,7 @@ import Control.DeepSeq (NFData)
|
||||
import Control.Lens (makeLenses, makePrisms)
|
||||
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
|
||||
import Data.Data (Data)
|
||||
import Data.HashMap.Strict (HashMap)
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.Hashable (Hashable)
|
||||
import Data.OpenApi (ToSchema)
|
||||
@ -43,13 +44,13 @@ import Hasura.Backends.DataConnector.API.V0.Target qualified as API.V0
|
||||
import Prelude
|
||||
|
||||
data Relationships = RTable TableRelationships | RFunction FunctionRelationships | RInterpolated InterpolatedRelationships
|
||||
deriving stock (Eq, Ord, Show, Generic, Data)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec Relationships
|
||||
|
||||
pattern RTableRelationships :: API.V0.TableName -> HashMap.HashMap RelationshipName Relationship -> Relationships
|
||||
pattern RTableRelationships :: API.V0.TableName -> HashMap RelationshipName Relationship -> Relationships
|
||||
pattern RTableRelationships source rels = RTable (TableRelationships source rels)
|
||||
|
||||
pattern RFunctionRelationships :: API.V0.FunctionName -> HashMap.HashMap RelationshipName Relationship -> Relationships
|
||||
pattern RFunctionRelationships :: API.V0.FunctionName -> HashMap RelationshipName Relationship -> Relationships
|
||||
pattern RFunctionRelationships source rels = RFunction (FunctionRelationships source rels)
|
||||
|
||||
instance HasCodec Relationships where
|
||||
@ -71,9 +72,9 @@ instance HasCodec Relationships where
|
||||
|
||||
data InterpolatedRelationships = InterpolatedRelationships
|
||||
{ _irSource :: API.V0.InterpolatedQueryId,
|
||||
_irRelationships :: HashMap.HashMap RelationshipName Relationship
|
||||
_irRelationships :: HashMap RelationshipName Relationship
|
||||
}
|
||||
deriving stock (Eq, Ord, Show, Generic, Data)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
|
||||
instance HasObjectCodec InterpolatedRelationships where
|
||||
objectCodec =
|
||||
@ -84,9 +85,9 @@ instance HasObjectCodec InterpolatedRelationships where
|
||||
-- NOTE: Prefix is `trel` due to TableRequest conflicting with `tr` prefix.
|
||||
data TableRelationships = TableRelationships
|
||||
{ _trelSourceTable :: API.V0.TableName,
|
||||
_trelRelationships :: HashMap.HashMap RelationshipName Relationship
|
||||
_trelRelationships :: HashMap RelationshipName Relationship
|
||||
}
|
||||
deriving stock (Eq, Ord, Show, Generic, Data)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
|
||||
instance HasObjectCodec TableRelationships where
|
||||
objectCodec =
|
||||
@ -96,9 +97,9 @@ instance HasObjectCodec TableRelationships where
|
||||
|
||||
data FunctionRelationships = FunctionRelationships
|
||||
{ _frelSourceFunction :: API.V0.FunctionName,
|
||||
_frelRelationships :: HashMap.HashMap RelationshipName Relationship
|
||||
_frelRelationships :: HashMap RelationshipName Relationship
|
||||
}
|
||||
deriving stock (Eq, Ord, Show, Generic, Data)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
|
||||
instance HasObjectCodec FunctionRelationships where
|
||||
objectCodec =
|
||||
@ -110,9 +111,9 @@ instance HasObjectCodec FunctionRelationships where
|
||||
data Relationship = Relationship
|
||||
{ _rTarget :: API.V0.Target,
|
||||
_rRelationshipType :: RelationshipType,
|
||||
_rColumnMapping :: HashMap.HashMap SourceColumnName TargetColumnName
|
||||
_rColumnMapping :: API.V0.ColumnPathMapping
|
||||
}
|
||||
deriving stock (Eq, Ord, Show, Generic, Data)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec Relationship
|
||||
|
||||
instance HasCodec Relationship where
|
||||
@ -140,9 +141,9 @@ instance HasCodec RelationshipType where
|
||||
named "RelationshipType" $
|
||||
stringConstCodec [(ObjectRelationship, "object"), (ArrayRelationship, "array")]
|
||||
|
||||
type SourceColumnName = API.V0.ColumnName
|
||||
type SourceColumnName = API.V0.ColumnSelector
|
||||
|
||||
type TargetColumnName = API.V0.ColumnName
|
||||
type TargetColumnName = API.V0.ColumnSelector
|
||||
|
||||
$(makeLenses 'TableRelationships)
|
||||
$(makeLenses 'Relationship)
|
||||
|
@ -122,7 +122,7 @@ instance HasCodec TableType where
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
newtype ForeignKeys = ForeignKeys {_unForeignKeys :: HashMap ConstraintName Constraint}
|
||||
deriving stock (Eq, Ord, Show, Generic, Data)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
deriving anyclass (NFData, Hashable)
|
||||
deriving (FromJSON, ToJSON) via Autodocodec ForeignKeys
|
||||
|
||||
@ -138,9 +138,9 @@ newtype ConstraintName = ConstraintName {unConstraintName :: Text}
|
||||
|
||||
data Constraint = Constraint
|
||||
{ _cForeignTable :: TableName,
|
||||
_cColumnMapping :: HashMap API.V0.ColumnName API.V0.ColumnName
|
||||
_cColumnMapping :: API.V0.ColumnPathMapping
|
||||
}
|
||||
deriving stock (Eq, Ord, Show, Generic, Data)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
deriving anyclass (NFData, Hashable)
|
||||
deriving (FromJSON, ToJSON) via Autodocodec Constraint
|
||||
|
||||
|
@ -155,7 +155,7 @@ albumsRelationshipName = API.RelationshipName "Albums"
|
||||
|
||||
artistsTableRelationships :: API.TableRelationships
|
||||
artistsTableRelationships =
|
||||
let joinFieldMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
let joinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ArtistId", API.mkColumnSelector $ API.ColumnName "ArtistId")]
|
||||
in API.TableRelationships
|
||||
artistsTableName
|
||||
( HashMap.fromList
|
||||
@ -175,8 +175,8 @@ albumsRowsById =
|
||||
|
||||
albumsTableRelationships :: API.TableRelationships
|
||||
albumsTableRelationships =
|
||||
let artistsJoinFieldMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
tracksJoinFieldMapping = HashMap.fromList [(API.ColumnName "AlbumId", API.ColumnName "AlbumId")]
|
||||
let artistsJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ArtistId", API.mkColumnSelector $ API.ColumnName "ArtistId")]
|
||||
tracksJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "AlbumId", API.mkColumnSelector $ API.ColumnName "AlbumId")]
|
||||
in API.TableRelationships
|
||||
albumsTableName
|
||||
( HashMap.fromList
|
||||
@ -203,8 +203,8 @@ customersRowsById =
|
||||
|
||||
customersTableRelationships :: API.TableRelationships
|
||||
customersTableRelationships =
|
||||
let supportRepJoinFieldMapping = HashMap.fromList [(API.ColumnName "SupportRepId", API.ColumnName "EmployeeId")]
|
||||
invoicesJoinFieldMapping = HashMap.fromList [(API.ColumnName "CustomerId", API.ColumnName "CustomerId")]
|
||||
let supportRepJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "SupportRepId", API.mkColumnSelector $ API.ColumnName "EmployeeId")]
|
||||
invoicesJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "CustomerId", API.mkColumnSelector $ API.ColumnName "CustomerId")]
|
||||
in API.TableRelationships
|
||||
customersTableName
|
||||
( HashMap.fromList
|
||||
@ -231,8 +231,8 @@ employeesRowsById =
|
||||
|
||||
employeesTableRelationships :: API.TableRelationships
|
||||
employeesTableRelationships =
|
||||
let supportRepJoinFieldMapping = HashMap.fromList [(API.ColumnName "EmployeeId", API.ColumnName "SupportRepId")]
|
||||
reportsToEmployeeJoinFieldMapping = HashMap.fromList [(API.ColumnName "ReportsTo", API.ColumnName "EmployeeId")]
|
||||
let supportRepJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "EmployeeId", API.mkColumnSelector $ API.ColumnName "SupportRepId")]
|
||||
reportsToEmployeeJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "ReportsTo", API.mkColumnSelector $ API.ColumnName "EmployeeId")]
|
||||
in API.TableRelationships
|
||||
employeesTableName
|
||||
( HashMap.fromList
|
||||
@ -259,8 +259,8 @@ invoicesRowsById =
|
||||
|
||||
invoicesTableRelationships :: API.TableRelationships
|
||||
invoicesTableRelationships =
|
||||
let invoiceLinesJoinFieldMapping = HashMap.fromList [(API.ColumnName "InvoiceId", API.ColumnName "InvoiceId")]
|
||||
customersJoinFieldMapping = HashMap.fromList [(API.ColumnName "CustomerId", API.ColumnName "CustomerId")]
|
||||
let invoiceLinesJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "InvoiceId", API.mkColumnSelector $ API.ColumnName "InvoiceId")]
|
||||
customersJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "CustomerId", API.mkColumnSelector $ API.ColumnName "CustomerId")]
|
||||
in API.TableRelationships
|
||||
invoicesTableName
|
||||
( HashMap.fromList
|
||||
@ -280,8 +280,8 @@ invoiceLinesRows = sortBy (API.FieldName "InvoiceLineId") $ readTableFromXmlInto
|
||||
|
||||
invoiceLinesTableRelationships :: API.TableRelationships
|
||||
invoiceLinesTableRelationships =
|
||||
let invoiceJoinFieldMapping = HashMap.fromList [(API.ColumnName "InvoiceId", API.ColumnName "InvoiceId")]
|
||||
tracksJoinFieldMapping = HashMap.fromList [(API.ColumnName "TrackId", API.ColumnName "TrackId")]
|
||||
let invoiceJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "InvoiceId", API.mkColumnSelector $ API.ColumnName "InvoiceId")]
|
||||
tracksJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "TrackId", API.mkColumnSelector $ API.ColumnName "TrackId")]
|
||||
in API.TableRelationships
|
||||
invoiceLinesTableName
|
||||
( HashMap.fromList
|
||||
@ -314,11 +314,11 @@ tracksRowsById =
|
||||
|
||||
tracksTableRelationships :: API.TableRelationships
|
||||
tracksTableRelationships =
|
||||
let invoiceLinesJoinFieldMapping = HashMap.fromList [(API.ColumnName "TrackId", API.ColumnName "TrackId")]
|
||||
mediaTypeJoinFieldMapping = HashMap.fromList [(API.ColumnName "MediaTypeId", API.ColumnName "MediaTypeId")]
|
||||
albumJoinFieldMapping = HashMap.fromList [(API.ColumnName "AlbumId", API.ColumnName "AlbumId")]
|
||||
genreJoinFieldMapping = HashMap.fromList [(API.ColumnName "GenreId", API.ColumnName "GenreId")]
|
||||
playlistTracksJoinFieldMapping = HashMap.fromList [(API.ColumnName "TrackId", API.ColumnName "TrackId")]
|
||||
let invoiceLinesJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "TrackId", API.mkColumnSelector $ API.ColumnName "TrackId")]
|
||||
mediaTypeJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "MediaTypeId", API.mkColumnSelector $ API.ColumnName "MediaTypeId")]
|
||||
albumJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "AlbumId", API.mkColumnSelector $ API.ColumnName "AlbumId")]
|
||||
genreJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "GenreId", API.mkColumnSelector $ API.ColumnName "GenreId")]
|
||||
playlistTracksJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "TrackId", API.mkColumnSelector $ API.ColumnName "TrackId")]
|
||||
in API.TableRelationships
|
||||
tracksTableName
|
||||
( HashMap.fromList
|
||||
@ -359,7 +359,7 @@ mkFibonacciRows n = take n $ fibonacciRow <$> fibs
|
||||
|
||||
genresTableRelationships :: API.TableRelationships
|
||||
genresTableRelationships =
|
||||
let joinFieldMapping = HashMap.fromList [(API.ColumnName "GenreId", API.ColumnName "GenreId")]
|
||||
let joinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "GenreId", API.mkColumnSelector $ API.ColumnName "GenreId")]
|
||||
in API.TableRelationships
|
||||
genresTableName
|
||||
( HashMap.fromList
|
||||
@ -538,7 +538,13 @@ mkTestData schemaResponse testConfig =
|
||||
formatTableRelationships :: API.TableRelationships -> API.TableRelationships
|
||||
formatTableRelationships =
|
||||
prefixTableRelationships
|
||||
>>> API.trelRelationships . traverse . API.rColumnMapping %~ (HashMap.toList >>> fmap (bimap (formatColumnName testConfig) (formatColumnName testConfig)) >>> HashMap.fromList)
|
||||
>>> API.trelRelationships . traverse . API.rColumnMapping
|
||||
%~ ( API.unColumnPathMapping
|
||||
>>> HashMap.toList
|
||||
>>> fmap (bimap (formatColumnSelector testConfig) (formatColumnSelector testConfig))
|
||||
>>> HashMap.fromList
|
||||
>>> API.ColumnPathMapping
|
||||
)
|
||||
|
||||
prefixTableRelationships :: API.TableRelationships -> API.TableRelationships
|
||||
prefixTableRelationships =
|
||||
@ -623,7 +629,7 @@ formatTableInfo testConfig =
|
||||
>>> API.tiPrimaryKey . _Just . traverse %~ formatColumnName testConfig
|
||||
>>> API.tiForeignKeys . API.unForeignKeys . traverse
|
||||
%~ ( API.cForeignTable %~ formatTableName testConfig
|
||||
>>> API.cColumnMapping %~ (HashMap.toList >>> fmap (bimap (formatColumnName testConfig) (formatColumnName testConfig)) >>> HashMap.fromList)
|
||||
>>> API.cColumnMapping %~ (API.unColumnPathMapping >>> HashMap.toList >>> fmap (bimap (formatColumnSelector testConfig) (formatColumnSelector testConfig)) >>> HashMap.fromList >>> API.ColumnPathMapping)
|
||||
)
|
||||
|
||||
applyTableNamePrefix :: [Text] -> API.TableName -> API.TableName
|
||||
@ -647,6 +653,11 @@ applyNameCasing casing text = case casing of
|
||||
formatColumnName :: TestConfig -> API.ColumnName -> API.ColumnName
|
||||
formatColumnName TestConfig {..} = API.ColumnName . applyNameCasing _tcColumnNameCasing . API.unColumnName
|
||||
|
||||
formatColumnSelector :: TestConfig -> API.ColumnSelector -> API.ColumnSelector
|
||||
formatColumnSelector testConfig = \case
|
||||
API.ColumnSelectorPath p -> API.ColumnSelectorPath $ formatColumnName testConfig <$> p
|
||||
API.ColumnSelectorColumn c -> API.ColumnSelectorColumn $ formatColumnName testConfig c
|
||||
|
||||
columnField :: API.SchemaResponse -> TestConfig -> API.TableName -> Text -> API.Field
|
||||
columnField schemaResponse testConfig tableName columnName =
|
||||
API.ColumnField columnName' scalarType Nothing
|
||||
|
@ -116,7 +116,7 @@ spec testConfig API.Capabilities {} = describe "supports functions" $ preloadAge
|
||||
]
|
||||
query' = Data.emptyQuery & qFields ?~ fields
|
||||
authorRelationship =
|
||||
let authorsJoinFieldMapping = HashMap.fromList [(API.ColumnName "author_id", API.ColumnName "id")]
|
||||
let authorsJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "author_id", API.mkColumnSelector $ API.ColumnName "id")]
|
||||
in API.FunctionRelationships
|
||||
_ftdSearchArticlesFunctionName
|
||||
( HashMap.fromList
|
||||
@ -164,7 +164,7 @@ spec testConfig API.Capabilities {} = describe "supports functions" $ preloadAge
|
||||
(API.ScalarValueComparison (API.ScalarValue (Number 10) (API.ScalarType "number")))
|
||||
query' = Data.emptyQuery & qFields ?~ fields & qWhere ?~ whereClause & qLimit ?~ 2
|
||||
authorRelationship =
|
||||
let authorsJoinFieldMapping = HashMap.fromList [(API.ColumnName "author_id", API.ColumnName "id")]
|
||||
let authorsJoinFieldMapping = API.ColumnPathMapping $ HashMap.fromList [(API.mkColumnSelector $ API.ColumnName "author_id", API.mkColumnSelector $ API.ColumnName "id")]
|
||||
in API.FunctionRelationships
|
||||
_ftdSearchArticlesFunctionName
|
||||
( HashMap.fromList
|
||||
|
@ -220,7 +220,12 @@ schema =
|
||||
API._tiDescription = Just "Collection of music albums created by artists",
|
||||
API._tiForeignKeys =
|
||||
API.ForeignKeys
|
||||
$ HashMap.singleton (API.ConstraintName "Artist") (API.Constraint (mkTableName "Artist") (HashMap.singleton (API.ColumnName "ArtistId") (API.ColumnName "ArtistId"))),
|
||||
$ HashMap.singleton
|
||||
(API.ConstraintName "Artist")
|
||||
( API.Constraint
|
||||
(mkTableName "Artist")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "ArtistId") (API.mkColumnSelector $ API.ColumnName "ArtistId"))
|
||||
),
|
||||
API._tiInsertable = True,
|
||||
API._tiUpdatable = True,
|
||||
API._tiDeletable = True
|
||||
@ -351,7 +356,12 @@ schema =
|
||||
API._tiDescription = Just "Collection of customers who can buy tracks",
|
||||
API._tiForeignKeys =
|
||||
API.ForeignKeys
|
||||
$ HashMap.singleton (API.ConstraintName "CustomerSupportRep") (API.Constraint (mkTableName "Employee") (HashMap.singleton (API.ColumnName "SupportRepId") (API.ColumnName "EmployeeId"))),
|
||||
$ HashMap.singleton
|
||||
(API.ConstraintName "CustomerSupportRep")
|
||||
( API.Constraint
|
||||
(mkTableName "Employee")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "SupportRepId") (API.mkColumnSelector $ API.ColumnName "EmployeeId"))
|
||||
),
|
||||
API._tiInsertable = True,
|
||||
API._tiUpdatable = True,
|
||||
API._tiDeletable = True
|
||||
@ -500,7 +510,12 @@ schema =
|
||||
API._tiDescription = Just "Collection of employees who work for the business",
|
||||
API._tiForeignKeys =
|
||||
API.ForeignKeys
|
||||
$ HashMap.singleton (API.ConstraintName "EmployeeReportsTo") (API.Constraint (mkTableName "Employee") (HashMap.singleton (API.ColumnName "ReportsTo") (API.ColumnName "EmployeeId"))),
|
||||
$ HashMap.singleton
|
||||
(API.ConstraintName "EmployeeReportsTo")
|
||||
( API.Constraint
|
||||
(mkTableName "Employee")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "ReportsTo") (API.mkColumnSelector $ API.ColumnName "EmployeeId"))
|
||||
),
|
||||
API._tiInsertable = True,
|
||||
API._tiUpdatable = True,
|
||||
API._tiDeletable = True
|
||||
@ -626,7 +641,9 @@ schema =
|
||||
API._tiForeignKeys =
|
||||
API.ForeignKeys
|
||||
$ HashMap.singleton (API.ConstraintName "InvoiceCustomer")
|
||||
$ API.Constraint (mkTableName "Customer") (HashMap.singleton (API.ColumnName "CustomerId") (API.ColumnName "CustomerId")),
|
||||
$ API.Constraint
|
||||
(mkTableName "Customer")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "CustomerId") (API.mkColumnSelector $ API.ColumnName "CustomerId")),
|
||||
API._tiInsertable = True,
|
||||
API._tiUpdatable = True,
|
||||
API._tiDeletable = True
|
||||
@ -686,8 +703,16 @@ schema =
|
||||
API._tiForeignKeys =
|
||||
API.ForeignKeys
|
||||
$ HashMap.fromList
|
||||
[ (API.ConstraintName "Invoice", API.Constraint (mkTableName "Invoice") (HashMap.singleton (API.ColumnName "InvoiceId") (API.ColumnName "InvoiceId"))),
|
||||
(API.ConstraintName "Track", API.Constraint (mkTableName "Track") (HashMap.singleton (API.ColumnName "TrackId") (API.ColumnName "TrackId")))
|
||||
[ ( API.ConstraintName "Invoice",
|
||||
API.Constraint
|
||||
(mkTableName "Invoice")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "InvoiceId") (API.mkColumnSelector $ API.ColumnName "InvoiceId"))
|
||||
),
|
||||
( API.ConstraintName "Track",
|
||||
API.Constraint
|
||||
(mkTableName "Track")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "TrackId") (API.mkColumnSelector $ API.ColumnName "TrackId"))
|
||||
)
|
||||
],
|
||||
API._tiInsertable = True,
|
||||
API._tiUpdatable = True,
|
||||
@ -814,9 +839,21 @@ schema =
|
||||
API._tiForeignKeys =
|
||||
API.ForeignKeys
|
||||
$ HashMap.fromList
|
||||
[ (API.ConstraintName "Album", API.Constraint (mkTableName "Album") (HashMap.singleton (API.ColumnName "AlbumId") (API.ColumnName "AlbumId"))),
|
||||
(API.ConstraintName "Genre", API.Constraint (mkTableName "Genre") (HashMap.singleton (API.ColumnName "GenreId") (API.ColumnName "GenreId"))),
|
||||
(API.ConstraintName "MediaType", API.Constraint (mkTableName "MediaType") (HashMap.singleton (API.ColumnName "MediaTypeId") (API.ColumnName "MediaTypeId")))
|
||||
[ ( API.ConstraintName "Album",
|
||||
API.Constraint
|
||||
(mkTableName "Album")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "AlbumId") (API.mkColumnSelector $ API.ColumnName "AlbumId"))
|
||||
),
|
||||
( API.ConstraintName "Genre",
|
||||
API.Constraint
|
||||
(mkTableName "Genre")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "GenreId") (API.mkColumnSelector $ API.ColumnName "GenreId"))
|
||||
),
|
||||
( API.ConstraintName "MediaType",
|
||||
API.Constraint
|
||||
(mkTableName "MediaType")
|
||||
(API.ColumnPathMapping $ HashMap.singleton (API.mkColumnSelector $ API.ColumnName "MediaTypeId") (API.mkColumnSelector $ API.ColumnName "MediaTypeId"))
|
||||
)
|
||||
],
|
||||
API._tiInsertable = True,
|
||||
API._tiUpdatable = True,
|
||||
|
@ -632,7 +632,7 @@ unfurlAnnotatedOrderByElement =
|
||||
pure (fieldName, expression)
|
||||
Ir.AOCObjectRelation Rql.RelInfo {riTarget = Rql.RelTargetNativeQuery _} _annBoolExp _annOrderByElementG ->
|
||||
error "unfurlAnnotatedOrderByElement RelTargetNativeQuery"
|
||||
Ir.AOCObjectRelation Rql.RelInfo {riMapping = mapping, riTarget = Rql.RelTargetTable tableName} annBoolExp annOrderByElementG -> do
|
||||
Ir.AOCObjectRelation Rql.RelInfo {riMapping = Rql.RelMapping mapping, riTarget = Rql.RelTargetTable tableName} annBoolExp annOrderByElementG -> do
|
||||
selectFrom <- lift (lift (fromQualifiedTable tableName))
|
||||
joinAliasEntity <-
|
||||
lift (lift (generateEntityAlias (ForOrderAlias (tableNameText tableName))))
|
||||
@ -674,7 +674,7 @@ unfurlAnnotatedOrderByElement =
|
||||
local (const joinAliasEntity) (unfurlAnnotatedOrderByElement annOrderByElementG)
|
||||
Ir.AOCArrayAggregation Rql.RelInfo {riTarget = Rql.RelTargetNativeQuery _} _annBoolExp _annAggregateOrderBy ->
|
||||
error "unfurlAnnotatedOrderByElement RelTargetNativeQuery"
|
||||
Ir.AOCArrayAggregation Rql.RelInfo {riMapping = mapping, riTarget = Rql.RelTargetTable tableName} annBoolExp annAggregateOrderBy -> do
|
||||
Ir.AOCArrayAggregation Rql.RelInfo {riMapping = Rql.RelMapping mapping, riTarget = Rql.RelTargetTable tableName} annBoolExp annAggregateOrderBy -> do
|
||||
selectFrom <- lift (lift (fromQualifiedTable tableName))
|
||||
let alias = aggFieldName
|
||||
joinAlias <-
|
||||
@ -835,7 +835,7 @@ fromAnnBoolExpFld =
|
||||
error "fromAnnBoolExpFld RelTargetNativeQuery"
|
||||
Ir.AVRemoteRelationship _ ->
|
||||
error "fromAnnBoolExpFld RemoteRelationship"
|
||||
Ir.AVRelationship Rql.RelInfo {riMapping = mapping, riTarget = Rql.RelTargetTable table} (Ir.RelationshipFilters tablePerms annBoolExp) -> do
|
||||
Ir.AVRelationship Rql.RelInfo {riMapping = Rql.RelMapping mapping, riTarget = Rql.RelTargetTable table} (Ir.RelationshipFilters tablePerms annBoolExp) -> do
|
||||
selectFrom <- lift (fromQualifiedTable table)
|
||||
foreignKeyConditions <- fromMapping selectFrom mapping
|
||||
whereExpression <-
|
||||
|
@ -28,6 +28,7 @@ instance Backend 'BigQuery where
|
||||
type NullsOrderType 'BigQuery = BigQuery.NullsOrder
|
||||
type CountType 'BigQuery = BigQuery.CountType
|
||||
type Column 'BigQuery = BigQuery.ColumnName
|
||||
type ColumnPath 'BigQuery = BigQuery.ColumnName
|
||||
type ScalarValue 'BigQuery = BigQuery.Value
|
||||
type ScalarType 'BigQuery = BigQuery.ScalarType
|
||||
type SQLExpression 'BigQuery = BigQuery.Expression
|
||||
@ -117,6 +118,10 @@ instance Backend 'BigQuery where
|
||||
|
||||
getColVals _ _ _ _ _ _ = throw500 "getColVals: not implemented for the BigQuery backend"
|
||||
|
||||
getColumnPathColumn = id
|
||||
|
||||
tryColumnPathToColumn = Just
|
||||
|
||||
instance HasSourceConfiguration 'BigQuery where
|
||||
type SourceConfig 'BigQuery = BigQuery.BigQuerySourceConfig
|
||||
type SourceConnConfiguration 'BigQuery = BigQuery.BigQueryConnSourceConfig
|
||||
|
@ -56,6 +56,7 @@ instance Backend 'DataConnector where
|
||||
type NullsOrderType 'DataConnector = Unimplemented
|
||||
type CountType 'DataConnector = DC.CountAggregate
|
||||
type Column 'DataConnector = DC.ColumnName
|
||||
type ColumnPath 'DataConnector = DC.ColumnPath
|
||||
type ScalarValue 'DataConnector = J.Value
|
||||
type ScalarType 'DataConnector = DC.ScalarType
|
||||
|
||||
@ -167,6 +168,15 @@ instance Backend 'DataConnector where
|
||||
|
||||
getColVals _ _ _ _ _ _ = throw500 "getColVals: not implemented for the Data Connector backend"
|
||||
|
||||
getColumnPathColumn = \case
|
||||
DC.CPPath p -> NonEmpty.head p
|
||||
DC.CPColumn c -> c
|
||||
|
||||
tryColumnPathToColumn = \case
|
||||
DC.CPPath (column :| []) -> Just column
|
||||
DC.CPColumn column -> Just column
|
||||
_ -> Nothing
|
||||
|
||||
backendSupportsNestedObjects = pure ()
|
||||
|
||||
sourceSupportsSchemalessTables =
|
||||
|
@ -8,7 +8,6 @@ import Control.Monad.Trans.Control
|
||||
import Data.Aeson qualified as J
|
||||
import Data.Aeson.Key qualified as K
|
||||
import Data.Aeson.KeyMap qualified as KM
|
||||
import Data.Bifunctor (bimap)
|
||||
import Data.Environment (Environment)
|
||||
import Data.Has (Has (getter))
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
@ -71,7 +70,7 @@ import Hasura.RQL.Types.Metadata (SourceMetadata (..))
|
||||
import Hasura.RQL.Types.Metadata.Backend (BackendMetadata (..))
|
||||
import Hasura.RQL.Types.Metadata.Object
|
||||
import Hasura.RQL.Types.NamingCase (NamingCase)
|
||||
import Hasura.RQL.Types.Relationships.Local (ArrRelDef, ObjRelDef, RelInfo ())
|
||||
import Hasura.RQL.Types.Relationships.Local (ArrRelDef, ObjRelDef, RelInfo (), RelMapping (..))
|
||||
import Hasura.RQL.Types.SchemaCache (CacheRM, askSourceConfig, askSourceInfo)
|
||||
import Hasura.RQL.Types.SchemaCache.Build
|
||||
import Hasura.RQL.Types.SchemaCacheTypes (DependencyReason (DRTable), SchemaDependency (SchemaDependency), SchemaObjId (SOSourceObj), SourceObjId (SOITable))
|
||||
@ -474,7 +473,7 @@ buildForeignKeySet (API.ForeignKeys constraints) =
|
||||
$ constraints
|
||||
& HashMap.foldMapWithKey @[RQL.T.T.ForeignKeyMetadata 'DataConnector]
|
||||
\constraintName API.Constraint {..} -> maybeToList do
|
||||
let columnMapAssocList = HashMap.foldrWithKey' (\(API.ColumnName k) (API.ColumnName v) acc -> (DC.ColumnName k, DC.ColumnName v) : acc) [] _cColumnMapping
|
||||
let columnMapAssocList = HashMap.foldrWithKey' (\k v acc -> (Witch.from k, Witch.from v) : acc) [] $ API.unColumnPathMapping _cColumnMapping
|
||||
columnMapping <- NEHashMap.fromList columnMapAssocList
|
||||
let foreignKey =
|
||||
RQL.T.T.ForeignKey
|
||||
@ -786,7 +785,7 @@ convertTableMetadataToTableInfo tableName logicalModelCache RQL.T.T.DBTableMetad
|
||||
constraint =
|
||||
SourceConstraint
|
||||
{ _scForeignTable = Witch.from _fkForeignTable,
|
||||
_scColumnMapping = HashMap.fromList $ bimap Witch.from Witch.from <$> NEHashMap.toList _fkColumnMapping
|
||||
_scColumnMapping = RelMapping $ NEHashMap.toHashMap _fkColumnMapping
|
||||
}
|
||||
in (constraintName, constraint)
|
||||
)
|
||||
|
@ -23,6 +23,7 @@ module Hasura.Backends.DataConnector.Adapter.Types
|
||||
TableName (..),
|
||||
ConstraintName (..),
|
||||
ColumnName (..),
|
||||
ColumnPath (..),
|
||||
FunctionName (..),
|
||||
FunctionReturnType (..),
|
||||
CountAggregate (..),
|
||||
@ -414,6 +415,41 @@ instance ToTxt ColumnName where
|
||||
instance ToErrorValue ColumnName where
|
||||
toErrorValue = ErrorValue.squote . unColumnName
|
||||
|
||||
instance Witch.From ColumnName ColumnPath where
|
||||
from = CPColumn
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
data ColumnPath
|
||||
= CPPath (NonEmpty ColumnName)
|
||||
| CPColumn (ColumnName)
|
||||
deriving stock (Eq, Ord, Show, Generic)
|
||||
deriving (FromJSON, ToJSON, ToSchema) via AC.Autodocodec ColumnPath
|
||||
deriving anyclass (Hashable, NFData)
|
||||
|
||||
instance HasCodec ColumnPath where
|
||||
codec = AC.disjointMatchChoiceCodec pathCodec columnCodec chooser
|
||||
where
|
||||
pathCodec = AC.dimapCodec CPPath id (codec @(NonEmpty ColumnName))
|
||||
columnCodec = AC.dimapCodec CPColumn id (codec @ColumnName)
|
||||
chooser = \case
|
||||
CPPath p -> Left p
|
||||
CPColumn c -> Right c
|
||||
|
||||
instance ToJSONKey ColumnPath
|
||||
|
||||
instance FromJSONKey ColumnPath
|
||||
|
||||
instance Witch.From API.ColumnSelector ColumnPath where
|
||||
from = \case
|
||||
API.ColumnSelectorPath p -> CPPath $ Witch.from <$> p
|
||||
API.ColumnSelectorColumn c -> CPColumn $ Witch.from c
|
||||
|
||||
instance Witch.From ColumnPath API.ColumnSelector where
|
||||
from = \case
|
||||
CPPath p -> API.ColumnSelectorPath $ Witch.from <$> p
|
||||
CPColumn c -> API.ColumnSelectorColumn $ Witch.from c
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
newtype FunctionName = FunctionName {unFunctionName :: NonEmpty Text}
|
||||
|
@ -68,7 +68,7 @@ import Hasura.RQL.Types.Backend (Backend, SessionVarType, getColVals)
|
||||
import Hasura.RQL.Types.BackendType
|
||||
import Hasura.RQL.Types.Column
|
||||
import Hasura.RQL.Types.Common
|
||||
import Hasura.RQL.Types.Relationships.Local (RelInfo (..), RelTarget (..))
|
||||
import Hasura.RQL.Types.Relationships.Local (RelInfo (..), RelMapping (..), RelTarget (..))
|
||||
import Hasura.SQL.AnyBackend qualified as AB
|
||||
import Hasura.SQL.Types (CollectableType (..))
|
||||
import Hasura.Session
|
||||
@ -151,7 +151,7 @@ recordTableRelationshipFromRelInfo sourceTableName RelInfo {..} = do
|
||||
API.Relationship
|
||||
{ _rTarget = API.TTable (API.TargetTable (Witch.from targetTableName)),
|
||||
_rRelationshipType = relationshipType,
|
||||
_rColumnMapping = HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList riMapping
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (unRelMapping riMapping)
|
||||
}
|
||||
recordRelationship
|
||||
sourceTableName
|
||||
@ -346,8 +346,10 @@ pushColumn :: ColumnStack -> ColumnName -> ColumnStack
|
||||
pushColumn (ColumnStack stack) columnName = ColumnStack $ columnName : stack
|
||||
|
||||
toColumnSelector :: ColumnStack -> ColumnName -> API.ColumnSelector
|
||||
toColumnSelector (ColumnStack []) columnName =
|
||||
API.ColumnSelectorColumn $ Witch.from columnName
|
||||
toColumnSelector (ColumnStack stack) columnName =
|
||||
API.ColumnSelector $ NonEmpty.reverse $ Witch.from columnName :| fmap Witch.from stack
|
||||
API.ColumnSelectorPath $ NonEmpty.reverse $ Witch.from columnName :| fmap Witch.from stack
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -214,7 +214,7 @@ fromNativeQueryArray arrRel translateFieldsAndAggregates sourceTargetName native
|
||||
API.Relationship
|
||||
{ _rTarget = TInterpolated (API.TargetInterpolatedQuery nqid),
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (_aarColumnMapping arrRel)
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (_aarColumnMapping arrRel)
|
||||
}
|
||||
|
||||
pure
|
||||
@ -252,7 +252,7 @@ fromNativeQueryObject objRel sourceTargetName nativeQuery = do
|
||||
API.Relationship
|
||||
{ _rTarget = TInterpolated (API.TargetInterpolatedQuery nqid),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (_aarColumnMapping objRel)
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (_aarColumnMapping objRel)
|
||||
}
|
||||
|
||||
pure
|
||||
@ -526,7 +526,7 @@ translateAnnField targetName = \case
|
||||
API.Relationship
|
||||
{ _rTarget = API.TTable (API.TargetTable targetTable),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (_aarColumnMapping objRel)
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (_aarColumnMapping objRel)
|
||||
}
|
||||
|
||||
pure
|
||||
@ -586,7 +586,7 @@ translateArrayRelationSelect targetName translateFieldsAndAggregates arrRel = do
|
||||
API.Relationship
|
||||
{ _rTarget = API.TTable (API.TargetTable (Witch.into targetTable)),
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (_aarColumnMapping arrRel)
|
||||
_rColumnMapping = API.ColumnPathMapping $ HashMap.fromList $ bimap Witch.from Witch.from <$> HashMap.toList (_aarColumnMapping arrRel)
|
||||
}
|
||||
|
||||
pure
|
||||
|
@ -86,7 +86,7 @@ fromAnnBoolExpFld =
|
||||
expressions <- traverse (fromOpExpG columnInfo) opExpGs
|
||||
potentiallyRedacted redactionExp (AndExpression expressions)
|
||||
IR.AVRemoteRelationship _ -> error "fromAnnBoolExpFld RemoteRelationship"
|
||||
IR.AVRelationship IR.RelInfo {riMapping = mapping, riTarget = target} (IR.RelationshipFilters tablePerm annBoolExp) -> do
|
||||
IR.AVRelationship IR.RelInfo {riMapping = IR.RelMapping mapping, riTarget = target} (IR.RelationshipFilters tablePerm annBoolExp) -> do
|
||||
case target of
|
||||
IR.RelTargetNativeQuery _ -> error "fromAnnBoolExpFld RelTargetNativeQuery"
|
||||
IR.RelTargetTable table -> do
|
||||
|
@ -991,20 +991,20 @@ unfurlAnnotatedOrderByElement =
|
||||
-- text/ntext/image. See ToQuery for more explanation.
|
||||
_ -> Nothing
|
||||
)
|
||||
IR.AOCObjectRelation IR.RelInfo {riMapping = mapping, riTarget = IR.RelTargetNativeQuery nativeQueryName} annBoolExp annOrderByElementG -> do
|
||||
IR.AOCObjectRelation IR.RelInfo {riMapping = IR.RelMapping mapping, riTarget = IR.RelTargetNativeQuery nativeQueryName} annBoolExp annOrderByElementG -> do
|
||||
let name = T.toTxt (getNativeQueryName nativeQueryName)
|
||||
selectFrom = TSQL.FromIdentifier name
|
||||
joinAliasEntity <-
|
||||
lift (lift (generateAlias (ForOrderAlias name)))
|
||||
genObjectRelation mapping annBoolExp annOrderByElementG joinAliasEntity selectFrom (Left nativeQueryName)
|
||||
IR.AOCObjectRelation IR.RelInfo {riMapping = mapping, riTarget = IR.RelTargetTable table} annBoolExp annOrderByElementG -> do
|
||||
IR.AOCObjectRelation IR.RelInfo {riMapping = IR.RelMapping mapping, riTarget = IR.RelTargetTable table} annBoolExp annOrderByElementG -> do
|
||||
selectFrom <- lift (lift (fromQualifiedTable table))
|
||||
joinAliasEntity <-
|
||||
lift (lift (generateAlias (ForOrderAlias (tableNameText table))))
|
||||
genObjectRelation mapping annBoolExp annOrderByElementG joinAliasEntity selectFrom (Right table)
|
||||
IR.AOCArrayAggregation IR.RelInfo {riTarget = IR.RelTargetNativeQuery _} _annBoolExp _annAggregateOrderBy ->
|
||||
error "unfurlAnnotatedOrderByElement RelTargetNativeQuery"
|
||||
IR.AOCArrayAggregation IR.RelInfo {riMapping = mapping, riTarget = IR.RelTargetTable tableName} annBoolExp annAggregateOrderBy -> do
|
||||
IR.AOCArrayAggregation IR.RelInfo {riMapping = IR.RelMapping mapping, riTarget = IR.RelTargetTable tableName} annBoolExp annAggregateOrderBy -> do
|
||||
selectFrom <- lift (lift (fromQualifiedTable tableName))
|
||||
let alias = aggFieldName
|
||||
joinAliasEntity <-
|
||||
|
@ -40,6 +40,7 @@ instance Backend 'MSSQL where
|
||||
type NullsOrderType 'MSSQL = MSSQL.NullsOrder
|
||||
type CountType 'MSSQL = MSSQL.CountType
|
||||
type Column 'MSSQL = MSSQL.ColumnName
|
||||
type ColumnPath 'MSSQL = MSSQL.ColumnName
|
||||
type ScalarValue 'MSSQL = MSSQL.Value
|
||||
type ScalarType 'MSSQL = MSSQL.ScalarType
|
||||
type BooleanOperators 'MSSQL = MSSQL.BooleanOperators
|
||||
@ -123,6 +124,10 @@ instance Backend 'MSSQL where
|
||||
|
||||
getColVals _ _ _ _ _ _ = throw500 "getColVals: not implemented for the MSSQL backend"
|
||||
|
||||
getColumnPathColumn = id
|
||||
|
||||
tryColumnPathToColumn = Just
|
||||
|
||||
instance HasSourceConfiguration 'MSSQL where
|
||||
type SourceConfig 'MSSQL = MSSQL.MSSQLSourceConfig
|
||||
type SourceConnConfiguration 'MSSQL = MSSQL.MSSQLConnConfiguration
|
||||
|
@ -195,7 +195,7 @@ insertObject singleObjIns additionalColumns userInfo planVars stringifyNum tCase
|
||||
afterInsertDepCols :: [ColumnInfo ('Postgres pgKind)]
|
||||
afterInsertDepCols =
|
||||
flip (getColInfos @('Postgres pgKind)) allColumns
|
||||
$ concatMap (HashMap.keys . riMapping . IR._riRelationInfo) allAfterInsertRels
|
||||
$ concatMap (HashMap.keys . unRelMapping . riMapping . IR._riRelationInfo) allAfterInsertRels
|
||||
|
||||
withArrRels ::
|
||||
Maybe (ColumnValues ('Postgres pgKind) TxtEncodedVal) ->
|
||||
@ -258,7 +258,7 @@ insertObjRel planVars userInfo stringifyNum tCase objRelIns =
|
||||
table = case riTarget relInfo of
|
||||
RelTargetNativeQuery _ -> error "insertObjRel RelTargetNativeQuery"
|
||||
RelTargetTable tn -> tn
|
||||
mapCols = riMapping relInfo
|
||||
mapCols = unRelMapping $ riMapping relInfo
|
||||
allCols = IR._aiTableColumns singleObjIns
|
||||
rCols = HashMap.elems mapCols
|
||||
rColInfos = getColInfos rCols allCols
|
||||
@ -298,7 +298,7 @@ insertArrRel resCols userInfo planVars stringifyNum tCase arrRelIns =
|
||||
$ throw500 "affected_rows not returned in array rel insert"
|
||||
where
|
||||
IR.RelationInsert multiObjIns relInfo = arrRelIns
|
||||
mapping = riMapping relInfo
|
||||
mapping = unRelMapping $ riMapping relInfo
|
||||
mutOutput = IR.MOutMultirowFields [("affected_rows", IR.MCount)]
|
||||
|
||||
-- | Validate an insert object based on insert columns,
|
||||
@ -325,7 +325,7 @@ validateInsert insCols objRels addCols = do
|
||||
<> " columns as their values are already being determined by parent insert"
|
||||
|
||||
forM_ objRels $ \relInfo -> do
|
||||
let lCols = HashMap.keys $ riMapping relInfo
|
||||
let lCols = HashMap.keys $ unRelMapping $ riMapping relInfo
|
||||
relName = riName relInfo
|
||||
relNameTxt = relNameToTxt relName
|
||||
lColConflicts = lCols `intersect` (addCols <> insCols)
|
||||
|
@ -323,7 +323,7 @@ instance
|
||||
let mappings :: HashMap Postgres.PGCol Postgres.PGCol
|
||||
mappings = NEHashMap.toHashMap _fkColumnMapping
|
||||
|
||||
pure (_cName _fkConstraint, SourceConstraint _fkForeignTable mappings)
|
||||
pure (_cName _fkConstraint, SourceConstraint _fkForeignTable $ RelMapping mappings)
|
||||
|
||||
pure
|
||||
SourceTableInfo
|
||||
|
@ -103,6 +103,7 @@ instance
|
||||
type NullsOrderType ('Postgres pgKind) = Postgres.NullsOrder
|
||||
type CountType ('Postgres pgKind) = Postgres.CountAggregate pgKind
|
||||
type Column ('Postgres pgKind) = Postgres.PGCol
|
||||
type ColumnPath ('Postgres pgKind) = Postgres.PGCol
|
||||
type ScalarValue ('Postgres pgKind) = Postgres.PGScalarValue
|
||||
type ScalarType ('Postgres pgKind) = Postgres.PGScalarType
|
||||
type BooleanOperators ('Postgres pgKind) = Postgres.BooleanOperators
|
||||
@ -177,6 +178,10 @@ instance
|
||||
|
||||
getColVals = Postgres.getPGColValues
|
||||
|
||||
getColumnPathColumn = id
|
||||
|
||||
tryColumnPathToColumn = Just
|
||||
|
||||
instance
|
||||
( HasTag ('Postgres pgKind)
|
||||
) =>
|
||||
|
@ -375,12 +375,12 @@ translateAggPredArguments predArgs relTableNameIdentifier userInfo =
|
||||
)
|
||||
cols
|
||||
|
||||
translateTableRelationship :: (Monad m) => HashMap PGCol PGCol -> TableIdentifier -> BoolExpM m S.BoolExp
|
||||
translateTableRelationship :: (Monad m) => RelMapping ('Postgres pgKind) -> TableIdentifier -> BoolExpM m S.BoolExp
|
||||
translateTableRelationship colMapping relTableNameIdentifier = do
|
||||
BoolExpCtx {currTableReference} <- ask
|
||||
pure
|
||||
$ sqlAnd
|
||||
$ flip map (HashMap.toList colMapping)
|
||||
$ flip map (HashMap.toList $ unRelMapping colMapping)
|
||||
$ \(lCol, rCol) ->
|
||||
S.BECompare
|
||||
S.SEQ
|
||||
|
@ -132,7 +132,7 @@ processOrderByItems userInfo sourcePrefix' selectSourceQual fieldAlias' similarA
|
||||
$ S.mkQIdenExp baseTableIdentifier
|
||||
$ ciColumn pgColInfo
|
||||
AOCObjectRelation relInfo relFilter rest -> withWriteObjectRelation $ do
|
||||
let RelInfo {riName = relName, riMapping = colMapping, riTarget = relTarget} = relInfo
|
||||
let RelInfo {riName = relName, riMapping = RelMapping colMapping, riTarget = relTarget} = relInfo
|
||||
relSourcePrefix = mkObjectRelationTableAlias sourcePrefix relName
|
||||
fieldName = mkOrderByFieldName relName
|
||||
case relTarget of
|
||||
@ -153,7 +153,7 @@ processOrderByItems userInfo sourcePrefix' selectSourceQual fieldAlias' similarA
|
||||
S.mkQIdenExp relSourcePrefix relOrderByAlias
|
||||
)
|
||||
AOCArrayAggregation relInfo relFilter aggOrderBy -> withWriteArrayRelation $ do
|
||||
let RelInfo {riName = relName, riMapping = colMapping, riTarget = relTarget} = relInfo
|
||||
let RelInfo {riName = relName, riMapping = RelMapping colMapping, riTarget = relTarget} = relInfo
|
||||
case relTarget of
|
||||
RelTargetNativeQuery _ -> error "processAnnotatedOrderByElement RelTargetNativeQuery (AOCArrayAggregation)"
|
||||
RelTargetTable relTable -> do
|
||||
|
@ -187,7 +187,7 @@ convertRemoteSourceRelationship ::
|
||||
forall b.
|
||||
(Backend b) =>
|
||||
-- | Join columns for the relationship
|
||||
HashMap (Column b) (Column b) ->
|
||||
HashMap (ColumnPath b) (ColumnPath b) ->
|
||||
-- | The LHS of the join, this is the expression which selects from json
|
||||
-- objects
|
||||
SelectFromG b (UnpreparedValue b) ->
|
||||
|
@ -1560,7 +1560,7 @@ relationshipField table ri@RelInfo {riTarget = RelTargetTable otherTableName} =
|
||||
RelTargetTable tn -> Just tn
|
||||
_ -> Nothing
|
||||
in if (remoteTableName == Just table)
|
||||
&& (riMapping remoteRI `HashMap.isInverseOf` riMapping ri)
|
||||
&& (unRelMapping (riMapping remoteRI) `HashMap.isInverseOf` unRelMapping (riMapping ri))
|
||||
&& (thisTablePerm == rfFilter)
|
||||
then BoolAnd []
|
||||
else x
|
||||
@ -1610,7 +1610,7 @@ relationshipField table ri@RelInfo {riTarget = RelTargetTable otherTableName} =
|
||||
nullable <- case (riIsManual ri, riInsertOrder ri) of
|
||||
-- Automatically generated forward relationship
|
||||
(False, BeforeParent) -> do
|
||||
let columns = HashMap.keys $ riMapping ri
|
||||
let columns = fmap (getColumnPathColumn @b) $ HashMap.keys $ unRelMapping $ riMapping ri
|
||||
fieldInfoMap = _tciFieldInfoMap $ _tiCoreInfo tableInfo
|
||||
findColumn col = HashMap.lookup (fromCol @b col) fieldInfoMap ^? _Just . _FIColumn . _SCIScalarColumn
|
||||
-- Fetch information about the referencing columns of the foreign key
|
||||
@ -1627,7 +1627,7 @@ relationshipField table ri@RelInfo {riTarget = RelTargetTable otherTableName} =
|
||||
$ P.subselection_ relFieldName desc selectionSetParser
|
||||
<&> \fields ->
|
||||
IR.AFObjectRelation
|
||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable
|
||||
$ IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) Nullable
|
||||
$ IR.AnnObjectSelectG fields (IR.FromTable otherTableName)
|
||||
$ deduplicatePermissions
|
||||
$ IR._tpFilter
|
||||
@ -1639,7 +1639,7 @@ relationshipField table ri@RelInfo {riTarget = RelTargetTable otherTableName} =
|
||||
otherTableParser <&> \selectExp ->
|
||||
IR.AFArrayRelation
|
||||
$ IR.ASSimple
|
||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable
|
||||
$ IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) Nullable
|
||||
$ deduplicatePermissions' selectExp
|
||||
relAggFieldName = applyFieldNameCaseCust tCase $ relFieldName <> Name.__aggregate
|
||||
relAggDesc = Just $ G.Description "An aggregate relationship"
|
||||
@ -1658,8 +1658,8 @@ relationshipField table ri@RelInfo {riTarget = RelTargetTable otherTableName} =
|
||||
pure
|
||||
$ catMaybes
|
||||
[ Just arrayRelField,
|
||||
fmap (IR.AFArrayRelation . IR.ASAggregate . IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable) <$> remoteAggField,
|
||||
fmap (IR.AFArrayRelation . IR.ASConnection . IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable) <$> remoteConnectionField
|
||||
fmap (IR.AFArrayRelation . IR.ASAggregate . IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) Nullable) <$> remoteAggField,
|
||||
fmap (IR.AFArrayRelation . IR.ASConnection . IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) Nullable) <$> remoteConnectionField
|
||||
]
|
||||
relationshipField _table ri@RelInfo {riTarget = RelTargetNativeQuery nativeQueryName} = runMaybeT do
|
||||
relFieldName <- lift $ textToName $ relNameToTxt $ riName ri
|
||||
@ -1680,7 +1680,7 @@ relationshipField _table ri@RelInfo {riTarget = RelTargetNativeQuery nativeQuery
|
||||
$ pure
|
||||
$ nativeQueryParser
|
||||
<&> \selectExp ->
|
||||
IR.AFObjectRelation (IR.AnnRelationSelectG (riName ri) (riMapping ri) nullability selectExp)
|
||||
IR.AFObjectRelation (IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) nullability selectExp)
|
||||
ArrRel -> do
|
||||
nativeQueryInfo <- askNativeQueryInfo nativeQueryName
|
||||
|
||||
@ -1697,4 +1697,4 @@ relationshipField _table ri@RelInfo {riTarget = RelTargetNativeQuery nativeQuery
|
||||
<&> \selectExp ->
|
||||
IR.AFArrayRelation
|
||||
$ IR.ASSimple
|
||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) innerNullability selectExp
|
||||
$ IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) innerNullability selectExp
|
||||
|
@ -48,7 +48,7 @@ import Hasura.RQL.IR.Value (Provenance (FreshVar), UnpreparedValue (UVParameter)
|
||||
import Hasura.RQL.Types.Column qualified as Column
|
||||
import Hasura.RQL.Types.Common (RelType (..), relNameToTxt)
|
||||
import Hasura.RQL.Types.Metadata.Object qualified as MO
|
||||
import Hasura.RQL.Types.Relationships.Local (Nullable (..), RelInfo (..), RelTarget (..))
|
||||
import Hasura.RQL.Types.Relationships.Local (Nullable (..), RelInfo (..), RelMapping (..), RelTarget (..))
|
||||
import Hasura.RQL.Types.Schema.Options qualified as Options
|
||||
import Hasura.RQL.Types.Source
|
||||
( SourceInfo (_siCustomization, _siName),
|
||||
@ -328,7 +328,7 @@ nativeQueryRelationshipField ri | riType ri == ObjRel = runMaybeT do
|
||||
pure
|
||||
$ nativeQueryParser
|
||||
<&> \selectExp ->
|
||||
IR.AFObjectRelation (IR.AnnRelationSelectG (riName ri) (riMapping ri) nullability selectExp)
|
||||
IR.AFObjectRelation (IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) nullability selectExp)
|
||||
RelTargetTable otherTableName -> do
|
||||
let desc = Just $ G.Description "An object relationship"
|
||||
roleName <- retrieve scRole
|
||||
@ -339,7 +339,7 @@ nativeQueryRelationshipField ri | riType ri == ObjRel = runMaybeT do
|
||||
$ P.subselection_ relFieldName desc selectionSetParser
|
||||
<&> \fields ->
|
||||
IR.AFObjectRelation
|
||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable
|
||||
$ IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) Nullable
|
||||
$ IR.AnnObjectSelectG fields (IR.FromTable otherTableName)
|
||||
$ IR._tpFilter
|
||||
$ tablePermissionsInfo remotePerms
|
||||
@ -361,7 +361,7 @@ nativeQueryRelationshipField ri = do
|
||||
<&> \selectExp ->
|
||||
IR.AFArrayRelation
|
||||
$ IR.ASSimple
|
||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) innerNullability selectExp
|
||||
$ IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) innerNullability selectExp
|
||||
RelTargetTable otherTableName -> runMaybeT $ do
|
||||
let arrayRelDesc = Just $ G.Description "An array relationship"
|
||||
|
||||
@ -371,6 +371,6 @@ nativeQueryRelationshipField ri = do
|
||||
otherTableParser <&> \selectExp ->
|
||||
IR.AFArrayRelation
|
||||
$ IR.ASSimple
|
||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable
|
||||
$ IR.AnnRelationSelectG (riName ri) (unRelMapping $ riMapping ri) Nullable
|
||||
$ selectExp
|
||||
pure arrayRelField
|
||||
|
@ -135,14 +135,15 @@ defaultBuildObjectRelationshipInfo ::
|
||||
m (RelInfo b, Seq SchemaDependency)
|
||||
defaultBuildObjectRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case ru of
|
||||
RUManual (RelManualNativeQueryConfig (RelManualNativeQueryConfigC {rmnNativeQueryName = refqt, rmnCommon = common})) -> do
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ rmColumns common
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ unRelMapping $ rmColumns common
|
||||
io = fromMaybe BeforeParent $ rmInsertOrder common
|
||||
mkNativeQueryDependency nativeQueryName reason col =
|
||||
SchemaDependency
|
||||
( SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOINativeQueryObj @b nativeQueryName
|
||||
$ NQOCol @b col
|
||||
$ NQOCol @b
|
||||
$ getColumnPathColumn @b col
|
||||
)
|
||||
reason
|
||||
mkDependency tableName reason col =
|
||||
@ -150,7 +151,8 @@ defaultBuildObjectRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case
|
||||
( SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOITableObj @b tableName
|
||||
$ TOCol @b col
|
||||
$ TOCol @b
|
||||
$ getColumnPathColumn @b col
|
||||
)
|
||||
reason
|
||||
dependencies =
|
||||
@ -158,14 +160,15 @@ defaultBuildObjectRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case
|
||||
<> (mkNativeQueryDependency refqt DRRightColumn <$> Seq.fromList rCols)
|
||||
pure (RelInfo rn ObjRel (rmColumns common) (RelTargetNativeQuery refqt) True io, dependencies)
|
||||
RUManual (RelManualTableConfig (RelManualTableConfigC {rmtTable = refqt, rmtCommon = common})) -> do
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ rmColumns common
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ unRelMapping $ rmColumns common
|
||||
io = fromMaybe BeforeParent $ rmInsertOrder common
|
||||
mkDependency tableName reason col =
|
||||
SchemaDependency
|
||||
( SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOITableObj @b tableName
|
||||
$ TOCol @b col
|
||||
$ TOCol @b
|
||||
$ getColumnPathColumn @b col
|
||||
)
|
||||
reason
|
||||
dependencies =
|
||||
@ -195,8 +198,8 @@ defaultBuildObjectRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case
|
||||
)
|
||||
DRRemoteTable
|
||||
]
|
||||
<> (drUsingColumnDep @b source qt <$> Seq.fromList (toList columns))
|
||||
pure (RelInfo rn ObjRel (NEHashMap.toHashMap colMap) (RelTargetTable foreignTable) False BeforeParent, dependencies)
|
||||
<> (drUsingColumnDep @b source qt <$> Seq.fromList (toList $ getColumnPathColumn @b <$> columns))
|
||||
pure (RelInfo rn ObjRel (RelMapping $ NEHashMap.toHashMap colMap) (RelTargetTable foreignTable) False BeforeParent, dependencies)
|
||||
RUFKeyOn (RemoteTable remoteTable remoteCols) ->
|
||||
mkFkeyRel ObjRel AfterParent source rn qt remoteTable remoteCols foreignKeys
|
||||
|
||||
@ -219,7 +222,8 @@ nativeQueryRelationshipSetup sourceName nativeQueryName relType (RelDef relName
|
||||
( SOSourceObj sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SOINativeQueryObj @b refqt
|
||||
$ NQOCol @b c
|
||||
$ NQOCol @b
|
||||
$ getColumnPathColumn @b c
|
||||
)
|
||||
DRRightColumn
|
||||
)
|
||||
@ -231,12 +235,13 @@ nativeQueryRelationshipSetup sourceName nativeQueryName relType (RelDef relName
|
||||
( SOSourceObj sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SOITableObj @b refqt
|
||||
$ TOCol @b c
|
||||
$ TOCol @b
|
||||
$ getColumnPathColumn @b c
|
||||
)
|
||||
DRRightColumn
|
||||
)
|
||||
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ rmColumns common
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ unRelMapping $ rmColumns common
|
||||
io = case relType of
|
||||
ObjRel -> fromMaybe BeforeParent $ rmInsertOrder common
|
||||
ArrRel -> AfterParent
|
||||
@ -247,7 +252,8 @@ nativeQueryRelationshipSetup sourceName nativeQueryName relType (RelDef relName
|
||||
( SOSourceObj sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SOINativeQueryObj @b nativeQueryName
|
||||
$ NQOCol @b c
|
||||
$ NQOCol @b
|
||||
$ getColumnPathColumn @b c
|
||||
)
|
||||
DRLeftColumn
|
||||
)
|
||||
@ -266,7 +272,7 @@ defaultBuildArrayRelationshipInfo ::
|
||||
m (RelInfo b, Seq SchemaDependency)
|
||||
defaultBuildArrayRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case ru of
|
||||
RUManual (RelManualNativeQueryConfig (RelManualNativeQueryConfigC {rmnNativeQueryName = refqt, rmnCommon = common})) -> do
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ rmColumns common
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ unRelMapping $ rmColumns common
|
||||
deps =
|
||||
( fmap
|
||||
( \c ->
|
||||
@ -274,7 +280,8 @@ defaultBuildArrayRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case
|
||||
( SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOITableObj @b qt
|
||||
$ TOCol @b c
|
||||
$ TOCol @b
|
||||
$ getColumnPathColumn @b c
|
||||
)
|
||||
DRLeftColumn
|
||||
)
|
||||
@ -286,14 +293,15 @@ defaultBuildArrayRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case
|
||||
( SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOINativeQueryObj @b refqt
|
||||
$ NQOCol @b c
|
||||
$ NQOCol @b
|
||||
$ getColumnPathColumn @b c
|
||||
)
|
||||
DRRightColumn
|
||||
)
|
||||
(Seq.fromList rCols)
|
||||
pure (RelInfo rn ArrRel (rmColumns common) (RelTargetNativeQuery refqt) True AfterParent, deps)
|
||||
RUManual (RelManualTableConfig (RelManualTableConfigC {rmtTable = refqt, rmtCommon = common})) -> do
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ rmColumns common
|
||||
let (lCols, rCols) = unzip $ HashMap.toList $ unRelMapping $ rmColumns common
|
||||
deps =
|
||||
( fmap
|
||||
( \c ->
|
||||
@ -301,7 +309,8 @@ defaultBuildArrayRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case
|
||||
( SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOITableObj @b qt
|
||||
$ TOCol @b c
|
||||
$ TOCol @b
|
||||
$ getColumnPathColumn @b c
|
||||
)
|
||||
DRLeftColumn
|
||||
)
|
||||
@ -313,7 +322,8 @@ defaultBuildArrayRelationshipInfo source foreignKeys qt (RelDef rn ru _) = case
|
||||
( SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOITableObj @b refqt
|
||||
$ TOCol @b c
|
||||
$ TOCol @b
|
||||
$ getColumnPathColumn @b c
|
||||
)
|
||||
DRRightColumn
|
||||
)
|
||||
@ -332,7 +342,7 @@ mkFkeyRel ::
|
||||
RelName ->
|
||||
TableName b ->
|
||||
TableName b ->
|
||||
NonEmpty (Column b) ->
|
||||
NonEmpty (ColumnPath b) ->
|
||||
HashMap (TableName b) (HashSet (ForeignKey b)) ->
|
||||
m (RelInfo b, Seq SchemaDependency)
|
||||
mkFkeyRel relType io source rn sourceTable remoteTable remoteColumns foreignKeys = do
|
||||
@ -358,17 +368,18 @@ mkFkeyRel relType io source rn sourceTable remoteTable remoteColumns foreignKeys
|
||||
DRRemoteTable
|
||||
]
|
||||
<> ( drUsingColumnDep @b source remoteTable
|
||||
<$> Seq.fromList (toList remoteColumns)
|
||||
<$> Seq.fromList (toList $ getColumnPathColumn @b <$> remoteColumns)
|
||||
)
|
||||
pure (RelInfo rn relType (reverseMap (NEHashMap.toHashMap colMap)) (RelTargetTable remoteTable) False io, dependencies)
|
||||
pure (RelInfo rn relType (RelMapping $ reverseMap $ NEHashMap.toHashMap colMap) (RelTargetTable remoteTable) False io, dependencies)
|
||||
where
|
||||
reverseMap :: (Hashable y) => HashMap x y -> HashMap y x
|
||||
reverseMap = HashMap.fromList . fmap swap . HashMap.toList
|
||||
|
||||
-- | Try to find a foreign key constraint, identifying a constraint by its set of columns
|
||||
getRequiredFkey ::
|
||||
forall m b.
|
||||
(QErrM m, Backend b) =>
|
||||
NonEmpty (Column b) ->
|
||||
NonEmpty (ColumnPath b) ->
|
||||
[ForeignKey b] ->
|
||||
m (ForeignKey b)
|
||||
getRequiredFkey cols fkeys =
|
||||
|
@ -36,10 +36,11 @@ import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.Common
|
||||
import Hasura.RQL.Types.Metadata.Backend
|
||||
import Hasura.RQL.Types.Relationships.Local (RelInfo (riMapping, riTarget), RelTarget (..))
|
||||
import Hasura.RQL.Types.Relationships.Local (RelInfo (riMapping, riTarget), RelMapping (..), RelTarget (..))
|
||||
import Hasura.RQL.Types.SchemaCache
|
||||
import Hasura.RQL.Types.SchemaCache.Build
|
||||
import Hasura.Table.Cache (ForeignKey, UniqueConstraint, _cName, _fkColumnMapping, _fkConstraint, _fkForeignTable, _ucColumns)
|
||||
import Witch qualified
|
||||
|
||||
-- | Datatype used by Metadata API to represent Request for Suggested Relationships
|
||||
data SuggestRels b = SuggestRels
|
||||
@ -102,7 +103,7 @@ instance (Backend b) => HasCodec (Relationship b) where
|
||||
|
||||
data Mapping b = Mapping
|
||||
{ mTable :: TableName b,
|
||||
mColumns :: [Column b],
|
||||
mColumns :: [ColumnPath b],
|
||||
mConstraintName :: Maybe J.Value
|
||||
}
|
||||
deriving (Generic)
|
||||
@ -133,7 +134,7 @@ suggestRelsFK ::
|
||||
HashMap (TableName b) (TableCoreInfo b) ->
|
||||
TableName b ->
|
||||
HashSet (UniqueConstraint b) ->
|
||||
H.HashSet (TableName b, HashMap (Column b) (Column b)) ->
|
||||
H.HashSet (TableName b, HashMap (ColumnPath b) (ColumnPath b)) ->
|
||||
(TableName b -> Bool) ->
|
||||
ForeignKey b ->
|
||||
[Relationship b]
|
||||
@ -145,6 +146,7 @@ suggestRelsFK omitTracked tables name uniqueConstraints tracked predicate foreig
|
||||
where
|
||||
toTracked = H.member (relatedTableName, columnRelationships) tracked
|
||||
fromTracked = H.member (name, invert columnRelationships) trackedBack
|
||||
toRelationship, fromRelationship :: Relationship b
|
||||
toRelationship =
|
||||
Relationship
|
||||
{ rType = ObjRel,
|
||||
@ -157,10 +159,10 @@ suggestRelsFK omitTracked tables name uniqueConstraints tracked predicate foreig
|
||||
rTo = Mapping {mTable = name, mColumns = localColumns, mConstraintName = Just constraintName},
|
||||
rFrom = Mapping {mTable = relatedTableName, mColumns = relatedColumns, mConstraintName = Nothing}
|
||||
}
|
||||
columnRelationships = MapNE.toHashMap (_fkColumnMapping foreignKey)
|
||||
columnRelationships = MapNE.toHashMap $ _fkColumnMapping foreignKey
|
||||
localColumns = HashMap.keys columnRelationships
|
||||
relatedColumns = HashMap.elems columnRelationships
|
||||
uniqueConstraintColumns = H.map _ucColumns uniqueConstraints
|
||||
uniqueConstraintColumns = H.map (H.map Witch.from . _ucColumns) uniqueConstraints
|
||||
relatedTableName = _fkForeignTable foreignKey
|
||||
relatedTable = HashMap.lookup relatedTableName tables
|
||||
constraintName = J.toJSON (_cName (_fkConstraint foreignKey))
|
||||
@ -174,10 +176,10 @@ suggestRelsFK omitTracked tables name uniqueConstraints tracked predicate foreig
|
||||
-- we're only interested in suggesting table-based relationships for now
|
||||
getRelationshipsInputs ::
|
||||
RelInfo b ->
|
||||
Maybe (TableName b, HashMap (Column b) (Column b))
|
||||
Maybe (TableName b, HashMap (ColumnPath b) (ColumnPath b))
|
||||
getRelationshipsInputs ri =
|
||||
case riTarget ri of
|
||||
RelTargetTable tn -> Just (tn, riMapping ri)
|
||||
RelTargetTable tn -> Just (tn, unRelMapping $ riMapping ri)
|
||||
_ -> Nothing
|
||||
|
||||
suggestRelsTable ::
|
||||
|
@ -289,7 +289,8 @@ processTablesDiff ::
|
||||
( MonadError QErr m,
|
||||
CacheRM m,
|
||||
MonadWriter MetadataModifier m,
|
||||
BackendMetadata b
|
||||
BackendMetadata b,
|
||||
Column b ~ ColumnPath b
|
||||
) =>
|
||||
SourceName ->
|
||||
TableCache b ->
|
||||
@ -313,7 +314,8 @@ alterTableInMetadata ::
|
||||
( MonadError QErr m,
|
||||
CacheRM m,
|
||||
MonadWriter MetadataModifier m,
|
||||
BackendMetadata b
|
||||
BackendMetadata b,
|
||||
Column b ~ ColumnPath b
|
||||
) =>
|
||||
SourceName ->
|
||||
TableCoreInfo b ->
|
||||
@ -387,7 +389,8 @@ alterColumnsInMetadata ::
|
||||
( MonadError QErr m,
|
||||
CacheRM m,
|
||||
MonadWriter MetadataModifier m,
|
||||
BackendMetadata b
|
||||
BackendMetadata b,
|
||||
Column b ~ ColumnPath b
|
||||
) =>
|
||||
SourceName ->
|
||||
[(RawColumnInfo b, RawColumnInfo b)] ->
|
||||
|
@ -40,7 +40,9 @@ resolveEnumReferences enumTables =
|
||||
where
|
||||
resolveEnumReference :: ForeignKey b -> Maybe (Column b, EnumReference b)
|
||||
resolveEnumReference foreignKey = do
|
||||
[(localColumn, foreignColumn)] <- pure $ NEHashMap.toList (_fkColumnMapping @b foreignKey)
|
||||
[(localColumnPath, foreignColumnPath)] <- pure $ NEHashMap.toList (_fkColumnMapping @b foreignKey)
|
||||
localColumn <- tryColumnPathToColumn @b localColumnPath
|
||||
foreignColumn <- tryColumnPathToColumn @b foreignColumnPath
|
||||
let foreignKeyTableName = _fkForeignTable foreignKey
|
||||
(primaryKey, tConfig, enumValues) <- HashMap.lookup foreignKeyTableName enumTables
|
||||
let tableCustomName = _tcCustomName tConfig
|
||||
|
@ -933,4 +933,4 @@ recreateSystemMetadata = do
|
||||
$ RelManualTableConfig
|
||||
$ RelManualTableConfigC
|
||||
(QualifiedObject schemaName tableName)
|
||||
(RelManualCommon (HashMap.fromList columns) Nothing)
|
||||
(RelManualCommon (RelMapping $ HashMap.fromList columns) Nothing)
|
||||
|
@ -162,7 +162,8 @@ renameColumnInMetadata ::
|
||||
( MonadError QErr m,
|
||||
CacheRM m,
|
||||
MonadWriter MetadataModifier m,
|
||||
BackendMetadata b
|
||||
BackendMetadata b,
|
||||
Column b ~ ColumnPath b
|
||||
) =>
|
||||
Column b ->
|
||||
Column b ->
|
||||
@ -532,7 +533,7 @@ updateColExp qt rf (ColExp fld val) =
|
||||
-- rename columns in relationship definitions
|
||||
updateColInRel ::
|
||||
forall b m.
|
||||
(CacheRM m, MonadWriter MetadataModifier m, BackendMetadata b) =>
|
||||
(CacheRM m, MonadWriter MetadataModifier m, BackendMetadata b, Column b ~ ColumnPath b) =>
|
||||
SourceName ->
|
||||
TableName b ->
|
||||
RelName ->
|
||||
@ -681,7 +682,7 @@ updateTableInRemoteRelationshipRHS source tableName remoteRelationshipName (_, n
|
||||
.~ toJSON newTableName
|
||||
|
||||
updateColInObjRel ::
|
||||
(Backend b) =>
|
||||
(Backend b, Column b ~ ColumnPath b) =>
|
||||
TableName b ->
|
||||
TableName b ->
|
||||
RenameCol b ->
|
||||
@ -694,7 +695,7 @@ updateColInObjRel fromQT toQT rnCol = \case
|
||||
RUManual $ updateRelManualConfig fromQT toQT rnCol manConfig
|
||||
|
||||
updateRelChoice ::
|
||||
(Backend b) =>
|
||||
(Backend b, Column b ~ ColumnPath b) =>
|
||||
TableName b ->
|
||||
TableName b ->
|
||||
RenameCol b ->
|
||||
@ -706,7 +707,7 @@ updateRelChoice fromQT toQT rnCol =
|
||||
RemoteTable t c -> RemoteTable t (getNewCol rnCol toQT c)
|
||||
|
||||
updateColInArrRel ::
|
||||
(Backend b) =>
|
||||
(Backend b, Column b ~ ColumnPath b) =>
|
||||
TableName b ->
|
||||
TableName b ->
|
||||
RenameCol b ->
|
||||
@ -718,8 +719,6 @@ updateColInArrRel fromQT toQT rnCol = \case
|
||||
in RUFKeyOn $ ArrRelUsingFKeyOn t updCol
|
||||
RUManual manConfig -> RUManual $ updateRelManualConfig fromQT toQT rnCol manConfig
|
||||
|
||||
type ColMap b = HashMap (Column b) (Column b)
|
||||
|
||||
getNewCol ::
|
||||
forall b f.
|
||||
(Backend b) =>
|
||||
@ -741,7 +740,7 @@ getNewCol rnCol qt cols =
|
||||
|
||||
updateRelManualConfig ::
|
||||
forall b.
|
||||
(Backend b) =>
|
||||
(Backend b, Column b ~ ColumnPath b) =>
|
||||
TableName b ->
|
||||
TableName b ->
|
||||
RenameCol b ->
|
||||
@ -754,14 +753,14 @@ updateRelManualConfig fromQT toQT rnCol (RelManualNativeQueryConfig (RelManualNa
|
||||
|
||||
updateColMap ::
|
||||
forall b.
|
||||
(Backend b) =>
|
||||
(Backend b, Column b ~ ColumnPath b) =>
|
||||
TableName b ->
|
||||
TableName b ->
|
||||
RenameCol b ->
|
||||
ColMap b ->
|
||||
ColMap b
|
||||
RelMapping b ->
|
||||
RelMapping b
|
||||
updateColMap fromQT toQT rnCol =
|
||||
HashMap.fromList . map (modCol fromQT *** modCol toQT) . HashMap.toList
|
||||
RelMapping . HashMap.fromList . map (modCol fromQT *** modCol toQT) . HashMap.toList . unRelMapping
|
||||
where
|
||||
RenameItem qt oCol nCol = rnCol
|
||||
modCol colQt col = if colQt == qt && col == oCol then nCol else col
|
||||
|
@ -286,7 +286,7 @@ convExtRel sqlGen fieldInfoMap relName mAlias selQ sessVarBldr prepValBldr = do
|
||||
relInfo <-
|
||||
withPathK "name"
|
||||
$ askRelType fieldInfoMap relName pgWhenRelErr
|
||||
let (RelInfo {riType = relTy, riMapping = colMapping, riTarget = relTarget}) = relInfo
|
||||
let (RelInfo {riType = relTy, riMapping = RelMapping colMapping, riTarget = relTarget}) = relInfo
|
||||
relTableName <- case relTarget of
|
||||
RelTargetNativeQuery _ -> error "convExtRel RelTargetNativeQuery"
|
||||
RelTargetTable tn -> pure tn
|
||||
|
@ -18,7 +18,7 @@ import Hasura.RQL.Types.Relationships.Local (Nullable)
|
||||
|
||||
data AnnRelationSelectG (b :: BackendType) a = AnnRelationSelectG
|
||||
{ _aarRelationshipName :: RelName, -- Relationship name
|
||||
_aarColumnMapping :: HashMap (Column b) (Column b), -- Column of left table to join with
|
||||
_aarColumnMapping :: HashMap (ColumnPath b) (ColumnPath b), -- Column of left table to join with
|
||||
_aarNullable :: Nullable, -- is the target object allowed to be missing?
|
||||
_aarAnnSelect :: a -- Current table. Almost ~ to SQL Select
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import Hasura.RQL.Types.Session (SessionVariables)
|
||||
import Hasura.RQL.Types.SourceConfiguration
|
||||
import Hasura.SQL.Types
|
||||
import Language.GraphQL.Draft.Syntax qualified as G
|
||||
import Witch (From)
|
||||
|
||||
type SessionVarType b = CollectableType (ScalarType b)
|
||||
|
||||
@ -81,6 +82,7 @@ class
|
||||
( HasSourceConfiguration b,
|
||||
Representable (BasicOrderType b),
|
||||
Representable (Column b),
|
||||
Representable (ColumnPath b),
|
||||
Representable (ComputedFieldDefinition b),
|
||||
Representable (ComputedFieldImplicitArguments b),
|
||||
Representable (ComputedFieldReturn b),
|
||||
@ -104,14 +106,18 @@ class
|
||||
Ord (FunctionName b),
|
||||
Ord (ScalarType b),
|
||||
Ord (Column b),
|
||||
Ord (ColumnPath b),
|
||||
Ord (ComputedFieldReturn b),
|
||||
Ord (ComputedFieldImplicitArguments b),
|
||||
Ord (ConstraintName b),
|
||||
Ord (FunctionArgument b),
|
||||
Ord (XComputedField b),
|
||||
Data (TableName b),
|
||||
From (Column b) (ColumnPath b),
|
||||
FromJSON (BackendConfig b),
|
||||
FromJSON (Column b),
|
||||
FromJSON (ColumnPath b),
|
||||
FromJSON (ColumnPath b),
|
||||
FromJSON (ComputedFieldDefinition b),
|
||||
FromJSON (ConnectionTemplateRequestContext b),
|
||||
FromJSON (ConstraintName b),
|
||||
@ -123,17 +129,22 @@ class
|
||||
FromJSON (ScalarType b),
|
||||
FromJSON (TableName b),
|
||||
FromJSONKey (Column b),
|
||||
FromJSONKey (ColumnPath b),
|
||||
FromJSONKey (ConstraintName b),
|
||||
HasCodec (BackendConfig b),
|
||||
HasCodec (BackendSourceKind b),
|
||||
HasCodec (Column b),
|
||||
HasCodec (ColumnPath b),
|
||||
HasCodec (ComputedFieldDefinition b),
|
||||
HasCodec (FunctionName b),
|
||||
HasCodec (FunctionReturnType b),
|
||||
HasCodec (ScalarType b),
|
||||
HasCodec (TableName b),
|
||||
Hashable (Column b),
|
||||
Hashable (ColumnPath b),
|
||||
ToJSON (BackendConfig b),
|
||||
ToJSON (Column b),
|
||||
ToJSON (ColumnPath b),
|
||||
ToJSON (ConstraintName b),
|
||||
ToJSON (ExecutionStatistics b),
|
||||
ToJSON (FunctionArgument b),
|
||||
@ -150,6 +161,7 @@ class
|
||||
ToJSON (HealthCheckTest b),
|
||||
ToJSON (ResolvedConnectionTemplate b),
|
||||
ToJSONKey (Column b),
|
||||
ToJSONKey (ColumnPath b),
|
||||
ToJSONKey (ConstraintName b),
|
||||
ToJSONKey (ScalarType b),
|
||||
ToTxt (Column b),
|
||||
@ -160,6 +172,7 @@ class
|
||||
ToErrorValue (Column b),
|
||||
ToErrorValue (TableName b),
|
||||
Typeable (Column b),
|
||||
Typeable (ColumnPath b),
|
||||
Typeable b,
|
||||
HasTag b,
|
||||
Traversable (CountType b),
|
||||
@ -232,6 +245,9 @@ class
|
||||
-- Name of a 'column'
|
||||
type Column b :: Type
|
||||
|
||||
-- Path to a column
|
||||
type ColumnPath b :: Type
|
||||
|
||||
type ScalarValue b :: Type
|
||||
type ScalarType b :: Type
|
||||
|
||||
@ -443,6 +459,14 @@ class
|
||||
(Column b, [RemoteRelSupportedOp RemoteRelSessionVariableORLiteralValue]) ->
|
||||
m [Text]
|
||||
|
||||
-- | Get the top-level column from a ColumnPath
|
||||
-- For backends that don't support nested objects (i.e. where ColumnPath b = Column b) this will be `id`.
|
||||
getColumnPathColumn :: ColumnPath b -> Column b
|
||||
|
||||
-- | Convert a singleton ColumnPath to a Column
|
||||
-- Should return Nothing for paths to nested fields
|
||||
tryColumnPathToColumn :: ColumnPath b -> Maybe (Column b)
|
||||
|
||||
backendSupportsNestedObjects :: Either QErr (XNestedObjects b)
|
||||
default backendSupportsNestedObjects :: (XNestedObjects b ~ XDisable) => Either QErr (XNestedObjects b)
|
||||
backendSupportsNestedObjects = throw400 InvalidConfiguration "Nested objects not supported"
|
||||
|
@ -10,6 +10,7 @@ module Hasura.RQL.Types.Relationships.Local
|
||||
ObjRelUsingChoice (..),
|
||||
RelDef (..),
|
||||
RelTarget (..),
|
||||
RelMapping (..),
|
||||
RelInfo (..),
|
||||
RelManualConfig (..),
|
||||
RelManualTableConfig (..),
|
||||
@ -31,6 +32,8 @@ import Autodocodec.Extended (optionalFieldOrIncludedNull', typeableName)
|
||||
import Control.Lens (makeLenses)
|
||||
import Data.Aeson.KeyMap qualified as KM
|
||||
import Data.Aeson.Types
|
||||
import Data.Bitraversable
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.Text qualified as T
|
||||
import Data.Typeable (Typeable)
|
||||
import Hasura.NativeQuery.Types (NativeQueryName)
|
||||
@ -39,6 +42,7 @@ import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.BackendTag (backendPrefix)
|
||||
import Hasura.RQL.Types.BackendType
|
||||
import Hasura.RQL.Types.Common
|
||||
import Witch qualified
|
||||
|
||||
data RelDef a = RelDef
|
||||
{ _rdName :: RelName,
|
||||
@ -112,7 +116,7 @@ deriving instance (Backend b) => Eq (RelManualNativeQueryConfig b)
|
||||
deriving instance (Backend b) => Show (RelManualNativeQueryConfig b)
|
||||
|
||||
data RelManualCommon (b :: BackendType) = RelManualCommon
|
||||
{ rmColumns :: HashMap (Column b) (Column b),
|
||||
{ rmColumns :: RelMapping b,
|
||||
rmInsertOrder :: Maybe InsertOrder
|
||||
}
|
||||
deriving (Generic)
|
||||
@ -188,7 +192,7 @@ instance (FromJSON a, Backend b) => FromJSON (RelUsing b a) where
|
||||
|
||||
data ArrRelUsingFKeyOn (b :: BackendType) = ArrRelUsingFKeyOn
|
||||
{ arufTable :: TableName b,
|
||||
arufColumns :: NonEmpty (Column b)
|
||||
arufColumns :: NonEmpty (ColumnPath b)
|
||||
}
|
||||
deriving (Generic)
|
||||
|
||||
@ -224,8 +228,8 @@ instance (ToAesonPairs a, Backend b) => ToJSON (WithTable b a) where
|
||||
object $ ("source" .= sourceName) : ("table" .= tn) : toAesonPairs rel
|
||||
|
||||
data ObjRelUsingChoice b
|
||||
= SameTable (NonEmpty (Column b))
|
||||
| RemoteTable (TableName b) (NonEmpty (Column b))
|
||||
= SameTable (NonEmpty (ColumnPath b))
|
||||
| RemoteTable (TableName b) (NonEmpty (ColumnPath b))
|
||||
deriving (Generic)
|
||||
|
||||
deriving instance (Backend b) => Eq (ObjRelUsingChoice b)
|
||||
@ -235,10 +239,10 @@ deriving instance (Backend b) => Show (ObjRelUsingChoice b)
|
||||
instance (Backend b) => HasCodec (ObjRelUsingChoice b) where
|
||||
codec = dimapCodec dec enc $ disjointEitherCodec sameTableCodec remoteTableCodec
|
||||
where
|
||||
sameTableCodec :: AC.JSONCodec (Either (Column b) (NonEmpty (Column b)))
|
||||
sameTableCodec :: AC.JSONCodec (Either (ColumnPath b) (NonEmpty (ColumnPath b)))
|
||||
sameTableCodec = disjointEitherCodec codec codec
|
||||
|
||||
remoteTableCodec :: AC.JSONCodec (Either (TableName b, Column b) (TableName b, NonEmpty (Column b)))
|
||||
remoteTableCodec :: AC.JSONCodec (Either (TableName b, ColumnPath b) (TableName b, NonEmpty (ColumnPath b)))
|
||||
remoteTableCodec =
|
||||
singleOrMultipleRelColumnsCodec @b
|
||||
$ backendPrefix @b
|
||||
@ -262,8 +266,8 @@ singleOrMultipleRelColumnsCodec ::
|
||||
Text ->
|
||||
AC.JSONCodec
|
||||
( Either
|
||||
(TableName b, Column b)
|
||||
(TableName b, NonEmpty (Column b))
|
||||
(TableName b, ColumnPath b)
|
||||
(TableName b, NonEmpty (ColumnPath b))
|
||||
)
|
||||
singleOrMultipleRelColumnsCodec codecName =
|
||||
disjointEitherCodec
|
||||
@ -310,7 +314,7 @@ instance (Backend b) => FromJSON (ObjRelUsingChoice b) where
|
||||
pure $ RemoteTable table cols
|
||||
val -> SameTable <$> parseColumns val
|
||||
where
|
||||
parseColumns :: Value -> Parser (NonEmpty (Column b))
|
||||
parseColumns :: Value -> Parser (NonEmpty (ColumnPath b))
|
||||
parseColumns = \case
|
||||
v@(String _) -> pure <$> parseJSON v
|
||||
v@(Array _) -> parseJSON v
|
||||
@ -321,12 +325,12 @@ instance (Backend b) => HasCodec (ArrRelUsingFKeyOn b) where
|
||||
dimapCodec dec enc
|
||||
$ singleOrMultipleRelColumnsCodec @b (backendPrefix @b <> "ArrRelUsingFKeyOn")
|
||||
where
|
||||
dec :: (Either (TableName b, Column b) (TableName b, NonEmpty (Column b))) -> ArrRelUsingFKeyOn b
|
||||
dec :: (Either (TableName b, ColumnPath b) (TableName b, NonEmpty (ColumnPath b))) -> ArrRelUsingFKeyOn b
|
||||
dec = \case
|
||||
Left (qt, col) -> ArrRelUsingFKeyOn qt (pure col)
|
||||
Right (qt, cols) -> ArrRelUsingFKeyOn qt cols
|
||||
|
||||
enc :: ArrRelUsingFKeyOn b -> (Either (TableName b, Column b) (TableName b, NonEmpty (Column b)))
|
||||
enc :: ArrRelUsingFKeyOn b -> (Either (TableName b, ColumnPath b) (TableName b, NonEmpty (ColumnPath b)))
|
||||
enc = \case
|
||||
ArrRelUsingFKeyOn qt (col :| []) -> Left (qt, col)
|
||||
ArrRelUsingFKeyOn qt cols -> Right (qt, cols)
|
||||
@ -352,7 +356,7 @@ instance (Backend b) => FromJSON (ArrRelUsingFKeyOn b) where
|
||||
pure $ ArrRelUsingFKeyOn table cols
|
||||
_ -> fail "Expecting object { table, columns }."
|
||||
where
|
||||
parseColumns :: Value -> Parser (NonEmpty (Column b))
|
||||
parseColumns :: Value -> Parser (NonEmpty (ColumnPath b))
|
||||
parseColumns = \case
|
||||
v@(String _) -> pure <$> parseJSON v
|
||||
v@(Array _) -> parseJSON v
|
||||
@ -391,10 +395,48 @@ instance (Backend b) => ToJSON (RelTarget b) where
|
||||
|
||||
---
|
||||
|
||||
newtype RelMapping (b :: BackendType) = RelMapping {unRelMapping :: HashMap (ColumnPath b) (ColumnPath b)}
|
||||
deriving (Generic)
|
||||
|
||||
deriving instance (Backend b) => Show (RelMapping b)
|
||||
|
||||
deriving instance (Backend b) => Eq (RelMapping b)
|
||||
|
||||
deriving instance (Backend b) => Ord (RelMapping b)
|
||||
|
||||
deriving via AC.Autodocodec (RelMapping b) instance (Backend b) => FromJSON (RelMapping b)
|
||||
|
||||
deriving via AC.Autodocodec (RelMapping b) instance (Backend b) => ToJSON (RelMapping b)
|
||||
|
||||
instance (Backend b) => NFData (RelMapping b)
|
||||
|
||||
instance (Backend b) => Hashable (RelMapping b)
|
||||
|
||||
-- If all keys in the RelMapping have a singleton ColumnPath then we want to
|
||||
-- want to represent the mapping as a JSON object with the source columns as properties
|
||||
-- (using `codec @(HashMap (Column b) (ColumnPath b))`).
|
||||
-- This is required for metadata and API backwards compatibilty.
|
||||
-- If some of the keys are not singletons then we can't use a JSON object so we use
|
||||
-- an array of pairs instead, as provided by `codec @(HashMap (ColumnPath b) (ColumnPath b))`
|
||||
instance (Backend b) => HasCodec (RelMapping b) where
|
||||
codec =
|
||||
AC.matchChoiceCodec
|
||||
(AC.dimapCodec RelMapping unRelMapping $ codec @(HashMap (ColumnPath b) (ColumnPath b)))
|
||||
(AC.dimapCodec toRelMapping id $ codec @(HashMap (Column b) (ColumnPath b)))
|
||||
\m -> maybeToEither m (tryFromRelMapping m)
|
||||
where
|
||||
toRelMapping :: HashMap (Column b) (ColumnPath b) -> RelMapping b
|
||||
toRelMapping = RelMapping . HashMap.mapKeys Witch.from
|
||||
|
||||
tryFromRelMapping :: RelMapping b -> Maybe (HashMap (Column b) (ColumnPath b))
|
||||
tryFromRelMapping = fmap HashMap.fromList . traverse (bitraverse (tryColumnPathToColumn @b) pure) . HashMap.toList . unRelMapping
|
||||
|
||||
---
|
||||
|
||||
data RelInfo (b :: BackendType) = RelInfo
|
||||
{ riName :: RelName,
|
||||
riType :: RelType,
|
||||
riMapping :: HashMap (Column b) (Column b),
|
||||
riMapping :: RelMapping b,
|
||||
riTarget :: RelTarget b,
|
||||
riIsManual :: Bool,
|
||||
riInsertOrder :: InsertOrder
|
||||
|
@ -38,6 +38,7 @@ import Data.Text (Text)
|
||||
import GHC.Generics (Generic)
|
||||
import Hasura.LogicalModel.Metadata
|
||||
import Hasura.RQL.Types.Backend (Backend (..), ConstraintName)
|
||||
import Hasura.RQL.Types.Relationships.Local (RelMapping (..))
|
||||
import Hasura.RQL.Types.Source.Column (SourceColumnInfo)
|
||||
import Hasura.RQL.Types.Source.TableType
|
||||
import Prelude
|
||||
@ -102,7 +103,7 @@ instance (Backend b) => HasCodec (SourceForeignKeys b) where
|
||||
|
||||
data SourceConstraint b = SourceConstraint
|
||||
{ _scForeignTable :: TableName b,
|
||||
_scColumnMapping :: HashMap (Column b) (Column b)
|
||||
_scColumnMapping :: RelMapping b
|
||||
}
|
||||
deriving stock (Generic)
|
||||
deriving anyclass (Hashable)
|
||||
|
@ -984,7 +984,7 @@ instance (Backend b) => FromJSON (UniqueConstraint b) where
|
||||
data ForeignKey (b :: BackendType) = ForeignKey
|
||||
{ _fkConstraint :: Constraint b,
|
||||
_fkForeignTable :: TableName b,
|
||||
_fkColumnMapping :: NEHashMap (Column b) (Column b)
|
||||
_fkColumnMapping :: NEHashMap (ColumnPath b) (ColumnPath b)
|
||||
}
|
||||
deriving (Generic)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{-# LANGUAGE OverloadedLists #-}
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
|
||||
module Hasura.Backends.DataConnector.API.V0.ColumnSpec (spec, genColumnName, genColumnType, genColumnInfo, genColumnValueGenerationStrategy) where
|
||||
module Hasura.Backends.DataConnector.API.V0.ColumnSpec (spec, genColumnName, genColumnSelector, genColumnType, genColumnInfo, genColumnValueGenerationStrategy) where
|
||||
|
||||
import Data.Aeson.QQ.Simple (aesonQQ)
|
||||
import Hasura.Backends.DataConnector.API.V0
|
||||
@ -19,6 +19,12 @@ spec = do
|
||||
describe "ColumnName" $ do
|
||||
testToFromJSONToSchema (ColumnName "my_column_name") [aesonQQ|"my_column_name"|]
|
||||
jsonOpenApiProperties genColumnName
|
||||
describe "ColumnSelector" $ do
|
||||
describe "single column selector"
|
||||
$ testToFromJSONToSchema (ColumnSelectorColumn $ ColumnName "foo") [aesonQQ|"foo"|]
|
||||
describe "nested path selector"
|
||||
$ testToFromJSONToSchema (ColumnSelectorPath [ColumnName "foo", ColumnName "bar"]) [aesonQQ|["foo","bar"]|]
|
||||
jsonOpenApiProperties genColumnSelector
|
||||
describe "ColumnInfo" $ do
|
||||
describe "minimal"
|
||||
$ testFromJSON
|
||||
@ -56,6 +62,13 @@ spec = do
|
||||
genColumnName :: (MonadGen m) => m ColumnName
|
||||
genColumnName = ColumnName <$> genArbitraryAlphaNumText defaultRange
|
||||
|
||||
genColumnSelector :: (MonadGen m) => m ColumnSelector
|
||||
genColumnSelector =
|
||||
Gen.choice
|
||||
[ ColumnSelectorPath <$> Gen.nonEmpty defaultRange genColumnName,
|
||||
ColumnSelectorColumn <$> genColumnName
|
||||
]
|
||||
|
||||
genColumnType :: Gen ColumnType
|
||||
genColumnType =
|
||||
Gen.choice
|
||||
|
@ -10,14 +10,13 @@ module Hasura.Backends.DataConnector.API.V0.ExpressionSpec
|
||||
genExpression,
|
||||
genRedactionExpressionName,
|
||||
genTargetRedactionExpressions,
|
||||
genColumnSelector,
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Aeson
|
||||
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.ColumnSpec (genColumnSelector)
|
||||
import Hasura.Backends.DataConnector.API.V0.RelationshipsSpec (genRelationshipName)
|
||||
import Hasura.Backends.DataConnector.API.V0.ScalarSpec (genScalarType, genScalarValue)
|
||||
import Hasura.Backends.DataConnector.API.V0.TableSpec (genTableName)
|
||||
@ -84,13 +83,6 @@ spec = do
|
||||
$ testToFromJSONToSchema CurrentTable [aesonQQ|[]|]
|
||||
jsonOpenApiProperties genColumnPath
|
||||
|
||||
describe "ColumnSelector" $ do
|
||||
describe "single column selector"
|
||||
$ testToFromJSONToSchema (ColumnSelector [ColumnName "foo"]) [aesonQQ|"foo"|]
|
||||
describe "nested path selector"
|
||||
$ testToFromJSONToSchema (ColumnSelector [ColumnName "foo", ColumnName "bar"]) [aesonQQ|["foo","bar"]|]
|
||||
jsonOpenApiProperties genColumnSelector
|
||||
|
||||
describe "ComparisonValue" $ do
|
||||
describe "AnotherColumnComparison"
|
||||
$ testToFromJSONToSchema
|
||||
@ -290,10 +282,6 @@ genColumnPath :: (MonadGen m) => m ColumnPath
|
||||
genColumnPath =
|
||||
Gen.element [CurrentTable, QueryTable]
|
||||
|
||||
genColumnSelector :: (MonadGen m) => m ColumnSelector
|
||||
genColumnSelector =
|
||||
ColumnSelector <$> Gen.nonEmpty defaultRange genColumnName
|
||||
|
||||
genComparisonValue :: (MonadGen m, GenBase m ~ Identity) => m ComparisonValue
|
||||
genComparisonValue =
|
||||
Gen.choice
|
||||
|
@ -12,7 +12,8 @@ import Data.Aeson.QQ.Simple (aesonQQ)
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Hasura.Backends.DataConnector.API.V0
|
||||
import Hasura.Backends.DataConnector.API.V0.AggregateSpec (genSingleColumnAggregate)
|
||||
import Hasura.Backends.DataConnector.API.V0.ExpressionSpec (genColumnSelector, genExpression, genRedactionExpressionName)
|
||||
import Hasura.Backends.DataConnector.API.V0.ColumnSpec (genColumnSelector)
|
||||
import Hasura.Backends.DataConnector.API.V0.ExpressionSpec (genExpression, genRedactionExpressionName)
|
||||
import Hasura.Backends.DataConnector.API.V0.RelationshipsSpec (genRelationshipName)
|
||||
import Hasura.Generator.Common (defaultRange)
|
||||
import Hasura.Prelude
|
||||
|
@ -12,7 +12,7 @@ where
|
||||
import Data.Aeson.QQ.Simple (aesonQQ)
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Hasura.Backends.DataConnector.API.V0
|
||||
import Hasura.Backends.DataConnector.API.V0.ColumnSpec (genColumnName)
|
||||
import Hasura.Backends.DataConnector.API.V0.ColumnSpec (genColumnSelector)
|
||||
import Hasura.Backends.DataConnector.API.V0.TableSpec (genTableName, genTableTarget)
|
||||
import Hasura.Generator.Common (defaultRange, genArbitraryAlphaNumText)
|
||||
import Hasura.Prelude
|
||||
@ -38,7 +38,7 @@ spec = do
|
||||
Relationship
|
||||
{ _rTarget = TTable (TargetTable (TableName ["target_table_name"])),
|
||||
_rRelationshipType = ObjectRelationship,
|
||||
_rColumnMapping = [(ColumnName "outer_column", ColumnName "inner_column")]
|
||||
_rColumnMapping = ColumnPathMapping [(mkColumnSelector $ ColumnName "outer_column", mkColumnSelector $ ColumnName "inner_column")]
|
||||
}
|
||||
testToFromJSONToSchema
|
||||
relationship
|
||||
@ -51,18 +51,20 @@ spec = do
|
||||
}
|
||||
|]
|
||||
jsonOpenApiProperties genRelationship
|
||||
describe "ColumnPathMapping"
|
||||
$ jsonOpenApiProperties genColumnPathMapping
|
||||
describe "TableRelationships" $ do
|
||||
let relationshipA =
|
||||
Relationship
|
||||
{ _rTarget = TTable (TargetTable (TableName ["target_table_name_a"])),
|
||||
_rRelationshipType = ObjectRelationship,
|
||||
_rColumnMapping = [(ColumnName "outer_column_a", ColumnName "inner_column_a")]
|
||||
_rColumnMapping = ColumnPathMapping [(mkColumnSelector $ ColumnName "outer_column_a", mkColumnSelector $ ColumnName "inner_column_a")]
|
||||
}
|
||||
let relationshipB =
|
||||
Relationship
|
||||
{ _rTarget = TTable (TargetTable (TableName ["target_table_name_b"])),
|
||||
_rRelationshipType = ArrayRelationship,
|
||||
_rColumnMapping = [(ColumnName "outer_column_b", ColumnName "inner_column_b")]
|
||||
_rColumnMapping = ColumnPathMapping [(mkColumnSelector $ ColumnName "outer_column_b", mkColumnSelector $ ColumnName "inner_column_b")]
|
||||
}
|
||||
let tableRelationships =
|
||||
TableRelationships
|
||||
@ -109,7 +111,7 @@ genRelationship =
|
||||
Relationship
|
||||
<$> genTableTarget
|
||||
<*> genRelationshipType
|
||||
<*> (HashMap.fromList <$> Gen.list defaultRange ((,) <$> genColumnName <*> genColumnName))
|
||||
<*> genColumnPathMapping
|
||||
|
||||
genRelationships :: Gen Relationships
|
||||
genRelationships = (RTable <$> genTableRelationships) <|> (RFunction <$> genFunctionRelationships)
|
||||
@ -128,3 +130,6 @@ genFunctionRelationships =
|
||||
|
||||
genFunctionName :: (MonadGen m) => m FunctionName
|
||||
genFunctionName = FunctionName <$> Gen.nonEmpty (linear 1 3) (genArbitraryAlphaNumText defaultRange)
|
||||
|
||||
genColumnPathMapping :: (MonadGen m) => m ColumnPathMapping
|
||||
genColumnPathMapping = ColumnPathMapping . HashMap.fromList <$> Gen.list defaultRange ((,) <$> genColumnSelector <*> genColumnSelector)
|
||||
|
@ -6,7 +6,7 @@ module Hasura.Backends.DataConnector.API.V0.TableSpec (spec, genTableName, genTa
|
||||
import Data.Aeson.QQ.Simple (aesonQQ)
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Hasura.Backends.DataConnector.API.V0
|
||||
import Hasura.Backends.DataConnector.API.V0.ColumnSpec (genColumnInfo, genColumnName)
|
||||
import Hasura.Backends.DataConnector.API.V0.ColumnSpec (genColumnInfo, genColumnName, genColumnSelector)
|
||||
import Hasura.Generator.Common
|
||||
import Hasura.Prelude
|
||||
import Hedgehog
|
||||
@ -60,7 +60,14 @@ spec = do
|
||||
Table
|
||||
[ColumnInfo (ColumnName "id") (ColumnTypeScalar $ ScalarType "string") False Nothing False False Nothing]
|
||||
(Just $ ColumnName "id" :| [])
|
||||
(ForeignKeys $ HashMap.singleton (ConstraintName "Artist") (Constraint (TableName ["artist_table"]) (HashMap.singleton (ColumnName "ArtistId") (ColumnName "ArtistId"))))
|
||||
( ForeignKeys
|
||||
$ HashMap.singleton
|
||||
(ConstraintName "Artist")
|
||||
( Constraint
|
||||
(TableName ["artist_table"])
|
||||
(ColumnPathMapping $ HashMap.singleton (mkColumnSelector $ ColumnName "ArtistId") (mkColumnSelector $ ColumnName "ArtistId"))
|
||||
)
|
||||
)
|
||||
(Just "my description")
|
||||
False
|
||||
False
|
||||
@ -101,7 +108,7 @@ genConstraintName = ConstraintName <$> genArbitraryAlphaNumText defaultRange
|
||||
|
||||
genConstraint :: (MonadGen m) => m Constraint
|
||||
genConstraint =
|
||||
let mapping = genHashMap genColumnName genColumnName defaultRange
|
||||
let mapping = ColumnPathMapping <$> genHashMap genColumnSelector genColumnSelector defaultRange
|
||||
in Constraint <$> genTableName <*> mapping
|
||||
|
||||
genTableType :: (MonadGen m) => m TableType
|
||||
|
@ -47,6 +47,7 @@ genSelectArgsG genA = do
|
||||
Gen.maybe
|
||||
$ genAnnBoolExp
|
||||
( genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumn
|
||||
genTableName
|
||||
genScalarType
|
||||
@ -66,6 +67,7 @@ genSelectArgsG genA = do
|
||||
genBasicOrderType
|
||||
genNullsOrderType
|
||||
( genAnnotatedOrderByElement @_ @('Postgres 'Vanilla)
|
||||
genColumn
|
||||
genColumn
|
||||
genTableName
|
||||
genScalarType
|
||||
@ -89,6 +91,7 @@ genSelectArgsG genA = do
|
||||
$ AnnDistinctColumn
|
||||
<$> genColumn
|
||||
<*> genAnnRedactionExp
|
||||
genColumn
|
||||
genColumn
|
||||
genTableName
|
||||
genScalarType
|
||||
|
@ -24,7 +24,7 @@ import Hedgehog.Gen qualified as Gen
|
||||
|
||||
genTablePermG :: (MonadGen m) => m a -> m (TablePermG ('Postgres 'Vanilla) a)
|
||||
genTablePermG genA = do
|
||||
let genV = genAnnBoolExpFld @_ @('Postgres 'Vanilla) genColumn genTableName genScalarType genFunctionName genXComputedField (genBooleanOperators genA) (genFunctionArgumentExp genA) genA
|
||||
let genV = genAnnBoolExpFld @_ @('Postgres 'Vanilla) genColumn genColumn genTableName genScalarType genFunctionName genXComputedField (genBooleanOperators genA) (genFunctionArgumentExp genA) genA
|
||||
gBoolExp <- genAnnBoolExp @_ @_ @('Postgres 'Vanilla) genV genTableName
|
||||
limit <- Gen.maybe (Gen.integral defaultRange)
|
||||
pure $ TablePerm gBoolExp limit
|
||||
|
@ -29,7 +29,7 @@ import Hasura.RQL.Types.BackendType (BackendSourceKind (PostgresVanillaKind), Ba
|
||||
import Hasura.RQL.Types.Column (ColumnType (ColumnScalar), ColumnValue (..))
|
||||
import Hasura.RQL.Types.Common (InsertOrder (..), RelName (..), RelType (..), SourceName (..))
|
||||
import Hasura.RQL.Types.NamingCase (NamingCase (..))
|
||||
import Hasura.RQL.Types.Relationships.Local (RelInfo (..), RelTarget (..))
|
||||
import Hasura.RQL.Types.Relationships.Local (RelInfo (..), RelMapping (..), RelTarget (..))
|
||||
import Hasura.RQL.Types.Schema.Options qualified as Options
|
||||
import Hasura.RQL.Types.Source (DBObjectsIntrospection (..), SourceInfo (..))
|
||||
import Hasura.RQL.Types.SourceCustomization (ResolvedSourceCustomization (..))
|
||||
@ -307,7 +307,7 @@ spec = do
|
||||
RelInfo
|
||||
{ riName = RelName [nonEmptyTextQQ|tracks|],
|
||||
riType = ArrRel,
|
||||
riMapping = HashMap.fromList [("id", "album_id")],
|
||||
riMapping = RelMapping $ HashMap.fromList [("id", "album_id")],
|
||||
riTarget = RelTargetTable (mkTable "track"),
|
||||
riIsManual = False,
|
||||
riInsertOrder = AfterParent
|
||||
|
@ -62,7 +62,9 @@ genAnnRedactionExp ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (ScalarType b)) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (TableName b) ->
|
||||
m (ScalarType b) ->
|
||||
m (FunctionName b) ->
|
||||
@ -73,6 +75,7 @@ genAnnRedactionExp ::
|
||||
m (AnnRedactionExp b a)
|
||||
genAnnRedactionExp
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -87,6 +90,7 @@ genAnnRedactionExp
|
||||
<$> genAnnBoolExp
|
||||
( genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -129,7 +133,9 @@ genAnnBoolExpFld ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (ScalarType b)) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (TableName b) ->
|
||||
m (ScalarType b) ->
|
||||
m (FunctionName b) ->
|
||||
@ -140,6 +146,7 @@ genAnnBoolExpFld ::
|
||||
m (AnnBoolExpFld b a)
|
||||
genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -157,6 +164,7 @@ genAnnBoolExpFld
|
||||
genScalarType
|
||||
<*> genAnnRedactionExp
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -175,11 +183,12 @@ genAnnBoolExpFld
|
||||
)
|
||||
relationship =
|
||||
AVRelationship
|
||||
<$> genRelInfo genTableName genColumn
|
||||
<$> genRelInfo genTableName genColumnPath
|
||||
<*> ( RelationshipFilters
|
||||
<$> genAnnBoolExp
|
||||
( genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -192,6 +201,7 @@ genAnnBoolExpFld
|
||||
<*> genAnnBoolExp
|
||||
( genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -207,6 +217,7 @@ genAnnBoolExpFld
|
||||
<$> genAnnComputedFieldBolExp
|
||||
genTableName
|
||||
genColumn
|
||||
genColumnPath
|
||||
genScalarType
|
||||
genBooleanOperators
|
||||
genXComputedField
|
||||
@ -216,15 +227,15 @@ genAnnBoolExpFld
|
||||
|
||||
genRelInfo ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (TableName b) ->
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (RelInfo b)
|
||||
genRelInfo genTableName genColumn =
|
||||
RelInfo
|
||||
<$> genRelName
|
||||
<*> genRelType
|
||||
<*> genHashMap genColumn genColumn defaultRange
|
||||
<*> (RelMapping <$> genHashMap genColumn genColumn defaultRange)
|
||||
<*> genRelTarget genTableName
|
||||
<*> bool_
|
||||
<*> genInsertOrder
|
||||
@ -252,8 +263,10 @@ genAnnComputedFieldBolExp ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (ScalarType b)) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (TableName b) ->
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (ScalarType b) ->
|
||||
m (BooleanOperators b a) ->
|
||||
m (XComputedField b) ->
|
||||
@ -264,6 +277,7 @@ genAnnComputedFieldBolExp ::
|
||||
genAnnComputedFieldBolExp
|
||||
genTableName
|
||||
genColumn
|
||||
genColumnPath
|
||||
genScalarType
|
||||
genBooleanOperators
|
||||
genXComputedField
|
||||
@ -278,6 +292,7 @@ genAnnComputedFieldBolExp
|
||||
<*> genComputedFieldBoolExp
|
||||
genTableName
|
||||
genColumn
|
||||
genColumnPath
|
||||
genScalarType
|
||||
genFunctionName
|
||||
genXComputedField
|
||||
@ -289,8 +304,10 @@ genComputedFieldBoolExp ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (ScalarType b)) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (TableName b) ->
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (ScalarType b) ->
|
||||
m (FunctionName b) ->
|
||||
m (XComputedField b) ->
|
||||
@ -301,6 +318,7 @@ genComputedFieldBoolExp ::
|
||||
genComputedFieldBoolExp
|
||||
genTableName
|
||||
genColumn
|
||||
genColumnPath
|
||||
genScalarType
|
||||
genFunctionName
|
||||
genXComputedField
|
||||
@ -311,6 +329,7 @@ genComputedFieldBoolExp
|
||||
[ CFBEScalar
|
||||
<$> genAnnRedactionExp
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -332,6 +351,7 @@ genComputedFieldBoolExp
|
||||
<*> genAnnBoolExp
|
||||
( genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -492,7 +512,9 @@ genAnnotatedOrderByElement ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (ScalarType b)) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (TableName b) ->
|
||||
m (ScalarType b) ->
|
||||
m (FunctionName b) ->
|
||||
@ -503,6 +525,7 @@ genAnnotatedOrderByElement ::
|
||||
m (AnnotatedOrderByElement b a)
|
||||
genAnnotatedOrderByElement
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -525,6 +548,7 @@ genAnnotatedOrderByElement
|
||||
genScalarType
|
||||
<*> genAnnRedactionExp
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -534,10 +558,11 @@ genAnnotatedOrderByElement
|
||||
genA
|
||||
objectRelation =
|
||||
AOCObjectRelation
|
||||
<$> genRelInfo genTableName genColumn
|
||||
<$> genRelInfo genTableName genColumnPath
|
||||
<*> genAnnBoolExp
|
||||
( genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -549,6 +574,7 @@ genAnnotatedOrderByElement
|
||||
genTableName
|
||||
<*> genAnnotatedOrderByElement
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -558,10 +584,11 @@ genAnnotatedOrderByElement
|
||||
genA
|
||||
arrayAggregation =
|
||||
AOCArrayAggregation
|
||||
<$> genRelInfo genTableName genColumn
|
||||
<$> genRelInfo genTableName genColumnPath
|
||||
<*> genAnnBoolExp
|
||||
( genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -573,6 +600,7 @@ genAnnotatedOrderByElement
|
||||
genTableName
|
||||
<*> genAnnotatedAggregateOrderBy
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -584,6 +612,7 @@ genAnnotatedOrderByElement
|
||||
AOCComputedField
|
||||
<$> genComputedFieldOrderBy
|
||||
genColumn
|
||||
genColumnPath
|
||||
genScalarType
|
||||
genTableName
|
||||
genFunctionName
|
||||
@ -596,7 +625,9 @@ genAnnotatedAggregateOrderBy ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (ScalarType b)) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (TableName b) ->
|
||||
m (ScalarType b) ->
|
||||
m (FunctionName b) ->
|
||||
@ -607,6 +638,7 @@ genAnnotatedAggregateOrderBy ::
|
||||
m (AnnotatedAggregateOrderBy b a)
|
||||
genAnnotatedAggregateOrderBy
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -626,6 +658,7 @@ genAnnotatedAggregateOrderBy
|
||||
genScalarType
|
||||
<*> genAnnRedactionExp
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -640,7 +673,9 @@ genComputedFieldOrderBy ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (ScalarType b)) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (ScalarType b) ->
|
||||
m (TableName b) ->
|
||||
m (FunctionName b) ->
|
||||
@ -651,6 +686,7 @@ genComputedFieldOrderBy ::
|
||||
m (ComputedFieldOrderBy b a)
|
||||
genComputedFieldOrderBy
|
||||
genColumn
|
||||
genColumnPath
|
||||
genScalarType
|
||||
genTableName
|
||||
genFunctionName
|
||||
@ -665,6 +701,7 @@ genComputedFieldOrderBy
|
||||
<*> genFunctionArgsExpG genFunctionArgumentExp
|
||||
<*> genComputedFieldOrderByElement
|
||||
genColumn
|
||||
genColumnPath
|
||||
genScalarType
|
||||
genTableName
|
||||
genFunctionName
|
||||
@ -677,7 +714,9 @@ genComputedFieldOrderByElement ::
|
||||
(MonadGen m) =>
|
||||
(Hashable (ScalarType b)) =>
|
||||
(Hashable (Column b)) =>
|
||||
(Hashable (ColumnPath b)) =>
|
||||
m (Column b) ->
|
||||
m (ColumnPath b) ->
|
||||
m (ScalarType b) ->
|
||||
m (TableName b) ->
|
||||
m (FunctionName b) ->
|
||||
@ -688,6 +727,7 @@ genComputedFieldOrderByElement ::
|
||||
m (ComputedFieldOrderByElement b a)
|
||||
genComputedFieldOrderByElement
|
||||
genColumn
|
||||
genColumnPath
|
||||
genScalarType
|
||||
genTableName
|
||||
genFunctionName
|
||||
@ -700,6 +740,7 @@ genComputedFieldOrderByElement
|
||||
<$> genScalarType
|
||||
<*> genAnnRedactionExp
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -712,6 +753,7 @@ genComputedFieldOrderByElement
|
||||
<*> genAnnBoolExp
|
||||
( genAnnBoolExpFld
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
@ -723,6 +765,7 @@ genComputedFieldOrderByElement
|
||||
genTableName
|
||||
<*> genAnnotatedAggregateOrderBy
|
||||
genColumn
|
||||
genColumnPath
|
||||
genTableName
|
||||
genScalarType
|
||||
genFunctionName
|
||||
|
Loading…
Reference in New Issue
Block a user