Open Source Repository

Home /hibernate/hibernate-3.2.7.ga | Repository Home


org/hibernate/dialect/Oracle9Dialect.java
//$Id: Oracle9Dialect.java 14189 2007-11-06 02:09:45Z d.plentz $
package org.hibernate.dialect;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.NvlFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.ViolatedConstraintNameExtracter;
import org.hibernate.util.ReflectHelper;

/**
 * An SQL dialect for Oracle 9 (uses ANSI-style syntax where possible).
 *
 @deprecated Use either Oracle9iDialect or Oracle10gDialect instead
 @author Gavin King, David Channon
 */
public class Oracle9Dialect extends Dialect {

  private static final Log log = LogFactory.getLogOracle9Dialect.class );

  public Oracle9Dialect() {
    super();
    log.warn"The Oracle9Dialect dialect has been deprecated; use either Oracle9iDialect or Oracle10gDialect instead" );
    registerColumnTypeTypes.BIT, "number(1,0)" );
    registerColumnTypeTypes.BIGINT, "number(19,0)" );
    registerColumnTypeTypes.SMALLINT, "number(5,0)" );
    registerColumnTypeTypes.TINYINT, "number(3,0)" );
    registerColumnTypeTypes.INTEGER, "number(10,0)" );
    registerColumnTypeTypes.CHAR, "char(1 char)" );
    registerColumnTypeTypes.VARCHAR, 4000"varchar2($l char)" );
    registerColumnTypeTypes.VARCHAR, "long" );
    registerColumnTypeTypes.FLOAT, "float" );
    registerColumnTypeTypes.DOUBLE, "double precision" );
    registerColumnTypeTypes.DATE, "date" );
    registerColumnTypeTypes.TIME, "date" );
    registerColumnTypeTypes.TIMESTAMP, "timestamp" );
    registerColumnTypeTypes.VARBINARY, 2000"raw($l)" );
    registerColumnTypeTypes.VARBINARY, "long raw" );
    registerColumnTypeTypes.NUMERIC, "number($p,$s)" );
    registerColumnTypeTypes.DECIMAL, "number($p,$s)" );
    registerColumnTypeTypes.BLOB, "blob" );
    registerColumnTypeTypes.CLOB, "clob" );

    // Oracle driver reports to support getGeneratedKeys(), but they only
    // support the version taking an array of the names of the columns to
    // be returned (via its RETURNING clause).  No other driver seems to
    // support this overloaded version.
    getDefaultProperties().setProperty(Environment.USE_GET_GENERATED_KEYS, "false");
    getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
    getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);

    registerFunction"abs"new StandardSQLFunction("abs") );
    registerFunction"sign"new StandardSQLFunction("sign", Hibernate.INTEGER) );

    registerFunction"acos"new StandardSQLFunction("acos", Hibernate.DOUBLE) );
    registerFunction"asin"new StandardSQLFunction("asin", Hibernate.DOUBLE) );
    registerFunction"atan"new StandardSQLFunction("atan", Hibernate.DOUBLE) );
    registerFunction"cos"new StandardSQLFunction("cos", Hibernate.DOUBLE) );
    registerFunction"cosh"new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
    registerFunction"exp"new StandardSQLFunction("exp", Hibernate.DOUBLE) );
    registerFunction"ln"new StandardSQLFunction("ln", Hibernate.DOUBLE) );
    registerFunction"sin"new StandardSQLFunction("sin", Hibernate.DOUBLE) );
    registerFunction"sinh"new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
    registerFunction"stddev"new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
    registerFunction"sqrt"new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
    registerFunction"tan"new StandardSQLFunction("tan", Hibernate.DOUBLE) );
    registerFunction"tanh"new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
    registerFunction"variance"new StandardSQLFunction("variance", Hibernate.DOUBLE) );

    registerFunction"round"new StandardSQLFunction("round") );
    registerFunction"trunc"new StandardSQLFunction("trunc") );
    registerFunction"ceil"new StandardSQLFunction("ceil") );
    registerFunction"floor"new StandardSQLFunction("floor") );

    registerFunction"chr"new StandardSQLFunction("chr", Hibernate.CHARACTER) );
    registerFunction"initcap"new StandardSQLFunction("initcap") );
    registerFunction"lower"new StandardSQLFunction("lower") );
    registerFunction"ltrim"new StandardSQLFunction("ltrim") );
    registerFunction"rtrim"new StandardSQLFunction("rtrim") );
    registerFunction"soundex"new StandardSQLFunction("soundex") );
    registerFunction"upper"new StandardSQLFunction("upper") );
    registerFunction"ascii"new StandardSQLFunction("ascii", Hibernate.INTEGER) );
    registerFunction"length"new StandardSQLFunction("length", Hibernate.LONG) );

    registerFunction"to_char"new StandardSQLFunction("to_char", Hibernate.STRING) );
    registerFunction"to_date"new StandardSQLFunction("to_date", Hibernate.TIMESTAMP) );

    registerFunction"current_date"new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
    registerFunction"current_time"new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) );
    registerFunction"current_timestamp"new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );

    registerFunction"last_day"new StandardSQLFunction("last_day", Hibernate.DATE) );
    registerFunction"sysdate"new NoArgSQLFunction("sysdate", Hibernate.DATE, false) );
    registerFunction"systimestamp"new NoArgSQLFunction("systimestamp", Hibernate.TIMESTAMP, false) );
    registerFunction"uid"new NoArgSQLFunction("uid", Hibernate.INTEGER, false) );
    registerFunction"user"new NoArgSQLFunction("user", Hibernate.STRING, false) );

    registerFunction"rowid"new NoArgSQLFunction("rowid", Hibernate.LONG, false) );
    registerFunction"rownum"new NoArgSQLFunction("rownum", Hibernate.LONG, false) );

    // Multi-param string dialect functions...
    registerFunction"concat"new VarArgsSQLFunction(Hibernate.STRING, """||""") );
    registerFunction"instr"new StandardSQLFunction("instr", Hibernate.INTEGER) );
    registerFunction"instrb"new StandardSQLFunction("instrb", Hibernate.INTEGER) );
    registerFunction"lpad"new StandardSQLFunction("lpad", Hibernate.STRING) );
    registerFunction"replace"new StandardSQLFunction("replace", Hibernate.STRING) );
    registerFunction"rpad"new StandardSQLFunction("rpad", Hibernate.STRING) );
    registerFunction"substr"new StandardSQLFunction("substr", Hibernate.STRING) );
    registerFunction"substrb"new StandardSQLFunction("substrb", Hibernate.STRING) );
    registerFunction"translate"new StandardSQLFunction("translate", Hibernate.STRING) );

    registerFunction"substring"new StandardSQLFunction"substr", Hibernate.STRING ) );
    registerFunction"locate"new SQLFunctionTemplateHibernate.INTEGER, "instr(?2,?1)" ) );
    registerFunction"bit_length"new SQLFunctionTemplateHibernate.INTEGER, "vsize(?1)*8" ) );
    registerFunction"coalesce"new NvlFunction() );

    // Multi-param numeric dialect functions...
    registerFunction"atan2"new StandardSQLFunction("atan2", Hibernate.FLOAT) );
    registerFunction"log"new StandardSQLFunction("log", Hibernate.INTEGER) );
    registerFunction"mod"new StandardSQLFunction("mod", Hibernate.INTEGER) );
    registerFunction"nvl"new StandardSQLFunction("nvl") );
    registerFunction"nvl2"new StandardSQLFunction("nvl2") );
    registerFunction"power"new StandardSQLFunction("power", Hibernate.FLOAT) );

    // Multi-param date dialect functions...
    registerFunction"add_months"new StandardSQLFunction("add_months", Hibernate.DATE) );
    registerFunction"months_between"new StandardSQLFunction("months_between", Hibernate.FLOAT) );
    registerFunction"next_day"new StandardSQLFunction("next_day", Hibernate.DATE) );

    registerFunction"str"new StandardSQLFunction("to_char", Hibernate.STRING) );
  }

  public String getAddColumnString() {
    return "add";
  }

  public String getSequenceNextValString(String sequenceName) {
    return "select " + getSelectSequenceNextValStringsequenceName " from dual";
  }

  public String getSelectSequenceNextValString(String sequenceName) {
    return sequenceName + ".nextval";
  }

  public String getCreateSequenceString(String sequenceName) {
    return "create sequence " + sequenceName; //starts with 1, implicitly
  }

  public String getDropSequenceString(String sequenceName) {
    return "drop sequence " + sequenceName;
  }

  public String getCascadeConstraintsString() {
    return " cascade constraints";
  }

  public boolean dropConstraints() {
    return false;
  }

  public String getForUpdateNowaitString() {
    return " for update nowait";
  }

  public boolean supportsSequences() {
    return true;
  }

  public boolean supportsPooledSequences() {
    return true;
  }

  public boolean supportsLimit() {
    return true;
  }

  public String getLimitString(String sql, boolean hasOffset) {

    sql = sql.trim();
    boolean isForUpdate = false;
    if sql.toLowerCase().endsWith(" for update") ) {
      sql = sql.substring0, sql.length()-11 );
      isForUpdate = true;
    }

    StringBuffer pagingSelect = new StringBuffersql.length()+100 );
    if (hasOffset) {
      pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
    }
    else {
      pagingSelect.append("select * from ( ");
    }
    pagingSelect.append(sql);
    if (hasOffset) {
      pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
    }
    else {
      pagingSelect.append(" ) where rownum <= ?");
    }

    if isForUpdate ) {
      pagingSelect.append" for update" );
    }

    return pagingSelect.toString();
  }

  public String getForUpdateString(String aliases) {
    return getForUpdateString() " of " + aliases;
  }

  public String getForUpdateNowaitString(String aliases) {
    return getForUpdateString() " of " + aliases + " nowait";
  }

  public boolean bindLimitParametersInReverseOrder() {
    return true;
  }

  public boolean useMaxForLimit() {
    return true;
  }

  public boolean forUpdateOfColumns() {
    return true;
  }

  public String getQuerySequencesString() {
    return "select sequence_name from user_sequences";
  }

  public String getSelectGUIDString() {
    return "select rawtohex(sys_guid()) from dual";
  }

  public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
        return EXTRACTER;
  }

  private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {

    /**
     * Extract the name of the violated constraint from the given SQLException.
     *
     @param sqle The exception that was the result of the constraint violation.
     @return The extracted constraint name.
     */
    public String extractConstraintName(SQLException sqle) {
      int errorCode = JDBCExceptionHelper.extractErrorCode(sqle);
      if errorCode == || errorCode == 2291 || errorCode == 2292 ) {
        return extractUsingTemplate"constraint ("") violated", sqle.getMessage() );
      }
      else if errorCode == 1400 ) {
        // simple nullability constraint
        return null;
      }
      else {
        return null;
      }
    }

  };

  // not final-static to avoid possible classcast exceptions if using different oracle drivers.
  int oracletypes_cursor_value = 0;
  public int registerResultSetOutParameter(java.sql.CallableStatement statement,int colthrows SQLException {
    if(oracletypes_cursor_value==0) {
      try {
        Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes");
        oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance());
      catch (Exception se) {
        throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se);
      }
    }
    //  register the type of the out param - an Oracle specific type
    statement.registerOutParameter(col, oracletypes_cursor_value);
    col++;
    return col;
  }

  public ResultSet getResultSet(CallableStatement psthrows SQLException {
    ps.execute();
    return ResultSet ps.getObject);
  }

  public boolean supportsUnionAll() {
    return true;
  }

  public boolean supportsCommentOn() {
    return true;
  }

  public boolean supportsTemporaryTables() {
    return true;
  }

  public String generateTemporaryTableName(String baseTableName) {
    String name = super.generateTemporaryTableName(baseTableName);
    return name.length() 30 ? name.substring130 : name;
  }

  public String getCreateTemporaryTableString() {
    return "create global temporary table";
  }

  public String getCreateTemporaryTablePostfix() {
    return "on commit delete rows";
  }

  public boolean dropTemporaryTableAfterUse() {
    return false;
  }

  public boolean supportsCurrentTimestampSelection() {
    return true;
  }

  public String getCurrentTimestampSelectString() {
    return "select systimestamp from dual";
  }

  public boolean isCurrentTimestampSelectStringCallable() {
    return false;
  }


  // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  public boolean supportsEmptyInList() {
    return false;
  }

  public boolean supportsExistsInSelect() {
    return false;
  }
}