fix(sql): keep merge update set line in statement continuation
This commit is contained in:
1 parent
ffb915061f
commit
280af02120
2 files changed
+45
-1
No files matched your search
@@ -1472,6 +1472,45 @@ FROM orders;`;
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps an Oracle MERGE together when each action starts its own line (#9516)", () => {
|
||||
const merge = `MERGE INTO bom_template t USING (SELECT id, no FROM stage_bom) s ON (t.id = s.id)
|
||||
WHEN MATCHED THEN
|
||||
UPDATE SET
|
||||
t.no = s.no
|
||||
WHERE
|
||||
t.no IS NULL
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (id, no)
|
||||
VALUES (s.id, s.no)`;
|
||||
for (const needle of ["MERGE INTO", "UPDATE SET", "WHERE", "INSERT (id, no)", "VALUES (s.id, s.no)"]) {
|
||||
expect(statementRangeAtCursor(merge, indexOf(merge, needle), "oracle")?.sql.trim()).toBe(merge);
|
||||
}
|
||||
expect(rangeSqlTexts(executableStatementRanges(merge, "oracle"))).toEqual([merge]);
|
||||
});
|
||||
|
||||
it("keeps an Oracle MERGE delete action that starts its own line together", () => {
|
||||
const merge = `MERGE INTO bom_template t USING (SELECT id FROM stage_bom) s ON (t.id = s.id)
|
||||
WHEN MATCHED THEN
|
||||
DELETE WHERE t.no IS NULL`;
|
||||
expect(rangeSqlTexts(executableStatementRanges(merge, "oracle"))).toEqual([merge]);
|
||||
});
|
||||
|
||||
it("keeps an Oracle MERGE together when the UPDATE action's SET starts its own line", () => {
|
||||
const merge = `MERGE INTO bom_template t USING (SELECT id, no FROM stage_bom) s ON (t.id = s.id)
|
||||
WHEN MATCHED THEN
|
||||
UPDATE
|
||||
SET t.no = s.no`;
|
||||
const update = "UPDATE bom_template\nSET no = 'x'";
|
||||
expect(rangeSqlTexts(executableStatementRanges(merge, "oracle"))).toEqual([merge]);
|
||||
expect(rangeSqlTexts(executableStatementRanges(`${merge};\n\n${update};`, "oracle"))).toEqual([merge, update]);
|
||||
});
|
||||
|
||||
it("still splits a standalone UPDATE that follows a terminated MERGE", () => {
|
||||
const merge = "MERGE INTO bom_template t USING (SELECT id FROM stage_bom) s ON (t.id = s.id)\nWHEN MATCHED THEN UPDATE SET t.no = s.no";
|
||||
const update = "UPDATE bom_template SET no = 'x'";
|
||||
expect(rangeSqlTexts(executableStatementRanges(`${merge};\n\n${update};`, "oracle"))).toEqual([merge, update]);
|
||||
});
|
||||
|
||||
it("returns the full SAP HANA DO block for cursors inside nested statements", () => {
|
||||
const range = statementRangeAtCursor(sapHanaDoBlockFixture, indexOf(sapHanaDoBlockFixture, "Result"), "saphana");
|
||||
|
||||
|
||||
@@ -1106,8 +1106,13 @@ function isMysqlAlterTableTruncatePartitionContinuation(sql: string, statementFr
|
||||
}
|
||||
|
||||
function isMergeActionContinuation(sql: string, statementFrom: number, lineStartFrom: number, keyword: string, databaseType?: DatabaseType, parameterOptions?: SqlParameterOptions): boolean {
|
||||
if (keyword !== "INSERT" || !startsWithSqlWords(sql, statementFrom, ["MERGE"], databaseType, parameterOptions)) return false;
|
||||
// Oracle (and friends) allow each MERGE action on its own line after
|
||||
// `WHEN ... MATCHED THEN`, e.g. `UPDATE SET ...` (#9516); only INSERT was
|
||||
// recognized, so UPDATE/DELETE action lines split the statement in two.
|
||||
if (keyword !== "INSERT" && keyword !== "UPDATE" && keyword !== "DELETE" && keyword !== "SET") return false;
|
||||
if (!startsWithSqlWords(sql, statementFrom, ["MERGE"], databaseType, parameterOptions)) return false;
|
||||
const words = topLevelWordsBefore(sql, statementFrom, lineStartFrom, 5, databaseType, parameterOptions);
|
||||
if (keyword === "SET") return words[words.length - 1] === "UPDATE" && words.includes("THEN") && words.includes("MATCHED");
|
||||
return words[words.length - 1] === "THEN" && words.includes("WHEN") && words.includes("MATCHED");
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user