Skip to content

Commit ee764e8

Browse files
committed
Merge origin/master
2 parents 2647c0e + 6527662 commit ee764e8

File tree

8 files changed

+106
-2
lines changed

8 files changed

+106
-2
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class AnalyticExpression extends ASTNodeAccessImpl implements Expression
4848
private WindowElement windowElement;
4949
private KeepExpression keep = null;
5050
private AnalyticType type = AnalyticType.OVER;
51+
private boolean distinct = false;
5152

5253
@Override
5354
public void accept(ExpressionVisitor expressionVisitor) {
@@ -126,11 +127,22 @@ public void setType(AnalyticType type) {
126127
this.type = type;
127128
}
128129

130+
public boolean isDistinct() {
131+
return distinct;
132+
}
133+
134+
public void setDistinct(boolean distinct) {
135+
this.distinct = distinct;
136+
}
137+
129138
@Override
130139
public String toString() {
131140
StringBuilder b = new StringBuilder();
132141

133142
b.append(name).append("(");
143+
if (isDistinct()) {
144+
b.append("DISTINCT ");
145+
}
134146
if (expression != null) {
135147
b.append(expression.toString());
136148
if (offset != null) {
@@ -146,7 +158,7 @@ public String toString() {
146158
if (keep != null) {
147159
b.append(keep.toString()).append(" ");
148160
}
149-
161+
150162
switch (type) {
151163
case WITHIN_GROUP:
152164
b.append("WITHIN GROUP");

src/main/java/net/sf/jsqlparser/statement/create/view/CreateView.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class CreateView implements Statement {
3838
private boolean orReplace = false;
3939
private List<String> columnNames = null;
4040
private boolean materialized = false;
41+
private ForceOption force = ForceOption.NONE;
4142

4243
@Override
4344
public void accept(StatementVisitor statementVisitor) {
@@ -98,12 +99,28 @@ public void setMaterialized(boolean materialized) {
9899
this.materialized = materialized;
99100
}
100101

102+
public ForceOption getForce() {
103+
return force;
104+
}
105+
106+
public void setForce(ForceOption force) {
107+
this.force = force;
108+
}
109+
101110
@Override
102111
public String toString() {
103112
StringBuilder sql = new StringBuilder("CREATE ");
104113
if (isOrReplace()) {
105114
sql.append("OR REPLACE ");
106115
}
116+
switch (force) {
117+
case FORCE:
118+
sql.append("FORCE ");
119+
break;
120+
case NO_FORCE:
121+
sql.append("NO FORCE ");
122+
break;
123+
}
107124
if (isMaterialized()) {
108125
sql.append("MATERIALIZED ");
109126
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2018 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
package net.sf.jsqlparser.statement.create.view;
23+
24+
/**
25+
*
26+
* @author Tobias Warneke ([email protected])
27+
*/
28+
public enum ForceOption {
29+
NONE,
30+
31+
FORCE,
32+
33+
NO_FORCE
34+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ public void deParse(CreateView createView) {
5656
if (createView.isOrReplace()) {
5757
buffer.append("OR REPLACE ");
5858
}
59+
switch (createView.getForce()) {
60+
case FORCE:
61+
buffer.append("FORCE ");
62+
break;
63+
case NO_FORCE:
64+
buffer.append("NO FORCE ");
65+
break;
66+
}
5967
if (createView.isMaterialized()) {
6068
buffer.append("MATERIALIZED ");
6169
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,9 @@ public void visit(AnalyticExpression aexpr) {
604604
WindowElement windowElement = aexpr.getWindowElement();
605605

606606
buffer.append(name).append("(");
607+
if (aexpr.isDistinct()) {
608+
buffer.append("DISTINCT ");
609+
}
607610
if (expression != null) {
608611
expression.accept(this);
609612
if (offset != null) {

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2616,10 +2616,14 @@ AnalyticExpression AnalyticExpression() :
26162616
Expression defaultValue = null;
26172617
WindowElement windowElement = null;
26182618
KeepExpression keep = null;
2619+
boolean distinct = false;
26192620
}
26202621
{
26212622
token=<S_IDENTIFIER> { retval.setName(token.image); }
2622-
"(" [ expr=SimpleExpression() ["," offset=SimpleExpression() ["," defaultValue=SimpleExpression() ]] | "*" { retval.setAllColumns(true); } ] ")"
2623+
"(" [
2624+
[ <K_DISTINCT> {distinct = true;} ]
2625+
(expr=SimpleExpression() ["," offset=SimpleExpression() ["," defaultValue=SimpleExpression() ]] | "*" { retval.setAllColumns(true); } )
2626+
] ")"
26232627

26242628
[ keep=KeepExpression() ]
26252629

@@ -2631,6 +2635,7 @@ AnalyticExpression AnalyticExpression() :
26312635
[olist=OrderByElements() [windowElement = WindowElement() ] ]
26322636

26332637
{
2638+
retval.setDistinct(distinct);
26342639
retval.setExpression(expr);
26352640
retval.setOffset(offset);
26362641
retval.setDefaultValue(defaultValue);
@@ -3197,6 +3202,10 @@ CreateView CreateView():
31973202
{
31983203
<K_CREATE>
31993204
[ <K_OR> <K_REPLACE> { createView.setOrReplace(true);} ]
3205+
[
3206+
<K_NO> <K_FORCE> { createView.setForce(ForceOption.NO_FORCE); }
3207+
| <K_FORCE> { createView.setForce(ForceOption.FORCE); }
3208+
]
32003209
[ <K_MATERIALIZED> { createView.setMaterialized(true);} ]
32013210
<K_VIEW> view=Table() { createView.setView(view); }
32023211
[ columnNames = ColumnsNamesList() { createView.setColumnNames(columnNames); } ]

src/test/java/net/sf/jsqlparser/test/create/CreateViewTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,20 @@ public void testCreateMaterializedView() throws JSQLParserException {
6868
String stmt = "CREATE MATERIALIZED VIEW view1 AS SELECT a, b FROM testtab";
6969
assertSqlCanBeParsedAndDeparsed(stmt);
7070
}
71+
72+
public void testCreateForceView() throws JSQLParserException {
73+
assertSqlCanBeParsedAndDeparsed("CREATE FORCE VIEW view1 AS SELECT a, b FROM testtab");
74+
}
75+
76+
public void testCreateForceView1() throws JSQLParserException {
77+
assertSqlCanBeParsedAndDeparsed("CREATE NO FORCE VIEW view1 AS SELECT a, b FROM testtab");
78+
}
79+
80+
public void testCreateForceView2() throws JSQLParserException {
81+
assertSqlCanBeParsedAndDeparsed("CREATE OR REPLACE FORCE VIEW view1 AS SELECT a, b FROM testtab");
82+
}
83+
84+
public void testCreateForceView3() throws JSQLParserException {
85+
assertSqlCanBeParsedAndDeparsed("CREATE OR REPLACE NO FORCE VIEW view1 AS SELECT a, b FROM testtab");
86+
}
7187
}

src/test/java/net/sf/jsqlparser/test/select/SelectTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,11 @@ public void testAnalyticFunctionProblem1() throws JSQLParserException {
16181618
String statement = "SELECT last_value(s.revenue_hold) OVER (PARTITION BY s.id_d_insertion_order, s.id_d_product_ad_attr, trunc(s.date_id, 'mm') ORDER BY s.date_id) AS col FROM s";
16191619
assertSqlCanBeParsedAndDeparsed(statement);
16201620
}
1621+
1622+
public void testAnalyticFunction19() throws JSQLParserException {
1623+
String statement = "SELECT count(DISTINCT CASE WHEN client_organic_search_drop_flag = 1 THEN brand END) OVER (PARTITION BY client, category_1, category_2, category_3, category_4 ) AS client_brand_org_drop_count FROM sometable";
1624+
assertSqlCanBeParsedAndDeparsed(statement);
1625+
}
16211626

16221627
public void testAnalyticFunctionProblem1b() throws JSQLParserException {
16231628
String statement = "SELECT last_value(s.revenue_hold) OVER (PARTITION BY s.id_d_insertion_order, s.id_d_product_ad_attr, trunc(s.date_id, 'mm') ORDER BY s.date_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS col FROM s";

0 commit comments

Comments
 (0)