From 786c8fc65858ff6b94ee8295c80155f110013a4a Mon Sep 17 00:00:00 2001 From: Nico Date: Tue, 29 Jan 2019 12:11:07 +0100 Subject: [PATCH] added support for T-SQL left and right joins (*= and =*) --- .../expression/ExpressionVisitor.java | 6 ++++ .../expression/ExpressionVisitorAdapter.java | 11 +++++- .../operators/relational/TSQLLeftJoin.java | 36 +++++++++++++++++++ .../operators/relational/TSQLRightJoin.java | 36 +++++++++++++++++++ .../sf/jsqlparser/util/TablesNamesFinder.java | 12 +++++++ .../util/deparser/ExpressionDeParser.java | 12 +++++++ .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 2 ++ .../statement/select/SelectTest.java | 14 +++++++- 8 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLLeftJoin.java create mode 100644 src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLRightJoin.java diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java index b1e4e7463..d75fbb76c 100644 --- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java +++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java @@ -48,6 +48,8 @@ import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo; import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator; import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator; +import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin; +import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin; import net.sf.jsqlparser.expression.operators.relational.JsonOperator; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.SubSelect; @@ -180,4 +182,8 @@ public interface ExpressionVisitor { public void visit(NotExpression aThis); + public void visit(TSQLLeftJoin tsqlLeftJoin); + + public void visit(TSQLRightJoin tsqlRightJoin); + } diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java index c5730c9a1..8988ac43b 100644 --- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java @@ -24,7 +24,6 @@ import net.sf.jsqlparser.expression.operators.arithmetic.*; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.conditional.OrExpression; -import net.sf.jsqlparser.expression.operators.relational.JsonOperator; import net.sf.jsqlparser.expression.operators.relational.*; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.AllColumns; @@ -508,4 +507,14 @@ public void visit(DateTimeLiteralExpression literal) { } + @Override + public void visit(TSQLLeftJoin tsqlLeftJoin) { + visitBinaryExpression(tsqlLeftJoin); + } + + @Override + public void visit(TSQLRightJoin tsqlRightJoin) { + visitBinaryExpression(tsqlRightJoin); + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLLeftJoin.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLLeftJoin.java new file mode 100644 index 000000000..c8d9e2112 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLLeftJoin.java @@ -0,0 +1,36 @@ +/* + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2013 JSQLParser + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.expression.ExpressionVisitor; + +public class TSQLLeftJoin extends ComparisonOperator { + + public TSQLLeftJoin() { + super("*="); + } + + @Override + public void accept(ExpressionVisitor expressionVisitor) { + expressionVisitor.visit(this); + } +} diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLRightJoin.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLRightJoin.java new file mode 100644 index 000000000..0430a87d5 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLRightJoin.java @@ -0,0 +1,36 @@ +/* + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2013 JSQLParser + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.expression.ExpressionVisitor; + +public class TSQLRightJoin extends ComparisonOperator { + + public TSQLRightJoin() { + super("=*"); + } + + @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 f62880b6f..cedd973d8 100644 --- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java +++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java @@ -91,6 +91,8 @@ import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo; import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator; import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator; +import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin; +import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.Block; @@ -859,4 +861,14 @@ public void visit(DescribeStatement describe) { public void visit(ExplainStatement explain) { explain.getStatement().accept(this); } + + @Override + public void visit(TSQLLeftJoin tsqlLeftJoin) { + visitBinaryExpression(tsqlLeftJoin); + } + + @Override + public void visit(TSQLRightJoin tsqlRightJoin) { + visitBinaryExpression(tsqlRightJoin); + } } 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 9336bfa0d..4bd4498c7 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java @@ -94,6 +94,8 @@ import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator; import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator; import net.sf.jsqlparser.expression.operators.relational.SupportsOldOracleJoinSyntax; +import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin; +import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.OrderByElement; @@ -812,4 +814,14 @@ public void visit(DateTimeLiteralExpression literal) { buffer.append(literal.toString()); } + @Override + public void visit(TSQLLeftJoin tsqlLeftJoin) { + visitBinaryExpression(tsqlLeftJoin, " *= "); + } + + @Override + public void visit(TSQLRightJoin tsqlRightJoin) { + visitBinaryExpression(tsqlRightJoin, " =* "); + } + } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 3369d06fb..ef943c2e3 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -2182,6 +2182,8 @@ Expression RegularCondition() #RegularCondition: ">" { result = new GreaterThan(); } | "<" { result = new MinorThan(); } | "=" { result = new EqualsTo(); } + | "*=" { result = new TSQLLeftJoin(); } + | "=*" { result = new TSQLRightJoin(); } | token= { result = new GreaterThanEquals(token.image); } | token= { result = new MinorThanEquals(token.image); } | token= { result = new NotEqualsTo(token.image); } 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 0c670beee..3b003599c 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java @@ -1810,12 +1810,24 @@ public void testFunctionRight() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed(statement); } + @Test + public void testTSQLJoin() throws JSQLParserException { + String stmt = "SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a *= tabelle2.b"; + assertSqlCanBeParsedAndDeparsed(stmt); + } + + @Test + public void testTSQLJoin2() throws JSQLParserException { + String stmt = "SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a =* tabelle2.b"; + assertSqlCanBeParsedAndDeparsed(stmt); + } + @Test public void testOracleJoin() throws JSQLParserException { String stmt = "SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a = tabelle2.b(+)"; assertSqlCanBeParsedAndDeparsed(stmt); } - + @Test public void testOracleJoin2() throws JSQLParserException { String stmt = "SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a(+) = tabelle2.b";