drizzle-databend 0.1.11 → 0.1.12

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.
Files changed (107) hide show
  1. package/dist/columns.d.ts +25 -37
  2. package/dist/databend-core/alias.d.ts +1 -0
  3. package/dist/databend-core/columns/all.d.ts +35 -0
  4. package/dist/databend-core/columns/array.d.ts +16 -0
  5. package/dist/databend-core/columns/bigint.d.ts +24 -0
  6. package/dist/databend-core/columns/binary.d.ts +13 -0
  7. package/dist/databend-core/columns/bitmap.d.ts +13 -0
  8. package/dist/databend-core/columns/boolean.d.ts +13 -0
  9. package/dist/databend-core/columns/common.d.ts +45 -0
  10. package/dist/databend-core/columns/custom.d.ts +33 -0
  11. package/dist/databend-core/columns/date.d.ts +16 -0
  12. package/dist/databend-core/columns/decimal.d.ts +19 -0
  13. package/dist/databend-core/columns/double.d.ts +14 -0
  14. package/dist/databend-core/columns/float.d.ts +14 -0
  15. package/dist/databend-core/columns/index.d.ts +21 -0
  16. package/dist/databend-core/columns/integer.d.ts +13 -0
  17. package/dist/databend-core/columns/map.d.ts +17 -0
  18. package/dist/databend-core/columns/smallint.d.ts +13 -0
  19. package/dist/databend-core/columns/text.d.ts +13 -0
  20. package/dist/databend-core/columns/timestamp.d.ts +16 -0
  21. package/dist/databend-core/columns/tinyint.d.ts +13 -0
  22. package/dist/databend-core/columns/tuple.d.ts +16 -0
  23. package/dist/databend-core/columns/varchar.d.ts +17 -0
  24. package/dist/databend-core/columns/variant.d.ts +15 -0
  25. package/dist/databend-core/db.d.ts +31 -0
  26. package/dist/databend-core/dialect.d.ts +29 -0
  27. package/dist/databend-core/index.d.ts +18 -0
  28. package/dist/databend-core/indexes.d.ts +24 -0
  29. package/dist/databend-core/primary-keys.d.ts +20 -0
  30. package/dist/databend-core/query-builders/count.d.ts +18 -0
  31. package/dist/databend-core/query-builders/delete.d.ts +18 -0
  32. package/dist/databend-core/query-builders/index.d.ts +5 -0
  33. package/dist/databend-core/query-builders/insert.d.ts +27 -0
  34. package/dist/databend-core/query-builders/query-builder.d.ts +19 -0
  35. package/dist/databend-core/query-builders/query.d.ts +37 -0
  36. package/dist/databend-core/query-builders/raw.d.ts +17 -0
  37. package/dist/databend-core/query-builders/select.d.ts +65 -0
  38. package/dist/databend-core/query-builders/update.d.ts +27 -0
  39. package/dist/databend-core/schema.d.ts +12 -0
  40. package/dist/databend-core/session.d.ts +28 -0
  41. package/dist/databend-core/subquery.d.ts +1 -0
  42. package/dist/databend-core/table.d.ts +12 -0
  43. package/dist/databend-core/utils.d.ts +7 -0
  44. package/dist/databend-core/view-base.d.ts +5 -0
  45. package/dist/databend-core/view-common.d.ts +1 -0
  46. package/dist/databend-core/view.d.ts +30 -0
  47. package/dist/dialect.d.ts +1 -10
  48. package/dist/driver.d.ts +4 -4
  49. package/dist/index.d.ts +10 -0
  50. package/dist/index.mjs +2584 -205
  51. package/dist/session.d.ts +22 -19
  52. package/dist/sql/result-mapper.d.ts +2 -3
  53. package/dist/sql/selection.d.ts +2 -1
  54. package/package.json +4 -4
  55. package/src/columns.ts +8 -7
  56. package/src/databend-core/alias.ts +5 -0
  57. package/src/databend-core/columns/all.ts +38 -0
  58. package/src/databend-core/columns/array.ts +46 -0
  59. package/src/databend-core/columns/bigint.ts +52 -0
  60. package/src/databend-core/columns/binary.ts +27 -0
  61. package/src/databend-core/columns/bitmap.ts +27 -0
  62. package/src/databend-core/columns/boolean.ts +27 -0
  63. package/src/databend-core/columns/common.ts +97 -0
  64. package/src/databend-core/columns/custom.ts +86 -0
  65. package/src/databend-core/columns/date.ts +49 -0
  66. package/src/databend-core/columns/decimal.ts +44 -0
  67. package/src/databend-core/columns/double.ts +34 -0
  68. package/src/databend-core/columns/float.ts +31 -0
  69. package/src/databend-core/columns/index.ts +21 -0
  70. package/src/databend-core/columns/integer.ts +27 -0
  71. package/src/databend-core/columns/map.ts +49 -0
  72. package/src/databend-core/columns/smallint.ts +27 -0
  73. package/src/databend-core/columns/text.ts +27 -0
  74. package/src/databend-core/columns/timestamp.ts +51 -0
  75. package/src/databend-core/columns/tinyint.ts +27 -0
  76. package/src/databend-core/columns/tuple.ts +46 -0
  77. package/src/databend-core/columns/varchar.ts +35 -0
  78. package/src/databend-core/columns/variant.ts +45 -0
  79. package/src/databend-core/db.ts +153 -0
  80. package/src/databend-core/dialect.ts +724 -0
  81. package/src/databend-core/index.ts +18 -0
  82. package/src/databend-core/indexes.ts +67 -0
  83. package/src/databend-core/primary-keys.ts +48 -0
  84. package/src/databend-core/query-builders/count.ts +47 -0
  85. package/src/databend-core/query-builders/delete.ts +56 -0
  86. package/src/databend-core/query-builders/index.ts +5 -0
  87. package/src/databend-core/query-builders/insert.ts +105 -0
  88. package/src/databend-core/query-builders/query-builder.ts +77 -0
  89. package/src/databend-core/query-builders/query.ts +124 -0
  90. package/src/databend-core/query-builders/raw.ts +37 -0
  91. package/src/databend-core/query-builders/select.ts +377 -0
  92. package/src/databend-core/query-builders/update.ts +82 -0
  93. package/src/databend-core/schema.ts +29 -0
  94. package/src/databend-core/session.ts +85 -0
  95. package/src/databend-core/subquery.ts +1 -0
  96. package/src/databend-core/table.ts +67 -0
  97. package/src/databend-core/utils.ts +34 -0
  98. package/src/databend-core/view-base.ts +6 -0
  99. package/src/databend-core/view-common.ts +1 -0
  100. package/src/databend-core/view.ts +127 -0
  101. package/src/dialect.ts +3 -119
  102. package/src/driver.ts +6 -7
  103. package/src/index.ts +27 -0
  104. package/src/migrator.ts +1 -2
  105. package/src/session.ts +42 -57
  106. package/src/sql/result-mapper.ts +12 -54
  107. package/src/sql/selection.ts +2 -1
