use of org.h2.engine.SessionLocal in project h2database by h2database.
the class Comparison method optimizeOr.
/**
* Replace the OR condition with IN condition if possible. Example: given
* the two conditions A=1 OR A=2, the new condition A IN(1, 2) is returned.
*
* @param session the session
* @param other the second condition
* @return null or the joined IN condition
*/
Expression optimizeOr(SessionLocal session, Comparison other) {
if (compareType == EQUAL && other.compareType == EQUAL) {
Expression left2 = other.left;
Expression right2 = other.right;
String l2 = left2.getSQL(DEFAULT_SQL_FLAGS);
String r2 = right2.getSQL(DEFAULT_SQL_FLAGS);
if (left.isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR)) {
String l = left.getSQL(DEFAULT_SQL_FLAGS);
if (l.equals(l2)) {
return getConditionIn(left, right, right2);
} else if (l.equals(r2)) {
return getConditionIn(left, right, left2);
}
}
if (right.isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR)) {
String r = right.getSQL(DEFAULT_SQL_FLAGS);
if (r.equals(l2)) {
return getConditionIn(right, left, right2);
} else if (r.equals(r2)) {
return getConditionIn(right, left, left2);
}
}
}
return null;
}
use of org.h2.engine.SessionLocal in project h2database by h2database.
the class Comparison method optimize.
@Override
public Expression optimize(SessionLocal session) {
left = left.optimize(session);
right = right.optimize(session);
check: {
TypeInfo leftType = left.getType(), rightType = right.getType();
if (session.getMode().numericWithBooleanComparison) {
switch(compareType) {
case EQUAL:
case NOT_EQUAL:
case EQUAL_NULL_SAFE:
case NOT_EQUAL_NULL_SAFE:
int lValueType = leftType.getValueType();
if (lValueType == Value.BOOLEAN) {
if (DataType.isNumericType(rightType.getValueType())) {
break check;
}
} else if (DataType.isNumericType(lValueType) && rightType.getValueType() == Value.BOOLEAN) {
break check;
}
}
}
TypeInfo.checkComparable(leftType, rightType);
}
if (whenOperand) {
return this;
}
if (right instanceof ExpressionColumn) {
if (left.isConstant() || left instanceof Parameter) {
Expression temp = left;
left = right;
right = temp;
compareType = getReversedCompareType(compareType);
}
}
if (left instanceof ExpressionColumn) {
if (right.isConstant()) {
Value r = right.getValue(session);
if (r == ValueNull.INSTANCE) {
if ((compareType & ~1) != EQUAL_NULL_SAFE) {
return TypedValueExpression.UNKNOWN;
}
}
TypeInfo colType = left.getType(), constType = r.getType();
int constValueType = constType.getValueType();
if (constValueType != colType.getValueType() || constValueType >= Value.ARRAY) {
TypeInfo resType = TypeInfo.getHigherType(colType, constType);
// once.
if (constValueType != resType.getValueType() || constValueType >= Value.ARRAY) {
Column column = ((ExpressionColumn) left).getColumn();
right = ValueExpression.get(r.convertTo(resType, session, column));
}
}
} else if (right instanceof Parameter) {
((Parameter) right).setColumn(((ExpressionColumn) left).getColumn());
}
}
if (left.isConstant() && right.isConstant()) {
return ValueExpression.getBoolean(getValue(session));
}
if (left.isNullConstant() || right.isNullConstant()) {
// a NULL constants
if ((compareType & ~1) != EQUAL_NULL_SAFE) {
return TypedValueExpression.UNKNOWN;
} else {
Expression e = left.isNullConstant() ? right : left;
int type = e.getType().getValueType();
if (type != Value.UNKNOWN && type != Value.ROW) {
return new NullPredicate(e, compareType == NOT_EQUAL_NULL_SAFE, false);
}
}
}
return this;
}
use of org.h2.engine.SessionLocal in project h2database by h2database.
the class ConditionInConstantSet method getAdditional.
/**
* Add an additional element if possible. Example: given two conditions
* A IN(1, 2) OR A=3, the constant 3 is added: A IN(1, 2, 3).
*
* @param session the session
* @param other the second condition
* @return null if the condition was not added, or the new condition
*/
Expression getAdditional(SessionLocal session, Comparison other) {
if (!not && !whenOperand && left.isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR)) {
Expression add = other.getIfEquals(left);
if (add != null) {
if (add.isConstant()) {
ArrayList<Expression> list = new ArrayList<>(valueList.size() + 1);
list.addAll(valueList);
list.add(add);
return new ConditionInConstantSet(session, left, false, false, list);
}
}
}
return null;
}
use of org.h2.engine.SessionLocal in project h2database by h2database.
the class ConditionAndOr method optimizeIfConstant.
/**
* Optimize the condition if at least one part is constant.
*
* @param session the session
* @param andOrType the type
* @param left the left part of the condition
* @param right the right part of the condition
* @return the optimized condition, or {@code null} if condition cannot be optimized
*/
static Expression optimizeIfConstant(SessionLocal session, int andOrType, Expression left, Expression right) {
if (!left.isConstant()) {
if (!right.isConstant()) {
return null;
} else {
return optimizeConstant(session, andOrType, right.getValue(session), left);
}
}
Value l = left.getValue(session);
if (!right.isConstant()) {
return optimizeConstant(session, andOrType, l, right);
}
Value r = right.getValue(session);
switch(andOrType) {
case AND:
{
if (l.isFalse() || r.isFalse()) {
return ValueExpression.FALSE;
}
if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) {
return TypedValueExpression.UNKNOWN;
}
return ValueExpression.TRUE;
}
case OR:
{
if (l.isTrue() || r.isTrue()) {
return ValueExpression.TRUE;
}
if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) {
return TypedValueExpression.UNKNOWN;
}
return ValueExpression.FALSE;
}
default:
throw DbException.getInternalError("type=" + andOrType);
}
}
use of org.h2.engine.SessionLocal in project h2database by h2database.
the class ConditionAndOr method getValue.
@Override
public Value getValue(SessionLocal session) {
Value l = left.getValue(session);
Value r;
switch(andOrType) {
case AND:
{
if (l.isFalse() || (r = right.getValue(session)).isFalse()) {
return ValueBoolean.FALSE;
}
if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) {
return ValueNull.INSTANCE;
}
return ValueBoolean.TRUE;
}
case OR:
{
if (l.isTrue() || (r = right.getValue(session)).isTrue()) {
return ValueBoolean.TRUE;
}
if (l == ValueNull.INSTANCE || r == ValueNull.INSTANCE) {
return ValueNull.INSTANCE;
}
return ValueBoolean.FALSE;
}
default:
throw DbException.getInternalError("type=" + andOrType);
}
}
Aggregations