Skip to content

Commit 4f49e0a

Browse files
committed
fixed SQLCommonParam handling in clickhouse
1 parent 5e9550e commit 4f49e0a

5 files changed

Lines changed: 68 additions & 8 deletions

File tree

integration-tests/tests/clickhouse/clickhouse-core.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,37 +184,37 @@ export const commonClickHouseTests = () => {
184184
test('base test with number param', (ctx) => {
185185
const res = ctx.sql`select ${1};`.toSQL();
186186

187-
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [1] });
187+
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [['val1', 1]] });
188188
});
189189

190190
test('base test with bigint param', (ctx) => {
191191
const res = ctx.sql`select ${BigInt(10)};`.toSQL();
192192

193-
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [10n] });
193+
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [['val1', 10n]] });
194194
});
195195

196196
test('base test with string param', (ctx) => {
197197
const res = ctx.sql`select ${'hello world.'};`.toSQL();
198198

199-
expect(res).toStrictEqual({ query: `select {val1:String};`, params: ['hello world.'] });
199+
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [['val1', 'hello world.']] });
200200
});
201201

202202
test('base test with boolean param', (ctx) => {
203203
const res = ctx.sql`select ${true};`.toSQL();
204204

205-
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [true] });
205+
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [['val1', true]] });
206206
});
207207

208208
test('base test with Date param', (ctx) => {
209209
const res = ctx.sql`select ${new Date('10.04.2025')};`.toSQL();
210210

211-
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [new Date('10.04.2025')] });
211+
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [['val1', new Date('10.04.2025')]] });
212212
});
213213

214214
test('base test with null param', (ctx) => {
215215
const res = ctx.sql`select ${null};`.toSQL();
216216

217-
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [null] });
217+
expect(res).toStrictEqual({ query: `select {val1:String};`, params: [['val1', null]] });
218218
});
219219

220220
// sql.append
@@ -227,7 +227,7 @@ export const commonClickHouseTests = () => {
227227
const res = query.toSQL();
228228
expect(res).toStrictEqual({
229229
query: 'select * from users where id = {val1:String} or id = {val2:String} or id = {val3:String};',
230-
params: [1, 3, 4],
230+
params: [['val1', 1], ['val2', 3], ['val3', 4]],
231231
});
232232
});
233233

integration-tests/tests/clickhouse/waddler.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,3 +1077,55 @@ test('sql.stream test', async () => {
10771077
expect(predicate).toBe(true);
10781078
}
10791079
});
1080+
1081+
test('query database test from documentation', async () => {
1082+
await sql.unsafe(`create table users(
1083+
id Int32,
1084+
name String,
1085+
age Int32,
1086+
email String
1087+
)
1088+
engine = MergeTree
1089+
order by id;
1090+
`).command();
1091+
1092+
const user = [
1093+
'John',
1094+
30,
1095+
'john@example.com',
1096+
];
1097+
await sql`insert into ${sql.identifier('users')} values ${sql.values([[sql.default, ...user]])};`.command();
1098+
// console.log('New user created!');
1099+
const _users = await sql`select * from ${sql.identifier('users')};`.query();
1100+
// console.log('Getting all users from the database:', users);
1101+
/*
1102+
const users: {
1103+
id: number;
1104+
name: string;
1105+
age: number;
1106+
email: string;
1107+
}[]
1108+
*/
1109+
await sql`alter table ${sql.identifier('users')} update age = ${31} where email = ${user[2]};`.command();
1110+
// console.log('User info updated!');
1111+
1112+
const stream = sql`select * from ${sql.identifier('users')};`.query().stream();
1113+
1114+
// console.log('Streaming users one at a time from the database.');
1115+
for await (const _user of stream) {
1116+
// console.log(user);
1117+
/*
1118+
const user: {
1119+
id: number;
1120+
name: string;
1121+
age: number;
1122+
email: string;
1123+
}
1124+
*/
1125+
}
1126+
1127+
await sql`alter table ${sql.identifier('users')} delete where email = ${user[2]};`.command();
1128+
// console.log('User deleted!');
1129+
1130+
await sql.unsafe(`drop table users;`).command();
1131+
});

waddler/src/clickhouse-core/dialect.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ export class ClickHouseDialect extends Dialect {
99
return `{val${lastParamIdx}:${typeToCast || 'String'}}`;
1010
}
1111

12+
override formParam(param: any, lastParamIdx: number) {
13+
return [`val${lastParamIdx}`, param];
14+
}
15+
1216
escapeIdentifier(identifier: string): string {
1317
return `\`${identifier}\``;
1418
}

waddler/src/sql-template-params.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import type { Identifier, IdentifierObject, Raw, UnsafeParamType, Value } from '
33

44
export abstract class Dialect implements BuildQueryConfig {
55
abstract escapeParam(lastParamIdx: number): string;
6+
formParam(param: any, _lastParamIdx: number): any {
7+
return param;
8+
}
69
abstract escapeIdentifier(identifier: string): string;
710
abstract checkIdentifierObject(object: IdentifierObject): void;
811

@@ -37,7 +40,7 @@ export class SQLCommonParam extends SQLChunk {
3740
) {
3841
return {
3942
sql: dialect.escapeParam(lastParamIdx + 1),
40-
params: [this.value],
43+
params: [dialect.formParam(this.value, lastParamIdx + 1)],
4144
};
4245
}
4346
}

waddler/src/sql.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export interface Query {
3030
export interface BuildQueryConfig {
3131
escapeIdentifier(identifier: string): string;
3232
escapeParam(lastParamIdx: number): string;
33+
formParam(param: any, lastParamIdx: number): any;
3334
checkIdentifierObject(object: IdentifierObject): void;
3435
valueToSQL(
3536
{ value, lastParamIdx, params }: {

0 commit comments

Comments
 (0)