diff --git a/src/main/java/net/sf/jsqlparser/statement/create/table/Index.java b/src/main/java/net/sf/jsqlparser/statement/create/table/Index.java index 93b672c96..651bbe66c 100644 --- a/src/main/java/net/sf/jsqlparser/statement/create/table/Index.java +++ b/src/main/java/net/sf/jsqlparser/statement/create/table/Index.java @@ -26,6 +26,7 @@ public class Index implements Serializable { private List columns; private final List name = new ArrayList<>(); private List idxSpec; + private String commentText; public List getColumnsNames() { return columns.stream() @@ -142,6 +143,11 @@ public String toString() { return head; } + // MYSQL: ALTER TABLE ADD INDEX COMMENT 'comment' + if (getCommentText() != null) { + return head + " " + tail + " COMMENT " + getCommentText(); + } + return head + " " + tail; } @@ -192,4 +198,12 @@ public String toString() { return columnName + (params != null ? " " + String.join(" ", params) : ""); } } + + public String getCommentText() { + return commentText; + } + + public void setCommentText(String commentText) { + this.commentText = commentText; + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/create/table/NamedConstraint.java b/src/main/java/net/sf/jsqlparser/statement/create/table/NamedConstraint.java index 8f188ebc8..b44b7a114 100644 --- a/src/main/java/net/sf/jsqlparser/statement/create/table/NamedConstraint.java +++ b/src/main/java/net/sf/jsqlparser/statement/create/table/NamedConstraint.java @@ -18,9 +18,16 @@ public class NamedConstraint extends Index { @Override public String toString() { String idxSpecText = PlainSelect.getStringList(getIndexSpec(), false, false); - return (getName() != null ? "CONSTRAINT " + getName() + " " : "") - + getType() + " " + PlainSelect.getStringList(getColumnsNames(), true, true) + (!"". - equals(idxSpecText) ? " " + idxSpecText : ""); + String head = getName() != null ? "CONSTRAINT " + getName() + " " : ""; + String tail = getType() + " " + PlainSelect.getStringList(getColumnsNames(), true, true) + + (!"".equals(idxSpecText) ? " " + idxSpecText : ""); + + // MYSQL: ALTER TABLE ADD CONSTRAINT COMMENT 'comment' + if (getCommentText() != null) { + return head + tail + " COMMENT " + getCommentText(); + } + + return head + tail; } @Override diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 824f6d6ce..a8cda9de0 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -6160,6 +6160,18 @@ List AlterExpressionConstraintState(): } } +Index IndexWithComment(Index index): +{ + Token tk = null; +} +{ + tk= { + index.setCommentText(tk.image); + } + { + return index; + } +} /** * This production needs refactoring to multiple smaller productions. The target class should @@ -6191,17 +6203,15 @@ AlterExpression AlterExpression(): ( ( ( - { alterExp.setOperation(AlterOperation.ADD); } + { alterExp.setOperation(AlterOperation.ADD); } | - { alterExp.setOperation(AlterOperation.ALTER); } + { alterExp.setOperation(AlterOperation.ALTER); } | { alterExp.setOperation(AlterOperation.MODIFY); } ) ( - LOOKAHEAD(2) ( - columnNames=ColumnsNamesList() { alterExp.setPkColumns(columnNames); } - ) + LOOKAHEAD(2) ( columnNames=ColumnsNamesList() { alterExp.setPkColumns(columnNames); }) constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] @@ -6214,6 +6224,7 @@ AlterExpression AlterExpression(): index = new Index().withType(tk.image).withName(sk3).withColumnsNames(columnNames); alterExp.setIndex(index); } + [ index = IndexWithComment(index) { alterExp.setIndex(index); } ] constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] ) @@ -6223,47 +6234,50 @@ AlterExpression AlterExpression(): ( LOOKAHEAD(4) ( - "(" { alterExp.useBrackets(true);} + "(" + { alterExp.useBrackets(true);} alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } ( "," alterExpressionColumnDataType = AlterExpressionColumnDataType() { - alterExp.addColDataType(alterExpressionColumnDataType); - } + alterExp.addColDataType(alterExpressionColumnDataType); + } )* - ")" - ) + ")" + ) | - LOOKAHEAD(2) alterExpressionColumnDataType = AlterExpressionColumnDataType() { - alterExp.addColDataType(alterExpressionColumnDataType); - } + LOOKAHEAD(2) alterExpressionColumnDataType = AlterExpressionColumnDataType() + { alterExp.addColDataType(alterExpressionColumnDataType); } | - LOOKAHEAD(3) alterExpressionColumnDropNotNull = AlterExpressionColumnDropNotNull() { - alterExp.addColDropNotNull( alterExpressionColumnDropNotNull); - } + LOOKAHEAD(3) alterExpressionColumnDropNotNull = AlterExpressionColumnDropNotNull() + { alterExp.addColDropNotNull( alterExpressionColumnDropNotNull);} | - alterExpressionColumnDropDefault = AlterExpressionColumnDropDefault() { - alterExp.addColDropDefault( alterExpressionColumnDropDefault); - } + alterExpressionColumnDropDefault = AlterExpressionColumnDropDefault() + { alterExp.addColDropDefault( alterExpressionColumnDropDefault); } ) ) | ( "(" alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } - ("," alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } )* ")" + ("," + alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } + )* + ")" ) | ( (( { alterExp.setUk(true); } | ) (tk= | tk=) { alterExp.setUkName(tk.image); } )? columnNames=ColumnsNamesList() { alterExp.setUkColumns(columnNames); } - [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }]) + [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ index = IndexWithComment(index) { alterExp.setIndex(index); } ] + ) | //following two choices regarding foreign keys should be merged ( columnNames=ColumnsNamesList() { alterExp.setFkColumns(columnNames); columnNames = null; } /* tk= [ columnNames=ColumnsNamesList() ] - { alterExp.setFkSourceTable(tk.image); alterExp.setFkSourceColumns(columnNames); } + { alterExp.setFkSourceTable(tk.image); alterExp.setFkSourceColumns(columnNames); } */ fkTable=Table() [ columnNames=ColumnsNamesList() ] { @@ -6273,17 +6287,17 @@ AlterExpression AlterExpression(): } [LOOKAHEAD(2) ( (tk= | tk=) action = Action() - { alterExp.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } - )] + { alterExp.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } + )] [LOOKAHEAD(2) ( (tk= | tk=) action = Action() - { alterExp.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } - )] + { alterExp.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } + )] ) | ( sk3=RelObjectName() - - ( ( tk= tk2= + ( + ( tk= tk2= columnNames=ColumnsNamesList() { fkIndex = new ForeignKeyIndex() @@ -6298,12 +6312,12 @@ AlterExpression AlterExpression(): alterExp.setIndex(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(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); } + )] constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } ) | @@ -6318,13 +6332,14 @@ AlterExpression AlterExpression(): } constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ index = IndexWithComment(index) { alterExp.setIndex(index); } ] ) | ( {Expression exp = null;} ("(" exp = Expression() ")")* { - CheckConstraint checkCs = new CheckConstraint().withName(sk3).withExpression(exp); - alterExp.setIndex(checkCs); - } + CheckConstraint checkCs = new CheckConstraint().withName(sk3).withExpression(exp); + alterExp.setIndex(checkCs); + } ) | ( @@ -6339,28 +6354,25 @@ AlterExpression AlterExpression(): } constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ index = IndexWithComment(index) { alterExp.setIndex(index); } ] ) | ( tk= - columnNames=ColumnsNamesList() - { - index = new NamedConstraint() - .withName(sk3) - .withType(tk.image) - .withColumnsNames(columnNames); - alterExp.setIndex(index); - } - constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } + columnNames=ColumnsNamesList() + { + index = new NamedConstraint() + .withName(sk3) + .withType(tk.image) + .withColumnsNames(columnNames); + alterExp.setIndex(index); + } + constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } ) - ) + ) ) | - ( sk3=RelObjectName() - tk= { - alterExp.withColumnName(sk3).withCommentText(tk.image); - } - ) + ( sk3=RelObjectName() tk= { alterExp.withColumnName(sk3).withCommentText(tk.image); } ) ) ) | @@ -6373,7 +6385,7 @@ AlterExpression AlterExpression(): ) ) | - { alterExp.setOperation(AlterOperation.DROP); } + { alterExp.setOperation(AlterOperation.DROP); } ( ( ( @@ -6406,9 +6418,9 @@ AlterExpression AlterExpression(): ( ( tk= | tk= ) ( tk2= | tk2= ) { - index = new Index().withType(tk.image).withName(tk2.image); - alterExp.setIndex(index); - } + index = new Index().withType(tk.image).withName(tk2.image); + alterExp.setIndex(index); + } ) | ( @@ -6435,18 +6447,18 @@ AlterExpression AlterExpression(): ) ) | - ( - { + ( + { alterExp.setOperation(AlterOperation.ALGORITHM); } ["=" { alterExp.setUseEqual(true);} ] sk3 = RelObjectName() {alterExp.addParameters(sk3); } - ) + ) | - LOOKAHEAD(2) { alterExp.setOperation(AlterOperation.RENAME); } [ { alterExp.hasColumn(true);} ] - ( tk= | tk= ) { alterExp.setColOldName(tk.image); } + LOOKAHEAD(2) { alterExp.setOperation(AlterOperation.RENAME); } [ { alterExp.hasColumn(true);} ] + ( tk= | tk= ) { alterExp.setColOldName(tk.image); } - (tk2= | tk2=) { alterExp.setColumnName(tk2.image); } + (tk2= | tk2=) { alterExp.setColumnName(tk2.image); } | ( {alterExp.setOperation(AlterOperation.RENAME_TABLE);} @@ -6471,7 +6483,7 @@ AlterExpression AlterExpression(): } alterExp.setOptionalSpecifier( optionalSpecifier.toString() ); - } + } ) { diff --git a/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java b/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java index 0a6dc77fd..881af7c2e 100644 --- a/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java @@ -873,6 +873,23 @@ public void testAlterTableDropMultipleColumnsIfExists() throws JSQLParserExcepti "ALTER TABLE test DROP COLUMN IF EXISTS name, DROP COLUMN IF EXISTS surname"); } + @Test + public void testAlterTableAddIndexWithComment1906() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE `student` ADD KEY `idx_name` (`name`) COMMENT 'name'"); + } + + @Test + public void testAlterTableAddIndexWithComment2() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE team_phases ADD CONSTRAINT team_phases_id_key UNIQUE (id) COMMENT 'name'"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE team_phases ADD CONSTRAINT team_phases_id_key UNIQUE KEY (c1, c2) COMMENT 'name'"); + + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE team_phases ADD CONSTRAINT team_phases_id_key PRIMARY KEY (id) COMMENT 'name'"); + } + @Test public void testAlterTableDropMultipleColumnsIfExistsWithParams() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed(