BBj SQL Engine Grammar Example

statement_list ::=
        statement:s1
      | statement_list SEMI_COLON statement:s2
      | error
      ;

statement ::=
        SELECT select_union:s
      | UPDATE update:u
      | INSERT insert:i
      | INSERT INTO insert:i
      | REPLACE insert:i
      | REPLACE INTO insert:i
      | CREATE SEQUENCE create_sequence:c
      | DROP SEQUENCE drop_sequence:d
      | ALTER SEQUENCE alter_sequence:a
      | CREATE DATABASE create_database_legacy:db
      | CREATE DATABASE LEGACY create_database_legacy:db
      | CREATE DATABASE ENHANCED create_database_enhanced:db
      | DROP DATABASE drop_database:d
      | CREATE TABLE create_table:c
      | CREATE VIEW create_view:c with_check_option:o
      | CREATE INDEX create_index:c
      | CREATE FULLTEXT INDEX ON id_list:i2 OPEN_PAREN index_col_list:c CLOSE_PAREN
      | CREATE UNIQUE INDEX create_index:c
      | CREATE PROCEDURE create_procedure:p
      | ALTER PROCEDURE alter_procedure:p
      | CREATE TRIGGER create_trigger:t
      | DELETE del:d
      | DROP TABLE drop_table:d
      | DROP PROCEDURE drop_procedure:d
      | DROP TRIGGER drop_trigger:d
      | DROP VIEW drop_view:d
      | DROP INDEX drop_index:d
      | DROP FULLTEXT INDEX ON id_list:t
      | RENAME id_list:o TO id:n
      | GRANT privilege_list:p ON grant_object:o TO user_list:u with_grant_option:w
      | GRANT privilege_list:p ON grant_object:o TO id_list_for_revoke:role with_grant_option:w
      | GRANT id_list_for_revoke:r TO user_list:u with_grant_option:w
      | REVOKE grant_option_for:g privilege_list:p ON id_list_for_revoke:l FROM user_list:u revoke_qual:q
      | REVOKE grant_option_for:g id_list_for_revoke:r FROM user_list:u revoke_qual:q
      | REVOKE grant_option_for:g privilege_list:p ON id_list_for_revoke:l FROM id_list_for_revoke:r revoke_qual:q
      | CREATE ROLE id_list_for_revoke:l
      | DROP ROLE id_list_for_revoke:l
      | ALTER TABLE alter_table:a
      | ALTER TRIGGER alter_trigger:a
      | CLONE DATABASE clone_database:c
      | GET TABLE INFO FOR id_list:i
                  | GET TABLE INFO FOR id_list:i NO ATTRIBUTES
      | ANALYZE DATABASE
      | ANALYZE TABLE id_list:i
      | CALL id_list:p call_params:v
      | QUESTION EQ CALL id_list:p call_params:v
      | OPEN_CURLY CALL id_list:p call_params:v CLOSE_CURLY
      | OPEN_CURLY QUESTION EQ CALL id_list:p call_params:v CLOSE_CURLY
      | RECOVER id_list:l
      | BEGIN TRANSACTION
      | CREATE SAVEPOINT id:i
      | ROLLBACK id:i
      | ROLLBACK
      | COMMIT
      | SET READ_ONLY boolean_value:b
      | SET TRANSACTION_ISOLATION isolation:i
      ;

boolean_value ::=
                TRUE
                  | FALSE
      ;

isolation ::=
      READ_COMMITTED
      | READ_UNCOMMITTED
      | REPEATABLE_READ
      | SERIALIZABLE
      ;

call_params ::=
                                /* Nothing */
                  | OPEN_PAREN value_list:v CLOSE_PAREN
                  ;


top ::=
        /* Nothing */
      | TOP TYPE_INTEGER:i
      ;

limit_select ::=
        /* Nothing */
      | LIMIT TYPE_INTEGER:first COMMA TYPE_INTEGER:count
      ;

alter_table ::=
        id_list:l ADD COLUMN table_col_list:c
      | id_list:t ADD INDEX id_list:idx OPEN_PAREN index_col_list:c CLOSE_PAREN
      | id_list:l ADD COLUMN OPEN_PAREN table_col_list:c CLOSE_PAREN
      | id_list:l ADD table_col_list:c
      | id_list:l ADD OPEN_PAREN table_col_list:c CLOSE_PAREN
      | id_list:l WITH NOCHECK ADD table_col_list:c
      | id_list:l WITH NOCHECK ADD OPEN_PAREN table_col_list:c CLOSE_PAREN
      | id_list:l WITH CHECK ADD table_col_list:c
      | id_list:l WITH CHECK ADD OPEN_PAREN table_col_list:c CLOSE_PAREN
      | id_list:l RENAME COLUMN id:o TO id:n
      | id_list:l ALTER COLUMN table_col_list:c
      | id_list:l ALTER COLUMN OPEN_PAREN table_col_list:c CLOSE_PAREN
      | id_list:l ALTER table_col_list:c
      | id_list:l ALTER OPEN_PAREN table_col_list:c CLOSE_PAREN
      | id_list:l DROP COLUMN col_list:c
      | id_list:t DROP INDEX id_list:idx
      | id_list:l DROP col_list:c
      | id_list:l DROP CONSTRAINT id:i
      ;

alter_table_constraint ::=
      CONSTRAINT id:i alter_table_constraint_type:t
      | ADD CONSTRAINT id:i alter_table_constraint_type:t
      ;

alter_table_constraint_type ::=
        PRIMARY KEY OPEN_PAREN col_list:c CLOSE_PAREN
      | UNIQUE OPEN_PAREN col_list:c CLOSE_PAREN
      | FOREIGN KEY OPEN_PAREN col_list:r CLOSE_PAREN REFERENCES id_list:i references_col_list:l references_match:m references_on_clause:o deferred:d
      | FOREIGN KEY col_list:r REFERENCES id_list:i references_col_list:l references_match:m references_on_clause:o deferred:d
      ;

references_col_list ::=
      | OPEN_PAREN col_list:c CLOSE_PAREN
      ;

references_match ::=
      | MATCH FULL
      | MATCH PARTIAL
      ;

on_update ::=
        ON UPDATE CASCADE
      | ON UPDATE SET OP_NULL
      | ON UPDATE SET DEFAULT
      | ON UPDATE NO ACTION
      ;

on_delete ::=
        ON DELETE CASCADE
      | ON DELETE SET OP_NULL
      | ON DELETE SET DEFAULT
      | ON DELETE NO ACTION
                  ;

references_on_clause ::=
      | on_update:u
      | on_delete:d
      | on_update:u on_delete:d
      | on_delete:d on_update:u
      ;

deferred ::=
      | INITIALLY DEFERRED DEFERRABLE
      | INITIALLY DEFERRED NOT DEFERRABLE
      | INITIALLY IMMEDIATE DEFERRABLE
      | INITIALLY IMMEDIATE NOT DEFERRABLE
      | NOT DEFERRABLE INITIALLY DEFERRED
      | DEFERRABLE INITIALLY DEFERRED
      | NOT DEFERRABLE INITIALLY IMMEDIATE
      | DEFERRABLE INITIALLY IMMEDIATE
      ;

select_union ::=
        select:s
      | select:s UNION union_qual:q SELECT select_union:u
      ;

union_qual ::=
      | ALL
      ;

select ::=
        select_cols:c
      | select_cols:c FROM table_list:t where:w group_by:g having:h order_by:o limit_select:l for_update:f
      | select_cols:c INTO id_list:i FROM table_list:t where:w group_by:g having:h order_by:o limit_select:l
      ;

update ::=
        id_list_for_update:i SET set_list:s where:w
      | id_list_for_update:i SET set_list:s FROM table_list:t where:w
      ;

insert ::=
        id_list:i OPEN_PAREN col_list:c CLOSE_PAREN VALUES insert_values_list:v
      | id_list:i OPEN_PAREN col_list:c CLOSE_PAREN insert_values_list:v
      | id_list:i VALUES insert_values_list:v
      | id_list:i OPEN_PAREN col_list:c CLOSE_PAREN VALUES OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | id_list:i OPEN_PAREN col_list:c CLOSE_PAREN OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | id_list:i OPEN_PAREN col_list:c CLOSE_PAREN VALUES SELECT select_union:s
      | id_list:i OPEN_PAREN col_list:c CLOSE_PAREN SELECT select_union:s
      | id_list:i VALUES OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | id_list:i OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | id_list:i VALUES SELECT select_union:s
      | id_list:i SELECT select_union:s
      ;

insert_values_list ::=
        OPEN_PAREN value_list:v CLOSE_PAREN
      | insert_values_list:l COMMA OPEN_PAREN value_list:v CLOSE_PAREN
      ;

create_sequence ::=
                id_list:i cs_increment:inc cs_start_with:start cs_max_value:max cs_min_value:min cs_cycle:cycle cs_cache:cache
      ;

drop_sequence ::=
                                id_list:i
                  ;

cs_increment ::=
                    /* nothing */
                  | INCREMENT BY TYPE_INTEGER:i
                  ;

cs_start_with ::=
                    /* nothing */
                  | START WITH TYPE_INTEGER:i
                  ;

cs_max_value ::=
                    /* nothing */
                  | MAXVALUE TYPE_INTEGER:i
                  | NOMAXVALUE
                  ;

cs_min_value ::=
                    /* nothing */
                  | MINVALUE TYPE_INTEGER:i
                  | NOMINVALUE
                  ;

cs_cycle ::=
                    /* nothing */
                  | CYCLE
                  | NOCYCLE
                  ;

cs_cache ::=
                    /* nothing */
                  | CACHE TYPE_INTEGER:i
                  | NOCACHE
                  ;

