Grammar NanoSqlParser
ANTLR-generated HTML file from /Users/donnie/Documents/CS122/Wi2017/nanodb-students/res/nanosql.g

Terence Parr, MageLang Institute
ANTLR Version 2.7.7 (20060906); 1989-2005


/**
 * A parser for processing SQL commands into the various command-classes derived
 * from {@link edu.caltech.nanodb.commands.Command}.  The information in these
 * commands is then used for data-definition, data-manipulation, and general
 * utility operations, within the database.
 */
Definition of parser NanoSqlParser, which is a subclass of LLkParser.


commands
	:	command ( SEMICOLON 
			(	command 
			|	
			) )* 
	;


/**
 * A single statement, which could be one of many possible options.  Note that
 * this command is not followed by a semicolon, which allows it to be used in the
 * "commands" rule.
 */
command
	:	(	create_stmt 
		|	drop_stmt 
		|	select_stmt 
		|	insert_stmt 
		|	update_stmt 
		|	delete_stmt 
		|	begin_txn_stmt 
		|	commit_txn_stmt 
		|	rollback_txn_stmt 
		|	analyze_stmt 
		|	explain_stmt 
		|	exit_stmt 
		|	crash_stmt 
		|	dump_table_stmt 
		|	flush_stmt 
		|	verify_stmt 
		|	optimize_stmt 
		|	show_stats_stmt 
		|	show_tables_stmt 
		|	show_vars_stmt 
		|	set_var_stmt 
		) 
	;


command_semicolon
	:	command SEMICOLON 
	;


/**
 * CREATE Statements - each database object that can be created will produce a
 * different {@link edu.caltech.nanodb.commands.Command} instance that contains
 * the SQL command's details.  This rule returns that Command instance, fully
 * configured.
 */
create_stmt
	:	create_table 
	|	create_view 
	|	create_index 
	;


drop_stmt
	:	drop_table_stmt 
	|	drop_index_stmt 
	;


select_stmt
	:	select_clause 
	;


insert_stmt
	:	INSERT INTO dbobj_ident insert_cols 
		(	insert_vals 
		|	select_clause 
		) 
	;


update_stmt
	:	UPDATE dbobj_ident SET dbobj_ident EQUALS expression ( COMMA dbobj_ident EQUALS expression )* 
		(	WHERE expression 
		|	
		) 
	;


delete_stmt
	:	DELETE FROM dbobj_ident 
		(	WHERE expression 
		|	
		) 
		
	;


begin_txn_stmt
	:	(	START TRANSACTION 
		|	BEGIN 
			(	WORK 
			|	
			) 
		) 
		
	;


commit_txn_stmt
	:	COMMIT 
		(	WORK 
		|	
		) 
		
	;


rollback_txn_stmt
	:	ROLLBACK 
		(	WORK 
		|	
		) 
		
	;


analyze_stmt
	:	ANALYZE 
		(	VERBOSE 
		|	
		) 
		dbobj_ident ( COMMA dbobj_ident )* 
	;


explain_stmt
	:	EXPLAIN 
		(	select_stmt 
		|	insert_stmt 
		|	update_stmt 
		|	delete_stmt 
		) 
		
	;


/**
 * The exit command is just a simple way for the main loop to know that it's
 * time to stop having fun.
 */
exit_stmt
	:	(	EXIT 
		|	QUIT 
		) 
		
	;


crash_stmt
	:	CRASH 
		(	INT_LITERAL 
		|	
		) 
		
	;


dump_table_stmt
	:	DUMP TABLE dbobj_ident 
		(	TO FILE STRING_LITERAL 
		|	
		) 
		(	FORMAT dbobj_ident 
		|	
		) 
		
	;


flush_stmt
	:	FLUSH 
	;


verify_stmt
	:	VERIFY dbobj_ident ( COMMA dbobj_ident )* 
	;


optimize_stmt
	:	OPTIMIZE dbobj_ident ( COMMA dbobj_ident )* 
	;


show_stats_stmt
	:	SHOW 
		(	dbobj_ident 
		|	TABLE dbobj_ident 
		) 
		STATS 
	;


show_tables_stmt
	:	SHOW TABLES 
	;


show_vars_stmt
	:	SHOW VARIABLES 
		(	LIKE STRING_LITERAL 
		|	
		) 
	;


set_var_stmt
	:	SET VARIABLE STRING_LITERAL EQUALS expression 
	;


/**
 * An UNQUALIFIED identifier for a "database object" - a table or column.
 */
dbobj_ident
	:	IDENT 
	|	QUOTED_IDENT 
	;


/**
 * Column names may be of the form <tt>colName</tt>, or
 * <tt>tblName.colName</tt>.
 */
column_name
	:	dbobj_ident 
		(	PERIOD dbobj_ident 
		|	
		) 
	;


create_table
	:	CREATE 
		(	TEMPORARY 
		|	
		) 
		TABLE 
		(	IF NOT EXISTS 
		|	
		) 
		dbobj_ident table_decl 
		(	cmd_properties 
		|	
		) 
	;


