All Downloads are FREE. Search and download functionalities are using the official Maven repository.

studio.raptor.sqlparser.fast.expression.ConditionAndOr Maven / Gradle / Ivy

/*
 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
 * and the EPL 1.0 (http://h2database.com/html/license.html).
 * Initial Developer: H2 Group
 */
package studio.raptor.sqlparser.fast.expression;

import studio.raptor.sqlparser.fast.engine.SysProperties;
import studio.raptor.sqlparser.fast.message.ParseException;
import studio.raptor.sqlparser.fast.table.ColumnResolver;
import studio.raptor.sqlparser.fast.value.Value;

/**
 * An 'and' or 'or' condition as in WHERE ID=1 AND NAME=?
 */
public class ConditionAndOr extends Condition {

  /**
   * The AND condition type as in ID=1 AND NAME='Hello'.
   */
  public static final int AND = 0;

  /**
   * The OR condition type as in ID=1 OR NAME='Hello'.
   */
  public static final int OR = 1;

  private final int andOrType;
  private Expression left, right;

  public ConditionAndOr(int andOrType, Expression left, Expression right) {
    this.andOrType = andOrType;
    this.left = left;
    this.right = right;
    if (SysProperties.CHECK && (left == null || right == null)) {
      ParseException.throwInternalError(left + " " + right);
    }
  }

  @Override
  public String getSQL() {
    String sql;
    switch (andOrType) {
      case AND:
        sql = left.getSQL() + "\n    AND " + right.getSQL();
        break;
      case OR:
        sql = left.getSQL() + "\n    OR " + right.getSQL();
        break;
      default:
        throw ParseException.throwInternalError("andOrType=" + andOrType);
    }
    return "(" + sql + ")";
  }

  @Override
  public Value getValue() {
    return null;
  }

  @Override
  public int getType() {
    return 0;
  }

  public Expression optimize() {
/*    // NULL handling: see wikipedia,
    // http://www-cs-students.stanford.edu/~wlam/compsci/sqlnulls
    left = left.optimize();
    right = right.optimize();
    int lc = left.getCost(), rc = right.getCost();
    if (rc < lc) {
      Expression t = left;
      left = right;
      right = t;
    }

    // TODO optimization: convert .. OR .. to UNION if the cost is lower
    Value l = left.isConstant() ? left.getValue() : null;
    Value r = right.isConstant() ? right.getValue() : null;
    if (l == null && r == null) {
      return this;
    }
    if (l != null && r != null) {
      return ValueExpression.get(getValue());
    }
    switch (andOrType) {
      case AND:
        if (l != null) {
          if (Boolean.FALSE.equals(l.getBoolean())) {
            return ValueExpression.get(l);
          } else if (Boolean.TRUE.equals(l.getBoolean())) {
            return right;
          }
        } else if (r != null) {
          if (Boolean.FALSE.equals(r.getBoolean())) {
            return ValueExpression.get(r);
          } else if (Boolean.TRUE.equals(r.getBoolean())) {
            return left;
          }
        }
        break;
      case OR:
        if (l != null) {
          if (Boolean.TRUE.equals(l.getBoolean())) {
            return ValueExpression.get(l);
          } else if (Boolean.FALSE.equals(l.getBoolean())) {
            return right;
          }
        } else if (r != null) {
          if (Boolean.TRUE.equals(r.getBoolean())) {
            return ValueExpression.get(r);
          } else if (Boolean.FALSE.equals(r.getBoolean())) {
            return left;
          }
        }
        break;
      default:
        ParseException.throwInternalError("type=" + andOrType);
    }*/
    return this;
  }

  @Override
  public void mapColumns(ColumnResolver resolver, int level) {
    left.mapColumns(resolver, level);
    right.mapColumns(resolver, level);
  }

  @Override
  public boolean isEverything(ExpressionVisitor visitor) {
    return left.isEverything(visitor) && right.isEverything(visitor);
  }

  /**
   * Get the left or the right sub-expression of this condition.
   *
   * @param getLeft true to get the left sub-expression, false to get the right sub-expression.
   * @return the sub-expression
   */
  public Expression getExpression(boolean getLeft) {
    return getLeft ? this.left : right;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy