Skip to content

Commit 8c057ab

Browse files
committed
fixes #164
1 parent e1193a6 commit 8c057ab

File tree

7 files changed

+109
-32
lines changed

7 files changed

+109
-32
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
package net.sf.jsqlparser.expression;
11+
12+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
13+
14+
public class CollateExpression extends ASTNodeAccessImpl implements Expression {
15+
16+
private Expression leftExpression;
17+
private String collate;
18+
19+
public CollateExpression(Expression leftExpression, String collate) {
20+
this.leftExpression = leftExpression;
21+
this.collate = collate;
22+
}
23+
24+
@Override
25+
public void accept(ExpressionVisitor expressionVisitor) {
26+
expressionVisitor.visit(this);
27+
}
28+
29+
public Expression getLeftExpression() {
30+
return leftExpression;
31+
}
32+
33+
public void setLeftExpression(Expression leftExpression) {
34+
this.leftExpression = leftExpression;
35+
}
36+
37+
public String getCollate() {
38+
return collate;
39+
}
40+
41+
public void setCollate(String collate) {
42+
this.collate = collate;
43+
}
44+
45+
@Override
46+
public String toString() {
47+
return leftExpression.toString() + " COLLATE " + collate;
48+
}
49+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,6 @@ public interface ExpressionVisitor {
170170

171171
public void visit(NextValExpression aThis);
172172

173+
public void visit(CollateExpression aThis);
174+
173175
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,8 @@ public void visit(DateTimeLiteralExpression literal) {
497497
public void visit(NextValExpression nextVal) {
498498
}
499499

500+
@Override
501+
public void visit(CollateExpression col) {
502+
col.getLeftExpression().accept(this);
503+
}
500504
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import net.sf.jsqlparser.expression.BinaryExpression;
1818
import net.sf.jsqlparser.expression.CaseExpression;
1919
import net.sf.jsqlparser.expression.CastExpression;
20+
import net.sf.jsqlparser.expression.CollateExpression;
2021
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
2122
import net.sf.jsqlparser.expression.DateValue;
2223
import net.sf.jsqlparser.expression.DoubleValue;
@@ -838,6 +839,11 @@ public void visit(ExplainStatement explain) {
838839
}
839840

840841
@Override
841-
public void visit(NextValExpression arg0) {
842+
public void visit(NextValExpression nextVal) {
843+
}
844+
845+
@Override
846+
public void visit(CollateExpression col) {
847+
col.getLeftExpression().accept(this);
842848
}
843849
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import net.sf.jsqlparser.expression.BinaryExpression;
1818
import net.sf.jsqlparser.expression.CaseExpression;
1919
import net.sf.jsqlparser.expression.CastExpression;
20+
import net.sf.jsqlparser.expression.CollateExpression;
2021
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
2122
import net.sf.jsqlparser.expression.DateValue;
2223
import net.sf.jsqlparser.expression.DoubleValue;
@@ -789,4 +790,9 @@ public void visit(NextValExpression nextVal) {
789790
buffer.append("NEXTVAL FOR ").append(nextVal.getName());
790791
}
791792

793+
@Override
794+
public void visit(CollateExpression col) {
795+
buffer.append(col.getLeftExpression().toString()).append(" COLLATE ").append(col.getCollate());
796+
}
797+
792798
}

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

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
129129
| <K_CHANGE:"CHANGE">
130130
| <K_CHECK:"CHECK">
131131
| <K_CHAR:"CHAR">
132+
| <K_COLLATE:"COLLATE">
132133
| <K_COLUMN:"COLUMN">
133134
| <K_COLUMNS:"COLUMNS">
134135
| <K_COMMIT:"COMMIT">
@@ -2660,63 +2661,67 @@ Expression PrimaryExpression() #PrimaryExpression:
26602661
ColDataType type = null;
26612662
}
26622663
{
2663-
[sign="+" | sign="-" | sign="~"]
2664-
(
2665-
<K_NULL> { retval = new NullValue(); }
2664+
[sign="+" | sign="-" | sign="~"]
2665+
(
2666+
<K_NULL> { retval = new NullValue(); }
2667+
2668+
| retval=CaseWhenExpression()
26662669

2667-
| retval=CaseWhenExpression()
2670+
| retval = SimpleJdbcParameter()
26682671

2669-
| retval = SimpleJdbcParameter()
2672+
| LOOKAHEAD(2) retval=JdbcNamedParameter()
26702673

2671-
| LOOKAHEAD(2) retval=JdbcNamedParameter()
2674+
| retval=UserVariable()
26722675

2673-
| retval=UserVariable()
2676+
| LOOKAHEAD(2) retval=NumericBind()
26742677

2675-
| LOOKAHEAD(2) retval=NumericBind()
2678+
| LOOKAHEAD(AnalyticExpression()) retval=AnalyticExpression()
26762679

2677-
| LOOKAHEAD(AnalyticExpression()) retval=AnalyticExpression()
2680+
| LOOKAHEAD(3) retval=ExtractExpression()
26782681

2679-
| LOOKAHEAD(3) retval=ExtractExpression()
2682+
| retval=MySQLGroupConcat()
26802683

2681-
| retval=MySQLGroupConcat()
2684+
| LOOKAHEAD(JsonExpression()) retval=JsonExpression()
26822685

2683-
| LOOKAHEAD(JsonExpression()) retval=JsonExpression()
2686+
| LOOKAHEAD(FunctionWithCondParams()) retval = FunctionWithCondParams()
26842687

2685-
| LOOKAHEAD(FunctionWithCondParams()) retval = FunctionWithCondParams()
2688+
| LOOKAHEAD(Function()) retval=Function()
26862689

2687-
| LOOKAHEAD(Function()) retval=Function()
2690+
| token=<S_DOUBLE> { retval = new DoubleValue(token.image); }
26882691

2689-
| token=<S_DOUBLE> { retval = new DoubleValue(token.image); }
2692+
| token=<S_LONG> { retval = new LongValue(token.image); }
26902693

2691-
| token=<S_LONG> { retval = new LongValue(token.image); }
2694+
| token=<S_HEX> { retval = new HexValue(token.image); }
26922695

2693-
| token=<S_HEX> { retval = new HexValue(token.image); }
2696+
| LOOKAHEAD(2) retval=CastExpression()
26942697

2695-
| LOOKAHEAD(2) retval=CastExpression()
2698+
// support timestamp expressions
2699+
| token=<K_TIME_KEY_EXPR> { retval = new TimeKeyExpression(token.image); }
26962700

2697-
// support timestamp expressions
2698-
| token=<K_TIME_KEY_EXPR> { retval = new TimeKeyExpression(token.image); }
2701+
| LOOKAHEAD(2) retval=DateTimeLiteralExpression()
26992702

2700-
| LOOKAHEAD(2) retval=DateTimeLiteralExpression()
2703+
| LOOKAHEAD(2) retval = IntervalExpression()
27012704

2702-
| LOOKAHEAD(2) retval = IntervalExpression()
2705+
| retval = NextValExpression()
27032706

2704-
| retval = NextValExpression()
2707+
| retval=Column()
27052708

2706-
| retval=Column()
2709+
| LOOKAHEAD("(" SimpleExpression() ")") "(" retval=SimpleExpression() ")" {retval = new Parenthesis(retval); }
27072710

2708-
| LOOKAHEAD("(" SimpleExpression() ")") "(" retval=SimpleExpression() ")" {retval = new Parenthesis(retval); }
2711+
| LOOKAHEAD(3) "(" retval=SubSelect() ")"
27092712

2710-
| LOOKAHEAD(3) "(" retval=SubSelect() ")"
2713+
| token=<S_CHAR_LITERAL> { retval = new StringValue(token.image); linkAST(retval,jjtThis); }
27112714

2712-
| token=<S_CHAR_LITERAL> { retval = new StringValue(token.image); linkAST(retval,jjtThis); }
2715+
| "{d" token=<S_CHAR_LITERAL> "}" { retval = new DateValue(token.image); }
27132716

2714-
| "{d" token=<S_CHAR_LITERAL> "}" { retval = new DateValue(token.image); }
2717+
| "{t" token=<S_CHAR_LITERAL> "}" { retval = new TimeValue(token.image); }
27152718

2716-
| "{t" token=<S_CHAR_LITERAL> "}" { retval = new TimeValue(token.image); }
2719+
| "{ts" token=<S_CHAR_LITERAL> "}" { retval = new TimestampValue(token.image); }
2720+
)
27172721

2718-
| "{ts" token=<S_CHAR_LITERAL> "}" { retval = new TimestampValue(token.image); }
2719-
)
2722+
[
2723+
<K_COLLATE> token=<S_IDENTIFIER> { retval = new CollateExpression(retval, token.image); }
2724+
]
27202725

27212726
( "::" type=ColDataType() {
27222727
castExpr = new CastExpression();

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3417,6 +3417,11 @@ public void testChainedunctions() throws JSQLParserException {
34173417
assertSqlCanBeParsedAndDeparsed("SELECT func('').func2('') AS foo FROM some_tables");
34183418
}
34193419

3420+
@Test
3421+
public void testCollateExprIssue164() throws JSQLParserException {
3422+
assertSqlCanBeParsedAndDeparsed("SELECT u.name COLLATE Latin1_General_CI_AS AS User FROM users u");
3423+
}
3424+
34203425
// @Test
34213426
// public void testIntervalExpression() throws JSQLParserException {
34223427
// assertSqlCanBeParsedAndDeparsed("SELECT count(emails.id) FROM emails WHERE (emails.date_entered + 30 DAYS) > CURRENT_DATE");

0 commit comments

Comments
 (0)