/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     Markus KARG - Added methods allowing to support stored procedure creation on SQLAnywherePlatform.
//     tware - added implementation of computeMaxRowsForSQL
//     Dies Koper (Fujitsu) - bug fix for printFieldUnique()
//     Dies Koper (Fujitsu) - added methods to create/drop indices
//     Vikram Bhatia - added method for releasing temporary LOBs after conversion
//     09/09/2011-2.3.1 Guy Pelletier
//       - 356197: Add new VPD type to MultitenantType
//     02/04/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     04/30/2014-2.6 Lukas Jungmann
//       - 380101: Invalid MySQL SQL syntax in query with LIMIT and FOR UPDATE
//     02/19/2015 - Rick Curtis
//       - 458877 : Add national character support
//     02/23/2015-2.6 Dalia Abo Sheasha
//       - 460607: Change DatabasePlatform StoredProcedureTerminationToken to be configurable
//     11/12/2018 - Will Dazey
//       - 540929 : 'jdbc.sql-cast' property does not copy
//     12/06/2018 - Will Dazey
//       - 542491: Add new 'eclipselink.jdbc.force-bind-parameters' property to force enable binding
package org.eclipse.persistence.internal.databaseaccess;

// javase imports
import java.io.ByteArrayInputStream;
import java.io.CharArrayReader;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Statement;
import java.sql.Struct;
import java.sql.Types;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

// EclipseLink imports
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.JavaPlatform;
import org.eclipse.persistence.internal.sequencing.Sequencing;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDatabaseField;
import org.eclipse.persistence.platform.database.AccessPlatform;
import org.eclipse.persistence.platform.database.DB2Platform;
import org.eclipse.persistence.platform.database.DBasePlatform;
import org.eclipse.persistence.platform.database.OraclePlatform;
import org.eclipse.persistence.platform.database.PostgreSQLPlatform;
import org.eclipse.persistence.platform.database.SybasePlatform;
import org.eclipse.persistence.platform.database.SymfowarePlatform;
import org.eclipse.persistence.platform.database.converters.StructConverter;
import org.eclipse.persistence.platform.database.partitioning.DataPartitioningCallback;
import org.eclipse.persistence.queries.Call;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.queries.SQLCall;
import org.eclipse.persistence.queries.StoredProcedureCall;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sequencing.TableSequence;
import org.eclipse.persistence.sessions.SessionProfiler;
import org.eclipse.persistence.tools.schemaframework.FieldDefinition;
import org.eclipse.persistence.tools.schemaframework.TableDefinition;

/**
 * DatabasePlatform is private to EclipseLink. It encapsulates behavior specific to a database platform
 * (eg. Oracle, Sybase, DBase), and provides protocol for EclipseLink to access this behavior. The behavior categories
 * which require platform specific handling are SQL generation and sequence behavior. While database platform
 * currently provides sequence number retrieval behavior, this will move to a sequence manager (when it is
 * implemented).
 *
 * @see AccessPlatform
 * @see DB2Platform
 * @see DBasePlatform
 * @see OraclePlatform
 * @see SybasePlatform
 *
 * @since TOPLink/Java 1.0
 */
public class DatabasePlatform extends DatasourcePlatform {

    /** Holds a map of values used to map JAVA types to database types for table creation */
    protected transient Map<Class, FieldTypeDefinition> fieldTypes;

    /** Indicates that native SQL should be used for literal values instead of ODBC escape format
    Only used with Oracle, Sybase &amp; DB2 */
    protected boolean usesNativeSQL;

    /** Indicates that binding will be used for BLOB data. NOTE: does not work well with ODBC. */
    protected boolean usesByteArrayBinding;

    /** Batch all write statements */
    protected boolean usesBatchWriting;

    /** Bind all arguments to any SQL statement. */
    protected boolean shouldBindAllParameters;

    /** Bind all arguments to any SQL statement. */
    protected boolean shouldForceBindAllParameters;

    /** Cache all prepared statements, this requires full parameter binding as well. */
    protected boolean shouldCacheAllStatements;

    /** The statement cache size for prepare parameterized statements. */
    protected int statementCacheSize;

    /** Can be used if the app expects upper case but the database is not return consistent case, i.e. different databases. */
    protected boolean shouldForceFieldNamesToUpperCase;

    /** Indicates (if true) to remove blanks characters from the right of CHAR strings. */
    protected boolean shouldTrimStrings;

    /** Indicates that streams will be used to store BLOB data. NOTE: does not work with ODBC */
    protected boolean usesStreamsForBinding;

    /** Indicates the size above which strings will be bound NOTE: does not work with ODBC */
    protected int stringBindingSize;

    /** Indicates that strings will above the stringBindingSize will be bound NOTE: does not work with ODBC */
    protected boolean usesStringBinding;

    /** Allow for the batch size to be set as many database have strict limits. **/
    protected int maxBatchWritingSize;

    /** used for casting of input parameters in certain DBs **/
    protected int castSizeForVarcharParameter;

    /** Allow for our batch writing support to be used in JDK 1.2. **/
    protected boolean usesJDBCBatchWriting;

    /** bug 4241441: Allow custom batch writing to enable batching with optimistic locking. **/
    protected boolean usesNativeBatchWriting;

    /** Allow for a custom batch writing mechanism. **/
    protected BatchWritingMechanism batchWritingMechanism;

    /** Allow configuration option to use Where clause outer joining or From clause joining. **/
    protected Boolean printOuterJoinInWhereClause;

    /** Allow configuration option to use Where clause joining or From clause joining. **/
    protected Boolean printInnerJoinInWhereClause;

    /** Allow for the code that is used for preparing cursored outs for a storedprocedure to be settable. **/
    protected int cursorCode;

    /** The transaction isolation level to be set on the connection (optional). */
    protected int transactionIsolation;

    /** Some JDBC drivers do not support AutoCommit in the way EclipseLink expects.  (e.g. Attunity Connect, JConnect) */
    protected boolean supportsAutoCommit;

    /**
     * Allow for driver level data conversion optimization to be disabled,
     * required because some drivers can loose precision.
     */
    protected boolean shouldOptimizeDataConversion;

    /** Stores mapping of class types to database types for schema creation. */
    protected transient Map<String, Class> classTypes;

    /** Allow for case in field names to be ignored as some databases are not case sensitive and when using custom this can be an issue. */
    public static boolean shouldIgnoreCaseOnFieldComparisons = false;


    /** Bug#3214927 The default is 32000 for DynamicSQLBatchWritingMechanism.
     * It would become 100 when switched to ParameterizedSQLBatchWritingMechanism.
     */
    public static final int DEFAULT_MAX_BATCH_WRITING_SIZE = 32000;
    public static final int DEFAULT_PARAMETERIZED_MAX_BATCH_WRITING_SIZE = 100;

    /** Timeout used is isValid() check for dead connections. */
    public static final int IS_VALID_TIMEOUT = 0;

    /** This attribute will store the SQL query that will be used to 'ping' the database
     * connection in order to check the health of a connection.
     */
    protected String pingSQL;

    /** The following two maps, provide two ways of looking up StructConverters.
     * They can be looked up by java Class or by Struct type
     */
    protected Map<String, StructConverter> structConverters = null;
    protected Map<Class, StructConverter> typeConverters = null;

    /**
     * Some platforms allow a query's maxRows and FirstResult settings to be
     * specified in SQL.  This setting allows it to be enabled/disabled
     */
    protected boolean useRownumFiltering = true;

    /**
     * Allow platform specific cast to be enabled.
     */
    protected boolean isCastRequired = false;

    /**
     * Allow user to require literals to be bound.
     */
    protected boolean shouldBindLiterals = true;

    /**
     * String used on all table creation statements generated from the DefaultTableGenerator
     * with a session using this project.  This value will be appended to CreationSuffix strings
     * stored within the DatabaseTable creationSuffix.
     */
    protected String tableCreationSuffix;

    /**
     * The delimiter between stored procedures in multiple stored procedure
     * calls.
     */
    protected String storedProcedureTerminationToken;


    /**
     * Used to integrate with data partitioning in an external DataSource such as UCP.
     */
    protected DataPartitioningCallback partitioningCallback;

    /** Allows auto-indexing for foreign keys to be set. */
    protected boolean shouldCreateIndicesOnForeignKeys;

    protected Boolean useJDBCStoredProcedureSyntax;
    protected String driverName;

    /**
     * Creates an instance of default database platform.
     */
    public DatabasePlatform() {
        this.tableQualifier = "";
        this.usesNativeSQL = false;
        this.usesByteArrayBinding = true;
        this.usesStringBinding = false;
        this.stringBindingSize = 255;
        this.shouldTrimStrings = true;
        this.shouldBindAllParameters = true;
        this.shouldForceBindAllParameters = false;
        this.shouldCacheAllStatements = false;
        this.shouldOptimizeDataConversion = true;
        this.statementCacheSize = 50;
        this.shouldForceFieldNamesToUpperCase = false;
        this.maxBatchWritingSize = 0;
        this.usesJDBCBatchWriting = true;
        this.transactionIsolation = -1;
        this.cursorCode = -10;
        this.supportsAutoCommit = true;
        this.usesNativeBatchWriting = false;
        this.castSizeForVarcharParameter = 32672;
        this.startDelimiter = "\"";
        this.endDelimiter = "\"";
        this.useJDBCStoredProcedureSyntax = null;
        this.storedProcedureTerminationToken = ";";
    }

    /**
     * Initialize operators to avoid concurrency issues.
     */
    @Override
    public void initialize() {
        getPlatformOperators();
    }

    /**
     * Check if has callback.
     * Used to integrate with data partitioning in an external DataSource such as UCP.
     */
    public boolean hasPartitioningCallback() {
        return this.partitioningCallback != null;
    }

    /**
     * Return callback.
     * Used to integrate with data partitioning in an external DataSource such as UCP.
     */
    public DataPartitioningCallback getPartitioningCallback() {
        return partitioningCallback;
    }

    /**
     * Set callback.
     * Used to integrate with data partitioning in an external DataSource such as UCP.
     */
    public void setPartitioningCallback(DataPartitioningCallback partitioningCallback) {
        this.partitioningCallback = partitioningCallback;
    }

    /**
     * Return if casting is enabled for platforms that support it.
     * Allow platform specific cast to be disabled.
     */
    public boolean isCastRequired() {
        return isCastRequired;
    }

    /**
     * Set if casting is enabled for platforms that support it.
     * Allow platform specific cast to be disabled.
     */
    public void setIsCastRequired(boolean isCastRequired) {
        this.isCastRequired = isCastRequired;
    }

    /**
     * INTERNAL:
     * Get the map of StructConverters that will be used to preprocess
     * STRUCT data as it is read
     */
    public Map<String, StructConverter> getStructConverters() {
        return this.structConverters;
    }

    /**
     * PUBLIC:
     * Get the String used on all table creation statements generated from the DefaultTableGenerator
     * with a session using this project (DDL generation).  This value will be appended to CreationSuffix strings
     * stored on the DatabaseTable or TableDefinition.
     */
    public String getTableCreationSuffix(){
        return this.tableCreationSuffix;
    }

    /**
     * INTERNAL:
     * Get the map of TypeConverters
     * This map indexes StructConverters by the Java Class they are meant to
     * convert
     */
    public Map<Class, StructConverter> getTypeConverters() {
        if (typeConverters == null){
            typeConverters = new HashMap<>();
        }
        return this.typeConverters;
    }

    /**
     * PUBLIC:
     * Add a StructConverter to this DatabasePlatform
     * This StructConverter will be invoked for all writes to the database for the class returned
     * by its getJavaType() method and for all reads from the database for the Structs described
     * by its getStructName() method
     */
    public void addStructConverter(StructConverter converter) {
        if (structConverters == null){
            structConverters = new HashMap<>();
        }
        if (typeConverters == null){
            typeConverters = new HashMap<>();
        }
        structConverters.put(converter.getStructName(), converter);
        typeConverters.put(converter.getJavaType(), converter);
    }

    /**
     * INTERNAL: This gets called on each iteration to add parameters to the batch
     * Needs to be implemented so that it returns the number of rows successfully modified
     * by this statement for optimistic locking purposes (if useNativeBatchWriting is enabled, and
     * the call uses optimistic locking).  Is used with parameterized SQL
     *
     * @return - number of rows modified/deleted by this statement if it was executed (0 if it wasn't)
     */
    public int addBatch(PreparedStatement statement) throws java.sql.SQLException {
        statement.addBatch();
        return 0;
    }

    /**
     * Used for stored procedure definitions.
     */
    public boolean allowsSizeInProcedureArguments() {
        return true;
    }

    /**
     * Appends a Boolean value as a number
     */
    protected void appendBoolean(Boolean bool, Writer writer) throws IOException {
        if (bool) {
            writer.write("1");
        } else {
            writer.write("0");
        }
    }

    /**
     * Append the ByteArray in ODBC literal format ({b hexString}).
     * This limits the amount of Binary data by the length of the SQL. Binding should increase this limit.
     */
    protected void appendByteArray(byte[] bytes, Writer writer) throws IOException {
        writer.write("{b '");
        Helper.writeHexString(bytes, writer);
        writer.write("'}");
    }

    /**
     * Answer a platform correct string representation of a Date, suitable for SQL generation.
     * The date is printed in the ODBC platform independent format {d 'yyyy-mm-dd'}.
     */
    protected void appendDate(java.sql.Date date, Writer writer) throws IOException {
        writer.write("{d '");
        writer.write(Helper.printDate(date));
        writer.write("'}");
    }

    /**
     * Write number to SQL string. This is provided so that database which do not support
     * Exponential format can customize their printing.
     */
    protected void appendNumber(Number number, Writer writer) throws IOException {
        writer.write(number.toString());
    }

    /**
     * INTERNAL:
     * In case shouldBindLiterals is true, instead of null value a DatabaseField
     * value may be passed (so that it's type could be used for binding null).
     */
    public void appendLiteralToCall(Call call, Writer writer, Object literal) {
        if(shouldBindLiterals()) {
            appendLiteralToCallWithBinding(call, writer, literal);
        } else {
            int nParametersToAdd = appendParameterInternal(call, writer, literal);
            for (int i = 0; i < nParametersToAdd; i++) {
                ((DatabaseCall)call).getParameterTypes().add(DatabaseCall.LITERAL);
            }
        }
    }

    /**
     * INTERNAL:
     * Override this method in case the platform needs to do something special for binding literals.
     * Note that instead of null value a DatabaseField
     * value may be passed (so that it's type could be used for binding null).
     */
    protected void appendLiteralToCallWithBinding(Call call, Writer writer, Object literal) {
        ((DatabaseCall)call).appendLiteral(writer, literal);
    }

    /**
     * Write a database-friendly representation of the given parameter to the writer.
     * Determine the class of the object to be written, and invoke the appropriate print method
     * for that object. The default is "toString".
     * The platform may decide to bind some types, such as byte arrays and large strings.
     * Should only be called in case binding is not used.
     */
    @Override
    public void appendParameter(Call call, Writer writer, Object parameter) {
        appendParameterInternal(call, writer, parameter);
    }

    /**
     * Returns the number of parameters that used binding.
     * Should only be called in case binding is not used.
     */
    public int appendParameterInternal(Call call, Writer writer, Object parameter) {
        int nBoundParameters = 0;
        DatabaseCall databaseCall = (DatabaseCall)call;
        try {
            // PERF: Print Calendars directly avoiding timestamp conversion,
            // Must be before conversion as you cannot bind calendars.
            if (parameter instanceof Calendar) {
                appendCalendar((Calendar)parameter, writer);
                return nBoundParameters;
            }
            Object dbValue = convertToDatabaseType(parameter);

            if (dbValue instanceof String) {// String and number first as they are most common.
                if (usesStringBinding() && (((String)dbValue).length() >= getStringBindingSize())) {
                    databaseCall.bindParameter(writer, dbValue);
                    nBoundParameters = 1;
                } else {
                    appendString((String)dbValue, writer);
                }
            } else if (dbValue instanceof Number) {
                appendNumber((Number)dbValue, writer);
            } else if (dbValue instanceof java.sql.Time) {
                appendTime((java.sql.Time)dbValue, writer);
            } else if (dbValue instanceof java.sql.Timestamp) {
                appendTimestamp((java.sql.Timestamp)dbValue, writer);
            } else if (dbValue instanceof java.time.LocalDate){
                appendDate(java.sql.Date.valueOf((java.time.LocalDate) dbValue), writer);
            } else if (dbValue instanceof java.time.LocalDateTime){
                appendTimestamp(java.sql.Timestamp.valueOf((java.time.LocalDateTime) dbValue), writer);
            } else if (dbValue instanceof java.time.OffsetDateTime) {
                appendTimestamp(java.sql.Timestamp.from(((java.time.OffsetDateTime) dbValue).toInstant()), writer);
            } else if (dbValue instanceof java.time.LocalTime){
                java.time.LocalTime lt = (java.time.LocalTime) dbValue;
                java.sql.Timestamp ts = java.sql.Timestamp.valueOf(java.time.LocalDateTime.of(java.time.LocalDate.ofEpochDay(0), lt));
                appendTimestamp(ts, writer);
            } else if (dbValue instanceof java.time.OffsetTime) {
                java.time.OffsetTime ot = (java.time.OffsetTime) dbValue;
                java.sql.Timestamp ts = java.sql.Timestamp.valueOf(java.time.LocalDateTime.of(java.time.LocalDate.ofEpochDay(0), ot.toLocalTime()));
                appendTimestamp(ts, writer);
            } else if (dbValue instanceof java.time.LocalDate){
                appendDate(java.sql.Date.valueOf((java.time.LocalDate) dbValue), writer);
            } else if (dbValue instanceof java.sql.Date) {
                appendDate((java.sql.Date)dbValue, writer);
            } else if (dbValue == null) {
                writer.write("NULL");
            } else if (dbValue instanceof Boolean) {
                appendBoolean((Boolean)dbValue, writer);
            } else if (dbValue instanceof byte[]) {
                if (usesByteArrayBinding()) {
                    databaseCall.bindParameter(writer, dbValue);
                    nBoundParameters = 1;
                } else {
                    appendByteArray((byte[])dbValue, writer);
                }
            } else if (dbValue instanceof Collection) {
                nBoundParameters = printValuelist((Collection)dbValue, databaseCall, writer);
            } else if (typeConverters != null && typeConverters.containsKey(dbValue.getClass())){
                dbValue = new BindCallCustomParameter(dbValue);
                // custom binding is required, object to be bound is wrapped (example NCHAR, NVARCHAR2, NCLOB on Oracle9)
                databaseCall.bindParameter(writer, dbValue);
            } else if ((parameter instanceof Struct) || (parameter instanceof Array) || (parameter instanceof Ref)) {
                databaseCall.bindParameter(writer, parameter);
                nBoundParameters = 1;
            } else if (dbValue.getClass() == int[].class) {
                nBoundParameters = printValuelist((int[])dbValue, databaseCall, writer);
            } else if (dbValue instanceof AppendCallCustomParameter) {
                // custom append is required (example BLOB, CLOB on Oracle8)
                ((AppendCallCustomParameter)dbValue).append(writer);
                nBoundParameters = 1;
            } else if (dbValue instanceof BindCallCustomParameter) {
                // custom binding is required, object to be bound is wrapped (example NCHAR, NVARCHAR2, NCLOB on Oracle9)
                databaseCall.bindParameter(writer, dbValue);
                nBoundParameters = 1;
            } else {
                // Assume database driver primitive that knows how to print itself, this is required for drivers
                // such as Oracle JDBC, Informix JDBC and others, as well as client specific classes.
                writer.write(dbValue.toString());
            }
        } catch (IOException exception) {
            throw ValidationException.fileError(exception);
        }

        return nBoundParameters;
    }

    /**
     * Write the string.  Quotes must be double quoted.
     */
    protected void appendString(String string, Writer writer) throws IOException {
        writer.write('\'');
        for (int position = 0; position < string.length(); position++) {
            if (string.charAt(position) == '\'') {
                writer.write("''");
            } else {
                writer.write(string.charAt(position));
            }
        }
        writer.write('\'');
    }

    /**
     * Answer a platform correct string representation of a Time, suitable for SQL generation.
     * The time is printed in the ODBC platform independent format {t'hh:mm:ss'}.
     */
    protected void appendTime(java.sql.Time time, Writer writer) throws IOException {
        writer.write("{t '");
        writer.write(Helper.printTime(time));
        writer.write("'}");
    }

    /**
     * Answer a platform correct string representation of a Timestamp, suitable for SQL generation.
     * The timestamp is printed in the ODBC platform independent timestamp format {ts'YYYY-MM-DD HH:MM:SS.NNNNNNNNN'}.
     */
    protected void appendTimestamp(java.sql.Timestamp timestamp, Writer writer) throws IOException {
        writer.write("{ts '");
        writer.write(Helper.printTimestamp(timestamp));
        writer.write("'}");
    }

    /**
     * Answer a platform correct string representation of a Calendar as a Timestamp, suitable for SQL generation.
     * The calendar is printed in the ODBC platform independent timestamp format {ts'YYYY-MM-DD HH:MM:SS.NNNNNNNNN'}.
     */
    protected void appendCalendar(Calendar calendar, Writer writer) throws IOException {
        writer.write("{ts '");
        writer.write(Helper.printCalendar(calendar));
        writer.write("'}");
    }

    /**
     * Used by JDBC drivers that do not support autocommit so simulate an autocommit.
     */
    public void autoCommit(DatabaseAccessor accessor) throws SQLException {
        if (!supportsAutoCommit()) {
            accessor.getConnection().commit();
        }
    }

    /**
     * Used for jdbc drivers which do not support autocommit to explicitly begin a transaction
     * This method is a no-op for databases which implement autocommit as expected.
     */
    public void beginTransaction(DatabaseAccessor accessor) throws SQLException {
        if (!supportsAutoCommit()) {
            Statement statement = accessor.getConnection().createStatement();
            try {
                statement.executeUpdate("BEGIN TRANSACTION");
            } finally {
                statement.close();
            }
        }
    }

    /**
     * INTERNAL:
     * Return the selection criteria used to IN batch fetching.
     */
    public Expression buildBatchCriteria(ExpressionBuilder builder,Expression field) {

        return field.in(
                builder.getParameter(ForeignReferenceMapping.QUERY_BATCH_PARAMETER));
    }

    /**
     * INTERNAL:
     * Return the selection criteria used to IN batch fetching.
     */
    public Expression buildBatchCriteriaForComplexId(ExpressionBuilder builder,List<Expression> fields) {
        return builder.value(fields).in(
                    builder.getParameter(ForeignReferenceMapping.QUERY_BATCH_PARAMETER));
    }

    /**
     * INTERNAL
     * Returns null unless the platform supports call with returning
     */
    public DatabaseCall buildCallWithReturning(SQLCall sqlCall, Vector returnFields) {
        throw ValidationException.platformDoesNotSupportCallWithReturning(Helper.getShortClassName(this));
    }

    /**
     * Return the mapping of class types to database types for the schema framework.
     */
    protected Map<String, Class> buildClassTypes() {
        Map<String, Class> classTypeMapping = new HashMap<>();
        // Key the Map the other way for table creation.
        classTypeMapping.put("NUMBER", java.math.BigInteger.class);
        classTypeMapping.put("DECIMAL", java.math.BigDecimal.class);
        classTypeMapping.put("INTEGER", Integer.class);
        classTypeMapping.put("INT", Integer.class);
        classTypeMapping.put("NUMERIC", java.math.BigInteger.class);
        classTypeMapping.put("FLOAT(16)", Float.class);
        classTypeMapping.put("FLOAT(32)", Double.class);
        classTypeMapping.put("NUMBER(1) default 0", Boolean.class);
        classTypeMapping.put("SHORT", Short.class);
        classTypeMapping.put("BYTE", Byte.class);
        classTypeMapping.put("DOUBLE", Double.class);
        classTypeMapping.put("FLOAT", Float.class);
        classTypeMapping.put("SMALLINT", Short.class);

        classTypeMapping.put("BIT", Boolean.class);
        classTypeMapping.put("SMALLINT DEFAULT 0", Boolean.class);

        classTypeMapping.put("VARCHAR", String.class);
        classTypeMapping.put("CHAR", Character.class);
        classTypeMapping.put("LONGVARBINARY", Byte[].class);
        classTypeMapping.put("TEXT", Character[].class);
        classTypeMapping.put("LONGTEXT", Character[].class);
        //    classTypeMapping.put("BINARY", Byte[].class);
        classTypeMapping.put("MEMO", Character[].class);
        classTypeMapping.put("VARCHAR2", String.class);
        classTypeMapping.put("LONG RAW", Byte[].class);
        classTypeMapping.put("LONG", Character[].class);

        classTypeMapping.put("DATE", java.sql.Date.class);
        classTypeMapping.put("TIMESTAMP", java.sql.Timestamp.class);
        classTypeMapping.put("TIME", java.sql.Time.class);
        classTypeMapping.put("DATETIME", java.sql.Timestamp.class);

        classTypeMapping.put("BIGINT", java.math.BigInteger.class);
        classTypeMapping.put("DOUBLE PRECIS", Double.class);
        classTypeMapping.put("IMAGE", Byte[].class);
        classTypeMapping.put("LONGVARCHAR", Character[].class);
        classTypeMapping.put("REAL", Float.class);
        classTypeMapping.put("TINYINT", Short.class);
        //    classTypeMapping.put("VARBINARY", Byte[].class);

        classTypeMapping.put("BLOB", Byte[].class);
        classTypeMapping.put("CLOB", Character[].class);

        return classTypeMapping;
    }
    /**
     * Return the mapping of class types to database types for the schema framework.
     */
    protected Hashtable buildFieldTypes() {
        Hashtable fieldTypeMapping;

        fieldTypeMapping = new Hashtable();
        fieldTypeMapping.put(Boolean.class, new FieldTypeDefinition("NUMBER", 1));

        fieldTypeMapping.put(Integer.class, new FieldTypeDefinition("NUMBER", 10));
        fieldTypeMapping.put(Long.class, new FieldTypeDefinition("NUMBER", 19));
        fieldTypeMapping.put(Float.class, new FieldTypeDefinition("NUMBER", 12, 5).setLimits(19, 0, 19));
        fieldTypeMapping.put(Double.class, new FieldTypeDefinition("NUMBER", 10, 5).setLimits(19, 0, 19));
        fieldTypeMapping.put(Short.class, new FieldTypeDefinition("NUMBER", 5));
        fieldTypeMapping.put(Byte.class, new FieldTypeDefinition("NUMBER", 3));
        fieldTypeMapping.put(java.math.BigInteger.class, new FieldTypeDefinition("NUMBER", 19));
        fieldTypeMapping.put(java.math.BigDecimal.class, new FieldTypeDefinition("NUMBER", 19, 0).setLimits(19, 0, 19));

        fieldTypeMapping.put(String.class, new FieldTypeDefinition("VARCHAR"));
        fieldTypeMapping.put(Character.class, new FieldTypeDefinition("CHAR"));

        fieldTypeMapping.put(Byte[].class, new FieldTypeDefinition("BLOB"));
        fieldTypeMapping.put(Character[].class, new FieldTypeDefinition("CLOB"));
        fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("BLOB"));
        fieldTypeMapping.put(char[].class, new FieldTypeDefinition("CLOB"));
        fieldTypeMapping.put(java.sql.Blob.class, new FieldTypeDefinition("BLOB"));
        fieldTypeMapping.put(java.sql.Clob.class, new FieldTypeDefinition("CLOB"));

        fieldTypeMapping.put(java.sql.Date.class, new FieldTypeDefinition("DATE"));
        fieldTypeMapping.put(java.sql.Timestamp.class, new FieldTypeDefinition("TIMESTAMP"));
        fieldTypeMapping.put(java.sql.Time.class, new FieldTypeDefinition("TIME"));
        //bug 5871089 the default generator requires definitions based on all java types
        fieldTypeMapping.put(java.util.Calendar.class, new FieldTypeDefinition("TIMESTAMP"));
        fieldTypeMapping.put(java.util.Date.class, new FieldTypeDefinition("TIMESTAMP"));
        fieldTypeMapping.put(java.lang.Number.class, new FieldTypeDefinition("NUMBER", 10));

        fieldTypeMapping.put(java.time.LocalDate.class, new FieldTypeDefinition("DATE"));
        fieldTypeMapping.put(java.time.LocalDateTime.class, new FieldTypeDefinition("TIMESTAMP"));
        fieldTypeMapping.put(java.time.LocalTime.class, new FieldTypeDefinition("TIME"));
        fieldTypeMapping.put(java.time.OffsetDateTime.class, new FieldTypeDefinition("TIMESTAMP"));
        fieldTypeMapping.put(java.time.OffsetTime.class, new FieldTypeDefinition("TIME"));

