fix(sql): recognize @set declarations after comments

Closes #6974
This commit is contained in:
t8y2 committed 2026-08-23 09:44:33 +00:00
1 parent 4dd107484f
commit 6e189723bd
3 files changed
+32 -8

No files matched your search

@@ -210,7 +210,7 @@ describe("useSqlExecution", () => {
it("expands preceding @set values in a selected shell-style statement", async () => {
const selectedSql = "SELECT * FROM patrol WHERE post_id = ${postid};";
const fullSql = ["@set postid = '224';", selectedSql, "@set postid = 'future';"].join("\n");
const fullSql = ["-- saved query", "@set postid='224';", selectedSql, "@set postid = 'future';"].join("\n");
const selectionFrom = fullSql.indexOf("SELECT");
const selectionTo = selectionFrom + selectedSql.length;
const activeTab = ref<QueryTab | undefined>({ ...queryTab("app"), sql: fullSql });
+15
View File
@@ -24,6 +24,21 @@ describe("expandSqlVariables", () => {
expect(expandSqlVariables(sql).sql).toBe("select * from t where post_id = '224'");
});
it("recognizes a declaration after a leading line comment", () => {
const sql = ["-- saved query", "@set devid=7062;", "select * from t where device_id = ${devid}"].join("\n");
expect(expandSqlVariables(sql).sql).toBe("-- saved query\nselect * from t where device_id = 7062");
});
it("recognizes declarations after comments at a statement boundary", () => {
const sql = ["select 1;", "/* next statement */", "@set devid = 7062;", "select ${devid}"].join("\n");
expect(expandSqlVariables(sql).sql).toBe("select 1;\n/* next statement */\nselect 7062");
});
it("does not recognize a declaration after an unterminated statement", () => {
const sql = ["select 1", "-- same statement", "@set devid = 7062;", "select ${devid}"].join("\n");
expect(expandSqlVariables(sql)).toEqual({ sql, expanded: false });
});
it("uses declarations from the surrounding document for a selected statement", () => {
const selectedSql = "select * from t where post_id = ${postid}";
const declarationSql = ["@set postid = '224';", selectedSql].join("\n");
+16 -7
View File
@@ -67,6 +67,7 @@ function collectDeclarations(sql: string, databaseType?: DatabaseType): Declarat
const declarations: DeclarationSpan[] = [];
let i = 0;
let dollarQuoteEnd = "";
let statementStart = true;
while (i < sql.length) {
if (dollarQuoteEnd) {
@@ -80,11 +81,17 @@ function collectDeclarations(sql: string, databaseType?: DatabaseType): Declarat
const ch = sql[i];
const next = sql[i + 1];
if (/\s/.test(ch)) {
i += 1;
continue;
}
if (ch === "'" || ch === '"' || ch === "`") {
statementStart = false;
i = skipQuoted(sql, i, ch);
continue;
}
if (ch === "[") {
statementStart = false;
i = skipBracketIdentifier(sql, i, databaseType);
continue;
}
@@ -99,19 +106,27 @@ function collectDeclarations(sql: string, databaseType?: DatabaseType): Declarat
if (ch === "$") {
const marker = readDollarQuoteMarker(sql, i);
if (marker) {
statementStart = false;
dollarQuoteEnd = marker;
i += marker.length;
continue;
}
}
if (ch === "@" && matchesWord(sql, i + 1, "set") && isStatementStart(sql, i)) {
if (ch === "@" && statementStart && matchesWord(sql, i + 1, "set")) {
const declaration = readDeclaration(sql, i, databaseType);
if (declaration) {
declarations.push(declaration);
i = declaration.end;
statementStart = true;
continue;
}
}
if (ch === ";") {
statementStart = true;
i += 1;
continue;
}
statementStart = false;
i += 1;
}
@@ -283,12 +298,6 @@ function stripDeclaration(sql: string, start: number, end: number): string {
return sql.slice(0, trimmableStart) + sql.slice(lineEnd);
}
function isStatementStart(sql: string, start: number): boolean {
let i = start - 1;
while (i >= 0 && /\s/.test(sql[i])) i -= 1;
return i < 0 || sql[i] === ";";
}
function matchesWord(sql: string, start: number, word: string): boolean {
const value = sql.slice(start, start + word.length);
if (value.toLowerCase() !== word) return false;