1 /* Copyright (C) 2014 InfiniDB, Inc.
2    Copyright (C) 2016 MariaDB Corporation
3 
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License
6    as published by the Free Software Foundation; version 2 of
7    the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17    MA 02110-1301, USA. */
18 
19 /* $Id: ddl.y 9314 2013-03-19 17:39:25Z dhall $ */
20 /* This describes a substantial subset of SQL92 DDL with some
21    enhancements from various vendors.  Most of the nomenclature in the
22    grammar is drawn from SQL92.
23 
24    If you have to care about this grammar, you should consult one or
25    more of the following sources:
26 
27    Lex and Yacc book.
28    ANSI SQL92 standard
29    Understanding the New Sql book
30    The postgress and mysql sources.  find x -name \*.y -o -name \*.yy.
31 
32    We support quoted identifiers.
33 
34    All literals are stored as unconverted strings.
35 
36    You can't say "NOT DEFERRABLE".  See the comment below.
37 
38    This is a reentrant parser.
39 
40    MCOL-66 Modify to be a reentrant parser
41    */
42 
43 %{
44 #include "sqlparser.h"
45 
46 #ifdef _MSC_VER
47 #include "ddl-gram-win.h"
48 #else
49 #include "ddl-gram.h"
50 #endif
51 
52 #include "my_global.h"
53 #include "my_sys.h"
54 
55 #define scanner x->scanner
56 
57 using namespace std;
58 using namespace ddlpackage;
59 
60 int ddllex(YYSTYPE* ddllval, void* yyscanner);
61 void ddlerror(struct pass_to_bison* x, char const *s);
62 char* copy_string(const char *str);
63 
fix_column_length(SchemaObject * elem,const CHARSET_INFO * def_cs)64 void fix_column_length(SchemaObject* elem, const CHARSET_INFO* def_cs) {
65     auto* column = dynamic_cast<ColumnDef*>(elem);
66     if (column == NULL || column->fType == NULL)
67     {
68         return;
69     }
70 
71     if (column->fType->fType == DDL_VARCHAR ||
72          column->fType->fType == DDL_CHAR ||
73          (column->fType->fType == DDL_TEXT && column->fType->fExplicitLength))
74     {
75         unsigned mul = def_cs ? def_cs->mbmaxlen : 1;
76         if (column->fType->fCharset) {
77             const CHARSET_INFO* cs = get_charset_by_csname(column->fType->fCharset, MY_CS_PRIMARY, MYF(0));
78             if (cs)
79                 mul = cs->mbmaxlen;
80         }
81         column->fType->fLength *= mul;
82     }
83 
84     if (column->fType->fType == DDL_TEXT && column->fType->fExplicitLength)
85     {
86         // Rounding the resulting length of TEXT(N) field to the next default length
87         if (column->fType->fLength <= 255)
88             column->fType->fLength = 255;
89         else if (column->fType->fLength <= 65535)
90             column->fType->fLength = 65535;
91         else if (column->fType->fLength <= 16777215)
92             column->fType->fLength = 16777215;
93         else if (column->fType->fLength <= 2100000000)
94             column->fType->fLength = 2100000000;
95         // otherwise leave the decision to a caller code
96     }
97 }
98 
99 %}
100 
101 %expect 17
102 %pure-parser
103 %lex-param {void * scanner}
104 %parse-param {struct ddlpackage::pass_to_bison * x}
105 
106  /* Bison uses this to generate a C union definition.  This is used to
107 	store the application created values associated with syntactic
108 	constructs. */
109 
110 %union {
111   ddlpackage::AlterTableStatement *alterTableStmt;
112   ddlpackage::AlterTableAction *ata;
113   ddlpackage::AlterTableActionList *ataList;
114   ddlpackage::DDL_CONSTRAINT_ATTRIBUTES cattr;
115   std::pair<std::string, std::string> *tableOption;
116   const char *columnOption;
117   ddlpackage::ColumnConstraintDef *columnConstraintDef;
118   ddlpackage::ColumnNameList *columnNameList;
119   ddlpackage::ColumnType* columnType;
120   ddlpackage::ConstraintAttributes *constraintAttributes;
121   ddlpackage::ColumnConstraintList *constraintList;
122   ddlpackage::DDL_CONSTRAINTS constraintType;
123   double dval;
124   bool flag;
125   int ival;
126   ddlpackage::QualifiedName *qualifiedName;
127   ddlpackage::SchemaObject *schemaObject;
128   ddlpackage::SqlStatement *sqlStmt;
129   ddlpackage::SqlStatementList *sqlStmtList;
130   const char *str;
131   ddlpackage::TableConstraintDef *tableConstraint;
132   ddlpackage::TableElementList *tableElementList;
133   ddlpackage::TableOptionMap *tableOptionMap;
134   ddlpackage::ColumnDefaultValue *colDefault;
135   ddlpackage::DDL_MATCH_TYPE matchType;
136   ddlpackage::DDL_REFERENTIAL_ACTION refActionCode;
137   ddlpackage::ReferentialAction *refAction;
138 };
139 
140 %{
141 
142 %}
143 
144 %token ACTION ADD ALTER AUTO_INCREMENT BIGINT BIT BLOB IDB_BLOB CASCADE IDB_CHAR
145 CHARACTER CHECK CLOB COLUMN
146 COLUMNS COMMENT CONSTRAINT CONSTRAINTS CREATE CURRENT_USER DATETIME DEC
147 DECIMAL DEFAULT DEFERRABLE DEFERRED IDB_DELETE DROP ENGINE
148 FOREIGN FULL IMMEDIATE INDEX INITIALLY IDB_INT INTEGER KEY LONGBLOB LONGTEXT
149 MATCH MAX_ROWS MEDIUMBLOB MEDIUMTEXT
150 MIN_ROWS MODIFY NO NOT NULL_TOK NUMBER NUMERIC ON PARTIAL PRECISION PRIMARY
151 REFERENCES RENAME RESTRICT SET SMALLINT TABLE TEXT TINYBLOB TINYTEXT
152 TINYINT TO UNIQUE UNSIGNED UPDATE USER SESSION_USER SYSTEM_USER VARCHAR VARBINARY
153 VARYING WITH ZONE DOUBLE IDB_FLOAT REAL CHARSET COLLATE IDB_IF EXISTS CHANGE TRUNCATE
154 BOOL BOOLEAN MEDIUMINT TIMESTAMP
155 
156 %token <str> DQ_IDENT IDENT FCONST SCONST CP_SEARCH_CONDITION_TEXT ICONST DATE TIME
157 
158 /* Notes:
159  * 1. "ata" stands for alter_table_action
160  * 2. The %type statements are how bison figures out what element of
161  * above union to use in generated code.  It's a little weird because
162  * you say "type" but what you specify is an member the union.
163  */
164 %type <ata>                  add_table_constraint_def
165 %type <ata>                  alter_column_def
166 %type <ata>                  alter_table_action
167 %type <ataList>              alter_table_actions
168 %type <sqlStmt>              alter_table_statement
169 %type <ata>                  ata_add_column
170 %type <ata>                  ata_rename_table
171 %type <columnType>           character_string_type
172 %type <columnType>           binary_string_type
173 %type <columnType>           blob_type
174 %type <columnType>           text_type
175 %type <str>                  check_constraint_def
176 %type <columnConstraintDef>  column_constraint
177 %type <columnConstraintDef>  column_constraint_def
178 %type <schemaObject>         column_def
179 %type <str>                  column_name
180 %type <columnNameList>       column_name_list
181 %type <constraintAttributes> constraint_attributes
182 %type <cattr>                constraint_check_time
183 %type <str>                  constraint_name
184 %type <sqlStmt>              create_table_statement
185 %type <sqlStmt>              create_index_statement
186 %type <columnType>           data_type
187 %type <columnType>           datetime_type
188 %type <colDefault>           default_clause
189 %type <cattr>                deferrability_clause
190 %type <refActionCode>        delete_rule
191 %type <refActionCode>        drop_behavior
192 %type <ata>                  drop_column_def
193 %type <ata>                  drop_table_constraint_def
194 %type <sqlStmt>              drop_index_statement
195 %type <sqlStmt>              drop_table_statement
196 %type <refActionCode>        opt_delete_rule
197 %type <columnType>           exact_numeric_type
198 %type <str>                  literal
199 %type <matchType>            opt_match_type
200 %type <matchType>            match_type
201 %type <ata>                  alter_table_comment
202 %type <ata>                  modify_column
203 %type <columnType>           numeric_type
204 %type <constraintList>       column_qualifier_list
205 %type <constraintAttributes> opt_constraint_attributes
206 %type <str>                  opt_constraint_name
207 %type <cattr>                opt_deferrability_clause
208 %type <columnType>           opt_precision_scale
209 %type <refAction>            opt_referential_triggered_action
210 %type <ival>                 opt_time_precision
211 %type <qualifiedName>        qualified_name
212 %type <refActionCode>        referential_action
213 %type <refAction>            referential_triggered_action
214 %type <schemaObject>         referential_constraint_def
215 %type <ata>                  rename_column
216 %type <sqlStmt>              stmt
217 %type <sqlStmtList>          stmtblock
218 %type <sqlStmtList>          stmtmulti
219 %type <str>                  string_literal
220 %type <schemaObject>         table_constraint
221 %type <schemaObject>         table_constraint_def
222 %type <schemaObject>         table_element
223 %type <tableElementList>     table_element_list
224 %type <qualifiedName>        table_name
225 %type <tableOption>          table_option
226 %type <columnOption>         column_option
227 %type <tableOptionMap>       table_options
228 %type <tableOptionMap>       opt_table_options
229 %type <schemaObject>         unique_constraint_def
230 %type <constraintType>       unique_specifier
231 %type <refActionCode>        update_rule
232 %type <refActionCode>        opt_update_rule
233 %type <columnType>           approximate_numeric_type
234 %type <str>                  opt_display_width
235 %type <str> 		     	 opt_display_precision_scale_null
236 %type <str>                  opt_if_exists
237 %type <str>                  opt_if_not_exists
238 %type <sqlStmt>              trunc_table_statement
239 %type <sqlStmt>              rename_table_statement
240 %type <str>                  ident
241 %type <str>                  opt_quoted_literal
242 %type <str>                  opt_column_charset
243 %%
244 stmtblock:	stmtmulti { x->fParseTree = $1; }
245 		;
246 
247 
248 stmtmulti:
249 	stmtmulti ';' stmt
250 	{
251 		if ($3 != NULL) {
252 			$1->push_back($3);
253 			$$ = $1;
254 		}
255 		else {
256 			$$ = $1;
257 		}
258 	}
259 	| stmt
260 	{
261 		if ($1 != NULL)
262 		{
263 			$$ = x->fParseTree;
264 			$$->push_back($1);
265 		}
266 		else
267 		{
268 			$$ = NULL;
269 		}
270 	}
271 
272 
273 stmt:
274 	alter_table_statement
275 	| create_table_statement
276 	| drop_index_statement
277 	| drop_table_statement
278 	| create_index_statement
279 	| trunc_table_statement
280 	| rename_table_statement
281 	| { $$ = NULL; }
282 	;
283 
284 drop_table_statement:
285 	DROP TABLE opt_if_exists qualified_name {$$ = new DropTableStatement($4, false);}
286 	| DROP TABLE opt_if_exists qualified_name CASCADE CONSTRAINTS
287 	{
288 		{$$ = new DropTableStatement($4, true);}
289 	}
290 	;
291 
292 opt_if_exists:
293 	IDB_IF EXISTS {$$ = NULL;}
294 	| {$$ = NULL;}
295 	;
296 
297 drop_index_statement:
298 	DROP INDEX qualified_name {$$ = new DropIndexStatement($3);}
299 	;
300 
301 /* Notice that we allow table_options here (e.g. engine=infinidb) but
302    we ignore them. */
303 create_index_statement:
304 	CREATE INDEX qualified_name ON qualified_name '(' column_name_list ')' opt_table_options
305 	{
306 		$$ = new CreateIndexStatement($3, $5, $7, false);
307 		delete $9;
308 	}
309 	| CREATE UNIQUE INDEX qualified_name ON qualified_name '(' column_name_list ')' opt_table_options
310 	{
311 		$$ = new CreateIndexStatement($4, $6, $8, true);
312 		delete $10;
313 	}
314 	;
315 
316 opt_table_options:
317 	table_options
318 	| {$$ = NULL;}
319 	;
320 
321 create_table_statement:
322 	CREATE TABLE opt_if_not_exists table_name '(' table_element_list ')' opt_table_options
323 	{
324         for (auto* elem : *$6)
325         {
326             fix_column_length(elem, x->default_table_charset);
327         }
328 		$$ = new CreateTableStatement(new TableDef($4, $6, $8));
329 	}
330 	;
331 
332 opt_if_not_exists:
333 	IDB_IF NOT EXISTS {$$ = NULL;}
334 	| {$$ = NULL;}
335 	;
336 
337 trunc_table_statement:
338 	TRUNCATE TABLE qualified_name {$$ = new TruncTableStatement($3);}
339 	| TRUNCATE qualified_name { {$$ = new TruncTableStatement($2);} }
340 	;
341 
342 rename_table_statement:
343     RENAME TABLE qualified_name TO qualified_name
344     {
345         // MCOL-876. The change reuses existing infrastructure.
346         AtaRenameTable* renameAction = new AtaRenameTable($5);
347         AlterTableActionList* actionList = new AlterTableActionList();
348         actionList->push_back(renameAction);
349         $$ = new AlterTableStatement($3, actionList);
350     }
351 
352 table_element_list:
353 	table_element
354 	{
355 		$$ = new TableElementList();
356 		$$->push_back($1);
357 	}
358 	|
359 	table_element_list ',' table_element
360 	{
361 		$$ = $1;
362 		$$->push_back($3);
363 	}
364 	;
365 
366 table_element:
367 	column_def
368 	| table_constraint_def
369 	;
370 
371 table_constraint_def:
372 	CONSTRAINT opt_constraint_name table_constraint opt_constraint_attributes
373 	{
374 		$$ = $3;
375 		$3->fName = $2;
376 	}
377 	|
378 	opt_constraint_name table_constraint opt_constraint_attributes
379 	{
380 		$$ = $2;
381 		$2->fName = $1;
382 	}
383 	;
384 
385 opt_constraint_name:
386 	constraint_name {$$ = $1;}
387 	| {$$ = "noname";}
388 	;
389 
390 table_constraint:
391 	unique_constraint_def
392 	| referential_constraint_def
393 	| check_constraint_def {$$ = new TableCheckConstraintDef($1);}
394 	;
395 
396 unique_constraint_def:
397 	unique_specifier '(' column_name_list ')'
398 	{
399 		if ($1 == DDL_UNIQUE)
400 		    $$ = new TableUniqueConstraintDef($3);
401         else if ($1 == DDL_PRIMARY_KEY)
402             $$ = new TablePrimaryKeyConstraintDef($3);
403 	}
404 	;
405 
406 column_name_list:
407 	column_name
408 	{
409 		$$ = new vector<string>;
410 		$$->push_back($1);
411 	}
412 	| column_name_list ',' column_name
413 	{
414 		$$ = $1;
415 		$$->push_back($3);
416 	}
417 	;
418 
419 unique_specifier:
420 	PRIMARY KEY {$$ = DDL_PRIMARY_KEY;}
421 	| UNIQUE {$$ = DDL_UNIQUE;}
422 	;
423 
424 referential_constraint_def:
425 	FOREIGN KEY '(' column_name_list ')' REFERENCES	table_name '(' column_name_list ')' opt_match_type opt_referential_triggered_action
426 	{
427 		$$ = new TableReferencesConstraintDef($4, $7, $9, $11, $12);
428 	}
429 	;
430 
431 opt_match_type:
432 	match_type
433 	| {$$ = DDL_FULL;}
434 	;
435 
436 match_type:
437 	MATCH match_type {$$ = $2;}
438 	;
439 
440 match_type:
441 	FULL {$$ = DDL_FULL;}
442 	| PARTIAL {$$ = DDL_PARTIAL;}
443 	;
444 
445 opt_referential_triggered_action:
446 	referential_triggered_action
447 	| {$$ = NULL;}
448 	;
449 
450 referential_triggered_action:
451 	update_rule opt_delete_rule
452 	{
453 		$$ = new ReferentialAction();
454 		$$->fOnUpdate = $1;
455 		$$->fOnDelete = $2;
456 	}
457 	| delete_rule opt_update_rule
458 	{
459 		$$ = new ReferentialAction();
460 		$$->fOnUpdate = $2;
461 		$$->fOnDelete = $1;
462 	}
463 	;
464 
465 opt_delete_rule:
466 	delete_rule
467 	| {$$ = DDL_NO_ACTION;}
468 	;
469 
470 opt_update_rule:
471 	update_rule
472 	| {$$ = DDL_NO_ACTION;}
473 	;
474 
475 update_rule:
476 	ON UPDATE referential_action {$$ = $3;}
477 	;
478 
479 delete_rule:
480 	ON IDB_DELETE referential_action {$$ = $3;}
481 	;
482 
483 referential_action:
484 	CASCADE {$$ = DDL_CASCADE;}
485 	| SET NULL_TOK {$$ = DDL_SET_NULL;}
486 	| SET DEFAULT {$$ = DDL_SET_DEFAULT;}
487 	| NO ACTION {$$ = DDL_NO_ACTION;}
488 	| RESTRICT {$$ = DDL_RESTRICT;}
489 	;
490 
491 table_options:
492 	table_option
493 	{
494 		$$ = new TableOptionMap();
495 		(*$$)[$1->first] = $1->second;
496 		delete $1;
497 	}
498 	| table_options table_option
499 	{
500 		$$ = $1;
501 		(*$$)[$2->first] = $2->second;
502 		delete $2;
503 	}
504 	;
505 
506 opt_equal:
507 	{} | '=' {}
508 	;
509 
510 table_option:
511  	ENGINE opt_equal ident {$$ = new pair<string,string>("engine", $3);}
512 	|
513  	MAX_ROWS opt_equal ICONST {$$ = new pair<string,string>("max_rows", $3);}
514  	|
515  	MIN_ROWS opt_equal ICONST {$$ = new pair<string,string>("min_rows", $3);}
516  	|
517  	COMMENT opt_equal string_literal {$$ = new pair<string,string>("comment", $3);}
518 	|
519 	COMMENT string_literal {$$ = new pair<string,string>("comment", $2);}
520  	|
521 	AUTO_INCREMENT opt_equal ICONST
522     {
523        $$ = new pair<string,string>("auto_increment", $3);
524     }
525  	|
526  	DEFAULT CHARSET opt_equal ident {$$ = new pair<string,string>("default charset", $4);}
527     |
528     CHARSET opt_equal ident {$$ = new pair<string, string>("default charset", $3);}
529  	|
530  	DEFAULT IDB_CHAR SET opt_equal ident {$$ = new pair<string,string>("default charset", $5);}
531     |
532     DEFAULT COLLATE opt_equal opt_quoted_literal {$$ = new pair<string, string>("default collate", $4);}
533     |
534     COLLATE opt_equal opt_quoted_literal {$$ = new pair<string, string>("default collate", $3);}
535 	;
536 
537 alter_table_statement:
538 	ALTER TABLE table_name alter_table_actions
539 	{
540 		$$ = new AlterTableStatement($3, $4);
541 	}
542 	;
543 
544 alter_table_actions:
545 	alter_table_action
546 	{
547 		if ($1 != NULL) {
548 			$$ = new AlterTableActionList();
549 			$$->push_back($1);
550 		}
551 		else {
552 			/* An alter_table_statement requires at least one action.
553 			   So, this shouldn't happen. */
554 			$$ = NULL;
555 		}
556 	}
557 	| alter_table_actions ',' alter_table_action
558 	{
559 		$$ = $1;
560 		$$->push_back($3);
561 	}
562 	| alter_table_actions alter_table_action
563 	{
564 		$$ = $1;
565 		$$->push_back($2);
566 	}
567 	;
568 
569 alter_table_action:
570 	ata_add_column
571 	| drop_column_def
572 	| alter_column_def
573 	| add_table_constraint_def
574 	| drop_table_constraint_def
575 	| ata_rename_table
576 	| modify_column
577 	| rename_column
578     | alter_table_comment
579 	;
580 
581 alter_table_comment:
582     COMMENT opt_equal string_literal
583     {$$ = new AtaTableComment($3);}
584     |
585     COMMENT string_literal
586     {$$ = new AtaTableComment($2);}
587     ;
588 
589 
590 
591 modify_column:
592 	MODIFY column_name data_type
593 	{$$ = new AtaModifyColumnType($2,$3);}
594 	|
595 	MODIFY COLUMN column_name data_type
596 	{$$ = new AtaModifyColumnType($3,$4);}
597 	;
598 
599 
600 rename_column:
601 	CHANGE column_name column_name data_type
602 	{$$ = new AtaRenameColumn($2, $3, $4, NULL);}
603 	|CHANGE column_name column_name data_type column_option
604 	{$$ = new AtaRenameColumn($2, $3, $4, $5);}
605 	|CHANGE COLUMN column_name column_name data_type
606 	{$$ = new AtaRenameColumn($3, $4, $5, NULL);}
607 	|CHANGE COLUMN column_name column_name data_type column_option
608 	{$$ = new AtaRenameColumn($3, $4, $5, $6);}
609 	|CHANGE column_name column_name data_type column_qualifier_list
610 	{$$ = new AtaRenameColumn($2, $3, $4, $5, NULL);}
611 	|CHANGE COLUMN column_name column_name data_type column_qualifier_list
612 	{$$ = new AtaRenameColumn($3, $4, $5, $6, NULL);}
613 	|CHANGE column_name column_name data_type column_qualifier_list column_option
614 	{$$ = new AtaRenameColumn($2, $3, $4, $5, NULL, $6);}
615 	|CHANGE COLUMN column_name column_name data_type column_qualifier_list column_option
616 	{$$ = new AtaRenameColumn($3, $4, $5, $6, NULL, $7);}
617 	|CHANGE column_name column_name data_type default_clause
618 	{$$ = new AtaRenameColumn($2, $3, $4, NULL, $5);}
619 	|CHANGE COLUMN column_name column_name data_type default_clause
620 	{$$ = new AtaRenameColumn($3, $4, $5, NULL, $6);}
621 	|CHANGE column_name column_name data_type default_clause column_option
622 	{$$ = new AtaRenameColumn($2, $3, $4, NULL, $5, $6);}
623 	|CHANGE COLUMN column_name column_name data_type default_clause column_option
624 	{$$ = new AtaRenameColumn($3, $4, $5, NULL, $6, $7);}
625 	|CHANGE column_name column_name data_type column_qualifier_list default_clause
626 	{$$ = new AtaRenameColumn($2, $3, $4, $5, $6);}
627 	|CHANGE COLUMN column_name column_name data_type column_qualifier_list default_clause
628 	{$$ = new AtaRenameColumn($3, $4, $5, $6, $7);}
629 	|CHANGE column_name column_name data_type default_clause column_qualifier_list
630 	{$$ = new AtaRenameColumn($2, $3, $4, $6, $5);}
631 	|CHANGE COLUMN column_name column_name data_type default_clause column_qualifier_list
632 	{$$ = new AtaRenameColumn($3, $4, $5, $7, $6);}
633 	|CHANGE column_name column_name data_type column_qualifier_list default_clause column_option
634 	{$$ = new AtaRenameColumn($2, $3, $4, $5, $6, $7);}
635 	|CHANGE COLUMN column_name column_name data_type column_qualifier_list default_clause column_option
636 	{$$ = new AtaRenameColumn($3, $4, $5, $6, $7, $8);}
637 	|CHANGE column_name column_name data_type default_clause column_qualifier_list column_option
638 	{$$ = new AtaRenameColumn($2, $3, $4, $6, $5, $7);}
639 	|CHANGE COLUMN column_name column_name data_type default_clause column_qualifier_list column_option
640 	{$$ = new AtaRenameColumn($3, $4, $5, $7, $6, $8);}
641 	;
642 
643 drop_table_constraint_def:
644 	DROP CONSTRAINT constraint_name drop_behavior
645 	{
646 		$$ = new AtaDropTableConstraint($3, $4);
647 	}
648 	;
649 
650 add_table_constraint_def:
651 	ADD table_constraint_def {$$ = new AtaAddTableConstraint(dynamic_cast<TableConstraintDef *>($2));}
652 	;
653 
654 ata_rename_table:
655 	RENAME table_name {$$ = new AtaRenameTable($2);}
656 	| RENAME TO table_name {$$ = new AtaRenameTable($3);}
657 	;
658 
659 table_name:
660 	qualified_name
661 	;
662 
663 qualified_name:
664 	ident {
665 				if (x->fDBSchema.size())
666 					$$ = new QualifiedName((char*)x->fDBSchema.c_str(), $1);
667 				else
668 				    $$ = new QualifiedName($1);
669 			}
670     | ident '.' ident
671         {
672             $$ = new QualifiedName($1, $3);
673         }
674 	;
675 
676 ident:
677     DQ_IDENT
678     | IDENT
679     ;
680 
681 ata_add_column:
682     /* See the documentation for SchemaObject for an explanation of why we are using
683      * dynamic_cast here.
684      */
685 	ADD column_def { fix_column_length($2, x->default_table_charset); $$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($2));}
686 	| ADD COLUMN column_def { fix_column_length($3, x->default_table_charset); $$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($3));}
687 	| ADD '(' table_element_list ')' {
688         for (auto* elem : *$3) {
689             fix_column_length(elem, x->default_table_charset);
690         }
691         $$ = new AtaAddColumns($3);
692     }
693 	| ADD COLUMN '(' table_element_list ')' {
694         for (auto* elem : *$4) {
695             fix_column_length(elem, x->default_table_charset);
696         }
697         $$ = new AtaAddColumns($4);
698     }
699 	;
700 
701 column_name:
702     TIME
703 	|DATE
704 	|ident
705 	;
706 
707 constraint_name:
708 	ident
709 	;
710 
711 column_option:
712 	COMMENT  string_literal {$$ = $2;}
713 
714 column_def:
715 	column_name data_type opt_null_tok
716 	{
717 		$$ = new ColumnDef($1, $2, NULL, NULL );
718 	}
719 	| column_name data_type opt_null_tok column_qualifier_list
720 	{
721 		$$ = new ColumnDef($1, $2, $4, NULL);
722 	}
723 	| column_name data_type opt_null_tok default_clause column_qualifier_list
724 	{
725 		$$ = new ColumnDef($1, $2, $5, $4);
726 	}
727 	| column_name data_type opt_null_tok default_clause
728 	{
729 		$$ = new ColumnDef($1, $2, NULL, $4, NULL);
730 	}
731 	| column_name data_type opt_null_tok column_option
732 	{
733 		$$ = new ColumnDef($1, $2, NULL, NULL, $4 );
734 	}
735 	| column_name data_type opt_null_tok column_qualifier_list column_option
736 	{
737 		$$ = new ColumnDef($1, $2, $4, NULL, $5);
738 	}
739 	| column_name data_type opt_null_tok default_clause column_qualifier_list column_option
740 	{
741 		$$ = new ColumnDef($1, $2, $5, $4, $6);
742 	}
743 	| column_name data_type opt_null_tok column_qualifier_list default_clause
744 	{
745 		$$ = new ColumnDef($1, $2, $4, $5);
746 	}
747 	| column_name data_type opt_null_tok column_qualifier_list default_clause column_option
748 	{
749 		$$ = new ColumnDef($1, $2, $4, $5, $6);
750 	}
751 	| column_name data_type opt_null_tok default_clause column_option
752 	{
753 		$$ = new ColumnDef($1, $2, NULL, $4, $5);
754 	}
755 	;
756 
757 opt_null_tok:
758 	/* empty */
759 	|
760 	NULL_TOK
761 	;
762 
763 default_clause:
764 	DEFAULT literal
765 	{
766 		$$ = new ColumnDefaultValue($2);
767 	}
768 	| DEFAULT DQ_IDENT /* MCOL-1406 */
769 	{
770 		$$ = new ColumnDefaultValue($2);
771 	}
772 	| DEFAULT NULL_TOK {$$ = new ColumnDefaultValue(NULL);}
773 	| DEFAULT USER {$$ = new ColumnDefaultValue("$USER");}
774 	| DEFAULT CURRENT_USER optional_braces {$$ = new ColumnDefaultValue("$CURRENT_USER");}
775 	| DEFAULT SESSION_USER {$$ = new ColumnDefaultValue("$SESSION_USER");}
776 	| DEFAULT SYSTEM_USER {$$ = new ColumnDefaultValue("$SYSTEM_USER");}
777 	;
778 
779 optional_braces:
780 	/* empty */ {}
781 	| '(' ')' {}
782 	;
783 
784 opt_column_charset:
785     /* empty */ { $$ = NULL; }
786     |
787     IDB_CHAR SET opt_quoted_literal { $$ = $3; }
788     ;
789 
790 opt_column_collate:
791     /* empty */ {}
792     |
793     COLLATE opt_quoted_literal {}
794     ;
795 
796 data_type:
797 	character_string_type opt_column_charset opt_column_collate {
798         $1->fCharset = $2;
799         $$ = $1;
800     }
801 	| binary_string_type
802 	| numeric_type
803 	| datetime_type
804 	| blob_type
805 	| text_type opt_column_charset opt_column_collate {
806         $1->fCharset = $2;
807         $$ = $1;
808     }
809 	| IDB_BLOB
810 	{
811 		$$ = new ColumnType(DDL_BLOB);
812 		$$->fLength = DDLDatatypeLength[DDL_BLOB];
813 	}
814 	| CLOB
815 	{
816 		$$ = new ColumnType(DDL_CLOB);
817 		$$->fLength = DDLDatatypeLength[DDL_CLOB];
818 	}
819 
820 	;
821 
822 column_qualifier_list:
823 	column_constraint_def
824 	{
825 		$$ = new ColumnConstraintList();
826 		$$->push_back($1);
827 	}
828 	| column_qualifier_list column_constraint_def
829 	{
830 		$$ = $1;
831 		$$->push_back($2);
832 	}
833 	;
834 
835 column_constraint_def:
836 	column_constraint opt_constraint_attributes
837 	{
838 		$$ = $1;
839 
840 		if($2 != NULL)
841 		{
842 			$1->fDeferrable = $2->fDeferrable;
843 			$1->fCheckTime = $2->fCheckTime;
844 		}
845 
846 	}
847 	| CONSTRAINT constraint_name column_constraint opt_constraint_attributes
848 	{
849 		$$ = $3;
850 		$3->fName = $2;
851 
852 		if($4 != NULL)
853 		{
854 			$3->fDeferrable = $4->fDeferrable;
855 			$3->fCheckTime = $4->fCheckTime;
856 		}
857 
858 	}
859 	;
860 
861 opt_constraint_attributes:
862 	constraint_attributes {$$ = $1;}
863 	| {$$ = NULL;}
864 	;
865 
866 constraint_attributes:
867 	constraint_check_time opt_deferrability_clause
868 	{
869 		$$ = new ConstraintAttributes($1, ($2 != 0));
870 	}
871 	|
872 	DEFERRABLE constraint_check_time
873 	{
874 		$$ = new ConstraintAttributes($2, true);
875 	}
876 /*
877 	|
878 	NOT DEFERRABLE constraint_check_time
879 	{
880 		$$ = new ConstraintAttributes($3, false);
881 	}
882 */
883 	;
884 
885 opt_deferrability_clause:
886 	deferrability_clause
887 	| {$$ = DDL_NON_DEFERRABLE;}
888 	;
889 
890 deferrability_clause:
891 	DEFERRABLE {$$ = DDL_DEFERRABLE;}
892 
893 /* The rule below forces a shift/shift conflict.  This will require
894 scanner hacking or something. Since constraints are non-deferrable by
895 default, I'm putting this off. You can still express all the cases,
896 you just can't say NOT DEFERRABLE. */
897 
898 /*	| NOT DEFERRABLE {$$ = DDL_DEFERRABLE;} */
899 	;
900 
901 constraint_check_time:
902 	INITIALLY DEFERRED {$$ = DDL_INITIALLY_DEFERRED;}
903 	| INITIALLY IMMEDIATE {$$ = DDL_INITIALLY_IMMEDIATE;}
904 	;
905 
906 column_constraint:
907 	NOT NULL_TOK {$$ = new ColumnConstraintDef(DDL_NOT_NULL);}
908 	| UNIQUE {$$ = new ColumnConstraintDef(DDL_UNIQUE);}
909 	| PRIMARY KEY {$$ = new ColumnConstraintDef(DDL_PRIMARY_KEY);}
910 	| AUTO_INCREMENT {$$ = new ColumnConstraintDef(DDL_AUTO_INCREMENT);}
911 	| check_constraint_def {$$ = new ColumnConstraintDef($1);}
912 	;
913 
914 check_constraint_def:
915 	CHECK '(' CP_SEARCH_CONDITION_TEXT ')' {$$ = $3;}
916 	;
917 
918 string_literal:
919 	'\'' SCONST '\'' {$$ = $2;}
920 	;
921 
922 opt_quoted_literal:
923     string_literal
924     |
925     ident
926     ;
927 
928 character_string_type:
929 	CHARACTER
930 	{
931 		$$ = new ColumnType(DDL_CHAR);
932 		$$->fLength = 1;
933 	}
934 	| IDB_CHAR
935 	{
936 		$$ = new ColumnType(DDL_CHAR);
937 		$$->fLength = 1;
938 	}
939 	| CHARACTER '(' ICONST ')'
940 	{
941 		$$ = new ColumnType(DDL_CHAR);
942 		$$->fLength = atoi($3);
943 	}
944 	| IDB_CHAR '(' ICONST ')'
945 	{
946 		$$ = new ColumnType(DDL_CHAR);
947 		$$->fLength = atoi($3);
948 	}
949 	| CHARACTER VARYING '(' ICONST ')'
950 	{
951 		$$ = new ColumnType(DDL_VARCHAR);
952 		$$->fLength = atoi($4);
953 	}
954 
955 	| IDB_CHAR VARYING '(' ICONST ')'
956 	{
957 		$$ = new ColumnType(DDL_VARCHAR);
958 		$$->fLength = atoi($4);
959 	}
960 
961 	| VARCHAR '(' ICONST ')'
962 	{
963 		$$ = new ColumnType(DDL_VARCHAR);
964 		$$->fLength = atoi($3);
965 	}
966 	;
967 
968 binary_string_type:
969 	VARBINARY '(' ICONST ')'
970 	{
971 		$$ = new ColumnType(DDL_VARBINARY);
972 		$$->fLength = atoi($3);
973 	}
974 	;
975 
976 blob_type:
977 	BLOB '(' ICONST ')'
978 	{
979 		$$ = new ColumnType(DDL_BLOB);
980 		$$->fLength = atol($3);
981 	}
982 	| BLOB
983 	{
984 		$$ = new ColumnType(DDL_BLOB);
985 		$$->fLength = 65535;
986 	}
987 	| TINYBLOB
988 	{
989 		$$ = new ColumnType(DDL_BLOB);
990 		$$->fLength = 255;
991 	}
992 	| MEDIUMBLOB
993 	{
994 		$$ = new ColumnType(DDL_BLOB);
995 		$$->fLength = 16777215;
996 	}
997 	| LONGBLOB
998 	{
999 		$$ = new ColumnType(DDL_BLOB);
1000 		$$->fLength = 2100000000;
1001 	}
1002 	;
1003 
1004 text_type:
1005 	TEXT '(' ICONST ')'
1006 	{
1007 		$$ = new ColumnType(DDL_TEXT);
1008 		$$->fLength = atol($3);
1009 		$$->fExplicitLength = true;
1010 	}
1011 	| TEXT
1012 	{
1013 		$$ = new ColumnType(DDL_TEXT);
1014 		$$->fLength = 65535;
1015 	}
1016 	| TINYTEXT
1017 	{
1018 		$$ = new ColumnType(DDL_TEXT);
1019 		$$->fLength = 255;
1020 	}
1021 	| MEDIUMTEXT
1022 	{
1023 		$$ = new ColumnType(DDL_TEXT);
1024 		$$->fLength = 16777215;
1025 	}
1026 	| LONGTEXT
1027 	{
1028 		$$ = new ColumnType(DDL_TEXT);
1029 		$$->fLength = 2100000000;
1030 	}
1031 	;
1032 
1033 numeric_type:
1034 	exact_numeric_type
1035 	| approximate_numeric_type
1036 	;
1037 
1038 exact_numeric_type:
1039 	NUMERIC opt_precision_scale
1040 	{
1041 		$2->fType = DDL_NUMERIC;
1042 		$2->fLength = DDLDatatypeLength[DDL_NUMERIC];
1043 		$$ = $2;
1044 	}
1045 	| NUMERIC opt_precision_scale UNSIGNED
1046 	{
1047 		$2->fType = DDL_UNSIGNED_NUMERIC;
1048 		$2->fLength = DDLDatatypeLength[DDL_UNSIGNED_NUMERIC];
1049 		$$ = $2;
1050 	}
1051 	| DECIMAL opt_precision_scale
1052 	{
1053 		$2->fType = DDL_DECIMAL;
1054 /*	   	$2->fLength = DDLDatatypeLength[DDL_DECIMAL]; */
1055 		$$ = $2;
1056 	}
1057 	| DECIMAL opt_precision_scale UNSIGNED
1058 	{
1059 		$2->fType = DDL_UNSIGNED_DECIMAL;
1060 /*	   	$3->fLength = DDLDatatypeLength[DDL_DECIMAL]; */
1061 		$$ = $2;
1062 	}
1063 	| NUMBER opt_precision_scale
1064 	{
1065 		$2->fType = DDL_DECIMAL;
1066 		$2->fLength = DDLDatatypeLength[DDL_DECIMAL];
1067 		$$ = $2;
1068 	}
1069 	| NUMBER opt_precision_scale UNSIGNED
1070 	{
1071 		$2->fType = DDL_UNSIGNED_DECIMAL;
1072 		$2->fLength = DDLDatatypeLength[DDL_UNSIGNED_DECIMAL];
1073 		$$ = $2;
1074 	}
1075 	| INTEGER opt_display_width
1076 	{
1077 		$$ = new ColumnType(DDL_INT);
1078 		$$->fLength = DDLDatatypeLength[DDL_INT];
1079 	}
1080 	| IDB_INT opt_display_width
1081 	{
1082 		$$ = new ColumnType(DDL_INT);
1083 		$$->fLength = DDLDatatypeLength[DDL_INT];
1084 	}
1085 	| SMALLINT opt_display_width
1086 	{
1087 		$$ = new ColumnType(DDL_SMALLINT);
1088 		$$->fLength = DDLDatatypeLength[DDL_SMALLINT];
1089 	}
1090 	| TINYINT opt_display_width
1091 	{
1092 		$$ = new ColumnType(DDL_TINYINT);
1093 		$$->fLength = DDLDatatypeLength[DDL_TINYINT];
1094 	}
1095 	| BIGINT opt_display_width
1096 	{
1097 		$$ = new ColumnType(DDL_BIGINT);
1098 		$$->fLength = DDLDatatypeLength[DDL_BIGINT];
1099 	}
1100 	| INTEGER opt_display_width UNSIGNED
1101 	{
1102 		$$ = new ColumnType(DDL_UNSIGNED_INT);
1103 		$$->fLength = DDLDatatypeLength[DDL_INT];
1104 	}
1105 	| IDB_INT opt_display_width UNSIGNED
1106 	{
1107 		$$ = new ColumnType(DDL_UNSIGNED_INT);
1108 		$$->fLength = DDLDatatypeLength[DDL_INT];
1109 	}
1110 	| SMALLINT opt_display_width UNSIGNED
1111 	{
1112 		$$ = new ColumnType(DDL_UNSIGNED_SMALLINT);
1113 		$$->fLength = DDLDatatypeLength[DDL_SMALLINT];
1114 	}
1115 	| TINYINT opt_display_width UNSIGNED
1116 	{
1117 		$$ = new ColumnType(DDL_UNSIGNED_TINYINT);
1118 		$$->fLength = DDLDatatypeLength[DDL_TINYINT];
1119 	}
1120 	| BIGINT opt_display_width UNSIGNED
1121 	{
1122 		$$ = new ColumnType(DDL_UNSIGNED_BIGINT);
1123 		$$->fLength = DDLDatatypeLength[DDL_BIGINT];
1124 	}
1125         | BOOLEAN
1126         {
1127                 $$ = new ColumnType(DDL_TINYINT);
1128                 $$->fLength = DDLDatatypeLength[DDL_TINYINT];
1129                 $$->fPrecision = 1;
1130         }
1131         | BOOL
1132         {
1133                 $$ = new ColumnType(DDL_TINYINT);
1134                 $$->fLength = DDLDatatypeLength[DDL_TINYINT];
1135                 $$->fPrecision = 1;
1136         }
1137 	| MEDIUMINT opt_display_width
1138 	{
1139 		$$ = new ColumnType(DDL_MEDINT);
1140 		$$->fLength = DDLDatatypeLength[DDL_MEDINT];
1141 	}
1142 	| MEDIUMINT opt_display_width UNSIGNED
1143 	{
1144 		$$ = new ColumnType(DDL_UNSIGNED_MEDINT);
1145 		$$->fLength = DDLDatatypeLength[DDL_UNSIGNED_MEDINT];
1146 	}
1147 	;
1148 /* Bug 1570, change default scale to 0 from -1 */
1149 opt_precision_scale:
1150 	'(' ICONST ')' {$$ = new ColumnType(atoi($2), 0);}
1151 	| '(' ICONST ',' ICONST ')' {$$ = new ColumnType(atoi($2), atoi($4));}
1152 	| {$$ = new ColumnType(10,0);}
1153 	;
1154 
1155 opt_display_width:
1156 	'(' ICONST ')' {$$ = NULL;}
1157 	| {$$ = NULL;}
1158 	;
1159 
1160 approximate_numeric_type:
1161 	DOUBLE opt_display_precision_scale_null
1162 	{
1163 		$$ = new ColumnType(DDL_DOUBLE);
1164 		$$->fLength = DDLDatatypeLength[DDL_DOUBLE];
1165 	}
1166 	| DOUBLE opt_display_precision_scale_null UNSIGNED
1167 	{
1168 		$$ = new ColumnType(DDL_UNSIGNED_DOUBLE);
1169 		$$->fLength = DDLDatatypeLength[DDL_DOUBLE];
1170 	}
1171     | DOUBLE PRECISION opt_display_precision_scale_null
1172 	{
1173 		$$ = new ColumnType(DDL_DOUBLE);
1174 		$$->fLength = DDLDatatypeLength[DDL_DOUBLE];
1175 	}
1176 	| DOUBLE PRECISION opt_display_precision_scale_null UNSIGNED
1177 	{
1178 		$$ = new ColumnType(DDL_UNSIGNED_DOUBLE);
1179 		$$->fLength = DDLDatatypeLength[DDL_DOUBLE];
1180 	}
1181 	| REAL opt_display_precision_scale_null
1182 	{
1183 		$$ = new ColumnType(DDL_DOUBLE);
1184 		$$->fLength = DDLDatatypeLength[DDL_DOUBLE];
1185 	}
1186 	| REAL opt_display_precision_scale_null UNSIGNED
1187 	{
1188 		$$ = new ColumnType(DDL_UNSIGNED_DOUBLE);
1189 		$$->fLength = DDLDatatypeLength[DDL_DOUBLE];
1190 	}
1191 	| IDB_FLOAT opt_display_precision_scale_null
1192 	{
1193 		$$ = new ColumnType(DDL_FLOAT);
1194 		$$->fLength = DDLDatatypeLength[DDL_FLOAT];
1195 	}
1196 	| IDB_FLOAT opt_display_precision_scale_null UNSIGNED
1197 	{
1198 		$$ = new ColumnType(DDL_UNSIGNED_FLOAT);
1199 		$$->fLength = DDLDatatypeLength[DDL_FLOAT];
1200 	}
1201 	;
1202 
1203 opt_display_precision_scale_null:
1204 		'(' ICONST ')' {$$ = NULL;}
1205 		|
1206         '(' ICONST ',' ICONST ')' {$$ = NULL;}
1207         | {$$ = NULL;}
1208         ;
1209 
1210 literal:
1211 	ICONST
1212 	| string_literal
1213 	| FCONST
1214 	;
1215 
1216 datetime_type:
1217 	DATETIME opt_time_precision
1218 	{
1219 		$$ = new ColumnType(DDL_DATETIME);
1220 		$$->fLength = DDLDatatypeLength[DDL_DATETIME];
1221                 $$->fPrecision = $2;
1222 	}
1223 	|
1224 	DATE
1225 	{
1226 		$$ = new ColumnType(DDL_DATE);
1227 		$$->fLength = DDLDatatypeLength[DDL_DATE];
1228 	}
1229 	|
1230 	TIME opt_time_precision
1231 	{
1232 		$$ = new ColumnType(DDL_TIME);
1233 		$$->fLength = DDLDatatypeLength[DDL_TIME];
1234 		$$->fPrecision = $2;
1235 	}
1236 	|
1237 	TIMESTAMP opt_time_precision
1238 	{
1239 		$$ = new ColumnType(DDL_TIMESTAMP);
1240 		$$->fLength = DDLDatatypeLength[DDL_TIMESTAMP];
1241 		$$->fPrecision = $2;
1242 	}
1243 
1244 opt_time_precision:
1245 	'(' ICONST ')' {$$ = atoi($2);}
1246 	| {$$ = -1;}
1247 	;
1248 
1249 drop_column_def:
1250 	DROP column_name drop_behavior {$$ = new AtaDropColumn($2, $3);}
1251 	| DROP COLUMN column_name drop_behavior {$$ = new AtaDropColumn($3, $4);}
1252 	| DROP COLUMN '(' column_name_list ')' {$$ = new AtaDropColumns($4);}
1253 	| DROP '(' column_name_list ')' {$$ = new AtaDropColumns($3);}
1254 	| DROP COLUMNS '(' column_name_list ')' {$$ = new AtaDropColumns($4);}
1255 	;
1256 
1257 drop_behavior:
1258 	CASCADE {$$ = DDL_CASCADE;}
1259 	| RESTRICT {$$ = DDL_RESTRICT;}
1260 	| {$$ = DDL_NO_ACTION;}
1261 	;
1262 
1263 alter_column_def:
1264 	ALTER opt_column column_name SET default_clause {$$ = new AtaSetColumnDefault($3, $5);}
1265 	| 	ALTER opt_column column_name DROP DEFAULT {$$ = new AtaDropColumnDefault($3);}
1266 	;
1267 
1268 opt_column:
1269 	COLUMN
1270 	|
1271 	;
1272 
1273 %%
1274 
1275 
1276