create_table ::=
        id_list:i OPEN_PAREN table_col_list:c CLOSE_PAREN
      | id_list:i STRING:s OPEN_PAREN table_col_list:c CLOSE_PAREN
      | id_list:i OPEN_PAREN table_col_list:c CLOSE_PAREN create_table_supplement:supplement
      | id_list:i STRING:s OPEN_PAREN table_col_list:c CLOSE_PAREN create_table_supplement:supplement
      | id_list:i OPEN_PAREN table_col_list:c CLOSE_PAREN file_type:create_file_type
      | id_list:i STRING:s OPEN_PAREN table_col_list:c CLOSE_PAREN file_type:create_file_type
      | id_list:i OPEN_PAREN table_col_list:c CLOSE_PAREN file_type:create_file_type boolean_value:err_if_file
      | id_list:i STRING:s OPEN_PAREN table_col_list:c CLOSE_PAREN file_type:create_file_type boolean_value:err_if_file
      ;

create_trigger ::=
                                ON id_list:tableName trigger_type:tt STRING:filename CODE_BLOCK:code
                  | ON STRING:dataFile trigger_type:tt STRING:filename CODE_BLOCK:code
                  | ON id_list:tableName trigger_type:tt STRING:filename
                  | ON STRING:dataFile trigger_type:tt STRING:filename
                  | ON id_list:tableName trigger_type:tt CODE_BLOCK:code
                  | ON STRING:dataFile trigger_type:tt CODE_BLOCK:code
                  | ON id_list:tableName trigger_type:tt
                  | ON STRING:dataFile trigger_type:tt
                  ;

alter_trigger ::=
                                ON id_list:tableName trigger_type:tt STRING:filename trigger_state:state CODE_BLOCK:code
                  | ON STRING:dataFile trigger_type:tt STRING:filename trigger_state:state CODE_BLOCK:code
                  | ON id_list:tableName trigger_type:tt STRING:filename trigger_state:state
                  | ON STRING:dataFile trigger_type:tt STRING:filename trigger_state:state
                  | ON id_list:tableName trigger_type:tt trigger_state:state CODE_BLOCK:code
                  | ON STRING:dataFile trigger_type:tt trigger_state:state CODE_BLOCK:code
                  | ON id_list:tableName trigger_type:tt trigger_state:state
                  | ON STRING:dataFile trigger_type:tt trigger_state:state
                  | ON id_list:tableName trigger_state:state
                  | ON STRING:dataFile trigger_state:state
                  ;

drop_trigger ::=
                                ON id_list:tableName trigger_type:tt
                  | ON STRING:dataFile trigger_type:tt
                  | ON id_list:tableName trigger_type:tt DELETE
                  | ON STRING:dataFile trigger_type:tt DELETE
                  ;

trigger_state ::=
                                ENABLED
                  | DISABLED
                  ;

trigger_type ::=
                                BEFORE_READ
                  | AFTER_READ
                  | INSTEADOF_READ
                  | BEFORE_WRITE
                  | AFTER_WRITE
                  | INSTEADOF_WRITE
      | BEFORE_KEY
                  | AFTER_KEY
                  | INSTEADOF_KEY
                  | BEFORE_REMOVE
                  | AFTER_REMOVE
                  | INSTEADOF_REMOVE
                  | BEFORE_ERASE
                  | AFTER_ERASE
                  | INSTEADOF_ERASE
                  | BEFORE_OPEN
                  | AFTER_OPEN
                  | BEFORE_CLOSE
                  | AFTER_CLOSE
                  ;

create_procedure ::=
                                id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN proc_return_type:rt CODE_BLOCK:code
                  | id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN STRING:src STRING:cfg proc_return_type:rt CODE_BLOCK:code
                  | id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN STRING:src STRING:cfg proc_return_type:rt
                  | id_list:i proc_return_type:rt CODE_BLOCK:code
                  | id_list:i STRING:src STRING:cfg proc_return_type:rt CODE_BLOCK:code
                  | id_list:i STRING:src STRING:cfg proc_return_type:rt
                  | id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN STRING:src STRING:cfg proc_return_type:rt CODE_BLOCK:code STRING:description
                  ;

alter_procedure ::=
                                id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN proc_return_type:rt CODE_BLOCK:code STRING:description
                  | id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN STRING:src STRING:cfg proc_return_type:rt CODE_BLOCK:code STRING:description
                  | id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN proc_return_type:rt STRING:description
                  | id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN STRING:description
                  | id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN
                  | id_list:i proc_return_type:rt STRING:description
                  | id_list:i OPEN_PAREN proc_param_list:p CLOSE_PAREN STRING:src STRING:cfg proc_return_type:rt STRING:description
                  | id_list:i proc_return_type:rt CODE_BLOCK:code STRING:description
                  | id_list:i STRING:src STRING:cfg proc_return_type:rt CODE_BLOCK:code STRING:description
                  | id_list:i STRING:src STRING:cfg proc_return_type:rt STRING:description
                  ;

