Skip to content

Commit fcb6b98

Browse files
Merge branch 'master' into fix/sample-extend-as-identifier
2 parents 8c023a2 + a6c8e89 commit fcb6b98

109 files changed

Lines changed: 7910 additions & 827 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
143143
| **ClickHouse column selection** | `COLUMNS('regexp')` select items with chained `APPLY`, `EXCEPT`, and `REPLACE` transformers |
144144
| **DML** | `INSERT` · `UPDATE` · `UPSERT` · `MERGE` · `DELETE` · `TRUNCATE TABLE` |
145145
| **DDL** | `CREATE …` · `ALTER …` · `DROP …` |
146+
| **MySQL table maintenance** | `ANALYZE` · `CHECK` · `OPTIMIZE` · `REPAIR TABLE` |
146147
| **PostgreSQL RLS** | `CREATE POLICY` · `ALTER TABLE … ENABLE`/`DISABLE`/`FORCE`/`NO FORCE ROW LEVEL SECURITY` |
147148
| **Informix constraints** | `ALTER TABLE … ADD CONSTRAINT` with trailing constraint names for primary, unique, foreign and check constraints; enable with `parser.withDialect(Dialect.INFORMIX)` |
148149
| **Salesforce SOQL** | `INCLUDES` · `EXCLUDES` |

‎src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class AnalyticExpression extends ASTNodeAccessImpl implements Expression
4141
private boolean unique = false;
4242
private boolean ignoreNullsOutside = false; // IGNORE NULLS outside function parameters
4343
private Expression filterExpression = null;
44+
private boolean filterWhereKeyword = true;
4445
private List<OrderByElement> funcOrderBy = null;
4546
private String onOverflowTruncate = null;
4647

@@ -391,12 +392,22 @@ public String toString() {
391392
/** Renders the filter using the caller's expression writer. */
392393
public void appendFilterTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
393394
if (filterExpression != null) {
394-
builder.append("FILTER (WHERE ");
395+
builder.append(filterWhereKeyword ? "FILTER (WHERE " : "FILTER (");
395396
expressionPrinter.accept(filterExpression);
396397
builder.append(')');
397398
}
398399
}
399400

401+
/** Whether the FILTER clause has WHERE, which DuckDB allows to leave out. */
402+
public boolean isFilterWhereKeyword() {
403+
return filterWhereKeyword;
404+
}
405+
406+
public AnalyticExpression setFilterWhereKeyword(boolean filterWhereKeyword) {
407+
this.filterWhereKeyword = filterWhereKeyword;
408+
return this;
409+
}
410+
400411
public boolean isAllColumns() {
401412
return allColumns;
402413
}