@@ -0,0 +1,127 @@
1
+ import { entityKind, is } from 'drizzle-orm/entity';
2
+ import { SelectionProxyHandler } from 'drizzle-orm/selection-proxy';
3
+ import { getTableColumns } from 'drizzle-orm/utils';
4
+ import { QueryBuilder } from './query-builders/query-builder.ts';
5
+ import { databendTable } from './table.ts';
6
+ import { DatabendViewBase } from './view-base.ts';
7
+ import { DatabendViewConfig } from './view-common.ts';
8
+
9
+ class DefaultViewBuilderCore {
10
+ static readonly [entityKind]: string = 'DatabendDefaultViewBuilderCore';
11
+ config: any = {};
12
+
13
+ constructor(protected name: string, protected schema?: string) {}
14
+
15
+ with(config: any) {
16
+ this.config.with = config;
17
+ return this;
18
+ }
19
+ }
20
+
21
+ export class ViewBuilder extends DefaultViewBuilderCore {
22
+ static override readonly [entityKind]: string = 'DatabendViewBuilder';
23
+
24
+ as(qb: any) {
25
+ if (typeof qb === 'function') {
26
+ qb = qb(new QueryBuilder());
27
+ }
28
+ const selectionProxy = new SelectionProxyHandler({
29
+ alias: this.name,
30
+ sqlBehavior: 'error',
31
+ sqlAliasedBehavior: 'alias',
32
+ replaceOriginalName: true,
33
+ });
34
+ const aliasedSelection = new Proxy(qb.getSelectedFields(), selectionProxy);
35
+ return new Proxy(
36
+ new DatabendView({
37
+ databendConfig: this.config,
38
+ config: {
39
+ name: this.name,
40
+ schema: this.schema,
41
+ selectedFields: aliasedSelection,
42
+ query: qb.getSQL().inlineParams(),
43
+ },
44
+ }),
45
+ selectionProxy
46
+ );
47
+ }
48
+ }
49
+
50
+ export class ManualViewBuilder extends DefaultViewBuilderCore {
51
+ static override readonly [entityKind]: string = 'DatabendManualViewBuilder';
52
+ columns: any;
53
+
54
+ constructor(name: string, columns: any, schema?: string) {
55
+ super(name, schema);
56
+ this.columns = getTableColumns(databendTable(name, columns));
57
+ }
58
+
59
+ existing() {
60
+ return new Proxy(
61
+ new DatabendView({
62
+ databendConfig: undefined,
63
+ config: {
64
+ name: this.name,
65
+ schema: this.schema,
66
+ selectedFields: this.columns,
67
+ query: undefined,
68
+ },
69
+ }),
70
+ new SelectionProxyHandler({
71
+ alias: this.name,
72
+ sqlBehavior: 'error',
73
+ sqlAliasedBehavior: 'alias',
74
+ replaceOriginalName: true,
75
+ })
76
+ );
77
+ }
78
+
79
+ as(query: any) {
80
+ return new Proxy(
81
+ new DatabendView({
82
+ databendConfig: this.config,
83
+ config: {
84
+ name: this.name,
85
+ schema: this.schema,
86
+ selectedFields: this.columns,
87
+ query: query.inlineParams(),
88
+ },
89
+ }),
90
+ new SelectionProxyHandler({
91
+ alias: this.name,
92
+ sqlBehavior: 'error',
93
+ sqlAliasedBehavior: 'alias',
94
+ replaceOriginalName: true,
95
+ })
96
+ );
97
+ }
98
+ }
99
+
100
+ export class DatabendView extends DatabendViewBase {
101
+ static override readonly [entityKind]: string = 'DatabendView';
102
+ [DatabendViewConfig]: any;
103
+
104
+ constructor({ databendConfig, config }: any) {
105
+ super(config);
106
+ if (databendConfig) {
107
+ this[DatabendViewConfig] = {
108
+ with: databendConfig.with,
109
+ };
110
+ }
111
+ }
112
+ }
113
+
114
+ function databendViewWithSchema(name: string, selection?: any, schema?: string) {
115
+ if (selection) {
116
+ return new ManualViewBuilder(name, selection, schema);
117
+ }
118
+ return new ViewBuilder(name, schema);
119
+ }
120
+
121
+ export function databendView(name: string, columns?: any) {
122
+ return databendViewWithSchema(name, columns, undefined);
123
+ }
124
+
125
+ export function isDatabendView(obj: unknown): obj is DatabendView {
126
+ return is(obj, DatabendView);
127
+ }
package/src/dialect.ts CHANGED
@@ -1,119 +1,3 @@
1
- import {
2
- type DriverValueEncoder,
3
- type QueryTypingsValue,
4
- sql,
5
- } from 'drizzle-orm';
6
- import { entityKind, is } from 'drizzle-orm/entity';
7
- import type { MigrationConfig, MigrationMeta } from 'drizzle-orm/migrator';
8
- import {
9
- PgBigInt53,
10
- PgBigInt64,
11
- PgDate,
12
- PgDateString,
13
- PgDialect,
14
- PgDoublePrecision,
15
- PgInteger,
16
- PgNumeric,
17
- PgReal,
18
- type PgSession,
19
- PgSmallInt,
20
- PgTime,
21
- PgTimestamp,
22
- PgTimestampString,
23
- PgUUID,
24
- } from 'drizzle-orm/pg-core';
25
-
26
- export class DatabendDialect extends PgDialect {
27
- static readonly [entityKind]: string = 'DatabendPgDialect';
28
-
29
- // Databend does not support savepoints
30
- areSavepointsUnsupported(): boolean {
31
- return true;
32
- }
33
-
34
- override async migrate(
35
- migrations: MigrationMeta[],
36
- session: PgSession,
37
- config: MigrationConfig | string
38
- ): Promise<void> {
39
- const migrationConfig: MigrationConfig =
40
- typeof config === 'string' ? { migrationsFolder: config } : config;
41
-
42
- const migrationsSchema = migrationConfig.migrationsSchema ?? 'default';
43
- const migrationsTable =
44
- migrationConfig.migrationsTable ?? '__drizzle_migrations';
45
-
46
- // Databend has no sequences. Use explicit ID via COALESCE(MAX(id), 0) + 1.
47
- const migrationTableCreate = sql`
48
- CREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsSchema)}.${sql.identifier(
49
- migrationsTable
50
- )} (
51
- id INT NOT NULL,
52
- hash VARCHAR NOT NULL,
53
- created_at BIGINT
54
- )
55
- `;
56
-
57
- await session.execute(migrationTableCreate);
58
-
59
- const dbMigrations = await session.all<{
60
- id: number;
61
- hash: string;
62
- created_at: string;
63
- }>(
64
- sql`SELECT id, hash, created_at FROM ${sql.identifier(
65
- migrationsSchema
66
- )}.${sql.identifier(migrationsTable)} ORDER BY created_at DESC LIMIT 1`
67
- );
68
-
69
- const lastDbMigration = dbMigrations[0];
70
-
71
- await session.transaction(async (tx) => {
72
- for await (const migration of migrations) {
73
- if (
74
- !lastDbMigration ||
75
- Number(lastDbMigration.created_at) < migration.folderMillis
76
- ) {
77
- for (const stmt of migration.sql) {
78
- await tx.execute(sql.raw(stmt));
79
- }
80
-
81
- await tx.execute(
82
- sql`INSERT INTO ${sql.identifier(
83
- migrationsSchema
84
- )}.${sql.identifier(migrationsTable)} (id, hash, created_at)
85
- VALUES (
86
- (SELECT COALESCE(MAX(id), 0) + 1 FROM ${sql.identifier(
87
- migrationsSchema
88
- )}.${sql.identifier(migrationsTable)}),
89
- ${migration.hash},
90
- ${migration.folderMillis}
91
- )`
92
- );
93
- }
94
- }
95
- });
96
- }
97
-
98
- override prepareTyping(
99
- encoder: DriverValueEncoder<unknown, unknown>
100
- ): QueryTypingsValue {
101
- if (
102
- is(encoder, PgNumeric) || is(encoder, PgInteger) || is(encoder, PgSmallInt)
103
- || is(encoder, PgReal) || is(encoder, PgDoublePrecision)
104
- || is(encoder, PgBigInt53) || is(encoder, PgBigInt64)
105
- ) {
106
- return 'decimal';
107
- } else if (is(encoder, PgTime)) {
108
- return 'time';
109
- } else if (is(encoder, PgTimestamp) || is(encoder, PgTimestampString)) {
110
- return 'timestamp';
111
- } else if (is(encoder, PgDate) || is(encoder, PgDateString)) {
112
- return 'date';
113
- } else if (is(encoder, PgUUID)) {
114
- return 'uuid';
115
- } else {
116
- return 'none';
117
- }
118
- }
119
- }
1
+ // Re-export DatabendDialect from the core module.
2
+ // All dialect logic now lives in databend-core/dialect.ts.
3
+ export { DatabendDialect } from './databend-core/dialect.ts';
package/src/driver.ts CHANGED
@@ -3,7 +3,6 @@ import { Client } from 'databend-driver';
3
3
  import { entityKind } from 'drizzle-orm/entity';
4
4
  import type { Logger } from 'drizzle-orm/logger';
5
5
  import { DefaultLogger } from 'drizzle-orm/logger';
6
- import { PgDatabase } from 'drizzle-orm/pg-core/db';
7
6
  import {
8
7
  createTableRelationsHelpers,
9
8
  type ExtractTablesWithRelations,
@@ -13,14 +12,14 @@ import {
13
12
  } from 'drizzle-orm/relations';
14
13
  import type { DrizzleConfig } from 'drizzle-orm/utils';
15
14
  import { closeClientConnection, isPool } from './client.ts';
16
- import { DatabendDialect } from './dialect.ts';
15
+ import { DatabendDatabase as DatabendDatabaseBase } from './databend-core/db.ts';
16
+ import { DatabendDialect } from './databend-core/dialect.ts';
17
17
  import {
18
18
  createDatabendConnectionPool,
19
19
  type DatabendPoolConfig,
20
20
  } from './pool.ts';
21
21
  import type {
22
22
  DatabendClientLike,
23
- DatabendQueryResultHKT,
24
23
  DatabendTransaction,
25
24
  } from './session.ts';
26
25
  import { DatabendSession } from './session.ts';
@@ -230,8 +229,8 @@ export class DatabendDatabase<
230
229
  TFullSchema extends Record<string, unknown> = Record<string, never>,
231
230
  TSchema extends TablesRelationalConfig =
232
231
  ExtractTablesWithRelations<TFullSchema>,
233
- > extends PgDatabase<DatabendQueryResultHKT, TFullSchema, TSchema> {
234
- static readonly [entityKind]: string = 'DatabendDatabase';
232
+ > extends DatabendDatabaseBase {
233
+ static override readonly [entityKind]: string = 'DatabendDatabase';
235
234
 
236
235
  /** The underlying connection or pool */
237
236
  readonly $client: DatabendClientLike;
@@ -240,8 +239,8 @@ export class DatabendDatabase<
240
239
  readonly $databendClient?: Client;
241
240
 
242
241
  constructor(
243
- readonly dialect: DatabendDialect,
244
- readonly session: DatabendSession<TFullSchema, TSchema>,
242
+ override readonly dialect: DatabendDialect,
243
+ override readonly session: DatabendSession<TFullSchema, TSchema>,
245
244
  schema: RelationalSchemaConfig<TSchema> | undefined,
246
245
  client: DatabendClientLike,
247
246
  databendClient?: Client
package/src/index.ts CHANGED
@@ -1,5 +1,32 @@
1
1
  export * from './client.ts';
2
2
  export * from './columns.ts';
3
+ export { alias } from './databend-core/alias.ts';
4
+ export { DatabendColumn, DatabendColumnBuilder } from './databend-core/columns/common.ts';
5
+ export {
6
+ bigint,
7
+ binary,
8
+ bitmap,
9
+ boolean,
10
+ date,
11
+ decimal,
12
+ doublePrecision,
13
+ float,
14
+ integer,
15
+ real,
16
+ smallint,
17
+ text,
18
+ timestamp,
19
+ tinyint,
20
+ varchar,
21
+ variant,
22
+ } from './databend-core/columns/index.ts';
23
+ export { DatabendDialect } from './databend-core/dialect.ts';
24
+ export { index, uniqueIndex } from './databend-core/indexes.ts';
25
+ export { primaryKey } from './databend-core/primary-keys.ts';
26
+ export { databendSchema } from './databend-core/schema.ts';
27
+ export { DatabendTable, databendTable, databendTableCreator } from './databend-core/table.ts';
28
+ export { getTableConfig } from './databend-core/utils.ts';
29
+ export { databendView } from './databend-core/view.ts';
3
30
  export * from './driver.ts';
4
31
  export * from './migrator.ts';
5
32
  export * from './pool.ts';
package/src/migrator.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import type { MigrationConfig } from 'drizzle-orm/migrator';
2
2
  import { readMigrationFiles } from 'drizzle-orm/migrator';
3
- import type { PgSession } from 'drizzle-orm/pg-core/session';
4
3
  import type { DatabendDatabase } from './driver.ts';
5
4
 
6
5
  export type DatabendMigrationConfig = MigrationConfig | string;
@@ -16,7 +15,7 @@ export async function migrate<TSchema extends Record<string, unknown>>(
16
15
 
17
16
  await db.dialect.migrate(
18
17
  migrations,
19
- db.session as unknown as PgSession,
18
+ db.session,
20
19
  migrationConfig
21
20
  );
22
21
  }
package/src/session.ts CHANGED
@@ -3,14 +3,6 @@ import { entityKind } from 'drizzle-orm/entity';
3
3
  import { TransactionRollbackError } from 'drizzle-orm/errors';
4
4
  import type { Logger } from 'drizzle-orm/logger';
5
5
  import { NoopLogger } from 'drizzle-orm/logger';
6
- import { PgTransaction } from 'drizzle-orm/pg-core';
7
- import type { SelectedFieldsOrdered } from 'drizzle-orm/pg-core/query-builders/select.types';
8
- import type {
9
- PgQueryResultHKT,
10
- PgTransactionConfig,
11
- PreparedQueryConfig,
12
- } from 'drizzle-orm/pg-core/session';
13
- import { PgPreparedQuery, PgSession } from 'drizzle-orm/pg-core/session';
14
6
  import type {
15
7
  RelationalSchemaConfig,
16
8
  TablesRelationalConfig,
@@ -27,25 +19,33 @@ import {
27
19
  executeOnClient,
28
20
  isPool,
29
21
  } from './client.ts';
30
- import type { DatabendDialect } from './dialect.ts';
22
+ import type { DatabendDialect } from './databend-core/dialect.ts';
23
+ import {
24
+ DatabendPreparedQuery as DatabendPreparedQueryBase,
25
+ DatabendSession as DatabendSessionBase,
26
+ DatabendTransaction as DatabendTransactionBase,
27
+ } from './databend-core/session.ts';
31
28
  import { mapResultRow } from './sql/result-mapper.ts';
32
29
 
33
30
  export type { DatabendClientLike, RowData } from './client.ts';
34
31
 
35
- export class DatabendPreparedQuery<
36
- T extends PreparedQueryConfig,
37
- > extends PgPreparedQuery<T> {
38
- static readonly [entityKind]: string = 'DatabendPreparedQuery';
32
+ export interface DatabendQueryResultHKT {
33
+ readonly row: RowData;
34
+ type: GenericTableData<Assume<this['row'], RowData>>;
35
+ }
36
+
37
+ export class DatabendPreparedQuery extends DatabendPreparedQueryBase {
38
+ static override readonly [entityKind]: string = 'DatabendPreparedQuery';
39
39
 
40
40
  constructor(
41
41
  private client: DatabendClientLike,
42
42
  private queryString: string,
43
43
  private params: unknown[],
44
44
  private logger: Logger,
45
- private fields: SelectedFieldsOrdered | undefined,
45
+ private fields: any[] | undefined,
46
46
  private _isResponseInArrayMode: boolean,
47
47
  private customResultMapper:
48
- | ((rows: unknown[][]) => T['execute'])
48
+ | ((rows: unknown[][]) => any)
49
49
  | undefined,
50
50
  private typings?: QueryTypingsValue[]
51
51
  ) {
@@ -54,7 +54,7 @@ export class DatabendPreparedQuery<
54
54
 
55
55
  async execute(
56
56
  placeholderValues: Record<string, unknown> | undefined = {}
57
- ): Promise<T['execute']> {
57
+ ): Promise<any> {
58
58
  const params = fillPlaceholders(this.params, placeholderValues);
59
59
  this.logger.logQuery(this.queryString, params);
60
60
 
@@ -70,24 +70,24 @@ export class DatabendPreparedQuery<
70
70
  );
71
71
 
72
72
  if (rows.length === 0) {
73
- return [] as T['execute'];
73
+ return [];
74
74
  }
75
75
 
76
76
  return customResultMapper
77
77
  ? customResultMapper(rows)
78
78
  : rows.map((row) =>
79
- mapResultRow<T['execute']>(fields, row, joinsNotNullableMap)
79
+ mapResultRow(fields, row, joinsNotNullableMap)
80
80
  );
81
81
  }
82
82
 
83
83
  const rows = await executeOnClient(this.client, this.queryString, params, typings);
84
84
 
85
- return rows as T['execute'];
85
+ return rows;
86
86
  }
87
87
 
88
88
  all(
89
89
  placeholderValues: Record<string, unknown> | undefined = {}
90
- ): Promise<T['all']> {
90
+ ): Promise<any> {
91
91
  return this.execute(placeholderValues);
92
92
  }
93
93
 
@@ -103,10 +103,10 @@ export interface DatabendSessionOptions {
103
103
  export class DatabendSession<
104
104
  TFullSchema extends Record<string, unknown> = Record<string, never>,
105
105
  TSchema extends TablesRelationalConfig = Record<string, never>,
106
- > extends PgSession<DatabendQueryResultHKT, TFullSchema, TSchema> {
107
- static readonly [entityKind]: string = 'DatabendSession';
106
+ > extends DatabendSessionBase {
107
+ static override readonly [entityKind]: string = 'DatabendSession';
108
108
 
109
- protected override dialect: DatabendDialect;
109
+ override dialect: DatabendDialect;
110
110
  private logger: Logger;
111
111
  private rollbackOnly = false;
112
112
 
@@ -121,13 +121,13 @@ export class DatabendSession<
121
121
  this.logger = options.logger ?? new NoopLogger();
122
122
  }
123
123
 
124
- prepareQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(
124
+ override prepareQuery(
125
125
  query: Query,
126
- fields: SelectedFieldsOrdered | undefined,
126
+ fields: any[] | undefined,
127
127
  name: string | undefined,
128
128
  isResponseInArrayMode: boolean,
129
- customResultMapper?: (rows: unknown[][]) => T['execute']
130
- ): PgPreparedQuery<T> {
129
+ customResultMapper?: (rows: unknown[][]) => any
130
+ ): DatabendPreparedQuery {
131
131
  void name;
132
132
  return new DatabendPreparedQuery(
133
133
  this.client,
@@ -143,7 +143,7 @@ export class DatabendSession<
143
143
 
144
144
  override async transaction<T>(
145
145
  transaction: (tx: DatabendTransaction<TFullSchema, TSchema>) => Promise<T>,
146
- config?: PgTransactionConfig
146
+ config?: DatabendTransactionConfig
147
147
  ): Promise<T> {
148
148
  let pinnedConnection: Connection | undefined;
149
149
  let pool: DatabendConnectionPool | undefined;
@@ -203,19 +203,10 @@ export class DatabendSession<
203
203
  }
204
204
  }
205
205
 
206
- type DatabendTransactionInternals<
207
- TFullSchema extends Record<string, unknown> = Record<string, never>,
208
- TSchema extends TablesRelationalConfig = Record<string, never>,
209
- > = {
210
- dialect: DatabendDialect;
211
- session: DatabendSession<TFullSchema, TSchema>;
212
- };
213
-
214
- type DatabendTransactionWithInternals<
215
- TFullSchema extends Record<string, unknown> = Record<string, never>,
216
- TSchema extends TablesRelationalConfig = Record<string, never>,
217
- > = DatabendTransactionInternals<TFullSchema, TSchema> &
218
- DatabendTransaction<TFullSchema, TSchema>;
206
+ export interface DatabendTransactionConfig {
207
+ isolationLevel?: string;
208
+ accessMode?: string;
209
+ }
219
210
 
220
211
  const VALID_TRANSACTION_ISOLATION_LEVELS = new Set<string>([
221
212
  'read uncommitted',
@@ -232,14 +223,16 @@ const VALID_TRANSACTION_ACCESS_MODES = new Set<string>([
232
223
  export class DatabendTransaction<
233
224
  TFullSchema extends Record<string, unknown>,
234
225
  TSchema extends TablesRelationalConfig,
235
- > extends PgTransaction<DatabendQueryResultHKT, TFullSchema, TSchema> {
236
- static readonly [entityKind]: string = 'DatabendTransaction';
226
+ > extends DatabendTransactionBase {
227
+ static override readonly [entityKind]: string = 'DatabendTransaction';
228
+
229
+ declare schema: any;
237
230
 
238
- rollback(): never {
231
+ override rollback(): never {
239
232
  throw new TransactionRollbackError();
240
233
  }
241
234
 
242
- getTransactionConfigSQL(config: PgTransactionConfig): SQL {
235
+ getTransactionConfigSQL(config: DatabendTransactionConfig): SQL {
243
236
  if (
244
237
  config.isolationLevel &&
245
238
  !VALID_TRANSACTION_ISOLATION_LEVELS.has(config.isolationLevel)
@@ -272,9 +265,8 @@ export class DatabendTransaction<
272
265
  return sql.raw(chunks.join(' '));
273
266
  }
274
267
 
275
- setTransaction(config: PgTransactionConfig): Promise<void> {
276
- type Tx = DatabendTransactionWithInternals<TFullSchema, TSchema>;
277
- return (this as unknown as Tx).session.execute(
268
+ setTransaction(config: DatabendTransactionConfig): Promise<void> {
269
+ return (this as any).session.execute(
278
270
  sql`SET TRANSACTION ${this.getTransactionConfigSQL(config)}`
279
271
  );
280
272
  }
@@ -283,8 +275,7 @@ export class DatabendTransaction<
283
275
  transaction: (tx: DatabendTransaction<TFullSchema, TSchema>) => Promise<T>
284
276
  ): Promise<T> {
285
277
  // Databend does not support savepoints. Use rollback-only fallback.
286
- type Tx = DatabendTransactionWithInternals<TFullSchema, TSchema>;
287
- const internals = this as unknown as Tx;
278
+ const internals = this as any;
288
279
 
289
280
  const nestedTx = new DatabendTransaction<TFullSchema, TSchema>(
290
281
  internals.dialect,
@@ -294,9 +285,7 @@ export class DatabendTransaction<
294
285
  );
295
286
 
296
287
  return transaction(nestedTx).catch((error) => {
297
- (
298
- internals.session as DatabendSession<TFullSchema, TSchema>
299
- ).markRollbackOnly();
288
+ (internals.session as DatabendSession<TFullSchema, TSchema>).markRollbackOnly();
300
289
  throw error;
301
290
  });
302
291
  }
@@ -305,7 +294,3 @@ export class DatabendTransaction<
305
294
  export type GenericRowData<T extends RowData = RowData> = T;
306
295
 
307
296
  export type GenericTableData<T = RowData> = T[];
308
-
309
- export interface DatabendQueryResultHKT extends PgQueryResultHKT {
310
- type: GenericTableData<Assume<this['row'], RowData>>;
311
- }
@@ -7,14 +7,9 @@ import {
7
7
  type SelectedFieldsOrdered,
8
8
  SQL,
9
9
  } from 'drizzle-orm';
10
- import {
11
- PgCustomColumn,
12
- PgDate,
13
- PgDateString,
14
- PgTime,
15
- PgTimestamp,
16
- PgTimestampString,
17
- } from 'drizzle-orm/pg-core';
10
+ import { DatabendCustomColumn } from '../databend-core/columns/custom.ts';
11
+ import { DatabendDate } from '../databend-core/columns/date.ts';
12
+ import { DatabendTimestamp } from '../databend-core/columns/timestamp.ts';
18
13
 
19
14
  type SQLInternal<T = unknown> = SQL<T> & {
20
15
  decoder: DriverValueDecoder<T, any>;
@@ -33,25 +28,21 @@ function toDecoderInput<TDecoder extends DriverValueDecoder<unknown, unknown>>(
33
28
 
34
29
  export function normalizeTimestampString(
35
30
  value: unknown,
36
- withTimezone: boolean
31
+ _withTimezone: boolean
37
32
  ): string | unknown {
38
33
  if (value instanceof Date) {
39
34
  const iso = value.toISOString().replace('T', ' ');
40
- return withTimezone ? iso.replace('Z', '+00') : iso.replace('Z', '');
35
+ return iso.replace('Z', '');
41
36
  }
42
37
  if (typeof value === 'string') {
43
- const normalized = value.replace('T', ' ');
44
- if (withTimezone) {
45
- return normalized.includes('+') ? normalized : `${normalized}+00`;
46
- }
47
- return normalized.replace(/\+00$/, '');
38
+ return value.replace('T', ' ');
48
39
  }
49
40
  return value;
50
41
  }
51
42
 
52
43
  export function normalizeTimestamp(
53
44
  value: unknown,
54
- withTimezone: boolean
45
+ _withTimezone: boolean
55
46
  ): Date | unknown {
56
47
  if (value instanceof Date) {
57
48
  return value;
@@ -60,7 +51,7 @@ export function normalizeTimestamp(
60
51
  const hasOffset =
61
52
  value.endsWith('Z') || /[+-]\d{2}:?\d{2}$/.test(value.trim());
62
53
  const spaced = value.replace(' ', 'T');
63
- const normalized = withTimezone || hasOffset ? spaced : `${spaced}+00`;
54
+ const normalized = hasOffset ? spaced : `${spaced}Z`;
64
55
  return new Date(normalized);
65
56
  }
66
57
  return value;
@@ -86,57 +77,24 @@ export function normalizeDateValue(value: unknown): Date | unknown {
86
77
  return value;
87
78
  }
88
79
 
89
- export function normalizeTime(value: unknown): string | unknown {
90
- if (typeof value === 'bigint') {
91
- const totalMillis = Number(value) / 1000;
92
- const date = new Date(totalMillis);
93
- return date.toISOString().split('T')[1]!.replace('Z', '');
94
- }
95
- if (value instanceof Date) {
96
- return value.toISOString().split('T')[1]!.replace('Z', '');
97
- }
98
- return value;
99
- }
100
-
101
80
  function mapDriverValue(
102
81
  decoder: DriverValueDecoder<unknown, unknown>,
103
82
  rawValue: unknown
104
83
  ): unknown {
105
- if (is(decoder, PgTimestampString)) {
106
- return decoder.mapFromDriverValue(
107
- toDecoderInput(
108
- decoder,
109
- normalizeTimestampString(rawValue, decoder.withTimezone)
110
- )
111
- );
112
- }
113
-
114
- if (is(decoder, PgTimestamp)) {
115
- const normalized = normalizeTimestamp(rawValue, decoder.withTimezone);
84
+ if (is(decoder, DatabendTimestamp)) {
85
+ const normalized = normalizeTimestamp(rawValue, false);
116
86
  if (normalized instanceof Date) {
117
87
  return normalized;
118
88
  }
119
89
  return decoder.mapFromDriverValue(toDecoderInput(decoder, normalized));
120
90
  }
121
91
 
122
- if (is(decoder, PgDateString)) {
92
+ if (is(decoder, DatabendDate)) {
123
93
  return decoder.mapFromDriverValue(
124
94
  toDecoderInput(decoder, normalizeDateString(rawValue))
125
95
  );
126
96
  }
127
97
 
128
- if (is(decoder, PgDate)) {
129
- return decoder.mapFromDriverValue(
130
- toDecoderInput(decoder, normalizeDateValue(rawValue))
131
- );
132
- }
133
-
134
- if (is(decoder, PgTime)) {
135
- return decoder.mapFromDriverValue(
136
- toDecoderInput(decoder, normalizeTime(rawValue))
137
- );
138
- }
139
-
140
98
  return decoder.mapFromDriverValue(toDecoderInput(decoder, rawValue));
141
99
  }
142
100
 
@@ -157,7 +115,7 @@ export function mapResultRow<TResult>(
157
115
  } else {
158
116
  const col = field.sql.queryChunks.find((chunk) => is(chunk, Column));
159
117
 
160
- if (is(col, PgCustomColumn)) {
118
+ if (is(col, DatabendCustomColumn)) {
161
119
  decoder = col;
162
120
  } else {
163
121
  decoder = (field.sql as SQLInternal).decoder;