diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java index 60e86c0d4..8a0c52b1d 100644 --- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java @@ -399,7 +399,7 @@ protected void visitBinaryExpression(BinaryExpression expr) { @Override public void visit(JsonExpression jsonExpr) { - visit(jsonExpr.getColumn()); + jsonExpr.getExpression().accept(this); } @Override diff --git a/src/main/java/net/sf/jsqlparser/expression/JsonExpression.java b/src/main/java/net/sf/jsqlparser/expression/JsonExpression.java index 472e793a8..fb5a16931 100644 --- a/src/main/java/net/sf/jsqlparser/expression/JsonExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/JsonExpression.java @@ -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 idents = new ArrayList(); private List operators = new ArrayList(); @@ -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 getIdents() { @@ -46,7 +45,7 @@ public void setColumn(Column column) { // operators.add("->"); // } // } -// +// // public void addIdent(String ident) { // addIdent(ident, "->"); // } @@ -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; } } diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java index 66558f726..2ff6b0343 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java @@ -454,7 +454,7 @@ public void visit(RegExpMySQLOperator rexpr) { @Override public void visit(JsonExpression jsonExpr) { - validateOptionalExpression(jsonExpr.getColumn()); + validateOptionalExpression(jsonExpr.getExpression()); } @Override diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 14f211bc2..ab31845fc 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -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= | token=) {result.addIdent(token.image,"->");} | "->>" (token= | token=) {result.addIdent(token.image,"->>");} | "#>" token= {result.addIdent(token.image,"#>");} | "#>>" token= {result.addIdent(token.image,"#>>");} )+ { - result.setColumn(column); + result.setExpression(expr); return result; } } diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java index 1d245bb48..105182e9a 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java @@ -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);