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

studio.raptor.sqlparser.fast.expression.ExpressionVisitor 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 java.util.HashSet;
import studio.raptor.sqlparser.fast.table.Table;
import studio.raptor.sqlparser.fast.table.Column;
import studio.raptor.sqlparser.fast.table.ColumnResolver;

/**
 * The visitor pattern is used to iterate through all expressions of a query
 * to optimize a statement.
 */
public class ExpressionVisitor {

  /**
   * Is the value independent on unset parameters or on columns of a higher
   * level query, or sequence values (that means can it be evaluated right
   * now)?
   */
  public static final int INDEPENDENT = 0;

  /**
   * The visitor singleton for the type INDEPENDENT.
   */
  public static final ExpressionVisitor INDEPENDENT_VISITOR =
      new ExpressionVisitor(INDEPENDENT);

  /**
   * Are all aggregates MIN(column), MAX(column), or COUNT(*) for the given
   * table (getTable)?
   */
  public static final int OPTIMIZABLE_MIN_MAX_COUNT_ALL = 1;

  /**
   * Does the expression return the same results for the same parameters?
   */
  public static final int DETERMINISTIC = 2;

  /**
   * The visitor singleton for the type DETERMINISTIC.
   */
  public static final ExpressionVisitor DETERMINISTIC_VISITOR =
      new ExpressionVisitor(DETERMINISTIC);

  /**
   * Can the expression be evaluated, that means are all columns set to
   * 'evaluatable'?
   */
  public static final int EVALUATABLE = 3;

  /**
   * The visitor singleton for the type EVALUATABLE.
   */
  public static final ExpressionVisitor EVALUATABLE_VISITOR =
      new ExpressionVisitor(EVALUATABLE);

  /**
   * Request to set the latest modification id (addDataModificationId).
   */
  public static final int SET_MAX_DATA_MODIFICATION_ID = 4;

  /**
   * Does the expression have no side effects (change the data)?
   */
  public static final int READONLY = 5;

  /**
   * The visitor singleton for the type EVALUATABLE.
   */
  public static final ExpressionVisitor READONLY_VISITOR =
      new ExpressionVisitor(READONLY);

  /**
   * Does an expression have no relation to the given table filter
   * (getResolver)?
   */
  public static final int NOT_FROM_RESOLVER = 6;

  /**
   * Request to get the set of dependencies (addDependency).
   */
  public static final int GET_DEPENDENCIES = 7;

  /**
   * Can the expression be added to a condition of an outer query. Example:
   * ROWNUM() can't be added as a condition to the inner query of select id
   * from (select t.*, rownum as r from test t) where r between 2 and 3; Also
   * a sequence expression must not be used.
   */
  public static final int QUERY_COMPARABLE = 8;

  /**
   * Get all referenced columns.
   */
  public static final int GET_COLUMNS = 9;

  /**
   * The visitor singleton for the type QUERY_COMPARABLE.
   */
  public static final ExpressionVisitor QUERY_COMPARABLE_VISITOR =
      new ExpressionVisitor(QUERY_COMPARABLE);

  private final int type;
  private final int queryLevel;
  private final HashSet columns;
  private final Table table;
  private final long[] maxDataModificationId;
  private final ColumnResolver resolver;

  private ExpressionVisitor(int type,
      int queryLevel,
      HashSet columns,
      Table table, ColumnResolver resolver,
      long[] maxDataModificationId) {
    this.type = type;
    this.queryLevel = queryLevel;
    this.columns = columns;
    this.table = table;
    this.resolver = resolver;
    this.maxDataModificationId = maxDataModificationId;
  }

  private ExpressionVisitor(int type) {
    this.type = type;
    this.queryLevel = 0;
    this.columns = null;
    this.table = null;
    this.resolver = null;
    this.maxDataModificationId = null;
  }

  /**
   * Add a new column to the set of columns.
   * This is used for GET_COLUMNS visitors.
   *
   * @param column the additional column.
   */
  void addColumn(Column column) {
    columns.add(column);
  }

  /**
   * Get the column resolver.
   * This is used for NOT_FROM_RESOLVER visitors.
   *
   * @return the column resolver
   */
  public ColumnResolver getResolver() {
    return resolver;
  }

  /**
   * Update the field maxDataModificationId if this value is higher
   * than the current value.
   * This is used for SET_MAX_DATA_MODIFICATION_ID visitors.
   *
   * @param value the data modification id
   */
  public void addDataModificationId(long value) {
    long m = maxDataModificationId[0];
    if (value > m) {
      maxDataModificationId[0] = value;
    }
  }

  /**
   * Get the last data modification.
   * This is used for SET_MAX_DATA_MODIFICATION_ID visitors.
   *
   * @return the maximum modification id
   */
  public long getMaxDataModificationId() {
    return maxDataModificationId[0];
  }

  int getQueryLevel() {
    return queryLevel;
  }

  /**
   * Get the table.
   * This is used for OPTIMIZABLE_MIN_MAX_COUNT_ALL visitors.
   *
   * @return the table
   */
  public Table getTable() {
    return table;
  }

  /**
   * Get the visitor type.
   *
   * @return the type
   */
  public int getType() {
    return type;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy