提交 da10d540 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add Expression.getSubexpression() and getSubexpressionCount()

上级 3fc4e02e
...@@ -12,19 +12,14 @@ import java.util.List; ...@@ -12,19 +12,14 @@ import java.util.List;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.engine.Mode.ModeEnum; import org.h2.engine.Mode.ModeEnum;
import org.h2.engine.Session;
import org.h2.expression.Alias; import org.h2.expression.Alias;
import org.h2.expression.Comparison;
import org.h2.expression.ConditionAndOr;
import org.h2.expression.ConditionNot;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn; import org.h2.expression.ExpressionColumn;
import org.h2.expression.ExpressionVisitor; import org.h2.expression.ExpressionVisitor;
import org.h2.expression.Function; import org.h2.expression.Function;
import org.h2.expression.Operation;
import org.h2.expression.Parameter; import org.h2.expression.Parameter;
import org.h2.expression.UnaryOperation;
import org.h2.expression.ValueExpression; import org.h2.expression.ValueExpression;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
...@@ -530,6 +525,7 @@ public abstract class Query extends Prepared { ...@@ -530,6 +525,7 @@ public abstract class Query extends Prepared {
*/ */
private static boolean checkOrderOther(Session session, Expression expr, ArrayList<String> expressionSQL) { private static boolean checkOrderOther(Session session, Expression expr, ArrayList<String> expressionSQL) {
if (expr.isConstant()) { if (expr.isConstant()) {
// ValueExpression or other
return true; return true;
} }
String exprSQL = expr.getSQL(); String exprSQL = expr.getSQL();
...@@ -538,42 +534,20 @@ public abstract class Query extends Prepared { ...@@ -538,42 +534,20 @@ public abstract class Query extends Prepared {
return true; return true;
} }
} }
if (expr instanceof Function) { int count = expr.getSubexpressionCount();
Function function = (Function) expr; if (expr instanceof Function ? !((Function) expr).isDeterministic() : count <= 0) {
if (!function.isDeterministic()) { // If expression is a non-deterministic function or expression is an
// ExpressionColumn, Parameter, SequenceValue or has other
// unsupported type without subexpressions
return false; return false;
} }
for (Expression e : function.getArgs()) { for (int i = 0; i < count; i++) {
if (!checkOrderOther(session, e, expressionSQL)) { if (!checkOrderOther(session, expr.getSubexpression(i), expressionSQL)) {
return false; return false;
} }
} }
return true; return true;
} }
if (expr instanceof Operation) {
Operation operation = (Operation) expr;
Expression right = operation.getRightSubExpression();
return checkOrderOther(session, operation.getLeftSubExpression(), expressionSQL)
&& (right == null || checkOrderOther(session, right, expressionSQL));
}
if (expr instanceof UnaryOperation) {
return checkOrderOther(session, ((UnaryOperation) expr).getSubExpression(), expressionSQL);
}
if (expr instanceof ConditionAndOr) {
ConditionAndOr condition = (ConditionAndOr) expr;
return checkOrderOther(session, condition.getLeftSubExpression(), expressionSQL)
&& checkOrderOther(session, condition.getRightSubExpression(), expressionSQL);
}
if (expr instanceof ConditionNot) {
return checkOrderOther(session, ((ConditionNot) expr).getSubCondition(), expressionSQL);
}
if (expr instanceof Comparison) {
Comparison condition = (Comparison) expr;
return checkOrderOther(session, condition.getLeftSubExpression(), expressionSQL)
&& checkOrderOther(session, condition.getRightSubExpression(), expressionSQL);
}
return false;
}
/** /**
* Create a {@link SortOrder} object given the list of {@link SelectOrderBy} * Create a {@link SortOrder} object given the list of {@link SelectOrderBy}
......
...@@ -587,22 +587,24 @@ public class Comparison extends Condition { ...@@ -587,22 +587,24 @@ public class Comparison extends Condition {
return null; return null;
} }
/** @Override
* Get the left sub-expression of this condition. public int getSubexpressionCount() {
* return compareType == IS_NULL || compareType == IS_NOT_NULL ? 1 : 2;
* @return the left sub-expression
*/
public Expression getLeftSubExpression() {
return left;
} }
/** @Override
* Get the right sub-expression of this condition. public Expression getSubexpression(int index) {
* switch (index) {
* @return the right sub-expression case 0:
*/ return left;
public Expression getRightSubExpression() { case 1:
if (compareType != IS_NULL && compareType != IS_NOT_NULL) {
return right; return right;
} }
//$FALL-THROUGH$
default:
throw new IndexOutOfBoundsException();
}
}
} }
...@@ -283,22 +283,21 @@ public class ConditionAndOr extends Condition { ...@@ -283,22 +283,21 @@ public class ConditionAndOr extends Condition {
return left.getCost() + right.getCost(); return left.getCost() + right.getCost();
} }
/** @Override
* Get the left sub-expression of this condition. public int getSubexpressionCount() {
* return 2;
* @return the left sub-expression
*/
public Expression getLeftSubExpression() {
return left;
} }
/** @Override
* Get the right sub-expression of this condition. public Expression getSubexpression(int index) {
* switch (index) {
* @return the right sub-expression case 0:
*/ return left;
public Expression getRightSubExpression() { case 1:
return right; return right;
default:
throw new IndexOutOfBoundsException();
}
} }
} }
...@@ -98,13 +98,17 @@ public class ConditionNot extends Condition { ...@@ -98,13 +98,17 @@ public class ConditionNot extends Condition {
return condition.getCost(); return condition.getCost();
} }
/** @Override
* Get the sub-expression of this condition. public int getSubexpressionCount() {
* return 1;
* @return the sub-expression }
*/
public Expression getSubCondition() { @Override
public Expression getSubexpression(int index) {
if (index == 0) {
return condition; return condition;
} }
throw new IndexOutOfBoundsException();
}
} }
...@@ -357,4 +357,24 @@ public abstract class Expression { ...@@ -357,4 +357,24 @@ public abstract class Expression {
} }
} }
/**
* Returns count of subexpressions.
*
* @return count of subexpressions
*/
public int getSubexpressionCount() {
return 0;
}
/**
* Returns subexpression with specified index.
*
* @param index 0-based index
* @return subexpression with specified index
* @throws IndexOutOfBoundsException if specified index is not valid
*/
public Expression getSubexpression(int index) {
throw new IndexOutOfBoundsException();
}
} }
...@@ -2710,4 +2710,14 @@ public class Function extends Expression implements FunctionCall { ...@@ -2710,4 +2710,14 @@ public class Function extends Expression implements FunctionCall {
return info.type == NEXTVAL; return info.type == NEXTVAL;
} }
@Override
public int getSubexpressionCount() {
return args.length;
}
@Override
public Expression getSubexpression(int index) {
return args[index];
}
} }
...@@ -451,22 +451,21 @@ public class Operation extends Expression { ...@@ -451,22 +451,21 @@ public class Operation extends Expression {
return left.getCost() + right.getCost() + 1; return left.getCost() + right.getCost() + 1;
} }
/** @Override
* Get the left sub-expression of this operation. public int getSubexpressionCount() {
* return 2;
* @return the left sub-expression
*/
public Expression getLeftSubExpression() {
return left;
} }
/** @Override
* Get the right sub-expression of this operation. public Expression getSubexpression(int index) {
* switch (index) {
* @return the right sub-expression case 0:
*/ return left;
public Expression getRightSubExpression() { case 1:
return right; return right;
default:
throw new IndexOutOfBoundsException();
}
} }
} }
...@@ -96,13 +96,17 @@ public class UnaryOperation extends Expression { ...@@ -96,13 +96,17 @@ public class UnaryOperation extends Expression {
return arg.getCost() + 1; return arg.getCost() + 1;
} }
/** @Override
* Get the sub-expression of this operation. public int getSubexpressionCount() {
* return 1;
* @return the sub-expression }
*/
public Expression getSubExpression() { @Override
public Expression getSubexpression(int index) {
if (index == 0) {
return arg; return arg;
} }
throw new IndexOutOfBoundsException();
}
} }
...@@ -669,19 +669,17 @@ public class FullText { ...@@ -669,19 +669,17 @@ public class FullText {
ArrayList<String> data, Expression expr) { ArrayList<String> data, Expression expr) {
if (expr instanceof ConditionAndOr) { if (expr instanceof ConditionAndOr) {
ConditionAndOr and = (ConditionAndOr) expr; ConditionAndOr and = (ConditionAndOr) expr;
Expression left = and.getLeftSubExpression(); addColumnData(columns, data, and.getSubexpression(0));
Expression right = and.getRightSubExpression(); addColumnData(columns, data, and.getSubexpression(1));
addColumnData(columns, data, left);
addColumnData(columns, data, right);
} else { } else {
Comparison comp = (Comparison) expr; Comparison comp = (Comparison) expr;
ExpressionColumn ec = (ExpressionColumn) comp.getLeftSubExpression(); ExpressionColumn ec = (ExpressionColumn) comp.getSubexpression(0);
ValueExpression ev = (ValueExpression) comp.getRightSubExpression();
String columnName = ec.getColumnName(); String columnName = ec.getColumnName();
columns.add(columnName); columns.add(columnName);
if (ev == null) { if (expr.getSubexpressionCount() == 1) {
data.add(null); data.add(null);
} else { } else {
ValueExpression ev = (ValueExpression) comp.getSubexpression(1);
data.add(ev.getValue(null).getString()); data.add(ev.getValue(null).getString());
} }
} }
......
...@@ -66,6 +66,9 @@ SELECT DISTINCT NAME, ID + 1 FROM TEST ORDER BY UPPER(NAME) || (ID + 1); ...@@ -66,6 +66,9 @@ SELECT DISTINCT NAME, ID + 1 FROM TEST ORDER BY UPPER(NAME) || (ID + 1);
SELECT DISTINCT ID FROM TEST ORDER BY NAME; SELECT DISTINCT ID FROM TEST ORDER BY NAME;
> exception ORDER_BY_NOT_IN_RESULT > exception ORDER_BY_NOT_IN_RESULT
SELECT DISTINCT ID FROM TEST ORDER BY UPPER(NAME);
> exception ORDER_BY_NOT_IN_RESULT
SELECT DISTINCT ID FROM TEST ORDER BY CURRENT_TIMESTAMP; SELECT DISTINCT ID FROM TEST ORDER BY CURRENT_TIMESTAMP;
> exception ORDER_BY_NOT_IN_RESULT > exception ORDER_BY_NOT_IN_RESULT
......
...@@ -789,4 +789,4 @@ inconsistencies discover eliminated violates tweaks postpone leftovers ...@@ -789,4 +789,4 @@ inconsistencies discover eliminated violates tweaks postpone leftovers
tied ties tied ties
launched unavailable smallmoney erroneously multiplier newid pan streamline unmap preview unexpectedly presumably launched unavailable smallmoney erroneously multiplier newid pan streamline unmap preview unexpectedly presumably
converging smth rng curs casts unmapping unmapper converging smth rng curs casts unmapping unmapper
immediate hhmmss scheduled hhmm prematurely postponed arranges immediate hhmmss scheduled hhmm prematurely postponed arranges subexpression subexpressions
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论