Skip to content

Commit c958e93

Browse files
committed
Merge upstream master and resolve CREATE TABLE grammar conflict
Signed-off-by: minleejae <mmj9808@gmail.com>
2 parents 5798b83 + 17be330 commit c958e93

9 files changed

Lines changed: 573 additions & 30 deletions

File tree

‎src/main/java/net/sf/jsqlparser/schema/Sequence.java‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ public Sequence addParameters(Collection<? extends Parameter> parameters) {
187187
* The available parameters to a sequence
188188
*/
189189
public enum ParameterType {
190-
INCREMENT_BY, INCREMENT, START_WITH, START, RESTART_WITH, MAXVALUE, NOMAXVALUE, MINVALUE, NOMINVALUE, CYCLE, NOCYCLE, CACHE, NOCACHE, ORDER, NOORDER, KEEP, NOKEEP, SESSION, GLOBAL, NO_MINVALUE, NO_MAXVALUE, NO_CYCLE;
190+
INCREMENT_BY, INCREMENT, START_WITH, START, RESTART_WITH, MAXVALUE, NOMAXVALUE, MINVALUE, NOMINVALUE, CYCLE, NOCYCLE, CACHE, NOCACHE, ORDER, NOORDER, KEEP, NOKEEP, SESSION, GLOBAL, NO_MINVALUE, NO_MAXVALUE, NO_CYCLE, SEQUENCE_NAME;
191191

192192
public static ParameterType from(String type) {
193193
return Enum.valueOf(ParameterType.class, type.toUpperCase(Locale.ROOT));
@@ -201,6 +201,7 @@ public static class Parameter implements java.io.Serializable {
201201

202202
private final ParameterType option;
203203
private Long value;
204+
private Sequence sequenceName;
204205

205206
public Parameter(ParameterType option) {
206207
this.option = option;
@@ -214,6 +215,20 @@ public ParameterType getOption() {
214215
return option;
215216
}
216217

218+
/** The sequence named by an identity declaration's SEQUENCE NAME option. */
219+
public Sequence getSequenceName() {
220+
return sequenceName;
221+
}
222+
223+
public void setSequenceName(Sequence sequenceName) {
224+
this.sequenceName = sequenceName;
225+
}
226+
227+
public Parameter withSequenceName(Sequence sequenceName) {
228+
setSequenceName(sequenceName);
229+
return this;
230+
}
231+
217232
@Override
218233
public String toString() {
219234
return formatParameter();
@@ -225,6 +240,8 @@ public void setValue(Long value) {
225240

226241
public String formatParameter() {
227242
switch (option) {
243+
case SEQUENCE_NAME:
244+
return "SEQUENCE NAME " + sequenceName.getFullyQualifiedName();
228245
case INCREMENT_BY:
229246
return prefix("INCREMENT BY");
230247
case INCREMENT:

‎src/main/java/net/sf/jsqlparser/statement/ReferentialAction.java‎

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@
1111

1212
import java.io.Serializable;
1313
import java.util.Locale;
14+
import java.util.List;
15+
import java.util.Objects;
16+
import net.sf.jsqlparser.statement.select.PlainSelect;
1417

1518
public class ReferentialAction implements Serializable {
1619

1720
private Type type;
1821
private Action action;
22+
private List<String> columnNames;
1923

2024
public ReferentialAction() {
2125
// default constructor
@@ -52,6 +56,20 @@ public ReferentialAction withAction(Action action) {
5256
return this;
5357
}
5458

59+
/** Columns affected by PostgreSQL ON DELETE SET NULL or SET DEFAULT; null means all columns. */
60+
public List<String> getColumnNames() {
61+
return columnNames;
62+
}
63+
64+
public void setColumnNames(List<String> columnNames) {
65+
this.columnNames = columnNames;
66+
}
67+
68+
public ReferentialAction withColumnNames(List<String> columnNames) {
69+
setColumnNames(columnNames);
70+
return this;
71+
}
72+
5573
@Override
5674
public int hashCode() {
5775
final int prime = 31;
@@ -64,7 +82,9 @@ public int hashCode() {
6482
@Override
6583
public String toString() {
6684
return " ON " + getType().name() + " " +
67-
getAction().getAction();
85+
getAction().getAction()
86+
+ (columnNames == null ? ""
87+
: " " + PlainSelect.getStringList(columnNames, true, true));
6888
}
6989

7090
@Override
@@ -79,12 +99,8 @@ public boolean equals(Object obj) {
7999
return false;
80100
}
81101
ReferentialAction other = (ReferentialAction) obj;
82-
// if (action != other.action) {
83-
// return false;
84-
// }
85-
// if (type != other.type) {
86-
// return false;
87-
return action == other.action && type == other.type;
102+
return action == other.action && type == other.type
103+
&& Objects.equals(columnNames, other.columnNames);
88104
}
89105

90106
public enum Type {

‎src/main/java/net/sf/jsqlparser/statement/create/table/CreateTable.java‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ public class CreateTable implements Statement {
3535
private List<Index> indexes;
3636
private List<TableElement> tableElements;
3737
private Select select;
38+
private DuplicateHandling duplicateHandling;
3839
private Table likeTable;
3940
private Table cloneTable;
4041
private ColDataType ofType;
4142
private boolean selectParenthesis;
4243
private boolean useAsKeyword = true;
44+
private Boolean withData;
4345
private boolean ifNotExists = false;
4446
private boolean orReplace = false;
4547
private TablePartitioning partitioning;
@@ -50,6 +52,19 @@ public class CreateTable implements Statement {
5052

5153
private SpannerInterleaveIn interleaveIn = null;
5254

55+
public enum DuplicateHandling {
56+
IGNORE, REPLACE
57+
}
58+
59+
/** MySQL's duplicate-key handling when creating a table from a query; null if omitted. */
60+
public DuplicateHandling getDuplicateHandling() {
61+
return duplicateHandling;
62+
}
63+
64+
public void setDuplicateHandling(DuplicateHandling duplicateHandling) {
65+
this.duplicateHandling = duplicateHandling;
66+
}
67+
5368
@Override
5469
public <T, S> T accept(StatementVisitor<T> statementVisitor, S context) {
5570
return statementVisitor.visit(this, context);
@@ -204,9 +219,21 @@ public void setUseAsKeyword(boolean useAsKeyword) {
204219
this.useAsKeyword = useAsKeyword;
205220
}
206221

222+
/** Returns null for omission, true for WITH DATA, and false for WITH NO DATA. */
223+
public Boolean getWithData() {
224+
return withData;
225+
}
226+
227+
public void setWithData(Boolean withData) {
228+
this.withData = withData;
229+
}
230+
207231
public StringBuilder appendSelectTo(StringBuilder builder,
208232
java.util.function.Consumer<Select> selectRenderer) {
209233
if (select != null) {
234+
if (duplicateHandling != null) {
235+
builder.append(' ').append(duplicateHandling);
236+
}
210237
builder.append(useAsKeyword ? " AS " : " ");
211238
if (selectParenthesis) {
212239
builder.append("(");
@@ -215,6 +242,9 @@ public StringBuilder appendSelectTo(StringBuilder builder,
215242
if (selectParenthesis) {
216243
builder.append(")");
217244
}
245+
if (withData != null) {
246+
builder.append(withData ? " WITH DATA" : " WITH NO DATA");
247+
}
218248
}
219249
return builder;
220250
}

‎src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt‎

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,11 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
14401440
return isKeywordAhead("MATCH_RECOGNIZE") && getToken(2).kind == OPENING_BRACKET;
14411441
}
14421442

1443+
private boolean isCreateTableQueryPrefix() {
1444+
int kind = getToken(1).kind;
1445+
return kind == K_AS || kind == K_TABLE || kind == K_IGNORE || kind == K_REPLACE;
1446+
}
1447+
14431448
private boolean isRowPatternPrimaryAhead() {
14441449
Token next = getToken(1);
14451450
return next.kind == OPENING_BRACKET || next.kind == OP_CARET
@@ -14143,8 +14148,7 @@ ColumnOption ColumnDefinitionOption(): {
1414314148
LOOKAHEAD(<K_PRIMARY> <K_KEY>) <K_PRIMARY> <K_KEY>
1414414149
{ option = ColumnOption.constraint(new NamedConstraint().withType("PRIMARY KEY")); }
1414514150
|
14146-
LOOKAHEAD([ <K_CONSTRAINT> RelObjectName() ] <K_CHECK>,
14147-
{ Dialect.POSTGRESQL.name().equals(getAsString(Feature.dialect)) })
14151+
LOOKAHEAD([ <K_CONSTRAINT> RelObjectName() ] <K_CHECK>)
1414814152
[ <K_CONSTRAINT> constraintName=RelObjectName() ]
1414914153
constraint=CheckConstraintSpec(constraintName)
1415014154
{ option = ColumnOption.constraint(constraint); }
@@ -14217,7 +14221,9 @@ IdentityDefinition IdentityDefinition():
1421714221
Token token;
1421814222
IdentityDefinition.GenerationMode mode;
1421914223
IdentityDefinition identity;
14220-
List<Sequence.Parameter> parameters;
14224+
List<Sequence.Parameter> parameters = new ArrayList<Sequence.Parameter>();
14225+
Sequence.Parameter parameter;
14226+
Sequence sequenceName;
1422114227
}
1422214228
{
1422314229
token=<S_IDENTIFIER> {
@@ -14226,8 +14232,18 @@ IdentityDefinition IdentityDefinition():
1422614232
( <K_ALWAYS> { mode = IdentityDefinition.GenerationMode.ALWAYS; }
1422714233
| <K_BY> <K_DEFAULT> { mode = IdentityDefinition.GenerationMode.BY_DEFAULT; } )
1422814234
<K_AS> <K_IDENTITY> { identity = new IdentityDefinition(mode); }
14229-
[ LOOKAHEAD(2) "(" parameters=SequenceParameters() ")" {
14230-
requireDdlSyntax(!parameters.isEmpty(), "Expected an identity sequence parameter");
14235+
[ LOOKAHEAD(1) "("
14236+
(
14237+
(
14238+
LOOKAHEAD(<K_SEQUENCE> <K_NAME>)
14239+
<K_SEQUENCE> <K_NAME> sequenceName=Sequence()
14240+
{ parameter = new Sequence.Parameter(Sequence.ParameterType.SEQUENCE_NAME)
14241+
.withSequenceName(sequenceName); }
14242+
| parameter=SequenceParameter()
14243+
)
14244+
{ parameters.add(parameter); }
14245+
)+
14246+
")" {
1423114247
identity.setParameters(parameters);
1423214248
} ]
1423314249
{ return identity; }
@@ -14969,6 +14985,7 @@ CreateTable CreateTable(boolean isUsingOrReplace):
1496914985
PartitionBound partitionBound = null;
1497014986
ColDataType ofType = null;
1497114987
ObjectNames typeName;
14988+
boolean withData;
1497214989
}
1497314990
{
1497414991
{ createTable.setOrReplace(isUsingOrReplace);}
@@ -15023,9 +15040,14 @@ CreateTable CreateTable(boolean isUsingOrReplace):
1502315040
[ rowMovement = RowMovement() { createTable.setRowMovement(rowMovement); }]
1502415041
[ LOOKAHEAD(2)
1502515042
{ createTable.setUseAsKeyword(false); }
15043+
[ ( tk=<K_IGNORE> | tk=<K_REPLACE> )
15044+
{ createTable.setDuplicateHandling(CreateTable.DuplicateHandling.valueOf(
15045+
tk.image.toUpperCase(Locale.ROOT))); } ]
1502615046
[ <K_AS> { createTable.setUseAsKeyword(true); } ]
1502715047
( LOOKAHEAD(<K_TABLE>) select=TableStatement() | select=Select() )
1502815048
{ createTable.setSelect(select, false); }
15049+
[ LOOKAHEAD(2) <K_WITH> withData=DataPopulation()
15050+
{ createTable.setWithData(withData); } ]
1502915051
]
1503015052
[
1503115053
<K_LIKE> ( LOOKAHEAD("(" Table() ")") "(" likeTable=Table() { createTable.setLikeTable(likeTable, true); } ")"
@@ -15092,10 +15114,10 @@ ColumnDefinition CreateTableColumnDefinition(boolean typed):
1509215114
void CreateTableOptions(List<TableOption> options):
1509315115
{ TableOption option; }
1509415116
{
15095-
[ LOOKAHEAD(2, { getToken(1).kind != K_AS && getToken(1).kind != K_TABLE
15117+
[ LOOKAHEAD(2, { !isCreateTableQueryPrefix()
1509615118
&& !(getToken(1).kind == K_PARTITION && getToken(2).kind == K_BY) })
1509715119
option=CreateTableOption() { options.add(option); }
15098-
( LOOKAHEAD(2, { getToken(1).kind != K_AS && getToken(1).kind != K_TABLE
15120+
( LOOKAHEAD(2, { !isCreateTableQueryPrefix()
1509915121
&& !(getToken(1).kind == K_PARTITION && getToken(2).kind == K_BY)
1510015122
&& !(getToken(1).kind == K_COMMA
1510115123
&& "INTERLEAVE".equalsIgnoreCase(getToken(2).image)) })
@@ -15624,7 +15646,7 @@ CreateView CreateView(boolean isUsingOrReplace):
1562415646
List<Index.Option> storageParameters = null;
1562515647
List<ViewOption> viewOptions = new ArrayList<ViewOption>();
1562615648
ViewOption viewOption = null;
15627-
boolean withData = true;
15649+
boolean withData;
1562815650
}
1562915651
{
1563015652
{ createView.setOrReplace(isUsingOrReplace);}
@@ -15679,7 +15701,7 @@ CreateView CreateView(boolean isUsingOrReplace):
1567915701
}
1568015702
}
1568115703
|
15682-
[ <K_NO> { withData = false; } ] <K_DATA> { createView.setWithData(withData); }
15704+
withData=DataPopulation() { createView.setWithData(withData); }
1568315705
)
1568415706
]
1568515707
{ createView.validateOptions(); return createView; }
@@ -15697,6 +15719,14 @@ ViewOption PostgreSqlViewOption():
1569715719
{ return new ViewOption(name, value, useEquals); }
1569815720
}
1569915721

15722+
/** Shared WITH [NO] DATA tail for table and materialized-view query sources. */
15723+
boolean DataPopulation():
15724+
{ boolean withData = true; }
15725+
{
15726+
[ <K_NO> { withData = false; } ] <K_DATA>
15727+
{ return withData; }
15728+
}
15729+
1570015730
List<String> CreateViewTailComment():
1570115731
{
1570215732
Token tk = null;
@@ -15744,21 +15774,32 @@ ReferentialAction.Action Action():
1574415774
* Shared between CREATE TABLE FK and ALTER TABLE FK definitions.
1574515775
*/
1574615776
void ReferentialActions(ForeignKeyReference reference):
15777+
{}
1574715778
{
15748-
Token tk;
15749-
ReferentialAction.Action action = null;
15779+
[ LOOKAHEAD(2) ReferentialActionSpec(reference) ]
15780+
[ LOOKAHEAD(2) ReferentialActionSpec(reference) ]
1575015781
}
15782+
15783+
void ReferentialActionSpec(ForeignKeyReference reference):
1575115784
{
15752-
[ LOOKAHEAD(2) (
15753-
<K_ON>
15754-
( tk=<K_DELETE> | tk=<K_UPDATE> ) action = Action()
15755-
{ reference.setReferentialAction(ReferentialAction.Type.from(tk.image), action); }
15756-
)]
15757-
[ LOOKAHEAD(2) (
15758-
<K_ON>
15759-
( tk=<K_DELETE> | tk=<K_UPDATE> ) action = Action()
15760-
{ reference.setReferentialAction(ReferentialAction.Type.from(tk.image), action); }
15761-
)]
15785+
Token token;
15786+
ReferentialAction.Type type;
15787+
ReferentialAction.Action action;
15788+
List<String> columnNames = null;
15789+
}
15790+
{
15791+
<K_ON> ( token=<K_DELETE> | token=<K_UPDATE> )
15792+
{ type = ReferentialAction.Type.from(token.image); }
15793+
action=Action()
15794+
[ LOOKAHEAD({ type == ReferentialAction.Type.DELETE
15795+
&& (action == ReferentialAction.Action.SET_NULL
15796+
|| action == ReferentialAction.Action.SET_DEFAULT)
15797+
&& "(".equals(getToken(1).image) })
15798+
columnNames=ColumnsNamesList() ]
15799+
{
15800+
reference.setReferentialAction(type, action);
15801+
reference.getReferentialAction(type).setColumnNames(columnNames);
15802+
}
1576215803
}
1576315804

1576415805
ForeignKeyReference ForeignKeyReferenceSpec():
@@ -16619,7 +16660,7 @@ TablePartitioning CreateTablePartitioning():
1661916660
]
1662016661
[ LOOKAHEAD(2) partitionDefinitions=PartitionDefinitions()
1662116662
{ partitioning.setPartitionDefinitions(partitionDefinitions); } ]
16622-
( LOOKAHEAD(2, { getToken(1).kind != K_AS })
16663+
( LOOKAHEAD(2, { !isCreateTableQueryPrefix() })
1662316664
parameter=CreateParameter() { partitionOptions.addAll(parameter); } )*
1662416665
{
1662516666
if (!partitionOptions.isEmpty()) {

0 commit comments

Comments
 (0)