Skip to content

Commit 3046924

Browse files
authored
Failure to parse query with PRIOR in select list (#2083)
* Added support for PRIOR operator to be used in select list * Fixed copy paste issue
1 parent 5cf281f commit 3046924

File tree

11 files changed

+155
-0
lines changed

11 files changed

+155
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2021 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
/*
11+
* Copyright (C) 2021 JSQLParser.
12+
*
13+
* This library is free software; you can redistribute it and/or modify it under the terms of the
14+
* GNU Lesser General Public License as published by the Free Software Foundation; either version
15+
* 2.1 of the License, or (at your option) any later version.
16+
*
17+
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
18+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19+
* Lesser General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Lesser General Public License along with this library;
22+
* if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23+
* 02110-1301 USA
24+
*/
25+
26+
package net.sf.jsqlparser.expression;
27+
28+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
29+
import net.sf.jsqlparser.schema.Column;
30+
31+
import java.util.Objects;
32+
33+
/**
34+
*
35+
* @author are
36+
*/
37+
public class ConnectByPriorOperator extends ASTNodeAccessImpl implements Expression {
38+
private final Column column;
39+
40+
public ConnectByPriorOperator(Column column) {
41+
this.column = Objects.requireNonNull(column,
42+
"The COLUMN of the ConnectByPrior Operator must not be null");
43+
}
44+
45+
public Column getColumn() {
46+
return column;
47+
}
48+
49+
@Override
50+
public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
51+
return expressionVisitor.visit(this, context);
52+
}
53+
54+
public StringBuilder appendTo(StringBuilder builder) {
55+
builder.append("PRIOR ").append(column);
56+
return builder;
57+
}
58+
59+
@Override
60+
public String toString() {
61+
return appendTo(new StringBuilder()).toString();
62+
}
63+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,12 @@ default void visit(ConnectByRootOperator connectByRootOperator) {
557557
this.visit(connectByRootOperator, null);
558558
}
559559

560+
<S> T visit(ConnectByPriorOperator connectByPriorOperator, S context);
561+
562+
default void visit(ConnectByPriorOperator connectByPriorOperator) {
563+
this.visit(connectByPriorOperator, null);
564+
}
565+
560566
<S> T visit(OracleNamedFunctionParameter oracleNamedFunctionParameter, S context);
561567

562568
default void visit(OracleNamedFunctionParameter oracleNamedFunctionParameter) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,11 @@ public <S> T visit(ConnectByRootOperator connectByRootOperator, S context) {
703703
return connectByRootOperator.getColumn().accept(this, context);
704704
}
705705

706+
@Override
707+
public <S> T visit(ConnectByPriorOperator connectByPriorOperator, S context) {
708+
return connectByPriorOperator.getColumn().accept(this, context);
709+
}
710+
706711
@Override
707712
public <S> T visit(OracleNamedFunctionParameter oracleNamedFunctionParameter, S context) {
708713
return oracleNamedFunctionParameter.getExpression().accept(this, context);

src/main/java/net/sf/jsqlparser/parser/ParserKeywordsUtils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class ParserKeywordsUtils {
5656
{"CHECK", RESTRICTED_SQL2016},
5757
{"CONNECT", RESTRICTED_ALIAS},
5858
{"CONNECT_BY_ROOT", RESTRICTED_JSQLPARSER},
59+
{"PRIOR", RESTRICTED_JSQLPARSER},
5960
{"CONSTRAINT", RESTRICTED_SQL2016},
6061
{"CREATE", RESTRICTED_ALIAS},
6162
{"CROSS", RESTRICTED_SQL2016},

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import net.sf.jsqlparser.expression.CastExpression;
2121
import net.sf.jsqlparser.expression.CollateExpression;
2222
import net.sf.jsqlparser.expression.ConnectByRootOperator;
23+
import net.sf.jsqlparser.expression.ConnectByPriorOperator;
2324
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
2425
import net.sf.jsqlparser.expression.DateValue;
2526
import net.sf.jsqlparser.expression.DoubleValue;
@@ -1722,6 +1723,12 @@ public <S> Void visit(ConnectByRootOperator connectByRootOperator, S context) {
17221723
return null;
17231724
}
17241725

1726+
@Override
1727+
public <S> Void visit(ConnectByPriorOperator connectByPriorOperator, S context) {
1728+
connectByPriorOperator.getColumn().accept(this, context);
1729+
return null;
1730+
}
1731+
17251732
@Override
17261733
public <S> Void visit(IfElseStatement ifElseStatement, S context) {
17271734
ifElseStatement.getIfStatement().accept(this, context);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import net.sf.jsqlparser.expression.CastExpression;
2121
import net.sf.jsqlparser.expression.CollateExpression;
2222
import net.sf.jsqlparser.expression.ConnectByRootOperator;
23+
import net.sf.jsqlparser.expression.ConnectByPriorOperator;
2324
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
2425
import net.sf.jsqlparser.expression.DateValue;
2526
import net.sf.jsqlparser.expression.DoubleValue;
@@ -1583,6 +1584,13 @@ public <S> StringBuilder visit(ConnectByRootOperator connectByRootOperator, S co
15831584
return buffer;
15841585
}
15851586

1587+
@Override
1588+
public <S> StringBuilder visit(ConnectByPriorOperator connectByPriorOperator, S context) {
1589+
buffer.append("PRIOR ");
1590+
connectByPriorOperator.getColumn().accept(this, context);
1591+
return buffer;
1592+
}
1593+
15861594
@Override
15871595
public <S> StringBuilder visit(OracleNamedFunctionParameter oracleNamedFunctionParameter,
15881596
S context) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import net.sf.jsqlparser.expression.CastExpression;
2020
import net.sf.jsqlparser.expression.CollateExpression;
2121
import net.sf.jsqlparser.expression.ConnectByRootOperator;
22+
import net.sf.jsqlparser.expression.ConnectByPriorOperator;
2223
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
2324
import net.sf.jsqlparser.expression.DateValue;
2425
import net.sf.jsqlparser.expression.DoubleValue;
@@ -1014,6 +1015,12 @@ public <S> Void visit(ConnectByRootOperator connectByRootOperator, S context) {
10141015
return null;
10151016
}
10161017

1018+
@Override
1019+
public <S> Void visit(ConnectByPriorOperator connectByPriorOperator, S context) {
1020+
connectByPriorOperator.getColumn().accept(this, context);
1021+
return null;
1022+
}
1023+
10171024
@Override
10181025
public <S> Void visit(OracleNamedFunctionParameter oracleNamedFunctionParameter, S context) {
10191026
oracleNamedFunctionParameter.getExpression().accept(this, context);

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2749,6 +2749,8 @@ SelectItem<?> SelectItem() #SelectItem:
27492749
(
27502750
expression = AllColumns()
27512751
|
2752+
expression = ConnectByPriorOperator()
2753+
|
27522754
LOOKAHEAD(AllTableColumns()) expression = AllTableColumns()
27532755
|
27542756
LOOKAHEAD( 3 ) expression = XorExpression()
@@ -4899,6 +4901,17 @@ ConnectByRootOperator ConnectByRootOperator() #ConnectByRootOperator: {
48994901
}
49004902
}
49014903

4904+
ConnectByPriorOperator ConnectByPriorOperator() #ConnectByPriorOperator: {
4905+
Column column;
4906+
}
4907+
{
4908+
<K_PRIOR> column = Column()
4909+
{
4910+
return new ConnectByPriorOperator(column);
4911+
}
4912+
}
4913+
4914+
49024915
NextValExpression NextValExpression() : {
49034916
ObjectNames data = null;
49044917
Token token;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
-- #%L
3+
-- JSQLParser library
4+
-- %%
5+
-- Copyright (C) 2004 - 2019 JSQLParser
6+
-- %%
7+
-- Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
-- #L%
9+
---
10+
select t.*, connect_by_root t.id as root_id
11+
from test t
12+
start with t.id = 1
13+
connect by prior t.id = t.parent_id
14+
order siblings by t.some_text
15+
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Oct 2, 2024, 8:11:58 PM
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
-- #%L
3+
-- JSQLParser library
4+
-- %%
5+
-- Copyright (C) 2004 - 2019 JSQLParser
6+
-- %%
7+
-- Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
-- #L%
9+
---
10+
select t.*, prior t.id parent_id
11+
from test t
12+
start with t.id = 1
13+
connect by prior t.id = t.parent_id
14+
order siblings by t.some_text
15+
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Oct 2, 2024, 8:14:31 PM

0 commit comments

Comments
 (0)