/*
 * 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.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<Class<?>, FieldTypeDefinition> buildFieldTypes() {
        Hashtable<Class<?>, FieldTypeDefinition> 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<Class<? extends Number>, ? super Number> maximumNumericValues() {
        Hashtable<Class<? extends Number>, ? super Number> 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<Class<? extends Number>, ? super Number> minimumNumericValues() {
        Hashtable<Class<? extends Number>, ? super Number> 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(Map<String, Class<?>> 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(Map<Class<?>, FieldTypeDefinition> 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 = 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:
     * This method builds a Struct using the unwrapped connection within the session
     * @return Struct
     */
    public Struct createStruct(String structTypeName, Object[] attributes, AbstractRecord row, Vector orderedFields, 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;
        }
    }

}
