diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/Between.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/Between.java index 8998863ef2..ff24e0eba3 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/Between.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/Between.java @@ -16,7 +16,7 @@ /** * A "BETWEEN" expr1 expr2 statement */ -public class Between extends ASTNodeAccessImpl implements Expression { +public class Between extends ASTNodeAccessImpl implements Expression, SupportsOldOracleJoinSyntax { private Expression leftExpression; private boolean not = false; @@ -82,7 +82,8 @@ public T accept(ExpressionVisitor expressionVisitor, S context) { @Override public String toString() { - return leftExpression + " " + (not ? "NOT " : "") + "BETWEEN " + return (oraclePriorPosition == ORACLE_PRIOR_START ? "PRIOR " : "") + leftExpression + " " + + (not ? "NOT " : "") + "BETWEEN " + (usingSymmetric ? "SYMMETRIC " : "") + (usingAsymmetric ? "ASYMMETRIC " : "") + betweenExpressionStart + " AND " @@ -120,4 +121,39 @@ public E getBetweenExpressionStart(Class type) { public E getLeftExpression(Class type) { return type.cast(getLeftExpression()); } + + private int oraclePriorPosition = NO_ORACLE_PRIOR; + + @Override + public int getOldOracleJoinSyntax() { + return NO_ORACLE_JOIN; + } + + @Override + public void setOldOracleJoinSyntax(int oldOracleJoinSyntax) { + throw new IllegalArgumentException( + "oracle join operator (+) is not supported on this condition"); + } + + @Override + public Between withOldOracleJoinSyntax(int oldOracleJoinSyntax) { + setOldOracleJoinSyntax(oldOracleJoinSyntax); + return this; + } + + @Override + public int getOraclePriorPosition() { + return oraclePriorPosition; + } + + @Override + public void setOraclePriorPosition(int oraclePriorPosition) { + this.oraclePriorPosition = oraclePriorPosition; + } + + public Between withOraclePriorPosition(int oraclePriorPosition) { + setOraclePriorPosition(oraclePriorPosition); + return this; + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/InExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/InExpression.java index 743d8a0aa7..c920c2b872 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/InExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/InExpression.java @@ -22,6 +22,8 @@ public class InExpression extends ASTNodeAccessImpl private Expression rightExpression; private int oldOracleJoinSyntax = NO_ORACLE_JOIN; + private int oraclePriorPosition = NO_ORACLE_PRIOR; + public InExpression() {} public InExpression(Expression leftExpression, Expression rightExpression) { @@ -94,6 +96,9 @@ private String getLeftExpressionString() { @Override public String toString() { StringBuilder statementBuilder = new StringBuilder(); + if (oraclePriorPosition == ORACLE_PRIOR_START) { + statementBuilder.append("PRIOR "); + } statementBuilder.append(getLeftExpressionString()); statementBuilder.append(" "); @@ -110,14 +115,12 @@ public String toString() { @Override public int getOraclePriorPosition() { - return SupportsOldOracleJoinSyntax.NO_ORACLE_PRIOR; + return oraclePriorPosition; } @Override public void setOraclePriorPosition(int priorPosition) { - if (priorPosition != SupportsOldOracleJoinSyntax.NO_ORACLE_PRIOR) { - throw new IllegalArgumentException("unexpected prior for oracle found"); - } + this.oraclePriorPosition = priorPosition; } public InExpression withRightExpression(Expression rightExpression) { diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsBooleanExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsBooleanExpression.java index 3c83365336..6cf101bd9a 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsBooleanExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsBooleanExpression.java @@ -13,7 +13,8 @@ import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.parser.ASTNodeAccessImpl; -public class IsBooleanExpression extends ASTNodeAccessImpl implements Expression { +public class IsBooleanExpression extends ASTNodeAccessImpl + implements Expression, SupportsOldOracleJoinSyntax { private Expression leftExpression; private boolean not = false; @@ -50,10 +51,11 @@ public T accept(ExpressionVisitor expressionVisitor, S context) { @Override public String toString() { + String prior = oraclePriorPosition == ORACLE_PRIOR_START ? "PRIOR " : ""; if (isTrue()) { - return leftExpression + " IS" + (not ? " NOT" : "") + " TRUE"; + return prior + leftExpression + " IS" + (not ? " NOT" : "") + " TRUE"; } else { - return leftExpression + " IS" + (not ? " NOT" : "") + " FALSE"; + return prior + leftExpression + " IS" + (not ? " NOT" : "") + " FALSE"; } } @@ -75,4 +77,39 @@ public IsBooleanExpression withNot(boolean not) { public E getLeftExpression(Class type) { return type.cast(getLeftExpression()); } + + private int oraclePriorPosition = NO_ORACLE_PRIOR; + + @Override + public int getOldOracleJoinSyntax() { + return NO_ORACLE_JOIN; + } + + @Override + public void setOldOracleJoinSyntax(int oldOracleJoinSyntax) { + throw new IllegalArgumentException( + "oracle join operator (+) is not supported on this condition"); + } + + @Override + public IsBooleanExpression withOldOracleJoinSyntax(int oldOracleJoinSyntax) { + setOldOracleJoinSyntax(oldOracleJoinSyntax); + return this; + } + + @Override + public int getOraclePriorPosition() { + return oraclePriorPosition; + } + + @Override + public void setOraclePriorPosition(int oraclePriorPosition) { + this.oraclePriorPosition = oraclePriorPosition; + } + + public IsBooleanExpression withOraclePriorPosition(int oraclePriorPosition) { + setOraclePriorPosition(oraclePriorPosition); + return this; + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsDistinctExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsDistinctExpression.java index 60add6b6ed..12bc3027cd 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsDistinctExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsDistinctExpression.java @@ -12,7 +12,7 @@ import net.sf.jsqlparser.expression.BinaryExpression; import net.sf.jsqlparser.expression.ExpressionVisitor; -public class IsDistinctExpression extends BinaryExpression { +public class IsDistinctExpression extends BinaryExpression implements SupportsOldOracleJoinSyntax { private boolean not = false; @@ -36,7 +36,43 @@ public String getStringExpression() { @Override public String toString() { - String retval = getLeftExpression() + getStringExpression() + getRightExpression(); + String retval = (oraclePriorPosition == ORACLE_PRIOR_START ? "PRIOR " : "") + + getLeftExpression() + getStringExpression() + getRightExpression(); return retval; } + + private int oraclePriorPosition = NO_ORACLE_PRIOR; + + @Override + public int getOldOracleJoinSyntax() { + return NO_ORACLE_JOIN; + } + + @Override + public void setOldOracleJoinSyntax(int oldOracleJoinSyntax) { + throw new IllegalArgumentException( + "oracle join operator (+) is not supported on this condition"); + } + + @Override + public IsDistinctExpression withOldOracleJoinSyntax(int oldOracleJoinSyntax) { + setOldOracleJoinSyntax(oldOracleJoinSyntax); + return this; + } + + @Override + public int getOraclePriorPosition() { + return oraclePriorPosition; + } + + @Override + public void setOraclePriorPosition(int oraclePriorPosition) { + this.oraclePriorPosition = oraclePriorPosition; + } + + public IsDistinctExpression withOraclePriorPosition(int oraclePriorPosition) { + setOraclePriorPosition(oraclePriorPosition); + return this; + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsNullExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsNullExpression.java index 393f9f1944..f044c436ae 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsNullExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsNullExpression.java @@ -14,7 +14,8 @@ import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import net.sf.jsqlparser.schema.Column; -public class IsNullExpression extends ASTNodeAccessImpl implements Expression { +public class IsNullExpression extends ASTNodeAccessImpl + implements Expression, SupportsOldOracleJoinSyntax { private Expression leftExpression; private boolean not = false; @@ -72,12 +73,13 @@ public T accept(ExpressionVisitor expressionVisitor, S context) { @Override public String toString() { + String prior = oraclePriorPosition == ORACLE_PRIOR_START ? "PRIOR " : ""; if (useNotNull) { - return leftExpression + " NOTNULL"; + return prior + leftExpression + " NOTNULL"; } else if (useIsNull) { - return leftExpression + (not ? " NOT" : "") + " ISNULL"; + return prior + leftExpression + (not ? " NOT" : "") + " ISNULL"; } else { - return leftExpression + " IS " + (not ? "NOT " : "") + "NULL"; + return prior + leftExpression + " IS " + (not ? "NOT " : "") + "NULL"; } } @@ -99,4 +101,39 @@ public IsNullExpression withNot(boolean not) { public E getLeftExpression(Class type) { return type.cast(getLeftExpression()); } + + private int oraclePriorPosition = NO_ORACLE_PRIOR; + + @Override + public int getOldOracleJoinSyntax() { + return NO_ORACLE_JOIN; + } + + @Override + public void setOldOracleJoinSyntax(int oldOracleJoinSyntax) { + throw new IllegalArgumentException( + "oracle join operator (+) is not supported on this condition"); + } + + @Override + public IsNullExpression withOldOracleJoinSyntax(int oldOracleJoinSyntax) { + setOldOracleJoinSyntax(oldOracleJoinSyntax); + return this; + } + + @Override + public int getOraclePriorPosition() { + return oraclePriorPosition; + } + + @Override + public void setOraclePriorPosition(int oraclePriorPosition) { + this.oraclePriorPosition = oraclePriorPosition; + } + + public IsNullExpression withOraclePriorPosition(int oraclePriorPosition) { + setOraclePriorPosition(oraclePriorPosition); + return this; + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsUnknownExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsUnknownExpression.java index 506d6e2466..06abbbcb55 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsUnknownExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/IsUnknownExpression.java @@ -13,7 +13,8 @@ import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.parser.ASTNodeAccessImpl; -public class IsUnknownExpression extends ASTNodeAccessImpl implements Expression { +public class IsUnknownExpression extends ASTNodeAccessImpl + implements Expression, SupportsOldOracleJoinSyntax { private Expression leftExpression; private boolean isNot = false; @@ -41,7 +42,8 @@ public T accept(ExpressionVisitor expressionVisitor, S context) { @Override public String toString() { - return leftExpression + " IS" + (isNot ? " NOT" : "") + " UNKNOWN"; + return (oraclePriorPosition == ORACLE_PRIOR_START ? "PRIOR " : "") + leftExpression + " IS" + + (isNot ? " NOT" : "") + " UNKNOWN"; } public IsUnknownExpression withLeftExpression(Expression leftExpression) { @@ -57,4 +59,39 @@ public IsUnknownExpression withNot(boolean isNot) { public E getLeftExpression(Class type) { return type.cast(getLeftExpression()); } + + private int oraclePriorPosition = NO_ORACLE_PRIOR; + + @Override + public int getOldOracleJoinSyntax() { + return NO_ORACLE_JOIN; + } + + @Override + public void setOldOracleJoinSyntax(int oldOracleJoinSyntax) { + throw new IllegalArgumentException( + "oracle join operator (+) is not supported on this condition"); + } + + @Override + public IsUnknownExpression withOldOracleJoinSyntax(int oldOracleJoinSyntax) { + setOldOracleJoinSyntax(oldOracleJoinSyntax); + return this; + } + + @Override + public int getOraclePriorPosition() { + return oraclePriorPosition; + } + + @Override + public void setOraclePriorPosition(int oraclePriorPosition) { + this.oraclePriorPosition = oraclePriorPosition; + } + + public IsUnknownExpression withOraclePriorPosition(int oraclePriorPosition) { + setOraclePriorPosition(oraclePriorPosition); + return this; + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/LikeExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/LikeExpression.java index 770db3de39..4d9201e5e4 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/LikeExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/LikeExpression.java @@ -14,7 +14,7 @@ import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitor; -public class LikeExpression extends BinaryExpression { +public class LikeExpression extends BinaryExpression implements SupportsOldOracleJoinSyntax { private boolean not = false; private boolean useBinary = false; private Expression escapeExpression = null; @@ -50,7 +50,8 @@ public String getStringExpression() { @Override public String toString() { - String retval = getLeftExpression() + " " + (not ? "NOT " : "") + String retval = (oraclePriorPosition == ORACLE_PRIOR_START ? "PRIOR " : "") + + getLeftExpression() + " " + (not ? "NOT " : "") + (likeKeyWord == KeyWord.SIMILAR_TO ? "SIMILAR TO" : likeKeyWord) + " " + (useBinary ? "BINARY " : "") + getRightExpression(); if (escapeExpression != null) { @@ -125,4 +126,39 @@ public static KeyWord from(String keyword) { keyword.toUpperCase(Locale.ROOT).replaceAll("\\s+", "_")); } } + + private int oraclePriorPosition = NO_ORACLE_PRIOR; + + @Override + public int getOldOracleJoinSyntax() { + return NO_ORACLE_JOIN; + } + + @Override + public void setOldOracleJoinSyntax(int oldOracleJoinSyntax) { + throw new IllegalArgumentException( + "oracle join operator (+) is not supported on this condition"); + } + + @Override + public LikeExpression withOldOracleJoinSyntax(int oldOracleJoinSyntax) { + setOldOracleJoinSyntax(oldOracleJoinSyntax); + return this; + } + + @Override + public int getOraclePriorPosition() { + return oraclePriorPosition; + } + + @Override + public void setOraclePriorPosition(int oraclePriorPosition) { + this.oraclePriorPosition = oraclePriorPosition; + } + + public LikeExpression withOraclePriorPosition(int oraclePriorPosition) { + setOraclePriorPosition(oraclePriorPosition); + return this; + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/MemberOfExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/MemberOfExpression.java index d602e62788..87a54dd072 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/MemberOfExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/MemberOfExpression.java @@ -13,7 +13,8 @@ import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.parser.ASTNodeAccessImpl; -public class MemberOfExpression extends ASTNodeAccessImpl implements Expression { +public class MemberOfExpression extends ASTNodeAccessImpl + implements Expression, SupportsOldOracleJoinSyntax { Expression leftExpression; Expression rightExpression; @@ -53,11 +54,47 @@ public MemberOfExpression setNot(boolean not) { @Override public String toString() { - return leftExpression + " MEMBER OF " + rightExpression; + return (oraclePriorPosition == ORACLE_PRIOR_START ? "PRIOR " : "") + leftExpression + + " MEMBER OF " + rightExpression; } @Override public T accept(ExpressionVisitor expressionVisitor, S context) { return expressionVisitor.visit(this, context); } + + private int oraclePriorPosition = NO_ORACLE_PRIOR; + + @Override + public int getOldOracleJoinSyntax() { + return NO_ORACLE_JOIN; + } + + @Override + public void setOldOracleJoinSyntax(int oldOracleJoinSyntax) { + throw new IllegalArgumentException( + "oracle join operator (+) is not supported on this condition"); + } + + @Override + public MemberOfExpression withOldOracleJoinSyntax(int oldOracleJoinSyntax) { + setOldOracleJoinSyntax(oldOracleJoinSyntax); + return this; + } + + @Override + public int getOraclePriorPosition() { + return oraclePriorPosition; + } + + @Override + public void setOraclePriorPosition(int oraclePriorPosition) { + this.oraclePriorPosition = oraclePriorPosition; + } + + public MemberOfExpression withOraclePriorPosition(int oraclePriorPosition) { + setOraclePriorPosition(oraclePriorPosition); + return this; + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/SimilarToExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/SimilarToExpression.java index 0818d75c0a..fbb50f25d5 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/SimilarToExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/SimilarToExpression.java @@ -13,7 +13,7 @@ import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitor; -public class SimilarToExpression extends BinaryExpression { +public class SimilarToExpression extends BinaryExpression implements SupportsOldOracleJoinSyntax { private boolean not = false; private String escape = null; @@ -38,7 +38,8 @@ public String getStringExpression() { @Override public String toString() { - String retval = getLeftExpression() + " " + (not ? "NOT " : "") + getStringExpression() + String retval = (oraclePriorPosition == ORACLE_PRIOR_START ? "PRIOR " : "") + + getLeftExpression() + " " + (not ? "NOT " : "") + getStringExpression() + " " + getRightExpression(); if (escape != null) { retval += " ESCAPE " + "'" + escape + "'"; @@ -74,4 +75,39 @@ public SimilarToExpression withLeftExpression(Expression arg0) { public SimilarToExpression withRightExpression(Expression arg0) { return (SimilarToExpression) super.withRightExpression(arg0); } + + private int oraclePriorPosition = NO_ORACLE_PRIOR; + + @Override + public int getOldOracleJoinSyntax() { + return NO_ORACLE_JOIN; + } + + @Override + public void setOldOracleJoinSyntax(int oldOracleJoinSyntax) { + throw new IllegalArgumentException( + "oracle join operator (+) is not supported on this condition"); + } + + @Override + public SimilarToExpression withOldOracleJoinSyntax(int oldOracleJoinSyntax) { + setOldOracleJoinSyntax(oldOracleJoinSyntax); + return this; + } + + @Override + public int getOraclePriorPosition() { + return oraclePriorPosition; + } + + @Override + public void setOraclePriorPosition(int oraclePriorPosition) { + this.oraclePriorPosition = oraclePriorPosition; + } + + public SimilarToExpression withOraclePriorPosition(int oraclePriorPosition) { + setOraclePriorPosition(oraclePriorPosition); + return this; + } + } 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 4a17272cc5..38fde71bb8 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java @@ -183,6 +183,9 @@ public StringBuilder visit(AndExpression andExpression, S context) { @Override public StringBuilder visit(Between between, S context) { + if (between.getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } between.getLeftExpression().accept(this, context); if (between.isNot()) { builder.append(" NOT"); @@ -268,11 +271,17 @@ public StringBuilder deparse( // if (expression.isNot()) { // buffer.append(NOT); // } + if (expression.getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } expression.getLeftExpression().accept(this, context); if (expression.getOldOracleJoinSyntax() == EqualsTo.ORACLE_JOIN_RIGHT) { builder.append("(+)"); } builder.append(operator); + if (expression.getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_END) { + builder.append("PRIOR "); + } expression.getRightExpression().accept(this, context); if (expression.getOldOracleJoinSyntax() == EqualsTo.ORACLE_JOIN_LEFT) { builder.append("(+)"); @@ -345,6 +354,10 @@ public void visit(BitwiseLeftShift expr) { @Override public StringBuilder visit(InExpression inExpression, S context) { + if (inExpression + .getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } inExpression.getLeftExpression().accept(this, context); if (inExpression .getOldOracleJoinSyntax() == SupportsOldOracleJoinSyntax.ORACLE_JOIN_RIGHT) { @@ -407,6 +420,10 @@ public StringBuilder visit(SignedExpression signedExpression, S context) { @Override public StringBuilder visit(IsNullExpression isNullExpression, S context) { + if (isNullExpression + .getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } isNullExpression.getLeftExpression().accept(this, context); if (isNullExpression.isUseNotNull()) { builder.append(" NOTNULL"); @@ -428,6 +445,10 @@ public StringBuilder visit(IsNullExpression isNullExpression, S context) { @Override public StringBuilder visit(IsBooleanExpression isBooleanExpression, S context) { + if (isBooleanExpression + .getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } isBooleanExpression.getLeftExpression().accept(this, context); if (isBooleanExpression.isTrue()) { if (isBooleanExpression.isNot()) { @@ -447,6 +468,10 @@ public StringBuilder visit(IsBooleanExpression isBooleanExpression, S contex @Override public StringBuilder visit(IsUnknownExpression isUnknownExpression, S context) { + if (isUnknownExpression + .getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } isUnknownExpression.getLeftExpression().accept(this, context); if (isUnknownExpression.isNot()) { builder.append(" IS NOT UNKNOWN"); @@ -472,6 +497,10 @@ public StringBuilder visit(LikeExpression likeExpression, S context) { ? " SIMILAR TO" : likeExpression.getLikeKeyWord().toString(); + if (likeExpression + .getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } likeExpression.getLeftExpression().accept(this, context); builder.append(" "); if (likeExpression.isNot()) { @@ -504,6 +533,10 @@ public StringBuilder visit(ExistsExpression existsExpression, S context) { @Override public StringBuilder visit(MemberOfExpression memberOfExpression, S context) { + if (memberOfExpression + .getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } memberOfExpression.getLeftExpression().accept(this, context); if (memberOfExpression.isNot()) { builder.append(" NOT MEMBER OF "); @@ -1505,7 +1538,12 @@ public StringBuilder visit(CollateExpression col, S context) { @Override public StringBuilder visit(SimilarToExpression expr, S context) { - deparse(expr, (expr.isNot() ? " NOT" : "") + " SIMILAR TO ", null); + if (expr.getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } + expr.getLeftExpression().accept(this, context); + builder.append(expr.isNot() ? " NOT SIMILAR TO " : " SIMILAR TO "); + expr.getRightExpression().accept(this, context); return builder; } @@ -1756,6 +1794,10 @@ public StringBuilder visit(AllValue allValue, S context) { @Override public StringBuilder visit(IsDistinctExpression isDistinctExpression, S context) { + if (isDistinctExpression + .getOraclePriorPosition() == SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START) { + builder.append("PRIOR "); + } builder.append(isDistinctExpression.getLeftExpression()) .append(isDistinctExpression.getStringExpression()) .append(isDistinctExpression.getRightExpression()); diff --git a/src/test/java/net/sf/jsqlparser/expression/operators/relational/OraclePriorPositionTest.java b/src/test/java/net/sf/jsqlparser/expression/operators/relational/OraclePriorPositionTest.java new file mode 100644 index 0000000000..643342b71b --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/expression/operators/relational/OraclePriorPositionTest.java @@ -0,0 +1,211 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2026 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.test.TestUtils; +import org.junit.jupiter.api.Test; + +public class OraclePriorPositionTest { + + private static Expression whereOf(String sqlStr) throws JSQLParserException { + PlainSelect select = + (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); + return select.getWhere(); + } + + @Test + public void testPriorBetween() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a BETWEEN 1 AND 2"); + Between between = (Between) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + between.getOraclePriorPosition()); + } + + @Test + public void testPriorLike() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a LIKE 'x%'"); + LikeExpression like = (LikeExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + like.getOraclePriorPosition()); + } + + @Test + public void testPriorNotLike() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a NOT LIKE 'x%'"); + LikeExpression like = (LikeExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + like.getOraclePriorPosition()); + } + + @Test + public void testPriorSimilarTo() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a SIMILAR TO 'x'"); + LikeExpression similarTo = (LikeExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + similarTo.getOraclePriorPosition()); + } + + @Test + public void testPriorSimilarToOnSeparateTokens() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a SIMILAR\nTO 'x'"); + SimilarToExpression similarTo = (SimilarToExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + similarTo.getOraclePriorPosition()); + } + + @Test + public void testPriorIsNull() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a IS NULL"); + IsNullExpression isNull = (IsNullExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + isNull.getOraclePriorPosition()); + } + + @Test + public void testPriorIsNotNull() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a IS NOT NULL"); + IsNullExpression isNull = (IsNullExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + isNull.getOraclePriorPosition()); + } + + @Test + public void testPriorIsTrue() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a IS TRUE"); + IsBooleanExpression isBoolean = (IsBooleanExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + isBoolean.getOraclePriorPosition()); + } + + @Test + public void testPriorIsUnknown() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a IS UNKNOWN"); + IsUnknownExpression isUnknown = (IsUnknownExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + isUnknown.getOraclePriorPosition()); + } + + @Test + public void testPriorIsDistinctFrom() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a IS DISTINCT FROM b"); + IsDistinctExpression isDistinct = (IsDistinctExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + isDistinct.getOraclePriorPosition()); + } + + @Test + public void testPriorMemberOf() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a MEMBER OF (1)"); + MemberOfExpression memberOf = (MemberOfExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + memberOf.getOraclePriorPosition()); + } + + @Test + public void testPriorIn() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a IN (1, 2)"); + InExpression in = (InExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + in.getOraclePriorPosition()); + } + + @Test + public void testPriorNotIn() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE PRIOR a NOT IN (1, 2)", + true); + } + + @Test + public void testPriorOnComparisonStartIsDeparsed() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE PRIOR a = b", true); + } + + @Test + public void testPriorOnComparisonEndIsDeparsed() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE a = PRIOR b", true); + } + + @Test + public void testPriorIsNullShorthand() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a ISNULL"); + IsNullExpression isNull = (IsNullExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + isNull.getOraclePriorPosition()); + } + + @Test + public void testPriorNotNullShorthand() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE PRIOR a NOTNULL", true); + } + + @Test + public void testPriorIsFalse() throws JSQLParserException { + Expression where = whereOf("SELECT * FROM t WHERE PRIOR a IS FALSE"); + IsBooleanExpression isBoolean = (IsBooleanExpression) where; + assertEquals(SupportsOldOracleJoinSyntax.ORACLE_PRIOR_START, + isBoolean.getOraclePriorPosition()); + } + + @Test + public void testPriorIsNotUnknown() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE PRIOR a IS NOT UNKNOWN", + true); + } + + @Test + public void testPriorNotSimilarTo() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed( + "SELECT * FROM t WHERE PRIOR a NOT SIMILAR TO 'x'", + true); + } + + @Test + public void testPriorInJoinOnClause() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed( + "SELECT * FROM t JOIN t2 ON PRIOR t.c = t2.c", true); + } + + @Test + public void testPriorBetweenEndOperandStaysIntact() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE a BETWEEN 1 AND PRIOR 2", + true); + } + + @Test + public void testPlainConditionsWithoutPriorAreUnchanged() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE a = b", true); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE a BETWEEN 1 AND 2", true); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE a LIKE 'x%'", true); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM t WHERE a IS NULL", true); + } + + @Test + public void testNotPriorBetween() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed( + "SELECT * FROM t WHERE NOT PRIOR a BETWEEN 1 AND 2", true); + } + + @Test + public void testPriorOnSeveralConditions() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed( + "SELECT * FROM t WHERE PRIOR a = b AND PRIOR c BETWEEN 1 AND 2", true); + } + + @Test + public void testPriorCombinedWithOracleJoinOnBetween() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed( + "SELECT * FROM t1, t2 WHERE PRIOR t2.c(+) BETWEEN 1 AND 2", true); + } +}