Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: kysely-org/kysely
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b9b80bcefc2afe4c3bcb2601a0d781670dcf4120
Choose a base ref
..
head repository: kysely-org/kysely
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f75bc1ed4b832486cf41bfecb8a09c4da80fd587
Choose a head ref
Showing with 88 additions and 0 deletions.
  1. +41 −0 src/plugin/with-schema/with-schema-transformer.ts
  2. +47 −0 test/node/src/with-schema.test.ts
41 changes: 41 additions & 0 deletions src/plugin/with-schema/with-schema-transformer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { AggregateFunctionNode } from '../../operation-node/aggregate-function-node.js'
import { AliasNode } from '../../operation-node/alias-node.js'
import { FunctionNode } from '../../operation-node/function-node.js'
import { IdentifierNode } from '../../operation-node/identifier-node.js'
import { ListNode } from '../../operation-node/list-node.js'
import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js'
@@ -36,6 +38,11 @@ const ROOT_OPERATION_NODES: Record<RootOperationNode['kind'], true> = freeze({
MergeQueryNode: true,
})

const SCHEMALESS_FUNCTIONS: Record<string, true> = {
json_agg: true,
to_json: true,
}

export class WithSchemaTransformer extends OperationNodeTransformer {
readonly #schema: string
readonly #schemableIds = new Set<string>()
@@ -107,6 +114,40 @@ export class WithSchemaTransformer extends OperationNodeTransformer {
}
}

protected override transformAggregateFunction(
node: AggregateFunctionNode,
): AggregateFunctionNode {
return {
...super.transformAggregateFunction({ ...node, aggregated: [] }),
aggregated: this.#transformTableArgsWithoutSchemas(node, 'aggregated'),
}
}

protected override transformFunction(node: FunctionNode): FunctionNode {
return {
...super.transformFunction({ ...node, arguments: [] }),
arguments: this.#transformTableArgsWithoutSchemas(node, 'arguments'),
}
}

#transformTableArgsWithoutSchemas<
A extends string,
N extends { func: string } & {
[K in A]: readonly OperationNode[]
},
>(node: N, argsKey: A): readonly OperationNode[] {
return SCHEMALESS_FUNCTIONS[node.func]
? node[argsKey].map((arg) =>
!TableNode.is(arg) || arg.table.schema
? this.transformNode(arg)
: {
...arg,
table: this.transformIdentifier(arg.table.identifier),
},
)
: this.transformNodeList(node[argsKey])
}

#isRootOperationNode(node: OperationNode): node is RootOperationNode {
return node.kind in ROOT_OPERATION_NODES
}
47 changes: 47 additions & 0 deletions test/node/src/with-schema.test.ts
Original file line number Diff line number Diff line change
@@ -218,6 +218,53 @@ for (const dialect of DIALECTS.filter(

await query.execute()
})

if (dialect === 'postgres') {
it('should not add schema for json_agg parameters', async () => {
const query = ctx.db
.withSchema('mammals')
.selectFrom('pet')
.select((eb) => [
eb.fn.jsonAgg('pet').as('one'),
eb.fn.jsonAgg(eb.table('pet')).as('two'),
eb.fn.jsonAgg('pet').orderBy('pet.name', 'desc').as('three'),
])

testSql(query, dialect, {
postgres: {
sql: 'select json_agg("pet") as "one", json_agg("pet") as "two", json_agg("pet" order by "mammals"."pet"."name" desc) as "three" from "mammals"."pet"',
parameters: [],
},
mysql: NOT_SUPPORTED,
mssql: NOT_SUPPORTED,
sqlite: NOT_SUPPORTED,
})

await query.execute()
})

it('should not add schema for to_json parameters', async () => {
const query = ctx.db
.withSchema('mammals')
.selectFrom('pet')
.select((eb) => [
eb.fn.toJson('pet').as('one'),
eb.fn.toJson(eb.table('pet')).as('two'),
])

testSql(query, dialect, {
postgres: {
sql: 'select to_json("pet") as "one", to_json("pet") as "two" from "mammals"."pet"',
parameters: [],
},
mysql: NOT_SUPPORTED,
mssql: NOT_SUPPORTED,
sqlite: NOT_SUPPORTED,
})

await query.execute()
})
}
})

describe('insert into', () => {