Skip to content

Commit 10e8e25

Browse files
committed
fixes #649
and implemented ! for not and extended not expression
1 parent 1529786 commit 10e8e25

File tree

8 files changed

+128
-57
lines changed

8 files changed

+128
-57
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Also I would like to know about needed examples or documentation stuff.
5959

6060
## Extensions in the latest SNAPSHOT version 2.0
6161

62+
* first support for db date arithmentic
6263
* support for chained functions
6364
* first support for **FOR XML PATH**
6465
* support for **NEXTVAL FOR**

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ public class IntervalExpression extends ASTNodeAccessImpl implements Expression
1515

1616
private String parameter = null;
1717
private String intervalType = null;
18+
private final boolean intervalKeyword;
19+
20+
public IntervalExpression() {
21+
this(true);
22+
}
23+
24+
public IntervalExpression(boolean intervalKeyword) {
25+
this.intervalKeyword = intervalKeyword;
26+
}
1827

1928
public String getParameter() {
2029
return parameter;
@@ -34,7 +43,7 @@ public void setIntervalType(String intervalType) {
3443

3544
@Override
3645
public String toString() {
37-
return "INTERVAL " + parameter + (intervalType != null ? " " + intervalType : "");
46+
return (intervalKeyword ? "INTERVAL " : "") + parameter + (intervalType != null ? " " + intervalType : "");
3847
}
3948

4049
@Override

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@ public class NotExpression extends ASTNodeAccessImpl implements Expression {
1515

1616
private Expression expression;
1717

18+
private boolean exclamationMark = false;
19+
1820
public NotExpression(Expression expression) {
21+
this(expression, false);
22+
}
23+
24+
public NotExpression(Expression expression, boolean useExclamationMark) {
1925
setExpression(expression);
26+
this.exclamationMark = useExclamationMark;
2027
}
2128

2229
public Expression getExpression() {
@@ -34,6 +41,14 @@ public void accept(ExpressionVisitor expressionVisitor) {
3441

3542
@Override
3643
public String toString() {
37-
return "NOT " + expression.toString();
44+
return (exclamationMark ? "! " : "NOT ") + expression.toString();
45+
}
46+
47+
public boolean isExclamationMark() {
48+
return exclamationMark;
49+
}
50+
51+
public void setExclamationMark(boolean exclamationMark) {
52+
this.exclamationMark = exclamationMark;
3853
}
3954
}

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

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
public class Parenthesis extends ASTNodeAccessImpl implements Expression {
1515

1616
private Expression expression;
17-
18-
private boolean not = false;
1917

2018
public Parenthesis() {
2119
}
@@ -37,16 +35,8 @@ public void accept(ExpressionVisitor expressionVisitor) {
3735
expressionVisitor.visit(this);
3836
}
3937

40-
public void setNot() {
41-
not = true;
42-
}
43-
44-
public boolean isNot() {
45-
return not;
46-
}
47-
4838
@Override
4939
public String toString() {
50-
return (not ? "NOT " : "") + "(" + expression + ")";
40+
return "(" + expression + ")";
5141
}
5242
}

src/main/java/net/sf/jsqlparser/util/cnfexpression/CloneHelper.java

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import java.util.ArrayList;
1313
import java.util.List;
14-
1514
import net.sf.jsqlparser.expression.BinaryExpression;
1615
import net.sf.jsqlparser.expression.Expression;
1716
import net.sf.jsqlparser.expression.NotExpression;
@@ -22,64 +21,61 @@
2221
class CloneHelper {
2322

2423
public Expression modify(Expression express) {
25-
if(express instanceof NotExpression) {
24+
if (express instanceof NotExpression) {
2625
return new NotExpression(modify(((NotExpression) express).getExpression()));
2726
}
28-
if(express instanceof Parenthesis) {
27+
if (express instanceof Parenthesis) {
2928
Parenthesis parenthesis = (Parenthesis) express;
3029
Expression result = modify(parenthesis.getExpression());
31-
if(parenthesis.isNot()) {
32-
return new NotExpression(result);
33-
}
3430
return result;
3531
}
36-
if(express instanceof AndExpression) {
32+
if (express instanceof AndExpression) {
3733
AndExpression and = (AndExpression) express;
3834
List<Expression> list = new ArrayList<Expression>();
3935
list.add(modify(and.getLeftExpression()));
4036
list.add(modify(and.getRightExpression()));
4137
MultiAndExpression result = new MultiAndExpression(list);
42-
if(and.isNot()) {
38+
if (and.isNot()) {
4339
return new NotExpression(result);
4440
}
4541
return result;
4642
}
47-
if(express instanceof OrExpression) {
43+
if (express instanceof OrExpression) {
4844
OrExpression or = (OrExpression) express;
4945
List<Expression> list = new ArrayList<Expression>();
5046
list.add(modify(or.getLeftExpression()));
5147
list.add(modify(or.getRightExpression()));
5248
MultiOrExpression result = new MultiOrExpression(list);
53-
if(or.isNot()) {
49+
if (or.isNot()) {
5450
return new NotExpression(result);
5551
}
5652
return result;
5753
}
58-
if(express instanceof BinaryExpression) {
54+
if (express instanceof BinaryExpression) {
5955
BinaryExpression binary = (BinaryExpression) express;
60-
if(binary.isNot()) {
56+
if (binary.isNot()) {
6157
binary.removeNot();
6258
return new NotExpression(modify(binary));
63-
}
59+
}
6460
}
6561
return express;
6662
}
67-
63+
6864
/**
69-
* This method is used to copy the expression which happens at
70-
* step four. I only copy the conditional expressions since the
71-
* CNF only changes the conditional part.
65+
* This method is used to copy the expression which happens at step four. I only copy the
66+
* conditional expressions since the CNF only changes the conditional part.
67+
*
7268
* @param express the expression that will be copied.
7369
* @return the copied expression.
7470
*/
7571
public Expression shallowCopy(Expression express) {
76-
if(express instanceof MultipleExpression) {
72+
if (express instanceof MultipleExpression) {
7773
MultipleExpression multi = (MultipleExpression) express;
7874
List<Expression> list = new ArrayList<Expression>();
79-
for(int i=0; i<multi.size(); i++) {
75+
for (int i = 0; i < multi.size(); i++) {
8076
list.add(shallowCopy(multi.getChild(i)));
8177
}
82-
if(express instanceof MultiAndExpression) {
78+
if (express instanceof MultiAndExpression) {
8379
return new MultiAndExpression(list);
8480
}
8581
/* since there only two possibilities of the multiple expression,
@@ -88,33 +84,34 @@ public Expression shallowCopy(Expression express) {
8884
}
8985
return express;
9086
}
91-
87+
9288
/**
93-
* This helper method is used to change the multiple expression into
94-
* the binary form, respectively and return the root of the expression tree.
89+
* This helper method is used to change the multiple expression into the binary form,
90+
* respectively and return the root of the expression tree.
91+
*
9592
* @param isMultiOr variable tells whether the expression is or.
9693
* @param exp the expression that needs to be converted.
9794
* @return the root of the expression tree.
9895
*/
9996
public Expression changeBack(Boolean isMultiOr, Expression exp) {
100-
if(!(exp instanceof MultipleExpression)) {
97+
if (!(exp instanceof MultipleExpression)) {
10198
return exp;
10299
}
103100
MultipleExpression changed = (MultipleExpression) exp;
104101
Expression result = changed.getChild(0);
105-
for(int i=1; i<changed.size(); i++) {
102+
for (int i = 1; i < changed.size(); i++) {
106103
Expression left = result;
107104
Expression right = changed.getChild(i);
108-
if(isMultiOr) {
105+
if (isMultiOr) {
109106
result = new OrExpression(left, right);
110107
} else {
111108
result = new AndExpression(left, right);
112109
}
113110
}
114-
if(isMultiOr) {
111+
if (isMultiOr) {
115112
return new Parenthesis(result);
116113
}
117114
return result;
118115
}
119-
116+
120117
}

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,11 @@ public void visit(HexValue hexValue) {
166166

167167
@Override
168168
public void visit(NotExpression notExpr) {
169-
buffer.append(NOT);
169+
if (notExpr.isExclamationMark()) {
170+
buffer.append("! ");
171+
} else {
172+
buffer.append(NOT);
173+
}
170174
notExpr.getExpression().accept(this);
171175
}
172176

@@ -320,14 +324,9 @@ public void visit(OrExpression orExpression) {
320324

321325
@Override
322326
public void visit(Parenthesis parenthesis) {
323-
if (parenthesis.isNot()) {
324-
buffer.append(NOT);
325-
}
326-
327327
buffer.append("(");
328328
parenthesis.getExpression().accept(this);
329329
buffer.append(")");
330-
331330
}
332331

333332
@Override

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

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
140140
| <K_CROSS:"CROSS">
141141
| <K_CURRENT: "CURRENT">
142142
| <K_DATETIMELITERAL : ("DATE" | "TIME" | "TIMESTAMP") >
143+
| <K_DATE_LITERAL : ( "YEAR" | "MONTH" | "DAY" ) >
143144
| <K_DEFERRABLE : "DEFERRABLE">
144145
| <K_DELAYED : "DELAYED">
145146
| <K_DELETE:"DELETE">
@@ -1046,6 +1047,7 @@ String RelObjectNameWithoutValue() :
10461047
| tk=<K_UNSIGNED>
10471048
| tk=<K_TEMP> | tk=<K_TEMPORARY> | tk=<K_TYPE> | tk=<K_ISNULL>
10481049
| tk=<K_ZONE> | tk=<K_COLUMNS> | tk=<K_DESCRIBE> | tk=<K_FN> | tk=<K_PATH>
1050+
| tk=<K_DATE_LITERAL>
10491051
/* | tk=<K_PLACING> | tk=<K_BOTH> | tk=<K_LEADING> | tk=<K_TRAILING> */
10501052
)
10511053

@@ -2119,7 +2121,7 @@ Expression AndExpression() :
21192121
left=Condition()
21202122
|
21212123
[ <K_NOT> { not = true; } ]
2122-
"(" left=OrExpression() ")" {left = new Parenthesis(left); if (not) { ((Parenthesis)left).setNot(); not = false; } }
2124+
"(" left=OrExpression() ")" {left = new Parenthesis(left); if (not) { left = new NotExpression(left); not = false; } }
21232125
)
21242126
{ result = left; }
21252127

@@ -2130,7 +2132,7 @@ Expression AndExpression() :
21302132
right=Condition()
21312133
|
21322134
[ <K_NOT> { not = true; } ]
2133-
"(" right=OrExpression() ")" {right = new Parenthesis(right); if (not) { ((Parenthesis)right).setNot(); not = false; } }
2135+
"(" right=OrExpression() ")" {right = new Parenthesis(right); if (not) { right = new NotExpression(right); not = false; } }
21342136
)
21352137
{
21362138
result = new AndExpression(left, right);
@@ -2149,7 +2151,7 @@ Expression Condition():
21492151
boolean not = false;
21502152
}
21512153
{
2152-
[ <K_NOT> { not = true; }]
2154+
[ LOOKAHEAD(2) <K_NOT> { not = true; }]
21532155
(
21542156
LOOKAHEAD(SQLCondition()) result=SQLCondition()
21552157
| LOOKAHEAD(RegularCondition()) result=RegularCondition()
@@ -2661,8 +2663,11 @@ Expression PrimaryExpression() #PrimaryExpression:
26612663
Token sign = null;
26622664
String tmp = "";
26632665
ColDataType type = null;
2666+
boolean not = false;
2667+
boolean exclamationMarkNot = false;
26642668
}
26652669
{
2670+
[ <K_NOT> { not=true; } | "!" { not=true; exclamationMarkNot=true; } ]
26662671
[sign="+" | sign="-" | sign="~"]
26672672
(
26682673
<K_NULL> { retval = new NullValue(); }
@@ -2689,6 +2694,8 @@ Expression PrimaryExpression() #PrimaryExpression:
26892694

26902695
| LOOKAHEAD(Function()) retval=Function()
26912696

2697+
| LOOKAHEAD(2) retval = IntervalExpression()
2698+
26922699
| token=<S_DOUBLE> { retval = new DoubleValue(token.image); }
26932700

26942701
| token=<S_LONG> { retval = new LongValue(token.image); }
@@ -2702,14 +2709,12 @@ Expression PrimaryExpression() #PrimaryExpression:
27022709

27032710
| LOOKAHEAD(2) retval=DateTimeLiteralExpression()
27042711

2705-
| LOOKAHEAD(2) retval = IntervalExpression()
2706-
27072712
| retval = NextValExpression()
27082713

27092714
| retval=Column()
27102715

27112716
| LOOKAHEAD("(" retval=SubSelect() ")") "(" retval=SubSelect() ")"
2712-
2717+
27132718
| "(" retval=SimpleExpression() ")" {retval = new Parenthesis(retval); }
27142719

27152720
| token=<S_CHAR_LITERAL> { retval = new StringValue(token.image); linkAST(retval,jjtThis); }
@@ -2737,6 +2742,9 @@ Expression PrimaryExpression() #PrimaryExpression:
27372742
if (sign != null) {
27382743
retval = new SignedExpression(sign.image.charAt(0), retval);
27392744
}
2745+
if (not) {
2746+
retval = new NotExpression(retval, exclamationMarkNot);
2747+
}
27402748
return retval;
27412749
}
27422750
}
@@ -2817,14 +2825,22 @@ JsonExpression JsonExpression() : {
28172825
}
28182826

28192827
IntervalExpression IntervalExpression() : {
2820-
IntervalExpression interval = new IntervalExpression();
2828+
IntervalExpression interval;
28212829
Token token;
28222830
boolean signed = false;
28232831
}
28242832
{
2825-
<K_INTERVAL> ["-" {signed=true;}] (token=<S_LONG> | token=<S_DOUBLE> | token=<S_CHAR_LITERAL>)
2826-
{ interval.setParameter((signed?"-":"") + token.image); }
2827-
[ LOOKAHEAD(2) token = <S_IDENTIFIER> { interval.setIntervalType(token.image); } ]
2833+
(
2834+
{ interval = new IntervalExpression(); }
2835+
<K_INTERVAL> ["-" {signed=true;}] (token=<S_LONG> | token=<S_DOUBLE> | token=<S_CHAR_LITERAL> )
2836+
{ interval.setParameter((signed?"-":"") + token.image); }
2837+
[ LOOKAHEAD(2) (token = <S_IDENTIFIER> | token = <K_DATE_LITERAL>) { interval.setIntervalType(token.image); } ]
2838+
|
2839+
{ interval = new IntervalExpression(false); }
2840+
( token=<S_LONG> | token=<S_DOUBLE> | token=<S_CHAR_LITERAL> )
2841+
{ interval.setParameter((signed?"-":"") + token.image); }
2842+
token = <K_DATE_LITERAL> { interval.setIntervalType(token.image); }
2843+
)
28282844
{
28292845
return interval;
28302846
}

0 commit comments

Comments
 (0)