/*
 * 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.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;
import java.util.StringTokenizer;

import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
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.Sequence;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.kernel.Filters;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.UnsupportedException;

import serp.util.Strings;

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

    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 String databaseProductName = "";
    protected String databaseProductVersion = "";
    protected int maj = 0;
    protected int min = 0;
    
    private int defaultBatchLimit = 100;

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

        nextSequenceQuery = "VALUES NEXTVAL FOR {0}";

        sequenceSQL = "SELECT SEQSCHEMA AS SEQUENCE_SCHEMA, "
            + "SEQNAME AS SEQUENCE_NAME FROM SYSCAT.SEQUENCES";
        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 = new String(
                "SYSCAT,SYSIBM,SYSSTAT,SYSIBMADM,SYSTOOLS");
        maxConstraintNameLength = 18;
        maxIndexNameLength = 18;
        maxColumnNameLength = 30;
        supportsDeferredConstraints = false;
        supportsDefaultDeleteAction = false;
        supportsAlterTableWithDropColumn = 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",
            "DATA", "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",
            "TYPE", "UNDO", "UNTIL", "VALIDPROC", "VARIABLE", "VARIANT", "VCAT",
            "VOLUMES", "WHILE", "WLM", "YEARS",
        }));
        
        super.setBatchLimit(defaultBatchLimit);
        
        selectWordSet.add("WITH");
    }

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

    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");
    }

    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);
        if (val instanceof Lit)
            selectSQL.append("CAST(");

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

        // ... and finish the cast
        if (val instanceof Lit) {
            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("(" + characterColumnSize + ")");

            selectSQL.append(")");
        }
    }

    public String[] getCreateSequenceSQL(Sequence seq) {
        String[] sql = super.getCreateSequenceSQL(seq);
        if (seq.getAllocate() > 1)
            sql[0] += " CACHE " + seq.getAllocate();
        return sql;
    }

    protected String getSequencesSQL(String schemaName, String sequenceName) {
        StringBuffer buf = new StringBuffer();
        buf.append(sequenceSQL);
        if (schemaName != null || sequenceName != null)
            buf.append(" WHERE ");
        if (schemaName != null) {
            buf.append(sequenceSchemaSQL);
            if (sequenceName != null)
                buf.append(" AND ");
        }
        if (sequenceName != null)
            buf.append(sequenceNameSQL);
        return buf.toString();
    }

    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() < conn.TRANSACTION_READ_COMMITTED)
            conn.setTransactionIsolation(conn.TRANSACTION_READ_COMMITTED);

        return conn;
    }

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

    	DatabaseMetaData metaData = conn.getMetaData();
        databaseProductName = nullSafe(metaData.getDatabaseProductName());
        databaseProductVersion = nullSafe(metaData.getDatabaseProductVersion());
        
        // Determine the type of DB2 database
        // First check for AS/400
        getProductVersionMajorMinorForISeries();

        if (maj > 0) {
            if (isDB2ISeriesV5R3OrEarlier())
                db2ServerType = db2ISeriesV5R3OrEarlier;
            else if (isDB2ISeriesV5R4OrLater())
                db2ServerType = db2ISeriesV5R4OrLater;
        }
        
    	if (db2ServerType == 0) {
    	    if (isJDBC3) {
    	        maj = metaData.getDatabaseMajorVersion();
    	        min = 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 databae product is supported
        if (db2ServerType == 0 || maj == 0)
            throw new UnsupportedException(_loc.get("db-not-supported",
                new Object[] {databaseProductName, databaseProductVersion }));                    

    	if (maj >= 9 || (maj == 8 && min >= 2)) {
    	    supportsLockingWithMultipleTables = true;
    	    supportsLockingWithInnerJoin = true;
    	    supportsLockingWithOuterJoin = true;
    	    forUpdateClause = "WITH RR USE AND KEEP UPDATE LOCKS";
    	    if (maj >=9)
    	        supportsXMLColumn = true;
    	}

        // platform specific settings
        switch (db2ServerType) {
        case  db2ZOSV8xOrLater:
            // DB2 Z/OS 
            characterColumnSize = 255;
            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM "
                + "SYSIBM.SYSDUMMY1";
            nextSequenceQuery = "SELECT NEXTVAL FOR {0} FROM "
                + "SYSIBM.SYSDUMMY1";
            sequenceSQL = "SELECT SCHEMA AS SEQUENCE_SCHEMA, "
                + "NAME AS SEQUENCE_NAME FROM SYSIBM.SYSSEQUENCES";
            sequenceSchemaSQL = "SCHEMA = ?";
            sequenceNameSQL = "NAME = ?";
            if (maj == 8) {
                // DB2 Z/OS Version 8: no bigint support, hence map Java
                // long to decimal
                bigintTypeName = "DECIMAL(31,0)";
            }
            ignoreSQLExceptionOnSetQueryTimeout = true; 
            break;
        case db2ISeriesV5R3OrEarlier:
        case db2ISeriesV5R4OrLater:
            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM "
                + "SYSIBM.SYSDUMMY1";
            nextSequenceQuery = "SELECT NEXTVAL FOR {0} FROM "
                + "SYSIBM.SYSDUMMY1";
            validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM "
                + "QSYS2.SYSTABLES";
            sequenceSQL = "SELECT SEQUENCE_SCHEMA, "
                + "SEQUENCE_NAME FROM QSYS2.SYSSEQUENCES";
            sequenceSchemaSQL = "SEQUENCE_SCHEMA = ?";
            sequenceNameSQL = "SEQUENCE_NAME = ?";
            break;
        }
    }

    /**
     * Get the update clause for the query based on the
     * updateClause and isolationLevel hints
     */
    protected String getForUpdateClause(JDBCFetchConfiguration fetch,
        boolean isForUpdate, Select sel) {
        int isolationLevel;
        // For db2UDBV81OrEarlier and db2ISeriesV5R3OrEarlier:
        // "optimize for" clause appears before "for update" clause.
        StringBuffer forUpdateString = new StringBuffer(
            getOptimizeClause(sel));
        try {
            // 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 (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;
                }
            }
        }
        catch (Exception e) {
            if (log.isTraceEnabled())
                log.error(e.toString(),e);
        }
        return forUpdateString.toString();
    }

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

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

    public boolean isDB2ISeriesV5R3OrEarlier() {
       return (databaseProductName.indexOf("AS") != -1
           && ((maj == 5 && min <=3) || maj < 5));
    }

    public boolean isDB2ISeriesV5R4OrLater() {
       return databaseProductName.indexOf("AS") != -1
           && (maj >=6 || (maj == 5 && min >=4));
    }

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

    /** 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
            maj = 5;
            min = 4;
            int index = databaseProductVersion.indexOf('V');
            if (index != -1) {
                String s = databaseProductVersion.substring(index);
                s = s.toUpperCase();

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

                    StringTokenizer stringtokenizer = new StringTokenizer(s, "0"
                        , false);                    
                    if (stringtokenizer.countTokens() == 2) {
                        String s1 = stringtokenizer.nextToken();
                        maj = Integer.parseInt(s1);
                        String s2 =  stringtokenizer.nextToken();
                        min = Integer.parseInt(s2);
                    }
                }
            }
        }
    }
    
    private void getProductVersionMajorMinor() {
        // Incase 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) {
            maj = 9;
            if (databaseProductVersion.indexOf("01") != -1) {
                min = 1;
            }
        } else if (databaseProductVersion.indexOf("08") != -1) {
            maj = 8;
            min = 2;
            if (databaseProductVersion.indexOf("01") != -1) {
                min = 1;
            }
        }
    }

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

        return "";
    }

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

    /**
     *  Append exception information from SQLCA to the exsisting
     *  exception meassage
     */
    private String appendExtendedExceptionMsg(String msg, SQLException sqle){
       final String GETSQLCA ="getSqlca";
       String exceptionMsg = new String();
       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);
            StringBuffer errdStr = new StringBuffer();

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

            String Warn = new String((char[]) getSqlWarnMethd.
                    invoke(sqlca, new Object[]{}));
            if (Warn.trim().length() != 0)
                exceptionMsg = exceptionMsg.concat(", Warn=" +Warn + "]" );
            else
                exceptionMsg = exceptionMsg.concat( "]" );
            msg = msg.concat(exceptionMsg);
            
            // 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;
    }
    
    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
     */
    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 = Strings.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)
     */
    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 + "(" + characterColumnSize + ")";
        fstring = "CAST(? AS " + type + ")";
        return fstring;
    }

    /**
     * Return the batch limit. If the batchLimit is -1, change it to 100 for
     * best performance
     */
    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
     */
    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
     */
    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;
    }

    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) + 1");
            } else {
                buf.append(", ");
                start.appendTo(buf);
            }
        }
        buf.append(") - 1)");
    }
    
    /** 
     * 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 + "(" + characterColumnSize + ")";
                String str = "CAST(? AS " + typeName + ")";
                buf.replaceSqlString(sqlString.length() - 1,
                        sqlString.length(), str);
            }
        }
    }

    /**
     * Create an index if necessary for some database tables
     */
    public void createIndexIfNecessary(Schema schema, String table,
            Column pkColumn) {
        if (isDB2ZOSV8xOrLater()) {
            // build the index for the sequence tables
            // the index name will the fully qualified table name + _IDX
            Table tab = schema.getTable(table);
            Index idx = tab.addIndex(tab.getFullName() + "_IDX");
            idx.setUnique(true);
            idx.addColumn(pkColumn);
        }
    }
    
    String nullSafe(String s) {
    	return s == null ? "" : s;
    }
}