proc_return_type ::=
                                NONE:t
                  | RESULT_SET:t
                  | col_type:t
      | col_type:t OPEN_PAREN TYPE_INTEGER:ti CLOSE_PAREN
      | col_type:t OPEN_PAREN TYPE_INTEGER:t1 COMMA TYPE_INTEGER:t2 CLOSE_PAREN
      ;

proc_param_list ::=
      | proc_param:p
      | proc_param_list:l COMMA proc_param:p
      ;

proc_param ::=
                                id:i col_type:t param_dir:d
      | id:i col_type:t OPEN_PAREN TYPE_INTEGER:ti CLOSE_PAREN param_dir:d
      | id:i col_type:t OPEN_PAREN TYPE_INTEGER:t1 COMMA TYPE_INTEGER:t2 CLOSE_PAREN param_dir:d
      ;

param_dir ::=
                    IN
      | OUT
      | IN_OUT
      ;

create_view ::=
        id_list:i OPEN_PAREN col_list:c CLOSE_PAREN AS SELECT select_union:s
      | id_list:i AS SELECT select_union:s
      ;

with_check_option ::=
      | WITH CHECK OPTION
      | WITH LOCAL CHECK OPTION
      | WITH CASCADE CHECK OPTION
      ;

create_index ::=
        id_list:i1 ON id_list:i2 OPEN_PAREN index_col_list:c CLOSE_PAREN
      ;

del ::=
        FROM id_list:l where:w
      ;

drop_table ::=
        id_list:l
      | id_list:l CASCADE
      | id_list:l CASCADE CONSTRAINTS
      ;

drop_procedure ::=
        id_list:l
      | id_list:l DELETE
      ;

clone_database ::=
        id:new_db_name STRING:db_dir
      ;

drop_database ::=
                    STRING:db_name
                  | STRING:db_name DELETE
                  ;

create_database_legacy ::=
                    STRING:db_name STRING:data STRING:dictionary
                  | STRING:db_name STRING:data STRING:dictionary STRING:date_format STRING:date_suffix
                  | STRING:db_name STRING:data STRING:dictionary file_type:create_file_type
                  | STRING:db_name STRING:data STRING:dictionary file_type:create_file_type STRING:date_format STRING:date_suffix
                  ;
                 
create_database_enhanced ::=
        STRING:db_name STRING:data STRING:dictionary
      | STRING:db_name STRING:data STRING:dictionary STRING:date_format STRING:date_suffix
      | STRING:db_name STRING:data STRING:dictionary file_type:create_file_type
      | STRING:db_name STRING:data STRING:dictionary file_type:create_file_type STRING:date_format STRING:date_suffix
      ;

create_table_supplement ::=
                                AUTO_INCREMENT EQ TYPE_INTEGER:i
                  ;

file_type ::=
                                MKEYED
                  | XKEYED
                  | MKEYED_R
                  | XKEYED_R
                  | VKEYED
                  | ESQL
                  | DEFAULT
                  ;

drop_view ::=
        id_list:l
      ;

drop_index ::=
        id_list:l
      ;

index_col_list ::=
        index_col:c
      | index_col_list:l COMMA index_col:c
      ;

index_col ::=
        id_list:i asc:a
      ;

table_col_list ::=
        table_col:c
      | table_col_list:l COMMA table_col:c
      ;

table_col ::=
                   id:i col_type:t col_qual:q
      | id:i ENUM OPEN_PAREN value_list:e CLOSE_PAREN col_qual:q
      | id:i SET OPEN_PAREN value_list:e CLOSE_PAREN col_qual:q
      | id:i col_type:t OPEN_PAREN TYPE_INTEGER:ti CLOSE_PAREN col_qual:q
      | id:i col_type:t OPEN_PAREN TYPE_INTEGER:t1 COMMA TYPE_INTEGER:t2 CLOSE_PAREN col_qual:q
      | id:i AS expression:e
      | alter_table_constraint:c
      | PRIMARY OPEN_PAREN col_list:l CLOSE_PAREN
      | PRIMARY KEY OPEN_PAREN col_list:l CLOSE_PAREN
      | INDEX OPEN_PAREN col_list:l CLOSE_PAREN
      | KEY OPEN_PAREN col_list:l CLOSE_PAREN
      | PRIMARY KEY OPEN_PAREN col_list:l CLOSE_PAREN id_list:name
      | INDEX OPEN_PAREN col_list:l CLOSE_PAREN id_list:name
      | KEY OPEN_PAREN col_list:l CLOSE_PAREN id_list:name
      | KEY id_list:name OPEN_PAREN col_list:l CLOSE_PAREN
      | FULLTEXT KEY OPEN_PAREN col_list:l CLOSE_PAREN id_list:name
      | FULLTEXT KEY id_list:name OPEN_PAREN col_list:l CLOSE_PAREN
      | UNIQUE INDEX OPEN_PAREN col_list:l CLOSE_PAREN id_list:name
      | UNIQUE INDEX OPEN_PAREN col_list:l CLOSE_PAREN
      | FOREIGN OPEN_PAREN col_list:l CLOSE_PAREN
      | FOREIGN KEY OPEN_PAREN col_list:l CLOSE_PAREN
      | FOREIGN KEY OPEN_PAREN col_list:r CLOSE_PAREN REFERENCES id_list:i references_col_list:l references_match:m references_on_clause:o deferred:d
      | UNIQUE OPEN_PAREN col_list:l CLOSE_PAREN
      | UNIQUE KEY OPEN_PAREN col_list:l CLOSE_PAREN
      | UNIQUE KEY id_list:name OPEN_PAREN col_list:l CLOSE_PAREN
      | NOT OP_NULL OPEN_PAREN col_list:l CLOSE_PAREN
      | CHECK OPEN_PAREN boolean_exp:b CLOSE_PAREN
      ;


