Skip to content

Commit

Permalink
Non-reserved words can be used as identifiers (#127)
Browse files Browse the repository at this point in the history
Previously all <key words> (which includes reserved and non-reserved
words) were disallowed as identifiers. Looking at the SQL standard more
closely, it does explicitly state that reserved words cannot be regular
identifiers using and case, but nowhere does it state that non-reserved
words are not allowed to be used as identifiers.

This is an import distinction because `public` is a non-reserved word
and we intend to use it for the default schema and also for
compatibility with the same schema in PostgreSQL.

Also, comments can now be placed in `grammar.bnf` with a `#` at the
start of the line (not within a line).

See #103
  • Loading branch information
elliotchance authored Aug 6, 2022
1 parent 7ee3bfd commit bdd136d
Show file tree
Hide file tree
Showing 7 changed files with 5,884 additions and 2,041 deletions.
7 changes: 4 additions & 3 deletions generate-grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,12 @@ def parse_grammar(grammar):

full_line = ''
for line in grammar.split("\n"):
if line.startswith('#'):
continue
if '/*' in line and '::=' in line:
parts = line.split('/*')
full_line += parts[0] + "::= "
grammar_types[parts[0].strip()] = parts[1].split('*/')[0].strip()
elif '/*' in line:
continue
elif line == '':
if full_line != '':
lines.append(full_line.strip())
Expand Down Expand Up @@ -375,7 +375,7 @@ def rule_name(name):
return name

def var_name(name):
return "rule_" + rule_name(name).lower().replace('<', '').replace(':', '').replace('>', '_').replace(' ', '_').replace('^', '_')
return "rule_" + rule_name(name).lower().replace('<', '').replace('-', '_').replace(':', '').replace('>', '_').replace(' ', '_').replace('^', '_')

# Generate grammar file
grammar_file = open('vsql/grammar.v', mode='w')
Expand Down Expand Up @@ -516,6 +516,7 @@ def parse_tree(text):
# parse_tree("VALUES TIMESTAMP '2022-06-30'")
# parse_tree("INSERT INTO foo ( f1 ) VALUES ( TIMESTAMP '2022-06-30' )")
# parse_tree("VALUES TRIM ( 'helloworld' )")
# parse_tree("CREATE SCHEMA public")

for arg in sys.argv[1:]:
print(arg)
Expand Down
296 changes: 293 additions & 3 deletions grammar.bnf
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/* This file describes the SQL grammar from the BNF rules defined in the SQL */
/* 2016 standard. Unfortunatly, the standard is not open source and many of */
/* the rules below are only partially */
# This file describes the SQL grammar from the BNF rules defined in the SQL
# 2016 standard.
#
# Unfortunately, the standard is not open source, however, you can find the BNF
# at: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html
#
# Many rules are missing, or only partially implemented.

<preparable statement> /* Stmt */ ::=
<preparable SQL data statement>
Expand Down Expand Up @@ -61,8 +65,294 @@
<actual identifier> /* Identifier */ ::=
<regular identifier>

# <non-reserved word> is added on top of the original <regular identifier> to
# allow non-reserved words to be used as identifiers. As far as I can tell, only
# <reserved word>s are restricted. See "9075-2:2016 5.2 #26".
<regular identifier> /* Identifier */ ::=
<identifier body>
| <non-reserved word> -> string_identifier

<non-reserved word> /* string */ ::=
A
| ABSOLUTE
| ACTION
| ADA
| ADD
| ADMIN
| AFTER
| ALWAYS
| ASC
| ASSERTION
| ASSIGNMENT
| ATTRIBUTE
| ATTRIBUTES
| BEFORE
| BERNOULLI
| BREADTH
| C
| CASCADE
| CATALOG
| CATALOG_NAME
| CHAIN
| CHAINING
| CHARACTER_SET_CATALOG
| CHARACTER_SET_NAME
| CHARACTER_SET_SCHEMA
| CHARACTERISTICS
| CHARACTERS
| CLASS_ORIGIN
| COBOL
| COLLATION
| COLLATION_CATALOG
| COLLATION_NAME
| COLLATION_SCHEMA
| COLUMNS
| COLUMN_NAME
| COMMAND_FUNCTION
| COMMAND_FUNCTION_CODE
| COMMITTED
| CONDITIONAL
| CONDITION_NUMBER
| CONNECTION
| CONNECTION_NAME
| CONSTRAINT_CATALOG
| CONSTRAINT_NAME
| CONSTRAINT_SCHEMA
| CONSTRAINTS
| CONSTRUCTOR
| CONTINUE
| CURSOR_NAME
| DATA
| DATETIME_INTERVAL_CODE
| DATETIME_INTERVAL_PRECISION
| DEFAULTS
| DEFERRABLE
| DEFERRED
| DEFINED
| DEFINER
| DEGREE
| DEPTH
| DERIVED
| DESC
| DESCRIBE_CATALOG
| DESCRIBE_NAME
| DESCRIBE_PROCEDURE_SPECIFIC_CATALOG
| DESCRIBE_PROCEDURE_SPECIFIC_NAME
| DESCRIBE_PROCEDURE_SPECIFIC_SCHEMA
| DESCRIBE_SCHEMA
| DESCRIPTOR
| DIAGNOSTICS
| DISPATCH
| DOMAIN
| DYNAMIC_FUNCTION
| DYNAMIC_FUNCTION_CODE
| ENCODING
| ENFORCED
| ERROR
| EXCLUDE
| EXCLUDING
| EXPRESSION
| FINAL
| FINISH
| FINISH_CATALOG
| FINISH_NAME
| FINISH_PROCEDURE_SPECIFIC_CATALOG
| FINISH_PROCEDURE_SPECIFIC_NAME
| FINISH_PROCEDURE_SPECIFIC_SCHEMA
| FINISH_SCHEMA
| FIRST
| FLAG
| FOLLOWING
| FORMAT
| FORTRAN
| FOUND
| FULFILL
| FULFILL_CATALOG
| FULFILL_NAME
| FULFILL_PROCEDURE_SPECIFIC_CATALOG
| FULFILL_PROCEDURE_SPECIFIC_NAME
| FULFILL_PROCEDURE_SPECIFIC_SCHEMA
| FULFILL_SCHEMA
| G
| GENERAL
| GENERATED
| GO
| GOTO
| GRANTED
| HAS_PASS_THROUGH_COLUMNS
| HAS_PASS_THRU_COLS
| HIERARCHY
| IGNORE
| IMMEDIATE
| IMMEDIATELY
| IMPLEMENTATION
| INCLUDING
| INCREMENT
| INITIALLY
| INPUT
| INSTANCE
| INSTANTIABLE
| INSTEAD
| INVOKER
| ISOLATION
| IS_PRUNABLE
| JSON
| K
| KEEP
| KEY
| KEYS
| KEY_MEMBER
| KEY_TYPE
| LAST
| LENGTH
| LEVEL
| LOCATOR
| M
| MAP
| MATCHED
| MAXVALUE
| MESSAGE_LENGTH
| MESSAGE_OCTET_LENGTH
| MESSAGE_TEXT
| MINVALUE
| MORE
| MUMPS
| NAME
| NAMES
| NESTED
| NESTING
| NEXT
| NFC
| NFD
| NFKC
| NFKD
| NORMALIZED
| NULLABLE
| NULLS
| NUMBER
| OBJECT
| OCTETS
| OPTION
| OPTIONS
| ORDERING
| ORDINALITY
| OTHERS
| OUTPUT
| OVERFLOW
| OVERRIDING
| P
| PAD
| PARAMETER_MODE
| PARAMETER_NAME
| PARAMETER_ORDINAL_POSITION
| PARAMETER_SPECIFIC_CATALOG
| PARAMETER_SPECIFIC_NAME
| PARAMETER_SPECIFIC_SCHEMA
| PARTIAL
| PASCAL
| PASS
| PASSING
| PAST
| PATH
| PLACING
| PLAN
| PLI
| PRECEDING
| PRESERVE
| PRIOR
| PRIVATE
| PRIVATE_PARAMETERS
| PRIVATE_PARAMS_S
| PRIVILEGES
| PRUNE
| PUBLIC
| QUOTES
| READ
| RELATIVE
| REPEATABLE
| RESPECT
| RESTART
| RESTRICT
| RETURNED_CARDINALITY
| RETURNED_LENGTH
| RETURNED_OCTET_LENGTH
| RETURNED_SQLSTATE
| RETURNING
| RETURNS_ONLY_PASS_THROUGH
| RET_ONLY_PASS_THRU
| ROLE
| ROUTINE
| ROUTINE_CATALOG
| ROUTINE_NAME
| ROUTINE_SCHEMA
| ROW_COUNT
| SCALAR
| SCALE
| SCHEMA
| SCHEMA_NAME
| SCOPE_CATALOG
| SCOPE_NAME
| SCOPE_SCHEMA
| SECTION
| SECURITY
| SELF
| SEQUENCE
| SERIALIZABLE
| SERVER_NAME
| SESSION
| SETS
| SIMPLE
| SIZE
| SOURCE
| SPACE
| SPECIFIC_NAME
| START_CATALOG
| START_NAME
| START_PROCEDURE_SPECIFIC_CATALOG
| START_PROCEDURE_SPECIFIC_NAME
| START_PROCEDURE_SPECIFIC_SCHEMA
| START_SCHEMA
| STATE
| STATEMENT
| STRING
| STRUCTURE
| STYLE
| SUBCLASS_ORIGIN
| T
| TABLE_NAME
| TABLE_SEMANTICS
| TEMPORARY
| THROUGH
| TIES
| TOP_LEVEL_COUNT
| TRANSACTION
| TRANSACTION_ACTIVE
| TRANSACTIONS_COMMITTED
| TRANSACTIONS_ROLLED_BACK
| TRANSFORM
| TRANSFORMS
| TRIGGER_CATALOG
| TRIGGER_NAME
| TRIGGER_SCHEMA
| TYPE
| UNBOUNDED
| UNCOMMITTED
| UNCONDITIONAL
| UNDER
| UNNAMED
| USAGE
| USER_DEFINED_TYPE_CATALOG
| USER_DEFINED_TYPE_CODE
| USER_DEFINED_TYPE_NAME
| USER_DEFINED_TYPE_SCHEMA
| UTF16
| UTF32
| UTF8
| VIEW
| WORK
| WRAPPER
| WRITE
| ZONE

<identifier body> /* Identifier */ ::=
<identifier start>
Expand Down
6 changes: 6 additions & 0 deletions tests/create-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ SELECT * FROM foo.bar;
-- msg: CREATE TABLE 1
-- msg: INSERT 1
-- BAZ: 123

CREATE SCHEMA absolute;
-- msg: CREATE SCHEMA 1

CREATE SCHEMA ABSOLUTE;
-- msg: CREATE SCHEMA 1
16 changes: 16 additions & 0 deletions tests/create-table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,19 @@ CREATE SCHEMA foo;
CREATE TABLE foo.bar (baz BIGINT);
-- msg: CREATE SCHEMA 1
-- msg: CREATE TABLE 1

CREATE TABLE absolute (baz BIGINT);
-- msg: CREATE TABLE 1

CREATE TABLE ABSOLUTE (baz BIGINT);
-- msg: CREATE TABLE 1

CREATE SCHEMA absolute;
CREATE TABLE absolute.continue (baz BIGINT);
-- msg: CREATE SCHEMA 1
-- msg: CREATE TABLE 1

CREATE SCHEMA absolute;
CREATE TABLE absolute.CONTINUE (baz BIGINT);
-- msg: CREATE SCHEMA 1
-- msg: CREATE TABLE 1
Loading

0 comments on commit bdd136d

Please sign in to comment.