diff --git a/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java b/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java index 5e1d373ea..900c2deb9 100644 --- a/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java +++ b/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java @@ -36,6 +36,9 @@ public class AlterExpression implements Serializable { private List colDataTypeList; private List columnDropNotNullList; private List columnDropDefaultList; + private List columnSetDefaultList; + private List columnSetVisibilityList; + private List pkColumns; private List ukColumns; private String ukName; @@ -88,6 +91,10 @@ public class AlterExpression implements Serializable { private int keyBlockSize; + private String constraintSymbol; + private boolean enforced; + private String constraintType; + public Index getOldIndex() { return oldIndex; } @@ -302,6 +309,10 @@ public void addColDropNotNull(ColumnDropNotNull columnDropNotNull) { columnDropNotNullList.add(columnDropNotNull); } + public List getColumnDropDefaultList() { + return columnDropDefaultList; + } + public void addColDropDefault(ColumnDropDefault columnDropDefault) { if (columnDropDefaultList == null) { columnDropDefaultList = new ArrayList<>(); @@ -309,6 +320,28 @@ public void addColDropDefault(ColumnDropDefault columnDropDefault) { columnDropDefaultList.add(columnDropDefault); } + public void addColSetDefault(ColumnSetDefault columnSetDefault) { + if (columnSetDefaultList == null) { + columnSetDefaultList = new ArrayList<>(); + } + columnSetDefaultList.add(columnSetDefault); + } + + public List getColumnSetDefaultList() { + return columnSetDefaultList; + } + + public void addColSetVisibility(ColumnSetVisibility columnSetVisibility) { + if (columnSetVisibilityList == null) { + columnSetVisibilityList = new ArrayList<>(); + } + columnSetVisibilityList.add(columnSetVisibility); + } + + public List getColumnSetVisibilityList() { + return columnSetVisibilityList; + } + public List getFkSourceColumns() { return fkSourceColumns; } @@ -571,6 +604,30 @@ public int getKeyBlockSize() { return keyBlockSize; } + public String getConstraintSymbol() { + return constraintSymbol; + } + + public void setConstraintSymbol(String constraintSymbol) { + this.constraintSymbol = constraintSymbol; + } + + public boolean isEnforced() { + return enforced; + } + + public void setEnforced(boolean enforced) { + this.enforced = enforced; + } + + public String getConstraintType() { + return constraintType; + } + + public void setConstraintType(String constraintType) { + this.constraintType = constraintType; + } + @Override @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity", "PMD.ExcessiveMethodLength", "PMD.SwitchStmtsShouldHaveDefault"}) @@ -580,6 +637,38 @@ public String toString() { if (operation == AlterOperation.UNSPECIFIC) { b.append(optionalSpecifier); + } else if (operation == AlterOperation.ALTER && constraintType != null) { + b.append("ALTER"); + b.append(" ").append(constraintType); + + if (constraintSymbol != null) { + b.append(" ").append(constraintSymbol); + } + if (!isEnforced()) { + b.append(" NOT "); + } + b.append(" ENFORCED"); + } else if (operation == AlterOperation.ALTER + && columnDropDefaultList != null && !columnDropDefaultList.isEmpty()) { + b.append("ALTER "); + if (hasColumn) { + b.append("COLUMN "); + } + b.append(PlainSelect.getStringList(columnDropDefaultList)); + } else if (operation == AlterOperation.ALTER + && columnSetDefaultList != null && !columnSetDefaultList.isEmpty()) { + b.append("ALTER "); + if (hasColumn) { + b.append("COLUMN "); + } + b.append(PlainSelect.getStringList(columnSetDefaultList)); + } else if (operation == AlterOperation.ALTER + && columnSetVisibilityList != null && !columnSetVisibilityList.isEmpty()) { + b.append("ALTER "); + if (hasColumn) { + b.append("COLUMN "); + } + b.append(PlainSelect.getStringList(columnSetVisibilityList)); } else if (operation == AlterOperation.SET_TABLE_OPTION) { b.append(tableOption); } else if (operation == AlterOperation.DISCARD_TABLESPACE) { @@ -1139,6 +1228,52 @@ public String toString() { } } + public static final class ColumnSetDefault implements Serializable { + private final String columnName; + private final String defaultValue; + + public ColumnSetDefault(String columnName, String defaultValue) { + this.columnName = columnName; + this.defaultValue = defaultValue; + } + + public String getColumnName() { + return columnName; + } + + public String getDefaultValue() { + return defaultValue; + } + + @Override + public String toString() { + return columnName + " SET DEFAULT " + defaultValue; + } + } + + public static final class ColumnSetVisibility implements Serializable { + private final String columnName; + private final boolean visible; + + public ColumnSetVisibility(String columnName, boolean visible) { + this.columnName = columnName; + this.visible = visible; + } + + public String getColumnName() { + return columnName; + } + + public boolean isVisible() { + return visible; + } + + @Override + public String toString() { + return columnName + " SET " + (visible ? " VISIBLE" : " INVISIBLE"); + } + } + public enum ConvertType { CONVERT_TO, DEFAULT_CHARACTER_SET, CHARACTER_SET } 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 aaa07c4ea..b39a3014e 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 @@ -37,7 +37,11 @@ public List getColumnsNames() { } public void setColumnsNames(List list) { - columns = list.stream().map(ColumnParams::new).collect(toList()); + if (list == null) { + this.columns = Collections.emptyList(); + } else { + this.columns = list.stream().map(ColumnParams::new).collect(toList()); + } } @Deprecated @@ -159,7 +163,9 @@ public String toString() { (!name.isEmpty() ? " " + getName() : "") + (using != null ? " USING " + using : ""); - String tail = PlainSelect.getStringList(columns, true, true) + String tail = (columns != null && !columns.isEmpty() + ? PlainSelect.getStringList(columns, true, true) + : "") + (!idxSpecText.isEmpty() ? " " + idxSpecText : ""); return tail.isEmpty() ? head : head + " " + tail; diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 2a75a6c4c..cf627c4ff 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -253,6 +253,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -2153,7 +2154,7 @@ String RelObjectNameWithoutValue() : { Token tk = null; } { ( tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= - | tk="ACTION" | tk="ACTIVE" | tk="ADD" | tk="ADVANCE" | tk="ADVISE" | tk="AGAINST" | tk="AGGREGATE" | tk="ALGORITHM" | tk="ALTER" | tk="ANALYZE" | tk="APPLY" | tk="APPROXIMATE" | tk="ARCHIVE" | tk="ARRAY" | tk="ASC" | tk="AT" | tk="AUTHORIZATION" | tk="AUTO" | tk="AUTO_INCREMENT" | tk="BASE64" | tk="BEGIN" | tk="BERNOULLI" | tk="BINARY" | tk="BIT" | tk="BLOCK" | tk="BROWSE" | tk="BUFFERS" | tk="BY" | tk="BYTE" | tk="BYTES" | tk="CACHE" | tk="CALL" | tk="CASCADE" | tk="CASE" | tk="CAST" | tk="CHANGE" | tk="CHANGES" | tk="CHAR" | tk="CHARACTER" | tk="CHECKPOINT" | tk="CLOSE" | tk="COALESCE" | tk="COLLATE" | tk="COLUMN" | tk="COLUMNS" | tk="COMMENT" | tk="COMMIT" | tk="CONCURRENTLY" | tk="CONFLICT" | tk="CONSTRAINTS" | tk="CONVERT" | tk="CORRESPONDING" | tk="COSTS" | tk="COUNT" | tk="CS" | tk="CYCLE" | tk="DATA" | tk="DATABASE" | tk="DATETIME" | tk="DBA_RECYCLEBIN" | tk="DDL" | tk="DECLARE" | tk="DEFERRABLE" | tk="DELAYED" | tk="DELETE" | tk="DESC" | tk="DESCRIBE" | tk="DISABLE" | tk="DISCARD" | tk="DISCONNECT" | tk="DIV" | tk="DML" | tk="DO" | tk="DOMAIN" | tk="DROP" | tk="DUMP" | tk="DUPLICATE" | tk="ELEMENTS" | tk="EMIT" | tk="ENABLE" | tk="ENCRYPTION" | tk="END" | tk="ENGINE" | tk="ERROR" | tk="ESCAPE" | tk="EXCHANGE" | tk="EXCLUDE" | tk="EXEC" | tk="EXECUTE" | tk="EXPLAIN" | tk="EXPLICIT" | tk="EXTENDED" | tk="EXTRACT" | tk="FILTER" | tk="FIRST" | tk="FLUSH" | tk="FN" | tk="FOLLOWING" | tk="FORMAT" | tk="FULLTEXT" | tk="FUNCTION" | tk="GRANT" | tk="GROUP_CONCAT" | tk="GUARD" | tk="HASH" | tk="HIGH" | tk="HIGH_PRIORITY" | tk="HISTORY" | tk="HOPPING" | tk="IMPORT" | tk="INCLUDE" | tk="INCLUDE_NULL_VALUES" | tk="INCREMENT" | tk="INDEX" | tk="INSERT" | tk="INTERLEAVE" | tk="INTERPRET" | tk="INVALIDATE" | tk="INVERSE" | tk="INVISIBLE" | tk="ISNULL" | tk="JSON" | tk="JSON_ARRAY" | tk="JSON_ARRAYAGG" | tk="JSON_OBJECT" | tk="JSON_OBJECTAGG" | tk="KEEP" | tk="KEY" | tk="KEYS" | tk="KEY_BLOCK_SIZE" | tk="LAST" | tk="LEADING" | tk="LESS" | tk="LINK" | tk="LOCAL" | tk="LOCK" | tk="LOCKED" | tk="LOG" | tk="LONGTEXT" | tk="LOOP" | tk="LOW" | tk="LOW_PRIORITY" | tk="MATCH" | tk="MATCHED" | tk="MATCH_ALL" | tk="MATCH_ANY" | tk="MATCH_PHRASE" | tk="MATCH_PHRASE_PREFIX" | tk="MATCH_REGEXP" | tk="MATERIALIZED" | tk="MAX" | tk="MAXVALUE" | tk="MEDIUMTEXT" | tk="MEMBER" | tk="MERGE" | tk="MIN" | tk="MINVALUE" | tk="MODIFY" | tk="MOVEMENT" | tk="NAME" | tk="NEXT" | tk="NO" | tk="NOCACHE" | tk="NOKEEP" | tk="NOLOCK" | tk="NOMAXVALUE" | tk="NOMINVALUE" | tk="NOORDER" | tk="NOTHING" | tk="NOTNULL" | tk="NOVALIDATE" | tk="NOWAIT" | tk="NULLS" | tk="OF" | tk="OFF" | tk="OPEN" | tk="ORDINALITY" | tk="OVER" | tk="OVERFLOW" | tk="OVERLAPS" | tk="OVERRIDING" | tk="OVERWRITE" | tk="PARALLEL" | tk="PARENT" | tk="PARSER" | tk="PARTITION" | tk="PARTITIONING" | tk="PATH" | tk="PERCENT" | tk="PLACING" | tk="PLAN" | tk="PLUS" | tk="PRECEDING" | tk="PRIMARY" | tk="PURGE" | tk="QUERY" | tk="QUICK" | tk="QUIESCE" | tk="RANGE" | tk="RAW" | tk="READ" | tk="REBUILD" | tk="RECURSIVE" | tk="RECYCLEBIN" | tk="REFERENCES" | tk="REFRESH" | tk="REGEXP" | tk="REGEXP_LIKE" | tk="REGISTER" | tk="REMOTE" | tk="REMOVE" | tk="RENAME" | tk="REORGANIZE" | tk="REPAIR" | tk="REPEATABLE" | tk="REPLACE" | tk="RESET" | tk="RESPECT" | tk="RESTART" | tk="RESTRICT" | tk="RESTRICTED" | tk="RESUMABLE" | tk="RESUME" | tk="RETURN" | tk="RLIKE" | tk="ROLLBACK" | tk="ROLLUP" | tk="ROOT" | tk="ROW" | tk="ROWS" | tk="RR" | tk="RS" | tk="SAFE_CAST" | tk="SAVEPOINT" | tk="SCHEMA" | tk="SECURE" | tk="SEED" | tk="SEPARATOR" | tk="SEQUENCE" | tk="SESSION" | tk="SETS" | tk="SHARE" | tk="SHOW" | tk="SHUTDOWN" | tk="SIBLINGS" | tk="SIGNED" | tk="SIMILAR" | tk="SIZE" | tk="SKIP" | tk="SPATIAL" | tk="STORED" | tk="STRICT" | tk="STRING" | tk="STRUCT" | tk="SUMMARIZE" | tk="SUSPEND" | tk="SWITCH" | tk="SYNONYM" | tk="SYSTEM" | tk="TABLE" | tk="TABLESPACE" | tk="TEMP" | tk="TEMPORARY" | tk="TEXT" | tk="THAN" | tk="THEN" | tk="TIMEOUT" | tk="TIMESTAMPTZ" | tk="TIMEZONE" | tk="TINYTEXT" | tk="TO" | tk="TRIGGER" | tk="TRUNCATE" | tk="TRY_CAST" | tk="TUMBLING" | tk="TYPE" | tk="UNLOGGED" | tk="UNQIESCE" | tk="UNSIGNED" | tk="UPDATE" | tk="UPSERT" | tk="UR" | tk="USER" | tk="VALIDATE" | tk="VALIDATION" | tk="VERBOSE" | tk="VIEW" | tk="VISIBLE" | tk="VOLATILE" | tk="WAIT" | tk="WITHIN" | tk="WITHOUT" | tk="WITHOUT_ARRAY_WRAPPER" | tk="WORK" | tk="XML" | tk="XMLAGG" | tk="XMLDATA" | tk="XMLSCHEMA" | tk="XMLTEXT" | tk="XSINIL" | tk="YAML" | tk="YES" | tk="ZONE" ) + | tk="ACTION" | tk="ACTIVE" | tk="ADD" | tk="ADVANCE" | tk="ADVISE" | tk="AGAINST" | tk="AGGREGATE" | tk="ALGORITHM" | tk="ALTER" | tk="ANALYZE" | tk="APPLY" | tk="APPROXIMATE" | tk="ARCHIVE" | tk="ARRAY" | tk="ASC" | tk="AT" | tk="AUTHORIZATION" | tk="AUTO" | tk="AUTO_INCREMENT" | tk="BASE64" | tk="BEGIN" | tk="BERNOULLI" | tk="BINARY" | tk="BIT" | tk="BLOCK" | tk="BROWSE" | tk="BUFFERS" | tk="BY" | tk="BYTE" | tk="BYTES" | tk="CACHE" | tk="CALL" | tk="CASCADE" | tk="CASE" | tk="CAST" | tk="CHANGE" | tk="CHANGES" | tk="CHAR" | tk="CHARACTER" | tk="CHECKPOINT" | tk="CLOSE" | tk="COALESCE" | tk="COLLATE" | tk="COLUMN" | tk="COLUMNS" | tk="COMMENT" | tk="COMMIT" | tk="CONCURRENTLY" | tk="CONFLICT" | tk="CONSTRAINTS" | tk="CONVERT" | tk="CORRESPONDING" | tk="COSTS" | tk="COUNT" | tk="CS" | tk="CYCLE" | tk="DATA" | tk="DATABASE" | tk="DATETIME" | tk="DBA_RECYCLEBIN" | tk="DDL" | tk="DECLARE" | tk="DEFERRABLE" | tk="DELAYED" | tk="DELETE" | tk="DESC" | tk="DESCRIBE" | tk="DISABLE" | tk="DISCARD" | tk="DISCONNECT" | tk="DIV" | tk="DML" | tk="DO" | tk="DOMAIN" | tk="DROP" | tk="DUMP" | tk="DUPLICATE" | tk="ELEMENTS" | tk="EMIT" | tk="ENABLE" | tk="ENCRYPTION" | tk="END" | tk="ENFORCED" | tk="ENGINE" | tk="ERROR" | tk="ESCAPE" | tk="EXCHANGE" | tk="EXCLUDE" | tk="EXEC" | tk="EXECUTE" | tk="EXPLAIN" | tk="EXPLICIT" | tk="EXTENDED" | tk="EXTRACT" | tk="FILTER" | tk="FIRST" | tk="FLUSH" | tk="FN" | tk="FOLLOWING" | tk="FORMAT" | tk="FULLTEXT" | tk="FUNCTION" | tk="GRANT" | tk="GROUP_CONCAT" | tk="GUARD" | tk="HASH" | tk="HIGH" | tk="HIGH_PRIORITY" | tk="HISTORY" | tk="HOPPING" | tk="IMPORT" | tk="INCLUDE" | tk="INCLUDE_NULL_VALUES" | tk="INCREMENT" | tk="INDEX" | tk="INSERT" | tk="INTERLEAVE" | tk="INTERPRET" | tk="INVALIDATE" | tk="INVERSE" | tk="INVISIBLE" | tk="ISNULL" | tk="JSON" | tk="JSON_ARRAY" | tk="JSON_ARRAYAGG" | tk="JSON_OBJECT" | tk="JSON_OBJECTAGG" | tk="KEEP" | tk="KEY" | tk="KEYS" | tk="KEY_BLOCK_SIZE" | tk="LAST" | tk="LEADING" | tk="LESS" | tk="LINK" | tk="LOCAL" | tk="LOCK" | tk="LOCKED" | tk="LOG" | tk="LONGTEXT" | tk="LOOP" | tk="LOW" | tk="LOW_PRIORITY" | tk="MATCH" | tk="MATCHED" | tk="MATCH_ALL" | tk="MATCH_ANY" | tk="MATCH_PHRASE" | tk="MATCH_PHRASE_PREFIX" | tk="MATCH_REGEXP" | tk="MATERIALIZED" | tk="MAX" | tk="MAXVALUE" | tk="MEDIUMTEXT" | tk="MEMBER" | tk="MERGE" | tk="MIN" | tk="MINVALUE" | tk="MODIFY" | tk="MOVEMENT" | tk="NAME" | tk="NEXT" | tk="NO" | tk="NOCACHE" | tk="NOKEEP" | tk="NOLOCK" | tk="NOMAXVALUE" | tk="NOMINVALUE" | tk="NOORDER" | tk="NOTHING" | tk="NOTNULL" | tk="NOVALIDATE" | tk="NOWAIT" | tk="NULLS" | tk="OF" | tk="OFF" | tk="OPEN" | tk="ORDINALITY" | tk="OVER" | tk="OVERFLOW" | tk="OVERLAPS" | tk="OVERRIDING" | tk="OVERWRITE" | tk="PARALLEL" | tk="PARENT" | tk="PARSER" | tk="PARTITION" | tk="PARTITIONING" | tk="PATH" | tk="PERCENT" | tk="PLACING" | tk="PLAN" | tk="PLUS" | tk="PRECEDING" | tk="PRIMARY" | tk="PURGE" | tk="QUERY" | tk="QUICK" | tk="QUIESCE" | tk="RANGE" | tk="RAW" | tk="READ" | tk="REBUILD" | tk="RECURSIVE" | tk="RECYCLEBIN" | tk="REFERENCES" | tk="REFRESH" | tk="REGEXP" | tk="REGEXP_LIKE" | tk="REGISTER" | tk="REMOTE" | tk="REMOVE" | tk="RENAME" | tk="REORGANIZE" | tk="REPAIR" | tk="REPEATABLE" | tk="REPLACE" | tk="RESET" | tk="RESPECT" | tk="RESTART" | tk="RESTRICT" | tk="RESTRICTED" | tk="RESUMABLE" | tk="RESUME" | tk="RETURN" | tk="RLIKE" | tk="ROLLBACK" | tk="ROLLUP" | tk="ROOT" | tk="ROW" | tk="ROWS" | tk="RR" | tk="RS" | tk="SAFE_CAST" | tk="SAVEPOINT" | tk="SCHEMA" | tk="SECURE" | tk="SEED" | tk="SEPARATOR" | tk="SEQUENCE" | tk="SESSION" | tk="SETS" | tk="SHARE" | tk="SHOW" | tk="SHUTDOWN" | tk="SIBLINGS" | tk="SIGNED" | tk="SIMILAR" | tk="SIZE" | tk="SKIP" | tk="SPATIAL" | tk="STORED" | tk="STRICT" | tk="STRING" | tk="STRUCT" | tk="SUMMARIZE" | tk="SUSPEND" | tk="SWITCH" | tk="SYNONYM" | tk="SYSTEM" | tk="TABLE" | tk="TABLESPACE" | tk="TEMP" | tk="TEMPORARY" | tk="TEXT" | tk="THAN" | tk="THEN" | tk="TIMEOUT" | tk="TIMESTAMPTZ" | tk="TIMEZONE" | tk="TINYTEXT" | tk="TO" | tk="TRIGGER" | tk="TRUNCATE" | tk="TRY_CAST" | tk="TUMBLING" | tk="TYPE" | tk="UNLOGGED" | tk="UNQIESCE" | tk="UNSIGNED" | tk="UPDATE" | tk="UPSERT" | tk="UR" | tk="USER" | tk="VALIDATE" | tk="VALIDATION" | tk="VERBOSE" | tk="VIEW" | tk="VISIBLE" | tk="VOLATILE" | tk="WAIT" | tk="WITHIN" | tk="WITHOUT" | tk="WITHOUT_ARRAY_WRAPPER" | tk="WORK" | tk="XML" | tk="XMLAGG" | tk="XMLDATA" | tk="XMLSCHEMA" | tk="XMLTEXT" | tk="XSINIL" | tk="YAML" | tk="YES" | tk="ZONE" ) { return tk.image; } } @@ -7614,6 +7615,34 @@ AlterExpression.ColumnDropDefault AlterExpressionColumnDropDefault(): } } +AlterExpression.ColumnSetDefault AlterExpressionColumnSetDefault(): +{ + String columnName = null; + Expression defaultValue = null; +} +{ + columnName = RelObjectName() defaultValue = Expression() + { + return new AlterExpression.ColumnSetDefault(columnName, defaultValue.toString()); + } +} + +AlterExpression.ColumnSetVisibility AlterExpressionColumnSetVisibility(): +{ + String columnName = null; + boolean visible = true; +} +{ + columnName = RelObjectName() + ( + { visible = true; } | + { visible = false; } + ) + { + return new AlterExpression.ColumnSetVisibility(columnName, visible); + } +} + List AlterExpressionConstraintState(): { List retval = new ArrayList(); @@ -7809,6 +7838,8 @@ AlterExpression AlterExpression(): AlterExpression.ColumnDataType alterExpressionColumnDataType = null; AlterExpression.ColumnDropNotNull alterExpressionColumnDropNotNull = null; AlterExpression.ColumnDropDefault alterExpressionColumnDropDefault = null; + AlterExpression.ColumnSetDefault alterExpressionColumnSetDefault = null; + AlterExpression.ColumnSetVisibility alterExpressionColumnSetVisibility = null; ReferentialAction.Action action = null; List partitions = null; List partitionDefinition = null; @@ -7844,11 +7875,11 @@ AlterExpression AlterExpression(): ( LOOKAHEAD(3) sk3 = RelObjectName() - [ sk4 = UsingIndexType() ] - columnNames = ColumnsNamesList() + [ LOOKAHEAD(2) sk4 = UsingIndexType() ] + [ LOOKAHEAD(2) columnNames = ColumnsNamesList() ] | - [ sk4 = UsingIndexType() ] - columnNames = ColumnsNamesList() + [ LOOKAHEAD(2) sk4 = UsingIndexType() ] + [ LOOKAHEAD(2) columnNames = ColumnsNamesList() ] ) IndexOptionList(indexSpec = new ArrayList()) { @@ -7915,6 +7946,15 @@ AlterExpression AlterExpression(): )? [ { alterExp.setUseIfNotExists(true); } ] ( + LOOKAHEAD(3) alterExpressionColumnDropDefault = AlterExpressionColumnDropDefault() + { alterExp.addColDropDefault(alterExpressionColumnDropDefault); } + | + LOOKAHEAD(3) alterExpressionColumnSetDefault = AlterExpressionColumnSetDefault() + { alterExp.addColSetDefault(alterExpressionColumnSetDefault); } + | + LOOKAHEAD(3) alterExpressionColumnSetVisibility = AlterExpressionColumnSetVisibility() + { alterExp.addColSetVisibility(alterExpressionColumnSetVisibility); } + | LOOKAHEAD(4) ( "(" { alterExp.useBrackets(true);} @@ -7935,12 +7975,18 @@ AlterExpression AlterExpression(): | LOOKAHEAD(3) alterExpressionColumnDropNotNull = AlterExpressionColumnDropNotNull() { alterExp.addColDropNotNull( alterExpressionColumnDropNotNull);} - | - alterExpressionColumnDropDefault = AlterExpressionColumnDropDefault() - { alterExp.addColDropDefault( alterExpressionColumnDropDefault); } ) ) | + LOOKAHEAD(3) alterExpressionColumnDropDefault = AlterExpressionColumnDropDefault() + { alterExp.addColDropDefault(alterExpressionColumnDropDefault); } + | + LOOKAHEAD(3) alterExpressionColumnSetDefault = AlterExpressionColumnSetDefault() + { alterExp.addColSetDefault(alterExpressionColumnSetDefault); } + | + LOOKAHEAD(3) alterExpressionColumnSetVisibility = AlterExpressionColumnSetVisibility() + { alterExp.addColSetVisibility(alterExpressionColumnSetVisibility); } + | ( "(" alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } ("," @@ -7976,84 +8022,105 @@ AlterExpression AlterExpression(): )] ) | + LOOKAHEAD(3) ( + sk3=RelObjectName() + { boolean enforced = true; } + [ tk = { enforced = false; } ] + { + alterExp.setEnforced(enforced); + alterExp.setConstraintType("CHECK"); + alterExp.setConstraintSymbol(sk3); + } + ) + | ( sk3=RelObjectName() ( - ( tk= tk2= - columnNames=ColumnsNamesList() - { - fkIndex = new ForeignKeyIndex() - .withName(sk3) - .withType(tk.image + " " + tk2.image) - .withColumnsNames(columnNames); - columnNames = null; - } - fkTable=Table() [ LOOKAHEAD(2) columnNames=ColumnsNamesList() ] - { - fkIndex.withTable(fkTable).withReferencedColumnNames(columnNames); - alterExp.setIndex(fkIndex); - } + ( tk= tk2= + columnNames=ColumnsNamesList() + { + fkIndex = new ForeignKeyIndex() + .withName(sk3) + .withType(tk.image + " " + tk2.image) + .withColumnsNames(columnNames); + columnNames = null; + } + fkTable=Table() [ LOOKAHEAD(2) columnNames=ColumnsNamesList() ] + { + fkIndex.withTable(fkTable).withReferencedColumnNames(columnNames); + 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); } - )] - constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } - ) - | - ( tk= tk2= - columnNames=ColumnsNamesList() - { - index = new NamedConstraint() - .withName(sk3) - .withType(tk.image + " " + tk2.image) - .withColumnsNames(columnNames); - alterExp.setIndex(index); - } - constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } - [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] - [ LOOKAHEAD(2) index = IndexWithComment(index) { alterExp.setIndex(index); } ] - ) - | - ( - {Expression exp = null;} (LOOKAHEAD(2) "(" exp = Expression() ")")* { - CheckConstraint checkCs = new CheckConstraint().withName(sk3).withExpression(exp); - alterExp.setIndex(checkCs); - } - ) - | - ( - tk= (tk2= { alterExp.setUk(true); } | tk2=)? - columnNames=ColumnsNamesList() - { - index = new NamedConstraint() + [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); } + ) + | + ( tk= tk2= + columnNames=ColumnsNamesList() + { + index = new NamedConstraint() .withName(sk3) - .withType(tk.image + (tk2!=null?" " + tk2.image:"")) + .withType(tk.image + " " + tk2.image) .withColumnsNames(columnNames); - alterExp.setIndex(index); - } - constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } - [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] - [ LOOKAHEAD(2) 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); } + alterExp.setIndex(index); + } + constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } + [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ LOOKAHEAD(2) index = IndexWithComment(index) { alterExp.setIndex(index); } ] + ) + | + LOOKAHEAD(2) ( + { boolean enforced = true; } + [ tk = { enforced = false; } ] + { + alterExp.setEnforced(enforced); + alterExp.setConstraintType("CONSTRAINT"); + alterExp.setConstraintSymbol(sk3); + } + ) + | + ( + {Expression exp = null;} (LOOKAHEAD(2) "(" exp = Expression() ")")* { + CheckConstraint checkCs = new CheckConstraint().withName(sk3).withExpression(exp); + alterExp.setIndex(checkCs); + } + ) + | + ( + tk= (tk2= { alterExp.setUk(true); } | tk2=)? + columnNames=ColumnsNamesList() + { + index = new NamedConstraint() + .withName(sk3) + .withType(tk.image + (tk2!=null?" " + tk2.image:"")) + .withColumnsNames(columnNames); + alterExp.setIndex(index); + } + constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } + [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ LOOKAHEAD(2) 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); } + ) ) - ) ) - ) + ) ) | ( 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 204600bb1..a1a9b46d4 100644 --- a/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java @@ -9,6 +9,13 @@ */ package net.sf.jsqlparser.statement.alter; +import static net.sf.jsqlparser.test.TestUtils.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.StringValue; import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo; @@ -28,15 +35,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Stream; - -import static net.sf.jsqlparser.test.TestUtils.*; -import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; -import static org.junit.jupiter.api.Assertions.*; - public class AlterTest { @Test @@ -83,7 +81,6 @@ public void testAlterTableAddColumn_ColumnKeyWordImplicit() throws JSQLParserExc assertEquals("varchar (255)", colDataTypes.get(0).getColDataType().toString()); } - @Test public void testAlterTableBackBrackets() throws JSQLParserException { String sql = "ALTER TABLE tablename add column (field string comment 'aaaaa')"; @@ -97,7 +94,6 @@ public void testAlterTableBackBrackets() throws JSQLParserException { assertEquals("tablename", alter2.getTable().toString()); } - @Test public void testAlterTableIssue1815() throws JSQLParserException { // MySQL: see https://dev.mysql.com/doc/refman/8.0/en/alter-table.html @@ -1350,7 +1346,6 @@ public void testIssue2106AlterTableTruncatePartition() throws JSQLParserExceptio assertEquals("p201807", partitionNames.get(3)); } - @Test public void testIssue2114AlterTableEncryption() throws JSQLParserException { String sql = "ALTER TABLE confidential_data ENCRYPTION = 'Y'"; @@ -2002,4 +1997,145 @@ public void testAlterTableAddIndex_UsingBeforeColumns() throws JSQLParserExcepti assertSqlCanBeParsedAndDeparsed(sql); } + + @Test + public void testAlterTableSetDefaultWithAlgorithm() throws JSQLParserException { + String sql = "ALTER TABLE t2 ALTER COLUMN b SET DEFAULT 100, ALGORITHM = INSTANT"; + Alter alter = (Alter) CCJSqlParserUtil.parse(sql); + + assertEquals("t2", alter.getTable().getFullyQualifiedName()); + List alterExpressions = alter.getAlterExpressions(); + assertNotNull(alterExpressions); + assertEquals(2, alterExpressions.size()); + + AlterExpression setDefaultExp = alterExpressions.get(0); + assertEquals(AlterOperation.ALTER, setDefaultExp.getOperation()); + assertEquals("b", setDefaultExp.getColumnSetDefaultList().get(0).getColumnName()); + assertEquals("100", setDefaultExp.getColumnSetDefaultList().get(0).getDefaultValue()); + + AlterExpression algorithmExp = alterExpressions.get(1); + assertEquals(AlterOperation.ALGORITHM, algorithmExp.getOperation()); + assertEquals("INSTANT", algorithmExp.getAlgorithmOption()); + + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testAlterTableDropDefaultWithAlgorithm() throws JSQLParserException { + String sql = "ALTER TABLE t2 ALTER COLUMN b DROP DEFAULT, ALGORITHM = INSTANT"; + Alter alter = (Alter) CCJSqlParserUtil.parse(sql); + + assertEquals("t2", alter.getTable().getFullyQualifiedName()); + List alterExpressions = alter.getAlterExpressions(); + assertNotNull(alterExpressions); + assertEquals(2, alterExpressions.size()); + + AlterExpression dropDefaultExp = alterExpressions.get(0); + assertEquals(AlterOperation.ALTER, dropDefaultExp.getOperation()); + assertEquals("b", dropDefaultExp.getColumnDropDefaultList().get(0).getColumnName()); + + AlterExpression algorithmExp = alterExpressions.get(1); + assertEquals(AlterOperation.ALGORITHM, algorithmExp.getOperation()); + assertEquals("INSTANT", algorithmExp.getAlgorithmOption()); + + assertSqlCanBeParsedAndDeparsed(sql); + } + + + @Test + public void testAlterTableColumnSetInvisible() throws JSQLParserException { + String sql = "ALTER TABLE tbl ALTER COLUMN ts SET INVISIBLE"; + Alter alter = (Alter) CCJSqlParserUtil.parse(sql); + + assertEquals("tbl", alter.getTable().getFullyQualifiedName()); + List alterExpressions = alter.getAlterExpressions(); + assertNotNull(alterExpressions); + assertEquals(1, alterExpressions.size()); + + AlterExpression setInvisibleExp = alterExpressions.get(0); + assertEquals(AlterOperation.ALTER, setInvisibleExp.getOperation()); + assertEquals("ts", setInvisibleExp.getColumnSetVisibilityList().get(0).getColumnName()); + assertFalse(setInvisibleExp.getColumnSetVisibilityList().get(0).isVisible()); + + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testAlterTableSetInvisible() throws JSQLParserException { + String sql = "ALTER TABLE tbl ALTER ts SET INVISIBLE"; + Alter alter = (Alter) CCJSqlParserUtil.parse(sql); + + assertEquals("tbl", alter.getTable().getFullyQualifiedName()); + List alterExpressions = alter.getAlterExpressions(); + assertNotNull(alterExpressions); + assertEquals(1, alterExpressions.size()); + + AlterExpression setInvisibleExp = alterExpressions.get(0); + assertEquals(AlterOperation.ALTER, setInvisibleExp.getOperation()); + assertEquals("ts", setInvisibleExp.getColumnSetVisibilityList().get(0).getColumnName()); + assertFalse(setInvisibleExp.getColumnSetVisibilityList().get(0).isVisible()); + + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testAlterIndexVisibility() throws JSQLParserException { + String sql = "ALTER TABLE tbl_name ALTER INDEX idx_name VISIBLE"; + Alter alterVisible = (Alter) CCJSqlParserUtil.parse(sql); + + assertEquals("tbl_name", alterVisible.getTable().getFullyQualifiedName()); + List alterExpressionsVisible = alterVisible.getAlterExpressions(); + assertNotNull(alterExpressionsVisible); + assertEquals(1, alterExpressionsVisible.size()); + + AlterExpression visibleExp = alterExpressionsVisible.get(0); + assertEquals(AlterOperation.ALTER, visibleExp.getOperation()); + assertEquals("idx_name", visibleExp.getIndex().getName()); + assertEquals("VISIBLE", visibleExp.getIndex().getIndexSpec().get(0)); + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testAlterTableAlterConstraintEnforced() throws JSQLParserException { + String sql = "ALTER TABLE employees ALTER CONSTRAINT chk_salary ENFORCED"; + Statement stmt = CCJSqlParserUtil.parse(sql); + assertInstanceOf(Alter.class, stmt); + + Alter alter = (Alter) stmt; + assertEquals("employees", alter.getTable().getFullyQualifiedName()); + + List alterExpressions = alter.getAlterExpressions(); + assertNotNull(alterExpressions); + assertEquals(1, alterExpressions.size()); + + AlterExpression alterConstraintExp = alterExpressions.get(0); + assertEquals(AlterOperation.ALTER, alterConstraintExp.getOperation()); + assertEquals("CONSTRAINT", alterConstraintExp.getConstraintType()); + assertEquals("chk_salary", alterConstraintExp.getConstraintSymbol()); + assertTrue(alterConstraintExp.isEnforced()); + + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testAlterTableAlterCheckNotEnforced() throws JSQLParserException { + String sql = "ALTER TABLE employees ALTER CHECK chk_salary NOT ENFORCED"; + Statement stmt = CCJSqlParserUtil.parse(sql); + assertInstanceOf(Alter.class, stmt); + + Alter alter = (Alter) stmt; + assertEquals("employees", alter.getTable().getFullyQualifiedName()); + + List alterExpressions = alter.getAlterExpressions(); + assertNotNull(alterExpressions); + assertEquals(1, alterExpressions.size()); + + AlterExpression alterCheckExp = alterExpressions.get(0); + assertEquals(AlterOperation.ALTER, alterCheckExp.getOperation()); + assertEquals("CHECK", alterCheckExp.getConstraintType()); + assertEquals("chk_salary", alterCheckExp.getConstraintSymbol()); + assertFalse(alterCheckExp.isEnforced()); + + assertSqlCanBeParsedAndDeparsed(sql); + } }