Skip to content

Commit

Permalink
Add support for casts in json expressions (#1189)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomershay committed May 10, 2021
1 parent 2320b1b commit 86b613c
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ protected void visitBinaryExpression(BinaryExpression expr) {

@Override
public void visit(JsonExpression jsonExpr) {
visit(jsonExpr.getColumn());
jsonExpr.getExpression().accept(this);
}

@Override
Expand Down
19 changes: 9 additions & 10 deletions src/main/java/net/sf/jsqlparser/expression/JsonExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@
import java.util.List;

import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
import net.sf.jsqlparser.schema.Column;

public class JsonExpression extends ASTNodeAccessImpl implements Expression {

private Column column;
private Expression expr;

private List<String> idents = new ArrayList<String>();
private List<String> operators = new ArrayList<String>();
Expand All @@ -27,12 +26,12 @@ public void accept(ExpressionVisitor expressionVisitor) {
expressionVisitor.visit(this);
}

public Column getColumn() {
return column;
public Expression getExpression() {
return expr;
}

public void setColumn(Column column) {
this.column = column;
public void setExpression(Expression expr) {
this.expr = expr;
}

// public List<String> getIdents() {
Expand All @@ -46,7 +45,7 @@ public void setColumn(Column column) {
// operators.add("->");
// }
// }
//
//
// public void addIdent(String ident) {
// addIdent(ident, "->");
// }
Expand All @@ -58,15 +57,15 @@ public void addIdent(String ident, String operator) {
@Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append(column.toString());
b.append(expr.toString());
for (int i = 0; i < idents.size(); i++) {
b.append(operators.get(i)).append(idents.get(i));
}
return b.toString();
}

public JsonExpression withColumn(Column column) {
this.setColumn(column);
public JsonExpression withExpression(Expression expr) {
this.setExpression(expr);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ public void visit(RegExpMySQLOperator rexpr) {

@Override
public void visit(JsonExpression jsonExpr) {
validateOptionalExpression(jsonExpr.getColumn());
validateOptionalExpression(jsonExpr.getExpression());
}

@Override
Expand Down
16 changes: 13 additions & 3 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -3483,18 +3483,28 @@ ArrayConstructor ArrayConstructor(final boolean arrayKeyword) : {

JsonExpression JsonExpression() : {
JsonExpression result = new JsonExpression();
Column column;
Expression expr;
Token token;
ColDataType type = null;
CastExpression castExpr = null;
}
{
column=Column() (
expr=Column()
( "::" type=ColDataType() {
castExpr = new CastExpression();
castExpr.setUseCastKeyword(false);
castExpr.setLeftExpression(expr);
castExpr.setType(type);
expr=castExpr;
} )*
(
"->" (token=<S_CHAR_LITERAL> | token=<S_LONG>) {result.addIdent(token.image,"->");} |
"->>" (token=<S_CHAR_LITERAL> | token=<S_LONG>) {result.addIdent(token.image,"->>");} |
"#>" token=<S_CHAR_LITERAL> {result.addIdent(token.image,"#>");} |
"#>>" token=<S_CHAR_LITERAL> {result.addIdent(token.image,"#>>");}
)+
{
result.setColumn(column);
result.setExpression(expr);
return result;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2723,6 +2723,11 @@ public void testJsonExpression() throws JSQLParserException {
}
}

@Test
public void testJsonExpressionWithCastExpression() throws JSQLParserException {
assertSqlCanBeParsedAndDeparsed("SELECT id FROM tbl WHERE p.company::json->'info'->>'country' = 'test'");
}

@Test
public void testJsonExpressionWithIntegerParameterIssue909() throws JSQLParserException {
assertSqlCanBeParsedAndDeparsed("select uc.\"id\", u.nickname, u.avatar, b.title, uc.images, uc.created_at as createdAt from library.ugc_comment uc INNER JOIN library.book b on (uc.books_id ->> 0)::INTEGER = b.\"id\" INNER JOIN library.users u ON uc.user_id = u.user_id where uc.id = 1", true);
Expand Down

0 comments on commit 86b613c

Please sign in to comment.