diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 992512c5e..1131a1db2 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -6217,78 +6217,85 @@ CreateTable CreateTable(boolean isUsingOrReplace): [ LOOKAHEAD(2) { createTable.setIfNotExists(true); }] table=Table() [ LOOKAHEAD(2) ( - LOOKAHEAD(3) - ("(" tableColumn=RelObjectName() { columns.add(tableColumn); } ("," tableColumn=RelObjectName() { columns.add(tableColumn); } )* ")") + LOOKAHEAD(3) ( + "(" tableColumn=RelObjectName() { columns.add(tableColumn); } ("," tableColumn=RelObjectName() { columns.add(tableColumn); } )* ")" + ) | - ("(" - coldef = ColumnDefinition() - - { columnDefinitions.add(coldef); } - ( - "," + "(" + coldef = ColumnDefinition() { columnDefinitions.add(coldef); } ( - LOOKAHEAD(3) ( - tk= + "," + ( + LOOKAHEAD(3) ( + { + idxSpec.clear(); + } + tk= sk3=RelObjectName() - /* colNames=ColumnsNamesList() */ colNames = ColumnNamesWithParamsList() - { idxSpec.clear(); } ( parameter=CreateParameter() { idxSpec.addAll(parameter); } )* { index = new Index().withType(tk.image).withName(sk3).withColumns(colNames).withIndexSpec(new ArrayList(idxSpec)); indexes.add(index); } - ) - | - LOOKAHEAD(3) ( - { - index = new NamedConstraint(); - } - [ sk3=RelObjectName() {index.setName(sk3);} ] + ) + | + LOOKAHEAD(3) ( + { + index = new NamedConstraint(); + tk2=null; + idxSpec.clear(); + } + [ sk3=RelObjectName() {index.setName(sk3);} ] + + ( + tk= tk2= + | + tk= [ tk2= ] + ) + { + index.setType( tk.image + ( tk2!=null ? " " + tk2.image : "" )); + tk2=null; + } - (tk= tk2= {index.setType(tk.image + " " + tk2.image);} - | tk= [ tk2= ] {index.setType(tk.image + (tk2!=null?" " + tk2.image:""));} - ) - /* colNames=ColumnsNamesList() */ colNames = ColumnNamesWithParamsList() - { idxSpec.clear(); } ( parameter=CreateParameter() { idxSpec.addAll(parameter); } )* { index.withColumns(colNames).withIndexSpec(new ArrayList(idxSpec)); indexes.add(index); } - // reset Token to null forcefullly + ) + | + LOOKAHEAD(3) ( { - tk2=null; - } - ) - | - LOOKAHEAD(3) ( {tk=null;} - [ tk= ] [ tk3= ] tk2= + tk=null; + idxSpec.clear(); + } + [ tk= ] + [ tk3= ] tk2= sk3=RelObjectName() - /* colNames=ColumnsNamesList() */ colNames = ColumnNamesWithParamsList() - { idxSpec.clear(); } ( parameter=CreateParameter() { idxSpec.addAll(parameter); } )* { index = new Index() - .withType((tk!=null?tk.image + " ":"") + (tk3!=null?tk3.image + " ":"") + tk2.image) - .withName(sk3) - .withColumns(colNames) - .withIndexSpec(new ArrayList(idxSpec)); + .withType( ( tk!=null ? tk.image + " " : "") + ( tk3!=null ? tk3.image + " ":"" ) + tk2.image) + .withName(sk3) + .withColumns(colNames) + .withIndexSpec(new ArrayList(idxSpec)); indexes.add(index); } - ) - | - LOOKAHEAD(3)( - { - fkIndex = new ForeignKeyIndex(); - } - [ sk3=RelObjectName() {fkIndex.setName(sk3);} ] - tk= tk2= - /* colNames=ColumnsNamesList() */ + ) + | + LOOKAHEAD(3)( + { + fkIndex = new ForeignKeyIndex(); + sk3=null; + + } + [ sk3=RelObjectName() { fkIndex.setName(sk3); } ] + tk= tk2= colNames = ColumnNamesWithParamsList() { fkIndex.withType(tk.image + " " + tk2.image).withColumns(colNames); @@ -6299,60 +6306,50 @@ CreateTable CreateTable(boolean isUsingOrReplace): fkIndex.setReferencedColumnNames(colNames2); indexes.add(fkIndex); } - [LOOKAHEAD(2) ( (tk= | tk=) action = Action() - { fkIndex.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } - )] - [LOOKAHEAD(2) ( (tk= | tk=) action = Action() - { fkIndex.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } - )] - ) - | - LOOKAHEAD(3)( - [ sk3 = RelObjectName()] - {Expression exp = null;} - ("(" exp = Expression() ")")* { - checkCs = new CheckConstraint().withName(sk3).withExpression(exp); - indexes.add(checkCs); - } - ) - | - LOOKAHEAD(2) tk= {excludeC = new ExcludeConstraint(); Expression exp = null;} - (tk2= - ("(" exp = Expression() ")")* {excludeC.setExpression(exp);}) - { - indexes.add(excludeC); - } - | - ( - - coldef = ColumnDefinition() - - /* - columnName=RelObjectName() - - colDataType = ColDataType() - { - columnSpecs = new ArrayList(); - } - - ( parameter=CreateParameter() { columnSpecs.addAll(parameter); } )* - - { - coldef = new ColumnDefinition(); - coldef.setColumnName(columnName); - coldef.setColDataType(colDataType); - if (columnSpecs.size() > 0) - coldef.setColumnSpecs(columnSpecs); - columnDefinitions.add(coldef); - } */ - { columnDefinitions.add(coldef); } + [ LOOKAHEAD(2) ( + + ( tk= | tk= ) action = Action() + { fkIndex.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } + ) + ] + [ LOOKAHEAD(2) ( + + ( tk= | tk=) action = Action() + { fkIndex.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } + ) + ] + ) + | + LOOKAHEAD(3)( + { + sk3 = null; + Expression exp = null; + } + [ sk3 = RelObjectName() ] + ( "(" exp = Expression() ")" )* + { + checkCs = new CheckConstraint().withName(sk3).withExpression(exp); + indexes.add(checkCs); + } + ) + | + LOOKAHEAD(2) tk= {excludeC = new ExcludeConstraint(); Expression exp = null;} + (tk2= + ("(" exp = Expression() ")")* {excludeC.setExpression(exp);}) + { + indexes.add(excludeC); + } + | + ( + coldef = ColumnDefinition() + { columnDefinitions.add(coldef); } + ) ) - ) - )* + )* - ")" + ")" ) - ) + ) ] ( LOOKAHEAD(2, { getToken(1).kind != K_AS }) parameter=CreateParameter() { tableOptions.addAll(parameter); } )* diff --git a/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java b/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java index d9c477159..6b2e67507 100644 --- a/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java @@ -1059,4 +1059,18 @@ void testIssue1864() throws JSQLParserException { + " CHARACTER SET armscii8 COLLATE armscii8_bin NULL DEFAULT NULL FIRST"; assertSqlCanBeParsedAndDeparsed(sqlStr, true); } + + @Test + void testUniqueAfterForeignKeyIssue2082() throws JSQLParserException { + String sqlStr = + "CREATE TABLE employees (\n" + + "employee_number int NOT NULL\n" + + ", employee_name char (50) NOT NULL\n" + + ", department_id int\n" + + ", salary int\n" + + ", PRIMARY KEY (employee_number)\n" + + ", FOREIGN KEY (department_id) REFERENCES departments(id)\n" + + ", UNIQUE (employee_name));"; + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } }