feat(sql): support MySQL routine blocks
This commit is contained in:
1 parent
7ff4d9f804
commit
b6b510d632
4 files changed
+530
-14
No files matched your search
@@ -65,6 +65,15 @@ END;
|
||||
/
|
||||
SELECT 1;`;
|
||||
|
||||
const mysqlRoutineFixture = `CREATE PROCEDURE p()
|
||||
BEGIN
|
||||
SELECT 1;
|
||||
IF 1 = 1 THEN
|
||||
SELECT 'ok';
|
||||
END IF;
|
||||
END;
|
||||
SELECT 2;`;
|
||||
|
||||
describe("splitSqlStatementRanges", () => {
|
||||
it("splits multiple top-level statements", () => {
|
||||
const sql = "SELECT 1;\nSELECT 2;\nSELECT 3;";
|
||||
@@ -127,6 +136,19 @@ describe("splitSqlStatementRanges", () => {
|
||||
expect(rangeSqlTexts(splitSqlStatementRanges(sql, "mysql"))).toEqual(["select COUNT(1) FROM your_table", "select COUNT(1) FROM your_table;"]);
|
||||
});
|
||||
|
||||
it("keeps MySQL routine blocks together without delimiter commands", () => {
|
||||
const ranges = splitSqlStatementRanges(mysqlRoutineFixture, "mysql");
|
||||
expect(rangeSqlTexts(ranges)).toEqual([mysqlRoutineFixture.slice(0, mysqlRoutineFixture.indexOf("\nSELECT 2;")).replace(/;$/, "").trim(), "SELECT 2"]);
|
||||
expect(ranges[0].sql).toContain("SELECT 1;");
|
||||
expect(ranges[0].sql).toContain("END IF;");
|
||||
expect(ranges[0].sql).not.toMatch(/END;$/);
|
||||
});
|
||||
|
||||
it("does not merge regular MySQL transaction statements as routine blocks", () => {
|
||||
const sql = "BEGIN; INSERT INTO t VALUES (1); COMMIT;";
|
||||
expect(rangeSqlTexts(splitSqlStatementRanges(sql, "mysql"))).toEqual(["BEGIN", "INSERT INTO t VALUES (1)", "COMMIT"]);
|
||||
});
|
||||
|
||||
it("keeps Oracle PL/SQL blocks together and treats slash lines as delimiters", () => {
|
||||
const ranges = splitSqlStatementRanges(oraclePlSqlFixture, "oracle");
|
||||
expect(rangeSqlTexts(ranges)).toEqual([oraclePlSqlFixture.slice(0, oraclePlSqlFixture.indexOf("\n/")), "SELECT 1"]);
|
||||
@@ -359,6 +381,11 @@ WHERE request_json LIKE '%"paperFlag":null%';`;
|
||||
expect(statementRangeAtCursor(sql, indexOf(sql, "delimiter"), "mysql")).toBeNull();
|
||||
});
|
||||
|
||||
it("returns the full MySQL routine block for cursors inside nested statements", () => {
|
||||
const range = statementRangeAtCursor(mysqlRoutineFixture, indexOf(mysqlRoutineFixture, "ok"), "mysql");
|
||||
expect(range?.sql.trim()).toBe(mysqlRoutineFixture.slice(0, mysqlRoutineFixture.indexOf("\nSELECT 2;")).replace(/;$/, "").trim());
|
||||
});
|
||||
|
||||
it("returns the full Oracle PL/SQL block for cursors inside nested statements", () => {
|
||||
const range = statementRangeAtCursor(oraclePlSqlFixture, indexOf(oraclePlSqlFixture, "ORDERS_10K", 2), "oracle");
|
||||
expect(range?.sql.trim()).toBe(oraclePlSqlFixture.slice(0, oraclePlSqlFixture.indexOf("\n/")));
|
||||
@@ -396,6 +423,10 @@ describe("executableStatementRanges", () => {
|
||||
it("does not split executable Oracle PL/SQL ranges at inner statement starts", () => {
|
||||
expect(rangeSqlTexts(executableStatementRanges(oraclePlSqlFixture, "oracle"))).toEqual([oraclePlSqlFixture.slice(0, oraclePlSqlFixture.indexOf("\n/")), "SELECT 1"]);
|
||||
});
|
||||
|
||||
it("does not split executable MySQL routine ranges at inner statements", () => {
|
||||
expect(rangeSqlTexts(executableStatementRanges(mysqlRoutineFixture, "mysql"))).toEqual([mysqlRoutineFixture.slice(0, mysqlRoutineFixture.indexOf("\nSELECT 2;")).replace(/;$/, "").trim(), "SELECT 2"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fullSqlRange", () => {
|
||||
@@ -520,6 +551,10 @@ describe("hasMultipleExecutionTargets", () => {
|
||||
expect(hasMultipleExecutionTargets(sql, "mysql")).toBe(true);
|
||||
});
|
||||
|
||||
it("counts MySQL routine blocks without delimiter by executable statements", () => {
|
||||
expect(hasMultipleExecutionTargets(mysqlRoutineFixture, "mysql")).toBe(true);
|
||||
});
|
||||
|
||||
it("does not show multiple targets for MySQL DESC UPDATE joins", () => {
|
||||
const sql = "desc update test_orders a\njoin test_users b\non a.id=b.id \nset a.name = '张三'\nwhere b.id > 10;";
|
||||
expect(hasMultipleExecutionTargets(sql, "mysql")).toBe(false);
|
||||
|
||||
Reference in new issue
Block a user