/*
 * 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.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.CharArrayReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.sql.DataSource;

import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.ColumnDefIdentifierRule;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.jdbc.identifier.DBIdentifierRule;
import org.apache.openjpa.jdbc.identifier.DBIdentifierUtil;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.kernel.exps.ExpContext;
import org.apache.openjpa.jdbc.kernel.exps.ExpState;
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
import org.apache.openjpa.jdbc.kernel.exps.Null;
import org.apache.openjpa.jdbc.kernel.exps.Val;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.DataSourceFactory;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.schema.ForeignKey.FKMapKey;
import org.apache.openjpa.jdbc.schema.Index;
import org.apache.openjpa.jdbc.schema.NameSet;
import org.apache.openjpa.jdbc.schema.PrimaryKey;
import org.apache.openjpa.jdbc.schema.Schema;
import org.apache.openjpa.jdbc.schema.SchemaGroup;
import org.apache.openjpa.jdbc.schema.Sequence;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.jdbc.schema.Unique;
import org.apache.openjpa.kernel.Filters;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.Seq;
import org.apache.openjpa.kernel.StateManagerImpl;
import org.apache.openjpa.kernel.exps.Path;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.identifier.IdentifierConfiguration;
import org.apache.openjpa.lib.identifier.IdentifierRule;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.jdbc.ConnectionDecorator;
import org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Localizer.Message;
import org.apache.openjpa.lib.util.StringUtil;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.ValueStrategies;
import org.apache.openjpa.util.ExceptionInfo;
import org.apache.openjpa.util.GeneralException;
import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.LockException;
import org.apache.openjpa.util.ObjectExistsException;
import org.apache.openjpa.util.ObjectNotFoundException;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.OptimisticException;
import org.apache.openjpa.util.ProxyManager;
import org.apache.openjpa.util.QueryException;
import org.apache.openjpa.util.ReferentialIntegrityException;
import org.apache.openjpa.util.Serialization;
import org.apache.openjpa.util.StoreException;
import org.apache.openjpa.util.UnsupportedException;
import org.apache.openjpa.util.UserException;


/**
 * Class which allows the creation of SQL dynamically, in a
 * database agnostic fashion. Subclass for the nuances of different data stores.
 */
