@hypequery/clickhouse 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/cte-scope.d.ts +91 -0
- package/dist/core/cte-scope.d.ts.map +1 -0
- package/dist/core/cte-scope.js +52 -0
- package/dist/core/dialects/clickhouse-dialect.d.ts.map +1 -1
- package/dist/core/dialects/clickhouse-dialect.js +4 -1
- package/dist/core/features/analytics.d.ts +13 -2
- package/dist/core/features/analytics.d.ts.map +1 -1
- package/dist/core/features/analytics.js +49 -3
- package/dist/core/features/joins.d.ts +5 -1
- package/dist/core/features/joins.d.ts.map +1 -1
- package/dist/core/features/joins.js +5 -1
- package/dist/core/formatters/sql-formatter.d.ts +1 -0
- package/dist/core/formatters/sql-formatter.d.ts.map +1 -1
- package/dist/core/formatters/sql-formatter.js +10 -3
- package/dist/core/query-builder.d.ts +89 -12
- package/dist/core/query-builder.d.ts.map +1 -1
- package/dist/core/query-builder.js +56 -4
- package/dist/core/query-node.d.ts.map +1 -1
- package/dist/core/query-node.js +7 -1
- package/dist/core/tests/integration/setup.d.ts +9 -0
- package/dist/core/tests/integration/setup.d.ts.map +1 -1
- package/dist/core/tests/test-utils.d.ts +23 -1
- package/dist/core/tests/test-utils.d.ts.map +1 -1
- package/dist/core/tests/test-utils.js +12 -3
- package/dist/core/types/builder-state.d.ts +68 -9
- package/dist/core/types/builder-state.d.ts.map +1 -1
- package/dist/core/types/builder-state.js +1 -0
- package/dist/core/types/select-types.d.ts +4 -2
- package/dist/core/types/select-types.d.ts.map +1 -1
- package/dist/core/utils/compound-parameter.d.ts +6 -0
- package/dist/core/utils/compound-parameter.d.ts.map +1 -0
- package/dist/core/utils/compound-parameter.js +70 -0
- package/dist/core/utils/cte-fragments.d.ts +17 -0
- package/dist/core/utils/cte-fragments.d.ts.map +1 -0
- package/dist/core/utils/cte-fragments.js +20 -0
- package/dist/core/utils/cte-scope-state.d.ts +5 -0
- package/dist/core/utils/cte-scope-state.d.ts.map +1 -0
- package/dist/core/utils/cte-scope-state.js +16 -0
- package/dist/core/utils/named-parameters.d.ts +30 -0
- package/dist/core/utils/named-parameters.d.ts.map +1 -0
- package/dist/core/utils/named-parameters.js +108 -0
- package/dist/core/utils/parameter-type.d.ts +10 -0
- package/dist/core/utils/parameter-type.d.ts.map +1 -0
- package/dist/core/utils/parameter-type.js +46 -0
- package/dist/core/utils/record-guards.d.ts +3 -0
- package/dist/core/utils/record-guards.d.ts.map +1 -0
- package/dist/core/utils/record-guards.js +7 -0
- package/dist/core/utils/sql-parens.d.ts +6 -0
- package/dist/core/utils/sql-parens.d.ts.map +1 -1
- package/dist/core/utils/sql-parens.js +6 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/types/base.d.ts +39 -0
- package/dist/types/base.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -9,6 +9,7 @@ import { QueryModifiersFeature } from './features/query-modifiers.js';
|
|
|
9
9
|
import { FilterValidator } from './validators/filter-validator.js';
|
|
10
10
|
import { createPredicateBuilder, } from './utils/predicate-builder.js';
|
|
11
11
|
import { CrossFilteringFeature } from './features/cross-filtering.js';
|
|
12
|
+
import { CteScope } from './cte-scope.js';
|
|
12
13
|
import { cloneSelectQueryNode, createSelectQueryNode, transformSelectQueryNode, } from './query-node.js';
|
|
13
14
|
import { executeWithCache } from './cache/cache-manager.js';
|
|
14
15
|
import { mergeCacheOptionsPartial, initializeCacheRuntime } from './cache/utils.js';
|
|
@@ -99,6 +100,9 @@ export class QueryBuilder {
|
|
|
99
100
|
if (this.query.from?.kind === 'subquery') {
|
|
100
101
|
throw new Error(`${feature} can only be applied to a table source. Apply ${innerMethod} to the inner query before passing it to db.from().`);
|
|
101
102
|
}
|
|
103
|
+
if (this.query.from?.kind === 'table' && this.query.from.cte) {
|
|
104
|
+
throw new Error(`${feature} can only be applied to a table source, and "${this.query.from.name}" is a CTE.`);
|
|
105
|
+
}
|
|
102
106
|
}
|
|
103
107
|
withAliasesState(aliases) {
|
|
104
108
|
return {
|
|
@@ -169,10 +173,33 @@ export class QueryBuilder {
|
|
|
169
173
|
next.cacheOptions = mergeCacheOptionsPartial(next.cacheOptions, options);
|
|
170
174
|
return next;
|
|
171
175
|
}
|
|
172
|
-
//
|
|
173
|
-
|
|
176
|
+
// Overloads expose the precise state. The implementation erases only State
|
|
177
|
+
// because QueryBuilder instances with different states are not assignable.
|
|
178
|
+
withCTE(alias, subquery, columns) {
|
|
179
|
+
return this.addCte(alias, subquery, columns, false);
|
|
180
|
+
}
|
|
181
|
+
withRecursiveCTE(alias, body, columns) {
|
|
182
|
+
return this.addCte(alias, body, columns, true);
|
|
183
|
+
}
|
|
184
|
+
addCte(alias, subquery, columns, recursive) {
|
|
174
185
|
assertSafeIdentifier(alias, 'CTE alias');
|
|
175
|
-
|
|
186
|
+
for (const column of Object.keys(columns ?? {})) {
|
|
187
|
+
assertSafeIdentifier(column, 'CTE column');
|
|
188
|
+
}
|
|
189
|
+
const nextConfig = this.analytics.addCTE(alias, subquery, { recursive });
|
|
190
|
+
// A raw body with no declared columns exposes nothing to type against, so
|
|
191
|
+
// the alias stays unregistered rather than registering an empty shape.
|
|
192
|
+
if (!(subquery instanceof QueryBuilder) && !columns) {
|
|
193
|
+
return this.assignQuery(this.cloneMutable(), nextConfig);
|
|
194
|
+
}
|
|
195
|
+
// Columns are carried by the state's type; a builder CTE takes its shape
|
|
196
|
+
// from the subquery's output type, so the runtime value stays empty.
|
|
197
|
+
const shape = columns ?? {};
|
|
198
|
+
const nextState = {
|
|
199
|
+
...this.state,
|
|
200
|
+
ctes: { ...this.state.ctes, [alias]: shape },
|
|
201
|
+
};
|
|
202
|
+
return this.transition(nextState, nextConfig);
|
|
176
203
|
}
|
|
177
204
|
// --- Analytics Helper: Add a scalar WITH alias.
|
|
178
205
|
withScalar(alias, expressionBuilder) {
|
|
@@ -530,7 +557,7 @@ export class QueryBuilder {
|
|
|
530
557
|
? { ...this.state.aliases, [alias]: table }
|
|
531
558
|
: this.state.aliases);
|
|
532
559
|
const nextState = this.withAliasesState(nextAliases);
|
|
533
|
-
const nextConfig = this.joins.addJoin(type, table, String(leftColumn), rightColumn, alias, undefined, on);
|
|
560
|
+
const nextConfig = this.joins.addJoin(type, String(table), String(leftColumn), String(rightColumn), alias, undefined, on);
|
|
534
561
|
return this.transition(nextState, nextConfig);
|
|
535
562
|
}
|
|
536
563
|
/**
|
|
@@ -571,10 +598,34 @@ export function createQueryBuilder(config) {
|
|
|
571
598
|
const resolvedDialect = dialect ?? new ClickHouseDialect();
|
|
572
599
|
const namespace = cacheConfig?.namespace || resolvedAdapter.namespace || resolvedAdapter.name;
|
|
573
600
|
const { runtime, cacheController } = initializeCacheRuntime(cacheConfig, namespace);
|
|
601
|
+
const rootScope = new CteScope({
|
|
602
|
+
runtime,
|
|
603
|
+
adapter: resolvedAdapter,
|
|
604
|
+
dialect: resolvedDialect,
|
|
605
|
+
});
|
|
574
606
|
return {
|
|
575
607
|
cache: cacheController,
|
|
576
608
|
adapter: resolvedAdapter,
|
|
577
609
|
dialect: resolvedDialect,
|
|
610
|
+
/**
|
|
611
|
+
* Declares a CTE before the query has a source, so the query can read from
|
|
612
|
+
* it. Use `db.table('x').withCTE(...)` when the CTE is only joined in.
|
|
613
|
+
*
|
|
614
|
+
* @example
|
|
615
|
+
* ```ts
|
|
616
|
+
* const rows = await db
|
|
617
|
+
* .withCTE('active_users', db.table('users').select(['id']).where('status', 'eq', 'active'))
|
|
618
|
+
* .table('active_users')
|
|
619
|
+
* .select(['id'])
|
|
620
|
+
* .execute();
|
|
621
|
+
* ```
|
|
622
|
+
*/
|
|
623
|
+
withCTE: rootScope.withCTE.bind(rootScope),
|
|
624
|
+
/**
|
|
625
|
+
* Declares a recursive CTE and renders the clause as `WITH RECURSIVE`.
|
|
626
|
+
* See {@link CteScope.withRecursiveCTE}.
|
|
627
|
+
*/
|
|
628
|
+
withRecursiveCTE: rootScope.withRecursiveCTE.bind(rootScope),
|
|
578
629
|
async rawQuery(sql, params = [], options) {
|
|
579
630
|
return resolvedAdapter.query(sql, params, options);
|
|
580
631
|
},
|
|
@@ -644,6 +695,7 @@ export function createQueryBuilder(config) {
|
|
|
644
695
|
base: {},
|
|
645
696
|
aliases: {},
|
|
646
697
|
scalars: {},
|
|
698
|
+
ctes: {},
|
|
647
699
|
};
|
|
648
700
|
const builder = new QueryBuilder(subquery.getTableName(), state, runtime, resolvedAdapter, resolvedDialect, {
|
|
649
701
|
kind: 'subquery',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-node.d.ts","sourceRoot":"","sources":["../../src/core/query-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AA0B3B,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAgCnE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EACpD,MAAM,GAAE,WAAW,CAAC,OAAO,EAAE,OAAO,CAAM,GACzC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"query-node.d.ts","sourceRoot":"","sources":["../../src/core/query-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AA0B3B,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAgCnE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EACpD,MAAM,GAAE,WAAW,CAAC,OAAO,EAAE,OAAO,CAAM,GACzC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAuCnC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EACnD,KAAK,EAAE,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,GACvC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAEnC;AAED,wBAAgB,qBAAqB,CACnC,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,CAAM,GAClD,eAAe,CAOjB;AAoBD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,CAE5E;AAED,MAAM,MAAM,kBAAkB,CAAC,OAAO,EAAE,OAAO,IAAI,CACjD,KAAK,EAAE,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,KACrC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEvC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EACvD,KAAK,EAAE,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,EACxC,UAAU,EAAE,aAAa,CAAC,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,GAC9D,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAKnC"}
|
package/dist/core/query-node.js
CHANGED
|
@@ -82,7 +82,13 @@ export function createSelectQueryNode(config = {}) {
|
|
|
82
82
|
joins: config.joins
|
|
83
83
|
? config.joins.map(item => ({ ...item, on: cloneExprNode(item.on) }))
|
|
84
84
|
: undefined,
|
|
85
|
-
ctes: config.ctes
|
|
85
|
+
ctes: config.ctes
|
|
86
|
+
? config.ctes.map(item => ({
|
|
87
|
+
...item,
|
|
88
|
+
parameters: item.parameters ? [...item.parameters] : undefined,
|
|
89
|
+
}))
|
|
90
|
+
: undefined,
|
|
91
|
+
recursiveCtes: config.recursiveCtes,
|
|
86
92
|
unionQueries: config.unionQueries ? [...config.unionQueries] : undefined,
|
|
87
93
|
settings: config.settings ? { ...config.settings } : undefined,
|
|
88
94
|
};
|
|
@@ -3,6 +3,15 @@ export declare const initializeTestConnection: () => Promise<{
|
|
|
3
3
|
cache: import("../../cache/controller.js").CacheController;
|
|
4
4
|
adapter: import("../../adapters/database-adapter.js").DatabaseAdapter;
|
|
5
5
|
dialect: import("../../dialects/sql-dialect.js").SqlDialect;
|
|
6
|
+
withCTE: {
|
|
7
|
+
<Alias extends string, SubqueryState extends import("../../types/builder-state.js").AnyBuilderState>(alias: Alias, subquery: import("../../query-builder.js").QueryBuilder<any, SubqueryState>): import("../../cte-scope.js").CteScope<import("../../types/builder-state.js").SchemaDefinition<unknown>, import("../../types/builder-state.js").RegisterCte<{}, Alias, SubqueryState["output"]>>;
|
|
8
|
+
<Alias extends string, Columns extends Record<string, import("../../../index.js").ColumnType>>(alias: Alias, sql: string | import("../../../index.js").RawCteBody, columns: Columns): import("../../cte-scope.js").CteScope<import("../../types/builder-state.js").SchemaDefinition<unknown>, import("../../types/builder-state.js").RegisterCte<{}, Alias, Columns>>;
|
|
9
|
+
(alias: string, sql: string | import("../../../index.js").RawCteBody): import("../../cte-scope.js").CteScope<import("../../types/builder-state.js").SchemaDefinition<unknown>, {}>;
|
|
10
|
+
};
|
|
11
|
+
withRecursiveCTE: {
|
|
12
|
+
<Alias extends string, Columns extends Record<string, import("../../../index.js").ColumnType>>(alias: Alias, body: string | import("../../../index.js").RawCteBody, columns: Columns): import("../../cte-scope.js").CteScope<import("../../types/builder-state.js").SchemaDefinition<unknown>, import("../../types/builder-state.js").RegisterCte<{}, Alias, Columns>>;
|
|
13
|
+
(alias: string, body: string | import("../../../index.js").RawCteBody): import("../../cte-scope.js").CteScope<import("../../types/builder-state.js").SchemaDefinition<unknown>, {}>;
|
|
14
|
+
};
|
|
6
15
|
rawQuery<TResult = any>(sql: string, params?: unknown[], options?: import("../../adapters/database-adapter.js").QueryExecutionOptions): Promise<TResult[]>;
|
|
7
16
|
close(): Promise<void>;
|
|
8
17
|
insert<TableName extends never>(tableName: TableName): import("../../insert-builder.js").InsertQB<import("../../types/builder-state.js").SchemaDefinition<unknown>, TableName>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/core/tests/integration/setup.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,SAAS,EAQV,MAAM,kDAAkD,CAAC;AA4B1D,eAAO,MAAM,wBAAwB
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/core/tests/integration/setup.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,SAAS,EAQV,MAAM,kDAAkD,CAAC;AA4B1D,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;EAyBpC,CAAC;AAGF,eAAO,MAAM,2BAA2B,yGAevC,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,OAAO,CAE/E,CAAC;AAGF,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,IAAI,CAO7D,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAC5B,oBAAgB,EAChB,sBAAoB,KACnB,OAAO,CAAC,IAAI,CAOd,CAAC;AAGF,eAAO,MAAM,uBAAuB,QAAa,OAAO,CAAC,IAAI,CAU5D,CAAC;AAGF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,OAAO,CAAC;QACnB,IAAI,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,MAAM,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;AAED,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC;AAKxE,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CAuBtD,CAAC"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { SelectQB } from '../query-builder.js';
|
|
1
|
+
import { QueryBuilder, SelectQB } from '../query-builder.js';
|
|
2
|
+
import type { DatabaseAdapter } from '../adapters/database-adapter.js';
|
|
3
|
+
import type { BuilderState } from '../types/builder-state.js';
|
|
2
4
|
import type { TableRecord } from '../../types/schema.js';
|
|
3
5
|
export type TestTableSchema = {
|
|
4
6
|
id: 'Int32';
|
|
@@ -39,6 +41,26 @@ export interface TestSchema {
|
|
|
39
41
|
users: UsersSchema;
|
|
40
42
|
}
|
|
41
43
|
export declare const TEST_SCHEMAS: TestSchema;
|
|
44
|
+
/** A client over the test schema, for the entry points that start from `db`. */
|
|
45
|
+
export declare function setupTestClient(): {
|
|
46
|
+
cache: import("../cache/controller.js").CacheController;
|
|
47
|
+
adapter: DatabaseAdapter;
|
|
48
|
+
dialect: import("../dialects/sql-dialect.js").SqlDialect;
|
|
49
|
+
withCTE: {
|
|
50
|
+
<Alias extends string, SubqueryState extends import("../types/builder-state.js").AnyBuilderState>(alias: Alias, subquery: QueryBuilder<any, SubqueryState>): import("../cte-scope.js").CteScope<TestSchema, import("../types/builder-state.js").RegisterCte<{}, Alias, SubqueryState["output"]>>;
|
|
51
|
+
<Alias extends string, Columns extends Record<string, import("../../types/schema.js").ColumnType>>(alias: Alias, sql: string | import("../../index.js").RawCteBody, columns: Columns): import("../cte-scope.js").CteScope<TestSchema, import("../types/builder-state.js").RegisterCte<{}, Alias, Columns>>;
|
|
52
|
+
(alias: string, sql: string | import("../../index.js").RawCteBody): import("../cte-scope.js").CteScope<TestSchema, {}>;
|
|
53
|
+
};
|
|
54
|
+
withRecursiveCTE: {
|
|
55
|
+
<Alias extends string, Columns extends Record<string, import("../../types/schema.js").ColumnType>>(alias: Alias, body: string | import("../../index.js").RawCteBody, columns: Columns): import("../cte-scope.js").CteScope<TestSchema, import("../types/builder-state.js").RegisterCte<{}, Alias, Columns>>;
|
|
56
|
+
(alias: string, body: string | import("../../index.js").RawCteBody): import("../cte-scope.js").CteScope<TestSchema, {}>;
|
|
57
|
+
};
|
|
58
|
+
rawQuery<TResult = any>(sql: string, params?: unknown[], options?: import("../adapters/database-adapter.js").QueryExecutionOptions): Promise<TResult[]>;
|
|
59
|
+
close(): Promise<void>;
|
|
60
|
+
insert<TableName extends keyof TestSchema>(tableName: TableName): import("../insert-builder.js").InsertQB<TestSchema, TableName>;
|
|
61
|
+
table<TableName extends keyof TestSchema>(tableName: TableName): SelectQB<TestSchema, TableName, TableRecord<TestSchema[TableName]>, TableName>;
|
|
62
|
+
from<SubqueryState extends BuilderState<TestSchema, string, any, keyof TestSchema, any, any, any>>(subquery: QueryBuilder<TestSchema, SubqueryState>): QueryBuilder<TestSchema, import("../types/builder-state.js").FromSubqueryState<TestSchema, SubqueryState>>;
|
|
63
|
+
};
|
|
42
64
|
export declare function setupUsersBuilder(): SelectQB<TestSchema, 'users', TableRecord<TestSchema['users']>, 'users'>;
|
|
43
65
|
export declare function setupTestBuilder(): SelectQB<TestSchema, 'test_table', TableRecord<TestSchema['test_table']>, 'test_table'>;
|
|
44
66
|
//# sourceMappingURL=test-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../../src/core/tests/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../../src/core/tests/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIzD,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IAEnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,qCAAqC,CAAC;IAChD,aAAa,EAAE,kBAAkB,CAAC;IAClC,UAAU,EAAE,+BAA+B,CAAC;IAC5C,aAAa,EAAE,4CAA4C,CAAC;IAC5D,aAAa,EAAE,yBAAyB,CAAC;IACzC,WAAW,EAAE,4BAA4B,CAAC;IAC1C,iBAAiB,EAAE,eAAe,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,QAAQ,CAAC;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IAEnB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,WAAW,EAAE,+CAA+C,CAAC;IAC7D,KAAK,EAAE,+BAA+B,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,eAAe,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,UAmC1B,CAAC;AA6BF,gFAAgF;AAChF,wBAAgB,eAAe;;;;;;;;;;;;;;;;;;EAK9B;AAED,wBAAgB,iBAAiB,IAAI,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAY5G;AAED,wBAAgB,gBAAgB,IAAI,QAAQ,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAY1H"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { QueryBuilder } from '../query-builder.js';
|
|
1
|
+
import { createQueryBuilder, QueryBuilder } from '../query-builder.js';
|
|
2
2
|
import { ClickHouseDialect } from '../dialects/clickhouse-dialect.js';
|
|
3
3
|
import { buildRuntimeContext, resolveCacheConfig } from '../cache/runtime-context.js';
|
|
4
4
|
import { substituteParameters } from '../utils.js';
|
|
@@ -49,6 +49,13 @@ const testAdapter = {
|
|
|
49
49
|
render: (sql, params = []) => substituteParameters(sql, params)
|
|
50
50
|
};
|
|
51
51
|
const testDialect = new ClickHouseDialect();
|
|
52
|
+
/** A client over the test schema, for the entry points that start from `db`. */
|
|
53
|
+
export function setupTestClient() {
|
|
54
|
+
return createQueryBuilder({
|
|
55
|
+
adapter: testAdapter,
|
|
56
|
+
dialect: testDialect,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
52
59
|
export function setupUsersBuilder() {
|
|
53
60
|
const state = {
|
|
54
61
|
schema: TEST_SCHEMAS,
|
|
@@ -57,7 +64,8 @@ export function setupUsersBuilder() {
|
|
|
57
64
|
baseTable: 'users',
|
|
58
65
|
base: TEST_SCHEMAS.users,
|
|
59
66
|
aliases: {},
|
|
60
|
-
scalars: {}
|
|
67
|
+
scalars: {},
|
|
68
|
+
ctes: {}
|
|
61
69
|
};
|
|
62
70
|
return new QueryBuilder('users', state, createTestRuntime(), testAdapter, testDialect);
|
|
63
71
|
}
|
|
@@ -69,7 +77,8 @@ export function setupTestBuilder() {
|
|
|
69
77
|
baseTable: 'test_table',
|
|
70
78
|
base: TEST_SCHEMAS.test_table,
|
|
71
79
|
aliases: {},
|
|
72
|
-
scalars: {}
|
|
80
|
+
scalars: {},
|
|
81
|
+
ctes: {}
|
|
73
82
|
};
|
|
74
83
|
return new QueryBuilder('test_table', state, createTestRuntime(), testAdapter, testDialect);
|
|
75
84
|
}
|
|
@@ -5,7 +5,22 @@ export type SchemaDefinition<Schema extends Record<string, any> = Record<string,
|
|
|
5
5
|
[K in keyof Schema]: Record<string, ColumnType>;
|
|
6
6
|
};
|
|
7
7
|
export declare const SUBQUERY_SOURCE_TABLE: "__hypequery_internal_subquery_source__";
|
|
8
|
-
export
|
|
8
|
+
export declare const CTE_SOURCE_TABLE: "__hypequery_internal_cte_source__";
|
|
9
|
+
/**
|
|
10
|
+
* Markers for sources that are not schema tables. They resolve to no columns,
|
|
11
|
+
* so they only ever gate the modifiers that need a real table.
|
|
12
|
+
*/
|
|
13
|
+
export type NonTableSource = typeof SUBQUERY_SOURCE_TABLE | typeof CTE_SOURCE_TABLE;
|
|
14
|
+
/**
|
|
15
|
+
* The columns a source exposes. Either schema-style `ColumnType` strings
|
|
16
|
+
* (`{ id: 'UUID' }`) or an already-resolved row type (`{ id: string }`), which
|
|
17
|
+
* is what a CTE built from another builder carries.
|
|
18
|
+
*/
|
|
19
|
+
export type ColumnShape = Record<string, unknown>;
|
|
20
|
+
export type CteShapes = Record<string, ColumnShape>;
|
|
21
|
+
/** A broad string alias must not shadow every schema table. */
|
|
22
|
+
export type RegisterCte<Ctes extends CteShapes, Alias extends string, Columns extends ColumnShape> = string extends Alias ? Ctes : Ctes & Record<Alias, Columns>;
|
|
23
|
+
export type BuilderState<Schema extends SchemaDefinition<Schema>, VisibleTables extends string, OutputRow, BaseTable extends keyof Schema, Aliases extends Partial<Record<string, keyof Schema>> = {}, Scalars extends Record<string, unknown> = {}, BaseShape extends Record<string, unknown> = Schema[BaseTable], Ctes extends CteShapes = {}> = {
|
|
9
24
|
schema: Schema;
|
|
10
25
|
tables: VisibleTables;
|
|
11
26
|
output: OutputRow;
|
|
@@ -13,18 +28,58 @@ export type BuilderState<Schema extends SchemaDefinition<Schema>, VisibleTables
|
|
|
13
28
|
base: BaseShape;
|
|
14
29
|
aliases: Aliases;
|
|
15
30
|
scalars: Scalars;
|
|
31
|
+
/**
|
|
32
|
+
* CTE aliases declared on this query, with the columns each exposes.
|
|
33
|
+
* Optional so hand-constructed states stay valid.
|
|
34
|
+
*/
|
|
35
|
+
ctes?: Ctes;
|
|
16
36
|
};
|
|
17
|
-
export type AnyBuilderState = BuilderState<any, any, any, any, any, any, any>;
|
|
18
|
-
|
|
19
|
-
|
|
37
|
+
export type AnyBuilderState = BuilderState<any, any, any, any, any, any, any, any>;
|
|
38
|
+
/**
|
|
39
|
+
* Resolves a column shape to the row type it produces. `ColumnType` strings are
|
|
40
|
+
* inferred; anything else is already a TypeScript type and passes through.
|
|
41
|
+
*/
|
|
42
|
+
export type RowFromShape<Shape> = Simplify<{
|
|
43
|
+
[K in keyof Shape]: Shape[K] extends ColumnType ? InferColumnType<Shape[K]> : Shape[K];
|
|
20
44
|
}>;
|
|
21
|
-
export type
|
|
22
|
-
|
|
45
|
+
export type BaseRow<State extends AnyBuilderState> = RowFromShape<State['base']>;
|
|
46
|
+
/** The CTE map, with the optionality of the state field resolved away. */
|
|
47
|
+
export type StateCtes<State extends AnyBuilderState> = NonNullable<State['ctes']>;
|
|
48
|
+
export type CteNames<State extends AnyBuilderState> = Extract<keyof StateCtes<State>, string>;
|
|
49
|
+
/** Tables a join may target: schema tables plus CTEs declared on this query. */
|
|
50
|
+
export type JoinableTable<State extends AnyBuilderState> = Extract<keyof State['schema'], string> | CteNames<State>;
|
|
51
|
+
export type WidenTables<State extends AnyBuilderState, Table extends keyof State['schema'] | CteNames<State>> = BuilderState<State['schema'], State['tables'] | (Table & string), State['output'], State['baseTable'], State['aliases'], State['scalars'], State['base'], StateCtes<State>>;
|
|
52
|
+
export type UpdateOutput<State extends AnyBuilderState, Output> = BuilderState<State['schema'], State['tables'], Output, State['baseTable'], State['aliases'], State['scalars'], State['base'], StateCtes<State>>;
|
|
23
53
|
export type InitialState<Schema extends SchemaDefinition<Schema>, Table extends keyof Schema> = BuilderState<Schema, Table & string, TableRecord<Schema[Table]>, Table, {}, {}>;
|
|
24
54
|
export type ExplicitSelectionState<State extends AnyBuilderState> = BaseRow<State> extends State['output'] ? State['output'] extends BaseRow<State> ? false : true : true;
|
|
25
55
|
export type AppendToOutput<State extends AnyBuilderState, Added> = UpdateOutput<State, ExplicitSelectionState<State> extends true ? Simplify<State['output'] & Added> : Simplify<Added>>;
|
|
26
|
-
export type AddAlias<State extends AnyBuilderState, Alias extends string, Table extends keyof State['schema']> = BuilderState<State['schema'], State['tables'] | Alias, State['output'], State['baseTable'], State['aliases'] & Record<Alias, Table>, State['scalars'], State['base']
|
|
27
|
-
export type AddScalar<State extends AnyBuilderState, Alias extends string, Value> = BuilderState<State['schema'], State['tables'], State['output'], State['baseTable'], State['aliases'], State['scalars'] & Record<Alias, Value>, State['base']
|
|
56
|
+
export type AddAlias<State extends AnyBuilderState, Alias extends string, Table extends keyof State['schema']> = BuilderState<State['schema'], State['tables'] | Alias, State['output'], State['baseTable'], State['aliases'] & Record<Alias, Table>, State['scalars'], State['base'], StateCtes<State>>;
|
|
57
|
+
export type AddScalar<State extends AnyBuilderState, Alias extends string, Value> = BuilderState<State['schema'], State['tables'], State['output'], State['baseTable'], State['aliases'], State['scalars'] & Record<Alias, Value>, State['base'], StateCtes<State>>;
|
|
58
|
+
/** Columns accepted for a join's right-hand side, qualified by table or CTE. */
|
|
59
|
+
export type JoinRightColumn<State extends AnyBuilderState, Table extends JoinableTable<State>> = `${Table}.${Extract<keyof ResolveTableSchema<State, Table>, string>}`;
|
|
60
|
+
/**
|
|
61
|
+
* Joining a CTE cannot take a table alias: aliases resolve through the schema,
|
|
62
|
+
* and a CTE has no schema entry to resolve to.
|
|
63
|
+
*/
|
|
64
|
+
export type JoinAliasArg<State extends AnyBuilderState, Table extends JoinableTable<State>, Alias> = Table extends CteNames<State> ? undefined : Alias;
|
|
65
|
+
export type JoinResultState<State extends AnyBuilderState, Table extends JoinableTable<State>, Alias> = Alias extends string ? AddAlias<WidenTables<State, Table>, Alias, Extract<Table, keyof State['schema']>> : WidenTables<State, Table>;
|
|
66
|
+
/**
|
|
67
|
+
* Registers a CTE alias and the columns it exposes. The alias only becomes
|
|
68
|
+
* selectable once the query joins it, which mirrors SQL scoping. A broad
|
|
69
|
+
* string alias remains untyped; registering it would shadow every schema table.
|
|
70
|
+
*/
|
|
71
|
+
export type AddCte<State extends AnyBuilderState, Alias extends string, Columns extends ColumnShape> = BuilderState<State['schema'], State['tables'], State['output'], State['baseTable'], State['aliases'], State['scalars'], State['base'], RegisterCte<StateCtes<State>, Alias, Columns>>;
|
|
72
|
+
/**
|
|
73
|
+
* Declares CTEs on a state that is otherwise unchanged — used when a query is
|
|
74
|
+
* started from a scope that already carries them.
|
|
75
|
+
*/
|
|
76
|
+
export type WithCtes<State extends AnyBuilderState, Ctes extends CteShapes> = BuilderState<State['schema'], State['tables'], State['output'], State['baseTable'], State['aliases'], State['scalars'], State['base'], StateCtes<State> & Ctes>;
|
|
77
|
+
/**
|
|
78
|
+
* The state of a query whose source is a declared CTE rather than a schema
|
|
79
|
+
* table. The CTE's declared columns stand in for a schema entry, so selects,
|
|
80
|
+
* filters, and the result row are typed from them.
|
|
81
|
+
*/
|
|
82
|
+
export type CteSourceState<Schema extends SchemaDefinition<Schema>, Alias extends string, Ctes extends CteShapes> = Alias extends keyof Ctes ? BuilderState<Schema, Alias | typeof CTE_SOURCE_TABLE, RowFromShape<Ctes[Alias]>, keyof Schema, {}, {}, Ctes[Alias], Ctes> : never;
|
|
28
83
|
export type FromSubqueryState<Schema extends SchemaDefinition<Schema>, SubqueryState extends BuilderState<Schema, string, any, keyof Schema, any, any, any>> = BuilderState<Schema, typeof SUBQUERY_SOURCE_TABLE, SubqueryState['output'], SubqueryState['baseTable'], {}, {}, SubqueryState['output']>;
|
|
29
84
|
export type InsertState<Schema extends SchemaDefinition<Schema>, Table extends keyof Schema, Row> = {
|
|
30
85
|
schema: Schema;
|
|
@@ -34,5 +89,9 @@ export type InsertState<Schema extends SchemaDefinition<Schema>, Table extends k
|
|
|
34
89
|
export type AnyInsertState = InsertState<any, any, any>;
|
|
35
90
|
export type InitialInsertState<Schema extends SchemaDefinition<Schema>, Table extends keyof Schema> = InsertState<Schema, Table, InsertRow<Schema[Table]>>;
|
|
36
91
|
export type UpdateInsertRow<State extends AnyInsertState, Row> = InsertState<State['schema'], State['table'], Row>;
|
|
37
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Resolves an identifier used in a query to the columns it exposes. CTEs are
|
|
94
|
+
* checked first because a CTE shadows a table of the same name in SQL.
|
|
95
|
+
*/
|
|
96
|
+
export type ResolveTableSchema<State extends AnyBuilderState, Table extends string> = Table extends keyof StateCtes<State> ? StateCtes<State>[Table] : Table extends keyof State['schema'] ? State['schema'][Table] : Table extends keyof State['aliases'] ? State['schema'][State['aliases'][Table]] : never;
|
|
38
97
|
//# sourceMappingURL=builder-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder-state.d.ts","sourceRoot":"","sources":["../../../src/core/types/builder-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;KACtF,CAAC,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;CAChD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAG,wCAAiD,CAAC;
|
|
1
|
+
{"version":3,"file":"builder-state.d.ts","sourceRoot":"","sources":["../../../src/core/types/builder-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,9 @@ import type { ColumnType, InferColumnType } from '../../types/schema.js';
|
|
|
3
3
|
import type { AnyBuilderState, BaseRow, ResolveTableSchema } from './builder-state.js';
|
|
4
4
|
import { Simplify, UnionToIntersection } from './type-helpers.js';
|
|
5
5
|
type TableIdentifiers<State extends AnyBuilderState> = State['tables'] & string;
|
|
6
|
-
type QualifiedColumnsFor<State extends AnyBuilderState, Table extends string> =
|
|
6
|
+
type QualifiedColumnsFor<State extends AnyBuilderState, Table extends string> = [
|
|
7
|
+
ResolveTableSchema<State, Table>
|
|
8
|
+
] extends [never] ? never : `${Table}.${Extract<keyof ResolveTableSchema<State, Table>, string>}`;
|
|
7
9
|
export type QualifiedColumnKeys<State extends AnyBuilderState> = {
|
|
8
10
|
[Table in TableIdentifiers<State>]: QualifiedColumnsFor<State, Table>;
|
|
9
11
|
}[TableIdentifiers<State>];
|
|
@@ -16,7 +18,7 @@ type AsKeyword = 'as' | 'AS' | 'As' | 'aS';
|
|
|
16
18
|
type AliasedColumnString<State extends AnyBuilderState> = `${StringSelectableColumn<State>} ${AsKeyword} ${string}`;
|
|
17
19
|
export type SelectableItem<State extends AnyBuilderState> = SelectableColumn<State> | AliasedColumnString<State> | AliasedExpression<any, string> | SqlExpression<any>;
|
|
18
20
|
export type ColumnSelectionKey<P> = P extends `${string}.${infer C}` ? C : P;
|
|
19
|
-
type QualifiedColumnValue<State extends AnyBuilderState, P> = P extends `${infer Table}.${infer Column}` ? ResolveTableSchema<State, Table> extends
|
|
21
|
+
type QualifiedColumnValue<State extends AnyBuilderState, P> = P extends `${infer Table}.${infer Column}` ? [ResolveTableSchema<State, Table>] extends [never] ? never : Column extends keyof ResolveTableSchema<State, Table> ? ResolveTableSchema<State, Table>[Column] extends ColumnType ? InferColumnType<ResolveTableSchema<State, Table>[Column]> : ResolveTableSchema<State, Table>[Column] : never : never;
|
|
20
22
|
export type ColumnSelectionValue<State extends AnyBuilderState, P> = P extends OutputColumnKeys<State> ? State['output'][P] : P extends ScalarColumnKeys<State> ? State['scalars'][P] : P extends BaseColumnKeys<State> ? BaseRow<State>[P] : QualifiedColumnValue<State, P>;
|
|
21
23
|
export type ArraySelectableColumn<State extends AnyBuilderState> = {
|
|
22
24
|
[P in SelectableColumn<State>]: ColumnSelectionValue<State, P> extends readonly unknown[] | null ? P : never;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select-types.d.ts","sourceRoot":"","sources":["../../../src/core/types/select-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAElE,KAAK,gBAAgB,CAAC,KAAK,SAAS,eAAe,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;AAEhF,KAAK,mBAAmB,CAAC,KAAK,SAAS,eAAe,EAAE,KAAK,SAAS,MAAM,IAC1E,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"select-types.d.ts","sourceRoot":"","sources":["../../../src/core/types/select-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep compound values bound as strings for CAST. The adapter escapes the
|
|
3
|
+
* resulting text again; tuple and map delimiters come only from the type.
|
|
4
|
+
*/
|
|
5
|
+
export declare function serializeCompoundParameter(value: unknown, type: string): unknown;
|
|
6
|
+
//# sourceMappingURL=compound-parameter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compound-parameter.d.ts","sourceRoot":"","sources":["../../../src/core/utils/compound-parameter.ts"],"names":[],"mappings":"AAkDA;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQhF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { escapeValue } from '../utils.js';
|
|
2
|
+
import { parseParameterType, parseTupleField } from './parameter-type.js';
|
|
3
|
+
import { isPlainRecord } from './record-guards.js';
|
|
4
|
+
function invalidValue(type) {
|
|
5
|
+
throw new Error(`Cannot serialize parameter value as ${type}. Use a matching JavaScript value or pass ClickHouse text for the whole parameter.`);
|
|
6
|
+
}
|
|
7
|
+
/** Serialize one value in ClickHouse text format, following its declared type. */
|
|
8
|
+
function serializeValue(value, type) {
|
|
9
|
+
const { name, args } = parseParameterType(type);
|
|
10
|
+
if ((name === 'Nullable' || name === 'LowCardinality') && args.length === 1) {
|
|
11
|
+
if (name === 'Nullable' && value === null)
|
|
12
|
+
return 'NULL';
|
|
13
|
+
return serializeValue(value, args[0]);
|
|
14
|
+
}
|
|
15
|
+
if (value === null || value === undefined)
|
|
16
|
+
return invalidValue(type);
|
|
17
|
+
// JSON is read as a quoted string inside compound text, unlike the tuple
|
|
18
|
+
// and map syntax around it. Reuse the existing JSON escaping path.
|
|
19
|
+
if (name === 'JSON')
|
|
20
|
+
return escapeValue(value);
|
|
21
|
+
if (name === 'Array' && args.length === 1) {
|
|
22
|
+
if (!Array.isArray(value))
|
|
23
|
+
return invalidValue(type);
|
|
24
|
+
return `[${Array.from(value, item => serializeValue(item, args[0])).join(',')}]`;
|
|
25
|
+
}
|
|
26
|
+
if (name === 'Tuple') {
|
|
27
|
+
const fields = args.map(parseTupleField);
|
|
28
|
+
let items;
|
|
29
|
+
if (Array.isArray(value) && value.length === fields.length) {
|
|
30
|
+
items = value;
|
|
31
|
+
}
|
|
32
|
+
else if (isPlainRecord(value) && fields.every(field => field.name !== undefined && Object.hasOwn(value, field.name))) {
|
|
33
|
+
items = fields.map(field => value[field.name]);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
return invalidValue(type);
|
|
37
|
+
}
|
|
38
|
+
return `(${fields.map((field, i) => serializeValue(items[i], field.type)).join(',')})`;
|
|
39
|
+
}
|
|
40
|
+
if (name === 'Map' && args.length === 2) {
|
|
41
|
+
const entries = value instanceof Map ? [...value.entries()] : isPlainRecord(value) ? Object.entries(value) : undefined;
|
|
42
|
+
if (!entries)
|
|
43
|
+
return invalidValue(type);
|
|
44
|
+
return `{${entries.map(([key, item]) => `${serializeValue(key, args[0])}:${serializeValue(item, args[1])}`).join(',')}}`;
|
|
45
|
+
}
|
|
46
|
+
if (typeof value === 'object' && !(value instanceof Date))
|
|
47
|
+
return invalidValue(type);
|
|
48
|
+
// UInt64 values and object-map keys may be strings; text readers for numeric
|
|
49
|
+
// types expect unquoted numbers. Validate before including them in the text.
|
|
50
|
+
if (typeof value === 'string' && /^(?:U?Int\d+|Float\d+|Decimal\d*)$/.test(name)) {
|
|
51
|
+
if (!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(value))
|
|
52
|
+
return invalidValue(type);
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
return escapeValue(value);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Keep compound values bound as strings for CAST. The adapter escapes the
|
|
59
|
+
* resulting text again; tuple and map delimiters come only from the type.
|
|
60
|
+
*/
|
|
61
|
+
export function serializeCompoundParameter(value, type) {
|
|
62
|
+
if (Array.isArray(value) || value instanceof Map || isPlainRecord(value)) {
|
|
63
|
+
// A top-level JSON value is already handled by the adapter's normal
|
|
64
|
+
// JSON.stringify + SQL escaping path. Quoting it here would double-wrap it.
|
|
65
|
+
if (parseParameterType(type).name === 'JSON')
|
|
66
|
+
return value;
|
|
67
|
+
return serializeValue(value, type);
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DatabaseAdapter } from '../adapters/database-adapter.js';
|
|
2
|
+
import type { CteNode } from '../../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Renders a CTE body to a standalone string with its values inlined, following
|
|
5
|
+
* the same path `toSQL()` uses so adapter-specific rendering is preserved.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renderCteBody(body: string, parameters: readonly unknown[], adapter: DatabaseAdapter): string;
|
|
8
|
+
/**
|
|
9
|
+
* The compilable form of a CTE entry. Structured entries keep their parameters
|
|
10
|
+
* bound; entries that predate the structured fields fall back to the rendered
|
|
11
|
+
* `expression`, which has its values already inlined.
|
|
12
|
+
*/
|
|
13
|
+
export declare function cteFragment(node: CteNode): {
|
|
14
|
+
sql: string;
|
|
15
|
+
parameters: readonly unknown[];
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=cte-fragments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cte-fragments.d.ts","sourceRoot":"","sources":["../../../src/core/utils/cte-fragments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAGpD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,SAAS,OAAO,EAAE,EAC9B,OAAO,EAAE,eAAe,GACvB,MAAM,CAIR;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,CAI1F"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { substituteParameters } from '../utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Renders a CTE body to a standalone string with its values inlined, following
|
|
4
|
+
* the same path `toSQL()` uses so adapter-specific rendering is preserved.
|
|
5
|
+
*/
|
|
6
|
+
export function renderCteBody(body, parameters, adapter) {
|
|
7
|
+
return adapter.render
|
|
8
|
+
? adapter.render(body, [...parameters])
|
|
9
|
+
: substituteParameters(body, parameters);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The compilable form of a CTE entry. Structured entries keep their parameters
|
|
13
|
+
* bound; entries that predate the structured fields fall back to the rendered
|
|
14
|
+
* `expression`, which has its values already inlined.
|
|
15
|
+
*/
|
|
16
|
+
export function cteFragment(node) {
|
|
17
|
+
return node.name !== undefined && node.body !== undefined
|
|
18
|
+
? { sql: `${node.name} AS (${node.body})`, parameters: node.parameters ?? [] }
|
|
19
|
+
: { sql: node.expression, parameters: [] };
|
|
20
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BuilderState, CteShapes, SchemaDefinition } from '../types/builder-state.js';
|
|
2
|
+
/** Concrete runtime metadata; result columns are carried by the public overloads. */
|
|
3
|
+
export type CteScopeRuntimeState<Schema extends SchemaDefinition<Schema>> = BuilderState<Schema, string, Record<string, unknown>, keyof Schema, {}, {}, Record<string, unknown>, CteShapes>;
|
|
4
|
+
export declare function createCteScopeState<Schema extends SchemaDefinition<Schema>>(name: string): CteScopeRuntimeState<Schema>;
|
|
5
|
+
//# sourceMappingURL=cte-scope-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cte-scope-state.d.ts","sourceRoot":"","sources":["../../../src/core/utils/cte-scope-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE3F,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,CAAC,MAAM,SAAS,gBAAgB,CAAC,MAAM,CAAC,IAAI,YAAY,CACtF,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAClG,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,MAAM,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACzE,IAAI,EAAE,MAAM,GACX,oBAAoB,CAAC,MAAM,CAAC,CAe9B"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function createCteScopeState(name) {
|
|
2
|
+
return {
|
|
3
|
+
// Schema definitions are type-only in createQueryBuilder, so no runtime
|
|
4
|
+
// schema is available here either.
|
|
5
|
+
schema: {},
|
|
6
|
+
tables: name,
|
|
7
|
+
// BuilderState currently constrains baseTable to schema keys, even though
|
|
8
|
+
// CTE names also serve as base sources. Keep that boundary explicit here.
|
|
9
|
+
baseTable: name,
|
|
10
|
+
base: {},
|
|
11
|
+
output: {},
|
|
12
|
+
aliases: {},
|
|
13
|
+
scalars: {},
|
|
14
|
+
ctes: {},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface NamedParameterBinding {
|
|
2
|
+
/**
|
|
3
|
+
* The SQL with every named placeholder rewritten to a positional `?`, kept
|
|
4
|
+
* inside a `CAST` to the type the placeholder declared.
|
|
5
|
+
*/
|
|
6
|
+
sql: string;
|
|
7
|
+
/** The values behind those placeholders, in the order they appear. */
|
|
8
|
+
parameters: unknown[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Rewrites ClickHouse-style `{name:Type}` placeholders to the positional `?`
|
|
12
|
+
* markers the builder binds against, pairing each with its value.
|
|
13
|
+
*
|
|
14
|
+
* TODO: Remove this client-side rewrite and its CAST/compound serialization
|
|
15
|
+
* once native server-side query_params binding replaces positional parameters.
|
|
16
|
+
* The public {name:Type} placeholder API can stay unchanged.
|
|
17
|
+
*
|
|
18
|
+
* Each marker is wrapped in a `CAST` to the declared type, which is what the
|
|
19
|
+
* server's own `{name:Type}` substitution does. Without it the value arrives as
|
|
20
|
+
* a String and any expression that depends on the real type fails to compile.
|
|
21
|
+
*
|
|
22
|
+
* Placeholders inside string literals, quoted identifiers, heredocs, and
|
|
23
|
+
* comments are data and are left alone, so a body can talk about braces without
|
|
24
|
+
* having them bound.
|
|
25
|
+
*
|
|
26
|
+
* Values that no placeholder references are ignored: a caller may pass one
|
|
27
|
+
* context object to several fragments.
|
|
28
|
+
*/
|
|
29
|
+
export declare function bindNamedParameters(sql: string, values?: Record<string, unknown>, context?: string): NamedParameterBinding;
|
|
30
|
+
//# sourceMappingURL=named-parameters.d.ts.map
|