        return fieldTypeMapping;
    }

    /**
     * Returns true iff:
     * <ul>
     * <li>tThe current driver supports calling get/setNString</li>
     * <li> Strings are globally mapped to a national character varying type (useNationalCharacterVarying()).</li>
     * </ul>
     */
    public boolean shouldUseGetSetNString() {
        return getDriverSupportsNVarChar() && getUseNationalCharacterVaryingTypeForString();
    }

    /**
     * True if the current jdbc driver supports get/setNString methods
     */
    protected boolean driverSupportsNationalCharacterVarying = false;
    /**
     * If true, the platform should map String columns to a type that supports
     * national characters.
     */
    protected boolean useNationalCharacterVarying = false;

    public boolean getDriverSupportsNVarChar() {
        return driverSupportsNationalCharacterVarying;
    }

    public void setDriverSupportsNVarChar(boolean b) {
        driverSupportsNationalCharacterVarying = b;
    }

    public boolean getUseNationalCharacterVaryingTypeForString() {
        return useNationalCharacterVarying;
    }

    public void setUseNationalCharacterVaryingTypeForString(boolean b) {
        useNationalCharacterVarying = b;
    }

    /**
     * Return the proc syntax for this platform.
     */
    public String buildProcedureCallString(StoredProcedureCall call, AbstractSession session, AbstractRecord row) {
        StringWriter writer = new StringWriter();
        writer.write(call.getCallHeader(this));
        writer.write(call.getProcedureName());
        if (requiresProcedureCallBrackets()) {
            writer.write("(");
        } else {
            writer.write(" ");
        }

        int indexFirst = call.getFirstParameterIndexForCallString();
        int size = call.getParameters().size();
        for (int index = indexFirst; index < size; index++) {
            String name = call.getProcedureArgumentNames().get(index);
            Object parameter = call.getParameters().get(index);
            Integer parameterType = call.getParameterTypes().get(index);
            // If the argument is optional and null, ignore it.
            if (!call.hasOptionalArguments() || !call.getOptionalArguments().contains(parameter) || (row.get(parameter) != null)) {

                writer.write(getProcedureArgument(name, parameter, parameterType, call, session));

                if (DatasourceCall.isOutputParameterType(parameterType)) {
                    if (requiresProcedureCallOuputToken()) {
                        writer.write(" ");
                        writer.write(getOutputProcedureToken());
                    }
                }
                if ((index + 1) < call.getParameters().size()) {
                    writer.write(", ");
                }
            }
        }

        if (requiresProcedureCallBrackets()) {
            writer.write(")");
        }
        writer.write(getProcedureCallTail());

        return writer.toString();
    }

    /**
     * INTERNAL
     * Indicates whether the platform can build call with returning.
     * In case this method returns true, buildCallWithReturning method
     * may be called.
     */
    public boolean canBuildCallWithReturning() {
        return false;
    }

    /**
     * INTERNAL:
     * Supports Batch Writing with Optimistic Locking.
     */
    public boolean canBatchWriteWithOptimisticLocking(DatabaseCall call) {
        if (this.batchWritingMechanism != null) {
            // Assume a custom batch mechanism can return a valid row count.
            return true;
        }
        // The JDBC spec supports this, so assume it is implemented correctly by default.
        return true;
    }

    /**
     * INTERNAL:
     * Use the JDBC maxResults and firstResultIndex setting to compute a value to use when
     * limiting the results of a query in SQL.  These limits tend to be used in two ways.
     *
     * 1. MaxRows is the index of the last row to be returned (like JDBC maxResults)
     * 2. MaxRows is the number of rows to be returned
     *
     * By default, we assume case 1 and simply return the value of maxResults.  Subclasses
     * may provide an override
     *
     * @see org.eclipse.persistence.platform.database.MySQLPlatform
     */
    public int computeMaxRowsForSQL(int firstResultIndex, int maxResults){
        return maxResults;
    }

    /**
     *  Used for jdbc drivers which do not support autocommit to explicitly commit a transaction
     *  This method is a no-op for databases which implement autocommit as expected.
     */
    public void commitTransaction(DatabaseAccessor accessor) throws SQLException {
        if (!supportsAutoCommit()) {
            accessor.getConnection().commit();
        }
    }

    /**
     * Any platform that supports VPD should implement this method.
     */
    public DatabaseQuery getVPDClearIdentifierQuery(String vpdIdentifier) {
        return null;
    }

    /**
     * Any platform that supports VPD should implement this method. Used for DDL
     * generation.
     */
    public String getVPDCreationFunctionString(String tableName, String tenantFieldName) {
        return null;
    }

    /**
     * Any platform that supports VPD should implement this method. Used for DDL
     * generation.
     */
    public String getVPDCreationPolicyString(String tableName, AbstractSession session) {
        return null;
    }

    /**
     * Any platform that supports VPD should implement this method. Used for DDL
     * generation.
     */
    public String getVPDDeletionString(String tableName, AbstractSession session) {
        return null;
    }

    /**
     * Any platform that supports VPD should implement this method.
     */
    public DatabaseQuery getVPDSetIdentifierQuery(String vpdIdentifier) {
        return null;
    }

    /**
     * INTERNAL
     * We support more primitive than JDBC does so we must do conversion before printing or binding.
     */
    public Object convertToDatabaseType(Object value) {
        if (value == null) {
            return null;
        }
        if (value.getClass() == ClassConstants.UTILDATE) {
            return Helper.timestampFromDate((java.util.Date)value);
        } else if (value instanceof Character) {
            return ((Character)value).toString();
        } else if (value instanceof Calendar) {
            return Helper.timestampFromDate(((Calendar)value).getTime());
        } else if (value instanceof BigInteger) {
            return new BigDecimal((BigInteger)value);
        } else if (value instanceof char[]) {
            return new String((char[])value);
        } else if (value instanceof Character[]) {
            return convertObject(value, ClassConstants.STRING);
        } else if (value instanceof Byte[]) {
            return convertObject(value, ClassConstants.APBYTE);
        }
        return value;
    }

    /**
     * Copy the state into the new platform.
     */
    @Override
    public void copyInto(Platform platform) {
        super.copyInto(platform);
        if (!(platform instanceof DatabasePlatform)) {
            return;
        }
        DatabasePlatform databasePlatform = (DatabasePlatform)platform;
        databasePlatform.setShouldTrimStrings(shouldTrimStrings());
        databasePlatform.setUsesNativeSQL(usesNativeSQL());
        databasePlatform.setUsesByteArrayBinding(usesByteArrayBinding());
        databasePlatform.setUsesStringBinding(usesStringBinding());
        databasePlatform.setShouldBindAllParameters(shouldBindAllParameters());
        databasePlatform.setShouldForceBindAllParameters(shouldForceBindAllParameters());
        databasePlatform.setShouldCacheAllStatements(shouldCacheAllStatements());
        databasePlatform.setStatementCacheSize(getStatementCacheSize());
        databasePlatform.setTransactionIsolation(getTransactionIsolation());
        databasePlatform.setBatchWritingMechanism(getBatchWritingMechanism());
        databasePlatform.setMaxBatchWritingSize(getMaxBatchWritingSize());
        databasePlatform.setShouldForceFieldNamesToUpperCase(shouldForceFieldNamesToUpperCase());
        databasePlatform.setShouldOptimizeDataConversion(shouldOptimizeDataConversion());
        databasePlatform.setStringBindingSize(getStringBindingSize());
        databasePlatform.setUsesBatchWriting(usesBatchWriting());
        databasePlatform.setUsesJDBCBatchWriting(usesJDBCBatchWriting());
        databasePlatform.setUsesNativeBatchWriting(usesNativeBatchWriting());
        databasePlatform.setUsesStreamsForBinding(usesStreamsForBinding());
        databasePlatform.shouldCreateIndicesOnForeignKeys = this.shouldCreateIndicesOnForeignKeys;
        databasePlatform.printOuterJoinInWhereClause = this.printOuterJoinInWhereClause;
        databasePlatform.printInnerJoinInWhereClause = this.printInnerJoinInWhereClause;
        //use the variable directly to avoid custom platform strings - only want to copy user set values.
        //specifically used for login platform detection
        databasePlatform.setTableCreationSuffix(this.tableCreationSuffix);
        databasePlatform.setIsCastRequired(isCastRequired());
    }

    /**
     * Used for batch writing and sp defs.
     */
    public String getBatchBeginString() {
        return "";
    }

    /**
     * Return if the platform does not maintain the row count on batch executes
     * and requires an output parameter to maintain the row count.
     */
    public boolean isRowCountOutputParameterRequired() {
        return false;
    }

    /**
     * Used for batch writing for row count return.
     */
    public String getBatchRowCountDeclareString() {
        return "";
    }

    /**
     * Used for batch writing for row count return.
     */
    public String getBatchRowCountAssignString() {
        return "";
    }

    /**
     * Used for batch writing for row count return.
     */
    public String getBatchRowCountReturnString() {
        return "";
    }

    /**
     * Used for batch writing and sp defs.
     */
    public String getBatchDelimiterString() {
        return "; ";
    }

    /**
     * Used for batch writing and sp defs.
     */
    public String getBatchEndString() {
        return "";
    }

    /**
     * INTERNAL:
     * This method is used to unwrap the oracle connection wrapped by
     * the application server.  EclipseLink needs this unwrapped connection for certain
     * Oracle Specific support. (ie TIMESTAMPTZ)
     * This is added as a workaround for bug 4565190
     */
    public Connection getConnection(AbstractSession session, Connection connection) {
        return connection;
    }

    /**
     * Used for constraint deletion.
     */
    public String getConstraintDeletionString() {
        return " DROP CONSTRAINT ";
    }

    /**
     * Used for constraint deletion.
     */
    public String getUniqueConstraintDeletionString() {
        return getConstraintDeletionString();
    }

    /**

    /**
     * Used for view creation.
     */
    public String getCreateViewString() {
        return "CREATE VIEW ";
    }

    /**
     * Allows DROP TABLE to cascade dropping of any dependent constraints if the database supports this option.
     */
    public String getDropCascadeString() {
        return "";
    }

    /**
     * This method determines if any special processing needs to occur prior to writing a field.
     *
     * It does things such as determining if a field must be bound and flagging the parameter as one
     * that must be bound.
     */
    @Override
    public Object getCustomModifyValueForCall(Call call, Object value, DatabaseField field, boolean shouldBind) {

        if (typeConverters != null){
            StructConverter converter = typeConverters.get(field.getType());

            if (converter != null) {
                Object bindValue = value;
                if (bindValue == null) {
                    bindValue = new ObjectRelationalDatabaseField(field);
                    ((ObjectRelationalDatabaseField)bindValue).setSqlType(java.sql.Types.STRUCT);
                    ((ObjectRelationalDatabaseField)bindValue).setSqlTypeName(converter.getStructName());
                }
                return new BindCallCustomParameter(bindValue);
            }
        }
        return super.getCustomModifyValueForCall(call, value, field, shouldBind);
    }

    /**
     * Used for stored procedure defs.
     */
    public String getProcedureEndString() {
        return getBatchEndString();
    }

    /**
     * Used for stored procedure defs.
     */
    public String getProcedureBeginString() {
        return getBatchBeginString();
    }

    /**
     * Used for stored procedure defs.
     */
    public String getProcedureAsString() {
        return " AS";
    }

    /**
     * Some platforms have an option list
     * Only to be used for stored procedure creation.
     * 
     * @see org.eclipse.persistence.tools.schemaframework.StoredProcedureDefinition
     */
    public String getProcedureOptionList() {
        return "";
    }

    /**
     * Return the class type to database type mapping for the schema framework.
     */
    public Map<String, Class> getClassTypes() {
        if (classTypes == null) {
            classTypes = buildClassTypes();
        }
        return classTypes;
    }

    /**
     * Used for stored function calls.
     */
    public String getAssignmentString() {
        return "= ";
    }


    /**
     * ADVANCED:
     * Get the maximum length allowed by the database for a Varchar Parameter
     * This is used by subclasses when writing SQL for parameters
     * @see DB2Platform
     */
    public int getCastSizeForVarcharParameter(){
        return castSizeForVarcharParameter;
    }

    /**
     * This method is used to print the required output parameter token for the
     * specific platform.  Used when stored procedures are created.
     */
    public String getCreationInOutputProcedureToken() {
        return getInOutputProcedureToken();
    }

    /**
     * This method is used to print the required output parameter token for the
     * specific platform.  Used when stored procedures are created.
     */
    public String getCreationOutputProcedureToken() {
        return getOutputProcedureToken();
    }

    /**
     * ADVANCED:
     * Return the code for preparing cursored output
     * parameters in a stored procedure
     */
    public int getCursorCode() {
        return cursorCode;
    }

    /**
     * Returns the table name used by TableSequence by default.
     */
    public String getDefaultSequenceTableName() {
        return "SEQUENCE";
    }

    /**
     * Return the create schema SQL syntax. Subclasses should override as needed.
     */
    public String getCreateDatabaseSchemaString(String schema) {
        return "CREATE SCHEMA " + schema;
    }

    /**
     * Return the drop schema SQL syntax. Subclasses should override as needed.
     */
    public String getDropDatabaseSchemaString(String schema) {
        return "DROP SCHEMA " + schema;
    }

    /**
     * Return the field type object describing this databases platform specific representation
     * of the Java primitive class name.
     */
    public FieldTypeDefinition getFieldTypeDefinition(Class javaClass) {
        return getFieldTypes().get(javaClass);
    }

    /**
     * Return the class type to database type mappings for the schema framework.
     */
    public Map<Class, FieldTypeDefinition> getFieldTypes() {
        if (this.fieldTypes == null) {
            this.fieldTypes = buildFieldTypes();
        }
        return this.fieldTypes;
    }

    /**
     * Used for stored function calls.
     */
    public String getFunctionCallHeader() {
        return getProcedureCallHeader() + "? " + getAssignmentString();
    }

    /**
     * This method is used to print the output parameter token when stored
     * procedures are called
     */
    public String getInOutputProcedureToken() {
        return "IN OUT";
    }

    /**
     * Returns the JDBC outer join operator for SELECT statements.
     */
    public String getJDBCOuterJoinString() {
        return "{oj ";
    }

    /**
     * Return the JDBC type for the given database field to be passed to Statement.setNull
     */
    public int getJDBCTypeForSetNull(DatabaseField field) {
        return getJDBCType(field);
    }

    /**
     * Return the JDBC type for the given database field.
     */
    public int getJDBCType(DatabaseField field) {
        if (field != null) {
            // If the field has a specified JDBC type, use it,
            // otherwise compute the type from the Java class type.
            if (field.getSqlType() != DatabaseField.NULL_SQL_TYPE) {
                return field.getSqlType();
            } else {
                return getJDBCType(ConversionManager.getObjectClass(field.getType()));
            }
        } else {
            return getJDBCType((Class)null);
        }
    }

    /**
     * Return the JDBC type for the Java type.
     */
    public int getJDBCType(Class javaType) {
        if (javaType == null) {
            return Types.VARCHAR;// Best guess, sometimes we cannot determine type from mapping, this may fail on some drivers, other dont care what type it is.
        } else if (javaType == ClassConstants.STRING) {
            return Types.VARCHAR;
        } else if (javaType == ClassConstants.BIGDECIMAL) {
            return Types.DECIMAL;
        } else if (javaType == ClassConstants.BIGINTEGER) {
            return Types.BIGINT;
        } else if (javaType == ClassConstants.BOOLEAN) {
            return Types.BIT;
        } else if (javaType == ClassConstants.BYTE) {
            return Types.TINYINT;
        } else if (javaType == ClassConstants.CHAR) {
            return Types.CHAR;
        } else if (javaType == ClassConstants.DOUBLE) {
            return Types.DOUBLE;
        } else if (javaType == ClassConstants.FLOAT) {
            return Types.FLOAT;
        } else if (javaType == ClassConstants.INTEGER) {
            return Types.INTEGER;
        } else if (javaType == ClassConstants.LONG) {
            return Types.BIGINT;
        } else if (javaType == ClassConstants.NUMBER) {
            return Types.DECIMAL;
        } else if (javaType == ClassConstants.SHORT ) {
            return Types.SMALLINT;
        } else if (javaType == ClassConstants.CALENDAR ) {
            return Types.TIMESTAMP;
        } else if (javaType == ClassConstants.UTILDATE ) {
            return Types.TIMESTAMP;
        } else if (javaType == ClassConstants.TIME ||
            javaType == ClassConstants.TIME_LTIME) { //bug 546312
            return Types.TIME;
        } else if (javaType == ClassConstants.SQLDATE ||
            javaType == ClassConstants.TIME_LDATE) { //bug 546312
            return Types.DATE;
        } else if (javaType == ClassConstants.TIMESTAMP ||
            javaType == ClassConstants.UTILDATE || //bug 5237080, return TIMESTAMP for java.util.Date as well
            javaType == ClassConstants.TIME_LDATETIME) { //bug 546312
            return Types.TIMESTAMP;
        } else if(javaType == ClassConstants.TIME_OTIME) { //bug 546312
            return Types.TIME_WITH_TIMEZONE;
        } else if(javaType == ClassConstants.TIME_ODATETIME) { //bug 546312
            return Types.TIMESTAMP_WITH_TIMEZONE;
        }else if (javaType == ClassConstants.ABYTE) {
            return Types.LONGVARBINARY;
        } else if (javaType == ClassConstants.APBYTE) {
            return Types.LONGVARBINARY;
        } else if (javaType == ClassConstants.BLOB) {
            return Types.BLOB;
        } else if (javaType == ClassConstants.ACHAR) {
            return Types.LONGVARCHAR;
        } else if (javaType == ClassConstants.APCHAR) {
            return Types.LONGVARCHAR;
        } else if (javaType == ClassConstants.CLOB) {
            return Types.CLOB;
        } else {
            return Types.VARCHAR;// Best guess, sometimes we cannot determine type from mapping, this may fail on some drivers, other dont care what type it is.
        }
    }

    /**
     * INTERNAL:
     * Returns the type name corresponding to the jdbc type
     */
    public String getJdbcTypeName(int jdbcType) {
        return null;
    }

    /**
     * INTERNAL:
     * Returns the minimum time increment supported by the platform.
     */
    public long minimumTimeIncrement() {
        return 1;
    }

    /**
     * PUBLIC:
     * Allow for the max batch writing size to be set.
     * This allows for the batch size to be limited as most database have strict limits.
     * The size is in characters, the default is 32000 but the real value depends on the database configuration.
     */
    public int getMaxBatchWritingSize() {
        return maxBatchWritingSize;
    }

    /**
     * INTERNAL:
     * returns the maximum number of characters that can be used in a field
     * name on this platform.
     */
    public int getMaxFieldNameSize() {
        return 50;
    }

    /**
     * INTERNAL:
     * returns the maximum number of characters that can be used in a foreign key
     * name on this platform.
     */
    public int getMaxForeignKeyNameSize() {
        return getMaxFieldNameSize();
    }

    /**
     * INTERNAL:
     * returns the maximum number of characters that can be used in an index
     * name on this platform.
     */
    public int getMaxIndexNameSize() {
        return getMaxFieldNameSize();
    }

    /**
     * INTERNAL:
     * returns the maximum number of characters that can be used in a unique key
     * name on this platform.
     */
    public int getMaxUniqueKeyNameSize() {
        return getMaxFieldNameSize();
    }

    /**
     * INTERNAL:
     * Get the object from the JDBC Result set.  Added to allow other platforms to
     * override.
     * @see "org.eclipse.persistence.platform.database.oracle.Oracle9Plaform"
     */
    public Object getObjectFromResultSet(ResultSet resultSet, int columnNumber, int type, AbstractSession session) throws java.sql.SQLException {
        Object objectFromResultSet = resultSet.getObject(columnNumber);
        if (objectFromResultSet != null){
            if(structConverters != null && type == Types.STRUCT){
                String structType = ((Struct)objectFromResultSet).getSQLTypeName();
                if (getStructConverters().containsKey(structType)) {
                    return getStructConverters().get(structType).convertToObject((Struct)objectFromResultSet);
                }
            } else if(type == Types.SQLXML) {
                return JavaPlatform.getStringAndFreeSQLXML(objectFromResultSet);
            }
        }
        return objectFromResultSet;
    }

    /**
     * Used for stored procedure creation: Prefix for INPUT parameters.
     * Not required on most platforms.
     */
    public String getInputProcedureToken() {
        return "";
    }

    /**
     * Used to allow platforms to define their own index prefixes
     */
    public String getIndexNamePrefix(boolean isUniqueSetOnField){
        return "IX_";
    }

    /**
     * This method is used to print the output parameter token when stored
     * procedures are called
     */
    public String getOutputProcedureToken() {
        return "OUT";
    }

    /**
     * Used for determining if an SQL exception was communication based. This SQL should be
     * as efficient as possible and ensure a round trip to the database.
     */
    public String getPingSQL(){
        return pingSQL;
    }

    /**
     * Used for sp defs.
     */
    public String getProcedureArgumentString() {
        return "";
    }

    /**
     * Obtain the platform specific argument string
     */
    public String getProcedureArgument(String name, Object parameter, Integer parameterType, StoredProcedureCall call, AbstractSession session) {
        if (name != null && shouldPrintStoredProcedureArgumentNameInCall()) {
            return getProcedureArgumentString() + name + " = " + "?";
        }
        return "?";
    }

    /**
     * Used for sp calls.
     */
    public String getProcedureCallHeader() {
        return "EXECUTE PROCEDURE ";
    }

    /**
     * Used for sp calls.
     */
    public String getProcedureCallTail() {
        return "";
    }

    public String getQualifiedSequenceTableName() {
        if (getDefaultSequence() instanceof TableSequence) {
            return getQualifiedName(((TableSequence)getDefaultSequence()).getTableName());
        } else {
            throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "getTableName");
        }
    }

    public String getQualifiedName(String name) {
        if (getTableQualifier().equals("")) {
            return name;
        } else {
            return getTableQualifier() + "." + name;
        }
    }

    /**
     * This syntax does no wait on the lock.
     * (i.e. In Oracle adding NOWAIT to the end will accomplish this)
     */
    public String getNoWaitString() {
        return " NOWAIT";
    }

    /**
     * This syntax does no wait on the lock.
     * (i.e. In Oracle adding FOR UPDATE NOWAIT to the end will accomplish this)
     */
    public String getSelectForUpdateNoWaitString() {
        return getSelectForUpdateString() + getNoWaitString();
    }

    /**
     * For fine-grained pessimistic locking the column names can be
     * specified individually.
     */
    public String getSelectForUpdateOfString() {
        return " FOR UPDATE OF ";
    }

    /**
     * Most database support a syntax. although don't actually lock the row.
     * Some require the OF some don't like it.
     */
    public String getSelectForUpdateString() {
        return " FOR UPDATE";
    }

    /**
     * Platforms that support the WAIT option should override this method.
     * By default the wait timeout is ignored.
     * 
     *  @see DatabasePlatform#supportsWaitForUpdate()
     */
    public String getSelectForUpdateWaitString(Integer waitTimeout) {
        return getSelectForUpdateString();
    }

    public String getSequenceCounterFieldName() {
        if (getDefaultSequence() instanceof TableSequence) {
            return ((TableSequence)getDefaultSequence()).getCounterFieldName();
        } else {
            throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "getCounterFieldName");
        }
    }

    public String getSequenceNameFieldName() {
        if (getDefaultSequence() instanceof TableSequence) {
            return ((TableSequence)getDefaultSequence()).getNameFieldName();
        } else {
            throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "getNameFieldName");
        }
    }

    @Override
    public int getSequencePreallocationSize() {
        return getDefaultSequence().getPreallocationSize();
    }

    public String getSequenceTableName() {
        if (getDefaultSequence() instanceof TableSequence) {
            String tableName = ((TableSequence)getDefaultSequence()).getTableName();
            if(tableName.length() == 0) {
                tableName = this.getDefaultSequenceTableName();
            }
            return tableName;
        } else {
            throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "getTableName");
        }
    }

    /**
     * The statement cache size for prepare parameterized statements.
     */
    public int getStatementCacheSize() {
        return statementCacheSize;
    }

    public String getStoredProcedureParameterPrefix() {
        return "";
    }

    /**
     * Returns the delimiter between stored procedures in multiple stored
     * procedure calls.
     */
    public String getStoredProcedureTerminationToken() {
        return storedProcedureTerminationToken;
    }

    public void setStoredProcedureTerminationToken(String storedProcedureTerminationToken) {
        this.storedProcedureTerminationToken = storedProcedureTerminationToken;
    }

    public int getStringBindingSize() {
        return stringBindingSize;
    }

    /**
     * Returns the transaction isolation setting for a connection.
     * Return -1 if it has not been set.
     */
    public int getTransactionIsolation() {
        return transactionIsolation;
    }

    /**
     * Some database require outer joins to be given in the where clause, others require it in the from clause.
     * Informix requires it in the from clause with no ON expression.
     */
    public boolean isInformixOuterJoin() {
        return false;
    }

    /**
     * Returns true if this platform complies with the expected behavior from
     * a jdbc execute call. Most platforms do, some have issues:
     *
     * @see PostgreSQLPlatform
     */
    public boolean isJDBCExecuteCompliant() {
        return true;
    }

    /**
     * Return true is the given exception occurred as a result of a lock
     * time out exception (WAIT clause). If sub-platform supports this clause,
     * this method should be necessary checks should be made.
     *
     * By default though, this method return false.
     *
     * @see OraclePlatform
     */
    public boolean isLockTimeoutException(DatabaseException e) {
        return false;
    }

    /**
     * INTERNAL:
     * Indicates whether SELECT DISTINCT ... FOR UPDATE is allowed by the platform (Oracle doesn't allow this).
     */
    public boolean isForUpdateCompatibleWithDistinct() {
        return true;
    }

    /**
     * INTERNAL:
     * Indicates whether SELECT DISTINCT lob FROM ... (where lob is BLOB or CLOB) is allowed by the platform (Oracle doesn't allow this).
     */
    public boolean isLobCompatibleWithDistinct() {
        return true;
    }

    /**
     *    Builds a table of maximum numeric values keyed on java class. This is used for type testing but
     * might also be useful to end users attempting to sanitize values.
     * <p><b>NOTE</b>: BigInteger &amp; BigDecimal maximums are dependent upon their precision &amp; Scale
     */
    public Hashtable maximumNumericValues() {
        Hashtable values = new Hashtable();

        values.put(Integer.class, Integer.MAX_VALUE);
        values.put(Long.class, Long.MAX_VALUE);
        values.put(Double.class, Double.MAX_VALUE);
        values.put(Short.class, Short.MAX_VALUE);
        values.put(Byte.class, Byte.MAX_VALUE);
        values.put(Float.class, Float.MAX_VALUE);
        values.put(java.math.BigInteger.class, new java.math.BigInteger("999999999999999999999999999999999999999"));
        values.put(java.math.BigDecimal.class, new java.math.BigDecimal("99999999999999999999.9999999999999999999"));
        return values;
    }

    /**
     *    Builds a table of minimum numeric values keyed on java class. This is used for type testing but
     * might also be useful to end users attempting to sanitize values.
     * <p><b>NOTE</b>: BigInteger &amp; BigDecimal minimums are dependent upon their precision &amp; Scale
     */
    public Hashtable minimumNumericValues() {
        Hashtable values = new Hashtable();

        values.put(Integer.class, Integer.MIN_VALUE);
        values.put(Long.class, Long.MIN_VALUE);
        values.put(Double.class, Double.MIN_VALUE);
        values.put(Short.class, Short.MIN_VALUE);
        values.put(Byte.class, Byte.MIN_VALUE);
        values.put(Float.class, Float.MIN_VALUE);
        values.put(java.math.BigInteger.class, new java.math.BigInteger("-99999999999999999999999999999999999999"));
        values.put(java.math.BigDecimal.class, new java.math.BigDecimal("-9999999999999999999.9999999999999999999"));
        return values;
    }

    /**
     * Internal: Allows setting the batch size on the statement
     *  Is used with parameterized SQL, and should only be passed in prepared statements
     *
     * @return statement to be used for batch writing
     */
    public Statement prepareBatchStatement(Statement statement, int maxBatchWritingSize) throws java.sql.SQLException {
        return statement;
    }

    /**
     * Append the receiver's field 'identity' constraint clause to a writer.
     */
    public void printFieldIdentityClause(Writer writer) throws ValidationException {
        //The default is to do nothing.
    }

    /**
     * Append the receiver's field 'NOT NULL' constraint clause to a writer.
     */
    public void printFieldNotNullClause(Writer writer) throws ValidationException {
        try {
            writer.write(" NOT NULL");
        } catch (IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
    }

    /**
     * Append the receiver's field 'NULL' constraint clause to a writer.
     */
    public void printFieldNullClause(Writer writer) throws ValidationException {
        // The default is to do nothing
    }

    /**
     * Print the int array on the writer. Added to handle int[] passed as parameters to named queries
     * Returns the number of  objects using binding.
     */
    public int printValuelist(int[] theObjects, DatabaseCall call, Writer writer) throws IOException {
        int nBoundParameters = 0;
        writer.write("(");
        for (int i = 0; i < theObjects.length; i++) {
            nBoundParameters = nBoundParameters + appendParameterInternal(call, writer, theObjects[i]);
            if (i < (theObjects.length - 1)) {
                writer.write(", ");
            }
        }
        writer.write(")");
        return nBoundParameters;
    }

    public int printValuelist(Collection theObjects, DatabaseCall call, Writer writer) throws IOException {
        int nBoundParameters = 0;
        writer.write("(");
        Iterator iterator = theObjects.iterator();
        while (iterator.hasNext()) {
            nBoundParameters = nBoundParameters + appendParameterInternal(call, writer, iterator.next());
            if (iterator.hasNext()) {
                writer.write(", ");
            }
        }
        writer.write(")");
        return nBoundParameters;
    }

    /**
     * This method is used to register output parameter on CallableStatements for Stored Procedures
     * as each database seems to have a different method.
     * 
     * @see java.sql.CallableStatement#registerOutParameter(int parameterIndex, int sqlType)
     */
    public void registerOutputParameter(CallableStatement statement, int parameterIndex, int sqlType) throws SQLException {
        statement.registerOutParameter(parameterIndex, sqlType);
    }

    /**
     * This method is used to register output parameter on CallableStatements for Stored Procedures
     * as each database seems to have a different method.
     * 
     * @see java.sql.CallableStatement#registerOutParameter(int parameterIndex, int sqlType, String typeName)
     */
    public void registerOutputParameter(CallableStatement statement, int parameterIndex, int sqlType, String typeName) throws SQLException {
        statement.registerOutParameter(parameterIndex, sqlType, typeName);
    }

    /**
     * This method is used to register output parameter on CallableStatements for Stored Procedures
     * as each database seems to have a different method.
     * 
     * @see java.sql.CallableStatement#registerOutParameter(String parameterName, int sqlType)
     */
    public void registerOutputParameter(CallableStatement statement, String parameterName, int sqlType) throws SQLException {
        statement.registerOutParameter(parameterName, sqlType);
    }

    /**
     * This method is used to register output parameter on CallableStatements for Stored Procedures
     * as each database seems to have a different method.
     * 
     * @see java.sql.CallableStatement#registerOutParameter(String parameterName, int sqlType, String typeName)
     */
    public void registerOutputParameter(CallableStatement statement, String parameterName, int sqlType, String typeName) throws SQLException {
        statement.registerOutParameter(parameterName, sqlType, typeName);
    }

    /**
     * This is used as some databases create the primary key constraint differently, i.e. Access.
     */
    public boolean requiresNamedPrimaryKeyConstraints() {
        return false;
    }

    /**
     * Used for stored procedure creation: Some platforms need brackets around arguments declaration even if no arguments exist. Those platform will override this and return true. All other platforms will omit the brackets in this case.
     */
    public boolean requiresProcedureBrackets() {
        return false;
    }

    /**
     * USed for sp calls.
     */
    public boolean requiresProcedureCallBrackets() {
        return true;
    }

    /**
     * Used for sp calls.  Sybase must print output after output params.
     */
    public boolean requiresProcedureCallOuputToken() {
        return false;
    }

    /**
     * INTERNAL:
     * Indicates whether the version of CallableStatement.registerOutputParameter method
     * that takes type name should be used.
     */
    public boolean requiresTypeNameToRegisterOutputParameter() {
        return false;
    }

    /**
     * Used for table creation. If a database platform does not support ALTER
     * TABLE syntax to add/drop unique constraints (like Symfoware), overriding
     * this method will allow the constraint to be specified in the CREATE TABLE
     * statement.
     * <p>
     * This only affects unique constraints specified using the UniqueConstraint
     * annotation or equivalent method. Columns for which the 'unique' attribute
     * is set to true will be declared 'UNIQUE' in the CREATE TABLE statement
     * regardless of the return value of this method.
     *
     * @return whether unique constraints should be declared as part of the
     *         CREATE TABLE statement instead of in separate ALTER TABLE
     *         ADD/DROP statements.
     */
    public boolean requiresUniqueConstraintCreationOnTableCreate() {
        return false;
    }

    /**
     * INTERNAL:
     * Used by Exists queries because they just need to select a single row.
     * In most databases, we will select one of the primary key fields.
     *
     * On databases where, for some reason we cannot select one of the key fields
     * this method can be overridden
     * @see SymfowarePlatform
     */
    public void retrieveFirstPrimaryKeyOrOne(ReportQuery subselect){
        subselect.setShouldRetrieveFirstPrimaryKey(true);
    }
    /**
     *  Used for jdbc drivers which do not support autocommit to explicitly rollback a transaction
     *  This method is a no-op for databases which implement autocommit as expected.
     */
    public void rollbackTransaction(DatabaseAccessor accessor) throws SQLException {
        if (!supportsAutoCommit()) {
            accessor.getConnection().rollback();
        }
    }

    /**
     * ADVANCED:
     * Set the maximum length allowed by the database for a Varchar Parameter
     * This is used by subclasses when writing SQL for parameters
     * @see DB2Platform
     */
    public void setCastSizeForVarcharParameter(int maxLength){
        castSizeForVarcharParameter = maxLength;
    }

    protected void setClassTypes(Hashtable classTypes) {
        this.classTypes = classTypes;
    }

    /**
     * ADVANCED:
     * Set the code for preparing cursored output
     * parameters in a stored procedure
     */
    public void setCursorCode(int cursorCode) {
        this.cursorCode = cursorCode;
    }

    /**
     * During auto-detect, the driver name is set on the platform.
     */
    public void setDriverName(String driverName) {
        this.driverName = driverName;
    }

    protected void setFieldTypes(Hashtable theFieldTypes) {
        fieldTypes = theFieldTypes;
    }

    /**
     * PUBLIC:
     * Allow for the max batch writing size to be set.
     * This allows for the batch size to be limited as most database have strict limits.
     * The size is in characters, the default is 32000 but the real value depends on the database configuration.
     */
    public void setMaxBatchWritingSize(int maxBatchWritingSize) {
        this.maxBatchWritingSize = maxBatchWritingSize;
    }

    public void setSequenceCounterFieldName(String name) {
        if (getDefaultSequence() instanceof TableSequence) {
            ((TableSequence)getDefaultSequence()).setCounterFieldName(name);
        } else {
            if (!name.equals((new TableSequence()).getCounterFieldName())) {
                ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "setCounterFieldName");
            }
        }
    }

    public void setSequenceNameFieldName(String name) {
        if (getDefaultSequence() instanceof TableSequence) {
            ((TableSequence)getDefaultSequence()).setNameFieldName(name);
        } else {
            if (!name.equals((new TableSequence()).getNameFieldName())) {
                throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "setNameFieldName");
            }
        }
    }

    public void setSequenceTableName(String name) {
        if (getDefaultSequence() instanceof TableSequence) {
            ((TableSequence)getDefaultSequence()).setTableName(name);
        } else {
            if (!name.equals((new TableSequence()).getTableName())) {
                throw ValidationException.wrongSequenceType(Helper.getShortClassName(getDefaultSequence()), "setTableName");
            }
        }
    }

    /**
     * Bind all arguments to any SQL statement.
     */
    public void setShouldBindAllParameters(boolean shouldBindAllParameters) {
        this.shouldBindAllParameters = shouldBindAllParameters;
    }

    /**
     * Cache all prepared statements, this requires full parameter binding as well.
     */
    public void setShouldCacheAllStatements(boolean shouldCacheAllStatements) {
        this.shouldCacheAllStatements = shouldCacheAllStatements;
    }

    /**
     * Used to enable parameter binding and override the platform default
     */
    public void setShouldForceBindAllParameters(boolean shouldForceBindAllParameters) {
        this.shouldForceBindAllParameters = shouldForceBindAllParameters;
    }

    /**
     * Can be used if the app expects upper case but the database is not return consistent case, i.e. different databases.
     */
    public void setShouldForceFieldNamesToUpperCase(boolean shouldForceFieldNamesToUpperCase) {
        this.shouldForceFieldNamesToUpperCase = shouldForceFieldNamesToUpperCase;
    }

    /**
     * Allow for case in field names to be ignored as some databases are not case sensitive and when using custom this can be an issue.
     */
    public static void setShouldIgnoreCaseOnFieldComparisons(boolean newShouldIgnoreCaseOnFieldComparisons) {
        shouldIgnoreCaseOnFieldComparisons = newShouldIgnoreCaseOnFieldComparisons;
    }

    /**
     * PUBLIC:
     * Set if our driver level data conversion optimization is enabled.
     * This can be disabled as some drivers perform data conversion themselves incorrectly.
     */
    public void setShouldOptimizeDataConversion(boolean value) {
        this.shouldOptimizeDataConversion = value;
    }

    public void setShouldTrimStrings(boolean aBoolean) {
        shouldTrimStrings = aBoolean;
    }

    /**
     * The statement cache size for prepare parameterized statements.
     */
    public void setStatementCacheSize(int statementCacheSize) {
        this.statementCacheSize = statementCacheSize;
    }

    public void setStringBindingSize(int aSize) {
        stringBindingSize = aSize;
    }

    /**
     * supportsAutoCommit can be set to false for JDBC drivers which do not support autocommit.
     */
    public void setSupportsAutoCommit(boolean supportsAutoCommit) {
        this.supportsAutoCommit = supportsAutoCommit;
    }

    /**
     * PUBLIC:
     * Get the String used on all table creation statements generated from the DefaultTableGenerator
     * with a session using this project (DDL generation).  This value will be appended to CreationSuffix strings
     * stored on the DatabaseTable or TableDefinition.
     * ie setTableCreationSuffix("engine=InnoDB");
     */
    public void setTableCreationSuffix(String tableCreationSuffix){
        this.tableCreationSuffix = tableCreationSuffix;
    }

    /**
     * Set the transaction isolation setting for a connection.
     */
    public void setTransactionIsolation(int isolationLevel) {
        transactionIsolation = isolationLevel;
    }

    /**
     * Return true if JDBC syntax should be used for stored procedure calls.
     */
    public void setUseJDBCStoredProcedureSyntax(Boolean useJDBCStoredProcedureSyntax) {
        this.useJDBCStoredProcedureSyntax = useJDBCStoredProcedureSyntax;
    }

    public void setUsesBatchWriting(boolean usesBatchWriting) {
        this.usesBatchWriting = usesBatchWriting;
    }

    public void setUsesByteArrayBinding(boolean usesByteArrayBinding) {
        this.usesByteArrayBinding = usesByteArrayBinding;
    }

    /**
     * Some JDBC 2 drivers to not support batching, so this lets are own batching be used.
     */
    public void setUsesJDBCBatchWriting(boolean usesJDBCBatchWriting) {
        this.usesJDBCBatchWriting = usesJDBCBatchWriting;
    }

    /**
     * Advanced:
     * This is used to enable native batch writing on drivers that support it.  Enabling
     * Native batchwriting will result in the batch writing mechanisms to be used on objects
     * that have optimistic locking, and so execution of statements on these objects will be
     * delayed until the batch statement is executed.  Only use this method with platforms that
     * have overridden the prepareBatchStatement, addBatch and executeBatch as required
     *
     * Current support is limited to the Oracle9Platform class.
     *
     * @param usesNativeBatchWriting - flag to turn on/off native batch writing
     */
    public void setUsesNativeBatchWriting(boolean usesNativeBatchWriting){
        this.usesNativeBatchWriting = usesNativeBatchWriting;
    }

    public void setUsesNativeSQL(boolean usesNativeSQL) {
        this.usesNativeSQL = usesNativeSQL;
    }

    /**
     * Return the custom batch writing mechanism.
     */
    public BatchWritingMechanism getBatchWritingMechanism() {
        return batchWritingMechanism;
    }

    /**
     * Set the custom batch writing mechanism.
     */
    public void setBatchWritingMechanism(BatchWritingMechanism batchWritingMechanism) {
        this.batchWritingMechanism = batchWritingMechanism;
    }

    /**
     * PUBLIC:
     * Set if SQL-Level pagination should be used for FirstResult and MaxRows settings.
     * Default is true.
     *
     * Note: This setting is used to disable SQL-level pagination on platforms for which it is
     * implemented.  On platforms where we use JDBC for pagination, it will be ignored
     */
    public void setShouldUseRownumFiltering(boolean useRownumFiltering) {
        this.useRownumFiltering = useRownumFiltering;
    }

    public void setUsesStreamsForBinding(boolean usesStreamsForBinding) {
        this.usesStreamsForBinding = usesStreamsForBinding;
    }

    /**
     * PUBLIC:
     * Changes the way that OuterJoins are done on the database.  With a value of
     * true, outerjoins are performed in the where clause using the outer join token
     * for that database.
     *
     *  With the value of false, outerjoins are performed in the from clause.
     */
    public void setPrintOuterJoinInWhereClause(boolean printOuterJoinInWhereClause) {
        this.printOuterJoinInWhereClause = printOuterJoinInWhereClause;
    }

    /**
     * PUBLIC:
     * Changes the way that inner joins are printed in generated SQL for the database.
     * With a value of true, inner joins are printed in the WHERE clause,
     * if false, inner joins are printed in the FROM clause.
     */
    public void setPrintInnerJoinInWhereClause(boolean printInnerJoinInWhereClause) {
        this.printInnerJoinInWhereClause = printInnerJoinInWhereClause;
    }

    public void setUsesStringBinding(boolean aBool) {
        usesStringBinding = aBool;
    }

    /**
     * Bind all arguments to any SQL statement.
     */
    public boolean shouldBindAllParameters() {
        return shouldBindAllParameters;
    }

    /**
     * Cache all prepared statements, this requires full parameter binding as well.
     */
    public boolean shouldCacheAllStatements() {
        return shouldCacheAllStatements;
    }

    /**
     * Used for table creation. Most databases create an index automatically
     * when a primary key is created. Symfoware does not.
     *
     * @return whether an index should be created explicitly for primary keys
     */
     public boolean shouldCreateIndicesForPrimaryKeys() {
         return false;
    }

    /**
     * Used for table creation. Most databases create an index automatically for
     * columns with a unique constraint. Symfoware does not.
     *
     * @return whether an index should be created explicitly for unique
     *         constraints
     */
    public boolean shouldCreateIndicesOnUniqueKeys() {
        return false;
    }

    /**
     * Used for table creation. Most databases do not create an index automatically for
     * foreign key columns.  Normally it is recommended to index foreign key columns.
     * This allows for foreign key indexes to be configured, by default foreign keys are not indexed.
     *
     * @return whether an index should be created explicitly for foreign key constraints
     */
    public boolean shouldCreateIndicesOnForeignKeys() {
        return shouldCreateIndicesOnForeignKeys;
    }

    /**
     * Used for table creation. Most databases do not create an index automatically for
     * foreign key columns.  Normally it is recommended to index foreign key columns.
     * This allows for foreign key indexes to be configured, by default foreign keys are not indexed.
     */
    public void setShouldCreateIndicesOnForeignKeys(boolean shouldCreateIndicesOnForeignKeys) {
        this.shouldCreateIndicesOnForeignKeys = shouldCreateIndicesOnForeignKeys;
    }

    /**
     * Used to enable parameter binding and override platform default
     */
    public boolean shouldForceBindAllParameters() {
        return this.shouldForceBindAllParameters;
    }

    /**
     * Can be used if the app expects upper case but the database is not return consistent case, i.e. different databases.
     */
    public boolean shouldForceFieldNamesToUpperCase() {
        return shouldForceFieldNamesToUpperCase;
    }

    /**
     * Allow for case in field names to be ignored as some databases are not case sensitive and when using custom this can be an issue.
     */
    public static boolean shouldIgnoreCaseOnFieldComparisons() {
        return shouldIgnoreCaseOnFieldComparisons;
    }

    /**
     * Allow for the platform to ignore exceptions.
     * This is required for DB2 which throws no-data modified as an exception.
     */
    public boolean shouldIgnoreException(SQLException exception) {
        // By default nothing is ignored.
        return false;
    }

    /**
     * Return if our driver level data conversion optimization is enabled.
     * This can be disabled as some drivers perform data conversion themselves incorrectly.
     */
    public boolean shouldOptimizeDataConversion() {
        return shouldOptimizeDataConversion;
    }

    /**
     * Used for stored procedure creation: Some platforms declare variables AFTER the procedure body's BEGIN string. These need to override and return true. All others will print the variable declaration BEFORE the body's BEGIN string.
     */
    public boolean shouldPrintStoredProcedureVariablesAfterBeginString() {
        return false;
    }

    /**
    * Some Platforms want the constraint name after the constraint definition.
    */
    public boolean shouldPrintConstraintNameAfter() {
        return false;
    }

    /**
     * This is required in the construction of the stored procedures with
     * output parameters
     */
    public boolean shouldPrintInOutputTokenBeforeType() {
        return true;
    }

    /**
     * Some database require outer joins to be given in the where clause, others require it in the from clause.
     */
    public boolean shouldPrintOuterJoinInWhereClause() {
        if(this.printOuterJoinInWhereClause == null) {
            this.printOuterJoinInWhereClause = Boolean.FALSE;
        }
        return this.printOuterJoinInWhereClause;
    }

    /**
     * This allows which clause inner joins are printed into in SQL generation.
     * By default most platforms put inner joins in the WHERE clause.
     * If set to false, inner joins will be printed in the FROM clause.
     */
    public boolean shouldPrintInnerJoinInWhereClause() {
        if (this.printInnerJoinInWhereClause == null) {
            return true;
        }
        return this.printInnerJoinInWhereClause;
    }

    /**
     * Used for stored procedure creation: Some platforms want to print prefix for INPUT arguments BEFORE NAME. If wanted, override and return true.
     */
    public boolean shouldPrintInputTokenAtStart() {
        return false;
    }

    /**
     * This is required in the construction of the stored procedures with
     * output parameters
     */
    public boolean shouldPrintOutputTokenBeforeType() {
        return true;
    }

    /**
     * This is required in the construction of the stored procedures with
     * output parameters
     */
    public boolean shouldPrintOutputTokenAtStart() {
        return false;
    }


    /**
     * INTERNAL:
     * Should the variable name of a stored procedure call be printed as part of the procedure call
     * e.g. EXECUTE PROCEDURE MyStoredProc(myvariable = ?)
     */
    public boolean shouldPrintStoredProcedureArgumentNameInCall(){
        return true;
    }

    public boolean shouldPrintForUpdateClause() {
        return true;
    }

    public boolean shouldTrimStrings() {
        return shouldTrimStrings;
    }

    @Override
    public boolean shouldUseCustomModifyForCall(DatabaseField field) {
        return (field.getSqlType() == Types.STRUCT &&
            (typeConverters != null && typeConverters.containsKey(field.getType()))) ||
            super.shouldUseCustomModifyForCall(field);
    }

    /**
     * JDBC defines and outer join syntax, many drivers do not support this. So we normally avoid it.
     */
    public boolean shouldUseJDBCOuterJoinSyntax() {
        return true;
    }

    /**
     * PUBLIC:
     * Return if Oracle ROWNUM pagination should be used for FirstResult and MaxRows settings.
     * Default is true.
     *
     * Note: This setting is used to disable SQL-level pagination on platforms for which it is
     * implemented.  On platforms where we use JDBC for pagination, it will be ignored
     */
    public boolean shouldUseRownumFiltering() {
        return this.useRownumFiltering;
    }

    /**
     * Indicates whether the ANSI syntax for inner joins (e.g. SELECT FROM t1
     * JOIN t2 ON t1.pk = t2.fk) is supported by this platform.
     */
    public boolean supportsANSIInnerJoinSyntax() {
        return true;
    }

    /**
     * supportsAutoCommit must sometimes be set to false for JDBC drivers which do not
     * support autocommit.  Used to determine how to handle transactions properly.
     */
    public boolean supportsAutoCommit() {
        return supportsAutoCommit;
    }

    /**
     * Some db allow VARCHAR db field to be used in arithmetic operations automatically converting them to numeric:
     * UPDATE OL_PHONE SET PHONE_ORDER_VARCHAR = (PHONE_ORDER_VARCHAR + 1) WHERE ...
     * SELECT ... WHERE  ... t0.MANAGED_ORDER_VARCHAR BETWEEN 1 AND 4 ...
     */
    public boolean supportsAutoConversionToNumericForArithmeticOperations() {
        return false;
    }

    public boolean supportsForeignKeyConstraints() {
        return true;
    }

    public boolean supportsUniqueKeyConstraints() {
        return true;
    }

    /**
     * By default, platforms do not support VPD. Those that do need to override
     * this method.
     */
    public boolean supportsVPD() {
        return false;
    }

    /**
     *  INTERNAL:
     *  Indicates whether the platform supports timeouts on For Update
     *  
     *  @see DatabasePlatform#getSelectForUpdateWaitString(Integer waitTimeout)
     */
    public boolean supportsWaitForUpdate() {
        return false;
    }

    public boolean supportsPrimaryKeyConstraint() {
        return true;
    }

    public boolean supportsStoredFunctions() {
        return false;
    }

    public boolean supportsDeleteOnCascade() {
        return supportsForeignKeyConstraints();
    }

    /**
     * Internal: This gets called on each batch statement execution
     * Needs to be implemented so that it returns the number of rows successfully modified
     * by this statement for optimistic locking purposes.
     *
     * @param isStatementPrepared - flag is set to true if this statement is prepared
     * @return - number of rows modified/deleted by this statement
     */
    public int executeBatch(Statement statement, boolean isStatementPrepared) throws java.sql.SQLException {
       int[] rowCounts = statement.executeBatch();
       int rowCount = 0;
       // Otherwise check if the row counts were returned.
       for (int count : rowCounts) {
           if (count > 0) {
               // The row count will be matched with the statement count.
               rowCount ++;
           } else {
               // The row counts were not known, check for a total row count.
               // If the total count is not known, then the update should fail,
               // and the platform must override canBatchWriteWithOptimisticLocking() to return false.
               return statement.getUpdateCount();
           }
       }
       return rowCount;
    }

    /**
     * because each platform has different requirements for accessing stored procedures and
     * the way that we can combine resultsets and output params, the stored procedure call
     * is being executed on the platform.
     */
    public Object executeStoredProcedure(DatabaseCall dbCall, PreparedStatement statement, DatabaseAccessor accessor, AbstractSession session) throws SQLException {
        Object result = null;
        ResultSet resultSet = null;
        if (!dbCall.getReturnsResultSet()) {// no result set is expected
            if (dbCall.isCursorOutputProcedure()) {
                result = accessor.executeNoSelect(dbCall, statement, session);
                int index = dbCall.getCursorOutIndex();
                resultSet = (ResultSet)dbCall.getOutputParameterValue((CallableStatement)statement, index - 1, session);
            } else {
                accessor.executeDirectNoSelect(statement, dbCall, session);

                // Meaning we have at least one out parameter (or out cursors).
                if (dbCall.shouldBuildOutputRow() || dbCall.hasOutputCursors()) {
                    result = accessor.buildOutputRow((CallableStatement)statement, dbCall, session);

                    // ReadAllQuery may be returning just output params, or they
                    // may be executing a DataReadQuery, which also assumes a vector
                    if (dbCall.areManyRowsReturned()) {
                        Vector tempResult = new Vector();
                        tempResult.add(result);
                        result = tempResult;
                    }
                } else {
                    // No out params whatsover, return an empty list.
                    result = new Vector();
                }
            }
        } else {
            // so specifically in Sybase JConnect 5.5 we must create the result vector before accessing the
            // output params in the case where the user is returning both.  this is a driver limitation
            resultSet = accessor.executeSelect(dbCall, statement, session);
        }

        if (resultSet != null) {
            dbCall.matchFieldOrder(resultSet, accessor, session);

            if (dbCall.isCursorReturned()) {
                dbCall.setStatement(statement);
                dbCall.setResult(resultSet);
                return dbCall;
            }

            result = accessor.processResultSet(resultSet, dbCall, statement, session);
        }

        // If the output is not allowed with the result set, we must hold off till the result set has
        // been processed before accessing the out parameters.
        if (dbCall.shouldBuildOutputRow() && ! isOutputAllowWithResultSet()) {
            AbstractRecord outputRow = accessor.buildOutputRow((CallableStatement)statement, dbCall, session);
            dbCall.getQuery().setProperty("output", outputRow);
            session.getEventManager().outputParametersDetected(outputRow, dbCall);
        }

        return result;
    }

    /**
     * Used for determining if an SQL exception was communication based. This SQL should be
     * as efficient as possible and ensure a round trip to the database.
     */
    public void setPingSQL(String pingSQL) {
        this.pingSQL = pingSQL;
    }

    /**
     * INTERNAL
     * Set the parameter in the JDBC statement at the given index.
     * This support a wide range of different parameter types,
     * and is heavily optimized for common types.
     */
    public void setParameterValueInDatabaseCall(Object parameter,
                PreparedStatement statement, int index, AbstractSession session)
                throws SQLException {
        // Process common types first.
        if (parameter instanceof String) {
            // Check for stream binding of large strings.
            if (usesStringBinding() && (((String)parameter).length() > getStringBindingSize())) {
                CharArrayReader reader = new CharArrayReader(((String)parameter).toCharArray());
                statement.setCharacterStream(index, reader, ((String)parameter).length());
            } else {
                if (shouldUseGetSetNString()) {
                    statement.setNString(index, (String) parameter);
                } else {
                    statement.setString(index, (String) parameter);
                }
            }
        } else if (parameter instanceof Number) {
            Number number = (Number) parameter;
            if (number instanceof Integer) {
                statement.setInt(index, number.intValue());
            } else if (number instanceof Long) {
                statement.setLong(index, number.longValue());
            }  else if (number instanceof BigDecimal) {
                statement.setBigDecimal(index, (BigDecimal) number);
            } else if (number instanceof Double) {
                statement.setDouble(index, number.doubleValue());
            } else if (number instanceof Float) {
                statement.setFloat(index, number.floatValue());
            } else if (number instanceof Short) {
                statement.setShort(index, number.shortValue());
            } else if (number instanceof Byte) {
                statement.setByte(index, number.byteValue());
            } else if (number instanceof BigInteger) {
                // Convert to BigDecimal.
                statement.setBigDecimal(index, new BigDecimal((BigInteger) number));
            } else {
                statement.setObject(index, parameter);
            }
        }  else if (parameter instanceof java.sql.Date){
            statement.setDate(index,(java.sql.Date)parameter);
        }  else if (parameter instanceof java.time.LocalDate){
            statement.setDate(index, java.sql.Date.valueOf((java.time.LocalDate) parameter));
        } else if (parameter instanceof java.sql.Timestamp){
            statement.setTimestamp(index,(java.sql.Timestamp)parameter);
        } else if (parameter instanceof java.time.LocalDateTime){
            statement.setTimestamp(index, java.sql.Timestamp.valueOf((java.time.LocalDateTime) parameter));
        } else if (parameter instanceof java.time.OffsetDateTime) {
            statement.setTimestamp(index, java.sql.Timestamp.from(((java.time.OffsetDateTime) parameter).toInstant()));
        } else if (parameter instanceof java.sql.Time){
            statement.setTime(index,(java.sql.Time)parameter);
        } else if (parameter instanceof java.time.LocalTime){
            java.time.LocalTime lt = (java.time.LocalTime) parameter;
            java.sql.Timestamp ts = java.sql.Timestamp.valueOf(java.time.LocalDateTime.of(java.time.LocalDate.ofEpochDay(0), lt));
            statement.setTimestamp(index, ts);
        } else if (parameter instanceof java.time.OffsetTime) {
            java.time.OffsetTime ot = (java.time.OffsetTime) parameter;
            java.sql.Timestamp ts = java.sql.Timestamp.valueOf(java.time.LocalDateTime.of(java.time.LocalDate.ofEpochDay(0), ot.toLocalTime()));
            statement.setTimestamp(index, ts);
        } else if (parameter instanceof Boolean) {
            statement.setBoolean(index, (Boolean) parameter);
        } else if (parameter == null) {
            // Normally null is passed as a DatabaseField so the type is included, but in some case may be passed directly.
            statement.setNull(index, getJDBCType((Class)null));
        } else if (parameter instanceof DatabaseField) {
            setNullFromDatabaseField((DatabaseField)parameter, statement, index);
        } else if (parameter instanceof byte[]) {
            if (usesStreamsForBinding()) {
                ByteArrayInputStream inputStream = new ByteArrayInputStream((byte[])parameter);
                statement.setBinaryStream(index, inputStream, ((byte[])parameter).length);
            } else {
                statement.setBytes(index, (byte[])parameter);
            }
        }
        // Next process types that need conversion.
        else if (parameter instanceof Calendar) {
            statement.setTimestamp(index, Helper.timestampFromDate(((Calendar)parameter).getTime()));
        } else if (parameter.getClass() == ClassConstants.UTILDATE) {
            statement.setTimestamp(index, Helper.timestampFromDate((java.util.Date) parameter));
        } else if (parameter instanceof Character) {
            statement.setString(index, ((Character)parameter).toString());
        } else if (parameter instanceof char[]) {
            statement.setString(index, new String((char[])parameter));
        } else if (parameter instanceof Character[]) {
            statement.setString(index, convertObject(parameter, ClassConstants.STRING));
        } else if (parameter instanceof Byte[]) {
            statement.setBytes(index, (byte[])convertObject(parameter, ClassConstants.APBYTE));
        } else if (parameter instanceof SQLXML) {
            statement.setSQLXML(index, (SQLXML) parameter);
        } else if (parameter instanceof BindCallCustomParameter) {
            ((BindCallCustomParameter)(parameter)).set(this, statement, index, session);
        } else if (typeConverters != null && typeConverters.containsKey(parameter.getClass())){
            StructConverter converter = typeConverters.get(parameter.getClass());
            parameter = converter.convertToStruct(parameter, getConnection(session, statement.getConnection()));
            statement.setObject(index, parameter);
        } else {
            statement.setObject(index, parameter);
        }
    }

    /**
     * INTERNAL
     * Set the parameter in the JDBC statement with the given name.
     * This support a wide range of different parameter types,
     * and is heavily optimized for common types.
     */
    public void setParameterValueInDatabaseCall(Object parameter,
                CallableStatement statement, String name, AbstractSession session)
                throws SQLException {
        // Process common types first.
        if (parameter instanceof String) {
            // Check for stream binding of large strings.
            if (usesStringBinding() && (((String)parameter).length() > getStringBindingSize())) {
                CharArrayReader reader = new CharArrayReader(((String)parameter).toCharArray());
                statement.setCharacterStream(name, reader, ((String)parameter).length());
            } else {
                if (shouldUseGetSetNString()) {
                    statement.setNString(name, (String) parameter);
                } else {
                    statement.setString(name, (String) parameter);
                }
            }
        } else if (parameter instanceof Number) {
            Number number = (Number) parameter;
            if (number instanceof Integer) {
                statement.setInt(name, number.intValue());
            } else if (number instanceof Long) {
                statement.setLong(name, number.longValue());
            }  else if (number instanceof BigDecimal) {
                statement.setBigDecimal(name, (BigDecimal) number);
            } else if (number instanceof Double) {
                statement.setDouble(name, number.doubleValue());
            } else if (number instanceof Float) {
                statement.setFloat(name, number.floatValue());
            } else if (number instanceof Short) {
                statement.setShort(name, number.shortValue());
            } else if (number instanceof Byte) {
                statement.setByte(name, number.byteValue());
            } else if (number instanceof BigInteger) {
                // Convert to BigDecimal.
                statement.setBigDecimal(name, new BigDecimal((BigInteger) number));
            } else {
                statement.setObject(name, parameter);
            }
        }  else if (parameter instanceof java.sql.Date){
            statement.setDate(name,(java.sql.Date)parameter);
        }  else if (parameter instanceof java.time.LocalDate){
            statement.setDate(name, java.sql.Date.valueOf((java.time.LocalDate) parameter));
        } else if (parameter instanceof java.sql.Timestamp){
            statement.setTimestamp(name,(java.sql.Timestamp)parameter);
        } else if (parameter instanceof java.time.LocalDateTime){
            statement.setTimestamp(name, java.sql.Timestamp.valueOf((java.time.LocalDateTime) parameter));
        } else if (parameter instanceof java.time.OffsetDateTime) {
            statement.setTimestamp(name, java.sql.Timestamp.from(((java.time.OffsetDateTime) parameter).toInstant()));
        } else if (parameter instanceof java.sql.Time){
            statement.setTime(name,(java.sql.Time)parameter);
        } else if (parameter instanceof java.time.LocalTime){
            java.time.LocalTime lt = (java.time.LocalTime) parameter;
            java.sql.Timestamp ts = java.sql.Timestamp.valueOf(java.time.LocalDateTime.of(java.time.LocalDate.ofEpochDay(0), lt));
            statement.setTimestamp(name, ts);
        } else if (parameter instanceof java.time.OffsetTime) {
            java.time.OffsetTime ot = (java.time.OffsetTime) parameter;
            java.sql.Timestamp ts = java.sql.Timestamp.valueOf(java.time.LocalDateTime.of(java.time.LocalDate.ofEpochDay(0), ot.toLocalTime()));
            statement.setTimestamp(name, ts);
        } else if (parameter instanceof Boolean) {
            statement.setBoolean(name, (Boolean) parameter);
        } else if (parameter == null) {
            // Normally null is passed as a DatabaseField so the type is included, but in some case may be passed directly.
            statement.setNull(name, getJDBCType((Class)null));
        } else if (parameter instanceof DatabaseField) {
            setNullFromDatabaseField((DatabaseField)parameter, statement, name);
        } else if (parameter instanceof byte[]) {
            if (usesStreamsForBinding()) {
                ByteArrayInputStream inputStream = new ByteArrayInputStream((byte[])parameter);
                statement.setBinaryStream(name, inputStream, ((byte[])parameter).length);
            } else {
                statement.setBytes(name, (byte[])parameter);
            }
        }
        // Next process types that need conversion.
        else if (parameter instanceof Calendar) {
            statement.setTimestamp(name, Helper.timestampFromDate(((Calendar)parameter).getTime()));
        } else if (parameter.getClass() == ClassConstants.UTILDATE) {
            statement.setTimestamp(name, Helper.timestampFromDate((java.util.Date) parameter));
        } else if (parameter instanceof Character) {
            statement.setString(name, ((Character)parameter).toString());
        } else if (parameter instanceof char[]) {
            statement.setString(name, new String((char[])parameter));
        } else if (parameter instanceof Character[]) {
            statement.setString(name, convertObject(parameter, ClassConstants.STRING));
        } else if (parameter instanceof Byte[]) {
            statement.setBytes(name, (byte[])convertObject(parameter, ClassConstants.APBYTE));
        } else if (parameter instanceof SQLXML) {
            statement.setSQLXML(name, (SQLXML) parameter);
        } else if (parameter instanceof BindCallCustomParameter) {
            ((BindCallCustomParameter)(parameter)).set(this, statement, name, session);
        } else if (typeConverters != null && typeConverters.containsKey(parameter.getClass())){
            StructConverter converter = typeConverters.get(parameter.getClass());
            parameter = converter.convertToStruct(parameter, getConnection(session, statement.getConnection()));
            statement.setObject(name, parameter);
        } else {
            statement.setObject(name, parameter);
        }
    }

    protected void setNullFromDatabaseField(DatabaseField databaseField, PreparedStatement statement, int index) throws SQLException {
        // Substituted null value for the corresponding DatabaseField.
        // Cannot bind null through set object, so we must compute the type, this is not good.
        // Fix for bug 2730536: for ARRAY/REF/STRUCT types must pass in the
        // user defined type to setNull as well.
        if (databaseField instanceof ObjectRelationalDatabaseField) {
            ObjectRelationalDatabaseField field = (ObjectRelationalDatabaseField)databaseField;
            statement.setNull(index, field.getSqlType(), field.getSqlTypeName());
        } else {
            int jdbcType = getJDBCTypeForSetNull(databaseField);
            statement.setNull(index, jdbcType);
        }
    }

    protected void setNullFromDatabaseField(DatabaseField databaseField, CallableStatement statement, String name) throws SQLException {
        // Substituted null value for the corresponding DatabaseField.
        // Cannot bind null through set object, so we must compute the type, this is not good.
        // Fix for bug 2730536: for ARRAY/REF/STRUCT types must pass in the
        // user defined type to setNull as well.
        if (databaseField instanceof ObjectRelationalDatabaseField) {
            ObjectRelationalDatabaseField field = (ObjectRelationalDatabaseField)databaseField;
            statement.setNull(name, field.getSqlType(), field.getSqlTypeName());
        } else {
            int jdbcType = getJDBCTypeForSetNull(databaseField);
            statement.setNull(name, jdbcType);
        }
    }

    /**
     * INTERNAL
     * Get the parameter from the JDBC statement with the given index.
     * @param index - 1-based index in the argument list
     */
    public Object getParameterValueFromDatabaseCall(CallableStatement statement, int index, AbstractSession session) throws SQLException {
        return statement.getObject(index);
    }

    /**
     * INTERNAL
     * Get the parameter from the JDBC statement with the given name.
     */
    public Object getParameterValueFromDatabaseCall(CallableStatement statement, String name, AbstractSession session) throws SQLException {
        return statement.getObject(name);
    }

    public boolean usesBatchWriting() {
        return usesBatchWriting;
    }

    public boolean usesByteArrayBinding() {
        return usesByteArrayBinding;
    }

    public boolean usesSequenceTable() {
        return getDefaultSequence() instanceof TableSequence;
    }

    /**
     * Some JDBC 2 drivers to not support batching, so this lets are own batching be used.
     */
    public boolean usesJDBCBatchWriting() {
        return usesJDBCBatchWriting;
    }

    public boolean usesNativeBatchWriting(){
        return usesNativeBatchWriting;
    }

    public boolean usesNativeSQL() {
        return usesNativeSQL;
    }

    public boolean usesStreamsForBinding() {
        return usesStreamsForBinding;
    }

    public boolean usesStringBinding() {
        return usesStringBinding;
    }

    /**
     * INTERNAL:
     * Write LOB value - only on Oracle8 and up
     */
    public void writeLOB(DatabaseField field, Object value, ResultSet resultSet, AbstractSession session) throws SQLException {
        // used by Oracle8Platform
    }

    /**
     * INTERNAL:
     * Indicates whether the platform supports the count distinct function with multiple fields.
     */
    public boolean supportsCountDistinctWithMultipleFields() {
        return false;
    }

    /**
     * INTERNAL:
     * Return if this database support index creation.
     */
    public boolean supportsIndexes() {
        return true;
    }

    /**
     * INTERNAL:
     * Return if this database requires the table name when dropping an index.
     */
    public boolean requiresTableInIndexDropDDL() {
        return false;
    }

    /**
     * INTERNAL:
     * Create platform-default Sequence
     */
    @Override
    protected Sequence createPlatformDefaultSequence() {
        return new TableSequence();
    }

    /**
     * INTERNAL:
     * Indicates whether the platform supports temporary tables.
     * Temporary tables may be used by UpdateAllQueries:
     * though attempt is always made to perform UpdateAll without using temporary
     * storage there are some scenarios that can't be fulfilled without it.
     * Don't override this method.
     * If the platform support temporary tables then override
     * either supportsLocalTempTables() or supportsGlobalTempTables()
     * method.
     */
     public boolean supportsTempTables() {
         return supportsLocalTempTables() || supportsGlobalTempTables();
     }

    /**
     * INTERNAL:
     * Indicates whether the platform supports local temporary tables.
     * "Local" means that several threads may create
     * temporary tables with the same name.
     * Local temporary table is created in the beginning of UpdateAllQuery
     * execution and dropped in the end of it.
     * Override this method if the platform supports local temporary tables.
     */
     public boolean supportsLocalTempTables() {
         return false;
     }

    /**
     * INTERNAL:
     * Indicates whether the platform supports global temporary tables.
     * "Global" means that an attempt to create temporary table with the same
     * name for the second time results in exception.
     * EclipseLink attempts to create global temporary table in the beginning of UpdateAllQuery,
     * execution and assumes that it already exists in case SQLException results.
     * In the end of UpdateAllQuery execution all rows are removed from the temporary table -
     * it is necessary in case the same temporary table will be used by another UpdateAllQuery
     * in the same transaction.
     * Override this method if the platform supports global temporary tables.
     * Note that this method is ignored in case supportsLocalTempTables() returns true.
     */
     public boolean supportsGlobalTempTables() {
         return false;
     }

    /**
     * INTERNAL:
     * Override this method if the platform supports temporary tables.
     * This should contain the beginning of sql string for
     * creating temporary table - the sql statement name, for instance:
     * "CREATE GLOBAL TEMPORARY TABLE ".
     * Don't forget to end it with a space.
     */
     protected String getCreateTempTableSqlPrefix() {
         throw ValidationException.platformDoesNotOverrideGetCreateTempTableSqlPrefix(Helper.getShortClassName(this));
     }

    /**
     * INTERNAL:
     * May override this method if the platform support temporary tables.
     * @param table is original table for which temp table is created.
     * @return temporary table
     */
     public DatabaseTable getTempTableForTable(DatabaseTable table) {
         return new DatabaseTable("TL_" + table.getName(), table.getTableQualifier(), table.shouldUseDelimiters(), getStartDelimiter(), getEndDelimiter());
     }

    /**
     * INTERNAL:
     * May override this method if the platform support temporary tables.
     * This should contain the ending of sql string for
     * creating temporary table, for instance:
     * " ON COMMIT DELETE ROWS"
     * Don't forget to begin it with a space.
     */
     protected String getCreateTempTableSqlSuffix() {
         return "";
     }

    /**
     * INTERNAL:
     * May override this method if the platform supports temporary tables.
     * With this method not overridden the sql string for temporary table creation
     * will include a list of database fields extracted from descriptor:
     * getCreateTempTableSqlPrefix() + getTempTableForTable(table).getQualifiedName() +
     * (list of database fields) + getCreateTempTableSqlSuffix().
     * If this method is overridden its output will be used instead of fields' list:
     * getCreateTempTableSqlPrefix() + getTempTableForTable(table).getQualifiedName() +
     * getCreateTempTableSqlBodyForTable(table) + getCreateTempTableSqlSuffix().
     * Don't forget to begin it with a space.
     * Example: " LIKE " + table.getQualifiedName();
     * @param table is original table for which temp table is created.
     * @return String
     */
     protected String getCreateTempTableSqlBodyForTable(DatabaseTable table) {
         return null;
     }

    /**
     * INTERNAL:
     * Indicates whether temporary table can specify primary keys (some platforms don't allow that).
     * Used by writeCreateTempTableSql method.
     */
    protected boolean shouldTempTableSpecifyPrimaryKeys() {
        return true;
    }

    /**
     * INTERNAL:
     * Don't override this method.
     * Write an sql string for creation of the temporary table.
     * Note that in case of local temp table support it's possible to limit
     * the fields in the temp table to those needed for the operation it supports (usedFields) -
     * the temp table will be dropped in the end of query execution.
     * Alternatively, in global temp table case the table with a given name is created just once
     * and will be potentially used by various operations with various sets of used fields,
     * therefore global temp table should contain all mapped fields (allFields).
     * Precondition: supportsTempTables() == true.
     * Precondition: pkFields contained in usedFields contained in allFields
     * @param writer for writing the sql
     * @param table is original table for which temp table is created.
     * @param pkFields primary key fields for the original table.
     * @param usedFields fields that will be used by operation for which temp table is created.
     * @param allFields all mapped fields for the original table.
     */
     public void writeCreateTempTableSql(Writer writer, DatabaseTable table, AbstractSession session,
                                        Collection pkFields,
                                        Collection usedFields,
                                        Collection allFields) throws IOException
    {
        String body = getCreateTempTableSqlBodyForTable(table);
        if(body == null) {
            TableDefinition tableDef = new TableDefinition();
            Collection fields;
            if(supportsLocalTempTables()) {
                fields = usedFields;
            } else {
                // supportsGlobalTempTables() == true
                fields = allFields;
            }
            Iterator itFields = fields.iterator();
            while (itFields.hasNext()) {
                DatabaseField field = (DatabaseField)itFields.next();
                FieldDefinition fieldDef;
                //gfbug3307, should use columnDefinition if it was defined.
                if ((field.getColumnDefinition()!= null) && (field.getColumnDefinition().length() == 0)) {
                    Class<? extends Class> type = ConversionManager.getObjectClass(field.getType());
                    // Default type to VARCHAR, if unknown.
                    if (type == null) {
                        type = ConversionManager.getObjectClass(ClassConstants.STRING);
                    }
                   fieldDef = new FieldDefinition(field.getNameDelimited(this), type);
                } else {
                   fieldDef = new FieldDefinition(field.getNameDelimited(this), field.getColumnDefinition());
                }
                if (pkFields.contains(field) && shouldTempTableSpecifyPrimaryKeys()) {
                    fieldDef.setIsPrimaryKey(true);
                }
                tableDef.addField(fieldDef);
            }
            tableDef.setCreationPrefix(getCreateTempTableSqlPrefix());
            tableDef.setName(getTempTableForTable(table).getQualifiedNameDelimited(this));
            tableDef.setCreationSuffix(getCreateTempTableSqlSuffix());
            tableDef.buildCreationWriter(session, writer);
        } else {
            writer.write(getCreateTempTableSqlPrefix());
            writer.write(getTempTableForTable(table).getQualifiedNameDelimited(this));
            writer.write(body);
            writer.write(getCreateTempTableSqlSuffix());
        }
    }

    /**
     * INTERNAL:
     * May need to override this method if the platform supports temporary tables
     * and the generated sql doesn't work.
     * Write an sql string for insertion into the temporary table.
     * Precondition: supportsTempTables() == true.
     * @param writer for writing the sql
     * @param table is original table for which temp table is created.
     * @param usedFields fields that will be used by operation for which temp table is created.
     */
     public void writeInsertIntoTableSql(Writer writer, DatabaseTable table, Collection usedFields) throws IOException {
        writer.write("INSERT INTO ");
        writer.write(getTempTableForTable(table).getQualifiedNameDelimited(this));

        writer.write(" (");
        writeFieldsList(writer, usedFields, this);
        writer.write(") ");
    }

    /**
     * INTERNAL:
     * Override this if the platform cannot handle NULL in select clause.
     */
    public boolean isNullAllowedInSelectClause() {
        return true;
    }

    /**
     * INTERNAL:
     * Return true if output parameters can be built with result sets.
     */
    public boolean isOutputAllowWithResultSet() {
        return true;
    }

    /**
     * INTERNAL:
     * Write used on all table creation statements generated from the DefaultTableGenerator
     * with a session using this project (DDL generation).  This writes the passed in string argument as
     * well as the value returned from the DatabasePlatform's getTableCreationSuffix()
     */
    public void writeTableCreationSuffix(Writer writer, String tableCreationSuffix) throws IOException {
        if(tableCreationSuffix!=null && tableCreationSuffix.length() > 0) {
            writer.write(" " + tableCreationSuffix);
        }
        String defaultTableCreationSuffix = getTableCreationSuffix();
        if (defaultTableCreationSuffix !=null && defaultTableCreationSuffix.length()>0) {
            writer.write(" " + defaultTableCreationSuffix);
        }
    }

    /**
     * INTERNAL:
     * May need to override this method if the platform supports temporary tables
     * and the generated sql doesn't work.
     * Write an sql string for updating the original table from the temporary table.
     * Precondition: supportsTempTables() == true.
     * Precondition: pkFields and assignFields don't intersect.
     * @param writer for writing the sql
     * @param table is original table for which temp table is created.
     * @param pkFields primary key fields for the original table.
     * @param assignedFields fields to be assigned a new value.
     */
     public void writeUpdateOriginalFromTempTableSql(Writer writer, DatabaseTable table,
                                                     Collection pkFields,
                                                     Collection assignedFields) throws IOException
    {
        writer.write("UPDATE ");
        String tableName = table.getQualifiedNameDelimited(this);
        writer.write(tableName);
        writer.write(" SET (");
        writeFieldsList(writer, assignedFields, this);
        writer.write(") = (SELECT ");
        writeFieldsList(writer, assignedFields, this);
        writer.write(" FROM ");
        String tempTableName = getTempTableForTable(table).getQualifiedNameDelimited(this);
        writer.write(tempTableName);
        writeAutoJoinWhereClause(writer, null, tableName, pkFields, this);
        writer.write(") WHERE EXISTS(SELECT ");
        writer.write(((DatabaseField)pkFields.iterator().next()).getNameDelimited(this));
        writer.write(" FROM ");
        writer.write(tempTableName);
        writeAutoJoinWhereClause(writer, null, tableName, pkFields, this);
        writer.write(")");
    }

    /**
     * INTERNAL:
     * Write an sql string for deletion from target table using temporary table.
     * At this point temporary table should contains pks for the rows that should be
     * deleted from target table.
     * Temporary tables are not required for DeleteAllQuery, however will be used if
     * shouldAlwaysUseTempStorageForModifyAll()==true
     * May need to override this method in case it generates sql that doesn't work on the platform.
     * Precondition: supportsTempTables() == true.
     * @param writer for writing the sql
     * @param table is original table for which temp table is created.
     * @param targetTable is a table from which to delete.
     * @param pkFields primary key fields for the original table.
     * @param targetPkFields primary key fields for the target table.
     */
     public void writeDeleteFromTargetTableUsingTempTableSql(Writer writer, DatabaseTable table, DatabaseTable targetTable,
                                                     Collection pkFields,
                                                     Collection targetPkFields, DatasourcePlatform platform) throws IOException
    {
        writer.write("DELETE FROM ");
        String targetTableName = targetTable.getQualifiedNameDelimited(this);
        writer.write(targetTableName);
        writer.write(" WHERE EXISTS(SELECT ");
        writer.write(((DatabaseField)pkFields.iterator().next()).getNameDelimited(platform));
        writer.write(" FROM ");
        String tempTableName = getTempTableForTable(table).getQualifiedNameDelimited(this);
        writer.write(tempTableName);
        writeJoinWhereClause(writer, null, targetTableName, pkFields, targetPkFields, this);
        writer.write(")");
    }

     public boolean wasFailureCommunicationBased(SQLException exception, Connection connection, AbstractSession sessionForProfile){
         if (connection == null) {
             //Without a connection we are  unable to determine what caused the error so return false.
             //The only case where connection will be null should be External Connection Pooling so
             //returning false is ok as there is no connection management requirement
             return false;
         } else if (this.pingSQL == null) {
             // By default use the JDBC isValid API unless a ping SQL has been set.
             // The ping SQL is set by most platforms, but user could set to null to used optimized JDBC check if desired.
             try {
                 return connection.isValid(IS_VALID_TIMEOUT);
             } catch (Throwable failed) {
                 // Catch throwable as old JDBC drivers may not support isValid.
                 return false;
             }
         }
         PreparedStatement statement = null;
         try{
             sessionForProfile.startOperationProfile(SessionProfiler.ConnectionPing);
             if (sessionForProfile.shouldLog(SessionLog.FINE, SessionLog.SQL)) {// Avoid printing if no logging required.
                 sessionForProfile.log(SessionLog.FINE, SessionLog.SQL, getPingSQL(), null, null, false);
             }
             statement = connection.prepareStatement(getPingSQL());
             ResultSet result = statement.executeQuery();
             result.close();
             statement.close();
         }catch (SQLException ex){
             try{
                 //try to close statement again in case the query or result.close() caused an exception.
                 if (statement != null) statement.close();
             }catch (SQLException exception2){
                 //ignore;
             }
             return true;
         }finally{
             sessionForProfile.endOperationProfile(SessionProfiler.ConnectionPing);
         }
         return false;
     }

    /**
     * INTERNAL:
     * Don't override this method.
     * Write an sql string for clean up of the temporary table.
     * Drop a local temp table or delete all from a global temp table (so that it's
     * ready to be used again in the same transaction).
     * Precondition: supportsTempTables() == true.
     * @param writer for writing the sql
     * @param table is original table for which temp table is created.
     */
     public void writeCleanUpTempTableSql(Writer writer, DatabaseTable table) throws IOException {
        if(supportsLocalTempTables()) {
            writer.write("DROP TABLE ");
        } else {
            // supportsGlobalTempTables() == true
            writer.write("DELETE FROM ");
        }
        writer.write(getTempTableForTable(table).getQualifiedNameDelimited(this));
    }

    /**
     * INTERNAL:
     * That method affects UpdateAllQuery and DeleteAllQuery execution.
     * In case it returns false modify all queries would attempt to proceed
     * without using temporary storage if it is possible.
     * In case it returns true modify all queries would use temporary storage unless
     * each modify statement doesn't reference any other tables.
     * May need to override this method if the platform can't handle the sql
     * generated for modify all queries without using temporary storage.
     */
    public boolean shouldAlwaysUseTempStorageForModifyAll() {
        return false;
    }

   /**
    * INTERNAL:
    * May need to override this method if the sql generated for UpdateAllQuery
    * using temp tables fails in case parameter binding is used.
    */
    public boolean dontBindUpdateAllQueryUsingTempTables() {
        return false;
    }

    /**
     * INTERNAL:
     * helper method, don't override.
     */
    protected static void writeFieldsList(Writer writer, Collection fields, DatasourcePlatform platform) throws IOException {
        boolean isFirst = true;
        Iterator itFields = fields.iterator();
        while(itFields.hasNext()) {
            if(isFirst) {
                isFirst = false;
            } else {
                writer.write(", ");
            }
            DatabaseField field = (DatabaseField)itFields.next();
            writer.write(field.getNameDelimited(platform));
        }
    }

    /**
     * INTERNAL:
     * helper method, don't override.
     */
    protected static void writeAutoAssignmentSetClause(Writer writer, String tableName1, String tableName2, Collection fields, DatasourcePlatform platform) throws IOException {
        writer.write(" SET ");
        writeFieldsAutoClause(writer, tableName1, tableName2, fields, ", ", platform);
    }

    /**
     * INTERNAL:
     * helper method, don't override.
     */
    protected static void writeAutoJoinWhereClause(Writer writer, String tableName1, String tableName2, Collection pkFields, DatasourcePlatform platform) throws IOException {
        writer.write(" WHERE ");
        writeFieldsAutoClause(writer, tableName1, tableName2, pkFields, " AND ", platform);
    }

    /**
     * INTERNAL:
     * helper method, don't override.
     */
    protected static void writeFieldsAutoClause(Writer writer, String tableName1, String tableName2, Collection fields, String separator, DatasourcePlatform platform) throws IOException {
        writeFields(writer, tableName1, tableName2, fields, fields, separator, platform);
    }
    /**
     * INTERNAL:
     * helper method, don't override.
     */
    protected static void writeJoinWhereClause(Writer writer, String tableName1, String tableName2, Collection pkFields1, Collection pkFields2, DatasourcePlatform platform) throws IOException {
        writer.write(" WHERE ");
        writeFields(writer, tableName1, tableName2, pkFields1, pkFields2, " AND ", platform);
    }

    /**
     * INTERNAL:
     * helper method, don't override.
     */
    protected static void writeFields(Writer writer, String tableName1, String tableName2, Collection fields1, Collection fields2, String separator, DatasourcePlatform platform) throws IOException {
        boolean isFirst = true;
        Iterator itFields1 = fields1.iterator();
        Iterator itFields2 = fields2.iterator();
        while(itFields1.hasNext()) {
            if(isFirst) {
                isFirst = false;
            } else {
                writer.write(separator);
            }
            if(tableName1 != null) {
                writer.write(tableName1);
                writer.write(".");
            }
            String fieldName1 = ((DatabaseField)itFields1.next()).getNameDelimited(platform);
            writer.write(fieldName1);
            writer.write(" = ");
            if(tableName2 != null) {
                writer.write(tableName2);
                writer.write(".");
            }
            String fieldName2 = ((DatabaseField)itFields2.next()).getNameDelimited(platform);
            writer.write(fieldName2);
        }
    }

    public boolean shouldPrintFieldIdentityClause(AbstractSession session, String qualifiedFieldName) {
        if (!supportsIdentity()) {
            return false;
        }
        if ((session.getSequencing() == null) || (session.getSequencing().whenShouldAcquireValueForAll() == Sequencing.BEFORE_INSERT)) {
            return false;
        }

        boolean shouldAcquireSequenceValueAfterInsert = false;
        DatabaseField field = new DatabaseField(qualifiedFieldName, getStartDelimiter(), getEndDelimiter());
        Iterator<ClassDescriptor> descriptors = session.getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = (ClassDescriptor)descriptors.next();
            if (!descriptor.usesSequenceNumbers()) {
                continue;
            }
            if (descriptor.getSequenceNumberField().equals(field)) {
                String seqName = descriptor.getSequenceNumberName();
                Sequence sequence = getSequence(seqName);
                shouldAcquireSequenceValueAfterInsert = sequence.shouldAcquireValueAfterInsert();
                break;
            }
        }
        return shouldAcquireSequenceValueAfterInsert;
    }

    public void printFieldTypeSize(Writer writer, FieldDefinition field,
            FieldTypeDefinition fieldType, boolean shouldPrintFieldIdentityClause) throws IOException {
        printFieldTypeSize(writer, field, fieldType);
    }

    protected void printFieldTypeSize(Writer writer, FieldDefinition field,
            FieldTypeDefinition fieldType) throws IOException {
        writer.write(fieldType.getName());
        if ((fieldType.isSizeAllowed()) && ((field.getSize() != 0) || (fieldType.isSizeRequired()))) {
            writer.write("(");
            if (field.getSize() == 0) {
                writer.write(Integer.toString(fieldType.getDefaultSize()));
            } else {
                writer.write(Integer.toString(field.getSize()));
            }
            if (field.getSubSize() != 0) {
                writer.write(",");
                writer.write(Integer.toString(field.getSubSize()));
            } else if (fieldType.getDefaultSubSize() != 0) {
                writer.write(",");
                writer.write(Integer.toString(fieldType.getDefaultSubSize()));
            }
            writer.write(")");
        }
    }

    /**
     * Allows unique columns to be defined as constraint if the UNIQUE keyword is not support on a column defintion.
     */
    public boolean supportsUniqueColumns() {
        return true;
    }

    public void printFieldUnique(Writer writer,  boolean shouldPrintFieldIdentityClause) throws IOException {
        printFieldUnique(writer);
    }

    protected void printFieldUnique(Writer writer) throws IOException {
        if (supportsUniqueKeyConstraints()) {
            writer.write(" UNIQUE");
        }
    }

    public void writeParameterMarker(Writer writer, ParameterExpression expression, AbstractRecord record, DatabaseCall call) throws IOException {
        writer.write("?");
    }

    /**
     * INTERNAL:
     * This method builds an Array using the unwrapped connection within the session
     * @return Array
     */
    public Array createArray(String elementDataTypeName, Object[] elements, AbstractSession session, Connection connection) throws SQLException {
        //Bug#5200836 need unwrap the connection prior to using.
        java.sql.Connection unwrappedConnection = getConnection(session, connection);
        return createArray(elementDataTypeName,elements,unwrappedConnection);
    }

    /**
     * INTERNAL:
     * This method builds a Struct using the unwrapped connection within the session
     * @return Struct
     */
    public Struct createStruct(String structTypeName, Object[] attributes, AbstractSession session, Connection connection) throws SQLException {
        java.sql.Connection unwrappedConnection = getConnection(session, connection);
        return createStruct(structTypeName,attributes,unwrappedConnection);
    }

    /**
     * INTERNAL:
     * Platforms that support java.sql.Array may override this method.
     * @return Array
     */
    public Array createArray(String elementDataTypeName, Object[] elements, Connection connection) throws SQLException {
        return connection.createArrayOf(elementDataTypeName, elements);
    }

    /**
     * INTERNAL:
     * Platforms that support java.sql.Struct may override this method.
     * @return Struct
     */
    public Struct createStruct(String structTypeName, Object[] attributes, Connection connection) throws SQLException {
        return connection.createStruct(structTypeName, attributes);
    }

    /**
     * INTERNAL:
     * Indicates whether the passed object is an instance of XDBDocument.
     * To avoid dependency on oracle.xdb the method returns false.
     * Overridden in Oracle9Platform
     * @return String
     */
    public boolean isXDBDocument(Object obj) {
        return false;
    }

    /**
     * PUBLIC:
     * Allows platform to choose whether to bind literals in DatabaseCalls or not.
     */
    public boolean shouldBindLiterals() {
        return this.shouldBindLiterals;
    }

    /**
     * PUBLIC:
     * Allows user to choose whether to bind literals in DatabaseCalls or not.
     */
    public void setShouldBindLiterals(boolean shouldBindLiterals) {
        this.shouldBindLiterals = shouldBindLiterals;
    }

    /**
     * INTERNAL:
     * Some databases have issues with using parameters on certain functions and relations.
     * This allows statements to disable binding only in these cases.
     */
    public boolean isDynamicSQLRequiredForFunctions() {
        return false;
    }

    /**
     * INTERNAL:
     * Platforms that support java.sql.Ref may override this method.
     * @return Object
     */
    public Object getRefValue(Ref ref,Connection connection) throws SQLException {
        return ref.getObject();
    }
    /**
     * INTERNAL:
     * This method builds a REF using the unwrapped connection within the session
     * @return Object
     */
    public Object getRefValue(Ref ref,AbstractSession executionSession,Connection connection) throws SQLException {
        //Bug#6068155, ensure connection is lived when processing the REF type value.
        java.sql.Connection unwrappedConnection = getConnection(executionSession,connection);
        return getRefValue(ref,unwrappedConnection);
    }


    /**
     * INTERNAL:
     * Prints return keyword for StoredFunctionDefinition:
     *    CREATE FUNCTION StoredFunction_In (P_IN BIGINT)
     *      RETURN  BIGINT
     * The method was introduced because MySQL requires "RETURNS" instead:
     *    CREATE FUNCTION StoredFunction_In (P_IN BIGINT)
     *      RETURNS  BIGINT
     */
    public void printStoredFunctionReturnKeyWord(Writer writer) throws IOException {
        writer.write("\n\t RETURN ");
    }

    /**
     * INTERNAL:
     * Print the SQL representation of the statement on a stream, storing the fields
     * in the DatabaseCall.
     */
    public void printSQLSelectStatement(DatabaseCall call, ExpressionSQLPrinter printer, SQLSelectStatement statement){
        call.setFields(statement.printSQL(printer));
    }

    /**
     * INTERNAL:
     * Indicates whether locking clause should be printed after where clause by SQLSelectStatement.
     * Example:
     *   on Oracle platform (method returns true):
     *     SELECT ADDRESS_ID, ... FROM ADDRESS WHERE (ADDRESS_ID = ?) FOR UPDATE
     *   on SQLServer platform (method returns false):
     *     SELECT ADDRESS_ID, ... FROM ADDRESS WITH (UPDLOCK) WHERE (ADDRESS_ID = ?)
     */
    public boolean shouldPrintLockingClauseAfterWhereClause() {
        return true;
    }

    /**
     * INTERNAL:
     * Indicates whether locking clause could be selectively applied only to some tables in a ReadQuery.
     * Example: the following locks the rows in SALARY table, doesn't lock the rows in EMPLOYEE table:
     *   on Oracle platform (method returns true):
     *     SELECT t0.EMP_ID..., t1.SALARY FROM EMPLOYEE t0, SALARY t1 WHERE ... FOR UPDATE t1.SALARY
     *   on SQLServer platform (method returns true):
     *     SELECT t0.EMP_ID..., t1.SALARY FROM EMPLOYEE t0, SALARY t1 WITH (UPDLOCK) WHERE ...
     */
    public boolean supportsIndividualTableLocking() {
        return true;
    }

    /**
     * INTERNAL:
     * Indicates whether locking clause could be applied to the query that has more than one table
     */
    public boolean supportsLockingQueriesWithMultipleTables() {
        return true;
    }

    /**
     * INTERNAL:
     * Indicates whether locking OF clause should print alias for field.
     * Example:
     *   on Oracle platform (method returns false):
     *     SELECT ADDRESS_ID, ... FROM ADDRESS T1 WHERE (T1.ADDRESS_ID = ?) FOR UPDATE OF T1.ADDRESS_ID
     *   on Postgres platform (method returns true):
     *     SELECT ADDRESS_ID, ... FROM ADDRESS T1 WHERE (T1.ADDRESS_ID = ?) FOR UPDATE OF T1
     */
    public boolean shouldPrintAliasForUpdate() {
        return false;
    }

    /**
     * INTERNAL:
     * Don't override this method.
     *
     * @param fullTableName
     *            qualified name of the table the index is to be created on
     * @param indexName
     *            name of the index
     * @param columnNames
     *            one or more columns the index is created for
     */
    public String buildCreateIndex(String fullTableName, String indexName, String... columnNames) {
        return buildCreateIndex(fullTableName, indexName, "", false, columnNames);
    }

    /**
     * INTERNAL:
     * Override this method with the platform's CREATE INDEX statement.
     *
     * @param fullTableName
     *            qualified name of the table the index is to be created on
     * @param indexName
     *            name of the index
     * @param qualifier
     *            qualifier to construct qualified name of index if needed
     * @param isUnique
     *            Indicates whether unique index is created
     * @param columnNames
     *            one or more columns the index is created for
     */
    public String buildCreateIndex(String fullTableName, String indexName, String qualifier, boolean isUnique, String... columnNames) {
        StringBuilder queryString = new StringBuilder();
        if (isUnique) {
            queryString.append("CREATE UNIQUE INDEX ");
        } else {
            queryString.append("CREATE INDEX ");
        }
        if (!qualifier.equals("")) {
            queryString.append(qualifier).append(".");
        }
        queryString.append(indexName).append(" ON ").append(fullTableName).append(" (");
        queryString.append(columnNames[0]);
        for (int i = 1; i < columnNames.length; i++) {
            queryString.append(", ").append(columnNames[i]);
        }
        queryString.append(")");
        return queryString.toString();
    }

    /**
     * INTERNAL:
     * Don't override this method.
     *
     * @param fullTableName
     *            qualified name of the table the index is to be removed from
     * @param indexName
     *            name of the index
     */
    public String buildDropIndex(String fullTableName, String indexName) {
        return buildDropIndex(fullTableName, indexName, "");
    }

    /**
     * INTERNAL:
     * Override this method with the platform's DROP INDEX statement.
     *
     * @param fullTableName
     *            qualified name of the table the index is to be removed from
     * @param indexName
     *            name of the index
     * @param qualifier
     *            qualifier to construct qualified name of index if needed
     */
    public String buildDropIndex(String fullTableName, String indexName, String qualifier) {
        StringBuilder queryString = new StringBuilder();
        queryString.append("DROP INDEX ");
        if (!qualifier.equals("")) {
            queryString.append(qualifier).append(".");
        }
        queryString.append(indexName);
        if (requiresTableInIndexDropDDL()) {
            queryString.append(" ON ").append(fullTableName);
        }
        return queryString.toString();
    }

    /**
     * INTERNAL:
     * Returns sql used to create sequence object in the database.
     */
    public Writer buildSequenceObjectCreationWriter(Writer writer, String fullSeqName, int increment, int start) throws IOException {
        writer.write("CREATE SEQUENCE ");
        writer.write(fullSeqName);
        if (increment != 1) {
            writer.write(" INCREMENT BY " + increment);
        }
        writer.write(" START WITH " + start);
        return writer;
    }

    /**
     * INTERNAL:
     * Returns sql used to delete sequence object from the database.
     */
    public Writer buildSequenceObjectDeletionWriter(Writer writer, String fullSeqName) throws IOException {
        writer.write("DROP SEQUENCE ");
        writer.write(fullSeqName);
        return writer;
    }

    /**
     * INTERNAL:
     * Returns sql used to alter sequence object's increment in the database.
     */
    public Writer buildSequenceObjectAlterIncrementWriter(Writer writer, String fullSeqName, int increment) throws IOException {
        writer.write("ALTER SEQUENCE ");
        writer.write(fullSeqName);
        writer.write(" INCREMENT BY " + increment);
        return writer;
    }

    /**
     * INTERNAL:
     * Override this method if the platform supports sequence objects
     * and it's possible to alter sequence object's increment in the database.
     */
    public boolean isAlterSequenceObjectSupported() {
        return false;
    }

    /**
     * INTERNAL:
     * Return if nesting outer joins is supported, i.e. each join must be followed by the ON clause.
     */
    public boolean supportsNestingOuterJoins() {
        return true;
    }

    /**
     * INTERNAL:
     * Return if brackets can be used in the ON clause for outer joins.
     */
    public boolean supportsOuterJoinsWithBrackets() {
        return true;
    }

    /**
     * INTERNAL:
     * Used by some platforms during reading of ResultSet to free temporary objects.
     */
    public void freeTemporaryObject(Object value) throws SQLException {
    }


    /**
     * INTERNAL:
     * Allow initialization from the connection.
     */
    public void initializeConnectionData(Connection connection) throws SQLException {
    }

    /**
     * INTERNAL:
     * May need to override this method if the platform supports ALTER TABLE ADD &lt;column&gt;
     * and the generated sql doesn't work.
     * Write the string that follows ALTER TABLE to create a sql statement for
     * the platform in order to append a new column to an existing table.
     */
     public void writeAddColumnClause(Writer writer, AbstractSession session, TableDefinition table, FieldDefinition field) throws IOException {
        writer.write("ADD ");
        field.appendDBString(writer, session, table);
    }

    /**
     * INTERNAL:
     * Override this method if the platform supports storing JDBC connection user name during
     * {@link #initializeConnectionData(Connection)}.
     * @return Always returns {@code false}
     */
    public boolean supportsConnectionUserName() {
        return false;
    }

    /**
     * INTERNAL:
     * Returns user name retrieved from JDBC connection.
     * @throws UnsupportedOperationException on every single call until overridden.
     */
    public String getConnectionUserName() {
        throw new UnsupportedOperationException("Connection user name is not supported.");
    }

    // Value of shouldCheckResultTableExistsQuery must be false.
    /**
     * INTERNAL:
     * Returns query to check whether given table exists.
     * Query execution throws an exception when no such table exists.
     * @param table database table meta-data
     * @return query to check whether given table exists
     */
    protected DataReadQuery getTableExistsQuery(final TableDefinition table) {
        final String sql = "SELECT 1 FROM " + table.getFullName();
        final DataReadQuery query = new DataReadQuery(sql);
        query.setMaxRows(1);
        return query;
    }

    /**
     * INTERNAL:
     * Executes and evaluates query to check whether given table exists.
     * Returned value is always {@code true}, because an exception is thrown
     * when given table does not exists.
     * @param session current database session
     * @param table database table meta-data
     * @param suppressLogging whether to suppress logging during query execution
     * @return value of {@code true} if given table exists or {@code false} otherwise
     */
    public boolean checkTableExists(final DatabaseSessionImpl session,
            final TableDefinition table, final boolean suppressLogging) {
        try {
            session.setLoggingOff(suppressLogging);
            session.executeQuery(getTableExistsQuery(table));
            return true;
        } catch (Exception notFound) {
            return false;
        }
    }

}
