/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openjpa.jdbc.sql;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import java.util.StringTokenizer;

import javax.sql.DataSource;

import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
import org.apache.openjpa.jdbc.kernel.exps.Lit;
import org.apache.openjpa.jdbc.kernel.exps.Param;
import org.apache.openjpa.jdbc.kernel.exps.Val;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.Index;
import org.apache.openjpa.jdbc.schema.Schema;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.kernel.Filters;
import org.apache.openjpa.kernel.MixedLockLevels;
import org.apache.openjpa.kernel.exps.Literal;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.StringUtil;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.StoreException;
import org.apache.openjpa.util.UnsupportedException;
import org.apache.openjpa.util.UserException;


/**
 * Dictionary for IBM DB2 database.
 */
public class DB2Dictionary
    extends AbstractDB2Dictionary {
    private static final Localizer _loc = Localizer.forPackage
        (DB2Dictionary.class);

    public static final String VENDOR_IBM = "ibm";
    public String optimizeClause = "optimize for";
    public String rowClause = "row";
    protected int db2ServerType = 0;
    public static final int db2ISeriesV5R3OrEarlier = 1;
    public static final int db2UDBV81OrEarlier = 2;
    public static final int db2ZOSV8xOrLater = 3;
    public static final int db2UDBV82OrLater = 4;
    public static final int db2ISeriesV5R4OrLater = 5;
    protected static final String forUpdate = "FOR UPDATE";
    protected static final String withURClause = "WITH UR";
    protected static final String withCSClause = "WITH CS";
    protected static final String withRSClause = "WITH RS";
    protected static final String withRRClause = "WITH RR";
    protected static final String useKeepShareLockClause     = "USE AND KEEP SHARE LOCKS";
    protected static final String useKeepUpdateLockClause    = "USE AND KEEP UPDATE LOCKS";
    protected static final String useKeepExclusiveLockClause = "USE AND KEEP EXCLUSIVE LOCKS";
    protected static final String forReadOnlyClause = "FOR READ ONLY";
    protected static final String defaultSequenceSQL
        = "SELECT SEQSCHEMA AS SEQUENCE_SCHEMA, SEQNAME AS SEQUENCE_NAME FROM SYSCAT.SEQUENCES";
    static final String SYSDUMMY = "SYSIBM.SYSDUMMY1";


    private int defaultBatchLimit = 100;
    public boolean appendExtendedExceptionText = true;

    /**
     * Affirms whether this dictionary uses {@code ROWNUM} feature.
     * {@code ROWNUM} feature is used to construct {@code SQL SELECT} query
     * that uses an offset or limits the number of resultant rows.
     * <br>
     * By default, this flag is set to {@code false}.
     */
    public boolean supportsRowNum = false;

    public DB2Dictionary() {
        platform = "DB2";
        validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM SYSIBM.SYSTABLES";
        supportsSelectEndIndex = true;

        nextSequenceQuery = "VALUES NEXTVAL FOR {0}";

        sequenceSQL = defaultSequenceSQL;
        sequenceSchemaSQL = "SEQSCHEMA = ?";
        sequenceNameSQL = "SEQNAME = ?";
        characterColumnSize = 254;

        binaryTypeName = "BLOB(1M)";
        longVarbinaryTypeName = "BLOB(1M)";
        varbinaryTypeName = "BLOB(1M)";
        clobTypeName = "CLOB(1M)";
        longVarcharTypeName = "LONG VARCHAR";
        datePrecision = MICRO;
        storeCharsAsNumbers = false;

        fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
            "LONG VARCHAR FOR BIT DATA", "LONG VARCHAR", "LONG VARGRAPHIC",
        }));
        systemSchemas = "SYSCAT,SYSIBM,SYSSTAT,SYSIBMADM,SYSTOOLS";
        maxConstraintNameLength = 18;
        maxIndexNameLength = 128;
        maxColumnNameLength = 30;
        supportsDeferredConstraints = false;
        supportsDefaultDeleteAction = false;
        supportsAlterTableWithDropColumn = false;
        supportsLockingWithOrderClause = true;
        supportsNullUniqueColumn = false;

        supportsNullTableForGetColumns = false;
        requiresCastForMathFunctions = true;
        requiresCastForComparisons = true;

        reservedWordSet.addAll(Arrays.asList(new String[]{
            "AFTER", "ALIAS", "ALLOW", "APPLICATION", "ASSOCIATE", "ASUTIME",
            "AUDIT", "AUX", "AUXILIARY", "BEFORE", "BINARY", "BUFFERPOOL",
            "CACHE", "CALL", "CALLED", "CAPTURE", "CARDINALITY", "CCSID",
            "CLUSTER", "COLLECTION", "COLLID", "COMMENT", "CONCAT",
            "CONDITION", "CONTAINS", "COUNT_BIG", "CURRENT_LC_CTYPE",
            "CURRENT_PATH", "CURRENT_SERVER", "CURRENT_TIMEZONE", "CYCLE",
            "DATABASE", "DAYS", "DB2GENERAL", "DB2GENRL", "DB2SQL",
            "DBINFO", "DEFAULTS", "DEFINITION", "DETERMINISTIC", "DISALLOW",
            "DO", "DSNHATTR", "DSSIZE", "DYNAMIC", "EACH", "EDITPROC", "ELSEIF",
            "ENCODING", "END-EXEC1", "ERASE", "EXCLUDING", "EXIT", "FENCED",
            "FIELDPROC", "FILE", "FINAL", "FREE", "FUNCTION", "GENERAL",
            "GENERATED", "GRAPHIC", "HANDLER", "HOLD", "HOURS", "IF",
            "INCLUDING", "INCREMENT", "INDEX", "INHERIT", "INOUT", "INTEGRITY",
            "ISOBID", "ITERATE", "JAR", "JAVA", "LABEL", "LC_CTYPE", "LEAVE",
            "LINKTYPE", "LOCALE", "LOCATOR", "LOCATORS", "LOCK", "LOCKMAX",
            "LOCKSIZE", "LONG", "LOOP", "MAXVALUE", "MICROSECOND",
            "MICROSECONDS", "MINUTES", "MINVALUE", "MODE", "MODIFIES", "MONTHS",
            "NEW", "NEW_TABLE", "NOCACHE", "NOCYCLE", "NODENAME", "NODENUMBER",
            "NOMAXVALUE", "NOMINVALUE", "NOORDER", "NULLS", "NUMPARTS", "OBID",
            "OLD", "OLD_TABLE", "OPTIMIZATION", "OPTIMIZE", "OUT", "OVERRIDING",
            "PACKAGE", "PARAMETER", "PART", "PARTITION", "PATH", "PIECESIZE",
            "PLAN", "PRIQTY", "PROGRAM", "PSID", "QUERYNO", "READS", "RECOVERY",
            "REFERENCING", "RELEASE", "RENAME", "REPEAT", "RESET", "RESIGNAL",
            "RESTART", "RESULT", "RESULT_SET_LOCATOR", "RETURN", "RETURNS",
            "ROUTINE", "ROW", "RRN", "RUN", "SAVEPOINT", "SCRATCHPAD",
            "SECONDS", "SECQTY", "SECURITY", "SENSITIVE", "SIGNAL", "SIMPLE",
            "SOURCE", "SPECIFIC", "SQLID", "STANDARD", "START", "STATIC",
            "STAY", "STOGROUP", "STORES", "STYLE", "SUBPAGES", "SYNONYM",
            "SYSFUN", "SYSIBM", "SYSPROC", "SYSTEM", "TABLESPACE", "TRIGGER",
            "UNDO", "UNTIL", "VALIDPROC", "VARIABLE", "VARIANT", "VCAT",
            "VOLUMES", "WHILE", "WLM", "YEARS",
        }));

        // reservedWordSet subset that CANNOT be used as valid column names
        // (i.e., without surrounding them with double-quotes)
        invalidColumnWordSet.addAll(Arrays.asList(new String[] {
            "CONSTRAINT", "END-EXEC", "END-EXEC1",
        }));


        super.setBatchLimit(defaultBatchLimit);

        selectWordSet.add("WITH");
    }

    @Override
    public boolean supportsRandomAccessResultSet(Select sel,
        boolean forUpdate) {
        return !forUpdate
            && super.supportsRandomAccessResultSet(sel, forUpdate);
    }

    @Override
    protected void appendSelectRange(SQLBuffer buf, long start, long end,
        boolean subselect) {
        // appends the literal range string, since DB2 is unable to handle
        // a bound parameter for it
        // do not generate FETCH FIRST clause for subselect
        if (!subselect)
            buf.append(" FETCH FIRST ").append(Long.toString(end)).
                append(" ROWS ONLY");
    }

    @Override
    protected void appendSelect(SQLBuffer selectSQL, Object alias, Select sel,
        int idx) {
        // if this is a literal value, add a cast...
        Object val = sel.getSelects().get(idx);
        boolean toCast = (val instanceof Lit) &&
            ((Lit)val).getParseType() != Literal.TYPE_DATE &&
            ((Lit)val).getParseType() != Literal.TYPE_TIME &&
            ((Lit)val).getParseType() != Literal.TYPE_TIMESTAMP;

        if (toCast)
            selectSQL.append("CAST(");

        // ... and add the select per super's behavior...
        super.appendSelect(selectSQL, alias, sel, idx);

        // ... and finish the cast
        if (toCast) {
            Class<?> c = ((Lit) val).getType();
            int javaTypeCode = JavaTypes.getTypeCode(c);
            int jdbcTypeCode = getJDBCType(javaTypeCode, false);
            String typeName = getTypeName(jdbcTypeCode);
            selectSQL.append(" AS " + typeName);

            // if the literal is a string, use the default char col size
            // in the cast statement.
            if (String.class.equals(c))
                selectSQL.append("(" + getCastStringColumnSize(val) + ")");

            selectSQL.append(")");
        }
    }

    @Override
    protected String getSequencesSQL(String schemaName, String sequenceName) {
        return getSequencesSQL(DBIdentifier.newSchema(schemaName),
            DBIdentifier.newSequence(sequenceName));
    }

    @Override
    protected String getSequencesSQL(DBIdentifier schemaName, DBIdentifier sequenceName) {
        StringBuilder buf = new StringBuilder();
        buf.append(sequenceSQL);
        if (!DBIdentifier.isNull(schemaName) || !DBIdentifier.isNull(sequenceName))
            buf.append(" WHERE ");
        if (!DBIdentifier.isNull(schemaName)) {
            buf.append(sequenceSchemaSQL);
            if (!DBIdentifier.isNull(sequenceName))
                buf.append(" AND ");
        }
        if (!DBIdentifier.isNull(sequenceName))
            buf.append(sequenceNameSQL);
        return buf.toString();
    }

    @Override
    public Connection decorate(Connection conn)
        throws SQLException {
        // some versions of the DB2 driver seem to default to
        // READ_UNCOMMITTED, which will prevent locking from working
        // (multiple SELECT ... FOR UPDATE statements are allowed on
        // the same instance); if we have not overridden the
        // transaction isolation in the configuration, default to
        // TRANSACTION_READ_COMMITTED
        conn = super.decorate(conn);

        if (conf.getTransactionIsolationConstant() == -1 &&
                conn.getTransactionIsolation() <
                Connection.TRANSACTION_READ_COMMITTED)
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

        return conn;
    }

    @Override
    public void connectedConfiguration(Connection conn) throws SQLException {
        super.connectedConfiguration(conn);

        DatabaseMetaData metaData = conn.getMetaData();

        String driverName = metaData.getDriverName();
        if (driverName != null && driverName.startsWith("IBM DB2"))
            driverVendor = VENDOR_IBM;
        else
            driverVendor = VENDOR_OTHER;


        // Determine the type of DB2 database
        // First check for AS/400
        getProductVersionMajorMinorForISeries();

        if (versionLaterThan(0)) {
            if (isDB2ISeriesV5R3OrEarlier())
                db2ServerType = db2ISeriesV5R3OrEarlier;
            else if (isDB2ISeriesV5R4OrLater())
                db2ServerType = db2ISeriesV5R4OrLater;
        }

        if (db2ServerType == 0) {
            if (isJDBC3) {
                setMajorVersion(metaData.getDatabaseMajorVersion());
                setMinorVersion(metaData.getDatabaseMinorVersion());
            }
            else
                getProductVersionMajorMinor();

            // Determine the type of DB2 database for ZOS & UDB
            if (isDB2UDBV81OrEarlier())
                db2ServerType = db2UDBV81OrEarlier;
            else if (isDB2ZOSV8xOrLater())
                db2ServerType = db2ZOSV8xOrLater;
            else if (isDB2UDBV82OrLater())
                db2ServerType = db2UDBV82OrLater;
        }

        // verify that database product is supported
        if (db2ServerType == 0 || getMajorVersion() < 0)
            throw new UnsupportedException(_loc.get("db-not-supported",
                new Object[] {databaseProductName, databaseProductVersion }));
        if (versionEqualOrLaterThan(9, 2)) {
            supportsLockingWithMultipleTables = true;
            supportsLockingWithInnerJoin = true;
            supportsLockingWithOuterJoin = true;
            forUpdateClause = "WITH RR USE AND KEEP UPDATE LOCKS";

            supportsXMLColumn = versionEqualOrLaterThan(9, 0);

        }

        // platform specific settings
        switch (db2ServerType) {
        case db2UDBV82OrLater:
            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM " + SYSDUMMY;
            break;
        case  db2ZOSV8xOrLater:
            // DB2 Z/OS
            characterColumnSize = 255;
            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM " + SYSDUMMY;
            nextSequenceQuery = "SELECT NEXTVAL FOR {0} FROM " + SYSDUMMY;
            // allow users to set a non default sequenceSQL.
            if (defaultSequenceSQL.equals(sequenceSQL)){
	            sequenceSQL = "SELECT SCHEMA AS SEQUENCE_SCHEMA, "
	                + "NAME AS SEQUENCE_NAME FROM SYSIBM.SYSSEQUENCES";

                if (log.isTraceEnabled())
                    log.trace(_loc.get("sequencesql-override", new Object[] {defaultSequenceSQL, sequenceSQL}));
            }
            sequenceSchemaSQL = "SCHEMA = ?";
            sequenceNameSQL = "NAME = ?";
            if (getMajorVersion() == 8) {
                // DB2 Z/OS Version 8: no bigint support, hence map Java
                // long to decimal
                bigintTypeName = "DECIMAL(31,0)";
            }
            break;
        case db2ISeriesV5R3OrEarlier:
        case db2ISeriesV5R4OrLater:
            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM " + SYSDUMMY;
            nextSequenceQuery = "SELECT NEXTVAL FOR {0} FROM " + SYSDUMMY;
            validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM "
                + "QSYS2.SYSTABLES";
            // allow users to set a non default sequenceSQL.
            if (defaultSequenceSQL.equals(sequenceSQL)){
	            sequenceSQL = "SELECT SEQUENCE_SCHEMA, "
	                + "SEQUENCE_NAME FROM QSYS2.SYSSEQUENCES";

                if (log.isTraceEnabled())
                    log.trace(_loc.get("sequencesql-override", new Object[] {defaultSequenceSQL, sequenceSQL}));
            }
            sequenceSchemaSQL = "SEQUENCE_SCHEMA = ?";
            sequenceNameSQL = "SEQUENCE_NAME = ?";
            // V5R4 and earlier systems do not support retrieval of generated keys
            if (isDB2ISeriesV5R4OrEarlier()) {
            	supportsGetGeneratedKeys = false;
            }

            break;
        }
    }


    @Override
    public boolean supportsIsolationForUpdate() {
        return true;
    }

    /**
     * Get the update clause for the query based on the
     * isolationLevel hints if it is for update.
     * It also handles the UR hint when it is not for update.
     */
    @Override
    protected String getForUpdateClause(JDBCFetchConfiguration fetch,
        boolean isForUpdate, Select sel) {
        int isolationLevel;
        // For db2UDBV81OrEarlier and db2ISeriesV5R3OrEarlier:
        // "optimize for" clause appears before "for update" clause.
        StringBuilder forUpdateString = new StringBuilder(getOptimizeClause(sel));
        // Determine the isolationLevel; the fetch
        // configuration data overrides the persistence.xml value
        if (fetch != null && fetch.getIsolation() != -1)
            isolationLevel = fetch.getIsolation();
        else
            isolationLevel = conf.getTransactionIsolationConstant();

        if (fetch != null && fetch.getReadLockLevel() >=
            MixedLockLevels.LOCK_PESSIMISTIC_WRITE)
            isolationLevel = Connection.TRANSACTION_SERIALIZABLE;

        if (isForUpdate) {
            switch (db2ServerType) {
            case db2ISeriesV5R3OrEarlier:
            case db2UDBV81OrEarlier:
                if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE)
                    forUpdateString.append(" ").append(forUpdateClause);
                else
                    forUpdateString.append(" ").append(forUpdate).append(" ")
                        .append(withRSClause);
                break;
            case db2ZOSV8xOrLater:
            case db2UDBV82OrLater:
                if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
                    forUpdateString.append(" ").append(forReadOnlyClause)
                        .append(" ").append(withRRClause).append(" ").append(
                            useKeepUpdateLockClause);
                } else {
                    forUpdateString.append(" ").append(forReadOnlyClause)
                        .append(" ").append(withRSClause).append(" ").append(
                            useKeepUpdateLockClause);
                }
                break;
            case db2ISeriesV5R4OrLater:
                if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
                    forUpdateString.append(" ").append(forReadOnlyClause)
                        .append(" ").append(withRRClause).append(" ").append(
                            useKeepExclusiveLockClause);
                } else {
                    forUpdateString.append(" ").append(forReadOnlyClause)
                        .append(" ").append(withRSClause).append(" ").append(
                            useKeepExclusiveLockClause);
                }
                break;
            }
        } else {
        	if ( fetch != null && fetch.getIsolation() == Connection.TRANSACTION_READ_UNCOMMITTED
        			&& sel != null && sel.getParent() == null) { // i.e. not a subquery
	            forUpdateString.append(" ").append(forReadOnlyClause)
	            .append(" ").append(withURClause);
	    	}
        }

        return forUpdateString.toString();
    }

    public boolean isDB2UDBV82OrLater() {
        return (databaseProductVersion.indexOf("SQL") != -1
             || databaseProductName.indexOf("DB2/") != -1)
             && versionEqualOrLaterThan(8, 2);
    }

    public boolean isDB2ZOSV8xOrLater() {
       return (databaseProductVersion.indexOf("DSN") != -1
            || databaseProductName.indexOf("DB2/") == -1)
            && versionLaterThan(7);
    }

    public boolean isDB2ISeriesV5R3OrEarlier() {
       return databaseProductName.indexOf("AS") != -1
           && versionEqualOrEarlierThan(5, 3);
    }

    public boolean isDB2ISeriesV5R4OrLater() {
       return databaseProductName.indexOf("AS") != -1
           && versionEqualOrLaterThan(5, 4);
    }

    public boolean isDB2ISeriesV5R4OrEarlier() {
        return databaseProductName.indexOf("AS") != -1
            && versionEqualOrEarlierThan(5, 4);
     }

    public boolean isDB2UDBV81OrEarlier() {
        return (databaseProductVersion.indexOf("SQL") != -1
            || databaseProductName.indexOf("DB2/") != -1)
            && versionEqualOrEarlierThan(8,1);
    }

    /** Get the version Major/Minor for the ISeries
     */
    private void getProductVersionMajorMinorForISeries() {
        // ISeries    DBProdName                 DB2 UDB for AS/400
        //   (Toolbox)DBProdVersion              05.04.0000 V5R4m0
        // ISeries                               DB2 UDB for AS/400
        //   (Native)                            V5R4M0
        // new jcc    DBProdVersion              QSQ05040 or QSQ06010
        if (databaseProductName.indexOf("AS") != -1) {
            // default to V5R4
            setMajorVersion(5);
            setMinorVersion(4);
            int index = databaseProductVersion.indexOf('V');
            if (index != -1) {
                String s = databaseProductVersion.substring(index);
                s = s.toUpperCase(Locale.ENGLISH);

                StringTokenizer stringtokenizer = new StringTokenizer(s, "VRM"
                    , false);
                if (stringtokenizer.countTokens() == 3) {
                    String s1 = stringtokenizer.nextToken();
                    setMajorVersion(Integer.parseInt(s1));
                    String s2 =  stringtokenizer.nextToken();
                    setMinorVersion(Integer.parseInt(s2));
                }
            } else {
                index = databaseProductVersion.indexOf('0');
                if (index != -1) {
                    String s = databaseProductVersion.substring(index);
                    s = s.toUpperCase(Locale.ENGLISH);

                    StringTokenizer stringtokenizer = new StringTokenizer(s, "0"
                        , false);
                    if (stringtokenizer.countTokens() == 2) {
                        String s1 = stringtokenizer.nextToken();
                        setMajorVersion(Integer.parseInt(s1));
                        String s2 =  stringtokenizer.nextToken();
                        setMinorVersion(Integer.parseInt(s2));
                    }
                }
            }
        }
    }

    private void getProductVersionMajorMinor() {
        // In case JDBC driver version is lower than 3
        // use following info to determine Major and Minor
        //                        CLI    vs      JCC
        // ZDBV8 DBProdName       DB2            DB2
        //       DBProdVersion    08.01.0005     DSN08015
        // ZDBV9                  DB2            DB2
        //                        09.01.0005     DSN09015
        // WinV9                  DB2/NT         DB2/NT
        //                        09.01.0000     SQL09010
        // SolarisV9                             DB2/SUN64
        //                                       SQL0901
        // Linux                  DB2/LINUX      DB2/LINUX
        //                        09.01.0000     SQL0901
        if (databaseProductVersion.indexOf("09") != -1) {
            setMajorVersion(9);
            if (databaseProductVersion.indexOf("01") != -1) {
                setMinorVersion(1);
            }
        } else if (databaseProductVersion.indexOf("08") != -1) {
        	setMajorVersion(8);
        	setMinorVersion(2);
            if (databaseProductVersion.indexOf("01") != -1) {
            	setMinorVersion(1);
            }
        }
    }

    protected String getOptimizeClause(Select sel) {
        if (sel != null && sel.getExpectedResultCount() > 0) {
            StringBuilder buf = new StringBuilder();
            buf.append(" ").append(optimizeClause).append(" ")
                .append(String.valueOf(sel.getExpectedResultCount()))
                .append(" ").append(rowClause);
            return buf.toString();
        }

        return "";
    }

    @Override
    public OpenJPAException newStoreException(String msg, SQLException[] causes, Object failed) {
        if (appendExtendedExceptionText == true && causes != null && causes.length > 0) {
            msg = appendExtendedExceptionMsg(msg, causes[0]);
        }
        return super.newStoreException(msg, causes, failed);
    }

    /**
     *  Append exception information from SQLCA to the existing
     *  exception message
     */
    private String appendExtendedExceptionMsg(String msg, SQLException sqle){
       final String GETSQLCA ="getSqlca";
       try {
            Method sqlcaM2 = sqle.getNextException().getClass()
                             .getMethod(GETSQLCA,null);
            Object sqlca = sqlcaM2.invoke(sqle.getNextException(),
                                          new Object[] {});
            Method  getSqlErrpMethd = sqlca.getClass().
            getMethod("getSqlErrp", null);
            Method  getSqlWarnMethd = sqlca.getClass().
            getMethod("getSqlWarn", null);
            Method  getSqlErrdMethd = sqlca.getClass().
            getMethod("getSqlErrd", null);
            StringBuilder errdStr = new StringBuilder();

            int[] errds = (int[]) getSqlErrdMethd.invoke(sqlca, new Object[]{});
            for (int i = 0; i < errds.length; i++)
                errdStr.append(errdStr.length() > 0 ? ", " : "").
                    append(errds[i]);
            StringBuilder exceptionMsg = new StringBuilder();
            exceptionMsg.append("SQLCA OUTPUT");
            exceptionMsg.append("[Errp=");
            exceptionMsg.append(getSqlErrpMethd.invoke(sqlca, new Object[]{}));
            exceptionMsg.append(", Errd=");
            exceptionMsg.append(errdStr);

            String Warn = new String((char[]) getSqlWarnMethd.
                    invoke(sqlca, new Object[]{}));
            if (Warn.trim().length() != 0) {
                exceptionMsg.append(", Warn=");
                exceptionMsg.append(Warn);
                exceptionMsg.append("]");
            } else {
                exceptionMsg.append("]");
            }
            msg = msg.concat(exceptionMsg.toString());

            // for batched execution failures, SQLExceptions are nested
            SQLException sqle2 = sqle.getNextException();
            while (sqle2 != null) {
                msg = msg.concat("\n" + sqle2.getMessage());
                sqle2 = sqle2.getNextException();
            }

            return msg;
        } catch (Throwable t) {
            return sqle.getMessage();
        }
    }

    public int getDb2ServerType() {
        return db2ServerType;
    }

    @Override
    protected void appendLength(SQLBuffer buf, int type) {
        if (type == Types.VARCHAR)
            buf.append("(").append(Integer.toString(characterColumnSize)).
                append(")");
    }

    /**
     * If this dictionary supports XML type,
     * use this method to append xml predicate.
     *
     * @param buf the SQL buffer to write the comparison
     * @param op the comparison operation to perform
     * @param lhs the left hand side of the comparison
     * @param rhs the right hand side of the comparison
     * @param lhsxml indicates whether the left operand maps to xml
     * @param rhsxml indicates whether the right operand maps to xml
     */
    @Override
    public void appendXmlComparison(SQLBuffer buf, String op, FilterValue lhs,
        FilterValue rhs, boolean lhsxml, boolean rhsxml) {
        super.appendXmlComparison(buf, op, lhs, rhs, lhsxml, rhsxml);
        if (lhsxml && rhsxml)
            appendXmlComparison2(buf, op, lhs, rhs);
        else if (lhsxml)
            appendXmlComparison1(buf, op, lhs, rhs);
        else
            appendXmlComparison1(buf, op, rhs, lhs);
    }

    /**
     * Append an xml comparison predicate.
     *
     * @param buf the SQL buffer to write the comparison
     * @param op the comparison operation to perform
     * @param lhs the left hand side of the comparison (maps to xml column)
     * @param rhs the right hand side of the comparison
     */
    private void appendXmlComparison1(SQLBuffer buf, String op,
            FilterValue lhs, FilterValue rhs) {
        boolean castrhs = false;
        Class<?> rc = Filters.wrap(rhs.getType());
        int type = 0;
        if (rhs.isConstant()) {
            type = getJDBCType(JavaTypes.getTypeCode(rc), false);
            castrhs = true;
        }

        appendXmlExists(buf, lhs);

        buf.append(" ").append(op).append(" ");

        buf.append("$");
        if (castrhs)
            buf.append("Parm");
        else
            rhs.appendTo(buf);

        buf.append("]' PASSING ");
        appendXmlVar(buf, lhs);
        buf.append(", ");

        if (castrhs)
            appendCast(buf, rhs, type);
        else
            rhs.appendTo(buf);

        buf.append(" AS \"");
        if (castrhs)
            buf.append("Parm");
        else
            rhs.appendTo(buf);
        buf.append("\")");
    }

    /**
     * Append an xml comparison predicate. (both operands map to xml column)
     *
     * @param buf the SQL buffer to write the comparison
     * @param op the comparison operation to perform
     * @param lhs the left hand side of the comparison (maps to xml column)
     * @param rhs the right hand side of the comparison (maps to xml column)
     */
    private void appendXmlComparison2(SQLBuffer buf, String op,
            FilterValue lhs, FilterValue rhs) {
        appendXmlExists(buf, lhs);

        buf.append(" ").append(op).append(" ");

        buf.append("$").append(rhs.getColumnAlias(
            rhs.getFieldMapping().getColumns()[0])).
            append("/*/");
        rhs.appendTo(buf);

        buf.append("]' PASSING ");
        appendXmlVar(buf, lhs);
        buf.append(", ");
        appendXmlVar(buf, rhs);
        buf.append(")");
    }

    private void appendXmlVar(SQLBuffer buf, FilterValue val) {
        buf.append(val.getColumnAlias(
            val.getFieldMapping().getColumns()[0])).
            append(" AS ").
            append("\"").append(val.getColumnAlias(
            val.getFieldMapping().getColumns()[0])).
            append("\"");
    }

    private void appendXmlExists(SQLBuffer buf, FilterValue val) {
        buf.append("XMLEXISTS('");
        buf.append("$").append(val.getColumnAlias(
            val.getFieldMapping().getColumns()[0])).
            append("/*[");
        val.appendTo(buf);
    }

    /**
     * add CAST for a scalar function where operand is a param
     *
     * @param func original string
     * @param target substring to look for
     * @param asString
     * @return updated string (func)
     */
    private String addCastAsString(String func, String target,
            String asString) {
        String fstring = func;
        if (func.indexOf(target) != -1) {
            fstring = StringUtil.replace(func, target, "CAST(" + target + asString + ")");
        }
        return fstring;
    }

    /**
     * add CAST for a function operator where operand is a param
     *
     * @param func function name
     * @param val type
     * @return updated string (func)
     */
    @Override
    public String addCastAsType(String func, Val val) {
        String fstring = null;
        String type = getTypeName(getJDBCType(JavaTypes.getTypeCode(val
            .getType()), false));
        if (String.class.equals(val.getType()))
            type = type + "(" + getCastStringColumnSize(val) + ")";
        fstring = "CAST(? AS " + type + ")";
        return fstring;
    }

    /**
     * Return the batch limit. If the batchLimit is -1, change it to 100 for
     * best performance
     */
    @Override
    public int getBatchLimit() {
        int limit = super.getBatchLimit();
        if (limit == UNLIMITED) {
            limit = defaultBatchLimit;
            if (log.isTraceEnabled())
                log.trace(_loc.get("batch_unlimit", String.valueOf(limit)));
        }
        return limit;
    }

    /**
     * Return the correct CAST function syntax
     *
     * @param val operand of cast
     * @param func original string
     * @return a String with the correct CAST function syntax
     */
    @Override
    public String getCastFunction(Val val, String func) {
        if (val instanceof Lit || val instanceof Param) {
            if (func.indexOf("VARCHAR") == -1) {
                func = addCastAsString(func, "{0}", " AS VARCHAR(" + varcharCastLength + ")");
            }
        }
        return func;
    }

    /**
     * Return the correct CAST function syntax
     *
     * @param val operand of cast
     * @param func original string
     * @param col database column
     * @return a String with the correct CAST function syntax
     */
    @Override
    public String getCastFunction(Val val, String func, Column col) {
        boolean doCast = false;
        if (val instanceof Lit || val instanceof Param) {
            doCast = true;
        }
        // cast anything not already a VARCHAR to VARCHAR
        if (col.getType() != Types.VARCHAR) {
            doCast = true;
        }
        if (doCast == true) {
            if (func.indexOf("VARCHAR") == -1) {
                func = addCastAsString(func, "{0}", " AS VARCHAR(" + varcharCastLength + ")");
            }
        }
        return func;
    }

    @Override
    public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
            FilterValue start) {
        if (find.getValue() != null) { // non constants
            buf.append("LOCATE(CAST((");
            find.appendTo(buf);
            buf.append(") AS VARCHAR(1000)), ");
        } else {
            // this is a constant
            buf.append("LOCATE(");
            find.appendTo(buf);
            buf.append(", ");
        }
        if (str.getValue() != null) {
            buf.append("CAST((");
            str.appendTo(buf);
            buf.append(") AS VARCHAR(1000))");
        } else {
            str.appendTo(buf);
        }
        if (start != null) {
            if (start.getValue() != null) {
                buf.append(", CAST((");
                start.appendTo(buf);
                buf.append(") AS INTEGER)");
            } else {
                buf.append(", ");
                start.appendTo(buf);
            }
        }
        buf.append(")");
    }

    /**
     * Cast the specified value to the specified type.
     *
     * @param buf the buffer to append the cast to
     * @param val the value to cast
     * @param type the type of the case, e.g. {@link Types#NUMERIC}
     */
    public void appendCast(SQLBuffer buf, FilterValue val, int type) {

        // Convert the cast function: "CAST({0} AS {1})"
        int firstParam = castFunction.indexOf("{0}");
        String pre = castFunction.substring(0, firstParam); // "CAST("
        String mid = castFunction.substring(firstParam + 3);
        int secondParam = mid.indexOf("{1}");
        String post;
        if (secondParam > -1) {
            post = mid.substring(secondParam + 3); // ")"
            mid = mid.substring(0, secondParam); // " AS "
        } else
            post = "";

        // No need to add CAST if the value is a constant
        if (val instanceof Lit || val instanceof Param) {
            buf.append(pre);
            val.appendTo(buf);
            buf.append(mid);
            buf.append(getTypeName(type));
            appendLength(buf, type);
            buf.append(post);
        } else {
            val.appendTo(buf);
            String sqlString = buf.getSQL(false);
            if (sqlString.endsWith("?")) {
                // case "(?" - convert to "CAST(? AS type"
                String typeName = getTypeName(type);
                if (String.class.equals(val.getType()))
                    typeName = typeName + "(" + getCastStringColumnSize(val) + ")";
                String str = "CAST(? AS " + typeName + ")";
                buf.replaceSqlString(sqlString.length() - 1,
                        sqlString.length(), str);
            }
        }
    }

    /**
     * Create an index if necessary for some database tables
     */
    @Override
    public void createIndexIfNecessary(Schema schema, String table,
        Column pkColumn) {
        createIndexIfNecessary(schema, DBIdentifier.newTable(table),
            pkColumn);
    }

    @Override
    public void createIndexIfNecessary(Schema schema, DBIdentifier table,
            Column pkColumn) {
        if (db2ServerType == db2ZOSV8xOrLater) {
            // build the index for the sequence tables
            // the index name will be the fully qualified table name + _IDX
            Table tab = schema.getTable(table);
            DBIdentifier fullIdxId = tab.getFullIdentifier().clone();
            DBIdentifier unQualifiedName = DBIdentifier.append(fullIdxId.getUnqualifiedName(), "IDX");
            fullIdxId.setName(getValidIndexName(unQualifiedName, tab));
            Index idx = tab.addIndex(fullIdxId);
            idx.setUnique(true);
            idx.addColumn(pkColumn);
        }
    }

    @Override
    public boolean isFatalException(int subtype, SQLException ex) {
        String errorState = ex.getSQLState();
        int errorCode = ex.getErrorCode();
        if (errorCode == -952 && "57014".equals(errorState))
            return false;
        /*
         * Check if this Exception was generated by a lock timeout expiration.
         * The following criteria are used to determine this:
         *
         * DB2 LUW Infocenter: SQLSTATE=57033 with reason code "80" indicates
         * the statement failed due to timeout. DB2 for z/OS Stored Procedures:
         * Through the CALL and Beyond, page 188: An ErrorCode of -913 with
         * SQLERR 00C9008E means a timeout has occurred.
         */
        if (subtype == StoreException.LOCK && "57033".equals(errorState)
            && ((ex.getMessage().indexOf("80") != -1)
                || (errorCode == -913 && ex.getMessage().contains("00C9008E")))) {
            return false;
        }
        if ((subtype == StoreException.QUERY && "57014".equals(errorState) &&
            (errorCode == -952 || errorCode == -905))) {
            return false;
        }
        return super.isFatalException(subtype, ex);
    }

    @Override
    protected void setDelimitedCase(DatabaseMetaData metaData) {
        delimitedCase = SCHEMA_CASE_PRESERVE;
    }

    /**
     * The Type 2 JDBC Driver may throw an SQLException when provided a non-
     * zero timeout if we're connected to Z/OS. The SQLException should be
     * logged but not thrown.
     */
    @Override
    public void setQueryTimeout(PreparedStatement stmnt, int timeout)
        throws SQLException {
        if (db2ServerType == db2ZOSV8xOrLater) {
            try {
                super.setQueryTimeout(stmnt, timeout);
            }
            catch (SQLException e) {
                if (log.isTraceEnabled()) {
                    log.trace(_loc.get("error-setting-query-timeout", timeout,
                        e.getMessage()), e);
                }
            }
        }
        else {
            super.setQueryTimeout(stmnt, timeout);
        }
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    @Override
    public void setBytes(PreparedStatement stmnt, int idx, byte[] val,
        Column col)
        throws SQLException {
        // for DB2, if the column was defined as CHAR for BIT DATA, then
        // we want to use the setBytes in stead of the setBinaryStream
        if (useSetBytesForBlobs
                || (!DBIdentifier.isNull(col.getTypeIdentifier()) &&
                col.getTypeIdentifier().getName().contains("BIT DATA"))) {
            stmnt.setBytes(idx, val);
        } else {
            setBinaryStream(stmnt, idx, new ByteArrayInputStream(val), val.length, col);
        }
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    @Override
    public byte[] getBytes(ResultSet rs, int column)
        throws SQLException {
        if (useGetBytesForBlobs) {
            return rs.getBytes(column);
        }
        if (useGetObjectForBlobs) {
            return (byte[]) rs.getObject(column);
        }

        int type = rs.getMetaData().getColumnType(column);
        switch (type) {
            case Types.BLOB:
                Blob blob = getBlob(rs, column);
                if (blob == null) {
                    return null;
                }

                int length = (int) blob.length();
                if (length == 0) {
                    return null;
                }
                return blob.getBytes(1, length);
            case Types.BINARY:
            default:
                return rs.getBytes(column);
        }
    }

    private int getCastStringColumnSize(Object val) {
        int colSize = characterColumnSize;
        if (val instanceof Lit) {
            String literal = (String) ((Lit) val).getValue();
            if (literal != null) {
                int literalLen = literal.length();
                if (literalLen > characterColumnSize) {
                    colSize = literalLen;
                }
            }
        }
        return colSize;
    }

    @Override
    public void insertBlobForStreamingLoad(Row row, Column col,
            JDBCStore store, Object ob, Select sel) throws SQLException {
        if (ob != null) {
            row.setBinaryStream(col, (InputStream)ob, -1);
        } else {
            row.setNull(col);
        }
    }

    @Override
    public void insertClobForStreamingLoad(Row row, Column col, Object ob)
    throws SQLException {
        if (ob != null) {
            row.setCharacterStream(col, (Reader)ob, -1);
        } else {
            row.setNull(col);
        }
    }

    @Override
    public void updateBlob(Select sel, JDBCStore store, InputStream is)
        throws SQLException {
        //NO-OP
    }

    @Override
    public void updateClob(Select sel, JDBCStore store, Reader reader)
        throws SQLException {
        //NO-OP
    }

    /**
     * Set the given date value as a parameter to the statement.
     */
    @Override
    public void setDate(PreparedStatement stmnt, int idx, Date val, Column col)
        throws SQLException {
        // When column metadata is not available, DB2 on z/OS does not like the value produced
        // by the default dictionary - java.util.Date is converted to java.sql.Timestamp.
        if (db2ServerType == db2ZOSV8xOrLater) {
            if (col == null && val != null && "java.util.Date".equals(val.getClass().getName())) {
                setDate(stmnt, idx, new java.sql.Date(val.getTime()), null, col);
                return;
            }
        }
        super.setDate(stmnt, idx, val, col);
    }

    public int getDB2MajorVersion() {
        return getMajorVersion();
    }

    public int getDB2MinorVersion() {
        return getMinorVersion();
    }

    @Override
    public String getDefaultSchemaName()  {
        if (defaultSchemaName == null) {
            Connection conn = null;
            Statement stmnt = null;
            ResultSet rs = null;
            try {
                String str = "SELECT CURRENT SCHEMA FROM " + SYSDUMMY;
                conn = getConnection();
                if (conn != null) {
                    stmnt = conn.createStatement();
                    rs = stmnt.executeQuery(str);
                    if (rs.next()) {
                        String currSchema = rs.getString(1);
                        if (currSchema != null) {
                            setDefaultSchemaName(currSchema.trim());
                        }
                    }
                } else {
                    if (log.isTraceEnabled()) {
                        log.trace(_loc.get("can_not_get_current_schema", "Unable to obtain a datasource"));
                    }
                }
            } catch (SQLException e) {
                if (log.isTraceEnabled()) {
                    log.trace(_loc.get("can_not_get_current_schema", e.getMessage()));
                }
            } finally {
                if (rs != null) {
                    try {
                        rs.close();
                    } catch (SQLException se) {
                        // ignore
                    }
                }
                if (stmnt != null) {
                    try {
                        stmnt.close();
                    } catch (SQLException se) {
                        // ignore
                    }
                }
                if (conn != null) {
                    try {
                        conn.close();
                    }
                    catch(SQLException se) {
                        // ignore
                    }
                }
            }
        }
        return defaultSchemaName;
    }

    /**
     * Obtain a connection from the configuration. Tries to use the jta-data-source first but falls back on the
     * non-jta-data-source if no jta-data-source has been defined.
     *
     * In practice this method is only called by getDefaultSchemaName which in turn is only used by the schema tool.
     *
     * @throws SQLException If neither datasource is available.
     * @return A connection which may be used to obtain the default schema name.
     */
    private Connection getConnection() throws SQLException {
    	DataSource  ds = null;
    	try {
            // try to obtain a connection from the primary datasource
            ds = conf.getDataSource(null);
    	} catch (UserException uex) {
    	}
    	if (ds==null) {
        	try {
                // use datasource 2 if available
                ds = conf.getDataSource2(null);
        	} catch (UserException uex2) {
        	}
        }
        if (ds != null) {
            return ds.getConnection();
        }
        return null;
    }

    @Override
    protected SQLBuffer toSelect(SQLBuffer select, JDBCFetchConfiguration fetch,
        SQLBuffer tables, SQLBuffer where, SQLBuffer group,
        SQLBuffer having, SQLBuffer order,
        boolean distinct, boolean forUpdate, long start, long end,
        Select sel) {
    	if (!supportsRowNum) {
    		return super.toSelect(select, fetch, tables, where, group, having, order,
    		        distinct, forUpdate, start, end, sel);
    	}
        // if no range, use standard select
        if (!isUsingRange(start, end)) {
            return super.toSelect(select, fetch, tables, where, group, having,
                order, distinct, forUpdate, 0, Long.MAX_VALUE, sel);
        }

        // if no skip, ordering, or distinct can use rownum directly
        SQLBuffer buf = new SQLBuffer(this);
        if (!requiresSubselectForRange(start, end, distinct, order)) {
            if (where != null && !where.isEmpty())
                buf.append(where).append(" AND ");
            buf.append("ROWNUM <= ").appendValue(end);
            return super.toSelect(select, fetch, tables, buf, group, having,
                order, distinct, forUpdate, 0, Long.MAX_VALUE, sel);
        }

        // if there is ordering, skip, or distinct we have to use subselects
        SQLBuffer newsel = super.toSelect(select, fetch, tables, where,
            group, having, order, distinct, forUpdate, 0, Long.MAX_VALUE,
            sel);

        // if no skip, can use single nested subselect
        if (!isUsingOffset(start)) {
            buf.append(getSelectOperation(fetch) + " * FROM (");
            buf.append(newsel);
            buf.append(") WHERE ROWNUM <= ").appendValue(end);
            return buf;
        }

        // with a skip, we have to use a double-nested subselect to put
        // where conditions on the rownum
        buf.append(getSelectOperation(fetch))
           .append(" * FROM (SELECT r.*, ROWNUM RNUM FROM (");
        buf.append(newsel);
        buf.append(") r");
        if (isUsingLimit(end))
            buf.append(" WHERE ROWNUM <= ").appendValue(end);
        buf.append(") WHERE RNUM > ").appendValue(start);
        return buf;
    }

    /**
     * Return true if the select with the given parameters needs a
     * subselect to apply a range.
     */
    private boolean requiresSubselectForRange(long start, long end, boolean distinct, SQLBuffer order) {
    	if (!isUsingRange(start, end))
    		return false;
        return isUsingOffset(start) || distinct || isUsingOrderBy(order);
    }


}
