From 6423197bd8691e2708ea3dfe64e7fef64b2c9131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Wed, 22 May 2024 17:24:05 +0200 Subject: [PATCH] Add support for Oracle LOOP statement --- src/SqlFormatter.php | 8 ++++++++ tests/clihighlight.txt | 6 ++++++ tests/compress.txt | 2 ++ tests/format-highlight.html | 6 ++++++ tests/format.txt | 6 ++++++ tests/highlight.html | 7 +++++++ tests/sql.sql | 7 +++++++ 7 files changed, 42 insertions(+) diff --git a/src/SqlFormatter.php b/src/SqlFormatter.php index b3ff6d9..1eaefdd 100644 --- a/src/SqlFormatter.php +++ b/src/SqlFormatter.php @@ -285,6 +285,14 @@ public function format(string $string, string $indentString = ' '): string } elseif (strtoupper($token->value()) === 'BEGIN') { $newline = true; $increaseBlockIndent = true; + } elseif (strtoupper($token->value()) === 'LOOP') { + // https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/basic-LOOP-statement.html + + $prevNotWhitespaceToken = $cursor->subCursor()->previous(Token::TOKEN_TYPE_WHITESPACE); + if ($prevNotWhitespaceToken !== null && strtoupper($prevNotWhitespaceToken->value()) !== 'END') { + $newline = true; + $increaseBlockIndent = true; + } } elseif (in_array(strtoupper($token->value()), ['WHEN', 'THEN', 'ELSE', 'END'], true)) { if (strtoupper($token->value()) !== 'THEN') { array_shift($indentTypes); diff --git a/tests/clihighlight.txt b/tests/clihighlight.txt index c407e1b..2bbdb9b 100644 --- a/tests/clihighlight.txt +++ b/tests/clihighlight.txt @@ -1098,3 +1098,9 @@ MY_NON_TOP_LEVEL_KEYWORD_FX_3(); throw; end end catch +--- +BEGIN + FOR i IN 1..5 LOOP + DBMS_OUTPUT.PUT_LINE(i); + END LOOP; +END; diff --git a/tests/compress.txt b/tests/compress.txt index 7d2f860..54f1c8d 100644 --- a/tests/compress.txt +++ b/tests/compress.txt @@ -99,3 +99,5 @@ MY_NON_TOP_LEVEL_KEYWORD_FX_1(); MY_NON_TOP_LEVEL_KEYWORD_FX_2(); SELECT x FROM SELECT case when name = 1 then 10 when name = 2 then 20 when name = 3 then case when age > 10 then 30 else 31 end else 40 end AS case1, (SELECT case name when 1 then 10 when 2 then 20 when 3 then case age when 10 then 30 else 31 end else 40 end) case2, name FROM user --- begin try insert into [t] ([name], [int], [float], [null]) values (N'Ewa', 1, 1.0, null); end try begin catch if ERROR_NUMBER() = 544 begin set IDENTITY_INSERT [t] on; begin try insert into [t] ([name], [int], [float], [null]) values (N'Ewa', 1, 1.0, null); set IDENTITY_INSERT [t] off; end try begin catch set IDENTITY_INSERT [t] off; throw; end catch end else begin throw; end end catch +--- +BEGIN FOR i IN 1..5 LOOP DBMS_OUTPUT.PUT_LINE(i); END LOOP; END; diff --git a/tests/format-highlight.html b/tests/format-highlight.html index 58ca6a7..ec1ba42 100644 --- a/tests/format-highlight.html +++ b/tests/format-highlight.html @@ -1098,3 +1098,9 @@ throw; end end catch +--- +
BEGIN
+  FOR i IN 1..5 LOOP
+    DBMS_OUTPUT.PUT_LINE(i);
+  END LOOP;
+END;
diff --git a/tests/format.txt b/tests/format.txt index 74f4448..36b6311 100644 --- a/tests/format.txt +++ b/tests/format.txt @@ -1096,3 +1096,9 @@ else throw; end end catch +--- +BEGIN + FOR i IN 1..5 LOOP + DBMS_OUTPUT.PUT_LINE(i); + END LOOP; +END; diff --git a/tests/highlight.html b/tests/highlight.html index 9814a61..35231aa 100644 --- a/tests/highlight.html +++ b/tests/highlight.html @@ -380,3 +380,10 @@ throw; end end catch +--- +
BEGIN
+  FOR i IN 1..5
+  LOOP
+    DBMS_OUTPUT.PUT_LINE(i);
+  END LOOP;
+END;
diff --git a/tests/sql.sql b/tests/sql.sql index 9ff65dc..e4d7f49 100644 --- a/tests/sql.sql +++ b/tests/sql.sql @@ -380,3 +380,10 @@ begin catch throw; end end catch +--- +BEGIN + FOR i IN 1..5 + LOOP + DBMS_OUTPUT.PUT_LINE(i); + END LOOP; +END;