col_type ::=
        CHAR
      | CHARACTER
      | CHARACTER VARYING
      | CHAR VARYING
      | VARCHAR
      | TINYTEXT
      | MEDIUMTEXT
      | LONGVARCHAR
      | LONGTEXT
      | LONG VARCHAR
      | LONG CHAR VARYING
      | BINARY
      | BINARY VARYING
      | VARBINARY
      | LONGVARBINARY
      | BLOB
      | LONGBLOB
      | LONG VARBINARY
      | LONG BINARY VARYING
      | FLOAT
      | DOUBLE
      | REAL
      | BYTE
      | TINYINT
      | SMALLINT
      | INT
      | MEDIUMINT
      | INTEGER
      | BIGINT
      | UNSIGNED BYTE
      | UNSIGNED TINYINT
      | UNSIGNED SMALLINT
      | UNSIGNED INT
      | UNSIGNED INTEGER
      | UNSIGNED BIGINT
      | UNSIGNED REAL
      | UNSIGNED FLOAT
      | UNSIGNED DOUBLE
      | UNSIGNED DECIMAL
      | UNSIGNED NUMERIC
      | TIMESTAMP
      | TIME
      | BIT
      | BOOLEAN
      | DECIMAL
      | NUMERIC
      | DATE
      | DATETIME
      ;

col_qual ::=
      /* EMPTY */
      | col_val:v col_const_list:l
      | col_const_list:l col_val:v
      | col_const_list:l
      | col_val:v
      ;

col_val ::=
      DEFAULT OP_NULL
      | DEFAULT expression:e
      | AUTO_INCREMENT
      | AUTO_INCREMENT OPEN_PAREN TYPE_INTEGER:s COMMA TYPE_INTEGER:i CLOSE_PAREN
      | IDENTITY
      | IDENTITY OPEN_PAREN TYPE_INTEGER:s COMMA TYPE_INTEGER:i CLOSE_PAREN
      ;

col_const_list ::=
        col_const:c
        |  col_const_list:l col_const:c
        | col_const_list:l CONSTRAINT id:i col_const:c
        ;

col_const ::=
        PRIMARY
        | PRIMARY KEY
        | FOREIGN
        | FOREIGN KEY
        | INDEX
        | UNIQUE
        | UNIQUE KEY
        | NOT OP_NULL
        | OP_NULL
        | CHECK OPEN_PAREN boolean_exp:b CLOSE_PAREN
        | REFERENCES id_list:i references_col_list:l references_match:m references_on_clause:o /* deferred:d */
        ;

col_list ::=
        id_list:i
      | id_list:i OPEN_PAREN TYPE_INTEGER:l CLOSE_PAREN
      | col_list:c COMMA id_list:i
      ;

set_list ::=
        set:s
      | set_list:l COMMA set:s
      ;

set ::=
        id_list:i EQ OP_NULL
      | id_list:i EQ expression:e
      ;

select_cols ::=
        select_qual:q top:t select_list:l
      | select_qual:q top:t ASTERISK
      ;

select_qual ::=
        /* empty */
      | ALL
      | DISTINCT
      ;

select_list ::=
        select_item:i
      | select_list:l COMMA select_item:i
      ;

select_item ::=
        expression:e
      | expression:e id_for_select:i
      | expression:e AS id:i
      | expression:e AS OPEN_BRACE id:i CLOSE_BRACE
      | expression:e AS STRING:s
      | expression:e STRING:s
      ;

expression ::=
        expression:e PLUS times:t
      | expression:e MINUS times:t
      | times:t
      ;

times ::=
        times:t ASTERISK neg:n
      | times:t DIV neg:n
      | neg:n
      ;

neg ::=
        term:t
      | PLUS term:t
      | MINUS term:t
      ;

term ::=
        OPEN_PAREN expression:e CLOSE_PAREN
      | OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | db_item_ref:r
      | simple_term:t
      | scalar:s
      ;