‎src/main/java/net/sf/jsqlparser/expression/ArrayExpression.java‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class ArrayExpression extends ASTNodeAccessImpl implements Expression {
1717
private Expression indexExpression;
1818
private Expression startIndexExpression;
1919
private Expression stopIndexExpression;
20+
private Expression stepExpression;
2021

2122

2223
public ArrayExpression() {
@@ -72,6 +73,19 @@ public void setStopIndexExpression(Expression stopIndexExpression) {
7273
this.stopIndexExpression = stopIndexExpression;
7374
}
7475

76+
public Expression getStepExpression() {
77+
return stepExpression;
78+
}
79+
80+
public void setStepExpression(Expression stepExpression) {
81+
this.stepExpression = stepExpression;
82+
}
83+
84+
public ArrayExpression withStepExpression(Expression stepExpression) {
85+
this.setStepExpression(stepExpression);
86+
return this;
87+
}
88+
7589
@Override
7690
public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
7791
return expressionVisitor.visit(this, context);
@@ -82,11 +96,8 @@ public String toString() {
8296
if (indexExpression != null) {
8397
return objExpression.toString() + "[" + indexExpression.toString() + "]";
8498
} else {
85-
return objExpression.toString() + "[" +
86-
(startIndexExpression == null ? "" : startIndexExpression.toString()) +
87-
":" +
88-
(stopIndexExpression == null ? "" : stopIndexExpression.toString()) +
89-
"]";
99+
return objExpression.toString() + "[" + RangeExpression.toString(startIndexExpression,
100+
stopIndexExpression, stepExpression) + "]";
90101
}
91102
}
92103

‎src/main/java/net/sf/jsqlparser/expression/ColumnsTransformer.java‎

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@
2525
public class ColumnsTransformer extends ASTNodeAccessImpl {
2626

2727
public enum ColumnsTransformerType {
28-
APPLY, EXCEPT, EXCLUDE, REPLACE
28+
APPLY, EXCEPT, EXCLUDE, REPLACE, RENAME
2929
}
3030

3131
private ColumnsTransformerType type;
3232
private Expression applyExpression;
3333
private ParenthesedExpressionList<Column> exceptColumns;
3434
private StringValue exceptPattern;
3535
private List<SelectItem<?>> replaceItems;
36+
private List<SelectItem<?>> renameItems;
37+
private boolean parenthesized = true;
3638
private boolean strict;
3739

3840
public ColumnsTransformer(ColumnsTransformerType type) {
@@ -108,6 +110,30 @@ public ColumnsTransformer setReplaceItems(List<SelectItem<?>> replaceItems) {
108110
return this;
109111
}
110112

113+
/** DuckDB's {@code RENAME (column AS name, ...)}: each item is a column with its new name. */
114+
public List<SelectItem<?>> getRenameItems() {
115+
return renameItems;
116+
}
117+
118+
public ColumnsTransformer setRenameItems(List<SelectItem<?>> renameItems) {
119+
this.renameItems = renameItems;
120+
return this;
121+
}
122+
123+
/**
124+
* Whether the columns or items of an {@code EXCLUDE}, {@code REPLACE} or {@code RENAME} are
125+
* parenthesized; DuckDB also accepts a single one without parentheses, e.g.
126+
* {@code * EXCLUDE i}.
127+
*/
128+
public boolean isParenthesized() {
129+
return parenthesized;
130+
}
131+
132+
public ColumnsTransformer setParenthesized(boolean parenthesized) {
133+
this.parenthesized = parenthesized;
134+
return this;
135+
}
136+
111137
void collectExpressions(List<Expression> expressions) {
112138
switch (type) {
113139
case APPLY:
@@ -135,6 +161,13 @@ void collectExpressions(List<Expression> expressions) {
135161
}
136162
}
137163
break;
164+
case RENAME:
165+
if (renameItems != null) {
166+
for (SelectItem<?> item : renameItems) {
167+
expressions.add(item.getExpression());
168+
}
169+
}
170+
break;
138171
default:
139172
throw new IllegalStateException("Unhandled ColumnsTransformerType: " + type);
140173
}
@@ -150,11 +183,22 @@ public StringBuilder appendTo(StringBuilder builder) {
150183
.append(exceptPattern != null ? exceptPattern : exceptColumns);
151184
break;
152185
case EXCLUDE:
153-
builder.append("EXCLUDE ").append(exceptColumns);
186+
builder.append("EXCLUDE ").append(parenthesized || exceptColumns.size() != 1
187+
? exceptColumns
188+
: exceptColumns.get(0));
154189
break;
155190
case REPLACE:
156-
builder.append("REPLACE").append(strict ? " STRICT" : "").append("(")
157-
.append(Select.getStringList(replaceItems)).append(")");
191+
boolean replaceParenthesized = parenthesized || replaceItems.size() != 1;
192+
builder.append("REPLACE").append(strict ? " STRICT" : "")
193+
.append(replaceParenthesized ? "(" : " ")
194+
.append(Select.getStringList(replaceItems))
195+
.append(replaceParenthesized ? ")" : "");
196+
break;
197+
case RENAME:
198+
boolean renameParenthesized = parenthesized || renameItems.size() != 1;
199+
builder.append("RENAME ").append(renameParenthesized ? "(" : "")
200+
.append(Select.getStringList(renameItems))
201+
.append(renameParenthesized ? ")" : "");
158202
break;
159203
default:
160204
throw new IllegalStateException("Unhandled ColumnsTransformerType: " + type);

‎src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
2020
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
2121
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
22+
import net.sf.jsqlparser.expression.operators.arithmetic.Exponentiation;
2223
import net.sf.jsqlparser.expression.operators.arithmetic.IntegerDivision;
2324
import net.sf.jsqlparser.expression.operators.arithmetic.Modulo;
2425
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
@@ -271,6 +272,15 @@ default void visit(Division division) {
271272

272273
<S> T visit(IntegerDivision integerDivision, S context);
273274

275+
default <S> T visit(Exponentiation exponentiation, S context) {
276+
visitExpression(exponentiation.getLeftExpression(), context);
277+
return visitExpression(exponentiation.getRightExpression(), context);
278+
}
279+
280+
default void visit(Exponentiation exponentiation) {
281+
this.visit(exponentiation, null);
282+
}
283+
274284
default void visit(IntegerDivision integerDivision) {
275285
this.visit(integerDivision, null);
276286
}
@@ -822,6 +832,16 @@ default void visit(LambdaExpression lambdaExpression) {
822832
this.visit(lambdaExpression, null);
823833
}
824834

835+
default <S> T visit(ListComprehension listComprehension, S context) {
836+
visitExpression(listComprehension.getExpression(), context);
837+
visitExpression(listComprehension.getList(), context);
838+
return visitExpression(listComprehension.getCondition(), context);
839+
}
840+
841+
default void visit(ListComprehension listComprehension) {
842+
this.visit(listComprehension, null);
843+
}
844+
825845
default <S> T visit(ColumnsExpression columnsExpression, S context) {
826846
for (Expression expression : columnsExpression.getAllExpressions()) {
827847
if (expression != null) {

‎src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
2323
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
2424
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
25+
import net.sf.jsqlparser.expression.operators.arithmetic.Exponentiation;
2526
import net.sf.jsqlparser.expression.operators.arithmetic.IntegerDivision;
2627
import net.sf.jsqlparser.expression.operators.arithmetic.Modulo;
2728
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
@@ -198,6 +199,11 @@ public <S> T visit(IntegerDivision integerDivision, S context) {
198199
return visitBinaryExpression(integerDivision, context);
199200
}
200201

202+
@Override
203+
public <S> T visit(Exponentiation exponentiation, S context) {
204+
return visitBinaryExpression(exponentiation, context);
205+
}
206+
201207
@Override
202208
public <S> T visit(Multiplication multiplication, S context) {
203209
return visitBinaryExpression(multiplication, context);
@@ -715,6 +721,9 @@ public <S> T visit(ArrayExpression arrayExpression, S context) {
715721
if (arrayExpression.getStopIndexExpression() != null) {
716722
subExpressions.add(arrayExpression.getStopIndexExpression());
717723
}
724+
if (arrayExpression.getStepExpression() != null) {
725+
subExpressions.add(arrayExpression.getStepExpression());
726+
}
718727
return visitExpressions(arrayExpression, context, subExpressions);
719728
}
720729

@@ -874,7 +883,7 @@ public <S> T visit(TrimFunction trimFunction, S context) {
874883
@Override
875884
public <S> T visit(RangeExpression rangeExpression, S context) {
876885
return visitExpressions(rangeExpression, context, rangeExpression.getStartExpression(),
877-
rangeExpression.getEndExpression());
886+
rangeExpression.getEndExpression(), rangeExpression.getStepExpression());
878887
}
879888

880889
@Override
@@ -909,6 +918,12 @@ public <S> T visit(LambdaExpression lambdaExpression, S context) {
909918
return lambdaExpression.getExpression().accept(this, context);
910919
}
911920

921+
@Override
922+
public <S> T visit(ListComprehension listComprehension, S context) {
923+
return visitExpressions(listComprehension, context, listComprehension.getExpression(),
924+
listComprehension.getList(), listComprehension.getCondition());
925+
}
926+
912927
@Override
913928
public <S> T visit(ColumnsExpression columnsExpression, S context) {
914929
return visitExpressions(columnsExpression, context, columnsExpression.getAllExpressions());

0 commit comments

Comments
 (0)