Skip to content

Commit 444c90c

Browse files
committed
Merge latest master and preserve dialect-specific parsing and documentation
2 parents 8d00c36 + 17f033d commit 444c90c

29 files changed

Lines changed: 1506 additions & 112 deletions

src/main/java/net/sf/jsqlparser/parser/AbstractJSqlParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public enum Dialect {
4646
AdjacentStringLiterals.WHITESPACE,
4747
Feature.allowDoubleQuotedStrings,
4848
Feature.allowBackslashEscapeCharacter), SNOWFLAKE(
49-
Feature.allowBackslashEscapeCharacter), INFORMIX;
49+
Feature.allowBackslashEscapeCharacter), INFORMIX, SPANNER;
5050

5151
private final Set<Feature> lexerFeatures;
5252
private final AdjacentStringLiterals adjacentStringLiterals;

src/main/java/net/sf/jsqlparser/parser/feature/Feature.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ public enum Feature {
453453
*
454454
* @see Execute
455455
*/
456+
oracleBlock,
457+
456458
execute, executeExec, executeCall, executeExecute, doStatement,
457459

458460
/**

src/main/java/net/sf/jsqlparser/statement/StatementFeatureVisitor.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
*/
1010
package net.sf.jsqlparser.statement;
1111

12+
import net.sf.jsqlparser.statement.oracle.OracleBlock;
13+
import net.sf.jsqlparser.statement.oracle.OracleAssignment;
14+
import net.sf.jsqlparser.statement.oracle.OracleNullStatement;
15+
1216
import net.sf.jsqlparser.statement.role.CreateRole;
1317
import net.sf.jsqlparser.statement.role.AlterRole;
1418
import net.sf.jsqlparser.statement.grant.Revoke;
@@ -65,6 +69,7 @@
6569
import net.sf.jsqlparser.statement.select.PivotVisitor;
6670
import net.sf.jsqlparser.statement.select.PivotVisitorAdapter;
6771
import net.sf.jsqlparser.statement.select.PlainSelect;
72+
import net.sf.jsqlparser.statement.select.MySqlSelectIntoClause;
6873
import net.sf.jsqlparser.statement.select.Select;
6974
import net.sf.jsqlparser.statement.select.SelectItem;
7075
import net.sf.jsqlparser.statement.select.SelectItemVisitor;
@@ -802,6 +807,12 @@ public <S> Void visit(PlainSelect plainSelect, S context) {
802807
analysis.certain.remove(StmtFeature.RETURNS_RESULT_SET);
803808
}
804809

810+
MySqlSelectIntoClause mySqlInto = plainSelect.getMySqlSelectIntoClause();
811+
if (mySqlInto != null && mySqlInto.getType() == MySqlSelectIntoClause.Type.VARIABLES) {
812+
analysis.certain(StmtFeature.MODIFIES_SESSION);
813+
analysis.certain.remove(StmtFeature.RETURNS_RESULT_SET);
814+
}
815+
805816
if (plainSelect.getForMode() != null) {
806817
// FOR UPDATE / FOR SHARE take row locks
807818
analysis.certain(StmtFeature.MODIFIES_TRANSACTION);
@@ -993,4 +1004,24 @@ public <S> Void visit(AlterSubscription statement, S context) {
9931004
}
9941005
return null;
9951006
}
1007+
1008+
@Override
1009+
public <S> Void visit(OracleBlock block, S context) {
1010+
analysis.claimTopLevel();
1011+
return super.visit(block, context);
1012+
}
1013+
1014+
@Override
1015+
public <S> Void visit(OracleAssignment assignment, S context) {
1016+
analysis.claimTopLevel();
1017+
// Assignment to a local variable is not a database write.
1018+
return super.visit(assignment, context);
1019+
}
1020+
1021+
@Override
1022+
public <S> Void visit(OracleNullStatement statement, S context) {
1023+
analysis.claimTopLevel();
1024+
return null;
1025+
}
1026+
9961027
}

src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
*/
1010
package net.sf.jsqlparser.statement;
1111

12+
import net.sf.jsqlparser.statement.oracle.OracleBlock;
13+
import net.sf.jsqlparser.statement.oracle.OracleAssignment;
14+
import net.sf.jsqlparser.statement.oracle.OracleNullStatement;
15+
1216
import net.sf.jsqlparser.statement.role.CreateRole;
1317
import net.sf.jsqlparser.statement.role.AlterRole;
1418
import net.sf.jsqlparser.statement.grant.Revoke;
@@ -528,4 +532,29 @@ default <S> T visit(AlterSubscription statement, S context) {
528532
default void visit(AlterSubscription statement) {
529533
visit(statement, null);
530534
}
535+
536+
default <S> T visit(OracleBlock block, S context) {
537+
return visit((Block) block, context);
538+
}
539+
540+
default void visit(OracleBlock block) {
541+
visit(block, null);
542+
}
543+
544+
default <S> T visit(OracleAssignment assignment, S context) {
545+
return null;
546+
}
547+
548+
default void visit(OracleAssignment assignment) {
549+
visit(assignment, null);
550+
}
551+
552+
default <S> T visit(OracleNullStatement statement, S context) {
553+
return null;
554+
}
555+
556+
default void visit(OracleNullStatement statement) {
557+
visit(statement, null);
558+
}
559+
531560
}

src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
*/
1010
package net.sf.jsqlparser.statement;
1111

12+
import net.sf.jsqlparser.statement.oracle.OracleBlock;
13+
import net.sf.jsqlparser.statement.oracle.OracleAssignment;
14+
1215
import net.sf.jsqlparser.statement.role.CreateRole;
1316
import net.sf.jsqlparser.statement.role.AlterRole;
1417
import net.sf.jsqlparser.statement.role.RoleOption;
@@ -334,7 +337,9 @@ public <S> T visit(Truncate truncate, S context) {
334337

335338
@Override
336339
public <S> T visit(CreateIndex createIndex, S context) {
337-
340+
TableDefinitionTraversal.visit(createIndex,
341+
expression -> expression.accept(expressionVisitor, context),
342+
table -> table.accept(fromItemVisitor, context));
338343
return null;
339344
}
340345

@@ -421,7 +426,7 @@ public <S> T visit(Statements statements, S context) {
421426

422427
@Override
423428
public <S> T visit(Execute execute, S context) {
424-
429+
expressionVisitor.visitExpression(execute.getExprList(), context);
425430
return null;
426431
}
427432

@@ -775,4 +780,19 @@ public <S> T visit(AlterSubscription statement, S context) {
775780
});
776781
return null;
777782
}
783+
784+
@Override
785+
public <S> T visit(OracleBlock block, S context) {
786+
block.visitChildren(expression -> expression.accept(expressionVisitor, context),
787+
statement -> statement.accept(this, context));
788+
return null;
789+
}
790+
791+
@Override
792+
public <S> T visit(OracleAssignment assignment, S context) {
793+
assignment.getTarget().accept(expressionVisitor, context);
794+
assignment.getValue().accept(expressionVisitor, context);
795+
return null;
796+
}
797+
778798
}

src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,12 @@
99
*/
1010
package net.sf.jsqlparser.statement.create.index;
1111

12-
import static java.util.stream.Collectors.joining;
13-
1412
import java.util.*;
13+
import java.util.function.Consumer;
1514
import net.sf.jsqlparser.expression.Expression;
1615
import net.sf.jsqlparser.schema.*;
1716
import net.sf.jsqlparser.statement.*;
1817
import net.sf.jsqlparser.statement.create.table.*;
19-
import net.sf.jsqlparser.statement.select.PlainSelect;
2018

2119
public class CreateIndex implements Statement {
2220

@@ -27,6 +25,7 @@ public class CreateIndex implements Statement {
2725
private boolean usingIfNotExists = false;
2826
private boolean concurrently;
2927
private boolean only;
28+
private boolean nullFiltered;
3029
private List<String> includeColumns;
3130
private Boolean nullsDistinct;
3231
private List<Index.Option> storageParameters;
@@ -66,6 +65,20 @@ public void setOnly(boolean only) {
6665
this.only = only;
6766
}
6867

68+
/** Whether this Spanner index omits rows with null key values. */
69+
public boolean isNullFiltered() {
70+
return nullFiltered;
71+
}
72+
73+
public void setNullFiltered(boolean nullFiltered) {
74+
this.nullFiltered = nullFiltered;
75+
}
76+
77+
public CreateIndex withNullFiltered(boolean nullFiltered) {
78+
setNullFiltered(nullFiltered);
79+
return this;
80+
}
81+
6982
public List<String> getIncludeColumns() {
7083
return includeColumns;
7184
}
@@ -142,10 +155,15 @@ public String toString() {
142155

143156
/** Shared rendering for the statement model and CreateIndexDeParser. */
144157
public StringBuilder appendTo(StringBuilder buffer) {
158+
return appendTo(buffer, expression -> buffer.append(expression));
159+
}
160+
161+
/** Shares rendering while allowing visitors to transform key and option expressions. */
162+
public StringBuilder appendTo(StringBuilder buffer, Consumer<Expression> expressionPrinter) {
145163
appendIndexHeader(buffer);
146164
appendIndexTarget(buffer);
147-
appendIndexColumns(buffer);
148-
appendPostgreSqlTail(buffer);
165+
appendIndexColumns(buffer, expressionPrinter);
166+
appendPostgreSqlTail(buffer, expressionPrinter);
149167
if (tailParameters != null) {
150168
for (String param : tailParameters) {
151169
buffer.append(" ").append(param);
@@ -159,6 +177,12 @@ private void appendIndexHeader(StringBuilder buffer) {
159177
if (index.getType() != null) {
160178
buffer.append(index.getType()).append(" ");
161179
}
180+
if (index.getClustering() != null) {
181+
buffer.append(index.getClustering()).append(" ");
182+
}
183+
if (nullFiltered) {
184+
buffer.append("NULL_FILTERED ");
185+
}
162186
buffer.append("INDEX ");
163187
if (concurrently) {
164188
buffer.append("CONCURRENTLY ");
@@ -185,32 +209,38 @@ private void appendIndexTarget(StringBuilder buffer) {
185209
}
186210
}
187211

188-
private void appendIndexColumns(StringBuilder buffer) {
189-
if (index.getColumnsNames() != null) {
212+
private void appendIndexColumns(StringBuilder buffer, Consumer<Expression> expressionPrinter) {
213+
if (index.getColumns() != null) {
190214
buffer.append(" (");
191-
buffer.append(index.getColumns().stream()
192-
.map(Index.ColumnParams::toString)
193-
.collect(joining(", ")));
215+
for (Iterator<Index.ColumnParams> columns = index.getColumns().iterator(); columns
216+
.hasNext();) {
217+
columns.next().appendTo(buffer, expressionPrinter);
218+
if (columns.hasNext()) {
219+
buffer.append(", ");
220+
}
221+
}
194222
buffer.append(")");
195223
}
196224
}
197225

198-
private void appendPostgreSqlTail(StringBuilder buffer) {
226+
private void appendPostgreSqlTail(StringBuilder buffer,
227+
Consumer<Expression> expressionPrinter) {
199228
if (includeColumns != null) {
200229
buffer.append(" INCLUDE (").append(String.join(", ", includeColumns)).append(")");
201230
}
202231
if (nullsDistinct != null) {
203232
buffer.append(" NULLS ").append(nullsDistinct ? "DISTINCT" : "NOT DISTINCT");
204233
}
205234
if (storageParameters != null) {
206-
buffer.append(" WITH ")
207-
.append(PlainSelect.getStringList(storageParameters, true, true));
235+
buffer.append(" WITH ");
236+
Index.Option.appendListTo(buffer, storageParameters, expressionPrinter);
208237
}
209238
if (tableSpace != null) {
210239
buffer.append(" TABLESPACE ").append(tableSpace);
211240
}
212241
if (where != null) {
213-
buffer.append(" WHERE ").append(where);
242+
buffer.append(" WHERE ");
243+
expressionPrinter.accept(where);
214244
}
215245
}
216246

src/main/java/net/sf/jsqlparser/statement/create/table/Index.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ public void appendTo(StringBuilder builder, Consumer<Expression> expressionPrint
511511
}
512512
appendParams(builder);
513513
appendCollation(builder);
514-
appendOperatorClass(builder);
514+
appendOperatorClass(builder, expressionPrinter);
515515
appendSortOrder(builder);
516516
appendNullOrdering(builder);
517517
if (exclusionOperator != null) {
@@ -531,13 +531,13 @@ private void appendCollation(StringBuilder builder) {
531531
}
532532
}
533533

534-
private void appendOperatorClass(StringBuilder builder) {
534+
private void appendOperatorClass(StringBuilder builder,
535+
Consumer<Expression> expressionPrinter) {
535536
if (operatorClass != null && !hasParam(operatorClass)) {
536537
builder.append(" ").append(operatorClass);
537538
if (operatorClassParameters != null && !operatorClassParameters.isEmpty()) {
538-
builder.append(" ")
539-
.append(PlainSelect.getStringList(
540-
operatorClassParameters, true, true));
539+
builder.append(" ");
540+
Option.appendListTo(builder, operatorClassParameters, expressionPrinter);
541541
}
542542
}
543543
}
@@ -559,7 +559,7 @@ private boolean hasParam(String expected) {
559559
}
560560
}
561561

562-
/** A named PostgreSQL index option with an optional value. */
562+
/** A named index option with an optional value. */
563563
public static class Option implements Serializable {
564564
private String name;
565565
private Expression value;
@@ -614,7 +614,33 @@ public Option withUseEquals(boolean useEquals) {
614614

615615
@Override
616616
public String toString() {
617-
return value == null ? name : name + (useEquals ? " = " : " ") + value;
617+
if (value == null) {
618+
return name;
619+
}
620+
StringBuilder builder = new StringBuilder();
621+
return appendTo(builder, expression -> builder.append(expression)).toString();
622+
}
623+
624+
public StringBuilder appendTo(StringBuilder builder,
625+
Consumer<Expression> expressionPrinter) {
626+
builder.append(name);
627+
if (value != null) {
628+
builder.append(useEquals ? " = " : " ");
629+
expressionPrinter.accept(value);
630+
}
631+
return builder;
632+
}
633+
634+
public static StringBuilder appendListTo(StringBuilder builder, List<Option> options,
635+
Consumer<Expression> expressionPrinter) {
636+
builder.append('(');
637+
for (int i = 0; i < options.size(); i++) {
638+
if (i > 0) {
639+
builder.append(", ");
640+
}
641+
options.get(i).appendTo(builder, expressionPrinter);
642+
}
643+
return builder.append(')');
618644
}
619645
}
620646
}

src/main/java/net/sf/jsqlparser/statement/execute/Execute.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ public String toString() {
7575
}
7676

7777
public StringBuilder appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
78-
builder.append(execType.name()).append(' ').append(name);
78+
if (execType != ExecType.IMPLICIT) {
79+
builder.append(execType.name()).append(' ');
80+
}
81+
builder.append(name);
7982
if (exprList != null) {
8083
builder.append(' ');
8184
boolean brackets = exprList instanceof ParenthesedExpressionList;
@@ -111,7 +114,7 @@ public Execute withExprList(ExpressionList exprList) {
111114
}
112115

113116
public enum ExecType {
114-
EXECUTE, EXEC, CALL;
117+
EXECUTE, EXEC, CALL, IMPLICIT;
115118

116119
public static ExecType from(String type) {
117120
return Enum.valueOf(ExecType.class, type.toUpperCase(Locale.ROOT));

0 commit comments

Comments
 (0)