db_item_ref ::=
        id_list_for_db_item:l
      | id_list_for_db_item:l OPEN_BRACE expression:e CLOSE_BRACE
      | id_for_func:i OPEN_PAREN func_qual:q func_arg:a CLOSE_PAREN
      | IFF OPEN_PAREN boolean_exp:b COMMA expression:e1 COMMA expression:e2 CLOSE_PAREN
      | CAST OPEN_PAREN expression:e1 AS id_for_cast:t1 CLOSE_PAREN
      | CONVERT OPEN_PAREN expression:e1 COMMA id:t1 CLOSE_PAREN
      | NULLIF OPEN_PAREN expression:e1 COMMA expression:e2 CLOSE_PAREN
      | COALESCE OPEN_PAREN func_arg:a CLOSE_PAREN
      | CASE when_list:w END
      | CASE when_list:w ELSE expression:e END
      | CASE expression:e1 when_expression_list:w END
      | CASE expression:e1 when_expression_list:w ELSE expression:e2 END
      ;

when_list ::=
      WHEN boolean_exp:b THEN expression:e
      | when_list:w WHEN boolean_exp:b THEN expression:e
      ;

when_expression_list ::=
      WHEN expression:e1 THEN expression:e2
      | when_expression_list:w WHEN expression:e1 THEN expression:e2
      ;

func_qual ::=
        /* empty */
      | ALL
      | DISTINCT
      ;

simple_term ::=
        real:r
      | HEX_VALUE:h
      | STRING:s
      | QUESTION
      | DATABASE OPEN_PAREN CLOSE_PAREN
      | DATABASE
      | USER OPEN_PAREN CLOSE_PAREN
      | USER
      | TRUE
      | FALSE
      | date:d
      ;

real ::=
        TYPE_INTEGER:i
      | TYPE_FLOAT:f
      | TYPE_BIG_INT:b
      ;

scalar ::=
        func:f
      ;

func ::=
        OPEN_CURLY FN fn:f CLOSE_CURLY
      ;

fn ::=
        id:i OPEN_PAREN func_arg:a CLOSE_PAREN
      ;

func_arg ::=
        /* empty */
      | ASTERISK
      | func_args:a
      ;

func_args ::=
        expression:e
      | func_args:a COMMA expression:e
      ;

date ::=
        OPEN_CURLY OP_D STRING:s CLOSE_CURLY
      | OPEN_CURLY OP_TS STRING:s CLOSE_CURLY
      | OPEN_CURLY OP_T STRING:s CLOSE_CURLY
      ;

for_update ::=
                                /* empty */
      |        FOR UPDATE
      | FOR UPDATE OF for_update_column_list:l
      |        FOR READ ONLY
      ;

for_update_column_list ::=
                id_list:l
                  | for_update_column_list:l1 COMMA id_list:l2
      ;

table_list ::=
        table_list_item:i
      | table_list:l COMMA table_list_item:i
      ;

table_list_item ::=
        table_ref:r
      | outer_join:o
      | oj:o
      | OPEN_PAREN table_list:o CLOSE_PAREN
      | OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | OPEN_PAREN SELECT select_union:s CLOSE_PAREN id_for_table:i
      | OPEN_PAREN SELECT select_union:s CLOSE_PAREN OPEN_BRACE id:i CLOSE_BRACE
      | OPEN_PAREN SELECT select_union:s CLOSE_PAREN AS id_for_table:i
      | OPEN_PAREN SELECT select_union:s CLOSE_PAREN AS OPEN_BRACE id:i CLOSE_BRACE
      | OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN
      | OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN id_for_table:i
      | OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN OPEN_BRACE id_for_table:i CLOSE_BRACE
      | OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN AS id_for_table:i
      | OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN AS OPEN_BRACE id_for_table:i CLOSE_BRACE
      ;

table_ref ::=
        id_list:l
      | id_list:l id_for_table:i
      | id_list:l OPEN_BRACE id:i CLOSE_BRACE
      | id_list:l AS id_for_table:i
      | id_list:l AS OPEN_BRACE id:i CLOSE_BRACE
      ;

outer_join ::=
        OPEN_CURLY OJ oj:o CLOSE_CURLY
      ;

oj ::=
        table_list_item:t1 LEFT OUTER JOIN table_list_item:t2 ON boolean_exp:b
      | table_list_item:t1 RIGHT OUTER JOIN table_list_item:t2 ON boolean_exp:b
      | table_list_item:t1 LEFT JOIN table_list_item:t2 ON boolean_exp:b
      | table_list_item:t1 RIGHT JOIN table_list_item:t2 ON boolean_exp:b
      | table_list_item:t1 FULL OUTER JOIN table_list_item:t2 ON boolean_exp:b
      | table_list_item:t1 FULL JOIN table_list_item:t2 ON boolean_exp:b
      | table_list_item:t1 INNER JOIN table_list_item:t2 ON boolean_exp:b
      ;

where ::=
        /* empty */
      | WHERE boolean_exp:b
      | WHERE CURRENT OF id:i
      ;

group_by ::=
        /* empty */
      | GROUP BY group_by_list:g
      ;

group_by_list ::=
        expression:e
      | group_by_list:g COMMA expression:e
      ;

having ::=
        /* empty */
      | HAVING boolean_exp:b
      ;

