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

package org.apache.asterix.jdbc.core;

import java.sql.DatabaseMetaData;
import java.sql.JDBCType;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class ADBMetaStatement extends ADBStatement {

    public static final String SCHEMALESS = "SCHEMALESS";
    public static final String TABLE = "TABLE";
    public static final String VIEW = "VIEW";

    private static final String PK_NAME_SUFFIX = "_pk";
    private static final String FK_NAME_SUFFIX = "_fk";

    public ADBMetaStatement(ADBConnection connection) {
        super(connection);
    }

    protected void populateQueryProlog(StringBuilder sql, String comment) {
        if (comment != null) {
            sql.append("/* ").append(comment).append(" */\n");
        }
        //sql.append("set `compiler.min.memory.allocation` 'false';\n");
    }

    protected ADBResultSet executeGetCatalogsQuery() throws SQLException {
        checkClosed();

        StringBuilder sql = new StringBuilder(256);
        populateQueryProlog(sql, "JDBC-GetCatalogs");

        sql.append("select TABLE_CAT ");
        sql.append("from Metadata.`Dataverse` ");
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("let TABLE_CAT = DatabaseName || '/' || DataverseName ");
                } else {
                    sql.append("let TABLE_CAT = DataverseName ");
                }
                break;
            case CATALOG_SCHEMA:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("let TABLE_CAT = DatabaseName ");
                } else {
                    sql.append("let name = decode_dataverse_name(DataverseName), ");
                    sql.append("TABLE_CAT = name[0] ");
                    sql.append("where (array_length(name) between 1 and 2) ");
                }
                sql.append("group by TABLE_CAT ");
                break;
            default:
                throw new IllegalStateException();
        }

        sql.append("order by TABLE_CAT");

        return executeQueryImpl(sql.toString(), null);
    }

    protected ADBResultSet executeGetSchemasQuery() throws SQLException {
        String catalog;
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                catalog = connection.getDataverseCanonicalName();
                break;
            case CATALOG_SCHEMA:
                catalog = connection.getCatalog();
                break;
            default:
                throw new IllegalStateException();
        }
        return executeGetSchemasQuery(catalog, null, "0");
    }

    protected ADBResultSet executeGetSchemasQuery(String catalog, String schemaPattern) throws SQLException {
        return executeGetSchemasQuery(catalog, schemaPattern, "1");
    }

    protected ADBResultSet executeGetSchemasQuery(String catalog, String schemaPattern, String tag)
            throws SQLException {
        checkClosed();

        StringBuilder sql = new StringBuilder(512);
        populateQueryProlog(sql, "JDBC-GetSchemas-" + tag);

        sql.append("select TABLE_SCHEM, TABLE_CATALOG ");
        sql.append("from Metadata.`Dataverse` ");
        sql.append("let ");
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("TABLE_CATALOG = DatabaseName || '/' || DataverseName, ");
                } else {
                    sql.append("TABLE_CATALOG = DataverseName, ");
                }
                sql.append("TABLE_SCHEM = null ");
                sql.append("where true ");
                break;
            case CATALOG_SCHEMA:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("TABLE_CATALOG = DatabaseName, ");
                    sql.append("TABLE_SCHEM = DataverseName ");
                } else {
                    sql.append("name = decode_dataverse_name(DataverseName), ");
                    sql.append("TABLE_CATALOG = name[0], ");
                    sql.append("TABLE_SCHEM = case array_length(name) when 1 then null else name[1] end ");
                    sql.append("where (array_length(name) between 1 and 2) ");
                }
                break;
            default:
                throw new IllegalStateException();
        }
        if (catalog != null) {
            sql.append("and (TABLE_CATALOG = $1) ");
        }
        if (schemaPattern != null) {
            sql.append("and (if_null(TABLE_SCHEM, '') like $2) ");
        }
        sql.append("order by TABLE_CATALOG, TABLE_SCHEM");

        return executeQueryImpl(sql.toString(), Arrays.asList(catalog, schemaPattern));
    }

    protected ADBResultSet executeGetTablesQuery(String catalog, String schemaPattern, String tableNamePattern,
            String[] types) throws SQLException {
        checkClosed();

        String datasetTermTabular = getDatasetTerm(true);
        String datasetTermNonTabular = getDatasetTerm(false);
        String viewTermTabular = getViewTerm(true);
        String viewTermNonTabular = getViewTerm(false);

        StringBuilder sql = new StringBuilder(1024);
        populateQueryProlog(sql, "JDBC-GetTables");

        sql.append("select TABLE_CAT, TABLE_SCHEM, TABLE_NAME, TABLE_TYPE, null REMARKS, null TYPE_CAT, ");
        sql.append("null TYPE_SCHEM, null TYPE_NAME, null SELF_REFERENCING_COL_NAME, null REF_GENERATION ");
        sql.append("from Metadata.`Dataset` ds join Metadata.`Datatype` dt ");
        sql.append("on ds.DatatypeDataverseName = dt.DataverseName and ds.DatatypeName = dt.DatatypeName ");
        if (connection.isDatabaseEntitySupported()) {
            sql.append("and ds.DatatypeDatabaseName = dt.DatabaseName ");
        }
        sql.append("let ");
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("TABLE_CAT = ds.DatabaseName || '/' || ds.DataverseName, ");
                } else {
                    sql.append("TABLE_CAT = ds.DataverseName, ");
                }
                sql.append("TABLE_SCHEM = null, ");
                break;
            case CATALOG_SCHEMA:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("TABLE_CAT = ds.DatabaseName, ");
                    sql.append("TABLE_SCHEM = ds.DataverseName, ");
                } else {
                    sql.append("dvname = decode_dataverse_name(ds.DataverseName), ");
                    sql.append("TABLE_CAT = dvname[0], ");
                    sql.append("TABLE_SCHEM = case array_length(dvname) when 1 then null else dvname[1] end, ");
                }
                break;
            default:
                throw new IllegalStateException();
        }
        sql.append("TABLE_NAME = ds.DatasetName, ");
        sql.append("isDataset = (ds.DatasetType = 'INTERNAL' or ds.DatasetType = 'EXTERNAL'), ");
        sql.append("isView = ds.DatasetType = 'VIEW', ");
        sql.append("hasFields = array_length(dt.Derived.Record.Fields) > 0, ");
        sql.append("TABLE_TYPE = case ");
        sql.append("when isDataset then (case when hasFields then '").append(datasetTermTabular).append("' else '")
                .append(datasetTermNonTabular).append("' end) ");
        sql.append("when isView then (case when hasFields then '").append(viewTermTabular).append("' else '")
                .append(viewTermNonTabular).append("' end) ");
        sql.append("else null end ");

        sql.append("where ");
        sql.append("(TABLE_TYPE ").append(types != null ? "in $1" : "is not null").append(") ");
        if (catalog != null) {
            sql.append("and (TABLE_CAT = $2) ");
        }
        if (schemaPattern != null) {
            sql.append("and (if_null(TABLE_SCHEM, '') like $3) ");
        }
        if (tableNamePattern != null) {
            sql.append("and (TABLE_NAME like $4) ");
        }
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                break;
            case CATALOG_SCHEMA:
                if (!connection.isDatabaseEntitySupported()) {
                    sql.append("and (array_length(dvname) between 1 and 2) ");
                }
                break;
            default:
                throw new IllegalStateException();
        }
        if (!connection.catalogIncludesSchemaless) {
            sql.append("and hasFields ");
        }

        sql.append("order by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM, TABLE_NAME");

        List<String> typesList = types != null ? Arrays.asList(types) : null;
        return executeQueryImpl(sql.toString(), Arrays.asList(typesList, catalog, schemaPattern, tableNamePattern));
    }

    protected ADBResultSet executeGetColumnsQuery(String catalog, String schemaPattern, String tableNamePattern,
            String columnNamePattern) throws SQLException {
        checkClosed();

        StringBuilder sql = new StringBuilder(2048);
        populateQueryProlog(sql, "JDBC-GetColumns");

        sql.append("select TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_SIZE, ");
        sql.append("1 BUFFER_LENGTH, null DECIMAL_DIGITS, 2 NUM_PREC_RADIX, NULLABLE, ");
        sql.append("null REMARKS, null COLUMN_DEF, DATA_TYPE SQL_DATA_TYPE,");
        sql.append("0 SQL_DATETIME_SUB, COLUMN_SIZE CHAR_OCTET_LENGTH, ORDINAL_POSITION, ");
        sql.append("case NULLABLE when 0 then 'NO' else 'YES' end IS_NULLABLE, ");
        sql.append("null SCOPE_CATALOG, null SCOPE_SCHEMA, null SCOPE_TABLE, null SOURCE_DATA_TYPE, ");
        sql.append("'NO' IS_AUTOINCREMENT, 'NO' IS_GENERATEDCOLUMN ");
        sql.append("from Metadata.`Dataset` ds ");
        sql.append("join Metadata.`Datatype` dt ");
        sql.append("on ds.DatatypeDataverseName = dt.DataverseName and ds.DatatypeName = dt.DatatypeName ");
        if (connection.isDatabaseEntitySupported()) {
            sql.append("and ds.DatatypeDatabaseName = dt.DatabaseName ");
        }
        sql.append("unnest dt.Derived.Record.Fields as field at fieldpos ");
        sql.append("left join Metadata.`Datatype` dt2 ");
        sql.append(
                "on field.FieldType = dt2.DatatypeName and ds.DataverseName = dt2.DataverseName and dt2.Derived is known ");
        if (connection.isDatabaseEntitySupported()) {
            sql.append("and ds.DatabaseName = dt2.DatabaseName ");
        }
        sql.append("let ");
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("TABLE_CAT = ds.DatabaseName || '/' || ds.DataverseName, ");
                } else {
                    sql.append("TABLE_CAT = ds.DataverseName, ");
                }
                sql.append("TABLE_SCHEM = null, ");
                break;
            case CATALOG_SCHEMA:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("TABLE_CAT = ds.DatabaseName, ");
                    sql.append("TABLE_SCHEM = ds.DataverseName, ");
                } else {
                    sql.append("dvname = decode_dataverse_name(ds.DataverseName), ");
                    sql.append("TABLE_CAT = dvname[0], ");
                    sql.append("TABLE_SCHEM = case array_length(dvname) when 1 then null else dvname[1] end, ");
                }
                break;
            default:
                throw new IllegalStateException();
        }
        sql.append("TABLE_NAME = ds.DatasetName, ");
        sql.append("COLUMN_NAME = field.FieldName, ");
        sql.append("TYPE_NAME = case ");
        for (ADBDatatype nestedType : new ADBDatatype[] { ADBDatatype.OBJECT, ADBDatatype.ARRAY,
                ADBDatatype.MULTISET }) {
            sql.append(String.format("when dt2.Derived.%s is known then '%s' ",
                    ADBDatatype.getDerivedRecordName(nestedType), nestedType.getTypeName()));
        }
        sql.append("else field.FieldType end, ");
        sql.append("DATA_TYPE = ");
        sql.append("case TYPE_NAME ");
        for (ADBDatatype type : ADBDatatype.values()) {
            JDBCType jdbcType = type.getJdbcType();
            if (type.isNullOrMissing() || jdbcType.equals(JDBCType.OTHER)) {
                // will be handled by the 'else' clause
                continue;
            }
            sql.append("when '").append(type.getTypeName()).append("' ");
            sql.append("then ").append(jdbcType.getVendorTypeNumber()).append(" ");
        }
        sql.append("else ").append(JDBCType.OTHER.getVendorTypeNumber()).append(" end, ");

        sql.append("COLUMN_SIZE = case field.FieldType when 'string' then 32767 else 8 end, "); // TODO:based on type
        sql.append("ORDINAL_POSITION = fieldpos, ");
        sql.append("NULLABLE = case when field.IsNullable or field.IsMissable then 1 else 0 end ");

        sql.append("where (array_length(dt.Derived.Record.Fields) > 0) ");
        if (catalog != null) {
            sql.append("and (TABLE_CAT = $1) ");
        }
        if (schemaPattern != null) {
            sql.append("and (if_null(TABLE_SCHEM, '') like $2) ");
        }
        if (tableNamePattern != null) {
            sql.append("and (TABLE_NAME like $3) ");
        }
        if (columnNamePattern != null) {
            sql.append("and (COLUMN_NAME like $4) ");
        }
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                break;
            case CATALOG_SCHEMA:
                if (!connection.isDatabaseEntitySupported()) {
                    sql.append("and (array_length(dvname) between 1 and 2) ");
                }
                break;
            default:
                throw new IllegalStateException();
        }

        sql.append("order by TABLE_CAT, TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION");

        return executeQueryImpl(sql.toString(),
                Arrays.asList(catalog, schemaPattern, tableNamePattern, columnNamePattern));
    }

    protected ADBResultSet executeGetPrimaryKeysQuery(String catalog, String schema, String table) throws SQLException {
        checkClosed();

        StringBuilder sql = new StringBuilder(1024);
        populateQueryProlog(sql, "JDBC-GetPrimaryKeys");

        sql.append("select TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, KEY_SEQ, PK_NAME ");
        sql.append("from Metadata.`Dataset` ds ");
        sql.append("join Metadata.`Datatype` dt ");
        sql.append("on ds.DatatypeDataverseName = dt.DataverseName and ds.DatatypeName = dt.DatatypeName ");
        if (connection.isDatabaseEntitySupported()) {
            sql.append("and ds.DatatypeDatabaseName = dt.DatabaseName ");
        }
        sql.append("unnest coalesce(ds.InternalDetails, ds.ExternalDetails, ds.ViewDetails).PrimaryKey pki at pkipos ");
        sql.append("let ");
        sql.append("hasFields = array_length(dt.Derived.Record.Fields) > 0, ");
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("TABLE_CAT = ds.DatabaseName || '/' || ds.DataverseName, ");
                } else {
                    sql.append("TABLE_CAT = ds.DataverseName, ");
                }
                sql.append("TABLE_SCHEM = null, ");
                break;
            case CATALOG_SCHEMA:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("TABLE_CAT = ds.DatabaseName, ");
                    sql.append("TABLE_SCHEM = ds.DataverseName, ");
                } else {
                    sql.append("dvname = decode_dataverse_name(ds.DataverseName), ");
                    sql.append("TABLE_CAT = dvname[0], ");
                    sql.append("TABLE_SCHEM = case array_length(dvname) when 1 then null else dvname[1] end, ");
                }
                break;
            default:
                throw new IllegalStateException();
        }
        sql.append("TABLE_NAME = ds.DatasetName, ");
        sql.append("COLUMN_NAME = pki[0], ");
        sql.append("KEY_SEQ = pkipos, ");
        sql.append("PK_NAME = TABLE_NAME || '").append(PK_NAME_SUFFIX).append("', ");
        sql.append("dsDetails = coalesce(ds.InternalDetails, ds.ExternalDetails, ds.ViewDetails) ");
        sql.append("where (every pk in dsDetails.PrimaryKey satisfies array_length(pk) = 1 end) ");
        sql.append("and (every si in dsDetails.KeySourceIndicator satisfies si = 0 end ) ");
        if (catalog != null) {
            sql.append("and (TABLE_CAT = $1) ");
        }
        if (schema != null) {
            sql.append("and (if_null(TABLE_SCHEM, '') like $2) ");
        }
        if (table != null) {
            sql.append("and (TABLE_NAME like $3) ");
        }
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                break;
            case CATALOG_SCHEMA:
                if (!connection.isDatabaseEntitySupported()) {
                    sql.append("and (array_length(dvname) between 1 and 2) ");
                }
                break;
            default:
                throw new IllegalStateException();
        }
        if (!connection.catalogIncludesSchemaless) {
            sql.append("and hasFields ");
        }

        sql.append("order by COLUMN_NAME");

        return executeQueryImpl(sql.toString(), Arrays.asList(catalog, schema, table));
    }

    protected ADBResultSet executeGetImportedKeysQuery(String catalog, String schema, String table)
            throws SQLException {
        return executeGetImportedExportedKeysQuery("JDBC-GetImportedKeys", null, null, null, catalog, schema, table,
                false);
    }

    protected ADBResultSet executeGetExportedKeysQuery(String catalog, String schema, String table)
            throws SQLException {
        return executeGetImportedExportedKeysQuery("JDBC-GetExportedKeys", catalog, schema, table, null, null, null,
                true);
    }

    protected ADBResultSet executeCrossReferenceQuery(String parentCatalog, String parentSchema, String parentTable,
            String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
        return executeGetImportedExportedKeysQuery("JDBC-CrossReference", parentCatalog, parentSchema, parentTable,
                foreignCatalog, foreignSchema, foreignTable, true);
    }

    protected ADBResultSet executeGetImportedExportedKeysQuery(String comment, String pkCatalog, String pkSchema,
            String pkTable, String fkCatalog, String fkSchema, String fkTable, boolean orderByFk) throws SQLException {
        StringBuilder sql = new StringBuilder(2048);
        populateQueryProlog(sql, comment);

        sql.append("select PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, PKCOLUMN_NAME, ");
        sql.append("FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FKCOLUMN_NAME, KEY_SEQ, ");
        sql.append(DatabaseMetaData.importedKeyNoAction).append(" UPDATE_RULE, ");
        sql.append(DatabaseMetaData.importedKeyNoAction).append(" DELETE_RULE, ");
        sql.append("FK_NAME, PK_NAME, ");
        sql.append(DatabaseMetaData.importedKeyInitiallyDeferred).append(" DEFERRABILITY ");
        sql.append("from Metadata.`Dataset` ds ");
        sql.append("join Metadata.`Datatype` dt ");
        sql.append("on ds.DatatypeDataverseName = dt.DataverseName and ds.DatatypeName = dt.DatatypeName ");
        if (connection.isDatabaseEntitySupported()) {
            sql.append("and ds.DatatypeDatabaseName = dt.DatabaseName ");
        }
        sql.append("unnest coalesce(ds.InternalDetails, ds.ExternalDetails, ds.ViewDetails).ForeignKeys fk at fkpos ");
        sql.append("join Metadata.`Dataset` ds2 ");
        sql.append("on fk.RefDataverseName = ds2.DataverseName and fk.RefDatasetName = ds2.DatasetName ");
        if (connection.isDatabaseEntitySupported()) {
            sql.append("and fk.RefDatabaseName = ds2.DatabaseName ");
        }
        sql.append("unnest fk.ForeignKey fki at fkipos ");
        sql.append("let ");
        sql.append("hasFields = array_length(dt.Derived.Record.Fields) > 0, ");
        switch (connection.catalogDataverseMode) {
            case CATALOG:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("FKTABLE_CAT = ds.DatabaseName || '/' || ds.DataverseName, ");
                    sql.append("PKTABLE_CAT = ds2.DatabaseName || '/' || ds2.DataverseName, ");
                } else {
                    sql.append("FKTABLE_CAT = ds.DataverseName, ");
                    sql.append("PKTABLE_CAT = ds2.DataverseName, ");
                }
                sql.append("FKTABLE_SCHEM = null, ");
                sql.append("PKTABLE_SCHEM = null, ");
                break;
            case CATALOG_SCHEMA:
                if (connection.isDatabaseEntitySupported()) {
                    sql.append("FKTABLE_CAT = ds.DatabaseName, ");
                    sql.append("FKTABLE_SCHEM = ds.DataverseName, ");
                    sql.append("PKTABLE_CAT = ds2.DatabaseName, ");
                    sql.append("PKTABLE_SCHEM = ds2.DataverseName, ");
                } else {
                    sql.append("dvname = decode_dataverse_name(ds.DataverseName), ");
                    sql.append("FKTABLE_CAT = dvname[0], ");
                    sql.append("FKTABLE_SCHEM = case array_length(dvname) when 1 then null else dvname[1] end, ");
                    sql.append("dvname2 = decode_dataverse_name(ds2.DataverseName), ");
                    sql.append("PKTABLE_CAT = dvname2[0], ");
                    sql.append("PKTABLE_SCHEM = case array_length(dvname2) when 1 then null else dvname2[1] end, ");
                }
                break;
            default:
                throw new IllegalStateException();
        }
        sql.append("ds2Details = coalesce(ds2.InternalDetails, ds2.ExternalDetails, ds2.ViewDetails), ");
        sql.append("FKTABLE_NAME = ds.DatasetName, ");
        sql.append("PKTABLE_NAME = ds2.DatasetName, ");
        sql.append("FKCOLUMN_NAME = fki[0], ");
        sql.append("PKCOLUMN_NAME = ds2Details.PrimaryKey[fkipos-1][0], ");
        sql.append("KEY_SEQ = fkipos, ");
        sql.append("PK_NAME = PKTABLE_NAME || '").append(PK_NAME_SUFFIX).append("', ");
        sql.append("FK_NAME = FKTABLE_NAME || '").append(FK_NAME_SUFFIX).append("_' || string(fkpos) ");
        sql.append("where (every fki2 in fk.ForeignKey satisfies array_length(fki2) = 1 end) ");
        sql.append("and (every fksi in fk.KeySourceIndicator satisfies fksi = 0 end ) ");
        sql.append("and (every pki in ds2Details.PrimaryKey satisfies array_length(pki) = 1 end) ");
        sql.append("and (every pksi in ds2Details.KeySourceIndicator satisfies pksi = 0 end) ");

        if (pkCatalog != null) {
            sql.append("and (").append("PKTABLE_CAT").append(" = $1) ");
        }
        if (pkSchema != null) {
            sql.append("and (if_null(").append("PKTABLE_SCHEM").append(", '') like $2) ");
        }
        if (pkTable != null) {
            sql.append("and (").append("PKTABLE_NAME").append(" like $3) ");
        }

        if (fkCatalog != null) {
            sql.append("and (").append("FKTABLE_CAT").append(" = $4) ");
        }
        if (fkSchema != null) {
            sql.append("and (if_null(").append("FKTABLE_SCHEM").append(", '') like $5) ");
        }
        if (fkTable != null) {
            sql.append("and (").append("FKTABLE_NAME").append(" like $6) ");
        }

        switch (connection.catalogDataverseMode) {
            case CATALOG:
                break;
            case CATALOG_SCHEMA:
                if (!connection.isDatabaseEntitySupported()) {
                    sql.append("and (array_length(dvname) between 1 and 2) ");
                    sql.append("and (array_length(dvname2) between 1 and 2) ");
                }
                break;
            default:
                throw new IllegalStateException();
        }
        if (!connection.catalogIncludesSchemaless) {
            sql.append("and hasFields ");
        }

        sql.append("order by ").append(
                orderByFk ? "FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME" : "PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME")
                .append(", KEY_SEQ");

        return executeQueryImpl(sql.toString(),
                Arrays.asList(pkCatalog, pkSchema, pkTable, fkCatalog, fkSchema, fkTable));
    }

    protected ADBResultSet executeGetTableTypesQuery() throws SQLException {
        checkClosed();

        LinkedHashSet<String> tableTypes = new LinkedHashSet<>();
        tableTypes.add(getDatasetTerm(true));
        tableTypes.add(getViewTerm(true));
        if (connection.catalogIncludesSchemaless) {
            tableTypes.add(getDatasetTerm(false));
            tableTypes.add(getViewTerm(false));
        }

        List<ADBColumn> columns = Collections.singletonList(new ADBColumn("TABLE_TYPE", ADBDatatype.STRING, false));

        AbstractValueSerializer stringSer = getADMFormatSerializer(String.class);
        ArrayNode result =
                (ArrayNode) connection.protocol.getDriverContext().getGenericObjectReader().createArrayNode();
        for (String tableType : tableTypes) {
            result.addObject().put("TABLE_TYPE", stringSer.serializeToString(tableType));
        }

        return createSystemResultSet(columns, result);
    }

    protected ADBResultSet executeGetTypeInfoQuery() throws SQLException {
        checkClosed();

        AbstractValueSerializer int16Ser = getADMFormatSerializer(Short.class);
        AbstractValueSerializer int32Ser = getADMFormatSerializer(Integer.class);
        AbstractValueSerializer stringSer = getADMFormatSerializer(String.class);

        List<ADBColumn> columns = new ArrayList<>();
        columns.add(new ADBColumn("TYPE_NAME", ADBDatatype.STRING, false));
        columns.add(new ADBColumn("DATA_TYPE", ADBDatatype.INTEGER, false));
        columns.add(new ADBColumn("PRECISION", ADBDatatype.INTEGER, true));
        columns.add(new ADBColumn("LITERAL_PREFIX", ADBDatatype.STRING, true));
        columns.add(new ADBColumn("LITERAL_SUFFIX", ADBDatatype.STRING, true));
        columns.add(new ADBColumn("CREATE_PARAMS", ADBDatatype.STRING, true));
        columns.add(new ADBColumn("NULLABLE", ADBDatatype.SMALLINT, true));
        columns.add(new ADBColumn("CASE_SENSITIVE", ADBDatatype.BOOLEAN, true));
        columns.add(new ADBColumn("SEARCHABLE", ADBDatatype.SMALLINT, true));
        columns.add(new ADBColumn("UNSIGNED_ATTRIBUTE", ADBDatatype.BOOLEAN, true));
        columns.add(new ADBColumn("FIXED_PREC_SCALE", ADBDatatype.BOOLEAN, true));
        columns.add(new ADBColumn("AUTO_INCREMENT", ADBDatatype.BOOLEAN, true));
        columns.add(new ADBColumn("LOCAL_TYPE_NAME", ADBDatatype.STRING, true));
        columns.add(new ADBColumn("MINIMUM_SCALE", ADBDatatype.SMALLINT, true));
        columns.add(new ADBColumn("MAXIMUM_SCALE", ADBDatatype.SMALLINT, true));
        columns.add(new ADBColumn("SQL_DATA_TYPE", ADBDatatype.INTEGER, true));
        columns.add(new ADBColumn("SQL_DATETIME_SUB", ADBDatatype.INTEGER, true));
        columns.add(new ADBColumn("NUM_PREC_RADIX", ADBDatatype.INTEGER, true));

        ArrayNode result =
                (ArrayNode) connection.protocol.getDriverContext().getGenericObjectReader().createArrayNode();
        populateTypeInfo(result.addObject(), ADBDatatype.BOOLEAN, 1, null, null, null, null, null, null, int16Ser,
                int32Ser, stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.TINYINT, 3, 10, 0, 0, false, null, null, int16Ser, int32Ser,
                stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.SMALLINT, 5, 10, 0, 0, false, null, null, int16Ser, int32Ser,
                stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.INTEGER, 10, 10, 0, 0, false, null, null, int16Ser, int32Ser,
                stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.BIGINT, 19, 10, 0, 0, false, null, null, int16Ser, int32Ser,
                stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.FLOAT, 7, 2, 0, 0, false, null, null, int16Ser, int32Ser,
                stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.DOUBLE, 15, 2, 0, 0, false, null, null, int16Ser, int32Ser,
                stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.DATE, 32, null, 0, 0, false, null, null, int16Ser, int32Ser,
                stringSer); // TODO:precision
        populateTypeInfo(result.addObject(), ADBDatatype.TIME, 32, null, 0, 0, false, null, null, int16Ser, int32Ser,
                stringSer); // TODO:precision
        populateTypeInfo(result.addObject(), ADBDatatype.DATETIME, 32, null, 0, 0, false, null, null, int16Ser,
                int32Ser, stringSer); // TODO:precision
        populateTypeInfo(result.addObject(), ADBDatatype.YEARMONTHDURATION, 32, null, 0, 0, false, null, null, int16Ser,
                int32Ser, stringSer); // TODO:precision
        populateTypeInfo(result.addObject(), ADBDatatype.DAYTIMEDURATION, 32, null, 0, 0, false, null, null, int16Ser,
                int32Ser, stringSer); // TODO:precision
        populateTypeInfo(result.addObject(), ADBDatatype.DURATION, 32, null, 0, 0, false, null, null, int16Ser,
                int32Ser, stringSer); // TODO:precision
        populateTypeInfo(result.addObject(), ADBDatatype.STRING, 32767, null, null, null, true, "'", "'", int16Ser,
                int32Ser, stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.ARRAY, 32767, null, 0, 0, false, null, null, int16Ser,
                int32Ser, stringSer);
        populateTypeInfo(result.addObject(), ADBDatatype.OBJECT, 32767, null, 0, 0, false, null, null, int16Ser,
                int32Ser, stringSer);

        return createSystemResultSet(columns, result);
    }

    protected void populateTypeInfo(ObjectNode typeInfo, ADBDatatype type, int precision, Integer precisionRadix,
            Integer minScale, Integer maxScale, Boolean searchable, String literalPrefix, String literalSuffix,
            ADBPreparedStatement.AbstractValueSerializer int16Ser,
            ADBPreparedStatement.AbstractValueSerializer int32Ser,
            ADBPreparedStatement.AbstractValueSerializer stringSer) {
        typeInfo.put("TYPE_NAME", stringSer.serializeToString(type.getTypeName()));
        typeInfo.put("DATA_TYPE", int32Ser.serializeToString(type.getJdbcType().getVendorTypeNumber()));
        typeInfo.put("PRECISION", int32Ser.serializeToString(precision));
        typeInfo.put("LITERAL_PREFIX", literalPrefix != null ? stringSer.serializeToString(literalPrefix) : null);
        typeInfo.put("LITERAL_SUFFIX", literalSuffix != null ? stringSer.serializeToString(literalSuffix) : null);
        typeInfo.putNull("CREATE_PARAMS");
        typeInfo.put("NULLABLE", int16Ser.serializeToString((short) DatabaseMetaData.typeNullable));
        typeInfo.put("CASE_SENSITIVE", false);
        typeInfo.put("SEARCHABLE",
                int16Ser.serializeToString((short) (searchable == null ? DatabaseMetaData.typePredNone
                        : searchable ? DatabaseMetaData.typeSearchable : DatabaseMetaData.typePredBasic)));
        typeInfo.put("UNSIGNED_ATTRIBUTE", false);
        typeInfo.put("FIXED_PREC_SCALE", false);
        typeInfo.putNull("AUTO_INCREMENT");
        typeInfo.putNull("LOCAL_TYPE_NAME");
        typeInfo.put("MINIMUM_SCALE", minScale != null ? int16Ser.serializeToString(minScale.shortValue()) : null);
        typeInfo.put("MAXIMUM_SCALE", maxScale != null ? int16Ser.serializeToString(maxScale.shortValue()) : null);
        typeInfo.put("SQL_DATA_TYPE", int32Ser.serializeToString(type.getTypeTag()));
        typeInfo.putNull("SQL_DATETIME_SUB");
        typeInfo.put("NUM_PREC_RADIX", int32Ser.serializeToString(precisionRadix != null ? precisionRadix : 10));
    }

    protected ADBResultSet executeEmptyResultQuery() throws SQLException {
        checkClosed();
        return createEmptyResultSet();
    }

    @Override
    protected ADBStatement getResultSetStatement(ADBResultSet rs) {
        return null;
    }

    @Override
    protected ADBProtocolBase.SubmitStatementOptions createSubmitStatementOptions() {
        ADBProtocolBase.SubmitStatementOptions options = super.createSubmitStatementOptions();
        // Metadata queries are always executed in SQL++ mode
        options.sqlCompatMode = false;
        return options;
    }

    protected String getDatasetTerm(boolean tabular) {
        return tabular ? TABLE : SCHEMALESS + " " + TABLE;
    }

    protected String getViewTerm(boolean tabular) {
        return tabular ? VIEW : SCHEMALESS + " " + VIEW;
    }
}
