{"id":12127,"date":"2023-02-19T17:27:05","date_gmt":"2023-02-19T16:27:05","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=12127"},"modified":"2024-01-13T16:02:41","modified_gmt":"2024-01-13T15:02:41","slug":"islandsql-episode-3-lock-table","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/","title":{"rendered":"IslandSQL Episode 3: Lock Table"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>In the&nbsp;<a href=\"https:\/\/www.salvis.com\/blog\/2023\/02\/07\/islandsql-episode-2-all-dml-statements\/\">last episode<\/a>, we extended the IslandSQL grammar to cover all DML statements as a single lexer token. Now it&#8217;s time to handle the complete grammar for one DML statement. The simplest one is <code>lock table<\/code>. A good reason to start with it and lay the foundation for the other DML commands.<\/p>\n\n\n\n<p>The full source code is available on&nbsp;<a href=\"https:\/\/github.com\/IslandSQL\/IslandSQL\/tree\/v0.3.1\">GitHub<\/a>&nbsp;and the binaries on&nbsp;<a href=\"https:\/\/central.sonatype.com\/artifact\/ch.islandsql\/islandsql\/0.3.1\">Maven Central<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Grammars in SQL Scripts<\/h2>\n\n\n\n<p>When using SQL scripts, we work with several grammars. There is always more than one grammar involved. It depends on your use case how much more.<\/p>\n\n\n\n<p>The candidates when working with an Oracle Database 21c are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SQL*Plus<\/li>\n\n\n\n<li>SQLcl<\/li>\n\n\n\n<li>PGQL<\/li>\n\n\n\n<li>SQL<\/li>\n\n\n\n<li>PL\/SQL<\/li>\n\n\n\n<li>Java<\/li>\n\n\n\n<li>more hidden in strings and LOBs such as XML, XSLT, JSON, &#8230;<\/li>\n<\/ul>\n\n\n\n<p>The number of grammars is growing. For example, we expect JavaScript stored procedures in Oracle Database 23c.<\/p>\n\n\n\n<p>In the previous episodes, we have primarily dealt with SQL*Plus and SQL as a whole. Before we deal with a specific SQL statement such as <code>lock table<\/code>, we need to know where a SQL statement starts and where it ends. The start seems obvious, but the end? Is the fragment <code>SQL_END<\/code> correctly describing the end of a SQL statement?<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">1) ANTLR fragment SQL_END<\/span><span role=\"button\" tabindex=\"0\" data-code=\"fragment SQL_END:\n      EOF\n    | (';' [ \\t]* SINGLE_NL?)\n    | SLASH_END\n;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">fragment<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">SQL_END<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #4FC1FF\">EOF<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #CE9178\">&#39;;&#39;<\/span><span style=\"color: #D4D4D4\"> [ \\<\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">]* <\/span><span style=\"color: #4FC1FF\">SINGLE_NL<\/span><span style=\"color: #D4D4D4\">?)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">SLASH_END<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Where Does a SQL Statement End?<\/h2>\n\n\n\n<p>A common misconception is, that a SQL statement ends with a semicolon. This seems to be true when you only look at the syntax per statement in the Oracle Database documentation, but it is not. Here&#8217;s an example:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">2) Lock table in dynamic SQL<\/span><span role=\"button\" tabindex=\"0\" data-code=\"begin\n   execute immediate '\n      lock table dept in exclusive mode\n   ';\nend;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #DCDCAA\">execute immediate<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">      lock table dept in exclusive mode<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">   &#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The anonymous PL\/SQL block executes a dynamic <code>lock table<\/code> statement on line 3. Please note that the <code>lock table<\/code> statement starts with whitespace and ends with whitespace. We do not pass a semicolon as part of the <code>execute immediate<\/code> statement. This anonymous PL\/SQL block completes successfully when the connected user can lock <code>emp<\/code>.<\/p>\n\n\n\n<p>However, when we add a semicolon at the end of the <code>lock table<\/code> statement we get the following error:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">3) Error when using semicolon in dynamic SQL<\/span><span role=\"button\" tabindex=\"0\" data-code=\"Error starting at line : 1 in command -\nbegin\n   execute immediate '\n      lock table dept in exclusive mode;\n   ';\nend;\nError report -\nORA-00933: SQL command not properly ended\nORA-06512: at line 2\n00933. 00000 -  &quot;SQL command not properly ended&quot;\n*Cause:    \n*Action:\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Error starting at line : 1 in command -<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   execute immediate &#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      lock table dept in exclusive mode;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   &#39;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">end;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Error report -<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ORA-00933: SQL command not properly ended<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ORA-06512: at line 2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">00933. 00000 -  &quot;SQL command not properly ended&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">*Cause:    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">*Action:<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>It&#8217;s not allowed to terminate a SQL statement with a semicolon in dynamic SQL and therefore also when executing SQL via JDBC or ODBC.<\/p>\n\n\n\n<p>But what is the semicolon for? Well, it terminates a SQL statement within a SQL*Plus or SQLcl script. In SQL*Plus you can change the behaviour using the <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/sqpug\/SET-system-variable-summary.html#GUID-5D91A9A9-13A2-4F62-B02A-AD2F3AFF8BB7\">set sqlterminator<\/a> command.<\/p>\n\n\n\n<p>The following script works in SQL*Plus (but not in SQLcl, it&#8217;s a <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/sql-developer-command-line\/22.4\/sqcug\/list-unsupported-commands-and-features-sqlplus.html\">documented limitation<\/a>):<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">4) Using dollar sign instead of semicolon to terminate SQL statement<\/span><span role=\"button\" tabindex=\"0\" data-code=\"set sqlterminator $\nlock table dept in exclusive mode$\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">set<\/span><span style=\"color: #D4D4D4\"> sqlterminator $<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> dept <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode$<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The semicolon is the default terminator of SQL statements in SQL scripts. The semicolon is part of the SQL*Plus grammar but not part of the SQL grammar. However, it is more. It is also the only supported statement terminator in PL\/SQL as the following SQL*Plus script shows.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">5) Statement terminator in PL\/SQL<\/span><span role=\"button\" tabindex=\"0\" data-code=\"set sqlterminator $\nbegin\n   lock table dept in exclusive mode;\nend;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">set<\/span><span style=\"color: #D4D4D4\"> sqlterminator $<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">lock<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> dept <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">exclusive<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">mode<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The semicolon on line 4 terminates the anonymous PL\/SQL block. It&#8217;s part of the PL\/SQL grammar. The final slash is not part of the anonymous PL\/SQL block. It is an alternative to the <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/sqpug\/RUN.html#GUID-C0504161-EFF9-4AF0-9F59-074F17B0CB85\">SQL*Plus run<\/a> command. It sends the buffer (the anonymous PL\/SQL block) to the database server.<\/p>\n\n\n\n<p>By the way, the Oracle Database documentation explains why it uses a semicolon in its grammar. Here is the corresponding quote:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Note: SQL statements are terminated differently in different programming environments. This documentation set uses the default SQL*Plus character, the semicolon (;).<br \/>&#8212; <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/sqlrf\/Lexical-Conventions.html\">Lexical Conventions, SQL Language Reference. Oracle Datase 21c<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>Yes, the semicolon is part of the SQL*Plus grammar. There is no common sequence of characters for identifying the end of an SQL statement.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Are We Going to Do Now?<\/h2>\n\n\n\n<p>I initially wanted to use <a href=\"https:\/\/github.com\/antlr\/antlr4\/blob\/master\/doc\/lexer-rules.md#lexical-modes\">ANTLR modes<\/a> to handle the complete grammar of chosen statements. However, ANTLR modes require that you can identify the start and the end of a mode. For the <code>lock mode<\/code> statement, the start is the <code>lock<\/code> keyword and the end is the <code>SQL_END<\/code> fragment as we used before. We could also use just the semicolon to determine the end. While this works for the <code>lock table<\/code> statement, it will cause some problems when trying to integrate the PL\/SQL grammar.<\/p>\n\n\n\n<p>How do we find out whether a semicolon belongs to a PL\/SQL statement or to an SQL statement? Is this possible in the lexer? Well, I think it&#8217;s possible by doing some semantic predicate acrobatics, but I don&#8217;t think it&#8217;s sensible.<\/p>\n\n\n\n<p>Another approach is to use two lexers. The first one, extracting the relevant statement in the scope of the IslandSQL grammar. And the second lexer processes only the extracted statements. The parser uses the token stream from the second lexer. Perfect. However, we want to keep the original positions (line\/column) of the tokens in scope. They are important for navigating to the right place in the code. How do we do that?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Keep Hidden Tokens as Whitespace<\/h2>\n\n\n\n<p>The idea is to replace all non-whitespace characters in hidden tokens with a space. This way the number of lines and the position in the line of all relevant tokens stay the same. The total number of characters is also the same (the number of bytes might change when multibyte characters are replaced).<\/p>\n\n\n\n<p>Here&#8217;s an example.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">6) Original SQL script<\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/* ===========================================\n * ignore multiline comment\n * =========================================== *\/\nselect * from dual;\n\nrem ignore remark: select * from dual;\n\n-- ignore single line comment\nlock table dept in exclusive mode;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/* ===========================================<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\"> * ignore multiline comment<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\"> * =========================================== *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> dual;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">rem <\/span><span style=\"color: #569CD6\">ignore<\/span><span style=\"color: #D4D4D4\"> remark: <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> dual;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">-- ignore single line comment<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> dept <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>After the transformation, the script should look like this.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">7) Transformed SQL script<\/span><span role=\"button\" tabindex=\"0\" data-code=\"..............................................\n...........................\n.................................................\nselect * from dual;\n\n......................................\n\n.............................\nlock table dept in exclusive mode;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">..............................................<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">...........................<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">.................................................<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> dual;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">......................................<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">.............................<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> dept <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Please note that a dot(<code>.<\/code>) represents a replaced character. Read a dot as a space.<\/p>\n\n\n\n<p>We can use this converted script as input for the second lexer.<\/p>\n\n\n\n<p>The implementation is relatively easy.&nbsp;I renamed the original lexer to <code>IslandSqlScopeLexer<\/code> und used this code for the transformation:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">8) getScopeText() method<\/span><span role=\"button\" tabindex=\"0\" data-code=\"static public String getScopeText(CommonTokenStream tokenStream) {\n    TokenStreamRewriter rewriter = new TokenStreamRewriter(tokenStream);\n    tokenStream.fill();\n    tokenStream.getTokens().stream()\n            .filter(token -&gt; token.getChannel() == Token.HIDDEN_CHANNEL\n                    &amp;&amp; token.getType() != IslandSqlScopeLexer.WS)\n            .forEach(token -&gt; {\n                        StringBuilder sb = new StringBuilder();\n                        token.getText().codePoints().mapToObj(c -&gt; (char) c)\n                                .forEach(c -&gt; sb.append(c == '\\t' || c == '\\r' || c == '\\n' ? c : ' '));\n                        rewriter.replace(token, sb.toString());\n                    }\n            );\n    return rewriter.getText();\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">static<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">String<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">getScopeText<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">CommonTokenStream<\/span><span style=\"color: #D4D4D4\"> tokenStream) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4EC9B0\">TokenStreamRewriter<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">rewriter<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">TokenStreamRewriter<\/span><span style=\"color: #D4D4D4\">(tokenStream);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">tokenStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">fill<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">tokenStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getTokens<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">stream<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            .<\/span><span style=\"color: #DCDCAA\">filter<\/span><span style=\"color: #D4D4D4\">(token <\/span><span style=\"color: #569CD6\">-&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getChannel<\/span><span style=\"color: #D4D4D4\">() == <\/span><span style=\"color: #9CDCFE\">Token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">HIDDEN_CHANNEL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    &amp;&amp; <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getType<\/span><span style=\"color: #D4D4D4\">() != <\/span><span style=\"color: #9CDCFE\">IslandSqlScopeLexer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">WS<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            .<\/span><span style=\"color: #DCDCAA\">forEach<\/span><span style=\"color: #D4D4D4\">(token <\/span><span style=\"color: #569CD6\">-&gt;<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #4EC9B0\">StringBuilder<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sb<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">StringBuilder<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getText<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">codePoints<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">mapToObj<\/span><span style=\"color: #D4D4D4\">(c <\/span><span style=\"color: #569CD6\">-&gt;<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #4EC9B0\">char<\/span><span style=\"color: #D4D4D4\">) c)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                .<\/span><span style=\"color: #DCDCAA\">forEach<\/span><span style=\"color: #D4D4D4\">(c <\/span><span style=\"color: #569CD6\">-&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sb<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">append<\/span><span style=\"color: #D4D4D4\">(c == <\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D7BA7D\">\\t<\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D4D4D4\"> || c == <\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D7BA7D\">\\r<\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D4D4D4\"> || c == <\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">?<\/span><span style=\"color: #D4D4D4\"> c <\/span><span style=\"color: #C586C0\">:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39; &#39;<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #9CDCFE\">rewriter<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">replace<\/span><span style=\"color: #D4D4D4\">(token, <\/span><span style=\"color: #9CDCFE\">sb<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toString<\/span><span style=\"color: #D4D4D4\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">rewriter<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getText<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The method gets a token stream as input and returns the transformed text (SQL script).<\/p>\n\n\n\n<p>The ANTLR runtime comes with a <a href=\"https:\/\/www.antlr.org\/api\/Java\/org\/antlr\/v4\/runtime\/TokenStreamRewriter.html\">TokenStreamRewriter<\/a> that helps adding, deleting or changing tokens. We are only changing hidden tokens that are not of type whitespace. Tabs, carriage returns and line feeds are kept. Other characters are replaced by a space.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The New Lexer<\/h2>\n\n\n\n<p>After the preprocessing of the original input, we can concentrate on the islands. The sea is represented as a whitespace. This simplifies the logic of the lexer.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(3 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">9) IslandSqlLexer.g4: based on https:\/\/github.com\/IslandSQL\/IslandSQL\/tree\/v0.3.1\/<\/span><span role=\"button\" tabindex=\"0\" data-code=\"lexer grammar IslandSqlLexer;\n\noptions {\n    superClass=IslandSqlLexerBase;\n    caseInsensitive = true;\n}\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Fragments to name expressions and reduce code duplication\n\/*----------------------------------------------------------------------------*\/\n\nfragment SINGLE_NL: '\\r'? '\\n';\nfragment COMMENT_OR_WS: ML_COMMENT|SL_COMMENT|WS;\nfragment SQL_TEXT: (ML_COMMENT|SL_COMMENT|STRING|.);\nfragment SLASH_END: SINGLE_NL WS* '\/' [ \\t]* (EOF|SINGLE_NL);\nfragment PLSQL_DECLARATION_END: ';'? [ \\t]* (EOF|SLASH_END);\nfragment SQL_END:\n      EOF\n    | (';' [ \\t]* SINGLE_NL?)\n    | SLASH_END\n;\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Hidden tokens\n\/*----------------------------------------------------------------------------*\/\n\nWS: [ \\t\\r\\n]+ -&gt; channel(HIDDEN);\nML_COMMENT: '\/*' .*? '*\/' -&gt; channel(HIDDEN);\nSL_COMMENT: '--' .*? (EOF|SINGLE_NL) -&gt; channel(HIDDEN);\nCONDITIONAL_COMPILATION_DIRECTIVE: '$if' .*? '$end' -&gt; channel(HIDDEN);\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Keywords\n\/*----------------------------------------------------------------------------*\/\n\nK_EXCLUSIVE: 'exclusive';\nK_FOR: 'for';\nK_IN: 'in';\nK_LOCK: 'lock';\nK_MODE: 'mode';\nK_NOWAIT: 'nowait';\nK_PARTITION: 'partition';\nK_ROW: 'row';\nK_SHARE: 'share';\nK_SUBPARTITION: 'subpartition';\nK_TABLE: 'table';\nK_UPDATE: 'update';\nK_WAIT: 'wait';\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Special characters\n\/*----------------------------------------------------------------------------*\/\n\nAT_SIGN: '@';\nCLOSE_PAREN: ')';\nCOMMA: ',';\nDOT: '.';\nOPEN_PAREN: '(';\nSEMI: ';';\nSLASH: '\/';\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Data types\n\/*----------------------------------------------------------------------------*\/\n\nSTRING:\n    'n'?\n    (\n          (['] .*? ['])+\n        | ('q' ['] '[' .*? ']' ['])\n        | ('q' ['] '(' .*? ')' ['])\n        | ('q' ['] '{' .*? '}' ['])\n        | ('q' ['] '<' .*? '&gt;' ['])\n        | ('q' ['] . {saveQuoteDelimiter1()}? .+? . ['] {checkQuoteDelimiter2()}?)\n    )\n;\n\nINT: [0-9]+;\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Identifier\n\/*----------------------------------------------------------------------------*\/\n\nQUOTED_ID: '&quot;' .*? '&quot;' ('&quot;' .*? '&quot;')*;\nID: [\\p{Alpha}] [_$#0-9\\p{Alpha}]*;\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Islands of interest as single tokens\n\/*----------------------------------------------------------------------------*\/\n\nCALL:\n    'call' COMMENT_OR_WS+ SQL_TEXT+? SQL_END\n;\n\nDELETE:\n    'delete' COMMENT_OR_WS+ SQL_TEXT+? SQL_END\n;\n\nEXPLAIN_PLAN:\n    'explain' COMMENT_OR_WS+ 'plan' COMMENT_OR_WS+ SQL_TEXT+? SQL_END\n;\n\nINSERT:\n    'insert' COMMENT_OR_WS+ SQL_TEXT+? SQL_END\n;\n\nMERGE:\n    'merge' COMMENT_OR_WS+ SQL_TEXT+? SQL_END\n;\n\nUPDATE:\n    'update' COMMENT_OR_WS+ SQL_TEXT+? 'set' COMMENT_OR_WS+ SQL_TEXT+? SQL_END\n;\n\nSELECT:\n    (\n          ('with' COMMENT_OR_WS+ ('function'|'procedure') SQL_TEXT+? PLSQL_DECLARATION_END)\n        | ('with' COMMENT_OR_WS+ SQL_TEXT+? SQL_END)\n        | (('(' COMMENT_OR_WS*)* 'select' COMMENT_OR_WS SQL_TEXT+? SQL_END)\n    )\n;\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Any other token\n\/*----------------------------------------------------------------------------*\/\n\nANY_OTHER: . -&gt; channel(HIDDEN);\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">lexer<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">grammar<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">IslandSqlLexer<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">options<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">superClass<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">IslandSqlLexerBase<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">caseInsensitive<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Fragments to name expressions and reduce code duplication<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">fragment<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">SINGLE_NL<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D7BA7D\">\\r<\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">fragment<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">ML_COMMENT<\/span><span style=\"color: #D4D4D4\">|<\/span><span style=\"color: #4FC1FF\">SL_COMMENT<\/span><span style=\"color: #D4D4D4\">|<\/span><span style=\"color: #4FC1FF\">WS<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">fragment<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">: (<\/span><span style=\"color: #4FC1FF\">ML_COMMENT<\/span><span style=\"color: #D4D4D4\">|<\/span><span style=\"color: #4FC1FF\">SL_COMMENT<\/span><span style=\"color: #D4D4D4\">|<\/span><span style=\"color: #4FC1FF\">STRING<\/span><span style=\"color: #D4D4D4\">|.);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">fragment<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">SLASH_END<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">SINGLE_NL<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">WS<\/span><span style=\"color: #D4D4D4\">* <\/span><span style=\"color: #CE9178\">&#39;\/&#39;<\/span><span style=\"color: #D4D4D4\"> [ \\<\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">]* (<\/span><span style=\"color: #4FC1FF\">EOF<\/span><span style=\"color: #D4D4D4\">|<\/span><span style=\"color: #4FC1FF\">SINGLE_NL<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">fragment<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">PLSQL_DECLARATION_END<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;;&#39;<\/span><span style=\"color: #D4D4D4\">? [ \\<\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">]* (<\/span><span style=\"color: #4FC1FF\">EOF<\/span><span style=\"color: #D4D4D4\">|<\/span><span style=\"color: #4FC1FF\">SLASH_END<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">fragment<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #4FC1FF\">EOF<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #CE9178\">&#39;;&#39;<\/span><span style=\"color: #D4D4D4\"> [ \\<\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">]* <\/span><span style=\"color: #4FC1FF\">SINGLE_NL<\/span><span style=\"color: #D4D4D4\">?)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">SLASH_END<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Hidden tokens<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">WS<\/span><span style=\"color: #D4D4D4\">: [ \\<\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">\\<\/span><span style=\"color: #9CDCFE\">r<\/span><span style=\"color: #D4D4D4\">\\<\/span><span style=\"color: #9CDCFE\">n<\/span><span style=\"color: #D4D4D4\">]+ -&gt; <\/span><span style=\"color: #DCDCAA\">channel<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">HIDDEN<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">ML_COMMENT<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;\/*&#39;<\/span><span style=\"color: #D4D4D4\"> .*? <\/span><span style=\"color: #CE9178\">&#39;*\/&#39;<\/span><span style=\"color: #D4D4D4\"> -&gt; <\/span><span style=\"color: #DCDCAA\">channel<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">HIDDEN<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">SL_COMMENT<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;--&#39;<\/span><span style=\"color: #D4D4D4\"> .*? (<\/span><span style=\"color: #4FC1FF\">EOF<\/span><span style=\"color: #D4D4D4\">|<\/span><span style=\"color: #4FC1FF\">SINGLE_NL<\/span><span style=\"color: #D4D4D4\">) -&gt; <\/span><span style=\"color: #DCDCAA\">channel<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">HIDDEN<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">CONDITIONAL_COMPILATION_DIRECTIVE<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;$if&#39;<\/span><span style=\"color: #D4D4D4\"> .*? <\/span><span style=\"color: #CE9178\">&#39;$end&#39;<\/span><span style=\"color: #D4D4D4\"> -&gt; <\/span><span style=\"color: #DCDCAA\">channel<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">HIDDEN<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Keywords<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_EXCLUSIVE<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;exclusive&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_FOR<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;for&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_IN<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;in&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_LOCK<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;lock&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_MODE<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;mode&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_NOWAIT<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;nowait&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_PARTITION<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;partition&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_ROW<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;row&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_SHARE<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;share&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_SUBPARTITION<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;subpartition&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_TABLE<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;table&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_UPDATE<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;update&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">K_WAIT<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;wait&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Special characters<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">AT_SIGN<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;@&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">CLOSE_PAREN<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;)&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">COMMA<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;,&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">DOT<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;.&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">OPEN_PAREN<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;(&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">SEMI<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;;&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">SLASH<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;\/&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Data types<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">STRING<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&#39;n&#39;<\/span><span style=\"color: #D4D4D4\">?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          ([<\/span><span style=\"color: #CE9178\">&#39;] .*? [&#39;<\/span><span style=\"color: #D4D4D4\">])+<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        | (<\/span><span style=\"color: #CE9178\">&#39;q&#39;<\/span><span style=\"color: #D4D4D4\"> [<\/span><span style=\"color: #CE9178\">&#39;] &#39;<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #CE9178\">&#39; .*? &#39;<\/span><span style=\"color: #D4D4D4\">]<\/span><span style=\"color: #CE9178\">&#39; [&#39;<\/span><span style=\"color: #D4D4D4\">])<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        | (<\/span><span style=\"color: #CE9178\">&#39;q&#39;<\/span><span style=\"color: #D4D4D4\"> [<\/span><span style=\"color: #CE9178\">&#39;] &#39;<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39; .*? &#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><span style=\"color: #CE9178\">&#39; [&#39;<\/span><span style=\"color: #D4D4D4\">])<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        | (<\/span><span style=\"color: #CE9178\">&#39;q&#39;<\/span><span style=\"color: #D4D4D4\"> [<\/span><span style=\"color: #CE9178\">&#39;] &#39;<\/span><span style=\"color: #D4D4D4\">{<\/span><span style=\"color: #CE9178\">&#39; .*? &#39;<\/span><span style=\"color: #D4D4D4\">}<\/span><span style=\"color: #CE9178\">&#39; [&#39;<\/span><span style=\"color: #D4D4D4\">])<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        | (<\/span><span style=\"color: #CE9178\">&#39;q&#39;<\/span><span style=\"color: #D4D4D4\"> [<\/span><span style=\"color: #CE9178\">&#39;] &#39;<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #CE9178\">&#39; .*? &#39;<\/span><span style=\"color: #D4D4D4\">&gt;<\/span><span style=\"color: #CE9178\">&#39; [&#39;<\/span><span style=\"color: #D4D4D4\">])<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        | (<\/span><span style=\"color: #CE9178\">&#39;q&#39;<\/span><span style=\"color: #D4D4D4\"> [<\/span><span style=\"color: #CE9178\">&#39;] . {saveQuoteDelimiter1()}? .+? . [&#39;<\/span><span style=\"color: #D4D4D4\">] {<\/span><span style=\"color: #DCDCAA\">checkQuoteDelimiter2<\/span><span style=\"color: #D4D4D4\">()}?)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">INT<\/span><span style=\"color: #D4D4D4\">: [<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #B5CEA8\">9<\/span><span style=\"color: #D4D4D4\">]+;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Identifier<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">QUOTED_ID<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&#39;&quot;&#39;<\/span><span style=\"color: #D4D4D4\"> .*? <\/span><span style=\"color: #CE9178\">&#39;&quot;&#39;<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #CE9178\">&#39;&quot;&#39;<\/span><span style=\"color: #D4D4D4\"> .*? <\/span><span style=\"color: #CE9178\">&#39;&quot;&#39;<\/span><span style=\"color: #D4D4D4\">)*;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">ID<\/span><span style=\"color: #D4D4D4\">: [\\<\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">{<\/span><span style=\"color: #9CDCFE\">Alpha<\/span><span style=\"color: #D4D4D4\">}] [<\/span><span style=\"color: #9CDCFE\">_$<\/span><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #B5CEA8\">9<\/span><span style=\"color: #D4D4D4\">\\<\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">{<\/span><span style=\"color: #9CDCFE\">Alpha<\/span><span style=\"color: #D4D4D4\">}]*;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Islands of interest as single tokens<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">CALL<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&#39;call&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">DELETE<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&#39;delete&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">EXPLAIN_PLAN<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&#39;explain&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #CE9178\">&#39;plan&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">INSERT<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&#39;insert&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">MERGE<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&#39;merge&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">UPDATE<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&#39;update&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #CE9178\">&#39;set&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">SELECT<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          (<\/span><span style=\"color: #CE9178\">&#39;with&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ (<\/span><span style=\"color: #CE9178\">&#39;function&#39;<\/span><span style=\"color: #D4D4D4\">|<\/span><span style=\"color: #CE9178\">&#39;procedure&#39;<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">PLSQL_DECLARATION_END<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        | (<\/span><span style=\"color: #CE9178\">&#39;with&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">+ <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        | ((<\/span><span style=\"color: #CE9178\">&#39;(&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\">*)* <\/span><span style=\"color: #CE9178\">&#39;select&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">COMMENT_OR_WS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">SQL_TEXT<\/span><span style=\"color: #D4D4D4\">+? <\/span><span style=\"color: #4FC1FF\">SQL_END<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Any other token<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4FC1FF\">ANY_OTHER<\/span><span style=\"color: #D4D4D4\">: . -&gt; <\/span><span style=\"color: #DCDCAA\">channel<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">HIDDEN<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Options<\/h3>\n\n\n\n<p>The options are the same as in <code>IslandSqlScopeLexer<\/code>. We need the superclass <code>IslandSqlLexerBase<\/code> only in the <code>STRING<\/code> rule to handle all quote identifiers supported by the Oracle Database.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fragments<\/h3>\n\n\n\n<p>We moved the fragments section to the top. The fragments <code>CONTINUE_LINE<\/code>, <code>SQLPLUS_TEXT<\/code> and <code> SQLPLUS_END<\/code> are not required in this lexer. They are used in <code>IslandSqlLexerBase<\/code> to identify SQL*Plus commands as hidden tokens.<\/p>\n\n\n\n<p>Since we replaced all SQL*Plus commands with whitespace there is no need to handle SQL*Plus commands in this lexer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hidden Tokens<\/h3>\n\n\n\n<p>In this section, we define the tokens that we do not need in the parser. Therefore we place them on the hidden channel.<\/p>\n\n\n\n<p>Wait, weren&#8217;t the hidden tokens replaced by whitespace? Yes, but only those that were not part of other tokens. However, the statements in scope (represented as a single token in <code>IslandSqlScopeLexer<\/code>) contain whitespace characters and maybe also comments or even conditional compilation directives (e.g. in plsql_declarations of a <code>select statement<\/code>). At the current stage of the grammar, the <code>CONDITIONAL_COMPILATION_DIRECTIVE<\/code> is de facto unused. We will need it (or some adequate replacement) once we are going to implement the <code>select<\/code> statement or other statements containing PL\/SQL code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Keywords<\/h3>\n\n\n\n<p>It&#8217;s a good practice to define a rule for each token. This way we can control the names of the constants generated by ANTLR. We prefix the keywords with a <code>K_<\/code> to distinguish them from other rules\/tokens. These keywords can also be used as identifiers in various contexts. At the current stage of the grammar, this section contains only the keywords used in the <code>lock table<\/code> statement of the Oracle Database 21c.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Special Characters<\/h3>\n\n\n\n<p>The <code>lock table<\/code> statement uses these special characters.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Data Types<\/h3>\n\n\n\n<p>The <code>STRING<\/code> rule is the same as in <code>IslandSqlScopeLexer<\/code>. It is a complete definition of a <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/sqlrf\/Literals.html#GUID-1824CBAA-6E16-4921-B2A6-112FB02248DA\">text literal<\/a>. The <code>INT<\/code> rule is new. It defines an unsigned integer.<\/p>\n\n\n\n<p>In a future version of the grammar, we will need to support all <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/sqlrf\/Literals.html#GUID-F521FBA0-FFED-4079-ABC4-9052218B3FD5\">numeric literals<\/a>. And of course also <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/sqlrf\/Literals.html#GUID-8F4B3F82-8821-4071-84D6-FBBA21C05AC1\">date literals<\/a> and <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/sqlrf\/Literals.html#GUID-DC8D1DAD-7D04-45EA-9546-82810CD09A1B\">interval literals<\/a>. We will split the implementation between the lexer and the parser. That will be a bit tricky. For now, let&#8217;s keep it simple. &#8211; An unsigned integer works in most cases.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Identifier<\/h3>\n\n\n\n<p>In the lexer, we define two types of identifiers. Quoted and nonquoted Identifiers. See also <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/Database-Object-Names-and-Qualifiers.html#GUID-75337742-67FD-4EC0-985F-741C93D918DA\">Database Object Naming Rules<\/a>. See also my blog post regarding unnecessary <a href=\"https:\/\/www.salvis.com\/blog\/2022\/10\/11\/quoted-identifiers-joelkallmanday\/\">quoted identifiers<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Islands of Interest as Single Token<\/h3>\n\n\n\n<p>This is the same list of rules as in <code>IslandSqlScopeLexer<\/code>. The only rule that is missing is <code>LOCK_TABLE<\/code> since we are tokenizing this SQL statement completely.<\/p>\n\n\n\n<p>Please note that the <code>UPDATE<\/code> rule includes a <code>set<\/code> keyword. This is necessary because the keyword <code>update<\/code>&nbsp; is also part of the <code>lock table<\/code> statement. Without this change, a lock table emp in share update mode nowait; statement would be partly identified as <code>update<\/code> statement (<code>update mode nowait;<\/code>).<\/p>\n\n\n\n<p>The final version of the lexer will not contain statements as single tokens.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Any Other Token<\/h3>\n\n\n\n<p>As in <code>IslandSqlScopeLexer<\/code> we put any other character on the hidden channel. This suppresses some errors in the parser. For example, we can insert a euro sign (<code>\u20ac<\/code>) or a pound sign (<code>\u00a3<\/code>) almost anywhere in the code without causing an error.<\/p>\n\n\n\n<p>In future versions of the lexer, we will put the <code>ANY_OTHER<\/code> token on the <code>DEFAULT_CHANNEL<\/code> to avoid this kind of error suppression.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Parser Changes<\/h2>\n\n\n\n<p>The changes to the previous version of the parser are highlighted.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(3 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">10) IslandSqlParser.g4: based on https:\/\/github.com\/IslandSQL\/IslandSQL\/tree\/v0.3.1\/<\/span><span role=\"button\" tabindex=\"0\" data-code=\"parser grammar IslandSqlParser;\n\noptions {\n    tokenVocab=IslandSqlLexer;\n}\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Start rule\n\/*----------------------------------------------------------------------------*\/\n\nfile: dmlStatement* EOF;\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Data Manipulation Language\n\/*----------------------------------------------------------------------------*\/\n\ndmlStatement:\n      callStatement\n    | deleteStatement\n    | explainPlanStatement\n    | insertStatement\n    | lockTableStatement\n    | mergeStatement\n    | selectStatement\n    | updateStatement\n;\n\ncallStatement: CALL;\ndeleteStatement: DELETE;\nexplainPlanStatement: EXPLAIN_PLAN;\ninsertStatement: INSERT;\nmergeStatement: MERGE;\nupdateStatement: UPDATE;\nselectStatement: SELECT;\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Lock table\n\/*----------------------------------------------------------------------------*\/\n\nlockTableStatement:\n    stmt=lockTableStatementUnterminated sqlEnd\n;\n\nlockTableStatementUnterminated:\n    K_LOCK K_TABLE objects+=lockTableObject (COMMA objects+=lockTableObject)*\n        K_IN lockmode=lockMode K_MODE waitOption=lockTableWaitOption?\n;\n\nlockTableObject:\n    (schema=sqlName DOT)? table=sqlName\n        (\n              partitionExtensionClause\n            | (AT_SIGN dblink=qualifiedName)\n        )?\n;\n\npartitionExtensionClause:\n      (K_PARTITION OPEN_PAREN name=sqlName CLOSE_PAREN)             # partition\n    | (K_PARTITION K_FOR OPEN_PAREN\n        (keys+=expression (COMMA keys+=expression)*) CLOSE_PAREN)   # partitionKeys\n    | (K_SUBPARTITION OPEN_PAREN name=sqlName CLOSE_PAREN)          # subpartition\n    | (K_SUBPARTITION K_FOR OPEN_PAREN\n        (keys+=expression (COMMA keys+=expression)*) CLOSE_PAREN)   # subpartitionKeys\n;\n\n\/\/ TODO: complete according https:\/\/github.com\/IslandSQL\/IslandSQL\/issues\/11\nexpression:\n      STRING        # stringLiteral\n    | INT           # integerLiteral\n    | sqlName       # sqlNameExpression\n;\n\nlockMode:\n      (K_ROW K_SHARE)               # rowShare\n    | (K_ROW K_EXCLUSIVE)           # rowExclusive\n    | (K_SHARE K_UPDATE)            # shareUpdate\n    | (K_SHARE)                     # share\n    | (K_SHARE K_ROW K_EXCLUSIVE)   # shareRowExclusive\n    | (K_EXCLUSIVE)                 # exclusive\n;\n\nlockTableWaitOption:\n      K_NOWAIT                  # nowait\n    | K_WAIT waitSeconds=INT    # wait\n;\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ Identifiers\n\/*----------------------------------------------------------------------------*\/\n\nkeywordAsId:\n      K_EXCLUSIVE\n    | K_FOR\n    | K_IN\n    | K_LOCK\n    | K_MODE\n    | K_NOWAIT\n    | K_PARTITION\n    | K_ROW\n    | K_SHARE\n    | K_SUBPARTITION\n    | K_TABLE\n    | K_UPDATE\n    | K_WAIT\n;\n\nunquotedId:\n      ID\n    | keywordAsId\n;\n\nsqlName:\n      unquotedId\n    | QUOTED_ID\n;\n\nqualifiedName:\n\tsqlName (DOT sqlName)*\n;\n\n\/*----------------------------------------------------------------------------*\/\n\/\/ SQL statement end, slash accepted without preceeding newline\n\/*----------------------------------------------------------------------------*\/\n\nsqlEnd: EOF | SEMI | SLASH;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">parser<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">grammar<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">IslandSqlParser<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">options<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">tokenVocab<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">IslandSqlLexer<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Start rule<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">file<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #9CDCFE\">dmlStatement<\/span><span style=\"color: #D4D4D4\">* <\/span><span style=\"color: #4FC1FF\">EOF<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/\/ Data Manipulation Language<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">dmlStatement<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">callStatement<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">deleteStatement<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">explainPlanStatement<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">insertStatement<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">lockTableStatement<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">mergeStatement<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">selectStatement<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">updateStatement<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">callStatement<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">CALL<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">deleteStatement<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">DELETE<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">explainPlanStatement<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">EXPLAIN_PLAN<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">insertStatement<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">INSERT<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">mergeStatement<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">MERGE<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">updateStatement<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">UPDATE<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">selectStatement<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">SELECT<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/\/ Lock table<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">lockTableStatement<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">stmt<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">lockTableStatementUnterminated<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sqlEnd<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">lockTableStatementUnterminated<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">K_LOCK<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_TABLE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">objects<\/span><span style=\"color: #D4D4D4\">+=<\/span><span style=\"color: #DCDCAA\">lockTableObject<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #4FC1FF\">COMMA<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">objects<\/span><span style=\"color: #D4D4D4\">+=<\/span><span style=\"color: #9CDCFE\">lockTableObject<\/span><span style=\"color: #D4D4D4\">)*<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #4FC1FF\">K_IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">lockmode<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">lockMode<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_MODE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">waitOption<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">lockTableWaitOption<\/span><span style=\"color: #D4D4D4\">?<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #9CDCFE\">lockTableObject<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    (<\/span><span style=\"color: #9CDCFE\">schema<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">sqlName<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">DOT<\/span><span style=\"color: #D4D4D4\">)? <\/span><span style=\"color: #9CDCFE\">table<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">sqlName<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">        (<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">              <\/span><span style=\"color: #9CDCFE\">partitionExtensionClause<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">            | (<\/span><span style=\"color: #4FC1FF\">AT_SIGN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">dblink<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">qualifiedName<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">        )?<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #9CDCFE\">partitionExtensionClause<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      (<\/span><span style=\"color: #4FC1FF\">K_PARTITION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">OPEN_PAREN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">name<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">sqlName<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">CLOSE_PAREN<\/span><span style=\"color: #D4D4D4\">)             # <\/span><span style=\"color: #9CDCFE\">partition<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #4FC1FF\">K_PARTITION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_FOR<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">OPEN_PAREN<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">        (<\/span><span style=\"color: #9CDCFE\">keys<\/span><span style=\"color: #D4D4D4\">+=<\/span><span style=\"color: #DCDCAA\">expression<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #4FC1FF\">COMMA<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">keys<\/span><span style=\"color: #D4D4D4\">+=<\/span><span style=\"color: #9CDCFE\">expression<\/span><span style=\"color: #D4D4D4\">)*) <\/span><span style=\"color: #4FC1FF\">CLOSE_PAREN<\/span><span style=\"color: #D4D4D4\">)   # <\/span><span style=\"color: #9CDCFE\">partitionKeys<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #4FC1FF\">K_SUBPARTITION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">OPEN_PAREN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">name<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #9CDCFE\">sqlName<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">CLOSE_PAREN<\/span><span style=\"color: #D4D4D4\">)          # <\/span><span style=\"color: #9CDCFE\">subpartition<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #4FC1FF\">K_SUBPARTITION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_FOR<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">OPEN_PAREN<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">        (<\/span><span style=\"color: #9CDCFE\">keys<\/span><span style=\"color: #D4D4D4\">+=<\/span><span style=\"color: #DCDCAA\">expression<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #4FC1FF\">COMMA<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">keys<\/span><span style=\"color: #D4D4D4\">+=<\/span><span style=\"color: #9CDCFE\">expression<\/span><span style=\"color: #D4D4D4\">)*) <\/span><span style=\"color: #4FC1FF\">CLOSE_PAREN<\/span><span style=\"color: #D4D4D4\">)   # <\/span><span style=\"color: #9CDCFE\">subpartitionKeys<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/\/ TODO: complete according https:\/\/github.com\/IslandSQL\/IslandSQL\/issues\/11<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #9CDCFE\">expression<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #4FC1FF\">STRING<\/span><span style=\"color: #D4D4D4\">        # <\/span><span style=\"color: #9CDCFE\">stringLiteral<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">INT<\/span><span style=\"color: #D4D4D4\">           # <\/span><span style=\"color: #9CDCFE\">integerLiteral<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">sqlName<\/span><span style=\"color: #D4D4D4\">       # <\/span><span style=\"color: #9CDCFE\">sqlNameExpression<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">lockMode<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      (<\/span><span style=\"color: #4FC1FF\">K_ROW<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_SHARE<\/span><span style=\"color: #D4D4D4\">)               # <\/span><span style=\"color: #9CDCFE\">rowShare<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #4FC1FF\">K_ROW<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_EXCLUSIVE<\/span><span style=\"color: #D4D4D4\">)           # <\/span><span style=\"color: #9CDCFE\">rowExclusive<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #4FC1FF\">K_SHARE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_UPDATE<\/span><span style=\"color: #D4D4D4\">)            # <\/span><span style=\"color: #9CDCFE\">shareUpdate<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #4FC1FF\">K_SHARE<\/span><span style=\"color: #D4D4D4\">)                     # <\/span><span style=\"color: #9CDCFE\">share<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #4FC1FF\">K_SHARE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_ROW<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">K_EXCLUSIVE<\/span><span style=\"color: #D4D4D4\">)   # <\/span><span style=\"color: #9CDCFE\">shareRowExclusive<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | (<\/span><span style=\"color: #4FC1FF\">K_EXCLUSIVE<\/span><span style=\"color: #D4D4D4\">)                 # <\/span><span style=\"color: #9CDCFE\">exclusive<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">lockTableWaitOption<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #4FC1FF\">K_NOWAIT<\/span><span style=\"color: #D4D4D4\">                  # <\/span><span style=\"color: #9CDCFE\">nowait<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_WAIT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">waitSeconds<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #4FC1FF\">INT<\/span><span style=\"color: #D4D4D4\">    # <\/span><span style=\"color: #9CDCFE\">wait<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/\/ Identifiers<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">keywordAsId<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #4FC1FF\">K_EXCLUSIVE<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_FOR<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_IN<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_LOCK<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_MODE<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_NOWAIT<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_PARTITION<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_ROW<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_SHARE<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_SUBPARTITION<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_TABLE<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_UPDATE<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">K_WAIT<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">unquotedId<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #4FC1FF\">ID<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #9CDCFE\">keywordAsId<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">sqlName<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">unquotedId<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    | <\/span><span style=\"color: #4FC1FF\">QUOTED_ID<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">qualifiedName<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #DCDCAA\">sqlName<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #4FC1FF\">DOT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sqlName<\/span><span style=\"color: #D4D4D4\">)*<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/\/ SQL statement end, slash accepted without preceeding newline<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">\/*----------------------------------------------------------------------------*\/<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">sqlEnd<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">EOF<\/span><span style=\"color: #D4D4D4\"> | <\/span><span style=\"color: #4FC1FF\">SEMI<\/span><span style=\"color: #D4D4D4\"> | <\/span><span style=\"color: #4FC1FF\">SLASH<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Data Manipulation Language<\/h3>\n\n\n\n<p>The only visible change in this section is the title. However, there is an important change regarding <code>lockTableStatement<\/code>.&nbsp; It&#8217;s not a simple rule referring to a lexer token anymore.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lock Table<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">lockTableStatement<\/h4>\n\n\n\n<p>On lines 40-42 we define the lockTableStatement. It starts with a lockTableStatementUnterminated and ends on sqlEnd. It contains the same number of characters as in the previous parser version. As a result, the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=phsalvisberg.islandsql\">extension for Visual Studio Code<\/a> finds the same <code>lock table<\/code> statements as before.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">lockTableStatementUnterminated<\/h4>\n\n\n\n<p>On lines 44-47 we define the <code>lockTableStatementUnterminated<\/code> according to the <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/sqlrf\/LOCK-TABLE.html\">Oracle Database SQL Language Reference 21c<\/a> with the following three fields:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>objects<\/code> as an array of <code>lockTableObjects<\/code> with at least one entry<\/li>\n\n\n\n<li><code>lockMode<\/code> that refers to a mandatory instance of <code>lockMode<\/code><\/li>\n\n\n\n<li>&nbsp;<code>waitOption<\/code> that refers to an optional instance of <code>lockTableWaitOption<\/code><\/li>\n<\/ul>\n\n\n\n<p>Based on that ANTLR generates a <code>IslandSqlParser<\/code> class with a nested class <code>LockTableStatementUnterminatedContext<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">11) Excerpt of IslandSqlParser.java generated by ANTLR<\/span><span role=\"button\" tabindex=\"0\" data-code=\"public class IslandSqlParser extends Parser {\n    ...\n    public static class LockTableStatementUnterminatedContext extends ParserRuleContext {\n        public LockTableObjectContext lockTableObject;\n        public List<LockTableObjectContext&gt; objects = new ArrayList<LockTableObjectContext&gt;();\n        public LockModeContext lockmode;\n        public LockTableWaitOptionContext waitOption;\n        ...\n    }\n    ...\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">IslandSqlParser<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">extends<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Parser<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">static<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">LockTableStatementUnterminatedContext<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">extends<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">ParserRuleContext<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">LockTableObjectContext<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">lockTableObject<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">List<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">LockTableObjectContext<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">objects<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">ArrayList<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">LockTableObjectContext<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">LockModeContext<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">lockmode<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">LockTableWaitOptionContext<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">waitOption<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        ...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The parser populates an instance of <code>LockTableStatementUnterminatedContext<\/code> according to the input. Interesting is, that there is a redundancy between <code>objects<\/code> and <code>lockTableObject<\/code>. The former contains all objects to be locked and the latter just the last one.<\/p>\n\n\n\n<p>Please note that the <code>lock table<\/code> statement ends on <code>mode<\/code> keyword or on <code>lockTableWaitOption<\/code> which can end on <code>wait<\/code> keyword or on an integer value.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">lockTableObject<\/h4>\n\n\n\n<p>The <code>lockTableObject<\/code> on lines 49-55 defines the following fields:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>schema<\/code>, optional refers to a <code>sqlName<\/code>identifier<\/li>\n\n\n\n<li><code>table<\/code>, mandatory refers to a <code>sqlName<\/code> identifier<\/li>\n\n\n\n<li><code>dblink<\/code>, optional refers to a <code>qualifiedName<\/code> identifier<\/li>\n<\/ul>\n\n\n\n<p>For the optional <code>partitionExtensionClause<\/code> no field is defined. I think this is wrong and should be fixed in a future version. Nonetheless, it&#8217;s possible to find it in the generic <code>children<\/code> field.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">partitionExtensionClause<\/h4>\n\n\n\n<p>The <code>partitionExtensionClause<\/code> on lines 57-64 defines four partition variants. Each variant has a label &#8211; the token after the hash sign (<code>#<\/code>). Based on these labels ANTLR generates the following subclasses of the class <code>PartitionExtensionClauseContext<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>PartitionContext<\/code><\/li>\n\n\n\n<li><code>SubpartitionKeysContext<\/code><\/li>\n\n\n\n<li><code>SubpartitionContext<\/code><\/li>\n\n\n\n<li><code>SubpartitionKeysContext<\/code><\/li>\n<\/ul>\n\n\n\n<p>It&#8217;s another good practice to define a label for an alternative. It simplifies finding classes in the parse tree using listeners or visitors and makes the parse tree more expressive. The next screenshots highlight the partition alternative in the ANTLR IntelliJ plugin. The ANTLR interpreter does not generate classes. Instead, it shows the alternative after a colon. Either the ordinal number or the label, if available. However, it&#8217;s still a good representation of what you can expect at runtime of the parser generated by ANTLR.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/antr-preview-lock-table-sales-partition.png\"><img loading=\"lazy\" decoding=\"async\" width=\"701\" height=\"642\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/antr-preview-lock-table-sales-partition.png\" alt=\"\" class=\"wp-image-12207\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/antr-preview-lock-table-sales-partition.png 701w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/antr-preview-lock-table-sales-partition-300x275.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/antr-preview-lock-table-sales-partition-159x146.png 159w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/antr-preview-lock-table-sales-partition-50x46.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/antr-preview-lock-table-sales-partition-82x75.png 82w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/antr-preview-lock-table-sales-partition-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, 701px\" \/><\/a><\/figure>\n\n\n\n<p>The alternatives for <code>partitionKeys<\/code> and <code>subpartitionKeys<\/code> define a field named <code>keys<\/code> with an array of <code>expression<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">expression<\/h4>\n\n\n\n<p>When working on a grammar you feel more than once like <a href=\"https:\/\/www.youtube.com\/watch?v=AbSehcT19u0\">Hal fixing a light bulb<\/a>. An expression is probably the most extensive part of the SQL grammar. It&#8217;s huge. It contains subqueries and a subquery is basically a <code>select<\/code> statement and a select statement uses conditions&#8230; Once we&#8217;ve done that, implementing the rest of the IslandSQL grammar is a piece of cake.<\/p>\n\n\n\n<p>Therefore I decided to postpone the complete implementation and define just the bare minimum on lines 66-71. Making the <code>lock table<\/code> statement work for partition keys based on integers, strings and variable names. &#8211; No datetime expressions yet.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">lockMode<\/h4>\n\n\n\n<p>The Oracle Database allows 6 different lock modes. You find the valid alternatives on lines 74-79.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">lockTableWaitOption<\/h4>\n\n\n\n<p>By default, the Oracle Database waits indefinitely for the lock. You can override this behaviour by one of the alternatives defined on lines 83-84.<\/p>\n\n\n\n<p>The grammar defines <code>waitSeconds<\/code> as an <code>INT<\/code>. That matches the definition in the SQL Language Reference of the Oracle Database 21c.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock_table.gif\"><img wpfc-lazyload-disable=\"true\" loading=\"lazy\" decoding=\"async\" width=\"631\" height=\"235\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock_table.gif\" alt=\"\" class=\"wp-image-12194\"\/><\/a><\/figure>\n\n\n\n<p>However, what is the meaning of <code>integer<\/code> in this case? Can we use an integer variable in PL\/SQL? Can we use a decimal literal that can be converted to an integer such as <code>10.<\/code>? Or can we use scientific notations such as <code>1e2<\/code> or even <code>1e2d<\/code>? To know that, we have to try it out.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">12) Integer tests in SQL*Plus<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SQL&gt; declare\n  2     co_wait_in_seconds constant integer := 10;\n  3  begin\n  4     lock table emp in exclusive mode wait co_wait_in_seconds;\n  5  end;\n  6  \/\n   lock table emp in exclusive mode wait co_wait_in_seconds;\n                                         *\nERROR at line 4:\nORA-06550: line 4, column 42:\nPL\/SQL: ORA-30005: missing or invalid WAIT interval\nORA-06550: line 4, column 4:\nPL\/SQL: SQL Statement ignored\n\nSQL&gt; lock table emp in exclusive mode wait 10.;\n\nTable(s) Locked.\n\nSQL&gt; lock table emp in exclusive mode wait 1e2;\n\nTable(s) Locked.\n\nSQL&gt; lock table emp in exclusive mode wait 1e2d;\nlock table emp in exclusive mode wait 1e2d\n                                      *\nERROR at line 1:\nORA-30005: missing or invalid WAIT interval\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #569CD6\">declare<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">     co_wait_in_seconds constant <\/span><span style=\"color: #569CD6\">integer<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">     lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> emp <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode wait co_wait_in_seconds;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">  \/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> emp <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode wait co_wait_in_seconds;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                         *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ERROR <\/span><span style=\"color: #569CD6\">at<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">line<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ORA-<\/span><span style=\"color: #B5CEA8\">06550<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">line<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, column <\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">PL\/<\/span><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">: ORA-<\/span><span style=\"color: #B5CEA8\">30005<\/span><span style=\"color: #D4D4D4\">: missing <\/span><span style=\"color: #569CD6\">or<\/span><span style=\"color: #D4D4D4\"> invalid WAIT interval<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ORA-<\/span><span style=\"color: #B5CEA8\">06550<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">line<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, column <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">PL\/<\/span><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">Statement<\/span><span style=\"color: #D4D4D4\"> ignored<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">&gt; lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> emp <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode wait <\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">.;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">Table<\/span><span style=\"color: #D4D4D4\">(s) Locked.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">&gt; lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> emp <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode wait 1e2;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">Table<\/span><span style=\"color: #D4D4D4\">(s) Locked.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">&gt; lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> emp <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode wait 1e2d;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">lock <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> emp <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> exclusive mode wait 1e2d<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                      *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ERROR <\/span><span style=\"color: #569CD6\">at<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">line<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ORA-<\/span><span style=\"color: #B5CEA8\">30005<\/span><span style=\"color: #D4D4D4\">: missing <\/span><span style=\"color: #569CD6\">or<\/span><span style=\"color: #D4D4D4\"> invalid WAIT interval<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>So, we cannot use a variable\/constant. But the scientific notation works and a decimal literal can be converted to an integer as long as we do not use the scientific notation.<\/p>\n\n\n\n<p>I consider it a bug that we cannot use a variable\/constant for the time to wait in PL\/SQL. Especially since we can use <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/21\/lnpls\/plsql-language-fundamentals.html#GUID-6CDF1EB6-913D-48E7-AFDA-DB4DE45209CE\">static expressions<\/a> in PL\/SQL in various places, e.g. to define the size of <code>varchar2<\/code> variable (since 12.2). It does not make sense to enforce the use of dynamic SQL to handle dynamic wait times in PL\/SQL.<\/p>\n\n\n\n<p>I can imagine that a future version of the Oracle Database will lift this restriction in the <code>lock table<\/code> statement. It would be a small change. Maybe not even documented. Therefore it might be a good idea to change this part of the grammar and support a bit more.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Identifiers<\/h3>\n\n\n\n<p>The Oracle Database allows the use of keywords as identifiers in a lot of places. Therefore we should allow the use of keywords such as <code>lock<\/code> in the <code>lock table<\/code> statement&#8217;s the identifiers <code>schema<\/code>, <code>table<\/code> and <code>dblink<\/code>.&nbsp; For that, we created a rule named <code>keywordAsId<\/code> on lines 91-105 that covers all keywords.<\/p>\n\n\n\n<p>We defined <code>ID<\/code> in the lexer. It covers all identifiers. However, keywords have a higher priority in the lexer. Therefore we defined a new rule <code>unquotedId<\/code> that combines <code>ID<\/code> with <code>keywordAsId<\/code>.<\/p>\n\n\n\n<p>The rule <code>sqlName<\/code> on lines 112-115 combines <code>unquotedId<\/code> with the <code>QUOTED_ID<\/code> which we defined in the lexer.<\/p>\n\n\n\n<p>And finally, the rule qualifiedName on lines 117-119 covers the unbounded concatenation of <code>SqlName<\/code> with a dot. The concatenation is optional. So a <code>qualifiedName<\/code> could look 100% the same as a <code>sqlName<\/code>. We could remove the <code>schema<\/code> in the rule <code>lockTableObject<\/code> and use <code>qualifiedName<\/code> for <code>table<\/code> like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">lockTableObject:\n    table=qualifiedName\n        (\n              partitionExtensionClause\n            | (AT_SIGN dblink=qualifiedName)\n        )?\n;<\/pre>\n\n\n\n<p>This works and is a valid representation of the grammar. However, it&#8217;s less expressive. For <code>dblink<\/code> we must use <code>qualifiedName<\/code>.&nbsp; There is no predefined, binding naming scheme that covers the number of segments for a database link name.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">SQL Statement End<\/h3>\n\n\n\n<p>The <code>sqlEnd<\/code> rule on the last line 125 defines the end of a SQL statement in SQL*Plus\/SQLcl. We do not handle whitespace here as in the <code>IslandSqlScopeLexer<\/code>. As a result a <code>lock table<\/code> statement could be terminated with a slash on the same line. This might need some rework in a future version of the grammar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Syntax Errors<\/h2>\n\n\n\n<p>Let&#8217;s look at a <code>lock table<\/code>&nbsp; statement that uses an invalid lock mode.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SQL&gt; lock table dept in access exclusive mode;\nlock table dept in access exclusive mode\n                          *\nERROR at line 1:\nORA-01737: valid modes: [ROW] SHARE, [[SHARE] ROW] EXCLUSIVE, SHARE UPDATE<\/pre>\n\n\n\n<p>This is a valid lock mode in <a href=\"https:\/\/www.postgresql.org\/docs\/15\/sql-lock.html\">PostgresSQL 15<\/a>. Besides the lock mode, the syntax of the lock table statement is different to the one in the Oracle Database 21c in various places. However, it should not be too complicated to define a grammar that can handle both syntaxes. We put this on the to-do list and focus on supporting the Oracle Database grammar first.<\/p>\n\n\n\n<p>However, how does our grammar deal with invalid SQL statements? &#8211; Here&#8217;s a screenshot of the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=phsalvisberg.islandsql\">extension for Visual Studio Code<\/a> showing some <code>lock table<\/code> statements.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1084\" height=\"436\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode.png\" alt=\"\" class=\"wp-image-12215\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode.png 1084w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode-300x121.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode-1024x412.png 1024w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode-768x309.png 768w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode-260x105.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode-50x20.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode-150x60.png 150w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/lock-table-problems-vscode-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, (max-width:1084px) 100vw, 1084px\" \/><\/a><\/figure>\n\n\n\n<p>You see the word <code>access<\/code> wavy underlined in red. On mouse over you get the details displayed in the <code>problems<\/code> panel. Furthermore, you see that <code>lock_table.sql<\/code> is displayed in red with a number <code>3<\/code> indicating that this file has three problems. And the outline view indicates problems by showing symbols in red.<\/p>\n\n\n\n<p>That&#8217;s the cool thing when using an IDE supporting <a href=\"https:\/\/microsoft.github.io\/language-server-protocol\/\">Micosoft&#8217;s Language Server Protocol<\/a>. We just have to provide the syntax errors and the visualization happens automatically by the IDE in a standardized manner.<\/p>\n\n\n\n<p>Right now the parser provides only syntax errors. However, it is relatively easy to implement a linter based on this grammar and provide the results as warnings. For example for <code>lock table<\/code> statements without a <code>waitOption<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Outlook<\/h2>\n\n\n\n<p>We have not succeeded in fully supporting the <code>lock table<\/code> statement. Some cases cannot yet be successfully parsed. I would like to address that. To do this, we need to look a bit more at literals and expressions before we deal with more DML statements.<\/p>\n\n\n\n<p>Another topic is the support of more SQL dialects.&nbsp; I&#8217;d like to support PostgreSQL. Maybe it is a good time to start as soon as a DML statement is fully covered.<\/p>\n\n\n\n<p>Stay tuned.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In the&nbsp;last episode, we extended the IslandSQL grammar to cover all DML statements as a single lexer token. Now it&#8217;s time to handle the complete grammar for one DML statement. The simplest one is lock table. A good reason to start with it and lay the foundation for the other DML<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":12218,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[139,86,137,107,85,138],"class_list":["post-12127","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-antlr","tag-code-analysis","tag-islandsql","tag-java","tag-sql","tag-vscode"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>IslandSQL Episode 3: Lock Table - Philipp Salvisberg&#039;s Blog<\/title>\n<meta name=\"description\" content=\"In this blog post we define the complete grammar for the lock table statement. We keep the other DML statements as single tokens.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"IslandSQL Episode 3: Lock Table - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"In this blog post we define the complete grammar for the lock table statement. We keep the other DML statements as single tokens.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-19T16:27:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-13T15:02:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/IslandSQL3.png\" \/>\n\t<meta property=\"og:image:width\" content=\"500\" \/>\n\t<meta property=\"og:image:height\" content=\"500\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Philipp Salvisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:site\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Salvisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"IslandSQL Episode 3: Lock Table\",\"datePublished\":\"2023-02-19T16:27:05+00:00\",\"dateModified\":\"2024-01-13T15:02:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/\"},\"wordCount\":2839,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/02\\\/IslandSQL3.png\",\"keywords\":[\"ANTLR\",\"Code Analysis\",\"IslandSQL\",\"Java\",\"SQL\",\"VSCode\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/\",\"name\":\"IslandSQL Episode 3: Lock Table - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/02\\\/IslandSQL3.png\",\"datePublished\":\"2023-02-19T16:27:05+00:00\",\"dateModified\":\"2024-01-13T15:02:41+00:00\",\"description\":\"In this blog post we define the complete grammar for the lock table statement. We keep the other DML statements as single tokens.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/02\\\/IslandSQL3.png\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/02\\\/IslandSQL3.png\",\"width\":500,\"height\":500},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2023\\\/02\\\/19\\\/islandsql-episode-3-lock-table\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"IslandSQL Episode 3: Lock Table\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\",\"name\":\"Philipp Salvisberg&#039;s Blog\",\"description\":\"Database-centric development\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\",\"name\":\"Philipp Salvisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"width\":400,\"height\":400,\"caption\":\"Philipp Salvisberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\"},\"sameAs\":[\"http:\\\/\\\/www.salvis.com\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"IslandSQL Episode 3: Lock Table - Philipp Salvisberg&#039;s Blog","description":"In this blog post we define the complete grammar for the lock table statement. We keep the other DML statements as single tokens.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/","og_locale":"en_US","og_type":"article","og_title":"IslandSQL Episode 3: Lock Table - Philipp Salvisberg&#039;s Blog","og_description":"In this blog post we define the complete grammar for the lock table statement. We keep the other DML statements as single tokens.","og_url":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2023-02-19T16:27:05+00:00","article_modified_time":"2024-01-13T15:02:41+00:00","og_image":[{"width":500,"height":500,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/IslandSQL3.png","type":"image\/png"}],"author":"Philipp Salvisberg","twitter_card":"summary_large_image","twitter_creator":"@phsalvisberg","twitter_site":"@phsalvisberg","twitter_misc":{"Written by":"Philipp Salvisberg","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"IslandSQL Episode 3: Lock Table","datePublished":"2023-02-19T16:27:05+00:00","dateModified":"2024-01-13T15:02:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/"},"wordCount":2839,"commentCount":1,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/IslandSQL3.png","keywords":["ANTLR","Code Analysis","IslandSQL","Java","SQL","VSCode"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/","url":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/","name":"IslandSQL Episode 3: Lock Table - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/IslandSQL3.png","datePublished":"2023-02-19T16:27:05+00:00","dateModified":"2024-01-13T15:02:41+00:00","description":"In this blog post we define the complete grammar for the lock table statement. We keep the other DML statements as single tokens.","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/IslandSQL3.png","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2023\/02\/IslandSQL3.png","width":500,"height":500},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2023\/02\/19\/islandsql-episode-3-lock-table\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"IslandSQL Episode 3: Lock Table"}]},{"@type":"WebSite","@id":"https:\/\/www.salvis.com\/blog\/#website","url":"https:\/\/www.salvis.com\/blog\/","name":"Philipp Salvisberg&#039;s Blog","description":"Database-centric development","publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.salvis.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515","name":"Philipp Salvisberg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","width":400,"height":400,"caption":"Philipp Salvisberg"},"logo":{"@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg"},"sameAs":["http:\/\/www.salvis.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/12127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/comments?post=12127"}],"version-history":[{"count":93,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/12127\/revisions"}],"predecessor-version":[{"id":13191,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/12127\/revisions\/13191"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/12218"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=12127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=12127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=12127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}