Skip to content

Commit 267af6c

Browse files
author
Sylvestre Gug
committed
do not mutate escape when needed
1 parent d889a6f commit 267af6c

File tree

2 files changed

+29
-29
lines changed

2 files changed

+29
-29
lines changed

src/table.mjs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,13 @@ export function makeQueryTemplate(operations, source) {
246246
const args = [
247247
[`SELECT ${columns} FROM ${formatTable(from.table, escaper)} t`]
248248
];
249+
args.escaper = escaper;
249250
for (let i = 0; i < filter.length; ++i) {
250251
appendSql(i ? `\nAND ` : `\nWHERE `, args);
251-
if (!filter[i].operands) throw new Error("missing operands");
252-
filter[i].operands.forEach((op) => {
253-
if (op.type === "column") op.value = escaper(op.value);
254-
});
255252
appendWhereEntry(filter[i], args);
256253
}
257254
for (let i = 0; i < sort.length; ++i) {
258255
appendSql(i ? `, ` : `\nORDER BY `, args);
259-
sort[i].column = escaper(sort[i].column);
260256
appendOrderBy(sort[i], args);
261257
}
262258
if (source.dialect === "mssql") {
@@ -268,7 +264,7 @@ export function makeQueryTemplate(operations, source) {
268264
);
269265
appendSql(`\nORDER BY `, args);
270266
appendOrderBy(
271-
{column: escaper(select.columns[0]), direction: "ASC"},
267+
{column: select.columns[0], direction: "ASC"},
272268
args
273269
);
274270
}
@@ -291,6 +287,7 @@ export function makeQueryTemplate(operations, source) {
291287
appendSql(` OFFSET ${slice.from}`, args);
292288
}
293289
}
290+
delete args.escaper;
294291
return args;
295292
}
296293

@@ -311,7 +308,8 @@ function appendSql(sql, args) {
311308
}
312309

313310
function appendOrderBy({column, direction}, args) {
314-
appendSql(`t.${column} ${direction.toUpperCase()}`, args);
311+
const escaper = args.escaper;
312+
appendSql(`t.${escaper(column)} ${direction.toUpperCase()}`, args);
315313
}
316314

317315
function appendWhereEntry({type, operands}, args) {
@@ -396,7 +394,8 @@ function appendWhereEntry({type, operands}, args) {
396394

397395
function appendOperand(o, args) {
398396
if (o.type === "column") {
399-
appendSql(`t.${o.value}`, args);
397+
const escaper = args.escaper;
398+
appendSql(`t.${escaper(o.value)}`, args);
400399
} else {
401400
args.push(o.value);
402401
args[0].push("");

test/table-test.mjs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -129,42 +129,43 @@ describe("makeQueryTemplate", () => {
129129
assert.deepStrictEqual(params, ["val1"]);
130130
});
131131

132-
it("makeQueryTemplate filter list", () => {
133-
const source = {name: "db", dialect: "postgres"};
132+
it("makeQueryTemplate filter and escape filters column only once", () => {
133+
const source = {name: "db", dialect: "postgres", escape: (i) => `_${i}_`};
134134
const operations = {
135135
...baseOperations,
136136
filter: [
137137
{
138-
type: "in",
139-
operands: [
140-
{type: "column", value: "col1"},
141-
{type: "resolved", value: "val1"},
142-
{type: "resolved", value: "val2"},
143-
{type: "resolved", value: "val3"}
144-
]
145-
},
146-
{
147-
type: "nin",
138+
type: "eq",
148139
operands: [
149-
{type: "column", value: "col1"},
150-
{type: "resolved", value: "val4"}
140+
{type: "column", value: "col2"},
141+
{type: "resolved", value: "val1"}
151142
]
152143
}
153144
]
154145
};
155146

147+
makeQueryTemplate(operations, source);
156148
const [parts, ...params] = makeQueryTemplate(operations, source);
157-
assert.deepStrictEqual(parts.join("?"), "SELECT t.col1,t.col2 FROM table1 t\nWHERE t.col1 IN (?,?,?)\nAND t.col1 NOT IN (?)");
158-
assert.deepStrictEqual(params, ["val1", "val2", "val3", "val4"]);
149+
assert.deepStrictEqual(
150+
parts.join("?"),
151+
"SELECT t._col1_,t._col2_ FROM table1 t\nWHERE t._col2_ = ?"
152+
);
153+
assert.deepStrictEqual(params, ["val1"]);
159154
});
160155

161-
it("makeQueryTemplate throw if filter is missing operands", () => {
156+
it("makeQueryTemplate filter list", () => {
162157
const source = {name: "db", dialect: "postgres"};
163158
const operations = {
164159
...baseOperations,
165160
filter: [
166161
{
167-
type: "in"
162+
type: "in",
163+
operands: [
164+
{type: "column", value: "col1"},
165+
{type: "resolved", value: "val1"},
166+
{type: "resolved", value: "val2"},
167+
{type: "resolved", value: "val3"}
168+
]
168169
},
169170
{
170171
type: "nin",
@@ -176,9 +177,9 @@ describe("makeQueryTemplate", () => {
176177
]
177178
};
178179

179-
assert.throws(() => {
180-
makeQueryTemplate(operations, source);
181-
}, Error);
180+
const [parts, ...params] = makeQueryTemplate(operations, source);
181+
assert.deepStrictEqual(parts.join("?"), "SELECT t.col1,t.col2 FROM table1 t\nWHERE t.col1 IN (?,?,?)\nAND t.col1 NOT IN (?)");
182+
assert.deepStrictEqual(params, ["val1", "val2", "val3", "val4"]);
182183
});
183184

184185
it("makeQueryTemplate select", () => {

0 commit comments

Comments
 (0)