public class DBDictionary
    implements Configurable, ConnectionDecorator, JoinSyntaxes,
    LoggingConnectionDecorator.SQLWarningHandler, IdentifierConfiguration {

    public static final String VENDOR_OTHER      = "other";
    public static final String VENDOR_DATADIRECT = "datadirect";

    public static final String SCHEMA_CASE_UPPER     = IdentifierUtil.CASE_UPPER;
    public static final String SCHEMA_CASE_LOWER     = IdentifierUtil.CASE_LOWER;
    public static final String SCHEMA_CASE_PRESERVE  = IdentifierUtil.CASE_PRESERVE;

    public static final String CONS_NAME_BEFORE = "before";
    public static final String CONS_NAME_MID    = "mid";
    public static final String CONS_NAME_AFTER  = "after";

    public int blobBufferSize = 50000;
    public int clobBufferSize = 50000;

    protected static final int RANGE_POST_SELECT   = 0;
    protected static final int RANGE_PRE_DISTINCT  = 1;
    protected static final int RANGE_POST_DISTINCT = 2;
    protected static final int RANGE_POST_LOCK     = 3;

    protected static final int NANO  = 1;
    protected static final int MICRO = NANO * 1000;
    protected static final int MILLI = MICRO * 1000;
    protected static final int CENTI = MILLI * 10;
    protected static final int DECI  = MILLI * 100;
    protected static final int SEC   = MILLI * 1000;

    protected static final int NAME_ANY      = DBIdentifierUtil.ANY;
    protected static final int NAME_TABLE    = DBIdentifierUtil.TABLE;
    protected static final int NAME_SEQUENCE = DBIdentifierUtil.SEQUENCE;

    protected static final int UNLIMITED = -1;
    protected static final int NO_BATCH = 0;

    private static final String ZERO_DATE_STR      = "'" + new java.sql.Date(0) + "'";
    private static final String ZERO_TIME_STR      = "'" + new Time(0) + "'";
    private static final String ZERO_TIMESTAMP_STR = "'" + new Timestamp(0) + "'";

    private static final Localizer _loc = Localizer.forPackage(DBDictionary.class);

    // Database version info preferably set from Connection metadata
    private int major;
    private int minor;

    // schema data
    public String platform = "Generic";
    public String databaseProductName = "";
    public String databaseProductVersion = "";
    public String driverVendor = null;
    public boolean createPrimaryKeys = true;
    public String constraintNameMode = CONS_NAME_BEFORE;
    public int maxTableNameLength = 128;
    public int maxColumnNameLength = 128;
    public int maxConstraintNameLength = 128;
    public int maxIndexNameLength = 128;
    public int maxIndexesPerTable = Integer.MAX_VALUE;
    public boolean supportsForeignKeys = true;
    public boolean supportsParameterInSelect = true;
    public boolean supportsForeignKeysComposite = true;
    public boolean supportsUniqueConstraints = true;
    public boolean supportsDeferredConstraints = true;
    public boolean supportsRestrictDeleteAction = true;
    public boolean supportsCascadeDeleteAction = true;
    public boolean supportsNullDeleteAction = true;
    public boolean supportsNullUniqueColumn = true;
    public boolean supportsDefaultDeleteAction = true;
    public boolean supportsRestrictUpdateAction = true;
    public boolean supportsCascadeUpdateAction = true;
    public boolean supportsNullUpdateAction = true;
    public boolean supportsDefaultUpdateAction = true;
    public boolean supportsAlterTableWithAddColumn = true;
    public boolean supportsAlterTableWithDropColumn = true;
    public boolean supportsComments = false;
    public Boolean supportsGetGeneratedKeys = null;
    public String reservedWords = null;
    public String systemSchemas = null;
    public String systemTables = null;
    public String selectWords = null;
    public String fixedSizeTypeNames = null;
    public String schemaCase = SCHEMA_CASE_UPPER;
    public boolean setStringRightTruncationOn = true;
    public boolean fullResultCollectionInOrderByRelation = false;
    public boolean disableSchemaFactoryColumnTypeErrors = false; //OPENJPA-2627

    // sql
    public boolean disableAlterSeqenceIncrementBy=false;
    public String validationSQL = null;
    public String closePoolSQL = null;
    public String initializationSQL = null;
    public int joinSyntax = SYNTAX_SQL92;
    public String outerJoinClause = "LEFT OUTER JOIN";
    public String innerJoinClause = "INNER JOIN";
    public String crossJoinClause = "CROSS JOIN";
    public boolean requiresConditionForCrossJoin = false;
    public String forUpdateClause = "FOR UPDATE";
    public String tableForUpdateClause = null;
    public String distinctCountColumnSeparator = null;
    public boolean supportsSelectForUpdate = true;
    public boolean supportsLockingWithDistinctClause = true;
    public boolean supportsLockingWithMultipleTables = true;
    public boolean supportsLockingWithOrderClause = true;
    public boolean supportsLockingWithOuterJoin = true;
    public boolean supportsLockingWithInnerJoin = true;
    public boolean supportsLockingWithSelectRange = true;
    public boolean supportsQueryTimeout = true;
    public boolean allowQueryTimeoutOnFindUpdate = false; //OPENJPA-2517
    public boolean simulateLocking = false;
    public boolean supportsSubselect = true;
    public boolean supportsCorrelatedSubselect = true;
    public boolean supportsHaving = true;
    public boolean supportsSelectStartIndex = false;
    public boolean supportsSelectEndIndex = false;
    public int rangePosition = RANGE_POST_SELECT;
    public boolean requiresAliasForSubselect = false;
    public boolean requiresTargetForDelete = false;
    public boolean allowsAliasInBulkClause = true;
    public boolean supportsMultipleNontransactionalResultSets = true;
    public boolean requiresSearchStringEscapeForLike = false;
    public String searchStringEscape = "\\";
    public boolean requiresCastForMathFunctions = false;
    public boolean requiresCastForComparisons = false;
    public boolean supportsModOperator = false;
    public boolean supportsXMLColumn = false;
    public boolean supportsCaseConversionForLob = false;
    public boolean reportsSuccessNoInfoOnBatchUpdates = false;
    public boolean supportsSelectFromFinalTable = false;
    public boolean supportsSimpleCaseExpression = true;
    public boolean supportsGeneralCaseExpression = true;
    public boolean useWildCardForCount = false;

    /**
     * Some Databases append whitespace after the schema name
     */
    public boolean trimSchemaName = false;

    // functions
    public String castFunction = "CAST({0} AS {1})";
    public String toLowerCaseFunction = "LOWER({0})";
    public String toUpperCaseFunction = "UPPER({0})";
    public String stringLengthFunction = "CHAR_LENGTH({0})";
    public String bitLengthFunction = "(OCTET_LENGTH({0}) * 8)";
    public String trimLeadingFunction = "TRIM(LEADING {1} FROM {0})";
    public String trimTrailingFunction = "TRIM(TRAILING {1} FROM {0})";
    public String trimBothFunction = "TRIM(BOTH {1} FROM {0})";
    public String concatenateFunction = "({0}||{1})";
    public String concatenateDelimiter = "'OPENJPATOKEN'";
    public String substringFunctionName = "SUBSTRING";
    public String currentDateFunction = "CURRENT_DATE";
    public String currentTimeFunction = "CURRENT_TIME";
    public String currentTimestampFunction = "CURRENT_TIMESTAMP";
    public String dropTableSQL = "DROP TABLE {0}";

    // types
    public boolean storageLimitationsFatal = false;
    public boolean storeLargeNumbersAsStrings = false;
    public boolean storeCharsAsNumbers = true;
    public boolean trimStringColumns = false;
    public boolean useGetBytesForBlobs = false;
    public boolean useSetBytesForBlobs = false;
    public boolean useGetObjectForBlobs = false;
    public boolean useGetStringForClobs = false;
    public boolean useSetStringForClobs = false;
    public boolean useJDBC4SetBinaryStream = true;//OPENJPA-2067
    public int maxEmbeddedBlobSize = -1;
    public int maxEmbeddedClobSize = -1;
    public int inClauseLimit = -1;
    public int datePrecision = MILLI;

    /**
     * @deprecated Use 'dateMillisecondBehavior' instead.
     */
    @Deprecated
    public boolean roundTimeToMillisec = true;

    /*
     * This defines how the milliseconds of a Date field are handled
     * when the Date is retrieved from the database, as follows:
     *
     * ROUND: This is the default.  The
     * Date will be rounded to the nearest millisecond.
     * DROP: The milliseconds will be dropped, thus rounding is not
     * performed.  As an example, a date of '2010-01-01 12:00:00.687701'
     * stored in the database will become '2010-01-01 12:00:00.000' in
     * the Date field of the entity.
     * RETAIN: The milliseconds will not be rounded and retained.  As an
     * example, a date of '2010-01-01 12:00:00.687701' stored in the
     * database will become '2010-01-01 12:00:00.687' in the Date field
     * of the entity.
     */
    public enum DateMillisecondBehaviors { DROP, ROUND, RETAIN };
    private DateMillisecondBehaviors dateMillisecondBehavior;

    /**
     * Defines how {@code Boolean} and {@code boolean} values get represented
     * in OpenJPA. Default to {@code INT_10}.
     * for backward compatibility.
     */
    protected BooleanRepresentation booleanRepresentation = BooleanRepresentationFactory.INT_10;

    public int characterColumnSize = 255;
    public String arrayTypeName = "ARRAY";
    public String bigintTypeName = "BIGINT";
    public String binaryTypeName = "BINARY";
    public String bitTypeName = "BIT";
    public String blobTypeName = "BLOB";
    public String booleanTypeName = "BOOLEAN";
    public String charTypeName = "CHAR";
    public String clobTypeName = "CLOB";
    public String dateTypeName = "DATE";
    public String decimalTypeName = "DECIMAL";
    public String distinctTypeName = "DISTINCT";
    public String doubleTypeName = "DOUBLE";
    public String floatTypeName = "FLOAT";
    public String integerTypeName = "INTEGER";
    public String javaObjectTypeName = "JAVA_OBJECT";
    public String longVarbinaryTypeName = "LONGVARBINARY";
    public String longVarcharTypeName = "LONGVARCHAR";
    public String nullTypeName = "NULL";
    public String numericTypeName = "NUMERIC";
    public String otherTypeName = "OTHER";
    public String realTypeName = "REAL";
    public String refTypeName = "REF";
    public String smallintTypeName = "SMALLINT";
    public String structTypeName = "STRUCT";
    public String timeTypeName = "TIME";
    public String timestampTypeName = "TIMESTAMP";
    public String timeWithZoneTypeName = "TIME WITH TIME ZONE";
    public String timestampWithZoneTypeName = "TIMESTAMP WITH TIME ZONE";
    public String tinyintTypeName = "TINYINT";
    public String varbinaryTypeName = "VARBINARY";
    public String varcharTypeName = "VARCHAR";
    public String xmlTypeName = "XML";
    public String xmlTypeEncoding = "UTF-8";
    public String getStringVal = "";

    // schema metadata
    public boolean useSchemaName = true;
    public String tableTypes = "TABLE";
    public boolean supportsSchemaForGetTables = true;
    public boolean supportsSchemaForGetColumns = true;
    public boolean supportsNullTableForGetColumns = true;
    public boolean supportsNullTableForGetPrimaryKeys = false;
    public boolean supportsNullTableForGetIndexInfo = false;
    public boolean supportsNullTableForGetImportedKeys = false;
    public boolean useGetBestRowIdentifierForPrimaryKeys = false;
    public boolean requiresAutoCommitForMetaData = false;
    public boolean tableLengthIncludesSchema = false;

    // auto-increment
    public int maxAutoAssignNameLength = 31;
    public String autoAssignClause = null;
    public String autoAssignTypeName = null;
    public boolean supportsAutoAssign = false;
    public String lastGeneratedKeyQuery = null;
    public String nextSequenceQuery = null;
    public String sequenceSQL = null;
    public String sequenceSchemaSQL = null;
    public String sequenceNameSQL = null;
    // most native sequences can be run inside the business transaction
    public int nativeSequenceType= Seq.TYPE_CONTIGUOUS;

    /**
     * This variable was used in 2.1.x and prior releases to indicate that
     * OpenJPA should not use the CACHE clause when getting a native
     * sequence; instead the INCREMENT BY clause gets its value equal to the
     * allocationSize property.  Post 2.1.x, code was added to allow
     * said functionality by default (see OPENJPA-1376).  For forward
     * compatibility, this variable should not be removed.
     */
    @Deprecated
    public boolean useNativeSequenceCache = true;

    /**
     * If a user sets the previous variable (useNativeSequenceCache) to false, we should log a
     * warning indicating that the variable no longer has an effect due to the code changes
     * of OPENJPA-1376.  We only want to log the warning once per instance, thus this
     * variable will be used to indicate if the warning should be printed or not.
     */
    @Deprecated
    private boolean logNativeSequenceCacheWarning = true;

    protected JDBCConfiguration conf = null;
    protected Log log = null;
    protected boolean connected = false;
    protected boolean isJDBC3 = false;
    protected boolean isJDBC4 = false;
    protected final Set<String> reservedWordSet = new HashSet<>();
    // reservedWordSet subset that CANNOT be used as valid column names
    // (i.e., without surrounding them with double-quotes)
    protected Set<String> invalidColumnWordSet = new HashSet<>();
    protected final Set<String> systemSchemaSet = new HashSet<>();
    protected final Set<String> systemTableSet = new HashSet<>();
    protected final Set<String> fixedSizeTypeNameSet = new HashSet<>();

    /**
     * set of types that might have an optional fraction (sub-second) part.
     * @{code @Column(scale=-1)} sets the fraction to zero.
     * @{code @Column(scale=0)} will use the default behaviour (no fraction information generated)
     */
    public final Set<String> fractionalTypeNameSet = new HashSet<>();

    /**
     * Default amount of digits for fractional Types.
     * This is not supported/required by every database.
     *
     * This value is only being used if no explicit {@code @Column(scale=n)} is set or n is zero.
     * Use {@code @Column(scale=-1)} to disable the explicit fraction part in the SQL generator.
     * @see #fractionalTypeNameSet
     * @see #getFractionLength(Column, String)
     */
    public int defaultFractionLength = 6;


    protected final Set<String> typeModifierSet = new HashSet<>();

    // NamingConfiguration properties
    private boolean delimitIdentifiers = false;
    public Boolean supportsDelimitedIdentifiers = null;
    public String leadingDelimiter = "\"";
    public String trailingDelimiter = "\"";
    public String nameConcatenator = "_";
    public String delimitedCase = SCHEMA_CASE_PRESERVE;
    public String catalogSeparator = ".";
    protected String defaultSchemaName = null;
    private String conversionKey = null;

    // Naming utility and naming rules
    private DBIdentifierUtil namingUtil = null;
    private Map<String, IdentifierRule> namingRules = new HashMap<>();
    private IdentifierRule defaultNamingRule = null;  // cached for performance

    /**
     * If a native query begins with any of the values found here then it will
     * be treated as a select statement.
     */
    protected final Set<String> selectWordSet = new HashSet<>();

    // when we store values that lose precision, track the types so that the
    // first time it happens we can warn the user
    private Set<Class<?>> _precisionWarnedTypes = null;

    // batchLimit value:
    // -1 = unlimited
    // 0  = no batch
    // any positive number = batch limit
    public int batchLimit = NO_BATCH;

    public final Map<Integer,Set<String>> sqlStateCodes =
        new HashMap<>();

    protected ProxyManager _proxyManager;

    public DBDictionary() {
        fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
            "BIGINT", "BIT", "BLOB", "CLOB", "DATE", "DECIMAL", "DISTINCT",
            "DOUBLE", "FLOAT", "INTEGER", "JAVA_OBJECT", "NULL", "NUMERIC",
            "OTHER", "REAL", "REF", "SMALLINT", "STRUCT", "TIME", "TIMESTAMP",
            "TINYINT",
        }));

        selectWordSet.add("SELECT");
    }

    /**
     * This method is called when the dictionary first sees any connection.
     * It is used to initialize dictionary metadata if needed. If you
     * override this method, be sure to call
     * <code>super.connectedConfiguration</code>.
     */
    public void connectedConfiguration(Connection conn)
        throws SQLException {
        if (!connected) {
            DatabaseMetaData metaData = null;
            try {
                metaData = conn.getMetaData();

                databaseProductName    = nullSafe(metaData.getDatabaseProductName());
                databaseProductVersion = nullSafe(metaData.getDatabaseProductVersion());
                setMajorVersion(metaData.getDatabaseMajorVersion());
                setMinorVersion(metaData.getDatabaseMinorVersion());
                try {
                    // JDBC3-only method, so it might throw an
                    // AbstractMethodError
                    int JDBCMajorVersion = metaData.getJDBCMajorVersion();
                    isJDBC3 = JDBCMajorVersion >= 3;
                    isJDBC4 = JDBCMajorVersion >= 4;
                } catch (Throwable t) {
                    // ignore if not JDBC3
                }
            } catch (Exception e) {
                if (log.isTraceEnabled())
                    log.trace(e.toString(), e);
            }

            if (log.isTraceEnabled()) {
                log.trace(DBDictionaryFactory.toString(metaData));

                if (isJDBC3) {
                    try {
                        log.trace(_loc.get("connection-defaults", new Object[]{
                            conn.getAutoCommit(), conn.getHoldability(),
                            conn.getTransactionIsolation()}));
                    } catch (Throwable t) {
                        log.trace("Unable to trace connection settings", t);
                    }
                }
            }

            // Configure the naming utility
            if (supportsDelimitedIdentifiers == null) // not explicitly set
                configureNamingUtil(metaData);

            // Auto-detect generated keys retrieval support unless user specified it.
            if (supportsGetGeneratedKeys == null) {
                supportsGetGeneratedKeys =  (isJDBC3) ? metaData.supportsGetGeneratedKeys() : false;
            }
            if (log.isInfoEnabled()) {
                log.info(_loc.get("dict-info", new Object[] {
                        metaData.getDatabaseProductName(), getMajorVersion(), getMinorVersion(),
                        metaData.getDriverName(), metaData.getDriverVersion()}));
            }
        }
        connected = true;
    }

    private void configureNamingUtil(DatabaseMetaData metaData) {
        // Get the naming utility from the configuration
        setSupportsDelimitedIdentifiers(metaData);
        setDelimitedCase(metaData);
    }

    /**
     * Configures the naming rules for this dictionary.  Subclasses should
     * override this method, providing their own naming rules.
     */
    protected void configureNamingRules() {
        // Add the default naming rule
        DBIdentifierRule defRule = new DBIdentifierRule(DBIdentifierType.DEFAULT, reservedWordSet);
        namingRules.put(defRule.getName(), defRule);
        // Disable delimiting of column definition.  DB platforms are very
        // picky about delimiters in column definitions. Base column types
        // do not require delimiters and will cause failures if delimited.
        DBIdentifierRule cdRule = new ColumnDefIdentifierRule();
        cdRule.setCanDelimit(false);
        namingRules.put(cdRule.getName(), cdRule);
    }

    //////////////////////
    // ResultSet wrappers
    //////////////////////

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Array getArray(ResultSet rs, int column)
        throws SQLException {
        return rs.getArray(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public InputStream getAsciiStream(ResultSet rs, int column)
        throws SQLException {
        return rs.getAsciiStream(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public BigDecimal getBigDecimal(ResultSet rs, int column)
        throws SQLException {
        if (storeLargeNumbersAsStrings) {
            String str = getString(rs, column);
            return (str == null) ? null : new BigDecimal(str);
        }
        return rs.getBigDecimal(column);
    }

    /**
     * Returns the specified column value as an unknown numeric type;
     * we try from the most generic to the least generic.
     */
    public Number getNumber(ResultSet rs, int column)
        throws SQLException {
        // try from the most generic, and if errors occur, try
        // less generic types; this enables us to handle values
        // like Double.NaN without having to introspect on the
        // ResultSetMetaData (bug #1053). Note that we handle
        // generic exceptions, since some drivers may throw
        // NumberFormatExceptions, whereas others may throw SQLExceptions
        try {
            return getBigDecimal(rs, column);
        } catch (Exception e1) {
            try {
                return Double.valueOf(getDouble(rs, column));
            } catch (Exception e2) {
                try {
                    return Float.valueOf(getFloat(rs, column));
                } catch (Exception e3) {
                    try {
                        return getLong(rs, column);
                    } catch (Exception e4) {
                        try {
                            return getInt(rs, column);
                        } catch (Exception e5) {
                        }
                    }
                }
            }

            if (e1 instanceof RuntimeException)
                throw(RuntimeException) e1;
            if (e1 instanceof SQLException)
                throw(SQLException) e1;
        }

        return null;
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public BigInteger getBigInteger(ResultSet rs, int column)
        throws SQLException {
        if (storeLargeNumbersAsStrings) {
            String str = getString(rs, column);
            return (str == null) ? null : new BigDecimal(str).toBigInteger();
        }
        BigDecimal bd = getBigDecimal(rs, column);
        return (bd == null) ? null : bd.toBigInteger();
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public InputStream getBinaryStream(ResultSet rs, int column)
        throws SQLException {
        return rs.getBinaryStream(column);
    }

    public InputStream getLOBStream(JDBCStore store, ResultSet rs,
        int column) throws SQLException {
        return rs.getBinaryStream(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Blob getBlob(ResultSet rs, int column)
        throws SQLException {
        return rs.getBlob(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Object getBlobObject(ResultSet rs, int column, JDBCStore store)
        throws SQLException {
        InputStream in = null;
        if (useGetBytesForBlobs || useGetObjectForBlobs) {
            byte[] bytes = getBytes(rs, column);
            if (bytes != null && bytes.length > 0)
                in = new ByteArrayInputStream(bytes);
        } else {
            Blob blob = getBlob(rs, column);
            if (blob != null && blob.length() > 0)
                in = blob.getBinaryStream();
        }
        if (in == null)
            return null;

        try {
            if (store == null)
                return Serialization.deserialize(in, null);
            return Serialization.deserialize(in, store.getContext());
        } finally {
            try {
                in.close();
            } catch (IOException ioe) {
            }
        }
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public boolean getBoolean(ResultSet rs, int column)
        throws SQLException {
        return booleanRepresentation.getBoolean(rs, column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public byte getByte(ResultSet rs, int column)
        throws SQLException {
        return rs.getByte(column);
    }

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

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

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type. Converts the date from a {@link Timestamp} by default.
     */
    public Calendar getCalendar(ResultSet rs, int column) throws SQLException {
        Date d = getDate(rs, column);
        if (d == null)
            return null;
        Calendar cal = (Calendar) getProxyManager().newCalendarProxy(GregorianCalendar.class, null);
        cal.setTime(d);
        return cal;
    }

    /**
     * Retrieve the specified column of the SQL ResultSet to the proper
     * {@link LocalDate} java type.
     */
    public LocalDate getLocalDate(ResultSet rs, int column) throws SQLException {
        java.sql.Date date = rs.getDate(column);
        return date != null ? date.toLocalDate() : null;
    }

    /**
     * Retrieve the specified column of the SQL ResultSet to the proper
     * {@link LocalTime} java type.
     */
    public LocalTime getLocalTime(ResultSet rs, int column) throws SQLException {
        java.sql.Time time = rs.getTime(column);
        return time != null ? time.toLocalTime() : null;
    }

    /**
     * Retrieve the specified column of the SQL ResultSet to the proper
     * {@link LocalDateTime} java type.
     */
    public LocalDateTime getLocalDateTime(ResultSet rs, int column) throws SQLException {
        Timestamp tst = rs.getTimestamp(column);
        return tst != null ? tst.toLocalDateTime() : null;
    }

    /**
     * Retrieve the specified column of the SQL ResultSet to the proper
     * {@link OffsetTime} java type.
     */
    public OffsetTime getOffsetTime(ResultSet rs, int column) throws SQLException {
        java.sql.Time time = rs.getTime(column);
        return time != null ? time.toLocalTime().atOffset(OffsetDateTime.now().getOffset()) : null;
    }

    /**
     * Retrieve the specified column of the SQL ResultSet to the proper
     * {@link OffsetDateTime} java type.
     */
    public OffsetDateTime getOffsetDateTime(ResultSet rs, int column) throws SQLException {
        Timestamp tst = rs.getTimestamp(column);
        return tst != null ? tst.toLocalDateTime().atZone(ZoneId.systemDefault()).toOffsetDateTime() : null;
    }

    private ProxyManager getProxyManager() {
        if (_proxyManager == null) {
            _proxyManager = conf.getProxyManagerInstance();
        }
        return _proxyManager;
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public char getChar(ResultSet rs, int column)
        throws SQLException {
        if (storeCharsAsNumbers)
            return (char) getInt(rs, column);

        String str = getString(rs, column);
        return (StringUtil.isEmpty(str)) ? 0 : str.charAt(0);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Reader getCharacterStream(ResultSet rs, int column)
        throws SQLException {
        return rs.getCharacterStream(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Clob getClob(ResultSet rs, int column)
        throws SQLException {
        return rs.getClob(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public String getClobString(ResultSet rs, int column)
        throws SQLException {
        if (useGetStringForClobs)
            return rs.getString(column);

        Clob clob = getClob(rs, column);
        if (clob == null)
            return null;
        if (clob.length() == 0)
            return "";

        // unlikely that we'll have strings over Integer.MAX_VALUE chars
        return clob.getSubString(1, (int) clob.length());
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type. Converts the date from a {@link Timestamp} by default.
     */
    public Date getDate(ResultSet rs, int column)
        throws SQLException {
        Timestamp tstamp = getTimestamp(rs, column, null);
        if (tstamp == null)
            return null;

        // get the fractional seconds component, rounding away anything beyond
        // milliseconds
        int fractional = 0;
        switch (getMillisecondBehavior()) {
            case DROP :
                fractional = 0;
                break;
            case RETAIN :
                fractional = (int) (tstamp.getNanos() / (double) MILLI);
                break;
            case ROUND :
                fractional = (int) Math.round(tstamp.getNanos() / (double) MILLI);
                break;
        }

        // get the millis component; some JDBC drivers round this to the
        // nearest second, while others do not
        long millis = (tstamp.getTime() / 1000L) * 1000L;
        return new Date(millis + fractional);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public java.sql.Date getDate(ResultSet rs, int column, Calendar cal)
        throws SQLException {
        if (cal == null)
            return rs.getDate(column);
        return rs.getDate(column, cal);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public double getDouble(ResultSet rs, int column)
        throws SQLException {
        return rs.getDouble(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public float getFloat(ResultSet rs, int column)
        throws SQLException {
        return rs.getFloat(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public int getInt(ResultSet rs, int column)
        throws SQLException {
        return rs.getInt(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Locale getLocale(ResultSet rs, int column)
        throws SQLException {
        String str = getString(rs, column);
        if (StringUtil.isEmpty(str))
            return null;

        String[] params = StringUtil.split(str, "_", 3);
        if (params.length < 3)
            return null;
        return new Locale(params[0], params[1], params[2]);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public long getLong(ResultSet rs, int column)
        throws SQLException {
        return rs.getLong(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Object getObject(ResultSet rs, int column, Map map)
        throws SQLException {
        if (map == null)
            return rs.getObject(column);
        return rs.getObject(column, map);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Ref getRef(ResultSet rs, int column, Map map)
        throws SQLException {
        return rs.getRef(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public short getShort(ResultSet rs, int column)
        throws SQLException {
        return rs.getShort(column);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public String getString(ResultSet rs, int column)
        throws SQLException {
        String res = rs.getString(column);
        if ((res != null) && trimStringColumns) {
            res = res.trim();
        }
        return res;
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Time getTime(ResultSet rs, int column, Calendar cal)
        throws SQLException {
        if (cal == null)
            return rs.getTime(column);
        return rs.getTime(column, cal);
    }

    /**
     * Convert the specified column of the SQL ResultSet to the proper
     * java type.
     */
    public Timestamp getTimestamp(ResultSet rs, int column, Calendar cal)
        throws SQLException {
        if (cal == null)
            return rs.getTimestamp(column);
        return rs.getTimestamp(column, cal);
    }

    //////////////////////////////
    // PreparedStatement wrappers
    //////////////////////////////

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setArray(PreparedStatement stmnt, int idx, Array val,
        Column col)
        throws SQLException {
        stmnt.setArray(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setAsciiStream(PreparedStatement stmnt, int idx, InputStream val, int length, Column col)
        throws SQLException {
        stmnt.setAsciiStream(idx, val, length);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setBigDecimal(PreparedStatement stmnt, int idx, BigDecimal val, Column col)
        throws SQLException {
        if ((col != null && col.isCompatible(Types.VARCHAR, null, 0, 0))
            || (col == null && storeLargeNumbersAsStrings)) {
            setString(stmnt, idx, val.toString(), col);
        }
        else {
            stmnt.setBigDecimal(idx, val);
        }
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setBigInteger(PreparedStatement stmnt, int idx, BigInteger val, Column col)
        throws SQLException {
        if ((col != null && col.isCompatible(Types.VARCHAR, null, 0, 0))
            || (col == null && storeLargeNumbersAsStrings)) {
            setString(stmnt, idx, val.toString(), col);
        }
        else {
            setBigDecimal(stmnt, idx, new BigDecimal(val), col);
        }
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setBinaryStream(PreparedStatement stmnt, int idx, InputStream val, int length, Column col)
        throws SQLException {

        //OPENJPA-2067: If the user has set the 'useJDBC4SetBinaryStream' property
        //then lets use the JDBC 4.0 version of the setBinaryStream method.
        if (useJDBC4SetBinaryStream) {
            if (isJDBC4){
                stmnt.setBinaryStream(idx, val);
                return;
            }
            else {
                log.trace(_loc.get("jdbc4-setbinarystream-unsupported"));
            }
        }

        stmnt.setBinaryStream(idx, val, length);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setBlob(PreparedStatement stmnt, int idx, Blob val, Column col)
        throws SQLException {
        stmnt.setBlob(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement. Uses the
     * {@link #serialize} method to serialize the value.
     */
    public void setBlobObject(PreparedStatement stmnt, int idx, Object val, Column col, JDBCStore store)
        throws SQLException {
        setBytes(stmnt, idx, serialize(val, store), col);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setBoolean(PreparedStatement stmnt, int idx, boolean val, Column col)
        throws SQLException {
        booleanRepresentation.setBoolean(stmnt, idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setByte(PreparedStatement stmnt, int idx, byte val, Column col)
        throws SQLException {
        stmnt.setByte(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setBytes(PreparedStatement stmnt, int idx, byte[] val,
        Column col)
        throws SQLException {
        if (useSetBytesForBlobs)
            stmnt.setBytes(idx, val);
        else
            setBinaryStream(stmnt, idx, new ByteArrayInputStream(val),
                val.length, col);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setChar(PreparedStatement stmnt, int idx, char val, Column col)
        throws SQLException {
        if ((col != null && col.isCompatible(Types.INTEGER, null, 0, 0))
            || (col == null && storeCharsAsNumbers))
            setInt(stmnt, idx, (int) val, col);
        else
            setString(stmnt, idx, String.valueOf(val), col);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setCharacterStream(PreparedStatement stmnt, int idx,
        Reader val, int length, Column col)
        throws SQLException {
        stmnt.setCharacterStream(idx, val, length);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setClob(PreparedStatement stmnt, int idx, Clob val, Column col)
        throws SQLException {
        stmnt.setClob(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setClobString(PreparedStatement stmnt, int idx, String val,
        Column col)
        throws SQLException {
        if (useSetStringForClobs)
            stmnt.setString(idx, val);
        else {
            // set reader from string
            StringReader in = new StringReader(val);
            setCharacterStream(stmnt, idx, in, val.length(), col);
        }
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setDate(PreparedStatement stmnt, int idx, Date val, Column col)
        throws SQLException {
        if (col != null && col.getType() == Types.DATE)
            setDate(stmnt, idx, new java.sql.Date(val.getTime()), null, col);
        else if (col != null && col.getType() == Types.TIME)
            setTime(stmnt, idx, new Time(val.getTime()), null, col);
        else if (val instanceof Timestamp)
            setTimestamp(stmnt, idx,(Timestamp) val, null, col);
        else
            setTimestamp(stmnt, idx, new Timestamp(val.getTime()), null, col);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setDate(PreparedStatement stmnt, int idx, java.sql.Date val, Calendar cal, Column col)
        throws SQLException {
        if (cal == null) {
            stmnt.setDate(idx, val);
        }
        else {
            stmnt.setDate(idx, val, cal);
        }
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setCalendar(PreparedStatement stmnt, int idx, Calendar val, Column col)
        throws SQLException {
        // by default we merely delegate to the Date parameter
        setDate(stmnt, idx, val.getTime(), col);
    }

    /**
     * Set the given LocalDate value as a parameter to the statement.
     *
     */
    public void setLocalDate(PreparedStatement stmnt, int idx, LocalDate val, Column col)
        throws SQLException {
        setDate(stmnt, idx, java.sql.Date.valueOf(val), null, col);
    }

    /**
     * Set the given LocalTime value as a parameter to the statement.
     *
     */
    public void setLocalTime(PreparedStatement stmnt, int idx, LocalTime val, Column col)
        throws SQLException {
        setTime(stmnt, idx, java.sql.Time.valueOf(val), null, col);
    }

    /**
     * Set the given LocalTime value as a parameter to the statement.
     *
     */
    public void setLocalDateTime(PreparedStatement stmnt, int idx, LocalDateTime val, Column col)
        throws SQLException {
        setTimestamp(stmnt, idx, java.sql.Timestamp.valueOf(val), null, col);
    }


    /**
     * Set the given LocalTime value as a parameter to the statement.
     *
     */
    public void setOffsetTime(PreparedStatement stmnt, int idx, OffsetTime val, Column col)
            throws SQLException {
        // adjust to the default timezone right now.
        // This is an ugly hack and cries for troubles in case the daylight saving changes...
        // Which is also the reason why we cannot cache the offset.
        // According to the Oracle docs the JDBC driver always assumes 'local time' ...
        LocalTime localTime = val.withOffsetSameInstant(OffsetDateTime.now().getOffset()).toLocalTime();
        setLocalTime(stmnt, idx, localTime, col);
    }

    /**
     * Set the given LocalTime value as a parameter to the statement.
     *
     */
    public void setOffsetDateTime(PreparedStatement stmnt, int idx, OffsetDateTime val, Column col)
            throws SQLException {
        LocalDateTime localdt = val.atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
        setLocalDateTime(stmnt, idx, localdt, col);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setDouble(PreparedStatement stmnt, int idx, double val, Column col)
        throws SQLException {
        stmnt.setDouble(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setFloat(PreparedStatement stmnt, int idx, float val, Column col)
        throws SQLException {
        stmnt.setFloat(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setInt(PreparedStatement stmnt, int idx, int val, Column col)
        throws SQLException {
        stmnt.setInt(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setLong(PreparedStatement stmnt, int idx, long val, Column col)
        throws SQLException {
        stmnt.setLong(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setLocale(PreparedStatement stmnt, int idx, Locale val, Column col)
        throws SQLException {
        setString(stmnt, idx, val.getLanguage() + "_" + val.getCountry()
            + "_" + val.getVariant(), col);
    }

    /**
     * Set null as a parameter to the statement. The column
     * type will come from {@link Types}.
     */
    public void setNull(PreparedStatement stmnt, int idx, int colType, Column col)
        throws SQLException {
        stmnt.setNull(idx, colType);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setNumber(PreparedStatement stmnt, int idx, Number num, Column col)
        throws SQLException {
        // check for known floating point types to give driver a chance to
        // handle special numbers like NaN and infinity; bug #1053
        if (num instanceof Double)
            setDouble(stmnt, idx, ((Double) num).doubleValue(), col);
        else if (num instanceof Float)
            setFloat(stmnt, idx, ((Float) num).floatValue(), col);
        else
            setBigDecimal(stmnt, idx, new BigDecimal(num.toString()), col);
    }

    /**
     * Set the given value as a parameter to the statement. The column
     * type will come from {@link Types}.
     */
    public void setObject(PreparedStatement stmnt, int idx, Object val, int colType, Column col)
        throws SQLException {
        if (colType == -1 || colType == Types.OTHER)
            stmnt.setObject(idx, val);
        else
            stmnt.setObject(idx, val, colType);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setRef(PreparedStatement stmnt, int idx, Ref val, Column col)
        throws SQLException {
        stmnt.setRef(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setShort(PreparedStatement stmnt, int idx, short val, Column col)
        throws SQLException {
        stmnt.setShort(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setString(PreparedStatement stmnt, int idx, String val, Column col)
        throws SQLException {
        stmnt.setString(idx, val);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setTime(PreparedStatement stmnt, int idx, Time val, Calendar cal, Column col)
        throws SQLException {
        if (cal == null)
            stmnt.setTime(idx, val);
        else
            stmnt.setTime(idx, val, cal);
    }

    /**
     * Set the given value as a parameter to the statement.
     */
    public void setTimestamp(PreparedStatement stmnt, int idx, Timestamp val, Calendar cal, Column col)
        throws SQLException {

        val = StateManagerImpl.roundTimestamp(val, datePrecision);

        if (cal == null)
            stmnt.setTimestamp(idx, val);
        else
            stmnt.setTimestamp(idx, val, cal);
    }

    /**
     * Set a column value into a prepared statement.
     *
     * @param stmnt the prepared statement to parameterize
     * @param idx the index of the parameter in the prepared statement
     * @param val the value of the column
     * @param col the column being set
     * @param type the field mapping type code for the value
     * @param store the store manager for the current context
     */
    public void setTyped(PreparedStatement stmnt, int idx, Object val, Column col, int type, JDBCStore store)
        throws SQLException {
        if (val == null) {
            setNull(stmnt, idx, (col == null) ? Types.OTHER : col.getType(),
                col);
            return;
        }

        Sized s;
        Calendard c;
        switch (type) {
            case JavaTypes.BOOLEAN:
            case JavaTypes.BOOLEAN_OBJ:
                setBoolean(stmnt, idx, ((Boolean) val).booleanValue(), col);
                break;
            case JavaTypes.BYTE:
            case JavaTypes.BYTE_OBJ:
                setByte(stmnt, idx, ((Number) val).byteValue(), col);
                break;
            case JavaTypes.CHAR:
            case JavaTypes.CHAR_OBJ:
                setChar(stmnt, idx, ((Character) val).charValue(), col);
                break;
            case JavaTypes.DOUBLE:
            case JavaTypes.DOUBLE_OBJ:
                setDouble(stmnt, idx, ((Number) val).doubleValue(), col);
                break;
            case JavaTypes.FLOAT:
            case JavaTypes.FLOAT_OBJ:
                setFloat(stmnt, idx, ((Number) val).floatValue(), col);
                break;
            case JavaTypes.INT:
            case JavaTypes.INT_OBJ:
                setInt(stmnt, idx, ((Number) val).intValue(), col);
                break;
            case JavaTypes.LONG:
            case JavaTypes.LONG_OBJ:
                setLong(stmnt, idx, ((Number) val).longValue(), col);
                break;
            case JavaTypes.SHORT:
            case JavaTypes.SHORT_OBJ:
                setShort(stmnt, idx, ((Number) val).shortValue(), col);
                break;
            case JavaTypes.STRING:
                if (col != null && (col.getType() == Types.CLOB
                    || col.getType() == Types.LONGVARCHAR))
                    setClobString(stmnt, idx, (String) val, col);
                else {
                    if (val instanceof String)
                        setString(stmnt, idx, (String) val, col);
                    else
                        setString(stmnt, idx, val.toString(), col);
                }
                break;
            case JavaTypes.OBJECT:
                setBlobObject(stmnt, idx, val, col, store);
                break;
            case JavaTypes.DATE:
                setDate(stmnt, idx, (Date) val, col);
                break;
            case JavaTypes.CALENDAR:
                setCalendar(stmnt, idx, (Calendar) val, col);
                break;
            case JavaTypes.LOCAL_DATE:
                setLocalDate(stmnt, idx, (LocalDate) val, col);
                break;
            case JavaTypes.LOCAL_TIME:
                setLocalTime(stmnt, idx, (LocalTime) val, col);
                break;
            case JavaTypes.LOCAL_DATETIME:
                setLocalDateTime(stmnt, idx, (LocalDateTime) val, col);
                break;
            case JavaTypes.OFFSET_TIME:
                setOffsetTime(stmnt, idx, (OffsetTime) val, col);
                break;
            case JavaTypes.OFFSET_DATETIME:
                setOffsetDateTime(stmnt, idx, (OffsetDateTime) val, col);
                break;
            case JavaTypes.BIGDECIMAL:
                setBigDecimal(stmnt, idx, (BigDecimal) val, col);
                break;
            case JavaTypes.BIGINTEGER:
                setBigInteger(stmnt, idx, (BigInteger) val, col);
                break;
            case JavaTypes.NUMBER:
                setNumber(stmnt, idx, (Number) val, col);
                break;
            case JavaTypes.LOCALE:
                setLocale(stmnt, idx, (Locale) val, col);
                break;
            case JavaSQLTypes.SQL_ARRAY:
                setArray(stmnt, idx, (Array) val, col);
                break;
            case JavaSQLTypes.ASCII_STREAM:
                s = (Sized) val;
                setAsciiStream(stmnt, idx, (InputStream) s.value, s.size, col);
                break;
            case JavaSQLTypes.BINARY_STREAM:
                s = (Sized) val;
                setBinaryStream(stmnt, idx, (InputStream) s.value, s.size, col);
                break;
            case JavaSQLTypes.BLOB:
                setBlob(stmnt, idx, (Blob) val, col);
                break;
            case JavaSQLTypes.BYTES:
                setBytes(stmnt, idx, (byte[]) val, col);
                break;
            case JavaSQLTypes.CHAR_STREAM:
                s = (Sized) val;
                setCharacterStream(stmnt, idx, (Reader) s.value, s.size, col);
                break;
            case JavaSQLTypes.CLOB:
                setClob(stmnt, idx, (Clob) val, col);
                break;
            case JavaSQLTypes.SQL_DATE:
                if (val instanceof Calendard) {
                    c = (Calendard) val;
                    setDate(stmnt, idx, (java.sql.Date) c.value, c.calendar,
                        col);
                } else
                    setDate(stmnt, idx, (java.sql.Date) val, null, col);
                break;
            case JavaSQLTypes.REF:
                setRef(stmnt, idx, (Ref) val, col);
                break;
            case JavaSQLTypes.TIME:
                if (val instanceof Calendard) {
                    c = (Calendard) val;
                    setTime(stmnt, idx, (Time) c.value, c.calendar, col);
                } else
                    setTime(stmnt, idx, (Time) val, null, col);
                break;
            case JavaSQLTypes.TIMESTAMP:
                if (val instanceof Calendard) {
                    c = (Calendard) val;
                    setTimestamp(stmnt, idx, (Timestamp) c.value, c.calendar,
                        col);
                } else
                    setTimestamp(stmnt, idx, (Timestamp) val, null, col);
                break;
            default:
                if (col != null && (col.getType() == Types.BLOB
                    || col.getType() == Types.VARBINARY))
                    setBlobObject(stmnt, idx, val, col, store);
                else
                    setObject(stmnt, idx, val, col.getType(), col);
        }
    }

    /**
     * Set a completely unknown parameter into a prepared statement.
     */
    public void setUnknown(PreparedStatement stmt, int idx, Object val, Column col) throws SQLException {
        if (val instanceof Object[]) {
            Object[] valArray = (Object[])val;
            for (Object object : valArray) {
                setUnknown(stmt, idx, col, object);
            }
        } else {
            setUnknown(stmt, idx, col, val);
        }
    }

    /**
     * Set a completely unknown parameter into a prepared statement.
     */
    public void setUnknown(PreparedStatement stmnt, int idx, Column col, Object val) throws SQLException {
        Sized sized = null;
        Calendard cald = null;
        if (val instanceof Sized) {
            sized = (Sized) val;
            val = sized.value;
        } else if (val instanceof Calendard) {
            cald = (Calendard) val;
            val = cald.value;
        }

        if (val == null)
            setNull(stmnt, idx, (col == null) ? Types.OTHER : col.getType(),
                col);
        else if (val instanceof String)
            setString(stmnt, idx, val.toString(), col);
        else if (val instanceof Integer)
            setInt(stmnt, idx, ((Integer) val).intValue(), col);
        else if (val instanceof Boolean)
            setBoolean(stmnt, idx, ((Boolean) val).booleanValue(), col);
        else if (val instanceof Long)
            setLong(stmnt, idx, ((Long) val).longValue(), col);
        else if (val instanceof Float)
            setFloat(stmnt, idx, ((Float) val).floatValue(), col);
        else if (val instanceof Double)
            setDouble(stmnt, idx, ((Double) val).doubleValue(), col);
        else if (val instanceof Byte)
            setByte(stmnt, idx, ((Byte) val).byteValue(), col);
        else if (val instanceof Character)
            setChar(stmnt, idx, ((Character) val).charValue(), col);
        else if (val instanceof Short)
            setShort(stmnt, idx, ((Short) val).shortValue(), col);
        else if (val instanceof Locale)
            setLocale(stmnt, idx, (Locale) val, col);
        else if (val instanceof BigDecimal)
            setBigDecimal(stmnt, idx, (BigDecimal) val, col);
        else if (val instanceof BigInteger)
            setBigInteger(stmnt, idx, (BigInteger) val, col);
        else if (val instanceof Array)
            setArray(stmnt, idx, (Array) val, col);
        else if (val instanceof Blob)
            setBlob(stmnt, idx, (Blob) val, col);
        else if (val instanceof byte[])
            setBytes(stmnt, idx, (byte[]) val, col);
        else if (val instanceof Clob)
            setClob(stmnt, idx, (Clob) val, col);
        else if (val instanceof Ref)
            setRef(stmnt, idx, (Ref) val, col);
        else if (val instanceof java.sql.Date)
            setDate(stmnt, idx, (java.sql.Date) val,
                (cald == null) ? null : cald.calendar, col);
        else if (val instanceof Timestamp)
            setTimestamp(stmnt, idx, (Timestamp) val,
                (cald == null) ? null : cald.calendar, col);
        else if (val instanceof Time)
            setTime(stmnt, idx, (Time) val,
                (cald == null) ? null : cald.calendar, col);
        else if (val instanceof Date)
            setDate(stmnt, idx, (Date) val, col);
        else if (val instanceof Calendar)
            setDate(stmnt, idx, ((Calendar) val).getTime(), col);
        else if (val instanceof LocalDate) {
            setLocalDate(stmnt, idx, (LocalDate) val, col);
        }
        else if (val instanceof LocalTime) {
            setLocalTime(stmnt, idx, (LocalTime) val, col);
        }
        else if (val instanceof LocalDateTime) {
            setLocalDateTime(stmnt, idx, (LocalDateTime) val, col);
        }
        else if (val instanceof Reader)
            setCharacterStream(stmnt, idx, (Reader) val,
                (sized == null) ? 0 : sized.size, col);
        else
            throw new UserException(_loc.get("bad-param", val.getClass()));
    }

    /**
     * Return the serialized bytes for the given object.
     */
    public byte[] serialize(Object val, JDBCStore store)
        throws SQLException {
        if (val == null)
            return null;
        if (val instanceof SerializedData)
            return ((SerializedData) val).bytes;
        return Serialization.serialize(val, store.getContext());
    }

    /**
     * Invoke the JDK 1.4 <code>setBytes</code> method on the given BLOB object.
     */
    public void putBytes(Blob blob, byte[] data)
        throws SQLException {
        blob.setBytes(1L, data);
    }

    /**
     * Invoke the JDK 1.4 <code>setString</code> method on the given CLOB
     * object.
     */
    public void putString(Clob clob, String data)
        throws SQLException {
        clob.setString(1L, data);
    }

    /**
     * Invoke the JDK 1.4 <code>setCharacterStream</code> method on the given
     * CLOB object.
     */
    public void putChars(Clob clob, char[] data)
        throws SQLException {
        Writer writer = clob.setCharacterStream(1L);
        try {
            writer.write(data);
            writer.flush();
        } catch (IOException ioe) {
            throw new SQLException(ioe.toString());
        }
    }

    /**
     * Warn that a particular value could not be stored precisely.
     * After the first warning for a particular type, messages
     * will be turned into trace messages.
     */
    protected void storageWarning(Object orig, Object converted) {
        boolean warn;
        synchronized (this) {
            if (_precisionWarnedTypes == null)
                _precisionWarnedTypes = new HashSet<>();
            warn = _precisionWarnedTypes.add(orig.getClass());
        }

        if (storageLimitationsFatal || (warn && log.isWarnEnabled())
            || (!warn && log.isTraceEnabled())) {
            Message msg = _loc.get("storage-restriction", new Object[]{
                platform,
                orig,
                orig.getClass().getName(),
                converted,
            });

            if (storageLimitationsFatal)
                throw new StoreException(msg);

            if (warn)
                log.warn(msg);
            else
                log.trace(msg);
        }
    }

    /////////
    // Types
    /////////

    /**
     * Return the preferred {@link Types} constant for the given
     * {@link JavaTypes} or {@link JavaSQLTypes} constant.
     */
    public int getJDBCType(int metaTypeCode, boolean lob) {
        return getJDBCType(metaTypeCode, lob, 0, 0);
    }

    /**
     * Return the preferred {@link Types} constant for the given
     * {@link JavaTypes} or {@link JavaSQLTypes} constant.
     */
    public int getJDBCType(int metaTypeCode, boolean lob, int precis,
        int scale, boolean xml) {
        return getJDBCType(metaTypeCode, lob, precis, scale);
    }

    /**
     * Return the preferred {@link Types} constant for the given
     * {@link JavaTypes} or {@link JavaSQLTypes} constant.
     */
    public int getJDBCType(int metaTypeCode, boolean lob, int precis,
        int scale) {
        if (lob) {
            switch (metaTypeCode) {
                case JavaTypes.STRING:
                case JavaSQLTypes.ASCII_STREAM:
                case JavaSQLTypes.CHAR_STREAM:
                    return getPreferredType(Types.CLOB);
                default:
                    return getPreferredType(Types.BLOB);
            }
        }

        switch (metaTypeCode) {
            case JavaTypes.BOOLEAN:
            case JavaTypes.BOOLEAN_OBJ:
                return getPreferredType(Types.BIT);
            case JavaTypes.BYTE:
            case JavaTypes.BYTE_OBJ:
                return getPreferredType(Types.TINYINT);
            case JavaTypes.CHAR:
            case JavaTypes.CHAR_OBJ:
                if (storeCharsAsNumbers)
                    return getPreferredType(Types.INTEGER);
                return getPreferredType(Types.CHAR);
            case JavaTypes.DOUBLE:
            case JavaTypes.DOUBLE_OBJ:
                if(precis > 0 || scale > 0) {
                    return getPreferredType(Types.NUMERIC);
                }
                else {
                    return getPreferredType(Types.DOUBLE);
                }
            case JavaTypes.FLOAT:
            case JavaTypes.FLOAT_OBJ:
                if(precis > 0 || scale > 0) {
                    return getPreferredType(Types.NUMERIC);
                }
                else {
                    return getPreferredType(Types.REAL);
                }
            case JavaTypes.INT:
            case JavaTypes.INT_OBJ:
                return getPreferredType(Types.INTEGER);
            case JavaTypes.LONG:
            case JavaTypes.LONG_OBJ:
                return getPreferredType(Types.BIGINT);
            case JavaTypes.SHORT:
            case JavaTypes.SHORT_OBJ:
                return getPreferredType(Types.SMALLINT);
            case JavaTypes.STRING:
            case JavaTypes.LOCALE:
            case JavaSQLTypes.ASCII_STREAM:
            case JavaSQLTypes.CHAR_STREAM:
                return getPreferredType(Types.VARCHAR);
            case JavaTypes.BIGINTEGER:
                if (storeLargeNumbersAsStrings)
                    return getPreferredType(Types.VARCHAR);
                return getPreferredType(Types.BIGINT);
            case JavaTypes.BIGDECIMAL:
                if (storeLargeNumbersAsStrings)
                    return getPreferredType(Types.VARCHAR);
                return getPreferredType(Types.NUMERIC);
            case JavaTypes.NUMBER:
                if (storeLargeNumbersAsStrings)
                    return getPreferredType(Types.VARCHAR);
                return getPreferredType(Types.NUMERIC);
            case JavaTypes.CALENDAR:
            case JavaTypes.DATE:
                return getPreferredType(Types.TIMESTAMP);
            case JavaTypes.LOCAL_DATE:
                return getPreferredType(Types.DATE);
            case JavaTypes.LOCAL_TIME:
                return getPreferredType(Types.TIME);
            case JavaTypes.LOCAL_DATETIME:
                return getPreferredType(Types.TIMESTAMP);
            case JavaTypes.OFFSET_TIME:
                return getPreferredType(Types.TIME_WITH_TIMEZONE);
            case JavaTypes.OFFSET_DATETIME:
                return getPreferredType(Types.TIMESTAMP_WITH_TIMEZONE);
            case JavaSQLTypes.SQL_ARRAY:
                return getPreferredType(Types.ARRAY);
            case JavaSQLTypes.BINARY_STREAM:
            case JavaSQLTypes.BLOB:
            case JavaSQLTypes.BYTES:
                return getPreferredType(Types.BLOB);
            case JavaSQLTypes.CLOB:
                return getPreferredType(Types.CLOB);
            case JavaSQLTypes.SQL_DATE:
                return getPreferredType(Types.DATE);
            case JavaSQLTypes.TIME:
                return getPreferredType(Types.TIME);
            case JavaSQLTypes.TIMESTAMP:
                return getPreferredType(Types.TIMESTAMP);
            default:
                return getPreferredType(Types.BLOB);
        }
    }

    /**
     * Return the preferred {@link Types} type for the given one. Returns
     * the given type by default.
     */
    public int getPreferredType(int type) {
        return type;
    }

    /**
     * Return the preferred database type name for the given column's type
     * from {@link Types}.
     */
    public String getTypeName(Column col) {
        if (!DBIdentifier.isEmpty(col.getTypeIdentifier()))
            return appendSize(col, toDBName(col.getTypeIdentifier()));

        if (col.isAutoAssigned() && autoAssignTypeName != null)
            return appendSize(col, autoAssignTypeName);

        return appendSize(col, getTypeName(col.getType()));
    }

    /**
     * Returns the type name for the specific constant as defined
     * by {@link java.sql.Types}.
     *
     * @param type the type
     * @return the name for the type
     */
    public String getTypeName(int type) {
        switch (type) {
            case Types.ARRAY:
                return arrayTypeName;
            case Types.BIGINT:
                return bigintTypeName;
            case Types.BINARY:
                return binaryTypeName;
            case Types.BIT:
                return bitTypeName;
            case Types.BLOB:
                return blobTypeName;
            case Types.BOOLEAN:
                return booleanTypeName;
            case Types.CHAR:
                return charTypeName;
            case Types.CLOB:
                return clobTypeName;
            case Types.DATE:
                return dateTypeName;
            case Types.DECIMAL:
                return decimalTypeName;
            case Types.DISTINCT:
                return distinctTypeName;
            case Types.DOUBLE:
                return doubleTypeName;
            case Types.FLOAT:
                return floatTypeName;
            case Types.INTEGER:
                return integerTypeName;
            case Types.JAVA_OBJECT:
                return javaObjectTypeName;
            case Types.LONGVARBINARY:
                return longVarbinaryTypeName;
            case Types.LONGVARCHAR:
                return longVarcharTypeName;
            case Types.NULL:
                return nullTypeName;
            case Types.NUMERIC:
                return numericTypeName;
            case Types.OTHER:
                return otherTypeName;
            case Types.REAL:
                return realTypeName;
            case Types.REF:
                return refTypeName;
            case Types.SMALLINT:
                return smallintTypeName;
            case Types.STRUCT:
                return structTypeName;
            case Types.TIME:
                return timeTypeName;
            case Types.TIMESTAMP:
                return timestampTypeName;
            case Types.TIME_WITH_TIMEZONE:
                return timeWithZoneTypeName;
            case Types.TIMESTAMP_WITH_TIMEZONE:
                return timestampWithZoneTypeName;
            case Types.TINYINT:
                return tinyintTypeName;
            case Types.VARBINARY:
                return varbinaryTypeName;
            case Types.VARCHAR:
                return varcharTypeName;
            default:
                return otherTypeName;
        }
    }

    /**
     * Helper method to add size properties to the specified type.
     * If present, the string "{0}" will be replaced with the size definition;
     * otherwise the size definition will be appended to the type name.
     * If your database has column types that don't allow size definitions,
     * override this method to return the unaltered type name for columns of
     * those types (or add the type names to the
     * <code>fixedSizeTypeNameSet</code>).
     *
     * <P>Some databases support "type modifiers", for example the unsigned
     * "modifier" in MySQL. In these cases the size should go between the type
     * and the "modifier", instead of after the modifier. For example
     * CREATE table FOO ( myint INT (10) UNSIGNED . . .) instead of
     * CREATE table FOO ( myint INT UNSIGNED (10) . . .).
     * Type modifiers should be added to <code>typeModifierSet</code> in
     * subclasses.
     */
    protected String appendSize(Column col, String typeName) {
        String upperCaseTypeName = typeName.toUpperCase(Locale.ENGLISH);
        if (fixedSizeTypeNameSet.contains(upperCaseTypeName)) {
            return typeName;
        }
        if (typeName.indexOf('(') != -1) {
            return typeName;
        }


        String size = null;
        int colSize = col.getSize();

        if (colSize<=0  && fractionalTypeNameSet.contains(upperCaseTypeName)){
            // special handling for types with fractions
            // Attention! We abuse @Column(scale=n)
            // One can disable all fractions with @Column(scale=-1)
            if (col.getDecimalDigits() != 0) { // the default
                colSize = col.getDecimalDigits() == -1 ? 0 : col.getDecimalDigits();
            }
            else {
                colSize = getFractionLength(col, typeName);
            }
            size = "(" + colSize + ")";
        } else if (colSize > 0) {
            StringBuilder buf = new StringBuilder(10);
            buf.append("(").append(colSize);
            if (col.getDecimalDigits() > 0)
                buf.append(", ").append(col.getDecimalDigits());
            buf.append(")");
            size = buf.toString();
        }

        return insertSize(typeName, size);
    }

    /**
     * Only get's used if no explicit scale is used (@{code @Column(scale=0)} which is the default).
     * Attention! @{code @Column(scale=-1)} disables the scale of a column
     * @return the fraction length of types which have a fraction
     * @see #fractionalTypeNameSet
     */
    protected int getFractionLength(Column col, String typeName) {
        return defaultFractionLength;
    }

    /**
     * Helper method that inserts a size clause for a given SQL type.
     *
     * @param typeName  The SQL type e.g. INT
     * @param size      The size clause e.g. (10)
     * @return          The typeName + size clause. Usually the size clause will
     *                  be appended to typeName. If the typeName contains a
     *                  marker : {0} or if typeName contains a modifier the
     *                  size clause will be inserted appropriately.
     */
    protected String insertSize(String typeName, String size) {
        if (StringUtil.isEmpty(size)) {
            int idx = typeName.indexOf("{0}");
            if (idx != -1) {
                return typeName.substring(0, idx);
            }
            return typeName;
        }

        int idx = typeName.indexOf("{0}");
        if (idx != -1) {
            // replace '{0}' with size
            String ret = typeName.substring(0, idx);
            if (size != null)
                ret = ret + size;
            if (typeName.length() > idx + 3)
                ret = ret + typeName.substring(idx + 3);
            return ret;
        }
        if (!typeModifierSet.isEmpty()) {
            String s;
            idx = typeName.length();
            int curIdx = -1;
            for (Iterator<String> i = typeModifierSet.iterator(); i.hasNext();) {
                s = i.next();
                if (typeName.toUpperCase(Locale.ENGLISH).indexOf(s) != -1) {
                    curIdx = typeName.toUpperCase(Locale.ENGLISH).indexOf(s);
                    if (curIdx != -1 && curIdx < idx) {
                        idx = curIdx;
                    }
                }
            }
            if(idx != typeName.length()) {
                String ret = typeName.substring(0, idx);
                ret = ret + size;
                ret = ret + ' ' + typeName.substring(idx);
                return ret;
            }
        }
        return typeName + size;
    }

    ///////////
    // Selects
    ///////////

    /**
     * Set the name of the join syntax to use: sql92, traditional, database.
     */
    public void setJoinSyntax(String syntax) {
        if ("sql92".equals(syntax))
            joinSyntax = SYNTAX_SQL92;
        else if ("traditional".equals(syntax))
            joinSyntax = SYNTAX_TRADITIONAL;
        else if ("database".equals(syntax))
            joinSyntax = SYNTAX_DATABASE;
        else if (!StringUtil.isEmpty(syntax))
            throw new IllegalArgumentException(syntax);
    }

    public boolean isImplicitJoin() {
        return false;
    }

    /**
     * Return a SQL string to act as a placeholder for the given column.
     */
    public String getPlaceholderValueString(Column col) {
        switch (col.getType()) {
            case Types.BIGINT:
            case Types.BIT:
            case Types.INTEGER:
            case Types.NUMERIC:
            case Types.SMALLINT:
            case Types.TINYINT:
                return "0";
            case Types.CHAR:
                return (storeCharsAsNumbers) ? "0" : "' '";
            case Types.CLOB:
            case Types.LONGVARCHAR:
            case Types.VARCHAR:
                return "''";
            case Types.DATE:
                return ZERO_DATE_STR;
            case Types.DECIMAL:
            case Types.DOUBLE:
            case Types.FLOAT:
            case Types.REAL:
                return "0.0";
            case Types.TIME:
                return ZERO_TIME_STR;
            case Types.TIMESTAMP:
                return ZERO_TIMESTAMP_STR;
            default:
                return "NULL";
        }
    }

    /**
     * Create a SELECT COUNT statement in the proper join syntax for the
     * given instance.
     */
    public SQLBuffer toSelectCount(Select sel) {
        SQLBuffer selectSQL = new SQLBuffer(this);
        SQLBuffer from;
        sel.addJoinClassConditions();
        if (sel.getFromSelect() != null)
            from = getFromSelect(sel, false);
        else
            from = getFrom(sel, false);
        SQLBuffer where = getWhere(sel, false);

        // if no grouping and no range, we might be able to get by without
        // a subselect
        if (sel.getGrouping() == null && sel.getStartIndex() == 0
            && sel.getEndIndex() == Long.MAX_VALUE) {
            // if the select has no identifier cols, use COUNT(*)
            List aliases = (!sel.isDistinct()) ? Collections.EMPTY_LIST
                : sel.getIdentifierAliases();
            if (useWildCardForCount || aliases.isEmpty()) {
                selectSQL.append("COUNT(*)");
                return toSelect(selectSQL, null, from, where, null, null, null,
                    false, false, 0, Long.MAX_VALUE);
            }

            // if there is a single distinct col, use COUNT(DISTINCT col)
            if (aliases.size() == 1) {
                selectSQL.append("COUNT(DISTINCT ").
                    append(aliases.get(0).toString()).append(")");
                return toSelect(selectSQL, null, from, where, null, null, null,
                    false, false, 0, Long.MAX_VALUE);
            }

            // can we combine distinct cols?
            if (distinctCountColumnSeparator != null) {
                selectSQL.append("COUNT(DISTINCT ");
                for (int i = 0; i < aliases.size(); i++) {
                    if (i > 0) {
                        selectSQL.append(" ");
                        selectSQL.append(distinctCountColumnSeparator);
                        selectSQL.append(" ");
                    }
                    selectSQL.append(aliases.get(i).toString());
                }
                selectSQL.append(")");
                return toSelect(selectSQL, null, from, where, null, null, null,
                    false, false, 0, Long.MAX_VALUE);
            }
        }

        // since we can't combine distinct cols, we have to perform an outer
        // COUNT(*) select using the original select as a subselect in the
        // FROM clause
        assertSupport(supportsSubselect, "SupportsSubselect");

        SQLBuffer subSelect = getSelects(sel, true, false);
        SQLBuffer subFrom = from;
        from = new SQLBuffer(this);
        from.append("(");
        from.append(toSelect(subSelect, null, subFrom, where,
            sel.getGrouping(), sel.getHaving(), null, sel.isDistinct(),
            false, sel.getStartIndex(), sel.getEndIndex(), true, sel));
        from.append(")");
        if (requiresAliasForSubselect)
            from.append(" ").append(Select.FROM_SELECT_ALIAS);

        selectSQL.append("COUNT(*)");
        return toSelect(selectSQL, null, from, null, null, null, null,
            false, false, 0, Long.MAX_VALUE);
    }

    /**
     * Create a DELETE statement for the specified Select. If the
     * database does not support the bulk delete statement (such as
     * cases where a subselect is required and the database doesn't support
     * subselects), this method should return null.
     */
    public SQLBuffer toDelete(ClassMapping mapping, Select sel,
        Object[] params) {
        return toBulkOperation(mapping, sel, null, params, null);
    }

    public SQLBuffer toUpdate(ClassMapping mapping, Select sel,
        JDBCStore store, Object[] params, Map updates) {
        return toBulkOperation(mapping, sel, store, params, updates);
    }

    /**
     * Returns the SQL for a bulk operation, either a DELETE or an UPDATE.
     *
     * @param mapping the mapping against which we are operating
     * @param sel the Select that will constitute the WHERE clause
     * @param store the current store
     * @param updateParams the Map that holds the update parameters; a null
     * value indicates that this is a delete operation
     * @return the SQLBuffer for the update, or <em>null</em> if it is not
     * possible to perform the bulk update
     */
    protected SQLBuffer toBulkOperation(ClassMapping mapping, Select sel,
        JDBCStore store, Object[] params, Map updateParams) {
        SQLBuffer sql = new SQLBuffer(this);
        if (updateParams == null) {
          if (requiresTargetForDelete) {
            sql.append("DELETE ");
            SQLBuffer deleteTargets = getDeleteTargets(sel);
            sql.append(deleteTargets);
            sql.append(" FROM ");
          } else {
            sql.append("DELETE FROM ");
          }
        }
        else
            sql.append("UPDATE ");
        sel.addJoinClassConditions();

        // if there is only a single table in the select, then we can
        // just issue a single DELETE FROM TABLE WHERE <conditions>
        // statement; otherwise, since SQL doesn't allow deleting
        // from one of a multi-table select, we need to issue a subselect
        // like DELETE FROM TABLE WHERE EXISTS
        // (SELECT 1 FROM TABLE t0 WHERE t0.ID = TABLE.ID); also, some
        // databases do not allow aliases in delete statements, which
        // also causes us to use a subselect
        Collection<String> selectedTables = getSelectTableAliases(sel);
        if (selectedTables.size() == 1 && supportsSubselect
            && allowsAliasInBulkClause) {
            SQLBuffer from;
            if (sel.getFromSelect() != null)
                from = getFromSelect(sel, false);
            else
                from = getFrom(sel, false);

            sql.append(from);
            appendUpdates(sel, store, sql, params, updateParams,
                allowsAliasInBulkClause);

            SQLBuffer where = sel.getWhere();
            if (where != null && !where.isEmpty()) {
                sql.append(" WHERE ");
                sql.append(where);
            }
            return sql;
        }

        Table table = mapping.getTable();
        String tableName = getFullName(table, false);

        // only use a  subselect if the where is not empty; otherwise
        // an unqualified delete or update will work
        if (sel.getWhere() == null || sel.getWhere().isEmpty()) {
            sql.append(tableName);
            appendUpdates(sel, store, sql, params, updateParams, false);
            return sql;
        }

        // we need to use a subselect if we are to bulk delete where
        // the select includes multiple tables; if the database
        // doesn't support it, then we need to signal this by returning null
        if (!supportsSubselect || !supportsCorrelatedSubselect)
            return null;

        Column[] pks = mapping.getPrimaryKeyColumns();
        sel.clearSelects();
        sel.setDistinct(true);

        // if we have only a single PK, we can use a non-correlated
        // subquery (using an IN statement), which is much faster than
        // a correlated subquery (since a correlated subquery needs
        // to be executed once for each row in the table)
        if (pks.length == 1) {
            sel.select(pks[0]);
            sql.append(tableName);
            appendUpdates(sel, store, sql, params, updateParams, false);
            sql.append(" WHERE ").
                append(pks[0]).append(" IN (").
                append(sel.toSelect(false, null)).append(")");
        } else {
            sel.clearSelects();
            sel.setDistinct(false);

            // since the select is using a correlated subquery, we
            // only need to select a bogus virtual column
            sel.select("1", null);

            // add in the joins to the table
            Column[] cols = table.getPrimaryKey().getColumns();
            SQLBuffer buf = new SQLBuffer(this);
            buf.append("(");
            for (int i = 0; i < cols.length; i++) {
                if (i > 0)
                    buf.append(" AND ");

                // add in "t0.PK = MYTABLE.PK"
                buf.append(sel.getColumnAlias(cols[i])).append(" = ").
                    append(table).append(catalogSeparator).append(cols[i]);
            }
            buf.append(")");
            sel.where(buf, null);

            sql.append(tableName);
            appendUpdates(sel, store, sql, params, updateParams, false);
            sql.append(" WHERE EXISTS (").
                append(sel.toSelect(false, null)).append(")");
        }
        return sql;
    }

    protected Collection<String> getSelectTableAliases(Select sel) {
        return sel.getTableAliases();
    }

    protected SQLBuffer getDeleteTargets(Select sel) {
      SQLBuffer deleteTargets = new SQLBuffer(this);
      Collection<String> aliases = sel.getTableAliases();
      // Assumes aliases are of the form "TABLENAME t0"
      // or "\"TABLE NAME\" t0"
      for (Iterator<String> itr = aliases.iterator(); itr.hasNext();) {
        String tableAlias = itr.next();
        String[] names = Normalizer.splitName(tableAlias, IdentifierUtil.SPACE);
        if (names.length > 1) {
          if (allowsAliasInBulkClause) {
            deleteTargets.append(names[1]);
          } else {
            deleteTargets.append(toDBName(DBIdentifier.newTable(names[0])));
          }
        } else {
          deleteTargets.append(toDBName(DBIdentifier.newTable(tableAlias)));
        }
        if (itr.hasNext())
          deleteTargets.append(", ");
      }
      return deleteTargets;
    }

    protected void appendUpdates(Select sel, JDBCStore store, SQLBuffer sql,
        Object[] params, Map updateParams, boolean allowAlias) {
        if (updateParams == null || updateParams.size() == 0)
            return;

        // manually build up the SET clause for the UPDATE statement
        sql.append(" SET ");
        ExpContext ctx = new ExpContext(store, params,
            store.getFetchConfiguration());

        // If the updates map contains any version fields, assume that the
        // optimistic lock version data is being handled properly by the
        // caller. Otherwise, give the version indicator an opportunity to
        // add more update clauses as needed.
        boolean augmentUpdates = true;

        for (Iterator i = updateParams.entrySet().iterator(); i.hasNext();) {
            Map.Entry next = (Map.Entry) i.next();
            Path path = (Path) next.getKey();
            FieldMapping fmd = (FieldMapping) path.last();

            if (fmd.isVersion())
                augmentUpdates = false;

            Val val = (Val) next.getValue();
            if (val == null)
                val = new Null();
            Column col = fmd.getColumns()[0];
            if (allowAlias) {
              sql.append(sel.getColumnAlias(col));
            } else {
              sql.append(toDBName(col.getIdentifier()));
            }
            sql.append(" = ");

            ExpState state = val.initialize(sel, ctx, 0);
            // JDBC Paths are always PCPaths; PCPath implements Val
            ExpState pathState = ((Val) path).initialize(sel, ctx, 0);
            calculateValue(val, sel, ctx, state, path, pathState);

            // append the value with a null for the Select; i
            // indicates that the
            int length = val.length(sel, ctx, state);
            for (int j = 0; j < length; j++)
                val.appendTo((allowAlias) ? sel : null, ctx, state, sql, j);

            if (i.hasNext())
                sql.append(", ");
        }

        if (augmentUpdates) {
            Path path = (Path) updateParams.keySet().iterator().next();
            FieldMapping fm = (FieldMapping) path.last();

            ClassMapping meta = fm.getDefiningMapping();
            Map<Column,?> updates = meta.getVersion().getBulkUpdateValues();
            for (Map.Entry e : updates.entrySet()) {
                Column col = (Column) e.getKey();
                Object val = e.getValue();
                sql.append(", ").append(toDBName(col.getIdentifier())).append(" = ");
                // Version update value for Numeric version is encoded in a String
                // to make SQL such as version = version+1 while Time stamp version is parameterized
                if (val instanceof String) {
                    sql.append((String)val);
                } else {
                    sql.appendValue(val);
                }
            }
        }
    }

    /**
     * Create SQL to delete the contents of the specified tables.
     * The default implementation drops all non-deferred RESTRICT foreign key
     * constraints involving the specified tables, issues DELETE statements
     * against the tables, and then adds the dropped constraints back in.
     * Databases with more optimal ways of deleting the contents of several
     * tables should override this method.
     */
    public String[] getDeleteTableContentsSQL(Table[] tables,Connection conn) {
        Collection<String> sql = new ArrayList<>();

        // collect and drop non-deferred physical restrict constraints, and
        // collect the DELETE FROM statements
        Collection<String> deleteSQL = new ArrayList<>(tables.length);
        Collection<ForeignKey> restrictConstraints =
            new LinkedHashSet<>();
        for (int i = 0; i < tables.length; i++) {
            ForeignKey[] fks = tables[i].getForeignKeys();
            for (int j = 0; j < fks.length; j++) {
                if (!fks[j].isLogical() && !fks[j].isDeferred()
                    && fks[j].getDeleteAction() == ForeignKey.ACTION_RESTRICT)
                restrictConstraints.add(fks[j]);
            }

            deleteSQL.add("DELETE FROM " +
                toDBName(tables[i].getFullIdentifier()));
        }

        for(ForeignKey fk : restrictConstraints) {
            String[] constraintSQL = getDropForeignKeySQL(fk,conn);
            sql.addAll(Arrays.asList(constraintSQL));
        }

        // add the delete statements after all the constraint mutations
        sql.addAll(deleteSQL);

        // add the deleted constraints back to the schema
        for (ForeignKey fk : restrictConstraints) {
            String[] constraintSQL = getAddForeignKeySQL(fk);
            sql.addAll(Arrays.asList(constraintSQL));
        }

        return (String[]) sql.toArray(new String[sql.size()]);
    }

    /**
     * Create a SELECT statement in the proper join syntax for the given
     * instance.
     */
    public SQLBuffer toSelect(Select sel, boolean forUpdate,
        JDBCFetchConfiguration fetch) {
        sel.addJoinClassConditions();
        boolean update = forUpdate && sel.getFromSelect() == null;
        SQLBuffer select = getSelects(sel, false, update);
        SQLBuffer ordering = null;
        if (!sel.isAggregate() || sel.getGrouping() != null)
            ordering = sel.getOrdering();
        SQLBuffer from;
        if (sel.getFromSelect() != null)
            from = getFromSelect(sel, forUpdate);
        else
            from = getFrom(sel, update);
        SQLBuffer where = getWhere(sel, update);
        return toSelect(select, fetch, from, where, sel.getGrouping(),
            sel.getHaving(), ordering, sel.isDistinct(), forUpdate,
            sel.getStartIndex(), sel.getEndIndex(), sel);
    }

    /**
     * Return the portion of the select statement between the FROM keyword
     * and the WHERE keyword.
     */
    protected SQLBuffer getFrom(Select sel, boolean forUpdate) {
        SQLBuffer fromSQL = new SQLBuffer(this);
        Collection aliases = sel.getTableAliases();
        if (aliases.size() < 2 || sel.getJoinSyntax() != SYNTAX_SQL92) {
            for (Iterator itr = aliases.iterator(); itr.hasNext();) {
                fromSQL.append(itr.next().toString());
                if (forUpdate && tableForUpdateClause != null)
                    fromSQL.append(" ").append(tableForUpdateClause);
                if (itr.hasNext())
                    fromSQL.append(", ");
            }
            if (aliases.size() < 2 && sel.getParent() != null) {
                // subquery may contain correlated joins
                Iterator itr = sel.getJoinIterator();
                while (itr.hasNext()) {
                    Join join = (Join) itr.next();
                    // append where clause
                    if (join.isCorrelated() && join.getForeignKey() != null) {
                        SQLBuffer where = new SQLBuffer(this);
                        where.append("(").append(toTraditionalJoin(join)).append(")");
                        sel.where(where.getSQL());
                    }
                }
            }
        } else {
            Iterator itr = sel.getJoinIterator();
            boolean first = true;
            while (itr.hasNext()) {
                Join join = (Join) itr.next();
                if (correlatedJoinCondition(join, sel))
                    continue;

                if (join.isCorrelated())
                    toCorrelatedJoin(sel, join, forUpdate, first);
                else
                    fromSQL.append(toSQL92Join(sel, join, forUpdate,
                        first));
                first = false;
                if (itr.hasNext() && join.isCorrelated()) {
                    if (fromSQL.getSQL().length() > 0)
                        fromSQL.append(", ");
                    first = true;
                }
            }

            for (Iterator itr2 = aliases.iterator(); itr2.hasNext();) {
                String tableAlias = itr2.next().toString();
                if (fromSQL.getSQL().indexOf(tableAlias) == -1) {
                    if (!first && fromSQL.getSQL().length() > 0)
                        fromSQL.append(", ");
                    fromSQL.append(tableAlias);
                    if (forUpdate && tableForUpdateClause != null)
                        fromSQL.append(" ").append(tableForUpdateClause);
                    first = false;
                }
            }
        }
        return fromSQL;
    }

    private boolean correlatedJoinCondition(Join join, Select sel) {
        if (!join.isCorrelated())
            return false;
        Iterator itr = sel.getJoinIterator();
        boolean skip = false;
        //if table1 in join is in the main query, table2 is in
        //subquery, and table2 participates in other joins
        //in subquery, the join condition can only be placed in
        //the where clause in the subquery
        while (itr.hasNext()) {
            Join join1 = (Join) itr.next();
            if (join == join1 && !join.isForeignKeyInversed()) {
                continue;
            }
            if (join.getIndex2() == join1.getIndex1() ||
                join.getIndex2() == join1.getIndex2()) {
                skip = true;
                if (join.getForeignKey() != null){
                    SQLBuffer where = new SQLBuffer(this);
                    where.append("(").append(toTraditionalJoin(join)).append(")");
                    sel.where(where.getSQL());
                }
                break;
            }
        }
        return skip;
    }


    /**
     * Return the FROM clause for a select that selects from a tmp table
     * created by an inner select.
     */
    protected SQLBuffer getFromSelect(Select sel, boolean forUpdate) {
        SQLBuffer fromSQL = new SQLBuffer(this);
        fromSQL.append("(");
        fromSQL.append(toSelect(sel.getFromSelect(), forUpdate, null));
        fromSQL.append(")");
        if (requiresAliasForSubselect)
            fromSQL.append(" ").append(Select.FROM_SELECT_ALIAS);
        return fromSQL;
    }

    /**
     * Return the WHERE portion of the select statement, or null if no where
     * conditions.
     */
    protected SQLBuffer getWhere(Select sel, boolean forUpdate) {
        Joins joins = sel.getJoins();
        if (sel.getJoinSyntax() == SYNTAX_SQL92
            || joins == null || joins.isEmpty())
            return sel.getWhere();

        SQLBuffer where = new SQLBuffer(this);
        if (sel.getWhere() != null)
            where.append(sel.getWhere());
        if (joins != null)
            sel.append(where, joins);
        return where;
    }

    /**
     * Use the given join instance to create SQL joining its tables in
     * the traditional style.
     */
    public SQLBuffer toTraditionalJoin(Join join) {
        ForeignKey fk = join.getForeignKey();
        if (fk == null)
            return null;

        boolean inverse = join.isForeignKeyInversed();
        Column[] from = (inverse) ? fk.getPrimaryKeyColumns()
            : fk.getColumns();
        Column[] to = (inverse) ? fk.getColumns()
            : fk.getPrimaryKeyColumns();

        // do column joins
        SQLBuffer buf = new SQLBuffer(this);
        int count = 0;
        for (int i = 0; i < from.length; i++, count++) {
            if (count > 0)
                buf.append(" AND ");
            buf.append(join.getAlias1()).append(".").append(from[i]);
            buf.append(" = ");
            buf.append(join.getAlias2()).append(".").append(to[i]);
        }

        // do constant joins
        Column[] constCols = fk.getConstantColumns();
        for (int i = 0; i < constCols.length; i++, count++) {
            if (count > 0)
                buf.append(" AND ");
            if (inverse)
                buf.appendValue(fk.getConstant(constCols[i]), constCols[i]);
            else
                buf.append(join.getAlias1()).append(".").
                    append(constCols[i]);
            buf.append(" = ");

            if (inverse)
                buf.append(join.getAlias2()).append(".").
                    append(constCols[i]);
            else
                buf.appendValue(fk.getConstant(constCols[i]), constCols[i]);
        }

        Column[] constColsPK = fk.getConstantPrimaryKeyColumns();
        for (int i = 0; i < constColsPK.length; i++, count++) {
            if (count > 0)
                buf.append(" AND ");
            if (inverse)
                buf.append(join.getAlias1()).append(".").
                    append(constColsPK[i]);
            else
                buf.appendValue(fk.getPrimaryKeyConstant(constColsPK[i]),
                    constColsPK[i]);
            buf.append(" = ");

            if (inverse)
                buf.appendValue(fk.getPrimaryKeyConstant(constColsPK[i]),
                    constColsPK[i]);
            else
                buf.append(join.getAlias2()).append(".").
                    append(constColsPK[i]);
        }
        return buf;
    }

    /**
     * Use the given join instance to create SQL joining its tables in
     * the SQL92 style.
     */
    public SQLBuffer toSQL92Join(Select sel, Join join, boolean forUpdate,
        boolean first) {
        SQLBuffer buf = new SQLBuffer(this);

        if (first) {
            buf.append(join.getTable1()).append(" ").
                append(join.getAlias1());
            if (forUpdate && tableForUpdateClause != null)
                buf.append(" ").append(tableForUpdateClause);
        }

        buf.append(" ");
        if (join.getType() == Join.TYPE_OUTER)
            buf.append(outerJoinClause);
        else if (join.getType() == Join.TYPE_INNER)
            buf.append(innerJoinClause);
        else // cross
            buf.append(crossJoinClause);
        buf.append(" ");

        buf.append(join.getTable2()).append(" ").append(join.getAlias2());
        if (forUpdate && tableForUpdateClause != null)
            buf.append(" ").append(tableForUpdateClause);

        if (join.getForeignKey() != null)
            buf.append(" ON ").append(toTraditionalJoin(join));
        else if (requiresConditionForCrossJoin &&
                join.getType() == Join.TYPE_CROSS)
            buf.append(" ON (1 = 1)");

        return buf;
    }

    private SQLBuffer toCorrelatedJoin(Select sel, Join join, boolean forUpdate,
        boolean first) {
        if (join.getForeignKey() != null){
            SQLBuffer where = new SQLBuffer(this);
            where.append("(").append(toTraditionalJoin(join)).append(")");
            sel.where(where.getSQL());
        }

        return null;
    }

    /**
     * Use the given join instance to create SQL joining its tables in
     * the database's native syntax. Throws an exception by default.
     */
    public SQLBuffer toNativeJoin(Join join) {
        throw new UnsupportedException();
    }

    /**
     * Returns if the given foreign key can be eagerly loaded using other joins.
     */
    public boolean canOuterJoin(int syntax, ForeignKey fk) {
        return syntax != SYNTAX_TRADITIONAL;
    }

    /**
     * Combine the given components into a SELECT statement.
     */
    public SQLBuffer toSelect(SQLBuffer selects, JDBCFetchConfiguration fetch,
        SQLBuffer from, SQLBuffer where, SQLBuffer group,
        SQLBuffer having, SQLBuffer order,
        boolean distinct, boolean forUpdate, long start, long end) {
        return toOperation(getSelectOperation(fetch), selects, from, where,
            group, having, order, distinct, start, end,
            getForUpdateClause(fetch, forUpdate, null));
    }

    /**
     * Combine the given components into a SELECT statement.
     */
    protected SQLBuffer toSelect(SQLBuffer selects,
        JDBCFetchConfiguration fetch,
        SQLBuffer from, SQLBuffer where, SQLBuffer group,
        SQLBuffer having, SQLBuffer order,
        boolean distinct, boolean forUpdate, long start, long end,
        boolean subselect, Select sel) {
        return toOperation(getSelectOperation(fetch), selects, from, where,
            group, having, order, distinct, start, end,
            getForUpdateClause(fetch, forUpdate, null), subselect);
    }

    public SQLBuffer toSelect(SQLBuffer selects, JDBCFetchConfiguration fetch,
            SQLBuffer from, SQLBuffer where, SQLBuffer group,
            SQLBuffer having, SQLBuffer order,
            boolean distinct, boolean forUpdate, long start, long end,
            boolean subselect, boolean checkTableForUpdate) {
            return toOperation(getSelectOperation(fetch), selects, from, where,
                    group, having, order, distinct, start, end,
                    getForUpdateClause(fetch, forUpdate, null), subselect,
                    checkTableForUpdate);
        }

    /**
     * Combine the given components into a SELECT statement.
     */
    protected SQLBuffer toSelect(SQLBuffer selects,
        JDBCFetchConfiguration fetch,
        SQLBuffer from, SQLBuffer where, SQLBuffer group,
        SQLBuffer having, SQLBuffer order,
        boolean distinct, boolean forUpdate, long start, long end,
        Select sel) {
        return toOperation(getSelectOperation(fetch), selects, from, where,
            group, having, order, distinct, start, end,
            getForUpdateClause(fetch, forUpdate, sel));
    }

    /**
     * Get the update clause for the query based on the
     * updateClause and isolationLevel hints
     */
    protected String getForUpdateClause(JDBCFetchConfiguration fetch,
        boolean isForUpdate, Select sel) {
        if (fetch != null && fetch.getIsolation() != -1) {
            throw new InvalidStateException(_loc.get(
                "isolation-level-config-not-supported", getClass().getName()));
        } else if (isForUpdate && !simulateLocking) {
            assertSupport(supportsSelectForUpdate, "SupportsSelectForUpdate");
            return forUpdateClause;
        } else {
            return null;
        }
    }

    /**
     * Return true if the dictionary uses isolation level to compute the
     * returned getForUpdateClause() SQL clause.
     */
    public boolean supportsIsolationForUpdate() {
        return false;
    }

    /**
     * Return the "SELECT" operation clause, adding any available hints, etc.
     */
    public String getSelectOperation(JDBCFetchConfiguration fetch) {
        return "SELECT";
    }

    /**
     * Return the SQL for the given selecting operation.
     */
    public SQLBuffer toOperation(String op, SQLBuffer selects,
        SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer having,
        SQLBuffer order, boolean distinct, long start, long end,
        String forUpdateClause) {
        return toOperation(op, selects, from, where, group, having, order,
            distinct, start, end, forUpdateClause, false);
    }

    /**
     * Return the SQL for the given selecting operation.
     */
    public SQLBuffer toOperation(String op, SQLBuffer selects,
        SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer having,
        SQLBuffer order, boolean distinct, long start, long end,
        String forUpdateClause, boolean subselect) {
        return toOperation(op, selects, from, where, group, having, order,
                distinct, start, end, forUpdateClause, subselect, false);
    }

    /**
     * Return the SQL for the given selecting operation.
     */
    private SQLBuffer toOperation(String op, SQLBuffer selects, SQLBuffer from,
            SQLBuffer where, SQLBuffer group, SQLBuffer having, SQLBuffer order,
            boolean distinct, long start, long end, String forUpdateClause,
            boolean subselect, boolean checkTableForUpdate) {
        SQLBuffer buf = new SQLBuffer(this);
        buf.append(op);

        boolean range = start != 0 || end != Long.MAX_VALUE;
        if (range && rangePosition == RANGE_PRE_DISTINCT)
            appendSelectRange(buf, start, end, subselect);
        if (distinct)
            buf.append(" DISTINCT");
        if (range && rangePosition == RANGE_POST_DISTINCT)
            appendSelectRange(buf, start, end, subselect);

        buf.append(" ").append(selects).append(" FROM ").append(from);

        if (checkTableForUpdate
                && (StringUtil.isEmpty(forUpdateClause) && !StringUtil.isEmpty(tableForUpdateClause))) {
            buf.append(" ").append(tableForUpdateClause);
        }

        if (where != null && !where.isEmpty())
            buf.append(" WHERE ").append(where);
        if (group != null && !group.isEmpty())
            buf.append(" GROUP BY ").append(group);
        if (having != null && !having.isEmpty()) {
            assertSupport(supportsHaving, "SupportsHaving");
            buf.append(" HAVING ").append(having);
        }
        if (order != null && !order.isEmpty())
            buf.append(" ORDER BY ").append(order);
        if (range && rangePosition == RANGE_POST_SELECT)
            appendSelectRange(buf, start, end, subselect);
        if (forUpdateClause != null)
            buf.append(" ").append(forUpdateClause);
        if (range && rangePosition == RANGE_POST_LOCK)
            appendSelectRange(buf, start, end, subselect);
        return buf;
    }

    /**
     * If this dictionary can select ranges,
     * use this method to append the range SQL.
     */
    protected void appendSelectRange(SQLBuffer buf, long start, long end,
        boolean subselect) {
    }

    /**
     * Return the portion of the select statement between the SELECT keyword
     * and the FROM keyword.
     */
    protected SQLBuffer getSelects(Select sel, boolean distinctIdentifiers,
        boolean forUpdate) {
        // append the aliases for all the columns
        SQLBuffer selectSQL = new SQLBuffer(this);
        List aliases;
        if (distinctIdentifiers)
            aliases = sel.getIdentifierAliases();
        else
            aliases = sel.getSelectAliases();

        Object alias;
        for (int i = 0; i < aliases.size(); i++) {
            alias = aliases.get(i);
            if (alias instanceof String) {
                alias = getNamingUtil().convertAlias((String)alias);
            }
            appendSelect(selectSQL, alias, sel, i);
            if (i < aliases.size() - 1)
                selectSQL.append(", ");
        }
        return selectSQL;
    }

    /**
     * Append <code>elem</code> to <code>selectSQL</code>.
     * @param selectSQL The SQLBuffer to append to.
     * @param elem A {@link SQLBuffer} or a {@link String} to append.
     *
     * @since 1.1.0
     */
    protected void appendSelect(SQLBuffer selectSQL, Object elem, Select sel, int idx) {
        if (elem instanceof SQLBuffer)
            selectSQL.append((SQLBuffer) elem);
        else
            selectSQL.append(elem.toString());
    }

    /**
     * Returns true if a "FOR UPDATE" clause can be used for the specified
     * Select object.
     */
    public boolean supportsLocking(Select sel) {
        if (sel.isAggregate())
            return false;
        if (!supportsSelectForUpdate)
            return false;
        if (!supportsLockingWithSelectRange && (sel.getStartIndex() != 0
            || sel.getEndIndex() != Long.MAX_VALUE))
            return false;

        // only inner select is locked
        if (sel.getFromSelect() != null)
            sel = sel.getFromSelect();

        if (!supportsLockingWithDistinctClause && sel.isDistinct())
            return false;
        if (!supportsLockingWithMultipleTables
            && sel.getTableAliases().size() > 1)
            return false;
        if (!supportsLockingWithOrderClause && sel.getOrdering() != null)
            return false;
        if (!supportsLockingWithOuterJoin || !supportsLockingWithInnerJoin) {
            for (Iterator itr = sel.getJoinIterator(); itr.hasNext();) {
                Join join = (Join) itr.next();
                if (!supportsLockingWithOuterJoin
                    && join.getType() == Join.TYPE_OUTER)
                    return false;
                if (!supportsLockingWithInnerJoin
                    && join.getType() == Join.TYPE_INNER)
                    return false;
            }
        }
        return true;
    }

    /**
     * Return false if the given select requires a forward-only result set.
     */
    public boolean supportsRandomAccessResultSet(Select sel,
        boolean forUpdate) {
        return !sel.isAggregate();
    }

    /**
     * Assert that the given dictionary flag is true. If it is not true,
     * throw an error saying that the given setting needs to return true for
     * the current operation to work.
     */
    public void assertSupport(boolean feature, String property) {
        if (!feature)
            throw new UnsupportedException(_loc.get("feature-not-supported",
                getClass(), property));
    }

    ////////////////////
    // Query functions
    ////////////////////

    /**
     * Invoke this database's substring function.
     * Numeric parameters are inlined if possible. This is to handle grouping by SUBSTRING -
     * most databases do not allow parameter binding in this case.
     *
     * @param buf the SQL buffer to write the substring invocation to
     * @param str a query value representing the target string
     * @param start a query value representing the start index
     * @param length a query value representing the length of substring, or null for none
     */
    public void substring(SQLBuffer buf, FilterValue str, FilterValue start,
        FilterValue length) {
        buf.append(substringFunctionName).append("(");
        str.appendTo(buf);
        buf.append(", ");
        if (start.getValue() instanceof Number) {
            buf.append(Long.toString(toLong(start)));
        } else {
            start.appendTo(buf);
        }
        if (length != null) {
            buf.append(", ");
            if (length.getValue() instanceof Number) {
                buf.append(Long.toString(toLong(length)));
            } else {
                length.appendTo(buf);
            }
        }
        buf.append(")");
    }

    long toLong(FilterValue litValue) {
        return ((Number) litValue.getValue()).longValue();
    }

    /**
     * Invoke this database's indexOf function.
     *
     * @param buf the SQL buffer to write the indexOf invocation to
     * @param str a query value representing the target string
     * @param find a query value representing the search string
     * @param start a query value representing the start index, or null
     * to start at the beginning
     */
    public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
        FilterValue start) {
        buf.append("(INSTR((");
        if (start != null)
            substring(buf, str, start, null);
        else
            str.appendTo(buf);
        buf.append("), (");
        find.appendTo(buf);
        buf.append("))");
        if (start != null) {
            buf.append(" - 1  + ");
            start.appendTo(buf);
        }
        buf.append(")");
    }

    /**
     * Append the numeric parts of a mathematical function.
     *
     * @param buf the SQL buffer to write the math function
     * @param op the mathematical operation to perform
     * @param lhs the left hand side of the math function
     * @param rhs the right hand side of the math function
     */
    public void mathFunction(SQLBuffer buf, String op, FilterValue lhs,
        FilterValue rhs) {
        boolean castlhs = false;
        boolean castrhs = false;
        Class lc = Filters.wrap(lhs.getType());
        Class rc = Filters.wrap(rhs.getType());
        int type = 0;
        if (requiresCastForMathFunctions && (lc != rc
            || (lhs.isConstant() || rhs.isConstant()))) {
            Class c = Filters.promote(lc, rc);
            type = getJDBCType(JavaTypes.getTypeCode(c), false);
            if (type != Types.VARBINARY && type != Types.BLOB) {
                castlhs = (lhs.isConstant() && rhs.isConstant()) || lc != c;
                castrhs = (lhs.isConstant() && rhs.isConstant()) || rc != c;
            }
        }

        boolean mod = "MOD".equals(op);
        if (mod) {
            if (supportsModOperator)
                op = "%";
            else
                buf.append(op);
        }
        buf.append("(");

        if (castlhs)
            appendCast(buf, lhs, type);
        else
            lhs.appendTo(buf);

        if (mod && !supportsModOperator)
            buf.append(", ");
        else
            buf.append(" ").append(op).append(" ");

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

        buf.append(")");
    }

    /**
     * Append a comparison.
     *
     * @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
     */
    public void comparison(SQLBuffer buf, String op, FilterValue lhs,
        FilterValue rhs) {
        boolean lhsxml = lhs.getXPath() != null;
        boolean rhsxml = rhs.getXPath() != null;
        if (lhsxml || rhsxml) {
            appendXmlComparison(buf, op, lhs, rhs, lhsxml, rhsxml);
            return;
        }
        boolean castlhs = false;
        boolean castrhs = false;
        Class lc = Filters.wrap(lhs.getType());
        Class rc = Filters.wrap(rhs.getType());

        // special case of comparison of two boolean constants
        // because some databases do not like false = false or false = true
        // but all databases understand 1 = 0 or 0 <> 1 etc.
        if (lc == rc && lc == Boolean.class && lhs.isConstant() && rhs.isConstant()) {
            String lvalue = Boolean.TRUE.equals(lhs.getValue()) ? "1" : "0";
            String rvalue = Boolean.TRUE.equals(rhs.getValue()) ? "1" : "0";
            buf.append(lvalue).append(op).append(rvalue);
            return;
        }
        int type = 0;
        if (requiresCastForComparisons && (lc != rc
            || (lhs.isConstant() && rhs.isConstant()))) {
            Class c = Filters.promote(lc, rc);
            type = getJDBCType(JavaTypes.getTypeCode(c), false);
            if (type != Types.VARBINARY && type != Types.BLOB) {
                castlhs = (lhs.isConstant() && rhs.isConstant()) || lc != c;
                castrhs = (lhs.isConstant() && rhs.isConstant()) || rc != c;
                castlhs = castlhs && lhs.requiresCast();
                castrhs = castrhs && rhs.requiresCast();
            }
        }

        if (castlhs)
            appendCast(buf, lhs, type);
        else
            lhs.appendTo(buf);

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

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

    /**
     * If this dictionary supports XML type,
     * use this method to append xml predicate.
     */
    public void appendXmlComparison(SQLBuffer buf, String op, FilterValue lhs,
        FilterValue rhs, boolean lhsxml, boolean rhsxml) {
        assertSupport(supportsXMLColumn, "SupportsXMLColumn");
    }

    /**
     * Append SQL for the given numeric value to the buffer, casting as needed.
     */
    protected void appendNumericCast(SQLBuffer buf, FilterValue val) {
        if (val.isConstant())
            appendCast(buf, val, Types.NUMERIC);
        else
            val.appendTo(buf);
    }

    /**
     * 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, Object 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 = "";

        buf.append(pre);
        if (val instanceof FilterValue)
            ((FilterValue) val).appendTo(buf);
        else if (val instanceof SQLBuffer)
            buf.append(((SQLBuffer) val));
        else
            buf.append(val.toString());
        buf.append(mid);
        buf.append(getTypeName(type));
        appendLength(buf, type);
        buf.append(post);
    }

    protected void appendLength(SQLBuffer buf, int type) {
    }


    /**
     * add CAST for a function operator where operand is a param
     * @param func  function name
     * @param val
     * @return updated func
     */
    public String addCastAsType(String func, Val val) {
        return null;
    }


    ///////////
    // DDL SQL
    ///////////

    /**
     * Increment the reference count of any table components that this
     * dictionary adds that are not used by mappings. Does nothing by default.
     */
    public void refSchemaComponents(Table table) {
    }

    /**
     * Returns the name of the column using database specific delimiters.
     */
    public DBIdentifier getColumnIdentifier(Column column) {
        if (column == null) {
            return DBIdentifier.NULL;
        }
        return column.getIdentifier();
    }

    public String getColumnDBName(Column column) {
        return toDBName(getColumnIdentifier(column));
    }

    /**
     * Returns the full name of the table, including the schema (delimited
     * by {@link #catalogSeparator}).
     */
    public DBIdentifier getFullIdentifier(Table table, boolean logical) {
        if (!useSchemaName || DBIdentifier.isNull(table.getSchemaIdentifier()))
            return table.getIdentifier();
        return table.getFullIdentifier();
    }

    public String getFullName(Table table, boolean logical) {
        if (!useSchemaName || DBIdentifier.isNull(table.getSchemaIdentifier()))
            return toDBName(table.getIdentifier());
        return toDBName(table.getFullIdentifier());
    }

    /**
     * Returns the full name of the index, including the schema (delimited
     * by the result of {@link #catalogSeparator}).
     */

    public String getFullName(Index index) {
        if (!useSchemaName || DBIdentifier.isNull(index.getSchemaIdentifier()))
            return toDBName(index.getIdentifier());
        return toDBName(index.getFullIdentifier());
    }

    /**
     * Returns the full name of the sequence, including the schema (delimited
     * by the result of {@link #catalogSeparator}).
     */

    public String getFullName(Sequence seq) {
        if (!useSchemaName || DBIdentifier.isNull(seq.getSchemaIdentifier()))
            return toDBName(seq.getIdentifier());
        return toDBName(seq.getFullIdentifier());
    }

    /**
     * Return the subset of the words in reservedWordSet that cannot be used as
     * valid column names for the current DB. If the column name is invalid the
     * getValidColumnName method of the DB dictionary should be invoked to make
     * it valid.
     *
     * @see #getValidColumnName(org.apache.openjpa.jdbc.identifier.DBIdentifier, org.apache.openjpa.jdbc.schema.Table)
     */
    public final Set<String> getInvalidColumnWordSet() {
        return invalidColumnWordSet;
    }

    /**
     * Make any necessary changes to the given table name to make it valid for
     * the current DB.
     * @deprecated
     */
    @Deprecated
    public String getValidTableName(String name, Schema schema) {
        return getValidTableName(DBIdentifier.newTable(name), schema).getName();
    }

    /**
     * Make any necessary changes to the given table name to make it valid for
     * the current DB.
     */
    public DBIdentifier getValidTableName(DBIdentifier name, Schema schema) {
        return namingUtil.getValidTableIdentifier(name, schema, maxTableNameLength);
    }

    /**
     * Make any necessary changes to the given sequence name to make it valid
     * for the current DB.
     * @deprecated
     */
    @Deprecated
    public String getValidSequenceName(String name, Schema schema) {
        return getValidSequenceName(DBIdentifier.newSequence(name), schema).getName();
    }

    /**
     * Make any necessary changes to the given sequence name to make it valid
     * for the current DB.
     */
    public DBIdentifier getValidSequenceName(DBIdentifier name, Schema schema) {
        return namingUtil.getValidSequenceIdentifier(name, schema, maxTableNameLength);
    }

    /**
     * Make any necessary changes to the given column name to make it valid
     * for the current DB.  The column name will be made unique for the
     * specified table.
     * @deprecated
     */
    @Deprecated
    public String getValidColumnName(String name, Table table) {
        return getValidColumnName(DBIdentifier.newColumn(name), table, true).getName();
    }

    /**
     * Make any necessary changes to the given column name to make it valid
     * for the current DB.  The column name will be made unique for the
     * specified table.
     */
    public DBIdentifier getValidColumnName(DBIdentifier name, Table table) {
        return getValidColumnName(name, table, true);
    }

    /**
     * Make any necessary changes to the given column name to make it valid
     * for the current DB.  If checkForUniqueness is true, the column name will
     * be made unique for the specified table.
     * @deprecated
     */
    @Deprecated
    public String getValidColumnName(String name, Table table,
        boolean checkForUniqueness) {
        return getValidColumnName(DBIdentifier.newColumn(name), table, checkForUniqueness).toString();
    }

    /**
     * Make any necessary changes to the given column name to make it valid
     * for the current DB.  If checkForUniqueness is true, the column name will
     * be made unique for the specified table.
     */
    public DBIdentifier getValidColumnName(DBIdentifier name, Table table,
        boolean checkForUniqueness) {
        return getNamingUtil().getValidColumnIdentifier(name, table, maxColumnNameLength,
            checkForUniqueness);
    }

    /**
     * Make any necessary changes to the given primary key name to make it
     * valid for the current DB.
     */
    public String getValidPrimaryKeyName(String name, Table table) {
        while (name.startsWith("_"))
            name = name.substring(1);
        return makeNameValid("P_" + name, table.getSchema().getSchemaGroup(),
            maxConstraintNameLength, NAME_ANY);
    }

    /**
     * Make any necessary changes to the given foreign key name to make it
     * valid for the current DB.
     * @deprecated
     */
    @Deprecated
    public String getValidForeignKeyName(String name, Table table,
        Table toTable) {
        return getValidForeignKeyName(DBIdentifier.newForeignKey(name), table,
            toTable).getName();
    }

    /**
     * Make any necessary changes to the given foreign key name to make it
     * valid for the current DB.
     */
    public DBIdentifier getValidForeignKeyName(DBIdentifier name, Table table,
        Table toTable) {
        return namingUtil.getValidForeignKeyIdentifier(name, table, toTable, maxConstraintNameLength);
    }

    /**
     * Make any necessary changes to the given index name to make it valid
     * for the current DB.
     * @deprecated
     */
    @Deprecated
    public String getValidIndexName(String name, Table table) {
        return getValidIndexName(DBIdentifier.newIndex(name), table).getName();
    }

    /**
     * Make any necessary changes to the given index name to make it valid
     * for the current DB.
     */
    public DBIdentifier getValidIndexName(DBIdentifier name, Table table) {
        return getNamingUtil().getValidIndexIdentifier(name, table, maxIndexNameLength);
    }

    /**
     * Make any necessary changes to the given unique constraint name to make
     * it valid for the current DB.
     * @deprecated
     */
    @Deprecated
    public String getValidUniqueName(String name, Table table) {
        return getValidUniqueName(DBIdentifier.newConstraint(name), table).getName();
    }

    /**
     * Make any necessary changes to the given unique constraint name to make
     * it valid for the current DB.
     */
    public DBIdentifier getValidUniqueName(DBIdentifier name, Table table) {
        return namingUtil.getValidUniqueIdentifier(name, table, maxConstraintNameLength);
    }

    /**
     * Shorten the specified name to the specified target name. This will
     * be done by first stripping out the vowels, and then removing
     * characters from the middle of the word until it reaches the target
     * length.
     */
    public static String shorten(String name, int targetLength) {
        if (name == null || name.length() <= targetLength)
            return name;

        StringBuilder nm = new StringBuilder(name);
        while (nm.length() > targetLength) {
            if (!stripVowel(nm)) {
                // cut out the middle char
                nm.replace(nm.length() / 2, (nm.length() / 2) + 1, "");
            }
        }
        return nm.toString();
    }

    /**
     * Remove vowels from the specified StringBuilder.
     *
     * @return true if any vowels have been removed
     */
    private static boolean stripVowel(StringBuilder name) {
        if (name == null || name.length() == 0)
            return false;

        char[] vowels = { 'A', 'E', 'I', 'O', 'U', };
        for (int i = 0; i < vowels.length; i++) {
            int index = name.toString().toUpperCase(Locale.ENGLISH).indexOf(vowels[i]);
            if (index != -1) {
                name.replace(index, index + 1, "");
                return true;
            }
        }
        return false;
    }

    /**
     * Shortens the given name to the given maximum length, then checks that
     * it is not a reserved word. If it is reserved, appends a "0". If
     * the name conflicts with an existing schema component, the last
     * character is replace with '0', then '1', etc.
     * Note that the given max len may be 0 if the database metadata is
     * incomplete.
     * @deprecated
     */
    @Deprecated
    protected String makeNameValid(String name, NameSet set, int maxLen,
        int nameType) {
        return makeNameValid(name, set, maxLen, nameType, true);
    }

    /**
     * Shortens the given name to the given maximum length, then checks that
     * it is not a reserved word. If it is reserved, appends a "0". If
     * the name conflicts with an existing schema component, the last
     * character is replace with '0', then '1', etc.
     * Note that the given max len may be 0 if the database metadata is
     * incomplete.
     */
    protected DBIdentifier makeNameValid(DBIdentifier name, NameSet set, int maxLen,
        int nameType) {
        return makeNameValid(name, set, maxLen, nameType, true);
    }

    /**
     * Shortens the given name to the given maximum length, then checks that
     * it is not a reserved word. If it is reserved, appends a "0". If
     * the name conflicts with an existing schema component and uniqueness
     * checking is enabled, the last character is replace with '0', then
     * '1', etc.
     * Note that the given max len may be 0 if the database metadata is
     * incomplete.
     *
     * Note: If the name is delimited, make sure the ending delimiter is
     * not stripped off.
     */
    protected String makeNameValid(String name, NameSet set, int maxLen,
        int nameType, boolean checkForUniqueness) {
        return namingUtil.makeNameValid(name, set,
            maxLen, nameType, checkForUniqueness).toString();
    }

    /**
     * Shortens the given name to the given maximum length, then checks that
     * it is not a reserved word. If it is reserved, appends a "0". If
     * the name conflicts with an existing schema component and uniqueness
     * checking is enabled, the last character is replace with '0', then
     * '1', etc.
     * Note that the given max len may be 0 if the database metadata is
     * incomplete.
     *
     * Note: If the name is delimited, make sure the ending delimiter is
     * not stripped off.
     */
    protected DBIdentifier makeNameValid(DBIdentifier name, NameSet set, int maxLen,
        int nameType, boolean checkForUniqueness) {
        return namingUtil.makeIdentifierValid(name, set,
            maxLen, checkForUniqueness);
    }

    /**
     * Return a series of SQL statements to create the given table, complete
     * with columns. Indexes and constraints will be created separately.
     */
    public String[] getCreateTableSQL(Table table, SchemaGroup group) {
        return getCreateTableSQL(table);
    }

    /**
     * Return a series of SQL statements to create the given table, complete
     * with columns. Indexes and constraints will be created separately.
     */
    public String[] getCreateTableSQL(Table table) {
        StringBuilder buf = new StringBuilder();
        String tableName =
            checkNameLength(getFullIdentifier(table, false), maxTableNameLength, "long-table-name",
                tableLengthIncludesSchema);
        buf.append("CREATE TABLE ").append(tableName);
        if (supportsComments && table.hasComment()) {
            buf.append(" ");
            comment(buf, table.getComment());
            buf.append("\n    (");
        } else {
            buf.append(" (");
        }

        // do this before getting the columns so we know how to handle
        // the last comma
        StringBuilder endBuf = new StringBuilder();
        PrimaryKey pk = table.getPrimaryKey();
        String pkStr;
        if (pk != null) {
            pkStr = getPrimaryKeyConstraintSQL(pk);
            if (pkStr != null)
                endBuf.append(pkStr);
        }

        Unique[] unqs = table.getUniques();
        String unqStr;
        for (int i = 0; i < unqs.length; i++) {
            unqStr = getUniqueConstraintSQL(unqs[i]);
            if (unqStr != null) {
                if (endBuf.length() > 0)
                    endBuf.append(", ");
                endBuf.append(unqStr);
            }
        }

        Column[] cols = table.getColumns();
        for (int i = 0; i < cols.length; i++) {
            buf.append(getDeclareColumnSQL(cols[i], false));
            if (i < cols.length - 1 || endBuf.length() > 0)
                buf.append(", ");
            if (supportsComments && cols[i].hasComment()) {
                comment(buf, cols[i].getComment());
                buf.append("\n    ");
            }
        }

        buf.append(endBuf.toString());
        buf.append(")");
        return new String[]{ buf.toString() };
    }

    public int getBatchFetchSize(int batchFetchSize) {
        return batchFetchSize;
    }

    protected StringBuilder comment(StringBuilder buf, String comment) {
        return buf.append("-- ").append(comment);
    }

    /**
     * Return a series of SQL statements to drop the given table. Indexes
     * will be dropped separately. Returns
     * <code>DROP TABLE &lt;table name&gt;</code> by default.
     */
    public String[] getDropTableSQL(Table table) {
        String drop = MessageFormat.format(dropTableSQL, new Object[]{
            getFullName(table, false) });
        return new String[]{ drop };
    }

    /**
     * Return a series of SQL statements to create the given sequence. Returns
     * <code>CREATE SEQUENCE &lt;sequence name&gt;[ START WITH &lt;start&gt;]
     * [ INCREMENT BY &lt;increment&gt;]</code> by default.
     */
    public String[] getCreateSequenceSQL(Sequence seq) {
        return commonCreateAlterSequenceSQL(seq, true);
    }

    public String getAlterSequenceSQL(Sequence seq) {
        return commonCreateAlterSequenceSQL(seq, false)[0];
    }

    private String[] commonCreateAlterSequenceSQL(Sequence seq, boolean create) {
        if (nextSequenceQuery == null)
            return null;

        //We need a place to detect if the user is setting the 'useNativeSequenceCache' property.
        //While in previous releases this property had meaning, it is no longer useful
        //given the code added via OPENJPA-1327.  As such, we need to warn user's the
        //property no longer has meaning.  While it would be nice to have a better way
        //to detect if the useNativeSequenceCache property has been set, the best we can do
        //is detect the variable in this code path as this is the path a user's code
        //would go down if they are still executing code which actually made use of
        //the support provided via setting useNativeSequenceCache.
        if (!useNativeSequenceCache && logNativeSequenceCacheWarning){
            log.warn(_loc.get("sequence-cache-warning"));
            logNativeSequenceCacheWarning=false;
        }

        StringBuilder buf = new StringBuilder();
        buf.append(create ? "CREATE" : "ALTER").append(" SEQUENCE ");

        //Strip off the schema and verify the sequence name is within the legal length, NOT
        //the schema name + sequence name.
        checkNameLength(toDBName(seq.getFullIdentifier().getUnqualifiedName()),
            maxTableNameLength, "long-seq-name");
        //Now use the full sequence name (schema + sequence name).
        String seqName = getFullName(seq);

        buf.append(seqName);
        if (create && seq.getInitialValue() != 0)
            buf.append(" START WITH ").append(seq.getInitialValue());
        if ((seq.getIncrement() >= 1) || (seq.getAllocate() >= 1))
            buf.append(" INCREMENT BY ").append(seq.getIncrement() * seq.getAllocate());
        return new String[]{ buf.toString() };
    }

    /**
     * Return a series of SQL statements to drop the given sequence. Returns
     * <code>DROP SEQUENCE &lt;sequence name&gt;</code> by default.
     */
    public String[] getDropSequenceSQL(Sequence seq) {
        return new String[]{ "DROP SEQUENCE " + getFullName(seq) };
    }

    /**
     * Return a series of SQL statements to create the given index. Returns
     * <code>CREATE [UNIQUE] INDEX &lt;index name&gt; ON &lt;table name&gt;
     * (&lt;col list&gt;)</code> by default.
     */
    public String[] getCreateIndexSQL(Index index) {
        StringBuilder buf = new StringBuilder();
        buf.append("CREATE ");
        if (index.isUnique())
            buf.append("UNIQUE ");

        DBIdentifier fullIdxName = index.getIdentifier();
        DBIdentifier unQualifiedName = fullIdxName.getUnqualifiedName();
        checkNameLength(toDBName(unQualifiedName), maxIndexNameLength,
                "long-index-name");
        String indexName = toDBName(fullIdxName);

        buf.append("INDEX ").append(indexName);
        buf.append(" ON ").append(getFullName(index.getTable(), false));
        buf.append(" (").append(namingUtil.appendColumns(index.getColumns())).
            append(")");

        return new String[]{ buf.toString() };
    }

    /**
     * Return a series of SQL statements to drop the given index. Returns
     * <code>DROP INDEX &lt;index name&gt;</code> by default.
     */
    public String[] getDropIndexSQL(Index index) {
        return new String[]{ "DROP INDEX " + getFullName(index) };
    }

    /**
     * Return a series of SQL statements to add the given column to
     * its table. Return an empty array if operation not supported. Returns
     * <code>ALTER TABLE &lt;table name&gt; ADD (&lt;col dec&gt;)</code>
     * by default.
     */
    public String[] getAddColumnSQL(Column column) {
        if (!supportsAlterTableWithAddColumn)
            return new String[0];

        String dec = getDeclareColumnSQL(column, true);
        if (dec == null)
            return new String[0];
        return new String[]{ "ALTER TABLE "
            + getFullName(column.getTable(), false) + " ADD " + dec };
    }

    /**
     * Return a series of SQL statements to drop the given column from
     * its table. Return an empty array if operation not supported. Returns
     * <code>ALTER TABLE &lt;table name&gt; DROP COLUMN &lt;col name&gt;</code>
     * by default.
     */
    public String[] getDropColumnSQL(Column column) {
        if (!supportsAlterTableWithDropColumn)
            return new String[0];
        return new String[]{ "ALTER TABLE "
            + getFullName(column.getTable(), false)
            + " DROP COLUMN " + column };
    }

    /**
     * Return a series of SQL statements to add the given primary key to
     * its table. Return an empty array if operation not supported.
     * Returns <code>ALTER TABLE &lt;table name&gt; ADD
     * &lt;pk cons sql &gt;</code> by default.
     */
    public String[] getAddPrimaryKeySQL(PrimaryKey pk) {
        String pksql = getPrimaryKeyConstraintSQL(pk);
        if (pksql == null)
            return new String[0];
        return new String[]{ "ALTER TABLE "
            + getFullName(pk.getTable(), false) + " ADD " + pksql };
    }

    /**
     * Return a series of SQL statements to drop the given primary key from
     * its table. Return an empty array if operation not supported.
     * Returns <code>ALTER TABLE &lt;table name&gt; DROP CONSTRAINT
     * &lt;pk name&gt;</code> by default.
     */
    public String[] getDropPrimaryKeySQL(PrimaryKey pk) {
        if (DBIdentifier.isNull(pk.getIdentifier()))
            return new String[0];
        return new String[]{ "ALTER TABLE "
            + getFullName(pk.getTable(), false)
            + " DROP CONSTRAINT " + toDBName(pk.getIdentifier()) };
    }

    /**
     * Return a series of SQL statements to add the given foreign key to
     * its table. Return an empty array if operation not supported.
     * Returns <code>ALTER TABLE &lt;table name&gt; ADD
     * &lt;fk cons sql &gt;</code> by default.
     */
    public String[] getAddForeignKeySQL(ForeignKey fk) {
        String fkSQL = getForeignKeyConstraintSQL(fk);
        if (fkSQL == null)
            return new String[0];
        return new String[]{ "ALTER TABLE "
            + getFullName(fk.getTable(), false) + " ADD " + fkSQL };
    }

    /**
     * Return a series of SQL statements to drop the given foreign key from
     * its table. Return an empty array if operation not supported.
     * Returns <code>ALTER TABLE &lt;table name&gt; DROP CONSTRAINT
     * &lt;fk name&gt;</code> by default.
     */
    public String[] getDropForeignKeySQL(ForeignKey fk, Connection conn) {
        if (DBIdentifier.isNull(fk.getIdentifier())) {
            String[] retVal;
            DBIdentifier fkName = fk.loadIdentifierFromDB(this,conn);
            retVal = (fkName == null || fkName.getName() == null) ?  new String[0] :
                new String[]{ "ALTER TABLE "
                + getFullName(fk.getTable(), false)
                + " DROP CONSTRAINT " + toDBName(fkName) };
            return retVal;
        }
        return new String[]{ "ALTER TABLE "
            + getFullName(fk.getTable(), false)
            + " DROP CONSTRAINT " + toDBName(fk.getIdentifier()) };
    }

    /**
     * Return the declaration SQL for the given column. This method is used
     * for each column from within {@link #getCreateTableSQL} and
     * {@link #getAddColumnSQL}.
     */
    protected String getDeclareColumnSQL(Column col, boolean alter) {
        StringBuilder buf = new StringBuilder();
        String columnName = checkNameLength(toDBName(col.getIdentifier()), maxColumnNameLength,
                "long-column-name");
        buf.append(columnName).append(" ");
        buf.append(getTypeName(col));

        // can't add constraints to a column we're adding after table
        // creation, cause some data might already be inserted
        if (!alter) {
            if (col.getDefaultString() != null && !col.isAutoAssigned())
                buf.append(" DEFAULT ").append(col.getDefaultString());
            if (col.isNotNull() || (!supportsNullUniqueColumn && col.hasConstraint(Unique.class)))
                buf.append(" NOT NULL");
        }
        if (col.isAutoAssigned()) {
            if (!supportsAutoAssign)
                log.warn(_loc.get("invalid-autoassign", platform, col));
            else if (autoAssignClause != null)
                buf.append(" ").append(autoAssignClause);
        }
        return buf.toString();
    }

    /**
     * Return the declaration SQL for the given primary key. This method is
     * used from within {@link #getCreateTableSQL} and
     * {@link #getAddPrimaryKeySQL}. Returns
     * <code>CONSTRAINT &lt;pk name&gt; PRIMARY KEY (&lt;col list&gt;)</code>
     * by default.
     */
    protected String getPrimaryKeyConstraintSQL(PrimaryKey pk) {
        // if we have disabled the creation of primary keys, abort here
        if (!createPrimaryKeys)
            return null;

        String name = toDBName(pk.getIdentifier());
        if (name != null && reservedWordSet.contains(name.toUpperCase(Locale.ENGLISH)))
            name = null;

        StringBuilder buf = new StringBuilder();
        if (name != null && CONS_NAME_BEFORE.equals(constraintNameMode))
            buf.append("CONSTRAINT ").append(name).append(" ");
        buf.append("PRIMARY KEY ");
        if (name != null && CONS_NAME_MID.equals(constraintNameMode))
            buf.append(name).append(" ");
        buf.append("(").append(namingUtil.appendColumns(pk.getColumns())).
            append(")");
        if (name != null && CONS_NAME_AFTER.equals(constraintNameMode))
            buf.append(" CONSTRAINT ").append(name);
        return buf.toString();
    }

    /**
     * Return the declaration SQL for the given foreign key, or null if it is
     * not supported. This method is used from within
     * {@link #getCreateTableSQL} and {@link #getAddForeignKeySQL}. Returns
     * <code>CONSTRAINT &lt;cons name&gt; FOREIGN KEY (&lt;col list&gt;)
     * REFERENCES &lt;foreign table&gt; (&lt;col list&gt;)
     * [ON DELETE &lt;action&gt;] [ON UPDATE &lt;action&gt;]</code> by default.
     */
    protected String getForeignKeyConstraintSQL(ForeignKey fk) {
        if (!supportsForeignKeys)
            return null;
        if (fk.getColumns().length > 0 && !supportsForeignKeysComposite)
            return null;
        if (fk.getDeleteAction() == ForeignKey.ACTION_NONE)
            return null;
        if (fk.isDeferred() && !supportsDeferredForeignKeyConstraints())
            return null;
        if (!supportsDeleteAction(fk.getDeleteAction())
            || !supportsUpdateAction(fk.getUpdateAction()))
            return null;

        Column[] locals = fk.getColumns();
        Column[] foreigns = fk.getPrimaryKeyColumns();

        int delActionId = fk.getDeleteAction();
        if (delActionId == ForeignKey.ACTION_NULL) {
            for (int i = 0; i < locals.length; i++) {
                if (locals[i].isNotNull())
                    delActionId = ForeignKey.ACTION_NONE;
            }
        }

        String delAction = getActionName(delActionId);
        String upAction = getActionName(fk.getUpdateAction());

        StringBuilder buf = new StringBuilder();
        if (!DBIdentifier.isNull(fk.getIdentifier())
            && CONS_NAME_BEFORE.equals(constraintNameMode))
            buf.append("CONSTRAINT ").append(toDBName(fk.getIdentifier())).append(" ");
        buf.append("FOREIGN KEY ");
        if (!DBIdentifier.isNull(fk.getIdentifier()) && CONS_NAME_MID.equals(constraintNameMode))
            buf.append(toDBName(fk.getIdentifier())).append(" ");
        buf.append("(").append(namingUtil.appendColumns(locals)).append(")");
        buf.append(" REFERENCES ");
        buf.append(getFullName(foreigns[0].getTable(), false));
        buf.append(" (").append(namingUtil.appendColumns(foreigns)).append(")");
        if (delAction != null)
            buf.append(" ON DELETE ").append(delAction);
        if (upAction != null)
            buf.append(" ON UPDATE ").append(upAction);
        if (fk.isDeferred())
            buf.append(" INITIALLY DEFERRED");
        if (supportsDeferredForeignKeyConstraints())
            buf.append(" DEFERRABLE");
        if (!DBIdentifier.isNull(fk.getIdentifier())
            && CONS_NAME_AFTER.equals(constraintNameMode))
            buf.append(" CONSTRAINT ").append(toDBName(fk.getIdentifier()));
        return buf.toString();
    }

    /**
     * Whether or not this dictionary supports deferred foreign key constraints.
     * This implementation returns {@link #supportsUniqueConstraints}.
     *
     * @since 1.1.0
     */
    protected boolean supportsDeferredForeignKeyConstraints() {
        return supportsDeferredConstraints;
    }

    /**
     * Return the name of the given foreign key action.
     */
    private String getActionName(int action) {
        switch (action) {
            case ForeignKey.ACTION_CASCADE:
                return "CASCADE";
            case ForeignKey.ACTION_NULL:
                return "SET NULL";
            case ForeignKey.ACTION_DEFAULT:
                return "SET DEFAULT";
            default:
                return null;
        }
    }

    /**
     * Whether this database supports the given foreign key delete action.
     */
    public boolean supportsDeleteAction(int action) {
        if (action == ForeignKey.ACTION_NONE)
            return true;
        if (!supportsForeignKeys)
            return false;
        switch (action) {
            case ForeignKey.ACTION_RESTRICT:
                return supportsRestrictDeleteAction;
            case ForeignKey.ACTION_CASCADE:
                return supportsCascadeDeleteAction;
            case ForeignKey.ACTION_NULL:
                return supportsNullDeleteAction;
            case ForeignKey.ACTION_DEFAULT:
                return supportsDefaultDeleteAction;
            default:
                return false;
        }
    }

    /**
     * Whether this database supports the given foreign key update action.
     */
    public boolean supportsUpdateAction(int action) {
        if (action == ForeignKey.ACTION_NONE)
            return true;
        if (!supportsForeignKeys)
            return false;
        switch (action) {
            case ForeignKey.ACTION_RESTRICT:
                return supportsRestrictUpdateAction;
            case ForeignKey.ACTION_CASCADE:
                return supportsCascadeUpdateAction;
            case ForeignKey.ACTION_NULL:
                return supportsNullUpdateAction;
            case ForeignKey.ACTION_DEFAULT:
                return supportsDefaultUpdateAction;
            default:
                return false;
        }
    }

    /**
     * Return the declaration SQL for the given unique constraint. This
     * method is used from within {@link #getCreateTableSQL}.
     * Returns <code>CONSTRAINT &lt;name&gt; UNIQUE (&lt;col list&gt;)</code>
     * by default.
     */
    protected String getUniqueConstraintSQL(Unique unq) {
        if (!supportsUniqueConstraints
            || (unq.isDeferred() && !supportsDeferredUniqueConstraints()))
            return null;
        StringBuilder buf = new StringBuilder();
        if (!DBIdentifier.isNull(unq.getIdentifier())
            && CONS_NAME_BEFORE.equals(constraintNameMode))
            buf.append("CONSTRAINT ").append(checkNameLength(toDBName(unq.getIdentifier()),
                maxConstraintNameLength, "long-constraint-name")).append(" ");
        buf.append("UNIQUE ");
        if (!DBIdentifier.isNull(unq.getIdentifier()) && CONS_NAME_MID.equals(constraintNameMode))
            buf.append(toDBName(unq.getIdentifier())).append(" ");
        buf.append("(").append(namingUtil.appendColumns(unq.getColumns())).
            append(")");
        if (unq.isDeferred())
            buf.append(" INITIALLY DEFERRED");
        if (supportsDeferredUniqueConstraints())
            buf.append(" DEFERRABLE");
        if (!DBIdentifier.isNull(unq.getIdentifier())
            && CONS_NAME_AFTER.equals(constraintNameMode))
            buf.append(" CONSTRAINT ").append(toDBName(unq.getIdentifier()));
        return buf.toString();
    }

    /**
     * Whether or not this dictionary supports deferred unique constraints.
     * This implementation returns {@link #supportsUniqueConstraints}.
     *
     * @since 1.1.0
     */
    protected boolean supportsDeferredUniqueConstraints() {
        return supportsDeferredConstraints;
    }

    /////////////////////
    // Database metadata
    /////////////////////

    /**
     * This method is used to filter system tables from database metadata.
     * Return true if the given table name represents a system table that
     * should not appear in the schema definition. By default, returns
     * true only if the given table is in the internal list of system tables,
     * or if the given schema is in the list of system schemas and is not
     * the target schema.
     *
     * @param name the table name
     * @param schema the table schema; may be null
     * @param targetSchema if true, then the given schema was listed by
     * the user as one of his schemas
     * @deprecated
     */
    @Deprecated
    public boolean isSystemTable(String name, String schema,
        boolean targetSchema) {
        return isSystemTable(DBIdentifier.newTable(name),
            DBIdentifier.newSchema(schema), targetSchema);
    }

    /**
     * This method is used to filter system tables from database metadata.
     * Return true if the given table name represents a system table that
     * should not appear in the schema definition. By default, returns
     * true only if the given table is in the internal list of system tables,
     * or if the given schema is in the list of system schemas and is not
     * the target schema.
     *
     * @param name the table name
     * @param schema the table schema; may be null
     * @param targetSchema if true, then the given schema was listed by
     * the user as one of his schemas
     */
    public boolean isSystemTable(DBIdentifier name, DBIdentifier schema,
        boolean targetSchema) {
        DBIdentifier sName = DBIdentifier.toUpper(name);
        if (systemTableSet.contains(sName.getName()))
            return true;
        DBIdentifier schName = DBIdentifier.toUpper(schema);
        return !targetSchema && schema != null
            && systemSchemaSet.contains(schName.getName());
    }

    /**
     * This method is used to filter system indexes from database metadata.
     * Return true if the given index name represents a system index that
     * should not appear in the schema definition. Returns false by default.
     *
     * @param name the index name
     * @param table the index table
     * @deprecated
     */
    @Deprecated
    public boolean isSystemIndex(String name, Table table) {
        return false;
    }

    /**
     * This method is used to filter system indexes from database metadata.
     * Return true if the given index name represents a system index that
     * should not appear in the schema definition. Returns false by default.
     *
     * @param name the index name
     * @param table the index table
     */
    public boolean isSystemIndex(DBIdentifier name, Table table) {
        return false;
    }

    /**
     * This method is used to filter system sequences from database metadata.
     * Return true if the given sequence represents a system sequence that
     * should not appear in the schema definition. Returns true if system
     * schema by default.
     *
     * @param name the table name
     * @param schema the table schema; may be null
     * @param targetSchema if true, then the given schema was listed by
     * the user as one of his schemas
     * @deprecated
     */
    @Deprecated
    public boolean isSystemSequence(String name, String schema,
        boolean targetSchema) {
        return isSystemSequence(DBIdentifier.newSequence(name),
            DBIdentifier.newSchema(schema), targetSchema);
    }

    /**
     * This method is used to filter system sequences from database metadata.
     * Return true if the given sequence represents a system sequence that
     * should not appear in the schema definition. Returns true if system
     * schema by default.
     *
     * @param name the table name
     * @param schema the table schema; may be null
     * @param targetSchema if true, then the given schema was listed by
     * the user as one of his schemas
     */
    public boolean isSystemSequence(DBIdentifier name, DBIdentifier schema,
        boolean targetSchema) {
        return !targetSchema && !DBIdentifier.isNull(schema)
            && systemSchemaSet.contains(DBIdentifier.toUpper(schema).getName());
    }

    /**
     * This method is used to filter system sequences from database metadata.
     * Return true if the given sequence represents a system sequence that
     * should not appear in the schema definition. Returns true if system
     * schema by default.
     *
     * @param name the table name
     * @param schema the table schema; may be null
     * @param targetSchema if true, then the given schema was listed by
     * the user as one of his schemas
     * @param conn connection to the database
     */
    public boolean isSystemSequence(DBIdentifier name, DBIdentifier schema,
        boolean targetSchema, Connection conn) {
        return isSystemSequence(name, schema, targetSchema);
    }

    /**
     * Reflect on the schema to find tables matching the given name pattern.
     * @deprecated not used by openjpa internally anymore
     * @see #getTables(DatabaseMetaData, DBIdentifier, DBIdentifier, DBIdentifier, Connection)
     */
    @Deprecated
    public Table[] getTables(DatabaseMetaData meta, String catalog,
        String schemaName, String tableName, Connection conn)
        throws SQLException {
        return getTables(meta, DBIdentifier.newCatalog(catalog), DBIdentifier.newSchema(schemaName),
            DBIdentifier.newTable(tableName), conn);
    }


    /**
     * Reflect on the schema to find tables matching the given name pattern.
     */
    public Table[] getTables(DatabaseMetaData meta, DBIdentifier sqlCatalog,
        DBIdentifier sqlSchemaName, DBIdentifier sqlTableName, Connection conn)
        throws SQLException {

        String schemaName = DBIdentifier.isNull(sqlSchemaName) ? null : sqlSchemaName.getName();
        if (!supportsSchemaForGetTables)
            schemaName = null;
        else {
            schemaName = getSchemaNameForMetadata(sqlSchemaName);
        }

        String[] types = StringUtil.split(tableTypes, ",", 0);
        for (int i = 0; i < types.length; i++)
            types[i] = types[i].trim();

        beforeMetadataOperation(conn);
        ResultSet tables = null;
        try {
            tables = meta.getTables(getCatalogNameForMetadata(sqlCatalog),
                schemaName, getTableNameForMetadata(sqlTableName), types);
            List<Table> tableList = new ArrayList<>();
            while (tables != null && tables.next()) {
                tableList.add(newTable(tables));
            }
            return tableList.toArray(new Table[tableList.size()]);
        } finally {
            if (tables != null) {
                try {
                    tables.close();
                }
                catch (Exception e) {
                }
            }
        }
    }

    /**
     * Create a new table from the information in the schema metadata.
     */
    protected Table newTable(ResultSet tableMeta)
        throws SQLException {
        Table t = new Table();
        t.setIdentifier(fromDBName(tableMeta.getString("TABLE_NAME"), DBIdentifierType.TABLE));
        return t;
    }

    /**
     * Reflect on the schema to find sequences matching the given name pattern.
     * Returns an empty array by default, as there is no standard way to
     * retrieve a list of sequences.
     * @deprecated
     */
    @Deprecated
    public Sequence[] getSequences(DatabaseMetaData meta, String catalog,
        String schemaName, String sequenceName, Connection conn)
        throws SQLException {
        return getSequences(meta, DBIdentifier.newCatalog(catalog), DBIdentifier.newSchema(schemaName),
            DBIdentifier.newSequence(sequenceName), conn);

    }

    public Sequence[] getSequences(DatabaseMetaData meta, DBIdentifier catalog,
        DBIdentifier schemaName, DBIdentifier sequenceName, Connection conn)
        throws SQLException {
        String str = getSequencesSQL(schemaName, sequenceName);
        if (str == null)
            return new Sequence[0];

        PreparedStatement stmnt = prepareStatement(conn, str);
        ResultSet rs = null;
        try {
            int idx = 1;
            if (!DBIdentifier.isNull(schemaName))
                stmnt.setString(idx++, DBIdentifier.toUpper(schemaName).getName());
            if (!DBIdentifier.isNull(sequenceName))
                stmnt.setString(idx++, sequenceName.getName());
            setQueryTimeout(stmnt, conf.getQueryTimeout());
            rs = executeQuery(conn, stmnt, str);
            return getSequence(rs);
         } finally {
            if (rs != null)
                try {
                    rs.close();
                } catch (SQLException se) {
                }
            if (stmnt != null)
                try {
                    stmnt.close();
                } catch (SQLException se) {
                }
        }
    }

    /**
     * Create a new sequence from the information in the schema metadata.
     */
    protected Sequence newSequence(ResultSet sequenceMeta)
        throws SQLException {
        Sequence seq = new Sequence();
        seq.setSchemaIdentifier(fromDBName(StringUtil.stripEnd(sequenceMeta.getString("SEQUENCE_SCHEMA"), null),
            DBIdentifierType.SCHEMA));
        seq.setIdentifier(fromDBName(StringUtil.stripEnd(sequenceMeta.getString("SEQUENCE_NAME"), null),
            DBIdentifierType.SEQUENCE));
        return seq;
    }

    /**
     * Return the SQL needed to select the list of sequences.
     * @deprecated
     */
    @Deprecated
    protected String getSequencesSQL(String schemaName, String sequenceName) {
        return null;
    }

    protected String getSequencesSQL(DBIdentifier schemaName, DBIdentifier sequenceName) {
        return null;
    }

    /**
     * Reflect on the schema to find columns matching the given table and
     * column patterns.
     * @deprecated
     */
    @Deprecated
    public Column[] getColumns(DatabaseMetaData meta, String catalog,
        String schemaName, String tableName, String columnName, Connection conn)
        throws SQLException {
        return getColumns(meta, DBIdentifier.newCatalog(catalog),
            DBIdentifier.newSchema(schemaName),
            DBIdentifier.newTable(tableName),
            DBIdentifier.newColumn(columnName),
            conn);
    }

    /**
     * Reflect on the schema to find columns matching the given table and
     * column patterns.
     */
    public Column[] getColumns(DatabaseMetaData meta, DBIdentifier catalog,
        DBIdentifier schemaName, DBIdentifier tableName, DBIdentifier columnName, Connection conn)
        throws SQLException {
        if (DBIdentifier.isNull(tableName) && !supportsNullTableForGetColumns)
            return null;

        String sqlSchemaName = null;
        if (!DBIdentifier.isNull(schemaName)) {
            sqlSchemaName = schemaName.getName();
        }
        if (!supportsSchemaForGetColumns)
            sqlSchemaName = null;
        else
            sqlSchemaName = getSchemaNameForMetadata(schemaName);

        beforeMetadataOperation(conn);
        ResultSet cols = null;
        try {
            cols = meta.getColumns(getCatalogNameForMetadata(catalog),
                sqlSchemaName, getTableNameForMetadata(tableName),
                getColumnNameForMetadata(columnName));

            List columnList = new ArrayList();
            while (cols != null && cols.next())
                columnList.add(newColumn(cols));
            return (Column[]) columnList.toArray
                (new Column[columnList.size()]);
        } finally {
            if (cols != null)
                try {
                    cols.close();
                } catch (Exception e) {
                }
        }
    }

    /**
     * Create a new column from the information in the schema metadata.
     */
    protected Column newColumn(ResultSet colMeta)
        throws SQLException {
        Column c = new Column();
        c.setSchemaIdentifier(fromDBName(colMeta.getString("TABLE_SCHEM"), DBIdentifierType.SCHEMA));
        c.setTableIdentifier(fromDBName(colMeta.getString("TABLE_NAME"), DBIdentifierType.TABLE));
        c.setIdentifier(fromDBName(colMeta.getString("COLUMN_NAME"), DBIdentifierType.COLUMN));
        c.setType(colMeta.getInt("DATA_TYPE"));
        c.setTypeIdentifier(fromDBName(colMeta.getString("TYPE_NAME"), DBIdentifierType.COLUMN_DEFINITION));
        c.setSize(colMeta.getInt("COLUMN_SIZE"));
        c.setDecimalDigits(colMeta.getInt("DECIMAL_DIGITS"));
        c.setNotNull(colMeta.getInt("NULLABLE")
            == DatabaseMetaData.columnNoNulls);

        String def = colMeta.getString("COLUMN_DEF");
        if (!StringUtil.isEmpty(def) && !"null".equalsIgnoreCase(def))
            c.setDefaultString(def);
        return c;
    }

    /**
     * Reflect on the schema to find primary keys for the given table pattern.
     * @deprecated
     */
    @Deprecated
    public PrimaryKey[] getPrimaryKeys(DatabaseMetaData meta,
        String catalog, String schemaName, String tableName, Connection conn)
        throws SQLException {
        return getPrimaryKeys(meta, DBIdentifier.newCatalog(catalog), DBIdentifier.newSchema(schemaName),
            DBIdentifier.newTable(tableName), conn);
    }

    /**
     * Reflect on the schema to find primary keys for the given table pattern.
     */
    public PrimaryKey[] getPrimaryKeys(DatabaseMetaData meta,
        DBIdentifier catalog, DBIdentifier schemaName, DBIdentifier tableName, Connection conn)
        throws SQLException {
        if (useGetBestRowIdentifierForPrimaryKeys)
            return getPrimaryKeysFromBestRowIdentifier(meta, catalog,
                schemaName, tableName, conn);
        return getPrimaryKeysFromGetPrimaryKeys(meta, catalog,
            schemaName, tableName, conn);
    }

    /**
     * Reflect on the schema to find primary keys for the given table pattern.
     * @deprecated
     */
    @Deprecated
    protected PrimaryKey[] getPrimaryKeysFromGetPrimaryKeys
        (DatabaseMetaData meta, String catalog, String schemaName,
            String tableName, Connection conn)
    throws SQLException {
        return getPrimaryKeysFromGetPrimaryKeys(meta, DBIdentifier.newCatalog(catalog),
            DBIdentifier.newSchema(schemaName), DBIdentifier.newTable(tableName), conn);
    }
    /**
     * Reflect on the schema to find primary keys for the given table pattern.
     */
    protected PrimaryKey[] getPrimaryKeysFromGetPrimaryKeys
        (DatabaseMetaData meta, DBIdentifier catalog, DBIdentifier schemaName,
            DBIdentifier tableName, Connection conn)
        throws SQLException {
        if (tableName == null && !supportsNullTableForGetPrimaryKeys)
            return null;

        beforeMetadataOperation(conn);
        ResultSet pks = null;
        try {
            pks = meta.getPrimaryKeys(getCatalogNameForMetadata(catalog),
                getSchemaNameForMetadata(schemaName),
                getTableNameForMetadata(tableName));

            List pkList = new ArrayList();
            while (pks != null && pks.next())
                pkList.add(newPrimaryKey(pks));
            return (PrimaryKey[]) pkList.toArray
                (new PrimaryKey[pkList.size()]);
        } finally {
            if (pks != null)
                try {
                    pks.close();
                } catch (Exception e) {
                }
        }
    }

    /**
     * Create a new primary key from the information in the schema metadata.
     */
    protected PrimaryKey newPrimaryKey(ResultSet pkMeta)
        throws SQLException {
        PrimaryKey pk = new PrimaryKey();
        pk.setSchemaIdentifier(fromDBName(pkMeta.getString("TABLE_SCHEM"), DBIdentifierType.SCHEMA));
        pk.setTableIdentifier(fromDBName(pkMeta.getString("TABLE_NAME"), DBIdentifierType.TABLE));
        pk.setColumnIdentifier(fromDBName(pkMeta.getString("COLUMN_NAME"), DBIdentifierType.COLUMN));
        pk.setIdentifier(fromDBName(pkMeta.getString("PK_NAME"), DBIdentifierType.CONSTRAINT));
        return pk;
    }

    /**
     * Reflect on the schema to find primary keys for the given table pattern.
     * @deprecated
     */
    @Deprecated
    protected PrimaryKey[] getPrimaryKeysFromBestRowIdentifier
        (DatabaseMetaData meta, String catalog, String schemaName,
            String tableName, Connection conn) throws SQLException {
        return getPrimaryKeysFromBestRowIdentifier(meta, DBIdentifier.newCatalog(catalog),
            DBIdentifier.newSchema(schemaName), DBIdentifier.newTable(tableName), conn);
    }

    /**
     * Reflect on the schema to find primary keys for the given table pattern.
     */
    protected PrimaryKey[] getPrimaryKeysFromBestRowIdentifier
        (DatabaseMetaData meta, DBIdentifier catalog, DBIdentifier schemaName,
            DBIdentifier tableName, Connection conn)
        throws SQLException {
        if (tableName == null)
            return null;

        beforeMetadataOperation(conn);
        ResultSet pks = null;
        try {
            pks = meta.getBestRowIdentifier(toDBName(catalog), toDBName(schemaName),
                toDBName(tableName), 0, false);

            List pkList = new ArrayList();
            while (pks != null && pks.next()) {
                PrimaryKey pk = new PrimaryKey();
                pk.setSchemaIdentifier(schemaName);
                pk.setTableIdentifier(tableName);
                pk.setColumnIdentifier(fromDBName(pks.getString("COLUMN_NAME"), DBIdentifierType.COLUMN));
                pkList.add(pk);
            }
            return (PrimaryKey[]) pkList.toArray
                (new PrimaryKey[pkList.size()]);
        } finally {
            if (pks != null)
                try {
                    pks.close();
                } catch (Exception e) {
                }
        }
    }

    /**
     * Reflect on the schema to find indexes matching the given table pattern.
     * @deprecated
     */
    @Deprecated
    public Index[] getIndexInfo(DatabaseMetaData meta, String catalog,
        String schemaName, String tableName, boolean unique,
        boolean approx, Connection conn)
        throws SQLException {
        return getIndexInfo(meta, DBIdentifier.newCatalog(catalog),
            DBIdentifier.newSchema(schemaName), DBIdentifier.newTable(tableName), unique,
            approx, conn);
    }

    /**
     * Reflect on the schema to find indexes matching the given table pattern.
     */
    public Index[] getIndexInfo(DatabaseMetaData meta, DBIdentifier catalog,
        DBIdentifier schemaName, DBIdentifier tableName, boolean unique,
        boolean approx, Connection conn)
        throws SQLException {
        if (tableName == null && !supportsNullTableForGetIndexInfo)
            return null;

        beforeMetadataOperation(conn);
        ResultSet indexes = null;
        try {
            indexes = meta.getIndexInfo(getCatalogNameForMetadata(catalog),
                getSchemaNameForMetadata(schemaName),
                getTableNameForMetadata(tableName), unique, approx);

            List indexList = new ArrayList();
            while (indexes != null && indexes.next())
                indexList.add(newIndex(indexes));
            return (Index[]) indexList.toArray(new Index[indexList.size()]);
        } finally {
            if (indexes != null)
                try {
                    indexes.close();
                } catch (Exception e) {
                }
        }
    }

    /**
     * Create a new index from the information in the schema metadata.
     */
    protected Index newIndex(ResultSet idxMeta)
        throws SQLException {
        Index idx = new Index();
        idx.setSchemaIdentifier(fromDBName(idxMeta.getString("TABLE_SCHEM"), DBIdentifierType.SCHEMA));
        idx.setTableIdentifier(fromDBName(idxMeta.getString("TABLE_NAME"), DBIdentifierType.TABLE));
        idx.setColumnIdentifier(fromDBName(idxMeta.getString("COLUMN_NAME"), DBIdentifierType.COLUMN));
        idx.setIdentifier(fromDBName(idxMeta.getString("INDEX_NAME"), DBIdentifierType.INDEX));
        idx.setUnique(!idxMeta.getBoolean("NON_UNIQUE"));
        return idx;
    }

    /**
     * Reflect on the schema to return foreign keys imported by the given
     * table pattern.
     * @deprecated
     */
    @Deprecated
    public ForeignKey[] getImportedKeys(DatabaseMetaData meta, String catalog,
        String schemaName, String tableName, Connection conn)
        throws SQLException {
        return getImportedKeys(meta, catalog, schemaName, tableName, conn, true);
    }

    /**
     * Reflect on the schema to return foreign keys imported by the given
     * table pattern.
     */
    public ForeignKey[] getImportedKeys(DatabaseMetaData meta, DBIdentifier catalog,
        DBIdentifier schemaName, DBIdentifier tableName, Connection conn)
        throws SQLException {
        return getImportedKeys(meta, catalog, schemaName, tableName, conn, true);
    }

    /**
     * Reflect on the schema to return full foreign keys imported by the given
     * table pattern.
     * @deprecated
     */
    @Deprecated
    public ForeignKey[] getImportedKeys(DatabaseMetaData meta, String catalog,
        String schemaName, String tableName, Connection conn, boolean partialKeys)
        throws SQLException {
        return getImportedKeys(meta, DBIdentifier.newCatalog(catalog),
            DBIdentifier.newSchema(schemaName), DBIdentifier.newTable(tableName), conn, partialKeys);
    }

    /**
     * Reflect on the schema to return full foreign keys imported by the given
     * table pattern.
     */
    public ForeignKey[] getImportedKeys(DatabaseMetaData meta, DBIdentifier catalog,
        DBIdentifier schemaName, DBIdentifier tableName, Connection conn, boolean partialKeys)
        throws SQLException {
        if (!supportsForeignKeys)
            return null;
        if (tableName == null && !supportsNullTableForGetImportedKeys)
            return null;

        beforeMetadataOperation(conn);
        ResultSet keys = null;
        try {
            keys = meta.getImportedKeys(getCatalogNameForMetadata(catalog),
                getSchemaNameForMetadata(schemaName),
                getTableNameForMetadata(tableName));

            List<ForeignKey> importedKeyList = new ArrayList<>();
            Map<FKMapKey, ForeignKey> fkMap = new HashMap<>();

            while (keys != null && keys.next()) {
                ForeignKey nfk = newForeignKey(keys);
                if (!partialKeys) {
                    ForeignKey fk = combineForeignKey(fkMap, nfk);
                    // If the key returned != new key, fk col was combined
                    // with existing fk.
                    if (fk != nfk) {
                        continue;
                    }
                }
                importedKeyList.add(nfk);
            }
            return (ForeignKey[]) importedKeyList.toArray
                (new ForeignKey[importedKeyList.size()]);
        } finally {
            if (keys != null) {
                try {
                    keys.close();
                } catch (Exception e) {
                }
            }
        }
    }

    /**
     * Combines partial foreign keys into singular key
     */
    protected ForeignKey combineForeignKey(Map<FKMapKey, ForeignKey> fkMap,
        ForeignKey fk) {

        FKMapKey fkmk = new FKMapKey(fk);
        ForeignKey baseKey = fkMap.get(fkmk);
        // Found the FK, add the additional column
        if (baseKey != null) {
            baseKey.addColumn(fk);
            return baseKey;
        }
        // fkey is new
        fkMap.put(fkmk, fk);
        return fk;
    }

    /**
     * Create a new foreign key from the information in the schema metadata.
     */
    protected ForeignKey newForeignKey(ResultSet fkMeta)
        throws SQLException {
        ForeignKey fk = new ForeignKey();
        fk.setSchemaIdentifier(fromDBName(fkMeta.getString("FKTABLE_SCHEM"), DBIdentifierType.SCHEMA));
        fk.setTableIdentifier(fromDBName(fkMeta.getString("FKTABLE_NAME"), DBIdentifierType.TABLE));
        fk.setColumnIdentifier(fromDBName(fkMeta.getString("FKCOLUMN_NAME"), DBIdentifierType.COLUMN));
        fk.setIdentifier(fromDBName(fkMeta.getString("FK_NAME"), DBIdentifierType.FOREIGN_KEY));
        fk.setPrimaryKeySchemaIdentifier(fromDBName(fkMeta.getString("PKTABLE_SCHEM"), DBIdentifierType.SCHEMA));
        fk.setPrimaryKeyTableIdentifier(fromDBName(fkMeta.getString("PKTABLE_NAME"), DBIdentifierType.TABLE));
        fk.setPrimaryKeyColumnIdentifier(fromDBName(fkMeta.getString("PKCOLUMN_NAME"), DBIdentifierType.COLUMN));
        fk.setKeySequence(fkMeta.getShort("KEY_SEQ"));
        fk.setDeferred(fkMeta.getShort("DEFERRABILITY")
            == DatabaseMetaData.importedKeyInitiallyDeferred);

        int del = fkMeta.getShort("DELETE_RULE");
        switch (del) {
            case DatabaseMetaData.importedKeySetNull:
                fk.setDeleteAction(ForeignKey.ACTION_NULL);
                break;
            case DatabaseMetaData.importedKeySetDefault:
                fk.setDeleteAction(ForeignKey.ACTION_DEFAULT);
                break;
            case DatabaseMetaData.importedKeyCascade:
                fk.setDeleteAction(ForeignKey.ACTION_CASCADE);
                break;
            default:
                fk.setDeleteAction(ForeignKey.ACTION_RESTRICT);
                break;
        }
        return fk;
    }

    /**
     * Returns the table name that will be used for obtaining information
     * from {@link DatabaseMetaData}.
     */
    protected String getTableNameForMetadata(String tableName) {
        return convertSchemaCase(DBIdentifier.newTable(tableName));
    }

    /**
     * Returns the table name that will be used for obtaining information
     * from {@link DatabaseMetaData}.
     */
    protected String getTableNameForMetadata(DBIdentifier tableName) {
        if (tableName == null) {
            return null;
        }
        return convertSchemaCase(tableName.getUnqualifiedName());
    }

    /**
     * Returns the schema name that will be used for obtaining information
     * from {@link DatabaseMetaData}.
     */
    protected String getSchemaNameForMetadata(String schemaName) {
        if (schemaName == null)
            schemaName = conf.getSchema();
        return convertSchemaCase(DBIdentifier.newSchema(schemaName));
    }

    /**
     * Returns the schema name that will be used for obtaining information
     * from {@link DatabaseMetaData}.
     */
    protected String getSchemaNameForMetadata(DBIdentifier schemaName) {
        if (DBIdentifier.isNull(schemaName))
            schemaName = DBIdentifier.newSchema(conf.getSchema());
        return convertSchemaCase(schemaName);
    }

    /**
     * Returns the catalog name that will be used for obtaining information
     * from {@link DatabaseMetaData}.
     */
    protected String getCatalogNameForMetadata(String catalogName) {
        return convertSchemaCase(DBIdentifier.newCatalog(catalogName));
    }

    /**
     * Returns the catalog name that will be used for obtaining information
     * from {@link DatabaseMetaData}.
     */
    protected String getCatalogNameForMetadata(DBIdentifier catalogName) {
        return convertSchemaCase(catalogName);
    }

    /**
     * Returns the column name that will be used for obtaining information
     * from {@link DatabaseMetaData}.
     */
    protected String getColumnNameForMetadata(String columnName) {
        return convertSchemaCase(DBIdentifier.newColumn(columnName));
    }

    /**
     * Returns the column name that will be used for obtaining information
     * from {@link DatabaseMetaData}.
     */
    protected String getColumnNameForMetadata(DBIdentifier columnName) {
        return convertSchemaCase(columnName);
    }

    /**
     * Convert the specified schema name to a name that the database will
     * be able to understand.
     */
    public String convertSchemaCase(String objectName) {
        return convertSchemaCase(DBIdentifier.newIdentifier(objectName, DBIdentifierType.DEFAULT, false));
    }

    /**
     * Convert the specified schema name to a name that the database will
     * be able to understand.
     */
    public String convertSchemaCase(DBIdentifier objectName) {
        return toDBName(namingUtil.convertSchemaCase(objectName), false);
    }

    /**
     * Return DB specific schemaCase
     */
    @Override
    public String getSchemaCase(){
        return schemaCase;
    }

    /**
     * Prepared the connection for metadata operations.
     */
    private void beforeMetadataOperation(Connection c) {
        if (requiresAutoCommitForMetaData) {
            try {
                c.rollback();
            } catch (SQLException sqle) {
            }
            try {
                if (!c.getAutoCommit())
                    c.setAutoCommit(true);
            } catch (SQLException sqle) {
            }
        }
    }

    /////////////////////////////
    // Sequences and Auto-Assign
    /////////////////////////////

    /**
     * Return the last generated value for the given column.
     * Throws an exception by default if {@link #lastGeneratedKeyQuery} is null.
     */
    public Object getGeneratedKey(Column col, Connection conn)
        throws SQLException {
        if (lastGeneratedKeyQuery == null)
            throw new StoreException(_loc.get("no-auto-assign"));

        // replace things like "SELECT MAX({0}) FROM {1}"
        String query = lastGeneratedKeyQuery;
        if (query.indexOf('{') != -1) // only if the token is in the string
        {
            query = getGenKeySeqName(query, col);
        }

        PreparedStatement stmnt = prepareStatement(conn, query);
        ResultSet rs = null;
        try {
            setQueryTimeout(stmnt, conf.getQueryTimeout());
            rs = executeQuery(conn, stmnt, query);
            return getKey(rs, col);
        } finally {
            if (rs != null)
                try { rs.close(); } catch (SQLException se) {}
            if (stmnt != null)
                try { stmnt.close(); } catch (SQLException se) {}
        }
    }

    protected String getGenKeySeqName(String query, Column col) {
        return MessageFormat.format(query, new Object[]{
                toDBName(col.getIdentifier()), getFullName(col.getTable(), false),
                getGeneratedKeySequenceName(col),
            });
    }

    /**
     * Return the sequence name used by databases for the given autoassigned
     * column. This is only used by databases that require an explicit name
     * to be used for auto-assign support.
     */
    protected String getGeneratedKeySequenceName(Column col) {
        return toDBName(namingUtil.getGeneratedKeySequenceName(col, maxAutoAssignNameLength));
    }

    protected Map<String, StoredProcedure> _procs = new TreeMap<>();

    /**
     * Gets the metadata of the stored procedure by the given name either from the cached version or
     * by enquiring the database.
     * @param meta the database meta data
     * @param catalog the catalog name or null
     * @param schema the schema name or null
     * @param procedure the procedure name
     * @return metadata about the named procedure or null
     * @throws SQLException when metadata query goes wrong
     */
    public StoredProcedure getStoredProcedure(DatabaseMetaData meta, DBIdentifier catalog, DBIdentifier schema,
                                              String procedure) throws SQLException {
        if (_procs.containsKey(procedure)) {
            return _procs.get(procedure);
        }
        ResultSet rs = meta.getProcedureColumns(
                getCatalogNameForMetadata(catalog),
                getSchemaNameForMetadata(schema),
                procedure,
                null);
        StoredProcedure sp = null;
        if (rs.next()) {
            sp = new StoredProcedure(rs);
        } else {
            ResultSet rsExist = meta.getProcedures(
                    getCatalogNameForMetadata(catalog),
                    getSchemaNameForMetadata(schema),
                    procedure);
            if (rsExist.next()) {
                sp = new StoredProcedure((String) null);
                sp.setCatalog(catalog);
                sp.setSchema(schema);
                sp.setName(procedure);
            }
        }
        _procs.put(procedure, sp);
        return sp;
    }

    ///////////////////////////////
    // Configurable implementation
    ///////////////////////////////

    @Override
    public void setConfiguration(Configuration conf) {
        this.conf = (JDBCConfiguration) conf;
        this.log = this.conf.getLog(JDBCConfiguration.LOG_JDBC);

        // Create the naming utility
        namingUtil = this.conf.getIdentifierUtilInstance();
        namingUtil.setIdentifierConfiguration(this);
        configureNamingRules();

        // warn about unsupported dicts
        if (log.isWarnEnabled() && !isSupported())
            log.warn(_loc.get("dict-not-supported", getClass()));
    }

    private boolean isSupported() {
        // if this is a custom dict, traverse to whatever openjpa dict it
        // extends
        Class c = getClass();
        while (!c.getName().startsWith("org.apache.openjpa."))
            c = c.getSuperclass();

        // the generic dbdictionary is not considered a supported dict; all
        // other concrete dictionaries are
        if (c == DBDictionary.class)
            return false;
        return true;
    }

    @Override
    public void startConfiguration() {
    }

    @Override
    public void endConfiguration() {
        // initialize the set of reserved SQL92 words from resource
        InputStream in = DBDictionary.class.getResourceAsStream
            ("sql-keywords.rsrc");
        try {
            String keywords = new BufferedReader(new InputStreamReader(in)).
                readLine();
            reservedWordSet.addAll(Arrays.asList(StringUtil.split
                (keywords, ",", 0)));
        } catch (IOException ioe) {
            throw new GeneralException(ioe);
        } finally {
            try { in.close(); } catch (IOException e) {}
        }

        // add additional reserved words set by user
        if (reservedWords != null)
            reservedWordSet.addAll(Arrays.asList(StringUtil.split(reservedWords.toUpperCase(Locale.ENGLISH), ",", 0)));

        // add system schemas set by user
        if (systemSchemas != null)
            systemSchemaSet.addAll(Arrays.asList(StringUtil.split(systemSchemas.toUpperCase(Locale.ENGLISH), ",", 0)));

        // add system tables set by user
        if (systemTables != null)
            systemTableSet.addAll(Arrays.asList(StringUtil.split(systemTables.toUpperCase(Locale.ENGLISH), ",", 0)));

        // add fixed size type names set by the user
        if (fixedSizeTypeNames != null)
            fixedSizeTypeNameSet.addAll(Arrays.asList(StringUtil.split(fixedSizeTypeNames.toUpperCase(Locale.ENGLISH), ",", 0)));

        // if user has unset sequence sql, null it out so we know sequences
        // aren't supported
        nextSequenceQuery = StringUtil.trimToNull(nextSequenceQuery);

        if (selectWords != null)
            selectWordSet.addAll(Arrays.asList(StringUtil.split(selectWords.toUpperCase(Locale.ENGLISH), ",", 0)));

        // initialize the error codes
        SQLErrorCodeReader codeReader = new SQLErrorCodeReader();
        String rsrc = "sql-error-state-codes.xml";
        // We'll allow sub-classes to override the stream for custom err codes
        // @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="UI_INHERITANCE_UNSAFE_GETRESOURCE")
        InputStream stream = getClass().getResourceAsStream(rsrc);
        String dictionaryClassName = getClass().getName();
        if (stream == null) { // User supplied dictionary but no error codes xml
            // use default
            stream = DBDictionary.class.getResourceAsStream(rsrc);
            dictionaryClassName = getClass().getSuperclass().getName();
        }
        codeReader.parse(stream, dictionaryClassName, this);
    }

    public void addErrorCode(int errorType, String errorCode) {
        if (errorCode == null || errorCode.trim().length() == 0)
            return;
        Set<String> codes = sqlStateCodes.get(errorType);
        if (codes == null) {
            codes = new HashSet<>();
            codes.add(errorCode.trim());
            sqlStateCodes.put(errorType, codes);
        } else {
            codes.add(errorCode.trim());
        }
    }

    /**
     * FIXME - OPENJPA-957 - lockTimeout is a server-side function and
     * shouldn't be using client-side setQueryTimeout for lock timeouts.
     *
     * This method is to provide override for non-JDBC or JDBC-like
     * implementation of setting query and lock timeouts.
     *
     * @param stmnt
     * @param fetch - optional lock and query timeouts in milliseconds
     * @param forUpdate - true if we should also try setting a lock timeout
     * @throws SQLException
     */
    public void setTimeouts(PreparedStatement stmnt,
        JDBCFetchConfiguration fetch, boolean forUpdate) throws SQLException {
        if (supportsQueryTimeout) {
            int timeout = fetch.getQueryTimeout();
            if (forUpdate) {
                // if this is a locking select and the lock timeout is greater
                // than the configured query timeout, use the lock timeout
                timeout = Math.max(fetch.getQueryTimeout(),
                    fetch.getLockTimeout());
            }
            setQueryTimeout(stmnt, timeout);
        }
    }

    /**
     * FIXME - OPENJPA-957 - lockTimeout is a server-side function and
     * shouldn't be using client-side setQueryTimeout for lock timeouts.
     *
     * This method is to provide override for non-JDBC or JDBC-like
     * implementation of setting query and lock timeouts.
     *
     * @param stmnt
     * @param conf - optional lock and query timeouts in milliseconds
     * @param forUpdate - true if we should also try setting a lock timeout
     * @throws SQLException
     */
    public void setTimeouts(PreparedStatement stmnt, JDBCConfiguration conf,
        boolean forUpdate) throws SQLException {
        if (supportsQueryTimeout) {
            int timeout = conf.getQueryTimeout();
            if (forUpdate) {
                // if this is a locking select and the lock timeout is greater
                // than the configured query timeout, use the lock timeout
                timeout = Math.max(conf.getQueryTimeout(),
                    conf.getLockTimeout());
            }
            setQueryTimeout(stmnt, timeout);
        }
    }

    /**
     * Provides the default validation handling of setting a query timeout.
     * @param stmnt
     * @param timeout in milliseconds
     * @throws SQLException
     */
    public void setQueryTimeout(PreparedStatement stmnt, int timeout)
        throws SQLException {
        if (supportsQueryTimeout) {
            if (timeout == -1) {
                // special OpenJPA allowed case denoting no timeout
                timeout = 0;
            } else if (timeout < 0) {
                if (log.isWarnEnabled())
                    log.warn(_loc.get("invalid-timeout", Integer.valueOf(timeout)));
                return;
            } else if (timeout > 0 && timeout < 1000) {
                // round up to 1 sec
                timeout = 1000;
                if (log.isWarnEnabled())
                    log.warn(_loc.get("millis-query-timeout"));
            }
            setStatementQueryTimeout(stmnt, timeout);
        }
    }

    /**
     * Allow subclasses to provide DB unique override implementations of
     * setting query timeouts, while preserving the default timeout logic
     * in the public setQueryTimeout method.
     * @param stmnt
     * @param timeout in milliseconds
     * @throws SQLException
     */
    protected void setStatementQueryTimeout(PreparedStatement stmnt,
        int timeout) throws SQLException {
        // JDBC uses seconds, so we'll do a simple round-down conversion here
        stmnt.setQueryTimeout(timeout / 1000);
    }

    //////////////////////////////////////
    // ConnectionDecorator implementation
    //////////////////////////////////////

    /**
     * Decorate the given connection if needed. Some databases require special
     * handling for JDBC bugs. This implementation issues any
     * {@link #initializationSQL} that has been set for the dictionary but
     * does not decorate the connection.
     */
    @Override
    public Connection decorate(Connection conn)
        throws SQLException {
        if (!connected)
            connectedConfiguration(conn);
        if (!StringUtil.isEmpty(initializationSQL)) {
            PreparedStatement stmnt = null;
            try {
                stmnt = conn.prepareStatement(initializationSQL);
                stmnt.execute();
            } catch (Exception e) {
                if (log.isTraceEnabled())
                    log.trace(e.toString(), e);
            } finally {
                if (stmnt != null)
                    try {
                        stmnt.close();
                    } catch (SQLException se) {
                    }
            }
        }
        return conn;
    }

    /**
     * Implementation of the
     * {@link LoggingConnectionDecorator.SQLWarningHandler} interface
     * that allows customization of the actions to perform when a
     * {@link SQLWarning} occurs at any point on a {@link Connection},
     * {@link Statement}, or {@link ResultSet}. This method may
     * be used determine those warnings the application wants to
     * consider critical failures, and throw the warning in those
     * cases. By default, this method does nothing.
     *
     * @see LoggingConnectionDecorator#setWarningAction
     * @see LoggingConnectionDecorator#setWarningHandler
     */
    @Override
    public void handleWarning(SQLWarning warning)
        throws SQLException {
    }

    /**
     * Return a new exception that wraps <code>causes</code>.
     * However, the details of exactly what type of exception is returned can
     * be determined by the implementation. This may take into account
     * DB-specific exception information in <code>causes</code>.
     */
    public OpenJPAException newStoreException(String msg, SQLException[] causes, Object failed) {
        if (causes != null && causes.length > 0) {
            OpenJPAException ret = narrow(msg, causes[0], failed);
            ret.setFailedObject(failed).setNestedThrowables(causes);
            return ret;
        }
        return new StoreException(msg).setFailedObject(failed).
            setNestedThrowables(causes);
    }

    /**
     * Gets the category of StoreException by matching the given SQLException's
     * error state code to the list of error codes supplied by the dictionary.
     *
     * @return a StoreException of {@link ExceptionInfo#GENERAL general} category
     * if the given SQL Exception can not be further categorized.
     *
     * @see #matchErrorState(Map, SQLException)
     */
    OpenJPAException narrow(String msg, SQLException ex, Object failed) {
        int errorType = matchErrorState(sqlStateCodes, ex);
        StoreException storeEx;
        switch (errorType) {
        case StoreException.LOCK:
            storeEx = new LockException(failed);
            break;
        case StoreException.OBJECT_EXISTS:
            storeEx = new ObjectExistsException(msg);
            break;
        case StoreException.OBJECT_NOT_FOUND:
            storeEx = new ObjectNotFoundException(failed);
            break;
        case StoreException.OPTIMISTIC:
            storeEx = new OptimisticException(failed);
            break;
        case StoreException.REFERENTIAL_INTEGRITY:
            storeEx = new ReferentialIntegrityException(msg);
            break;
        case StoreException.QUERY:
            storeEx = new QueryException(msg);
            break;
        default:
            storeEx = new StoreException(msg);
        }
        storeEx.setFatal(isFatalException(errorType, ex));
        return storeEx;
    }

    /**
     * Determine the more appropriate type of store exception by matching the SQL Error State of the
     * the given SQLException to the given Error States categorized by error types.
     * Dictionary subclass can override this method and extract
     * SQLException data to figure out if the exception is recoverable.
     *
     * @param errorStates classification of SQL error states by their specific nature. The keys of the
     * map represent one of the constants defined in {@link StoreException}. The value corresponding to
     * a key represent the set of SQL Error States representing specific category of database error.
     * This supplied map is sourced from <code>sql-error-state-codes.xml</xml> and filtered the
     * error states for the current database.
     *
     * @param ex original SQL Exception as raised by the database driver.
     *
     * @return A constant indicating the category of error as defined in {@link StoreException}.
     */
    protected int matchErrorState(Map<Integer,Set<String>> errorStates, SQLException ex) {
        String errorState = ex.getSQLState();
        for (Map.Entry<Integer,Set<String>> states : errorStates.entrySet()) {
            if (states.getValue().contains(errorState))
                return states.getKey();
        }
        return ExceptionInfo.GENERAL;
    }

    /**
     * Determine if the given SQL Exception is fatal or recoverable (such as a timeout).
     * This implementation always returns true (i.e. all exceptions are fatal).
     * The current dictionary implementation can overwrite this method to mark certain
     * exception conditions as recoverable error.

     * @param subtype A constant indicating the category of error as defined in {@link StoreException}.
     * @param ex original SQL Exception as raised by the database driver.
     *
     * @return false if the error is fatal.
     */
    public boolean isFatalException(int subtype, SQLException ex) {
        return true;
    }

    /**
     * Closes the specified {@link DataSource} and releases any
     * resources associated with it.
     *
     * @param dataSource the DataSource to close
     */
    public void closeDataSource(DataSource dataSource) {
        DataSourceFactory.closeDataSource(dataSource);
    }

    /**
     * Used by some mappings to represent data that has already been
     * serialized so that we don't have to serialize multiple times.
     */
    public static class SerializedData {

        public final byte[] bytes;

        public SerializedData(byte[] bytes) {
            this.bytes = bytes;
        }
    }

    /**
     * Return version column name
     * @param column
     * @param tableAlias : this is needed for platform specific version column
     */
    public String getVersionColumn(Column column, String tableAlias) {
        return getVersionColumn(column, DBIdentifier.newTable(tableAlias)).toString();
    }

    public DBIdentifier getVersionColumn(Column column, DBIdentifier tableAlias) {
        return column.getIdentifier();
    }

    public void insertBlobForStreamingLoad(Row row, Column col,
        JDBCStore store, Object ob, Select sel) throws SQLException {
        if (ob != null) {
            row.setBinaryStream(col,
                new ByteArrayInputStream(new byte[0]), 0);
        } else {
            row.setNull(col);
        }
    }

    public void insertClobForStreamingLoad(Row row, Column col, Object ob)
    throws SQLException {
        if (ob != null) {
        row.setCharacterStream(col,
                new CharArrayReader(new char[0]), 0);
        } else {
            row.setNull(col);
        }
    }

    public void updateBlob(Select sel, JDBCStore store, InputStream is)
        throws SQLException {
        SQLBuffer sql = sel.toSelect(true, store.getFetchConfiguration());
        ResultSet res = null;
        Connection conn = store.getConnection();
        PreparedStatement stmnt = null;
        try {
            stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(),
                ResultSet.TYPE_SCROLL_SENSITIVE,
                ResultSet.CONCUR_UPDATABLE);
            setTimeouts(stmnt, store.getFetchConfiguration(), true);
            res = stmnt.executeQuery();
            if (!res.next()) {
                throw new InternalException(_loc.get("stream-exception"));
            }
            Blob blob = res.getBlob(1);
            OutputStream os = blob.setBinaryStream(1);
            copy(is, os);
            os.close();
            res.updateBlob(1, blob);
            res.updateRow();

        } catch (IOException ioe) {
            throw new StoreException(ioe);
        } finally {
            if (res != null)
                try { res.close (); } catch (SQLException e) {}
            if (stmnt != null)
                try { stmnt.close (); } catch (SQLException e) {}
            if (conn != null)
                try { conn.close (); } catch (SQLException e) {}
        }
    }

    public void updateClob(Select sel, JDBCStore store, Reader reader)
        throws SQLException {
        SQLBuffer sql = sel.toSelect(true, store.getFetchConfiguration());
        ResultSet res = null;
        Connection conn = store.getConnection();
        PreparedStatement stmnt = null;
        try {
            stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(),
                ResultSet.TYPE_SCROLL_SENSITIVE,
                ResultSet.CONCUR_UPDATABLE);
            setTimeouts(stmnt, store.getFetchConfiguration(), true);
            res = stmnt.executeQuery();
            if (!res.next()) {
                throw new InternalException(_loc.get("stream-exception"));
            }
            Clob clob = res.getClob(1);
            if (clob != null) {
                Writer writer = clob.setCharacterStream(1);
                copy(reader, writer);
                writer.close();
                res.updateClob(1, clob);
                res.updateRow();
            }

        } catch (IOException ioe) {
            throw new StoreException(ioe);
        } finally {
            if (res != null)
                try { res.close (); } catch (SQLException e) {}
            if (stmnt != null)
                try { stmnt.close (); } catch (SQLException e) {}
            if (conn != null)
                try { conn.close (); } catch (SQLException e) {}
        }
    }

    protected long copy(InputStream in, OutputStream out) throws IOException {
        byte[] copyBuffer = new byte[blobBufferSize];
        long bytesCopied = 0;
        int read = -1;

        while ((read = in.read(copyBuffer, 0, copyBuffer.length)) != -1) {
            out.write(copyBuffer, 0, read);
            bytesCopied += read;
        }
        return bytesCopied;
    }

    protected long copy(Reader reader, Writer writer) throws IOException {
        char[] copyBuffer = new char[clobBufferSize];
        long bytesCopied = 0;
        int read = -1;

        while ((read = reader.read(copyBuffer, 0, copyBuffer.length)) != -1) {
            writer.write(copyBuffer, 0, read);
            bytesCopied += read;
        }

        return bytesCopied;
    }

    /**
     * Attach CAST to the current function if necessary
     *
     * @param val operand value
     * @parma func the sql function statement
     * @return a String with the correct CAST function syntax
     */
    public String getCastFunction(Val val, String func) {
        return func;
    }

    /**
     * Return the correct CAST function syntax.  This should be overriden by subclasses
     * that need access to the Column information.
     *
     * @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) {
        return getCastFunction (val, func);
    }

    /**
     * Create an index if necessary for some database tables
     * @deprecated
     */
    @Deprecated
    public void createIndexIfNecessary(Schema schema, String table,
            Column pkColumn) {
    }

    public void createIndexIfNecessary(Schema schema, DBIdentifier table,
        Column pkColumn) {
    }

    /**
     * Return the batchLimit
     */
    public int getBatchLimit(){
        return batchLimit;
    }

    /**
     * Set the batchLimit value
     */
    public void setBatchLimit(int limit){
        batchLimit = limit;
    }

    /**
     * Validate the batch process. In some cases, we can't batch the statements
     * due to some restrictions. For example, if the GeneratedType=IDENTITY,
     * we have to disable the batch process because we need to get the ID value
     * right away for the in-memory entity to use.
     */
    public boolean validateBatchProcess(RowImpl row, Column[] autoAssign,
            OpenJPAStateManager  sm, ClassMapping cmd ) {
        boolean disableBatch = false;
        if (getBatchLimit()== 0) return false;
        if (autoAssign != null && sm != null) {
            FieldMetaData[] fmd = cmd.getPrimaryKeyFields();
            int i = 0;
            while (!disableBatch && i < fmd.length) {
                if (fmd[i].getValueStrategy() == ValueStrategies.AUTOASSIGN)
                    disableBatch = true;
                i++;
            }
        }
        // go to each Dictionary to validate the batch capability
        if (!disableBatch)
            disableBatch = validateDBSpecificBatchProcess(disableBatch, row,
                autoAssign, sm, cmd);
        return disableBatch;
    }

    /**
     * Allow each Dictionary to validate its own batch process.
     */
    public boolean validateDBSpecificBatchProcess (boolean disableBatch,
            RowImpl row, Column[] autoAssign,
            OpenJPAStateManager  sm, ClassMapping cmd ) {
        return disableBatch;
    }

    /**
     * This method is to provide override for non-JDBC or JDBC-like
     * implementation of executing query.
     */
    protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt,
            String sql
        ) throws SQLException {
        return stmnt.executeQuery();
    }

    /**
     * This method is to provide override for non-JDBC or JDBC-like
     * implementation of preparing statement.
     */
    protected PreparedStatement prepareStatement(Connection conn, String sql)
        throws SQLException {
        return conn.prepareStatement(sql);
    }

    /**
     * This method is to provide override for non-JDBC or JDBC-like
     * implementation of getting sequence from the result set.
     */
    protected Sequence[] getSequence(ResultSet rs) throws SQLException {
        List seqList = new ArrayList();
        while (rs != null && rs.next())
            seqList.add(newSequence(rs));
        return (Sequence[]) seqList.toArray(new Sequence[seqList.size()]);
    }

    /**
     * This method is to provide override for non-JDBC or JDBC-like
     * implementation of getting key from the result set.
     */
    protected Object getKey (ResultSet rs, Column col) throws SQLException {
        if (!rs.next())
            throw new StoreException(_loc.get("no-genkey"));
        Object key = rs.getObject(1);
        if (key == null)
            log.warn(_loc.get("invalid-genkey", col));
        return key;
    }

    /**
     * This method is to provide override for non-JDBC or JDBC-like
     * implementation of calculating value.
     */
    protected void calculateValue(Val val, Select sel, ExpContext ctx,
        ExpState state, Path path, ExpState pathState) {
        val.calculateValue(sel, ctx, state, (Val) path, pathState);
    }

    /**
     * Determine whether the provided <code>sql</code> may be treated as a
     * select statement on this database.
     *
     * @param sql   A sql statement.
     *
     * @return true if <code>sql</code> represents a select statement.
     */
    public boolean isSelect(String sql) {
        Iterator i = selectWordSet.iterator();
        String cur;
        while (i.hasNext()) {
            cur = (String) i.next();
            if (sql.length() >= cur.length()
                    && sql.substring(0, cur.length()).equalsIgnoreCase(cur)) {
                return true;
            }
        }
        return false;
    }

    public boolean needsToCreateIndex(Index idx, Table table, Unique[] uniques) {
        return needsToCreateIndex(idx, table);
    }

    public boolean needsToCreateIndex(Index idx, Table table) {
        return true;
    }

    /**
     * Return batched statements update success count
     * @param ps A PreparedStatement
     * @return return update count
     */
    public int getBatchUpdateCount(PreparedStatement ps) throws SQLException {
        return 0;
    }

    public boolean getTrimSchemaName() {
        return trimSchemaName;
    }

    public void setTrimSchemaName(boolean trimSchemaName) {
        this.trimSchemaName = trimSchemaName;
    }

    public void deleteStream(JDBCStore store, Select sel) throws SQLException {
        // Do nothing
    }

    /**
     * Validate that the given name is not longer than given maximum length.
     * If the given name is indeed longer then raises a UserException with the
     * given message key otherwise returns the same name.
     */
    final String checkNameLength(String name, int length, String msgKey) {
        if (name.length() > length) {
            throw new UserException(_loc.get(msgKey, name, name.length(), length));
        }
        return name;
    }

    /**
     * Validate that the given name is not longer than given maximum length. Uses the unqualified name
     * from the supplied {@link DBIdentifier} by default..
     *
     * @param identifier The database identifier to check.
     * @param length    Max length for this type of identifier
     * @param msgKey    message identifier for the exception.
     *
     * @throws {@link UserException} with the given message key if the given name is indeed longer.
     * @return the same name.
     */
    final String checkNameLength(DBIdentifier identifier, int length, String msgKey) {
        return checkNameLength(identifier, length, msgKey, false);
    }

    /**
     * Validate that the given name is not longer than given maximum length. Conditionally uses the unqualified name
     * from the supplied {@link DBIdentifier}.
     *
     * @param identifier The database identifier to check.
     * @param length    Max length for this type of identifier
     * @param msgKey    message identifier for the exception.
     * @param qualified If true the qualified name of the DBIdentifier will be used.
     *
     * @throws {@link UserException} with the given message key if the given name is indeed longer.
     * @return the same name.
     */
    final String checkNameLength(DBIdentifier identifier, int length, String msgKey, boolean qualified) {
        // always return the input name,
        String name = toDBName(identifier);
        String compareName = qualified ? name : toDBName(identifier.getUnqualifiedName());

        if (compareName.length() > length) {
            throw new UserException(_loc.get(msgKey, name, name.length(), length));
        }
        return name;
    }

    protected void setDelimitedCase(DatabaseMetaData metaData) {
        try {
            if (metaData.storesMixedCaseQuotedIdentifiers()) {
                delimitedCase = SCHEMA_CASE_PRESERVE;
            }
            else if (metaData.storesUpperCaseQuotedIdentifiers()) {
                delimitedCase = SCHEMA_CASE_UPPER;
            }
            else if (metaData.storesLowerCaseQuotedIdentifiers()) {
                delimitedCase = SCHEMA_CASE_LOWER;
            }
        } catch (SQLException e) {
            getLog().warn("cannot-determine-identifier-case");
            if (getLog().isTraceEnabled()) {
                getLog().trace(e.toString(), e);
            }
        }
    }

    /**
     * @return the supportsDelimitedIds
     */
    @Override
    public boolean getSupportsDelimitedIdentifiers() {
        return (supportsDelimitedIdentifiers == null ? false : supportsDelimitedIdentifiers);
    }

    /**
     * @param supportsDelimitedIds the supportsDelimitedIds to set
     */
    public void setSupportsDelimitedIdentifiers(boolean supportsDelimitedIds) {
        supportsDelimitedIdentifiers = Boolean.valueOf(supportsDelimitedIds);
    }

    /**
     * @param metaData the DatabaseMetaData to use to determine whether delimiters can be supported
     */
    private void setSupportsDelimitedIdentifiers(DatabaseMetaData metaData) {
        try {
            supportsDelimitedIdentifiers = Boolean.valueOf(
                metaData.supportsMixedCaseQuotedIdentifiers() ||
                metaData.storesLowerCaseQuotedIdentifiers() ||
                metaData.storesUpperCaseQuotedIdentifiers());
        } catch (SQLException e) {
            supportsDelimitedIdentifiers = Boolean.valueOf(false);
            getLog().warn(_loc.get("unknown-delim-support", e));
        }
    }

    /**
     * @return the delimitIds
     */
    public boolean getDelimitIdentifiers() {
        return delimitIdentifiers;
    }

    /**
     * @param delimitIds the delimitIds to set
     */
    public void setDelimitIdentifiers(boolean delimitIds) {
        delimitIdentifiers = delimitIds;
    }

    /**
     * @return supportsXMLColumn
     */
    public boolean getSupportsXMLColumn() {
        return supportsXMLColumn;
    }

    /**
     * @param b boolean representing if XML columns are supported
     */
    public void setSupportsXMLColumn(boolean b) {
        supportsXMLColumn = b;
    }

    /**
     * @return xmlTypeEncoding
     */
    public String getXMLTypeEncoding() {
        return xmlTypeEncoding;
    }

    /**
     * @param encoding database required JAXB encoding for the XML value
     */
    public void setXMLTypeEncoding(String encoding) {
        xmlTypeEncoding = encoding;
    }

    public Log getLog() {
        return log;
    }

    @Override
    public boolean delimitAll() {
        return delimitIdentifiers;
    }

    @Override
    public String getLeadingDelimiter() {
        return leadingDelimiter;
    }

    public void setLeadingDelimiter(String delim) {
        leadingDelimiter = delim;
    }

    @Override
    public String getIdentifierDelimiter() {
        return catalogSeparator;
    }

    @Override
    public String getIdentifierConcatenator() {
        return nameConcatenator;
    }

    @Override
    public String getTrailingDelimiter() {
        return trailingDelimiter;
    }

    public void setTrailingDelimiter(String delim) {
        trailingDelimiter = delim;
    }

    @Override
    public IdentifierRule getDefaultIdentifierRule() {
        if (defaultNamingRule == null) {
            defaultNamingRule = namingRules.get(DBIdentifierType.DEFAULT.name());
        }
        return defaultNamingRule;
    }

    @Override
    public <T> IdentifierRule getIdentifierRule(T t) {
        if (t.equals(DBIdentifierType.DEFAULT.name())) {
            return getDefaultIdentifierRule();
        }
        IdentifierRule nrule = namingRules.get(t);
        if (nrule == null) {
            return getDefaultIdentifierRule();
        }
        return nrule;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Map<String, IdentifierRule> getIdentifierRules() {
        return namingRules;
    }

    /**
     * Returns the naming utility used by this dictionary instance
     */
    public DBIdentifierUtil getNamingUtil() {
        return namingUtil;
    }

    @Override
    public String getDelimitedCase() {
        return delimitedCase;
    }

    public String toDBName(DBIdentifier name) {
        if (!getSupportsDelimitedIdentifiers())
            return name.getName();
        else
            return getNamingUtil().toDBName(name);
    }

    public String toDBName(DBIdentifier name, boolean delimit) {
        if (!getSupportsDelimitedIdentifiers())
            return name.getName();
        else
            return getNamingUtil().toDBName(name, delimit);
    }

    public DBIdentifier fromDBName(String name, DBIdentifierType id) {
        return getNamingUtil().fromDBName(name, id);
    }

    public void setDefaultSchemaName(String defaultSchemaName) {
        this.defaultSchemaName = defaultSchemaName;
    }

    public String getDefaultSchemaName() {
        return defaultSchemaName;
    }

    @Override
    public String getConversionKey() {
        if (conversionKey == null) {
            conversionKey = getLeadingDelimiter() + getIdentifierDelimiter() +
            getTrailingDelimiter();
        }
        return conversionKey;
    }

    /**
     * Return parameter marker for INSERT and UPDATE statements.
     * Usually it is <code>?</code> but some database-specific types might require customization.
     *
     * @param col column definition
     * @param val value to be inserted/updated
     * @return parameter marker
     */
    public String getMarkerForInsertUpdate(Column col, Object val) {
        return "?";
    }

    public String getIsNullSQL(String colAlias, int colType)  {
        return String.format("%s IS NULL", colAlias);
    }

    public String getIsNotNullSQL(String colAlias, int colType) {
        return String.format("%s IS NOT NULL", colAlias);
    }

    public String getIdentityColumnName() {
        return null;
    }

    /**
     * Default behavior is ROUND
     */
    public DateMillisecondBehaviors getMillisecondBehavior() {
        // If the user hasn't configured this property, fall back
        // to looking at the old property in the mean time till
        // we can get rid of it.
        if (dateMillisecondBehavior == null) {
            if (roundTimeToMillisec) {
                dateMillisecondBehavior = DateMillisecondBehaviors.ROUND;
            } else {
                dateMillisecondBehavior = DateMillisecondBehaviors.DROP;
            }
        }
        return dateMillisecondBehavior;
    }

    public void setDateMillisecondBehavior(String str) {
        if (str != null) {
            // Tolerate different case
            str = str.toUpperCase(Locale.ENGLISH);
            dateMillisecondBehavior = DateMillisecondBehaviors.valueOf(str);
        } else {
            dateMillisecondBehavior = null;
        }
    }

    public BooleanRepresentation getBooleanRepresentation() {
        return booleanRepresentation;
    }

    public void setBooleanRepresentation(String booleanRepresentationKey) {
        BooleanRepresentation evaluatedBooleanRepresentation = null;
        if (booleanRepresentationKey != null && booleanRepresentationKey.length() > 0) {
            ClassLoader cl = conf.getUserClassLoader();
            evaluatedBooleanRepresentation = BooleanRepresentationFactory.valueOf(booleanRepresentationKey, cl);
        }

        booleanRepresentation = evaluatedBooleanRepresentation != null
                                    ? evaluatedBooleanRepresentation
                                    : BooleanRepresentationFactory.INT_10;
        if (log.isInfoEnabled()) {
            log.info(_loc.get("using-booleanRepresentation", booleanRepresentation));
        }
    }

    protected boolean isUsingRange(long start, long end) {
		return isUsingOffset(start) || isUsingLimit(end);
	}

	protected boolean isUsingOffset(long start) {
		return start != 0;
	}

	protected boolean isUsingLimit(long end) {
		return end != Long.MAX_VALUE;
	}

	protected boolean isUsingOrderBy(SQLBuffer sql) {
		return sql != null && !sql.isEmpty();
	}

	protected boolean versionEqualOrLaterThan(int maj, int min) {
    	return (major > maj) || (major == maj && minor >= min);
    }

	protected boolean versionEqualOrEarlierThan(int maj, int min) {
    	return (major < maj) || (major == maj && minor <= min);
    }

	protected boolean versionLaterThan(int maj) {
    	return (major > maj);
    }

	/**
	 * Gets major version of the database server.
	 */
	public final int getMajorVersion() {
		return major;
	}

	/**
	 * Sets major version of the database server.
	 */
	public void setMajorVersion(int maj) {
		major = maj;
	}

	/**
	 * Gets minor version of the database server.
	 */
	public final int getMinorVersion() {
		return major;
	}

	/**
	 * Sets minor version of the database server.
	 */
	public void setMinorVersion(int min) {
		minor = min;
	}

    String nullSafe(String s) {
        return s == null ? "" : s;
    }

	public int applyRange(Select select, int count) {
		return count;
	}

}
