fix(sql): ignore native SQL variables
This commit is contained in:
1 parent
6cba08fccb
commit
9288717ac4
3 files changed
+440
-9
No files matched your search
@@ -12,6 +12,8 @@ describe("extractSqlParameters", () => {
|
||||
select '\${quoted}' as a, "\${identifier}" as b, \`\${mysql_identifier}\`
|
||||
-- \${line_comment}
|
||||
# \${hash_comment}
|
||||
#\${hash_comment_without_space}
|
||||
select 1 #comment \${inline_hash_comment}
|
||||
/* \${block_comment} */
|
||||
from t
|
||||
where id = \${id}
|
||||
@@ -48,6 +50,103 @@ describe("extractSqlParameters", () => {
|
||||
expect(extractSqlParameters(sql)).toEqual(["input_value"]);
|
||||
});
|
||||
|
||||
it("ignores variables assigned by SET statements", () => {
|
||||
const sql = `
|
||||
set @date_start = '2026-07-04 00:00:00';
|
||||
select * from fin_pur_payment AS fp where fp.create_time < @date_start and fp.tenant_id = @tenant_id
|
||||
`;
|
||||
expect(extractSqlParameters(sql)).toEqual(["tenant_id"]);
|
||||
});
|
||||
|
||||
it("ignores multiple variables assigned by SET statements", () => {
|
||||
const sql = `
|
||||
set @date_start := '2026-07-01', @date_end = '2026-07-31';
|
||||
select * from orders where created_at between @date_start and @date_end and tenant_id = @tenant_id
|
||||
`;
|
||||
expect(extractSqlParameters(sql)).toEqual(["tenant_id"]);
|
||||
});
|
||||
|
||||
it("ignores variables assigned by SELECT statements", () => {
|
||||
const sql = `
|
||||
select @date_start := min(created_at), @date_end = max(created_at) from orders;
|
||||
select * from orders where created_at between @date_start and @date_end and tenant_id = @tenant_id
|
||||
`;
|
||||
expect(extractSqlParameters(sql)).toEqual(["tenant_id"]);
|
||||
});
|
||||
|
||||
it("ignores SQL Server procedure parameters declared in routine definitions", () => {
|
||||
const sql = `
|
||||
create procedure dbo.search_orders
|
||||
@date_start datetime,
|
||||
@status nvarchar(20) = N'paid'
|
||||
as
|
||||
begin
|
||||
select * from orders where created_at >= @date_start and status = @status and tenant_id = @tenant_id;
|
||||
end
|
||||
`;
|
||||
expect(extractSqlParameters(sql)).toEqual(["tenant_id"]);
|
||||
});
|
||||
|
||||
it("ignores SQL Server function parameters declared in routine definitions", () => {
|
||||
const sql = `
|
||||
create function dbo.order_count(@date_start datetime, @status nvarchar(20))
|
||||
returns int
|
||||
as
|
||||
begin
|
||||
return (select count(*) from orders where created_at >= @date_start and status = @status and tenant_id = @tenant_id);
|
||||
end
|
||||
`;
|
||||
expect(extractSqlParameters(sql)).toEqual(["tenant_id"]);
|
||||
});
|
||||
|
||||
it("keeps template parameters in non-routine CREATE statements", () => {
|
||||
const sql = "create table #orders (tenant_id int default @tenant_id);";
|
||||
expect(extractSqlParameters(sql)).toEqual(["tenant_id"]);
|
||||
});
|
||||
|
||||
it("ignores named stored procedure arguments while preserving template values", () => {
|
||||
const sql = "exec dbo.search_orders @date_start = '2026-07-04', @status = @status_value, @tenant_id = @tenant_id";
|
||||
expect(extractSqlParameters(sql)).toEqual(["status_value", "tenant_id"]);
|
||||
});
|
||||
|
||||
it("ignores declared SQL Server table variables", () => {
|
||||
const sql = `
|
||||
declare @ids table (id int);
|
||||
insert into @ids values (1);
|
||||
select * from @ids where id = @input_id;
|
||||
`;
|
||||
expect(extractSqlParameters(sql)).toEqual(["input_id"]);
|
||||
});
|
||||
|
||||
it("ignores SQL Server and MySQL system variables", () => {
|
||||
const sql = "select @@ROWCOUNT, @@IDENTITY, @@SERVERNAME, @@session.sql_mode, @@global.time_zone, @input_value";
|
||||
expect(extractSqlParameters(sql)).toEqual(["input_value"]);
|
||||
});
|
||||
|
||||
it("extracts template parameters from ordinary SELECT filters", () => {
|
||||
const sql = `
|
||||
select * from fin_pur_payment
|
||||
where tenant_id = @tenant_id;
|
||||
`;
|
||||
expect(extractSqlParameters(sql)).toEqual(["tenant_id"]);
|
||||
});
|
||||
|
||||
it("extracts remaining template parameters after SET-defined variables", () => {
|
||||
const sql = `
|
||||
set @date_start = '2026-07-04 00:00:00';
|
||||
|
||||
select * from fin_pur_payment
|
||||
where create_time < @date_start
|
||||
and tenant_id = @tenant_id;
|
||||
`;
|
||||
expect(extractSqlParameters(sql)).toEqual(["tenant_id"]);
|
||||
});
|
||||
|
||||
it("does not treat native variable updates as template parameters", () => {
|
||||
const sql = "set @n = 1; set @n = @n + 1; select @n;";
|
||||
expect(extractSqlParameters(sql)).toEqual([]);
|
||||
});
|
||||
|
||||
it("stops SQL Server declaration scanning when a new statement starts without a semicolon", () => {
|
||||
const sql = `
|
||||
declare @id int = 1
|
||||
@@ -113,6 +212,26 @@ describe("substituteSqlParameters", () => {
|
||||
const sql = "DECLARE @id int = 1; SELECT * FROM users WHERE id = @id AND tenant_id = @tenant_id";
|
||||
expect(substituteSqlParameters(sql, { tenant_id: { kind: "number", value: "7" } })).toBe("DECLARE @id int = 1; SELECT * FROM users WHERE id = @id AND tenant_id = 7");
|
||||
});
|
||||
|
||||
it("leaves variables assigned by SET statements untouched while replacing undeclared variables", () => {
|
||||
const sql = "set @date_start = '2026-07-04 00:00:00'; select * from fin_pur_payment where create_time < @date_start and tenant_id = @tenant_id";
|
||||
expect(substituteSqlParameters(sql, { tenant_id: { kind: "number", value: "7" } })).toBe("set @date_start = '2026-07-04 00:00:00'; select * from fin_pur_payment where create_time < @date_start and tenant_id = 7");
|
||||
});
|
||||
|
||||
it("preserves native variable updates instead of rewriting SQL text", () => {
|
||||
const sql = "set @n = 1; set @n = @n + 1; select @n;";
|
||||
expect(substituteSqlParameters(sql, {})).toBe(sql);
|
||||
});
|
||||
|
||||
it("leaves named stored procedure arguments untouched while replacing their template values", () => {
|
||||
const sql = "exec dbo.search_orders @date_start = '2026-07-04', @status = @status_value, @tenant_id = @tenant_id";
|
||||
expect(
|
||||
substituteSqlParameters(sql, {
|
||||
status_value: { kind: "string", value: "paid" },
|
||||
tenant_id: { kind: "number", value: "7" },
|
||||
}),
|
||||
).toBe("exec dbo.search_orders @date_start = '2026-07-04', @status = 'paid', @tenant_id = 7");
|
||||
});
|
||||
});
|
||||
|
||||
describe("sqlParameterLiteral", () => {
|
||||
|
||||
Reference in new issue
Block a user