Skip to content

Commit 9c292ef

Browse files
committed
Merge latest master and resolve usage documentation conflict
2 parents 5bd6cdd + eddb1fb commit 9c292ef

13 files changed

Lines changed: 545 additions & 19 deletions

File tree

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public enum Kind {
2727
PRIMARY_KEY, UNIQUE, INDEX, FULLTEXT, SPATIAL, FOREIGN_KEY, CHECK, EXCLUDE, DEFAULT, OTHER
2828
}
2929

30+
public enum Clustering {
31+
CLUSTERED, NONCLUSTERED
32+
}
33+
3034
private final List<String> name = new ArrayList<>();
3135
private String type;
3236
private String using;
@@ -35,12 +39,31 @@ public enum Kind {
3539
private String commentText;
3640
private String indexKeyword;
3741
private Kind kind = Kind.OTHER;
42+
private Clustering clustering;
3843
private Boolean nullsDistinct;
3944
private List<String> includeColumns;
4045
private List<Option> storageParameters;
4146
private String tableSpace;
4247
private ConstraintAttributes constraintAttributes;
4348

49+
/** Returns the explicit SQL Server clustering option, or null when it was omitted. */
50+
public Clustering getClustering() {
51+
return clustering;
52+
}
53+
54+
public void setClustering(Clustering clustering) {
55+
this.clustering = clustering;
56+
}
57+
58+
public Index withClustering(Clustering clustering) {
59+
setClustering(clustering);
60+
return this;
61+
}
62+
63+
public String clusteringClause() {
64+
return clustering == null ? "" : " " + clustering;
65+
}
66+
4467
public Boolean getNullsDistinct() {
4568
return nullsDistinct;
4669
}
@@ -277,7 +300,8 @@ public String toString() {
277300
: "")
278301
+ (!idxSpecText.isEmpty() ? " " + idxSpecText : "");
279302

280-
StringBuilder sql = new StringBuilder(head).append(nullsDistinctClause());
303+
StringBuilder sql = new StringBuilder(head).append(nullsDistinctClause())
304+
.append(clusteringClause());
281305
if (!tail.isEmpty()) {
282306
sql.append(' ').append(tail);
283307
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public String toString() {
9191
String tail = getType()
9292
+ nullsDistinctClause()
9393
+ keyword
94+
+ clusteringClause()
9495
+ (indexName != null ? " " + indexName : "")
9596
+ (getUsing() != null ? " USING " + getUsing() : "")
9697
+ (getColumns() == null ? ""
@@ -113,6 +114,12 @@ public NamedConstraint withIndexName(String indexName) {
113114
return this;
114115
}
115116

117+
@Override
118+
public NamedConstraint withClustering(Clustering clustering) {
119+
setClustering(clustering);
120+
return this;
121+
}
122+
116123
public NamedConstraint withUseConstraintKeyword(boolean useConstraintKeyword) {
117124
setUseConstraintKeyword(useConstraintKeyword);
118125
return this;

src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ public <S> T visit(SetOperationList setOpList, S context) {
298298
*/
299299
@Override
300300
public <S> T visit(WithItem<?> withItem, S context) {
301+
if (withItem.getCycleClause() != null) {
302+
withItem.getCycleClause().accept(expressionVisitor, context);
303+
}
301304
ParenthesedStatement body = withItem.getParenthesedStatement();
302305

303306
// ParenthesedSelect is a Select and stays on the select path
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2026 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.select;
11+
12+
import java.io.Serializable;
13+
import java.util.function.Consumer;
14+
import net.sf.jsqlparser.expression.Expression;
15+
import net.sf.jsqlparser.expression.ExpressionVisitor;
16+
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
17+
import net.sf.jsqlparser.schema.Column;
18+
19+
/** Cycle detection metadata for a recursive common table expression. */
20+
public class WithCycleClause implements Serializable {
21+
private ExpressionList<Column> cycleColumns;
22+
private String markColumnName;
23+
private Expression markValue;
24+
private Expression markDefault;
25+
private String pathColumnName;
26+
27+
public ExpressionList<Column> getCycleColumns() {
28+
return cycleColumns;
29+
}
30+
31+
public void setCycleColumns(ExpressionList<Column> cycleColumns) {
32+
this.cycleColumns = cycleColumns;
33+
}
34+
35+
public WithCycleClause withCycleColumns(ExpressionList<Column> cycleColumns) {
36+
setCycleColumns(cycleColumns);
37+
return this;
38+
}
39+
40+
public String getMarkColumnName() {
41+
return markColumnName;
42+
}
43+
44+
public void setMarkColumnName(String markColumnName) {
45+
this.markColumnName = markColumnName;
46+
}
47+
48+
public WithCycleClause withMarkColumnName(String markColumnName) {
49+
setMarkColumnName(markColumnName);
50+
return this;
51+
}
52+
53+
public Expression getMarkValue() {
54+
return markValue;
55+
}
56+
57+
public void setMarkValue(Expression markValue) {
58+
this.markValue = markValue;
59+
}
60+
61+
public WithCycleClause withMarkValue(Expression markValue) {
62+
setMarkValue(markValue);
63+
return this;
64+
}
65+
66+
public Expression getMarkDefault() {
67+
return markDefault;
68+
}
69+
70+
public void setMarkDefault(Expression markDefault) {
71+
this.markDefault = markDefault;
72+
}
73+
74+
public WithCycleClause withMarkDefault(Expression markDefault) {
75+
setMarkDefault(markDefault);
76+
return this;
77+
}
78+
79+
public String getPathColumnName() {
80+
return pathColumnName;
81+
}
82+
83+
public void setPathColumnName(String pathColumnName) {
84+
this.pathColumnName = pathColumnName;
85+
}
86+
87+
public WithCycleClause withPathColumnName(String pathColumnName) {
88+
setPathColumnName(pathColumnName);
89+
return this;
90+
}
91+
92+
public <S> void accept(ExpressionVisitor<?> visitor, S context) {
93+
if (cycleColumns != null) {
94+
cycleColumns.forEach(column -> column.accept(visitor, context));
95+
}
96+
if (markValue != null) {
97+
markValue.accept(visitor, context);
98+
}
99+
if (markDefault != null) {
100+
markDefault.accept(visitor, context);
101+
}
102+
}
103+
104+
public StringBuilder appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
105+
builder.append("CYCLE ");
106+
if (cycleColumns != null) {
107+
for (int i = 0; i < cycleColumns.size(); i++) {
108+
if (i > 0) {
109+
builder.append(", ");
110+
}
111+
expressionPrinter.accept(cycleColumns.get(i));
112+
}
113+
}
114+
builder.append(" SET ").append(markColumnName);
115+
if (markValue != null) {
116+
builder.append(" TO ");
117+
expressionPrinter.accept(markValue);
118+
builder.append(" DEFAULT ");
119+
expressionPrinter.accept(markDefault);
120+
}
121+
return builder.append(" USING ").append(pathColumnName);
122+
}
123+
124+
@Override
125+
public String toString() {
126+
StringBuilder builder = new StringBuilder();
127+
return appendTo(builder, expression -> builder.append(expression)).toString();
128+
}
129+
}

src/main/java/net/sf/jsqlparser/statement/select/WithItem.java

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

12+
import java.util.function.Consumer;
13+
import net.sf.jsqlparser.expression.Expression;
14+
1215
import java.io.Serializable;
1316
import java.util.ArrayList;
1417
import java.util.Collection;
@@ -28,6 +31,7 @@ public class WithItem<K extends ParenthesedStatement> implements Serializable {
2831
private List<SelectItem<?>> withItemList;
2932
private WithFunctionDeclaration withFunctionDeclaration;
3033
private WithSearchClause searchClause;
34+
private WithCycleClause cycleClause;
3135
private boolean recursive = false;
3236
private boolean usingNot = false;
3337
private boolean materialized = false;
@@ -149,6 +153,32 @@ public WithItem<K> withSearchClause(WithSearchClause searchClause) {
149153
return this;
150154
}
151155

156+
public WithCycleClause getCycleClause() {
157+
return cycleClause;
158+
}
159+
160+
public void setCycleClause(WithCycleClause cycleClause) {
161+
this.cycleClause = cycleClause;
162+
}
163+
164+
public WithItem<K> withCycleClause(WithCycleClause cycleClause) {
165+
setCycleClause(cycleClause);
166+
return this;
167+
}
168+
169+
public StringBuilder appendRecursiveClausesTo(StringBuilder builder,
170+
Consumer<Expression> expressionPrinter) {
171+
if (searchClause != null) {
172+
builder.append(" ");
173+
searchClause.appendTo(builder, expressionPrinter);
174+
}
175+
if (cycleClause != null) {
176+
builder.append(" ");
177+
cycleClause.appendTo(builder, expressionPrinter);
178+
}
179+
return builder;
180+
}
181+
152182
@Override
153183
public String toString() {
154184
StringBuilder builder = new StringBuilder();
@@ -174,9 +204,7 @@ public String toString() {
174204
: "MATERIALIZED ");
175205
}
176206
builder.append(statement);
177-
if (searchClause != null) {
178-
builder.append(" ").append(searchClause);
179-
}
207+
appendRecursiveClausesTo(builder, expression -> builder.append(expression));
180208
}
181209
return builder.toString();
182210
}

src/main/java/net/sf/jsqlparser/statement/select/WithSearchClause.java

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

12+
import java.util.function.Consumer;
13+
import net.sf.jsqlparser.expression.Expression;
14+
1215
import java.io.Serializable;
1316
import java.util.Collection;
1417

@@ -86,15 +89,23 @@ public WithSearchClause withSequenceColumnName(String sequenceColumnName) {
8689
return this;
8790
}
8891

92+
public StringBuilder appendTo(StringBuilder builder,
93+
Consumer<Expression> expressionPrinter) {
94+
builder.append("SEARCH ").append(searchOrder).append(" FIRST BY ");
95+
if (searchColumns != null) {
96+
for (int i = 0; i < searchColumns.size(); i++) {
97+
if (i > 0) {
98+
builder.append(", ");
99+
}
100+
expressionPrinter.accept(searchColumns.get(i));
101+
}
102+
}
103+
return builder.append(" SET ").append(sequenceColumnName);
104+
}
105+
89106
@Override
90107
public String toString() {
91-
return new StringBuilder()
92-
.append("SEARCH ")
93-
.append(searchOrder)
94-
.append(" FIRST BY ")
95-
.append(Select.getStringList(searchColumns))
96-
.append(" SET ")
97-
.append(sequenceColumnName)
98-
.toString();
108+
StringBuilder builder = new StringBuilder();
109+
return appendTo(builder, expression -> builder.append(expression)).toString();
99110
}
100111
}

src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ public <S> Void visit(WithItem<?> withItem, S context) {
333333
if (withItem.getAlias() != null) {
334334
otherItemNames.add(withItem.getAlias().getName());
335335
}
336+
if (withItem.getCycleClause() != null) {
337+
withItem.getCycleClause().accept(this, context);
338+
}
336339
// dispatch any ParenthesedStatement payload (Select, Delete, Update, Insert)
337340
withItem.accept((StatementVisitor<?>) this, context);
338341
return null;

src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -901,9 +901,8 @@ public <S> StringBuilder visit(WithItem<?> withItem, S context) {
901901
StatementDeParser statementDeParser =
902902
new StatementDeParser((ExpressionDeParser) expressionVisitor, this, builder);
903903
statementDeParser.deParse(withItem.getParenthesedStatement());
904-
if (withItem.getSearchClause() != null) {
905-
builder.append(" ").append(withItem.getSearchClause());
906-
}
904+
withItem.appendRecursiveClausesTo(builder,
905+
expression -> expression.accept(expressionVisitor, context));
907906
} else {
908907
builder.append(withItem.getWithFunctionDeclaration().toString());
909908
}

src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@ public <S> Void visit(WithItem<?> withItem, S context) {
394394
if (isNotEmpty(withItem.getWithItemList())) {
395395
withItem.getWithItemList().forEach(wi -> wi.accept(this, context));
396396
}
397+
if (withItem.getCycleClause() != null) {
398+
withItem.getCycleClause().accept(getValidator(ExpressionValidator.class), context);
399+
}
397400
withItem.accept(getValidator(StatementValidator.class), context);
398401
return null;
399402
}

0 commit comments

Comments
 (0)