Skip to content

Commit 1f0027a

Browse files
rebeliceclaude
andauthored
fix: BYT-8268 - require CALL keyword at SQL level and fix related grammar issues (#38)
This commit addresses BYT-8268 by making the CALL keyword mandatory at SQL statement level while keeping it optional at PL/SQL block level, and fixes grammar issues that were previously hidden by optional CALL. Changes: 1. Split call_statement into two rules: - sql_call_statement: CALL keyword MANDATORY (SQL level) - plsql_call_statement: CALL keyword OPTIONAL (PL/SQL block level) 2. Support method chaining in CALL statements: - CALL obj_constructor(...).method(...) INTO :var 3. Fix commit_statement to allow WRITE clause independently: - Previously: COMMIT [COMMENT 'text' [WRITE ...]] - Now: COMMIT [COMMENT 'text'] [WRITE ...] 4. Fix link_name to support qualified database links: - Now supports: @schema.linkname or @linkname.domain 5. Fix system_action to support multi-word actions: - Added: ADMINISTER KEY MANAGEMENT - Added: General patterns for 2-3 word actions Why these changes: - The optional CALL keyword caused keywords like CASCADE to be misidentified as procedure calls, leading to incorrect SQL splitting - At SQL level, Oracle requires CALL keyword - At PL/SQL block level, Oracle allows direct procedure invocation - The fixes to COMMIT, link_name, and system_action address grammar deficiencies that were previously hidden by the optional CALL Tests: All 600+ parser tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <[email protected]>
1 parent e7e9eb8 commit 1f0027a

File tree

7 files changed

+26444
-25733
lines changed

7 files changed

+26444
-25733
lines changed

plsql/PlSqlParser.g4

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ unit_statement
178178
| truncate_cluster
179179
| truncate_table
180180
| unified_auditing
181-
| call_statement // put call statement after all statements.
181+
| sql_call_statement // put call statement after all statements. BYT-8268: SQL level requires CALL keyword
182182
;
183183

184184
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-DISKGROUP.html
@@ -1335,11 +1335,16 @@ object_action
13351335
| RENAME
13361336
;
13371337

1338+
// BYT-8268: Added support for multi-word system actions
1339+
// Note: Complete list varies by Oracle version, query AUDITABLE_SYSTEM_ACTIONS view for full list
13381340
system_action
1339-
: id_expression // SELECT name FROM AUDITABLE_SYSTEM_ACTIONS WHERE component = 'Standard';
1341+
: ADMINISTER KEY MANAGEMENT // TDE operations
13401342
| (CREATE | ALTER | DROP) JAVA
13411343
| LOCK TABLE
13421344
| (READ | WRITE | EXECUTE) DIRECTORY
1345+
| id_expression id_expression id_expression // 3-word actions (ALTER AUDIT POLICY, etc.)
1346+
| id_expression id_expression // 2-word actions (ALTER ASSEMBLY, CREATE TABLE, etc.)
1347+
| id_expression // Single-word actions
13431348
;
13441349

13451350
component_actions
@@ -5607,7 +5612,7 @@ statement
56075612
| case_statement
56085613
| sql_statement
56095614
| pipe_row_statement
5610-
| call_statement // put call statement after others.
5615+
| plsql_call_statement // put call statement after others. BYT-8268: PL/SQL level allows optional CALL
56115616
;
56125617

56135618
swallow_to_semi
@@ -5687,8 +5692,16 @@ return_statement
56875692
: RETURN expression?
56885693
;
56895694

5690-
call_statement
5691-
: CALL? routine_name function_argument? (INTO bind_variable)?
5695+
// BYT-8268: Split into two rules for different contexts
5696+
// SQL level: CALL keyword is MANDATORY to prevent misidentifying keywords like CASCADE as procedure calls
5697+
sql_call_statement
5698+
: CALL routine_name function_argument? ('.' id_expression function_argument?)* (INTO bind_variable)?
5699+
;
5700+
5701+
// PL/SQL block level: CALL keyword is OPTIONAL (standard PL/SQL allows direct procedure calls)
5702+
// Support method chaining: obj_constructor(...).method(...) or CALL obj_constructor(...).method(...)
5703+
plsql_call_statement
5704+
: CALL? routine_name function_argument? ('.' id_expression function_argument?)* (INTO bind_variable)?
56925705
;
56935706

56945707
pipe_row_statement
@@ -5790,10 +5803,11 @@ set_constraint_command
57905803

57915804
// https://docs.oracle.com/cd/E18283_01/server.112/e17118/statements_4010.htm#SQLRF01110
57925805
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/COMMIT.html
5806+
// BYT-8268: Fixed to allow WRITE clause independently, not just after COMMENT
5807+
// Correct Oracle syntax: COMMIT [WORK] [COMMENT 'text'] [WRITE [WAIT|NOWAIT] [IMMEDIATE|BATCH]] [FORCE...]
57935808
commit_statement
5794-
: COMMIT WORK?
5795-
( COMMENT CHAR_STRING write_clause?
5796-
| FORCE ( CHAR_STRING (',' numeric)?
5809+
: COMMIT WORK? (COMMENT CHAR_STRING)? write_clause?
5810+
( FORCE ( CHAR_STRING (',' numeric)?
57975811
| CORRUPT_XID CHAR_STRING
57985812
| CORRUPT_XID_ALL
57995813
)
@@ -6952,8 +6966,9 @@ collection_name
69526966
: identifier ('.' id_expression)?
69536967
;
69546968

6969+
// BYT-8268: Database link names can include domain qualifiers (e.g., linkname.domain)
69556970
link_name
6956-
: identifier
6971+
: identifier ('.' id_expression)*
69576972
;
69586973

69596974
column_name

plsql/plsql_lexer.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)