Skip to content

Commit 2f6afbc

Browse files
feat: WITH ... AS NOT MATERIALIZED
- fixes #2251 Signed-off-by: Andreas Reichel <[email protected]>
1 parent 001ad1c commit 2f6afbc

File tree

4 files changed

+57
-5
lines changed

4 files changed

+57
-5
lines changed

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class WithItem<K extends ParenthesedStatement> implements Serializable {
2828
private Alias alias;
2929
private List<SelectItem<?>> withItemList;
3030
private boolean recursive = false;
31-
31+
private boolean usingNot = false;
3232
private boolean materialized = false;
3333

3434
public WithItem(K statement, Alias alias) {
@@ -90,6 +90,24 @@ public void setMaterialized(boolean materialized) {
9090
this.materialized = materialized;
9191
}
9292

93+
public K getStatement() {
94+
return statement;
95+
}
96+
97+
public WithItem<K> setStatement(K statement) {
98+
this.statement = statement;
99+
return this;
100+
}
101+
102+
public boolean isUsingNot() {
103+
return usingNot;
104+
}
105+
106+
public WithItem<K> setUsingNot(boolean usingNot) {
107+
this.usingNot = usingNot;
108+
return this;
109+
}
110+
93111
/**
94112
* The {@link SelectItem}s in this WITH (for example the A,B,C in "WITH mywith (A,B,C) AS ...")
95113
*
@@ -119,7 +137,11 @@ public String toString() {
119137
builder.append(")");
120138
}
121139
builder.append(" AS ");
122-
builder.append(materialized ? "MATERIALIZED " : "");
140+
if (materialized) {
141+
builder.append(usingNot
142+
? "NOT MATERIALIZED "
143+
: "MATERIALIZED ");
144+
}
123145
builder.append(statement);
124146
return builder.toString();
125147
}
@@ -144,6 +166,13 @@ public WithItem<?> withRecursive(boolean recursive, boolean materialized) {
144166
return this;
145167
}
146168

169+
public WithItem<?> withRecursive(boolean recursive, boolean usingNot, boolean materialized) {
170+
this.setRecursive(recursive);
171+
this.setUsingNot(usingNot);
172+
this.setMaterialized(materialized);
173+
return this;
174+
}
175+
147176
public WithItem<?> addWithItemList(SelectItem<?>... withItemList) {
148177
List<SelectItem<?>> collection =
149178
Optional.ofNullable(getWithItemList()).orElseGet(ArrayList::new);

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,9 @@ public <S> StringBuilder visit(WithItem<?> withItem, S context) {
718718
}
719719
builder.append(" AS ");
720720
if (withItem.isMaterialized()) {
721-
builder.append("MATERIALIZED ");
721+
builder.append(withItem.isUsingNot()
722+
? "NOT MATERIALIZED "
723+
: "MATERIALIZED ");
722724
}
723725
StatementDeParser statementDeParser =
724726
new StatementDeParser((ExpressionDeParser) expressionVisitor, this, builder);

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3348,6 +3348,7 @@ WithItem<?> WithItem() #WithItem:
33483348
{
33493349
boolean recursive = false;
33503350
boolean materialized = false;
3351+
boolean usingNot = false;
33513352
String name;
33523353
List<SelectItem<?>> selectItems = null;
33533354
ParenthesedStatement statement;
@@ -3357,7 +3358,7 @@ WithItem<?> WithItem() #WithItem:
33573358
name=RelObjectName()
33583359
[ "(" selectItems=SelectItemsList() ")" ]
33593360
<K_AS>
3360-
[ LOOKAHEAD(2) <K_MATERIALIZED> { materialized = true; } ]
3361+
[ LOOKAHEAD(2) [ <K_NOT> { usingNot = true; } ] <K_MATERIALIZED> { materialized = true; } ]
33613362
(
33623363
LOOKAHEAD(2) statement = ParenthesedSelect()
33633364
|
@@ -3370,7 +3371,7 @@ WithItem<?> WithItem() #WithItem:
33703371
{
33713372
WithItem<?> withItem = new WithItem(statement, new Alias(name, false));
33723373
return withItem
3373-
.withRecursive(recursive, materialized)
3374+
.withRecursive(recursive, usingNot, materialized)
33743375
.withWithItemList(selectItems);
33753376
}
33763377
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.sf.jsqlparser.statement.select;
2+
3+
import net.sf.jsqlparser.JSQLParserException;
4+
import net.sf.jsqlparser.test.TestUtils;
5+
import org.junit.jupiter.api.Test;
6+
7+
class WithItemTest {
8+
9+
@Test
10+
void testNotMaterializedIssue2251() throws JSQLParserException {
11+
String sqlStr = "WITH devices AS NOT MATERIALIZED (\n"
12+
+ " SELECT\n"
13+
+ " d.uuid AS device_uuid\n"
14+
+ " FROM active_devices d\n"
15+
+ ")\n"
16+
+ "SELECT 1;";
17+
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
18+
}
19+
20+
}

0 commit comments

Comments
 (0)