Skip to content

Commit 5ee6ec9

Browse files
Assorted fixes to the Java CC Parser definition (#1153)
* Implement Oracle Hints for INSERT, UPDATE, MERGE, DELETE * Correct CreateIndex TailOptions Add a Test Case for CreateIndex TailOptions * Add WHERE expression to MergeInsert Add test case for MergeInsert WHERE expression * Fix Issue #1156: ALTER TABLE ADD FOREIGN KEY with schema reference Add a specific test case
1 parent b880e16 commit 5ee6ec9

File tree

15 files changed

+269
-46
lines changed

15 files changed

+269
-46
lines changed

nb-configuration.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
That way multiple projects can share the same settings (useful for formatting rules for example).
1414
Any value defined here will override the pom.xml file value but is only applicable to the current project.
1515
-->
16-
<netbeans.compile.on.save>none</netbeans.compile.on.save>
16+
<netbeans.compile.on.save>all</netbeans.compile.on.save>
1717
<com-junichi11-netbeans-changelf.enable>false</com-junichi11-netbeans-changelf.enable>
1818
<com-junichi11-netbeans-changelf.use-project>true</com-junichi11-netbeans-changelf.use-project>
1919
<com-junichi11-netbeans-changelf.lf-kind>LF</com-junichi11-netbeans-changelf.lf-kind>

src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public class AlterExpression {
4848
private Set<ReferentialAction> referentialActions = new LinkedHashSet<>(2);
4949

5050
private List<String> fkColumns;
51+
private String fkSourceSchema;
52+
5153
private String fkSourceTable;
5254
private List<String> fkSourceColumns;
5355
private boolean uk;
@@ -56,6 +58,13 @@ public class AlterExpression {
5658
private List<ConstraintState> constraints;
5759
private List<String> parameters;
5860
private String commentText;
61+
62+
public String getFkSourceSchema() {
63+
return fkSourceSchema;
64+
}
65+
public void setFkSourceSchema(String fkSourceSchema) {
66+
this.fkSourceSchema = fkSourceSchema;
67+
}
5968

6069
public String getCommentText() {
6170
return commentText;
@@ -405,11 +414,18 @@ public String toString() {
405414
}
406415
b.append(" (").append(PlainSelect.getStringList(ukColumns)).append(")");
407416
} else if (fkColumns != null) {
408-
b.append("FOREIGN KEY (").append(PlainSelect.getStringList(fkColumns)).append(") REFERENCES ")
409-
.append(fkSourceTable).append(" (").append(
410-
PlainSelect.getStringList(fkSourceColumns))
411-
.append(")");
412-
referentialActions.forEach(b::append);
417+
b.append("FOREIGN KEY (")
418+
.append(PlainSelect.getStringList(fkColumns))
419+
.append(") REFERENCES ")
420+
.append(
421+
fkSourceSchema != null && fkSourceSchema.trim().length() > 0
422+
? fkSourceSchema + "."
423+
: "")
424+
.append(fkSourceTable)
425+
.append(" (")
426+
.append(PlainSelect.getStringList(fkSourceColumns))
427+
.append(")");
428+
referentialActions.forEach(b::append);
413429
} else if (index != null) {
414430
b.append(index);
415431
}
@@ -490,6 +506,11 @@ public AlterExpression withFkColumns(List<String> fkColumns) {
490506
this.setFkColumns(fkColumns);
491507
return this;
492508
}
509+
510+
public AlterExpression withFkSourceSchema(String fkSourceSchema) {
511+
this.setFkSourceTable(fkSourceSchema);
512+
return this;
513+
}
493514

494515
public AlterExpression withFkSourceTable(String fkSourceTable) {
495516
this.setFkSourceTable(fkSourceTable);

src/main/java/net/sf/jsqlparser/statement/delete/Delete.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.Optional;
1717
import static java.util.stream.Collectors.joining;
1818
import net.sf.jsqlparser.expression.Expression;
19+
import net.sf.jsqlparser.expression.OracleHint;
1920
import net.sf.jsqlparser.schema.Table;
2021
import net.sf.jsqlparser.statement.Statement;
2122
import net.sf.jsqlparser.statement.StatementVisitor;
@@ -27,6 +28,7 @@
2728
public class Delete implements Statement {
2829

2930
private Table table;
31+
private OracleHint oracleHint = null;
3032
private List<Table> tables;
3133
private List<Join> joins;
3234
private Expression where;
@@ -61,6 +63,14 @@ public void setTable(Table name) {
6163
public void setWhere(Expression expression) {
6264
where = expression;
6365
}
66+
67+
public OracleHint getOracleHint() {
68+
return oracleHint;
69+
}
70+
71+
public void setOracleHint(OracleHint oracleHint) {
72+
this.oracleHint = oracleHint;
73+
}
6474

6575
public Limit getLimit() {
6676
return limit;

src/main/java/net/sf/jsqlparser/statement/insert/Insert.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.List;
1717
import java.util.Optional;
1818
import net.sf.jsqlparser.expression.Expression;
19+
import net.sf.jsqlparser.expression.OracleHint;
1920
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
2021
import net.sf.jsqlparser.schema.Column;
2122
import net.sf.jsqlparser.schema.Table;
@@ -29,6 +30,7 @@
2930
public class Insert implements Statement {
3031

3132
private Table table;
33+
private OracleHint oracleHint = null;
3234
private List<Column> columns;
3335
private ItemsList itemsList;
3436
private boolean useValues = true;
@@ -61,6 +63,14 @@ public Table getTable() {
6163
public void setTable(Table name) {
6264
table = name;
6365
}
66+
67+
public OracleHint getOracleHint() {
68+
return oracleHint;
69+
}
70+
71+
public void setOracleHint(OracleHint oracleHint) {
72+
this.oracleHint = oracleHint;
73+
}
6474

6575
public List<Column> getColumns() {
6676
return columns;

src/main/java/net/sf/jsqlparser/statement/merge/Merge.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import net.sf.jsqlparser.expression.Alias;
1313
import net.sf.jsqlparser.expression.Expression;
14+
import net.sf.jsqlparser.expression.OracleHint;
1415
import net.sf.jsqlparser.schema.Table;
1516
import net.sf.jsqlparser.statement.Statement;
1617
import net.sf.jsqlparser.statement.StatementVisitor;
@@ -19,6 +20,7 @@
1920
public class Merge implements Statement {
2021

2122
private Table table;
23+
private OracleHint oracleHint = null;
2224
private Table usingTable;
2325
private SubSelect usingSelect;
2426
private Alias usingAlias;
@@ -34,6 +36,14 @@ public Table getTable() {
3436
public void setTable(Table name) {
3537
table = name;
3638
}
39+
40+
public OracleHint getOracleHint() {
41+
return oracleHint;
42+
}
43+
44+
public void setOracleHint(OracleHint oracleHint) {
45+
this.oracleHint = oracleHint;
46+
}
3747

3848
public Table getUsingTable() {
3949
return usingTable;

src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class MergeInsert {
2222

2323
private List<Column> columns = null;
2424
private List<Expression> values = null;
25+
private Expression whereCondition;
2526

2627
public List<Column> getColumns() {
2728
return columns;
@@ -38,12 +39,21 @@ public List<Expression> getValues() {
3839
public void setValues(List<Expression> values) {
3940
this.values = values;
4041
}
42+
43+
public Expression getWhereCondition() {
44+
return whereCondition;
45+
}
46+
47+
public void setWhereCondition(Expression whereCondition) {
48+
this.whereCondition = whereCondition;
49+
}
4150

4251
@Override
4352
public String toString() {
4453
return " WHEN NOT MATCHED THEN INSERT "
4554
+ (columns.isEmpty() ? "" : PlainSelect.getStringList(columns, true, true))
46-
+ " VALUES " + PlainSelect.getStringList(values, true, true);
55+
+ " VALUES " + PlainSelect.getStringList(values, true, true)
56+
+ (whereCondition != null ? (" WHERE " + whereCondition) : "");
4757
}
4858

4959
public MergeInsert withColumns(List<Column> columns) {
@@ -79,4 +89,13 @@ public MergeInsert addValues(Collection<? extends Expression> values) {
7989
collection.addAll(values);
8090
return this.withValues(collection);
8191
}
92+
93+
public MergeInsert withWhereCondition(Expression whereCondition) {
94+
this.setWhereCondition(whereCondition);
95+
return this;
96+
}
97+
98+
public <E extends Expression> E getWhereCondition(Class<E> type) {
99+
return type.cast(getWhereCondition());
100+
}
82101
}

src/main/java/net/sf/jsqlparser/statement/update/Update.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.List;
1616
import java.util.Optional;
1717
import net.sf.jsqlparser.expression.Expression;
18+
import net.sf.jsqlparser.expression.OracleHint;
1819
import net.sf.jsqlparser.schema.Column;
1920
import net.sf.jsqlparser.schema.Table;
2021
import net.sf.jsqlparser.statement.Statement;
@@ -39,6 +40,7 @@ public class Update implements Statement {
3940
private Select select;
4041
private boolean useColumnsBrackets = true;
4142
private boolean useSelect = false;
43+
private OracleHint oracleHint = null;
4244
private List<OrderByElement> orderByElements;
4345
private Limit limit;
4446
private boolean returningAllColumns = false;
@@ -64,6 +66,14 @@ public void setTable(Table table) {
6466
public void setWhere(Expression expression) {
6567
where = expression;
6668
}
69+
70+
public OracleHint getOracleHint() {
71+
return oracleHint;
72+
}
73+
74+
public void setOracleHint(OracleHint oracleHint) {
75+
this.oracleHint = oracleHint;
76+
}
6777

6878
public List<Column> getColumns() {
6979
return columns;
@@ -160,7 +170,7 @@ public List<SelectExpressionItem> getReturningExpressionList() {
160170
public void setReturningExpressionList(List<SelectExpressionItem> returningExpressionList) {
161171
this.returningExpressionList = returningExpressionList;
162172
}
163-
173+
164174
@Override
165175
public String toString() {
166176
StringBuilder b = new StringBuilder("UPDATE ");

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

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ Update Update():
879879
List<SelectExpressionItem> returning = null;
880880
}
881881
{
882-
<K_UPDATE> table=TableWithAlias()
882+
<K_UPDATE> { update.setOracleHint(getOracleHint()); } table=TableWithAlias()
883883
startJoins=JoinsList()
884884

885885
<K_SET>
@@ -1023,7 +1023,7 @@ Insert Insert( List<WithItem> with ):
10231023
boolean useAs = false;
10241024
}
10251025
{
1026-
<K_INSERT>
1026+
<K_INSERT> { insert.setOracleHint(getOracleHint()); }
10271027
[(tk = <K_LOW_PRIORITY> | tk = <K_DELAYED> | tk = <K_HIGH_PRIORITY>)
10281028
{if (tk!=null)
10291029
modifierPriority = InsertModifierPriority.valueOf(tk.image.toUpperCase());
@@ -1209,7 +1209,7 @@ Delete Delete():
12091209
List<OrderByElement> orderByElements;
12101210
}
12111211
{
1212-
<K_DELETE> [LOOKAHEAD(2) (table=TableWithAlias() { tables.add(table); }
1212+
<K_DELETE> { delete.setOracleHint(getOracleHint()); } [LOOKAHEAD(2) (table=TableWithAlias() { tables.add(table); }
12131213
("," table=TableWithAlias() { tables.add(table); } )*
12141214
<K_FROM> | <K_FROM>)]
12151215

@@ -1235,7 +1235,7 @@ Statement Merge() : {
12351235
MergeInsert insert;
12361236
}
12371237
{
1238-
<K_MERGE> <K_INTO> table=TableWithAlias() { merge.setTable(table); }
1238+
<K_MERGE> { merge.setOracleHint(getOracleHint()); } <K_INTO> table=TableWithAlias() { merge.setTable(table); }
12391239
<K_USING>
12401240
( table=Table() { merge.setUsingTable(table); }
12411241
| "(" select=SubSelect() { merge.setUsingSelect(select); } ")" )
@@ -1287,14 +1287,18 @@ MergeInsert MergeInsertClause() : {
12871287
List<Expression> expList = new ArrayList<Expression>();
12881288
Column col;
12891289
Expression exp;
1290+
Expression condition;
12901291
}
12911292
{
12921293
<K_WHEN> <K_NOT> <K_MATCHED> <K_THEN>
12931294
<K_INSERT> ["(" col=Column() { columns.add(col); } ("," col=Column() { columns.add(col); } )* ")"] <K_VALUES>
12941295
"(" exp=SimpleExpression() { expList.add(exp); } ("," exp=SimpleExpression() { expList.add(exp); } )* ")"
1295-
{
1296-
return mi.withColumns(columns).withValues(expList);
1297-
}
1296+
1297+
{ mi.withColumns(columns).withValues(expList); }
1298+
1299+
[ <K_WHERE> condition = Expression() { mi.setWhereCondition(condition); }]
1300+
1301+
{ return mi; }
12981302
}
12991303

13001304
List<String> RelObjectNameList() : {
@@ -4028,7 +4032,7 @@ CreateIndex CreateIndex():
40284032
Index index = null;
40294033
//String name = null;
40304034
List<String> parameter = new ArrayList<String>();
4031-
List<String> tailParameter = null;
4035+
List<String> tailParameters = new ArrayList<String>();
40324036
List<String> name;
40334037
}
40344038
{
@@ -4049,13 +4053,15 @@ CreateIndex CreateIndex():
40494053

40504054
colNames = ColumnNamesWithParamsList()
40514055

4052-
[ tailParameter = CreateParameter() {} ]
4056+
/* [ tailParameter = CreateParameter() {} ] */
4057+
4058+
( parameter=CreateParameter() { tailParameters.addAll(parameter); } )*
40534059

40544060
{
40554061
index.setColumns(colNames);
40564062
createIndex.setIndex(index);
40574063
createIndex.setTable(table);
4058-
createIndex.setTailParameters(tailParameter);
4064+
createIndex.setTailParameters(tailParameters);
40594065
return createIndex;
40604066
}
40614067
}
@@ -4790,8 +4796,16 @@ AlterExpression AlterExpression():
47904796
|
47914797
//following two choices regarding foreign keys should be merged
47924798
( <K_FOREIGN> <K_KEY> columnNames=ColumnsNamesList() { alterExp.setFkColumns(columnNames); columnNames = null; }
4793-
<K_REFERENCES> tk=<S_IDENTIFIER> [ columnNames=ColumnsNamesList() ]
4799+
/*
4800+
<K_REFERENCES> tk=<S_IDENTIFIER> [ columnNames=ColumnsNamesList() ]
47944801
{ alterExp.setFkSourceTable(tk.image); alterExp.setFkSourceColumns(columnNames); }
4802+
*/
4803+
<K_REFERENCES> fkTable=Table() [ columnNames=ColumnsNamesList() ]
4804+
{
4805+
alterExp.setFkSourceSchema(fkTable.getSchemaName());
4806+
alterExp.setFkSourceTable(fkTable.getName());
4807+
alterExp.setFkSourceColumns(columnNames);
4808+
}
47954809

47964810
[LOOKAHEAD(2) (<K_ON> (tk=<K_DELETE> | tk=<K_UPDATE>) action = Action()
47974811
{ alterExp.setReferentialAction(ReferentialAction.Type.valueOf(tk.image), action); }

src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,20 @@ public void testAlterTableForgeignKey3() throws JSQLParserException {
146146
public void testAlterTableForgeignKey4() throws JSQLParserException {
147147
assertSqlCanBeParsedAndDeparsed("ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id) ON DELETE SET NULL");
148148
}
149+
150+
@Test
151+
public void testAlterTableForgeignWithFkSchema() throws JSQLParserException {
152+
final String FK_SCHEMA_NAME = "my_schema";
153+
final String FK_TABLE_NAME= "ra_user";
154+
String sql = "ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES " + FK_SCHEMA_NAME +"." + FK_TABLE_NAME + " (id) ON DELETE SET NULL";
155+
assertSqlCanBeParsedAndDeparsed(sql);
156+
157+
Alter alter = (Alter) CCJSqlParserUtil.parse(sql);
158+
AlterExpression alterExpression = alter.getAlterExpressions().get(0);
159+
160+
assertEquals(alterExpression.getFkSourceSchema(), FK_SCHEMA_NAME);
161+
assertEquals(alterExpression.getFkSourceTable(), FK_TABLE_NAME);
162+
}
149163

150164
@Test
151165
public void testAlterTableDropColumn() throws JSQLParserException {

src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package net.sf.jsqlparser.statement.create;
1111

1212
import java.io.StringReader;
13+
import java.util.List;
1314
import net.sf.jsqlparser.JSQLParserException;
1415
import net.sf.jsqlparser.parser.CCJSqlParserManager;
1516
import net.sf.jsqlparser.statement.create.index.CreateIndex;
@@ -119,4 +120,20 @@ public void testFullIndexNameIssue936() throws JSQLParserException {
119120
public void testFullIndexNameIssue936_2() throws JSQLParserException {
120121
assertSqlCanBeParsedAndDeparsed("CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\") TABLESPACE \"TS\"");
121122
}
123+
124+
@Test
125+
public void testCreateIndexTrailingOptions() throws JSQLParserException {
126+
String statement =
127+
"CREATE UNIQUE INDEX cfe.version_info_idx2\n"
128+
+ " ON cfe.version_info ( major_version\n"
129+
+ " , minor_version\n"
130+
+ " , patch_level ) parallel compress nologging\n"
131+
+ ";";
132+
CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement));
133+
List<String> tailParameters = createIndex.getTailParameters();
134+
assertEquals(3, tailParameters.size());
135+
assertEquals(tailParameters.get(0), "parallel");
136+
assertEquals(tailParameters.get(1), "compress");
137+
assertEquals(tailParameters.get(2), "nologging");
138+
}
122139
}

0 commit comments

Comments
 (0)