Skip to content

Commit e72b97e

Browse files
committed
Merge latest master and preserve dialect-specific parsing and documentation
2 parents 86c0ac2 + 17f033d commit e72b97e

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, insertBulk,
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;
@@ -66,6 +70,7 @@
6670
import net.sf.jsqlparser.statement.select.PivotVisitor;
6771
import net.sf.jsqlparser.statement.select.PivotVisitorAdapter;
6872
import net.sf.jsqlparser.statement.select.PlainSelect;
73+
import net.sf.jsqlparser.statement.select.MySqlSelectIntoClause;
6974
import net.sf.jsqlparser.statement.select.Select;
7075
import net.sf.jsqlparser.statement.select.SelectItem;
7176
import net.sf.jsqlparser.statement.select.SelectItemVisitor;
@@ -803,6 +808,12 @@ public <S> Void visit(PlainSelect plainSelect, S context) {
803808
analysis.certain.remove(StmtFeature.RETURNS_RESULT_SET);
804809
}
805810

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

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;
@@ -529,4 +533,29 @@ default <S> T visit(AlterSubscription statement, S context) {
529533
default void visit(AlterSubscription statement) {
530534
visit(statement, null);
531535
}
536+
537+
default <S> T visit(OracleBlock block, S context) {
538+
return visit((Block) block, context);
539+
}
540+
541+
default void visit(OracleBlock block) {
542+
visit(block, null);
543+
}
544+
545+
default <S> T visit(OracleAssignment assignment, S context) {
546+
return null;
547+
}
548+
549+
default void visit(OracleAssignment assignment) {
550+
visit(assignment, null);
551+
}
552+
553+
default <S> T visit(OracleNullStatement statement, S context) {
554+
return null;
555+
}
556+
557+
default void visit(OracleNullStatement statement) {
558+
visit(statement, null);
559+
}
560+
532561
}

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;
@@ -342,7 +345,9 @@ public <S> T visit(Truncate truncate, S context) {
342345

343346
@Override
344347
public <S> T visit(CreateIndex createIndex, S context) {
345-
348+
TableDefinitionTraversal.visit(createIndex,
349+
expression -> expression.accept(expressionVisitor, context),
350+
table -> table.accept(fromItemVisitor, context));
346351
return null;
347352
}
348353

@@ -429,7 +434,7 @@ public <S> T visit(Statements statements, S context) {
429434

430435
@Override
431436
public <S> T visit(Execute execute, S context) {
432-
437+
expressionVisitor.visitExpression(execute.getExprList(), context);
433438
return null;
434439
}
435440

@@ -777,4 +782,19 @@ public <S> T visit(AlterSubscription statement, S context) {
777782
});
778783
return null;
779784
}
785+
786+
@Override
787+
public <S> T visit(OracleBlock block, S context) {
788+
block.visitChildren(expression -> expression.accept(expressionVisitor, context),
789+
statement -> statement.accept(this, context));
790+
return null;
791+
}
792+
793+
@Override
794+
public <S> T visit(OracleAssignment assignment, S context) {
795+
assignment.getTarget().accept(expressionVisitor, context);
796+
assignment.getValue().accept(expressionVisitor, context);
797+
return null;
798+
}
799+
780800
}

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)