order_by ::=
        /* empty */
      | ORDER BY order_by_list:l
      ;

order_by_list ::=
        order_by_item:i
      | order_by_list:l COMMA order_by_item:i
      ;

order_by_item ::=
        expression:e asc:a
      ;

asc ::=
        /* empty */
      | ASC
      | DESC
      ;

boolean_exp ::=
        and:a
      | and:a OR boolean_exp:b
      ;

and ::=
        not:n
      | not:n AND and:a
      ;

not ::=
        comparison:c
      | NOT comparison:c
      ;

comparison ::=
        OPEN_PAREN boolean_exp:b CLOSE_PAREN
      | db_item_ref:r IS OP_NULL
      | db_item_ref:r IS NOT OP_NULL
      | expression:e1 LIKE expression:e2
      | expression:e1 NOT LIKE expression:e2
      | expression:e1 REGEXP expression:e2
      | expression:e1 NOT REGEXP expression:e2
      | expression:e IN OPEN_PAREN value_list:v CLOSE_PAREN
      | expression:e NOT IN OPEN_PAREN value_list:v CLOSE_PAREN
      | expression:e1 op:o expression:e2
      | expression:e1 op:o OPEN_PAREN boolean_exp:e2 CLOSE_PAREN
      | OPEN_PAREN boolean_exp:e1 CLOSE_PAREN op:o expression:e2
      | OPEN_PAREN boolean_exp:e1 CLOSE_PAREN op:o OPEN_PAREN boolean_exp:e2 CLOSE_PAREN
      | EXISTS OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | EXISTS OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN
      | expression:e op:o1 select_op:o2 OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | expression:e op:o1 select_op:o2 OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN
      | expression:e IN OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | expression:e NOT IN OPEN_PAREN SELECT select_union:s CLOSE_PAREN
      | expression:e IN OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN
      | expression:e NOT IN OPEN_PAREN CALL id_list:p call_params:v CLOSE_PAREN
      | expression:e1 BETWEEN expression:e2 AND expression:e3
      | expression:e1 NOT BETWEEN expression:e2 AND expression:e3
      ;

select_op ::=
        ALL
      | SOME
      | ANY
      ;

op ::=
        GREATER_THAN
      | GREATER_THAN_EQ
      | LESS_THAN
      | LESS_THAN_EQ
      | EQ
      | NOT_EQ
      ;

value_list ::=
        OP_NULL
      | expression:e
      | value_list:l COMMA OP_NULL
      | value_list:l COMMA expression:e
      ;
                 
privilege_list ::=
        privilege:p
      | privilege_list:l COMMA privilege:p
      ;

privilege ::=
        SELECT
      | UPDATE
      | INSERT
      | DELETE
      | CALL
      | CREATE TABLE
                  | CREATE VIEW
                  | CREATE SEQUENCE
                  | CREATE PROCEDURE
                  | CREATE TRIGGER
                  | ALTER TABLE
                  | ALTER VIEW
                  | ALTER SEQUENCE
                  | ALTER PROCEDURE
                  | ALTER TRIGGER
                  | CREATE ROLE
      | DROP TABLE
                  | DROP VIEW
                  | DROP SEQUENCE
                  | DROP PROCEDURE
                  | DROP TRIGGER
                  | DROP ROLE
      | REFERENCES
      | USAGE
      | ALL
      ;

grant_object ::=
        id_list_for_revoke:i
      | TABLE id_list:i
      | VIEW id_list:i
      | PROCEDURE id_list:i
      | TRIGGER id_list:i
      | SEQUENCE id_list:i
      | ROLE id_list:i
      | DOMAIN id_list:i
      | CHARACTER SET id_list:i
      | COLLATION id_list:i
      | TRANSLATION id_list:i
      | DATABASE
      ;

grant_option_for ::=
      | GRANT OPTION FOR
      ;

with_grant_option ::=
      | WITH GRANT OPTION
      ;

revoke_qual ::=
      | RESTRICT
      | CASCADE
      ;

user_list ::=
        STRING:u
      | user_list:l COMMA STRING:u
      ;

id_common ::=
        ID:i
      | NO
      | INFO
      | GET
      | RESULT_SET
      | BY
      | ASC
      | MAXVALUE
      | DESC
      | OJ
      | OUTER
      | JOIN
      | FN
      | OR
      | AND
      | OP_D
      | OP_TS
                  | OP_T
      | UPDATE
      | INSERT
      | REPLACE
      | VALUES
      | CREATE
      | CHAR
      | VARYING
      | VARCHAR
      | LONGVARCHAR
      | BINARY
      | VARBINARY
      | LONGVARBINARY
      | BLOB
      | LONGTEXT
      | FLOAT
      | DOUBLE
      | REAL
      | BYTE
      | SMALLINT
      | INT
      | INTEGER
      | UNSIGNED
      | DATETIME
      | TIMESTAMP
      | VIEW
      | DELETE
      | DROP
      | PRIMARY
      | FOREIGN
      | UNIQUE
      | BETWEEN
      | LONG
      | THEN
      | ELSE
      | END
      | CURRENT
      | OF
      | ACTION
      | PARTIAL
      | MATCH
      | IDENTITY
      | LEGACY
      | ENHANCED
      | AUTO_INCREMENT
      | BIGINT
      | TINYINT
      | BOOLEAN
      | TIME
      | READ
      | ONLY
      | RECOVER
      | NOCHECK
      | CHECK
      | BEGIN
      | TRANSACTION
      | SAVEPOINT
      | ROLLBACK
      | COMMIT
      | READ_ONLY
      | SEQUENCE
      ;

id_for_func ::=
        id_common:i
      | DATE
      | TABLE
      | AS
      | FROM
      | WHERE
      | HAVING
      | ORDER
      | LEFT
      | RIGHT
      | INNER
      | FULL
      | ON
      | GROUP
      | SET
      | UNION
      | INTO
      | KEY
      ;

id_for_db_item ::=
        id_for_func:i
      | IFF
      | CONVERT
      | CAST
      | NULLIF
      | COALESCE
      ;

id_for_table ::=
        id_common:i
      | TABLE
      | AS
      | FROM
      | ALL
      | SOME
      | DISTINCT
      | USER
      | NOT
      | IS
      | LIKE
      | REGEXP
      | IN
      | SELECT
      | OP_NULL
      | EXISTS
      | ANY
      | SET
      | INTO
                  | TRUE
      | FALSE
      ;

id_for_select ::=
        id_common:i
      | TABLE
      | WHERE
      | ALL
      | SOME
      | DISTINCT
      | USER
      | HAVING
      | ORDER
      | LEFT
      | RIGHT
      | INNER
      | FULL
      | ON
      | GROUP
      | NOT
      | IS
      | LIKE
      | REGEXP
      | IN
      | SELECT
      | OP_NULL
      | EXISTS
      | ANY
      | SET
      | IFF
      | CONVERT
      | CAST
      | NULLIF
      | COALESCE
      | CASE
      | WHEN
      | TRUE
      | FALSE
      ;

id_for_update ::=
        id_common:i
      | TABLE
      | AS
      | FROM
      | WHERE
      | ALL
      | SOME
      | DISTINCT
      | USER
      | HAVING
      | ORDER
      | LEFT
      | RIGHT
      | INNER
      | FULL
      | ON
      | GROUP
      | NOT
      | IS
      | LIKE
      | REGEXP
      | IN
      | SELECT
      | OP_NULL
      | EXISTS
      | ANY
      | UNION
      | IFF
      | CONVERT
      | CAST
      | NULLIF
      | COALESCE
      | CASE
      | WHEN
      | INTO
      | TRUE
      | FALSE
      ;

id ::=
        id_common:i
      | TABLE
      | AS
      | FROM
      | WHERE
      | ALL
      | SOME
      | DISTINCT
      | USER
      | HAVING
      | ORDER
      | LEFT
      | RIGHT
      | INNER
      | FULL
      | ON
      | GROUP
      | NOT
      | IS
      | LIKE
      | REGEXP
      | IN
      | OP_NULL
      | EXISTS
      | ANY
      | SET
      | UNION
      | IFF
      | CONVERT
      | CAST
      | NULLIF
      | COALESCE
      | CASE
      | WHEN
      | TRUE
      | FALSE
      ;

id_for_cast ::=
        id_common:i
      | NUMERIC
      | DECIMAL
      | BIT
      | INTO
      | TRUE
      | FALSE
      ;

id_for_revoke ::=
        id_common:i
      | INTO
      | TRUE
      | FALSE
      ;

id_list ::=
        id:i
      | OPEN_BRACE id:i CLOSE_BRACE
      | DATE
      | OPEN_BRACE DATE CLOSE_BRACE
      | id_list:l DOT DATE
      | id_list:l DOT OPEN_BRACE DATE CLOSE_BRACE
      | id_list:l DOT id:i
      | id_list:l DOT OPEN_BRACE id:i CLOSE_BRACE
      ;

id_list_for_db_item ::=
        id_for_db_item:i
      | OPEN_BRACE id:i CLOSE_BRACE
      | id_list_for_db_item:l DOT id_for_db_item:i
      | id_list_for_db_item:l DOT OPEN_BRACE id:i CLOSE_BRACE
      | id_list_for_db_item:l DOT ASTERISK
      ;

id_list_for_update ::=
        id_for_update:i
      | OPEN_BRACE id:i CLOSE_BRACE
      | id_list_for_update:l DOT id_for_update:i
      | id_list_for_update:l DOT OPEN_BRACE id:i CLOSE_BRACE
      ;

id_list_for_revoke ::=
        id_for_revoke:i
      | OPEN_BRACE id:i CLOSE_BRACE
      | id_list_for_revoke:l DOT id_for_revoke:i
      | id_list_for_revoke:l DOT OPEN_BRACE id:i CLOSE_BRACE
      ;