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