create_view
	:	CREATE VIEW dbobj_ident AS select_clause 
	;


create_index
	:	CREATE 
		(	UNIQUE 
		|	
		) 
		INDEX 
		(	dbobj_ident 
		|	
		) 
		ON dbobj_ident LPAREN dbobj_ident ( COMMA dbobj_ident )* RPAREN 
		(	cmd_properties 
		|	
		) 
	;


/**
 * Parse a comma-delimited list of column-declarations, and add them to the
 * passed-in CreateTableCommand object.  Semantic checks are done along the way
 * to ensure that none of the values are contradictory or otherwise insane.
 */
table_decl
	:	LPAREN 
		(	table_col_decl 
		|	table_constraint 
		) 
		( COMMA 
			(	table_col_decl 
			|	table_constraint 
			) )* RPAREN 
	;


cmd_properties
	:	PROPERTIES LPAREN dbobj_ident EQUALS literal_expr ( COMMA dbobj_ident EQUALS literal_expr )* RPAREN 
	;


/**
 * Table column declarations are similar to view column declarations, but can
 * have additional syntax declaring constraints on values in the table-column.
 */
table_col_decl
	:	IDENT column_type ( column_constraint )* 
	;


/**
 * Table columns can have a number of constraints, which may optionally be named.
 * Note that column-constraints and table-constraints can be quite different,
 * even though they are represented with the same Java class in the
 * implementation.
 */
table_constraint
	:	(	CONSTRAINT IDENT 
		|	
		) 
		(	(	UNIQUE 
			|	PRIMARY KEY 
			) 
			LPAREN IDENT ( COMMA IDENT )* RPAREN 
		|	FOREIGN KEY LPAREN IDENT ( COMMA IDENT )* RPAREN REFERENCES IDENT 
			(	LPAREN IDENT ( COMMA IDENT )* RPAREN 
			|	
			) 
			(	ON DELETE 
				(	RESTRICT 
				|	CASCADE 
				|	SET NULL 
				) 
			|	
			) 
			(	ON UPDATE 
				(	RESTRICT 
				|	CASCADE 
				|	SET NULL 
				) 
			|	
			) 
		) 
	;


/**
 * Column type-specifications are parsed by this rule.  Some types are simple
 * keywords.  Others have supporting arguments to parse as well, such as lengths
 * or precisions.  User-defined types are not supported.
 */
column_type
	:	(	TYPE_INT 
		|	TYPE_INTEGER 
		) 
		
	|	TYPE_BIGINT 
	|	TYPE_FLOAT 
	|	TYPE_DOUBLE 
	|	(	TYPE_CHAR 
		|	TYPE_VARCHAR 
		) 
		LPAREN INT_LITERAL RPAREN 
	|	TYPE_CHARACTER 
		(	TYPE_VARYING 
		|	
		) 
		LPAREN INT_LITERAL RPAREN 
	|	TYPE_DATE 
	|	TYPE_DATETIME 
	|	TYPE_TIME 
	|	TYPE_TIMESTAMP 
	;


/**
 * Table columns can have a number of constraints, which may optionally be named.
 * Note that column-constraints and table-constraints can be quite different,
 * even though they are represented with the same Java class in the
 * implementation.
 */
column_constraint
	:	(	CONSTRAINT IDENT 
		|	
		) 
		(	NOT NULL 
		|	UNIQUE 
		|	PRIMARY KEY 
		|	REFERENCES IDENT 
			(	LPAREN IDENT RPAREN 
			|	
			) 
		) 
	;


literal_expr
	:	NULL 
	|	TRUE 
	|	FALSE 
	|	INT_LITERAL 
	|	LONG_LITERAL 
	|	FLOAT_LITERAL 
	|	DEC_LITERAL 
	|	STRING_LITERAL 
	;


/**
 * This rule parses a SELECT clause.  Since SELECT clauses can be nested in
 * other expressions, it's important to have this as a separate sub-rule in the
 * parser.
 */
select_clause
	:	(	WITH LPAREN select_clause RPAREN 
			(	AS 
			|	
			) 
			dbobj_ident ( COMMA LPAREN select_clause RPAREN 
				(	AS 
				|	
				) 
				dbobj_ident )* 
		|	
		) 
		SELECT 
		(	ALL 
		|	DISTINCT 
		|	
		) 
		select_value ( COMMA select_value )* 
		(	FROM from_clause 
		|	
		) 
		(	WHERE expression 
		|	
		) 
		(	GROUP BY expression ( COMMA expression )* 
			(	HAVING expression 
			|	
			) 
		|	
		) 
		(	ORDER BY expression 
			(	ASC 
			|	DESC 
			|	
			) 
			( COMMA expression 
				(	ASC 
				|	DESC 
				|	
				) 
				)* 
		|	
		) 
		(	LIMIT INT_LITERAL 
		|	
		) 
		(	OFFSET INT_LITERAL 
		|	
		) 
	;


drop_table_stmt
	:	DROP TABLE 
		(	IF EXISTS 
		|	
		) 
		dbobj_ident 
	;


