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

com.mckoi.database.interpret.FromClause Maven / Gradle / Ivy

/**
 * com.mckoi.database.interpret.FromClause  09 Sep 2001
 *
 * Mckoi SQL Database ( http://www.mckoi.com/database )
 * Copyright (C) 2000, 2001, 2002  Diehl and Associates, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * Version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License Version 2 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * Version 2 along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * Change Log:
 * 
 * 
 */

package com.mckoi.database.interpret;

import com.mckoi.database.*;
import java.util.Set;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collection;

/**
 * A container for the From clause of a select statement.  This handles
 * the different types of joins.
 *
 * @author Tobias Downer
 */

public final class FromClause
           implements java.io.Serializable, StatementTreeObject, Cloneable {

  static final long serialVersionUID = 565726601314503609L;

  /**
   * The JoiningSet object that we have created to represent the joins in this
   * FROM clause.
   */
  private JoiningSet join_set = new JoiningSet();

  /**
   * A list of all FromTableDef objects in this clause in order of when they
   * were specified.
   */
  private ArrayList def_list = new ArrayList();

  /**
   * A list of all table names in this from clause.
   */
  private ArrayList all_table_names = new ArrayList();

  /**
   * An id used for making unique names for anonymous inner selects.
   */
  private int table_key = 0;


  /**
   * Creates a new unique key string.
   */
  private String createNewKey() {
    ++table_key;
    return Integer.toString(table_key);
  }


  private void addTableDef(String table_name, FromTableDef def) {
    if (table_name != null) {
      if (all_table_names.contains(table_name)) {
        throw new Error("Duplicate table name in FROM clause: " + table_name);
      }
      all_table_names.add(table_name);
    }
    // Create a new unique key for this table
    String key = createNewKey();
    def.setUniqueKey(key);
    // Add the table key to the join set
    join_set.addTable(new TableName(key));
    // Add to the alias def map
    def_list.add(def);
  }

  /**
   * Adds a table name to this FROM clause.  Note that the given name
   * may be a dot deliminated ref such as (schema.table_name).
   */
  public void addTable(String table_name) {
    addTableDef(table_name, new FromTableDef(table_name));
  }

  /**
   * Adds a table name + alias to this FROM clause.
   */
  public void addTable(String table_name, String table_alias) {
    addTableDef(table_alias, new FromTableDef(table_name, table_alias));
  }

  /**
   * A generic form of a table declaration.  If any parameters are 'null' it
   * means the information is not available.
   */
  public void addTableDeclaration(String table_name,
                                  TableSelectExpression select,
                                  String table_alias) {
    // This is an inner select in the FROM clause
    if (table_name == null && select != null) {
      if (table_alias == null) {
        addTableDef(null, new FromTableDef(select));
      }
      else {
        addTableDef(table_alias, new FromTableDef(select, table_alias));
      }
    }
    // This is a standard table reference in the FROM clause
    else if (table_name != null && select == null) {
      if (table_alias == null) {
        addTable(table_name);
      }
      else {
        addTable(table_name, table_alias);
      }
    }
    // Error
    else {
      throw new Error("Unvalid declaration parameters.");
    }

  }

  /**
   * Adds a Join to the from clause.  'type' must be a join type as defined
   * in JoiningSet.
   */
  public void addJoin(int type) {
//    System.out.println("Add Join: " + type);
    join_set.addJoin(type);
  }

  /**
   * Hack, add a joining type to the previous entry from the end.  This is
   * an artifact of how joins are parsed.
   */
  public void addPreviousJoin(int type, Expression on_expression) {
    join_set.addPreviousJoin(type, on_expression);
  }

  /**
   * Adds a Join to the from clause.  'type' must be a join type as defined
   * in JoiningSet, and expression represents the ON condition.
   */
  public void addJoin(int type, Expression on_expression) {
    join_set.addJoin(type, on_expression);
  }

  /**
   * Returns the JoiningSet object for the FROM clause.
   */
  public JoiningSet getJoinSet() {
    return join_set;
  }

  /**
   * Returns the type of join after table 'n' in the set of tables in the
   * from clause.  Returns, JoiningSet.INNER_JOIN, JoiningSet.FULL_OUTER_JOIN,
   * etc.
   */
  public int getJoinType(int n) {
    return getJoinSet().getJoinType(n);
  }

  /**
   * Returns the ON Expression for the type of join after table 'n' in the
   * set.
   */
  public Expression getOnExpression(int n) {
    return getJoinSet().getOnExpression(n);
  }

  /**
   * Returns a Set of FromTableDef objects that represent all the tables
   * that are in this from clause.
   */
  public Collection allTables() {
    return def_list;
  }

  // Implemented from StatementTreeObject
  public void prepareExpressions(ExpressionPreparer preparer)
                                                  throws DatabaseException {
    // Prepare expressions in the JoiningSet first
    int size = join_set.getTableCount() - 1;
    for (int i = 0; i < size; ++i) {
      Expression exp = join_set.getOnExpression(i);
      if (exp != null) {
        exp.prepare(preparer);
      }
    }
    // Prepare the StatementTree sub-queries in the from tables
    for (int i = 0; i < def_list.size(); ++i) {
      FromTableDef table_def = (FromTableDef) def_list.get(i);
      table_def.prepareExpressions(preparer);
    }

  }

  public Object clone() throws CloneNotSupportedException {
    FromClause v = (FromClause) super.clone();
    v.join_set = (JoiningSet) join_set.clone();
    ArrayList cloned_def_list = new ArrayList(def_list.size());
    v.def_list = cloned_def_list;
    v.all_table_names = (ArrayList) all_table_names.clone();

    for (int i = 0; i < def_list.size(); ++i) {
      FromTableDef table_def = (FromTableDef) def_list.get(i);
      cloned_def_list.add(table_def.clone());
    }

    return v;
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy