SQL Grammar Definitions

This page provides the formal Java CUP definitions of the SQL grammar used by BBj and PRO/5.

For more information about the BASIS SQL engine, see SQL — Grammar and SQL Grammar

statement_list

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

statement

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
  | EXPLAIN explain:e
  | CREATE INDEX create_index:c
  | CREATE FULLTEXT INDEX ON id_list:i2 OPEN_PAREN index_col_list:c CLOSE_PAREN
  | CREATE FULLTEXT INDEX ON id_list:i2 OPEN_PAREN index_col_list:c CLOSE_PAREN ANALYZER EQ STRING:analyzer STOPWORDS_LANG EQ STRING:stopwords
  | 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

boolean_value ::=
    TRUE
  | FALSE
  ;

isolation

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

call_params

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

top

top ::=
    | TOP TYPE_INTEGER:i
  ;

limit_select

limit_select ::=
    | LIMIT TYPE_INTEGER:first COMMA TYPE_INTEGER:count
  ;

alter_table

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

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

alter_table_constraint_type

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

references_col_list ::=
    | OPEN_PAREN col_list:c CLOSE_PAREN
  ;

references_match

references_match ::=
    | MATCH FULL
  | MATCH PARTIAL
  ;

on_update

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

on_delete

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

references_on_clause

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

deferred

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_union ::=
    select:s
  | select:s UNION union_qual:q SELECT select_union:u
  ;

union_qual

union_qual ::=
    | ALL
  ;

select

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

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

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

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

create_sequence

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

drop_sequence ::=
    id_list:i
  ;

cs_increment

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

cs_start_with

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

cs_max_value

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

cs_min_value

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

cs_cycle

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

cs_cache

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

create_table

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_and_mode:create_file_type
  | id_list:i STRING:s OPEN_PAREN table_col_list:c CLOSE_PAREN file_type_and_mode:create_file_type
  | id_list:i OPEN_PAREN table_col_list:c CLOSE_PAREN file_type_and_mode:create_file_type boolean_value:err_if_file
  | id_list:i STRING:s OPEN_PAREN table_col_list:c CLOSE_PAREN file_type_and_mode:create_file_type boolean_value:err_if_file
  ;

create_trigger

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

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

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

trigger_state ::=
    ENABLED
  | DISABLED
  ;

trigger_type

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

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

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

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_list ::=
    | proc_param:p
  | proc_param_list:l COMMA proc_param:p
  ;

proc_param

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

param_dir ::=
    IN
  | OUT
  | IN_OUT
  ;

explain

explain ::=
    SELECT select_union:s
  

create_view

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 CHECK OPTION
  | WITH LOCAL CHECK OPTION
  | WITH CASCADE CHECK OPTION
  ;

create_index

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

del

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

drop_table

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

drop_procedure

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

clone_database

clone_database ::=
    id:new_db_name STRING:db_dir
  ;

drop_database

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

create_database_legacy

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

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

create_table_supplement ::=
    AUTO_INCREMENT EQ TYPE_INTEGER:i
  ;

file_type_and_mode

file_type_and_mode ::=
    file_type:type
  | file_type:type COMMA MODE EQ STRING:m
  ;

file_type

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

drop_view

drop_view ::=
    id_list:l
  ;

drop_index

drop_index ::=
    id_list:l
  ;

index_col_list

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

index_col

index_col ::=
    id_list:i asc:a
  ;

table_col_list

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

table_col

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

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

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

col_val

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_list ::=
    col_const:c
  |  col_const_list:l col_const:c
  | col_const_list:l CONSTRAINT id:i col_const:c
  ;

col_const

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

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_list ::=
    set:s
  | set_list:l COMMA set:s
  ;

set

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

select_cols

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

select_qual

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

select_list

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

select_item

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 ::=
    expression:e PLUS times:t
  | expression:e MINUS times:t
  | times:t
  ;

times

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

neg

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

term

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

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
  | CAST OPEN_PAREN OP_NULL AS id_for_cast:t1 CLOSE_PAREN
  | CONVERT OPEN_PAREN expression:e1 COMMA id:t1 CLOSE_PAREN
  | CONVERT OPEN_PAREN OP_NULL COMMA id:t1 CLOSE_PAREN
  | NULLIF OPEN_PAREN expression:e1 COMMA expression:e2 CLOSE_PAREN
  | NULLIF OPEN_PAREN OP_NULL 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_list ::=
    WHEN boolean_exp:b THEN expression:e
  | when_list:w WHEN boolean_exp:b THEN expression:e
  ;

when_expression_list

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

func_qual

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

simple_term

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

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

scalar

scalar ::=
    func:f
  ;

func

func ::=
    OPEN_CURLY FN fn:f CLOSE_CURLY
  ;

fn

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

func_arg

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

func_args

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

date

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

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

for_update_column_list

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

table_list

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

table_list_item

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

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

outer_join ::=
    OPEN_CURLY OJ oj:o CLOSE_CURLY
  ;

oj

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

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

group_by

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

group_by_list

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

having

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

order_by

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

order_by_list

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

order_by_item

order_by_item ::=
    expression:e asc:a
  ;

asc

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

boolean_exp

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

and

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

not

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

comparison

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

select_op ::=
    ALL
  | SOME
  | ANY
  ;

op

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

value_list

value_list ::=
    OP_NULL
  | expression:e
  | value_list:l COMMA OP_NULL
  | value_list:l COMMA expression:e
  ;

id_common

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
  | MODE
  ;

id_for_func

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_db_item ::=
    id_for_func:i
  | IFF
  | CONVERT
  | CAST
  | NULLIF
  | COALESCE
  ;

id_for_table

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_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_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 ::=
    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_for_cast ::=
    id_common:i
  | NUMERIC
  | DECIMAL
  | BIT
  | INTO
  | TRUE
  | FALSE
  ;

id_for_revoke

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

id_list

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_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_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_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
  ;

privilege_list

privilege_list ::=
    privilege:p
  | privilege_list:l COMMA privilege:p
  ;

privilege

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

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 ::=
    | GRANT OPTION FOR
  ;

with_grant_option

with_grant_option ::=
    | WITH GRANT OPTION
  ;

revoke_qual

revoke_qual ::=
    | RESTRICT
  | CASCADE
  ;

user_list

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