drop_index_stmt
	:	DROP INDEX dbobj_ident ON dbobj_ident 
	;


select_value
	:	STAR 
	|	expression 
		(	(	AS 
			|	
			) 
			dbobj_ident 
		|	
		) 
		
	;


from_clause
	:	join_expr ( COMMA join_expr )* 
	;


/**
 * The expression rule matches pretty much any possible logical and/or
 * mathematical expression that one might need.  Note that it will parse a lot
 * of expressions that don't make any sense because of type-matching
 * requirements, but that is fine - this parse rule is about determining the
 * appropriate structure of the expression, and that is about applying operator
 * precedence and following the form of the expressions.  Semantic analysis
 * catches the nonsensical statements.
 */
expression
	:	logical_or_expr 
	;


join_expr
	:	from_expr ( 
			(	CROSS 
			|	(	NATURAL 
				|	
				) 
				(	INNER 
				|	(	LEFT 
					|	RIGHT 
					|	FULL 
					) 
					(	OUTER 
					|	
					) 
				|	
				) 
			) 
			( JOIN from_expr 
				(	ON expression 
				|	USING LPAREN dbobj_ident ( COMMA dbobj_ident )* RPAREN 
				|	
				) ) )* 
	;


from_expr
	:	dbobj_ident 
		(	LPAREN 
			(	expression ( COMMA expression )* 
			|	
			) 
			RPAREN 
		|	
		) 
		(	(	AS 
			|	
			) 
			dbobj_ident 
		|	
		) 
		
	|	LPAREN select_clause RPAREN 
		(	AS 
		|	
		) 
		dbobj_ident 
	|	LPAREN from_clause RPAREN 
	;


insert_cols
	:	(	LPAREN dbobj_ident ( COMMA dbobj_ident )* RPAREN 
		|	
		) 
	;


insert_vals
	:	VALUES LPAREN expression ( COMMA expression )* RPAREN 
	;


dump_index_stmt
	:	DUMP INDEX dbobj_ident ON TABLE dbobj_ident 
		(	TO FILE STRING_LITERAL 
		|	
		) 
		(	FORMAT dbobj_ident 
		|	
		) 
		
	;


logical_or_expr
	:	logical_and_expr ( OR logical_and_expr )* 
	;


expr_list
	:	LPAREN 
		(	expression ( COMMA expression )* 
		|	
		) 
		RPAREN 
	;


logical_and_expr
	:	logical_not_expr ( AND logical_not_expr )* 
	;


logical_not_expr
	:	(	NOT 
		|	
		) 
		(	relational_expr 
		|	exists_expr 
		) 
		
	;


/**
 * @todo Change this rule to a compare_expr, then create a relational_expr that
 *       includes compare_expr, like_expr, between_expr, in_expr, and is_expr.
 *       BUT:  this introduces nondeterminism into the parser, once you add the
 *       other alternatives.  :(  Work out a solution...
 */
relational_expr
	:	additive_expr 
		(	( (	EQUALS 
				|	NOT_EQUALS 
				|	GRTR_THAN 
				|	LESS_THAN 
				|	GRTR_EQUAL 
				|	LESS_EQUAL 
				) 
				additive_expr ) 
		|	IS 
			(	NOT 
			|	
			) 
			NULL 
		|	( (	NOT 
				|	
				) 
				(	( (	LIKE 
						|	SIMILAR TO 
						) 
						additive_expr ) 
				|	( BETWEEN additive_expr AND additive_expr ) 
				|	( IN 
						(	expr_list 
						|	LPAREN select_clause RPAREN 
						) ) 
				) ) 
		|	
		) 
	;


exists_expr
	:	EXISTS LPAREN select_clause RPAREN 
	;


/**
 * A numeric expression is at least one numeric term.  Multiple numeric terms
 * are added or subtracted with each other.
 */
additive_expr
	:	mult_expr ( (	PLUS 
			|	MINUS 
			) 
			mult_expr )* 
	;


/**
 * A numeric term is at least one numeric factor.  Multiple numeric factors
 * are multiplied or divided with each other.
 */
mult_expr
	:	unary_op_expr ( (	STAR 
			|	SLASH 
			|	PERCENT 
			) 
			unary_op_expr )* 
	;


unary_op_expr
	:	MINUS unary_op_expr 
	|	PLUS unary_op_expr 
	|	base_expr 
	;


base_expr
	:	literal_expr 
	|	column_name 
	|	function_call 
	|	LPAREN 
		(	logical_or_expr 
		|	select_clause 
		) 
		RPAREN 
	;


/**
 * A function call can refer to either a normal scalar function, or it can refer
 * to an aggregate function call.  It's up to the query executor to ensure that
 * the function actually exists, and that it's the proper type for its context.
 */
function_call
	:	( dbobj_ident LPAREN 
			(	(	(	DISTINCT 
					|	
					) 
					expression ( COMMA expression )* 
				|	STAR 
				) 
			|	
			) 
			RPAREN ) 
	;