package ModSQL;
import java.sql.*;
 
/* $Id: Operator_Concat.java,v 1.6 2003/07/09 06:54:49 cvs Exp $
 *
 * Copyright (c) 2003 Chris Studholme <chris.studholme@utoronto.ca>
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See COPYING for more information.
 */

/**
 * <p>SQL operator "||". 
 *
 * @author chris.studholme@utoronto.ca
 */
final class Operator_Concat extends Operator {

  /**
   * <p>Prepare the function for use.  This method verifies that the 
   * parameters are strings.
   *
   * @throws SQLException if the parameters are invalid
   */
  public void optimize() throws SQLException {
    super.optimize();
    if (parameters.length<=0) 
      throw new SQLException("'||' operator requires at least one parameter");
    for (int i=0; i<parameters.length; ++i)
      switch (parameters[i].getSQLType()) {
      case Types.NULL:
      case Types.CHAR:
      case Types.VARCHAR:
      case Types.LONGVARCHAR:
	break;
      default:
	throw new SQLException("invalid parameter type in '||' operator");
      }
    evaluateConstantParameters();
  }

  /**
   * Returns "#CONCAT".
   *
   * @return name of function 
   */
  public String functionName() {
    return "#CONCAT";
  }


  /****************  result meta-data  ****************/
  

  /**
   * Return the SQL type of the value that this function expects to return.
   * The data returned by the function must either be of this type, or null.
   *
   * @return SQL type of data to be returned
   * @throws SQLException if a database-access error occurs.
   */
  public int getSQLType() throws SQLException {
    boolean longchar=false;
    for (int i=0; i<parameters.length; ++i) 
      switch (parameters[i].getSQLType()) {
      case Types.NULL:
	return Types.NULL;
      case Types.CHAR:
      case Types.VARCHAR:
	break;
      case Types.LONGVARCHAR:
	longchar=true;
	break;
      default:
	throw new SQLException("invalid parameter type in '||' operator");
      }
    return longchar ? Types.LONGVARCHAR : Types.VARCHAR;
  }


  /**
   * Return the maximum number of characters that this function expects to
   * return in a String object.  If the maximum size is unknown for any
   * of the parameter, this method returns -1.
   *
   * @return maximum size of String returned or -1 if unknown
   * @throws SQLException if a database-access error occurs
   */
  public int getMaxResultSize() throws SQLException {
    int maxlen=0;
    for (int i=0; i<parameters.length; ++i) {
      int len = parameters[i].getMaxResultSize();
      if (len<0) return -1;
      maxlen+=len;
    }
    return maxlen;
  }


  /****************  evaluation methods  ****************/


  /**
   * Evaluate parameters and compute the function.
   *
   * @param aggregate passed to parameters
   * @return result object
   * @throws SQLException if a database-access error occurs
   * @throws EndOfTable if thrown by a parameter
   */
  public Object evaluate(boolean aggregate) throws SQLException, EndOfTable {
    if (!evaluateParameters(aggregate))
      return null;
    StringBuffer result = new StringBuffer();
    for (int i=0; i<parameter_value.length; ++i)
      result.append(parameter_value[i]);
    return result.toString();
  }

  /**
   * Evaluate parameters and compute the function.
   *
   * @param match_op how the value should be matched
   * @param match_value desired value
   * @return result object
   * @throws SQLException if a database-access error occurs
   * @throws EndOfTable if thrown by a parameter
   */
  public Object evaluate(int match_op, Object match_value)
    throws SQLException, EndOfTable {
    // we could do a little better here
    return evaluate(false);
  }

};


