From 91a73e67cb3cacc5564c8ddbfe1064c60de7fe33 Mon Sep 17 00:00:00 2001 From: Thomas Powell Date: Mon, 28 Mar 2022 14:50:38 +0100 Subject: [PATCH 1/2] Add support for geometry distance operators in PostGIS. --- .../expression/ExpressionVisitor.java | 2 ++ .../expression/ExpressionVisitorAdapter.java | 7 ++++++- .../relational/GeometryDistance.java | 19 +++++++++++++++++++ .../sf/jsqlparser/util/TablesNamesFinder.java | 5 +++++ .../util/deparser/ExpressionDeParser.java | 5 +++++ .../validator/ExpressionValidator.java | 4 ++++ .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 2 ++ .../statement/select/SelectTest.java | 6 ++++++ 8 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/sf/jsqlparser/expression/operators/relational/GeometryDistance.java diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java index 05fcd6940..ed4460e1c 100644 --- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java +++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java @@ -188,4 +188,6 @@ public interface ExpressionVisitor { void visit(AllValue allValue); void visit(IsDistinctExpression isDistinctExpression); + + void visit(GeometryDistance geometryDistance); } diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java index 281906839..aab345edd 100644 --- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java @@ -634,7 +634,12 @@ public void visit(ConnectByRootOperator connectByRootOperator) { public void visit(OracleNamedFunctionParameter oracleNamedFunctionParameter) { oracleNamedFunctionParameter.getExpression().accept(this); } - + + @Override + public void visit(GeometryDistance geometryDistance) { + visitBinaryExpression(geometryDistance); + } + public void visit(ColumnDefinition columnDefinition) { columnDefinition.accept(this); } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/GeometryDistance.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/GeometryDistance.java new file mode 100644 index 000000000..401fe4e61 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/GeometryDistance.java @@ -0,0 +1,19 @@ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.expression.ExpressionVisitor; + +public class GeometryDistance extends ComparisonOperator { + + public GeometryDistance() { + super("<->"); + } + + public GeometryDistance(String operator) { + super(operator); + } + + @Override + public void accept(ExpressionVisitor expressionVisitor) { + expressionVisitor.visit(this); + } +} diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java index c256c308b..32b316b58 100644 --- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java +++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java @@ -1031,4 +1031,9 @@ public void visit(PurgeStatement purgeStatement) { public void visit(AlterSystemStatement alterSystemStatement) { // no tables involved in this statement } + + @Override + public void visit(GeometryDistance geometryDistance) { + visitBinaryExpression(geometryDistance); + } } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java index 64aa277bc..b4056fe03 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java @@ -996,4 +996,9 @@ public void visit(IsDistinctExpression isDistinctExpression) { isDistinctExpression.getStringExpression() + isDistinctExpression.getRightExpression()); } + + @Override + public void visit(GeometryDistance geometryDistance) { + visitOldOracleJoinBinaryExpression(geometryDistance, " <-> "); + } } 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 43234dd8b..21a1b2c68 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 @@ -586,4 +586,8 @@ public void visit(IsDistinctExpression isDistinctExpression) { isDistinctExpression.getRightExpression().accept(this); } + @Override + public void visit(GeometryDistance geometryDistance) { + visitOldOracleJoinBinaryExpression(geometryDistance, " <-> "); + } } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 07f29df88..95827b83b 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -3110,6 +3110,8 @@ Expression RegularCondition() #RegularCondition: | { result = new JsonOperator("||"); } | "-" { result = new JsonOperator("-"); } | "-#" { result = new JsonOperator("-#"); } + | <-> { result = new GeometryDistance("<->"); } + | <#> { result = new GeometryDistance("<#>"); } ) ( LOOKAHEAD(2) rightExpression=ComparisonItem() { oraclePrior = EqualsTo.ORACLE_PRIOR_END; } 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 e4d8064dc..7ca40c11b 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java @@ -2803,6 +2803,12 @@ public void testNotEqualsTo() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT * FROM foo WHERE a <> b"); } + @Test + public void testGeometryDistance() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT * FROM foo ORDER BY a <-> b"); + assertSqlCanBeParsedAndDeparsed("SELECT * FROM foo ORDER BY a <#> b"); + } + @Test public void testJsonExpression() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT data->'images'->'thumbnail'->'url' AS thumb FROM instagram"); From 1be2df8a9edb7fe6497a81f4d0436136d272765b Mon Sep 17 00:00:00 2001 From: Thomas Powell Date: Mon, 28 Mar 2022 14:52:14 +0100 Subject: [PATCH 2/2] Fix missing imports. --- .../java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java | 1 + .../util/validation/validator/ExpressionValidator.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java index b4056fe03..93d4d954d 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java @@ -34,6 +34,7 @@ import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.FullTextSearch; +import net.sf.jsqlparser.expression.operators.relational.GeometryDistance; import net.sf.jsqlparser.expression.operators.relational.GreaterThan; import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals; import net.sf.jsqlparser.expression.operators.relational.InExpression; 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 21a1b2c68..d517c4b00 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 @@ -30,6 +30,7 @@ import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.FullTextSearch; +import net.sf.jsqlparser.expression.operators.relational.GeometryDistance; import net.sf.jsqlparser.expression.operators.relational.GreaterThan; import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals; import net.sf.jsqlparser.expression.operators.relational.InExpression;