// 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.

#pragma once

#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>

#include "arrow/type_fwd.h"
#include "arrow/util/optional.h"
#include "arrow/util/variant.h"

namespace arrow {
namespace flight {
namespace sql {

/// \brief Variant supporting all possible types on SQL info.
using SqlInfoResult =
    arrow::util::Variant<std::string, bool, int64_t, int32_t, std::vector<std::string>,
                         std::unordered_map<int32_t, std::vector<int32_t>>>;

/// \brief Map SQL info identifier to its value.
using SqlInfoResultMap = std::unordered_map<int32_t, SqlInfoResult>;

/// \brief Options to be set in the SqlInfo.
struct SqlInfoOptions {
  enum SqlInfo {
    // Server Information [0-500): Provides basic information about the Flight SQL Server.

    // Retrieves a UTF-8 string with the name of the Flight SQL Server.
    FLIGHT_SQL_SERVER_NAME = 0,

    // Retrieves a UTF-8 string with the native version of the Flight SQL Server.
    FLIGHT_SQL_SERVER_VERSION = 1,

    // Retrieves a UTF-8 string with the Arrow format version of the Flight SQL Server.
    FLIGHT_SQL_SERVER_ARROW_VERSION = 2,

    /*
     * Retrieves a boolean value indicating whether the Flight SQL Server is read only.
     *
     * Returns:
     * - false: if read-write
     * - true: if read only
     */
    FLIGHT_SQL_SERVER_READ_ONLY = 3,

    // SQL Syntax Information [500-1000): provides information about SQL syntax supported
    // by the Flight SQL Server.

    /*
     * Retrieves a boolean value indicating whether the Flight SQL Server supports CREATE
     * and DROP of catalogs.
     *
     * Returns:
     * - false: if it doesn't support CREATE and DROP of catalogs.
     * - true: if it supports CREATE and DROP of catalogs.
     */
    SQL_DDL_CATALOG = 500,

    /*
     * Retrieves a boolean value indicating whether the Flight SQL Server supports CREATE
     * and DROP of schemas.
     *
     * Returns:
     * - false: if it doesn't support CREATE and DROP of schemas.
     * - true: if it supports CREATE and DROP of schemas.
     */
    SQL_DDL_SCHEMA = 501,

    /*
     * Indicates whether the Flight SQL Server supports CREATE and DROP of tables.
     *
     * Returns:
     * - false: if it doesn't support CREATE and DROP of tables.
     * - true: if it supports CREATE and DROP of tables.
     */
    SQL_DDL_TABLE = 502,

    /*
     * Retrieves a uint32 value representing the enu uint32 ordinal for the case
     * sensitivity of catalog, table and schema names.
     *
     * The possible values are listed in
     * `arrow.flight.protocol.sql.SqlSupportedCaseSensitivity`.
     */
    SQL_IDENTIFIER_CASE = 503,

    // Retrieves a UTF-8 string with the supported character(s) used to surround a
    // delimited identifier.
    SQL_IDENTIFIER_QUOTE_CHAR = 504,

    /*
     * Retrieves a uint32 value representing the enu uint32 ordinal for the case
     * sensitivity of quoted identifiers.
     *
     * The possible values are listed in
     * `arrow.flight.protocol.sql.SqlSupportedCaseSensitivity`.
     */
    SQL_QUOTED_IDENTIFIER_CASE = 505,

    /*
     * Retrieves a boolean value indicating whether all tables are selectable.
     *
     * Returns:
     * - false: if not all tables are selectable or if none are;
     * - true: if all tables are selectable.
     */
    SQL_ALL_TABLES_ARE_SELECTABLE = 506,

    /*
     * Retrieves the null ordering.
     *
     * Returns a uint32 ordinal for the null ordering being used, as described in
     * `arrow.flight.protocol.sql.SqlNullOrdering`.
     */
    SQL_NULL_ORDERING = 507,

    // Retrieves a UTF-8 string list with values of the supported keywords.
    SQL_KEYWORDS = 508,

    // Retrieves a UTF-8 string list with values of the supported numeric functions.
    SQL_NUMERIC_FUNCTIONS = 509,

    // Retrieves a UTF-8 string list with values of the supported string functions.
    SQL_STRING_FUNCTIONS = 510,

    // Retrieves a UTF-8 string list with values of the supported system functions.
    SQL_SYSTEM_FUNCTIONS = 511,

    // Retrieves a UTF-8 string list with values of the supported datetime functions.
    SQL_DATETIME_FUNCTIONS = 512,

    /*
     * Retrieves the UTF-8 string that can be used to escape wildcard characters.
     * This is the string that can be used to escape '_' or '%' in the catalog search
     * parameters that are a pattern (and therefore use one of the wildcard characters).
     * The '_' character represents any single character; the '%' character represents any
     * sequence of zero or more characters.
     */
    SQL_SEARCH_STRING_ESCAPE = 513,

    /*
     * Retrieves a UTF-8 string with all the "extra" characters that can be used in
     * unquoted identifier names (those beyond a-z, A-Z, 0-9 and _).
     */
    SQL_EXTRA_NAME_CHARACTERS = 514,

    /*
     * Retrieves a boolean value indicating whether column aliasing is supported.
     * If so, the SQL AS clause can be used to provide names for computed columns or to
     * provide alias names for columns as required.
     *
     * Returns:
     * - false: if column aliasing is unsupported;
     * - true: if column aliasing is supported.
     */
    SQL_SUPPORTS_COLUMN_ALIASING = 515,

    /*
     * Retrieves a boolean value indicating whether concatenations between null and
     * non-null values being null are supported.
     *
     * - Returns:
     * - false: if concatenations between null and non-null values being null are
     * unsupported;
     * - true: if concatenations between null and non-null values being null are
     * supported.
     */
    SQL_NULL_PLUS_NULL_IS_NULL = 516,

    /*
     * Retrieves a map where the key is the type to convert from and the value is a list
     * with the types to convert to, indicating the supported conversions. Each key and
     * each item on the list value is a value to a predefined type on SqlSupportsConvert
     * enum. The returned map will be:  map<int32, list<int32>>
     */
    SQL_SUPPORTS_CONVERT = 517,

    /*
     * Retrieves a boolean value indicating whether, when table correlation names are
     * supported, they are restricted to being different from the names of the tables.
     *
     * Returns:
     * - false: if table correlation names are unsupported;
     * - true: if table correlation names are supported.
     */
    SQL_SUPPORTS_TABLE_CORRELATION_NAMES = 518,

    /*
     * Retrieves a boolean value indicating whether, when table correlation names are
     * supported, they are restricted to being different from the names of the tables.
     *
     * Returns:
     * - false: if different table correlation names are unsupported;
     * - true: if different table correlation names are supported
     */
    SQL_SUPPORTS_DIFFERENT_TABLE_CORRELATION_NAMES = 519,

    /*
     * Retrieves a boolean value indicating whether expressions in ORDER BY lists are
     * supported.
     *
     * Returns:
     * - false: if expressions in ORDER BY are unsupported;
     * - true: if expressions in ORDER BY are supported;
     */
    SQL_SUPPORTS_EXPRESSIONS_IN_ORDER_BY = 520,

    /*
     * Retrieves a boolean value indicating whether using a column that is not in the
     * SELECT statement in a GROUP BY clause is supported.
     *
     * Returns:
     * - false: if using a column that is not in the SELECT statement in a GROUP BY clause
     * is unsupported;
     * - true: if using a column that is not in the SELECT statement in a GROUP BY clause
     * is supported.
     */
    SQL_SUPPORTS_ORDER_BY_UNRELATED = 521,

    /*
     * Retrieves the supported GROUP BY commands;
     *
     * Returns an int32 bitmask value representing the supported commands.
     * The returned bitmask should be parsed in order to retrieve the supported commands.
     *
     * For instance:
     * - return 0 (\b0)   => [] (GROUP BY is unsupported);
     * - return 1 (\b1)   => [SQL_GROUP_BY_UNRELATED];
     * - return 2 (\b10)  => [SQL_GROUP_BY_BEYOND_SELECT];
     * - return 3 (\b11)  => [SQL_GROUP_BY_UNRELATED, SQL_GROUP_BY_BEYOND_SELECT].
     * Valid GROUP BY types are described under
     * `arrow.flight.protocol.sql.SqlSupportedGroupBy`.
     */
    SQL_SUPPORTED_GROUP_BY = 522,

    /*
     * Retrieves a boolean value indicating whether specifying a LIKE escape clause is
     * supported.
     *
     * Returns:
     * - false: if specifying a LIKE escape clause is unsupported;
     * - true: if specifying a LIKE escape clause is supported.
     */
    SQL_SUPPORTS_LIKE_ESCAPE_CLAUSE = 523,

    /*
     * Retrieves a boolean value indicating whether columns may be defined as
     * non-nullable.
     *
     * Returns:
     * - false: if columns cannot be defined as non-nullable;
     * - true: if columns may be defined as non-nullable.
     */
    SQL_SUPPORTS_NON_NULLABLE_COLUMNS = 524,

    /*
     * Retrieves the supported SQL grammar level as per the ODBC specification.
     *
     * Returns an int32 bitmask value representing the supported SQL grammar level.
     * The returned bitmask should be parsed in order to retrieve the supported grammar
     * levels.
     *
     * For instance:
     * - return 0 (\b0)   => [] (SQL grammar is unsupported);
     * - return 1 (\b1)   => [SQL_MINIMUM_GRAMMAR];
     * - return 2 (\b10)  => [SQL_CORE_GRAMMAR];
     * - return 3 (\b11)  => [SQL_MINIMUM_GRAMMAR, SQL_CORE_GRAMMAR];
     * - return 4 (\b100) => [SQL_EXTENDED_GRAMMAR];
     * - return 5 (\b101) => [SQL_MINIMUM_GRAMMAR, SQL_EXTENDED_GRAMMAR];
     * - return 6 (\b110) => [SQL_CORE_GRAMMAR, SQL_EXTENDED_GRAMMAR];
     * - return 7 (\b111) => [SQL_MINIMUM_GRAMMAR, SQL_CORE_GRAMMAR,
     * SQL_EXTENDED_GRAMMAR]. Valid SQL grammar levels are described under
     * `arrow.flight.protocol.sql.SupportedSqlGrammar`.
     */
    SQL_SUPPORTED_GRAMMAR = 525,

    /*
     * Retrieves the supported ANSI92 SQL grammar level.
     *
     * Returns an int32 bitmask value representing the supported ANSI92 SQL grammar level.
     * The returned bitmask should be parsed in order to retrieve the supported commands.
     *
     * For instance:
     * - return 0 (\b0)   => [] (ANSI92 SQL grammar is unsupported);
     * - return 1 (\b1)   => [ANSI92_ENTRY_SQL];
     * - return 2 (\b10)  => [ANSI92_INTERMEDIATE_SQL];
     * - return 3 (\b11)  => [ANSI92_ENTRY_SQL, ANSI92_INTERMEDIATE_SQL];
     * - return 4 (\b100) => [ANSI92_FULL_SQL];
     * - return 5 (\b101) => [ANSI92_ENTRY_SQL, ANSI92_FULL_SQL];
     * - return 6 (\b110) => [ANSI92_INTERMEDIATE_SQL, ANSI92_FULL_SQL];
     * - return 7 (\b111) => [ANSI92_ENTRY_SQL, ANSI92_INTERMEDIATE_SQL, ANSI92_FULL_SQL].
     * Valid ANSI92 SQL grammar levels are described under
     * `arrow.flight.protocol.sql.SupportedAnsi92SqlGrammarLevel`.
     */
    SQL_ANSI92_SUPPORTED_LEVEL = 526,

    /*
     * Retrieves a boolean value indicating whether the SQL Integrity Enhancement Facility
     * is supported.
     *
     * Returns:
     * - false: if the SQL Integrity Enhancement Facility is supported;
     * - true: if the SQL Integrity Enhancement Facility is supported.
     */
    SQL_SUPPORTS_INTEGRITY_ENHANCEMENT_FACILITY = 527,

    /*
     * Retrieves the support level for SQL OUTER JOINs.
     *
     * Returns a uint3 uint32 ordinal for the SQL ordering being used, as described in
     * `arrow.flight.protocol.sql.SqlOuterJoinsSupportLevel`.
     */
    SQL_OUTER_JOINS_SUPPORT_LEVEL = 528,

    // Retrieves a UTF-8 string with the preferred term for "schema".
    SQL_SCHEMA_TERM = 529,

    // Retrieves a UTF-8 string with the preferred term for "procedure".
    SQL_PROCEDURE_TERM = 530,

    // Retrieves a UTF-8 string with the preferred term for "catalog".
    SQL_CATALOG_TERM = 531,

    /*
     * Retrieves a boolean value indicating whether a catalog appears at the start of a
     * fully qualified table name.
     *
     * - false: if a catalog does not appear at the start of a fully qualified table name;
     * - true: if a catalog appears at the start of a fully qualified table name.
     */
    SQL_CATALOG_AT_START = 532,

    /*
     * Retrieves the supported actions for a SQL schema.
     *
     * Returns an int32 bitmask value representing the supported actions for a SQL schema.
     * The returned bitmask should be parsed in order to retrieve the supported actions
     * for a SQL schema.
     *
     * For instance:
     * - return 0 (\b0)   => [] (no supported actions for SQL schema);
     * - return 1 (\b1)   => [SQL_ELEMENT_IN_PROCEDURE_CALLS];
     * - return 2 (\b10)  => [SQL_ELEMENT_IN_INDEX_DEFINITIONS];
     * - return 3 (\b11)  => [SQL_ELEMENT_IN_PROCEDURE_CALLS,
     * SQL_ELEMENT_IN_INDEX_DEFINITIONS];
     * - return 4 (\b100) => [SQL_ELEMENT_IN_PRIVILEGE_DEFINITIONS];
     * - return 5 (\b101) => [SQL_ELEMENT_IN_PROCEDURE_CALLS,
     * SQL_ELEMENT_IN_PRIVILEGE_DEFINITIONS];
     * - return 6 (\b110) => [SQL_ELEMENT_IN_INDEX_DEFINITIONS,
     * SQL_ELEMENT_IN_PRIVILEGE_DEFINITIONS];
     * - return 7 (\b111) => [SQL_ELEMENT_IN_PROCEDURE_CALLS,
     * SQL_ELEMENT_IN_INDEX_DEFINITIONS, SQL_ELEMENT_IN_PRIVILEGE_DEFINITIONS]. Valid
     * actions for a SQL schema described under
     * `arrow.flight.protocol.sql.SqlSupportedElementActions`.
     */
    SQL_SCHEMAS_SUPPORTED_ACTIONS = 533,

    /*
     * Retrieves the supported actions for a SQL schema.
     *
     * Returns an int32 bitmask value representing the supported actions for a SQL
     * catalog. The returned bitmask should be parsed in order to retrieve the supported
     * actions for a SQL catalog.
     *
     * For instance:
     * - return 0 (\b0)   => [] (no supported actions for SQL catalog);
     * - return 1 (\b1)   => [SQL_ELEMENT_IN_PROCEDURE_CALLS];
     * - return 2 (\b10)  => [SQL_ELEMENT_IN_INDEX_DEFINITIONS];
     * - return 3 (\b11)  => [SQL_ELEMENT_IN_PROCEDURE_CALLS,
     * SQL_ELEMENT_IN_INDEX_DEFINITIONS];
     * - return 4 (\b100) => [SQL_ELEMENT_IN_PRIVILEGE_DEFINITIONS];
     * - return 5 (\b101) => [SQL_ELEMENT_IN_PROCEDURE_CALLS,
     * SQL_ELEMENT_IN_PRIVILEGE_DEFINITIONS];
     * - return 6 (\b110) => [SQL_ELEMENT_IN_INDEX_DEFINITIONS,
     * SQL_ELEMENT_IN_PRIVILEGE_DEFINITIONS];
     * - return 7 (\b111) => [SQL_ELEMENT_IN_PROCEDURE_CALLS,
     * SQL_ELEMENT_IN_INDEX_DEFINITIONS, SQL_ELEMENT_IN_PRIVILEGE_DEFINITIONS]. Valid
     * actions for a SQL catalog are described under
     * `arrow.flight.protocol.sql.SqlSupportedElementActions`.
     */
    SQL_CATALOGS_SUPPORTED_ACTIONS = 534,

    /*
     * Retrieves the supported SQL positioned commands.
     *
     * Returns an int32 bitmask value representing the supported SQL positioned commands.
     * The returned bitmask should be parsed in order to retrieve the supported SQL
     * positioned commands.
     *
     * For instance:
     * - return 0 (\b0)   => [] (no supported SQL positioned commands);
     * - return 1 (\b1)   => [SQL_POSITIONED_DELETE];
     * - return 2 (\b10)  => [SQL_POSITIONED_UPDATE];
     * - return 3 (\b11)  => [SQL_POSITIONED_DELETE, SQL_POSITIONED_UPDATE].
     * Valid SQL positioned commands are described under
     * `arrow.flight.protocol.sql.SqlSupportedPositionedCommands`.
     */
    SQL_SUPPORTED_POSITIONED_COMMANDS = 535,

    /*
     * Retrieves a boolean value indicating whether SELECT FOR UPDATE statements are
     * supported.
     *
     * Returns:
     * - false: if SELECT FOR UPDATE statements are unsupported;
     * - true: if SELECT FOR UPDATE statements are supported.
     */
    SQL_SELECT_FOR_UPDATE_SUPPORTED = 536,

    /*
     * Retrieves a boolean value indicating whether stored procedure calls that use the
     * stored procedure escape syntax are supported.
     *
     * Returns:
     * - false: if stored procedure calls that use the stored procedure escape syntax are
     * unsupported;
     * - true: if stored procedure calls that use the stored procedure escape syntax are
     * supported.
     */
    SQL_STORED_PROCEDURES_SUPPORTED = 537,

    /*
     * Retrieves the supported SQL subqueries.
     *
     * Returns an int32 bitmask value representing the supported SQL subqueries.
     * The returned bitmask should be parsed in order to retrieve the supported SQL
     * subqueries.
     *
     * For instance:
     * - return 0   (\b0)     => [] (no supported SQL subqueries);
     * - return 1   (\b1)     => [SQL_SUBQUERIES_IN_COMPARISONS];
     * - return 2   (\b10)    => [SQL_SUBQUERIES_IN_EXISTS];
     * - return 3   (\b11)    => [SQL_SUBQUERIES_IN_COMPARISONS,
     * SQL_SUBQUERIES_IN_EXISTS];
     * - return 4   (\b100)   => [SQL_SUBQUERIES_IN_INS];
     * - return 5   (\b101)   => [SQL_SUBQUERIES_IN_COMPARISONS, SQL_SUBQUERIES_IN_INS];
     * - return 6   (\b110)   => [SQL_SUBQUERIES_IN_COMPARISONS,
     * SQL_SUBQUERIES_IN_EXISTS];
     * - return 7   (\b111)   => [SQL_SUBQUERIES_IN_COMPARISONS, SQL_SUBQUERIES_IN_EXISTS,
     * SQL_SUBQUERIES_IN_INS];
     * - return 8   (\b1000)  => [SQL_SUBQUERIES_IN_QUANTIFIEDS];
     * - return 9   (\b1001)  => [SQL_SUBQUERIES_IN_COMPARISONS,
     * SQL_SUBQUERIES_IN_QUANTIFIEDS];
     * - return 10  (\b1010)  => [SQL_SUBQUERIES_IN_EXISTS,
     * SQL_SUBQUERIES_IN_QUANTIFIEDS];
     * - return 11  (\b1011)  => [SQL_SUBQUERIES_IN_COMPARISONS, SQL_SUBQUERIES_IN_EXISTS,
     * SQL_SUBQUERIES_IN_QUANTIFIEDS];
     * - return 12  (\b1100)  => [SQL_SUBQUERIES_IN_INS, SQL_SUBQUERIES_IN_QUANTIFIEDS];
     * - return 13  (\b1101)  => [SQL_SUBQUERIES_IN_COMPARISONS, SQL_SUBQUERIES_IN_INS,
     * SQL_SUBQUERIES_IN_QUANTIFIEDS];
     * - return 14  (\b1110)  => [SQL_SUBQUERIES_IN_EXISTS, SQL_SUBQUERIES_IN_INS,
     * SQL_SUBQUERIES_IN_QUANTIFIEDS];
     * - return 15  (\b1111)  => [SQL_SUBQUERIES_IN_COMPARISONS, SQL_SUBQUERIES_IN_EXISTS,
     * SQL_SUBQUERIES_IN_INS, SQL_SUBQUERIES_IN_QUANTIFIEDS];
     * - ...
     * Valid SQL subqueries are described under
     * `arrow.flight.protocol.sql.SqlSupportedSubqueries`.
     */
    SQL_SUPPORTED_SUBQUERIES = 538,

    /*
     * Retrieves a boolean value indicating whether correlated subqueries are supported.
     *
     * Returns:
     * - false: if correlated subqueries are unsupported;
     * - true: if correlated subqueries are supported.
     */
    SQL_CORRELATED_SUBQUERIES_SUPPORTED = 539,

    /*
     * Retrieves the supported SQL UNIONs.
     *
     * Returns an int32 bitmask value representing the supported SQL UNIONs.
     * The returned bitmask should be parsed in order to retrieve the supported SQL
     * UNIONs.
     *
     * For instance:
     * - return 0 (\b0)   => [] (no supported SQL positioned commands);
     * - return 1 (\b1)   => [SQL_UNION];
     * - return 2 (\b10)  => [SQL_UNION_ALL];
     * - return 3 (\b11)  => [SQL_UNION, SQL_UNION_ALL].
     * Valid SQL positioned commands are described under
     * `arrow.flight.protocol.sql.SqlSupportedUnions`.
     */
    SQL_SUPPORTED_UNIONS = 540,

    // Retrieves a uint32 value representing the maximum number of hex characters allowed
    // in an inline binary literal.
    SQL_MAX_BINARY_LITERAL_LENGTH = 541,

    // Retrieves a uint32 value representing the maximum number of characters allowed for
    // a character literal.
    SQL_MAX_CHAR_LITERAL_LENGTH = 542,

    // Retrieves a uint32 value representing the maximum number of characters allowed for
    // a column name.
    SQL_MAX_COLUMN_NAME_LENGTH = 543,

    // Retrieves a uint32 value representing the the maximum number of columns allowed in
    // a GROUP BY clause.
    SQL_MAX_COLUMNS_IN_GROUP_BY = 544,

    // Retrieves a uint32 value representing the maximum number of columns allowed in an
    // index.
    SQL_MAX_COLUMNS_IN_INDEX = 545,

    // Retrieves a uint32 value representing the maximum number of columns allowed in an
    // ORDER BY clause.
    SQL_MAX_COLUMNS_IN_ORDER_BY = 546,

    // Retrieves a uint32 value representing the maximum number of columns allowed in a
    // SELECT list.
    SQL_MAX_COLUMNS_IN_SELECT = 547,

    // Retrieves a uint32 value representing the maximum number of columns allowed in a
    // table.
    SQL_MAX_COLUMNS_IN_TABLE = 548,

    // Retrieves a uint32 value representing the maximum number of concurrent connections
    // possible.
    SQL_MAX_CONNECTIONS = 549,

    // Retrieves a uint32 value the maximum number of characters allowed in a cursor name.
    SQL_MAX_CURSOR_NAME_LENGTH = 550,

    /*
     * Retrieves a uint32 value representing the maximum number of bytes allowed for an
     * index, including all of the parts of the index.
     */
    SQL_MAX_INDEX_LENGTH = 551,

    // Retrieves a uint32 value representing the maximum number of characters allowed in a
    // procedure name.
    SQL_SCHEMA_NAME_LENGTH = 552,

    // Retrieves a uint32 value representing the maximum number of bytes allowed in a
    // single row.
    SQL_MAX_PROCEDURE_NAME_LENGTH = 553,

    // Retrieves a uint32 value representing the maximum number of characters allowed in a
    // catalog name.
    SQL_MAX_CATALOG_NAME_LENGTH = 554,

    // Retrieves a uint32 value representing the maximum number of bytes allowed in a
    // single row.
    SQL_MAX_ROW_SIZE = 555,

    /*
     * Retrieves a boolean indicating whether the return value for the JDBC method
     * getMaxRowSize includes the SQL data types LONGVARCHAR and LONGVARBINARY.
     *
     * Returns:
     * - false: if return value for the JDBC method getMaxRowSize does
     *          not include the SQL data types LONGVARCHAR and LONGVARBINARY;
     * - true: if return value for the JDBC method getMaxRowSize includes
     *         the SQL data types LONGVARCHAR and LONGVARBINARY.
     */
    SQL_MAX_ROW_SIZE_INCLUDES_BLOBS = 556,

    /*
     * Retrieves a uint32 value representing the maximum number of characters allowed for
     * an SQL statement; a result of 0 (zero) means that there is no limit or the limit is
     * not known.
     */
    SQL_MAX_STATEMENT_LENGTH = 557,

    // Retrieves a uint32 value representing the maximum number of active statements that
    // can be open at the same time.
    SQL_MAX_STATEMENTS = 558,

    // Retrieves a uint32 value representing the maximum number of characters allowed in a
    // table name.
    SQL_MAX_TABLE_NAME_LENGTH = 559,

    // Retrieves a uint32 value representing the maximum number of tables allowed in a
    // SELECT statement.
    SQL_MAX_TABLES_IN_SELECT = 560,

    // Retrieves a uint32 value representing the maximum number of characters allowed in a
    // user name.
    SQL_MAX_USERNAME_LENGTH = 561,

    /*
     * Retrieves this database's default transaction isolation level as described in
     * `arrow.flight.protocol.sql.SqlTransactionIsolationLevel`.
     *
     * Returns a uint32 ordinal for the SQL transaction isolation level.
     */
    SQL_DEFAULT_TRANSACTION_ISOLATION = 562,

    /*
     * Retrieves a boolean value indicating whether transactions are supported. If not,
     * invoking the method commit is a noop, and the isolation level is
     * `arrow.flight.protocol.sql.SqlTransactionIsolationLevel.TRANSACTION_NONE`.
     *
     * Returns:
     * - false: if transactions are unsupported;
     * - true: if transactions are supported.
     */
    SQL_TRANSACTIONS_SUPPORTED = 563,

    /*
     * Retrieves the supported transactions isolation levels.
     *
     * Returns an int32 bitmask value representing the supported transactions isolation
     * levels. The returned bitmask should be parsed in order to retrieve the supported
     * transactions isolation levels.
     *
     * For instance:
     * - return 0   (\b0)     => [] (no supported SQL transactions isolation levels);
     * - return 1   (\b1)     => [SQL_TRANSACTION_NONE];
     * - return 2   (\b10)    => [SQL_TRANSACTION_READ_UNCOMMITTED];
     * - return 3   (\b11)    => [SQL_TRANSACTION_NONE, SQL_TRANSACTION_READ_UNCOMMITTED];
     * - return 4   (\b100)   => [SQL_TRANSACTION_REPEATABLE_READ];
     * - return 5   (\b101)   => [SQL_TRANSACTION_NONE, SQL_TRANSACTION_REPEATABLE_READ];
     * - return 6   (\b110)   => [SQL_TRANSACTION_READ_UNCOMMITTED,
     * SQL_TRANSACTION_REPEATABLE_READ];
     * - return 7   (\b111)   => [SQL_TRANSACTION_NONE, SQL_TRANSACTION_READ_UNCOMMITTED,
     * SQL_TRANSACTION_REPEATABLE_READ];
     * - return 8   (\b1000)  => [SQL_TRANSACTION_REPEATABLE_READ];
     * - return 9   (\b1001)  => [SQL_TRANSACTION_NONE, SQL_TRANSACTION_REPEATABLE_READ];
     * - return 10  (\b1010)  => [SQL_TRANSACTION_READ_UNCOMMITTED,
     * SQL_TRANSACTION_REPEATABLE_READ];
     * - return 11  (\b1011)  => [SQL_TRANSACTION_NONE, SQL_TRANSACTION_READ_UNCOMMITTED,
     * SQL_TRANSACTION_REPEATABLE_READ];
     * - return 12  (\b1100)  => [SQL_TRANSACTION_REPEATABLE_READ,
     * SQL_TRANSACTION_REPEATABLE_READ];
     * - return 13  (\b1101)  => [SQL_TRANSACTION_NONE, SQL_TRANSACTION_REPEATABLE_READ,
     * SQL_TRANSACTION_REPEATABLE_READ];
     * - return 14  (\b1110)  => [SQL_TRANSACTION_READ_UNCOMMITTED,
     * SQL_TRANSACTION_REPEATABLE_READ, SQL_TRANSACTION_REPEATABLE_READ];
     * - return 15  (\b1111)  => [SQL_TRANSACTION_NONE, SQL_TRANSACTION_READ_UNCOMMITTED,
     * SQL_TRANSACTION_REPEATABLE_READ, SQL_TRANSACTION_REPEATABLE_READ];
     * - return 16  (\b10000) => [SQL_TRANSACTION_SERIALIZABLE];
     * - ...
     * Valid SQL positioned commands are described under
     * `arrow.flight.protocol.sql.SqlTransactionIsolationLevel`.
     */
    SQL_SUPPORTED_TRANSACTIONS_ISOLATION_LEVELS = 564,

    /*
     * Retrieves a boolean value indicating whether a data definition statement within a
     * transaction forces the transaction to commit.
     *
     * Returns:
     * - false: if a data definition statement within a transaction does not force the
     * transaction to commit;
     * - true: if a data definition statement within a transaction forces the transaction
     * to commit.
     */
    SQL_DATA_DEFINITION_CAUSES_TRANSACTION_COMMIT = 565,

    /*
     * Retrieves a boolean value indicating whether a data definition statement within a
     * transaction is ignored.
     *
     * Returns:
     * - false: if a data definition statement within a transaction is taken into account;
     * - true: a data definition statement within a transaction is ignored.
     */
    SQL_DATA_DEFINITIONS_IN_TRANSACTIONS_IGNORED = 566,

    /*
     * Retrieves an int32 bitmask value representing the supported result set types.
     * The returned bitmask should be parsed in order to retrieve the supported result set
     * types.
     *
     * For instance:
     * - return 0   (\b0)     => [] (no supported result set types);
     * - return 1   (\b1)     => [SQL_RESULT_SET_TYPE_UNSPECIFIED];
     * - return 2   (\b10)    => [SQL_RESULT_SET_TYPE_FORWARD_ONLY];
     * - return 3   (\b11)    => [SQL_RESULT_SET_TYPE_UNSPECIFIED,
     * SQL_RESULT_SET_TYPE_FORWARD_ONLY];
     * - return 4   (\b100)   => [SQL_RESULT_SET_TYPE_SCROLL_INSENSITIVE];
     * - return 5   (\b101)   => [SQL_RESULT_SET_TYPE_UNSPECIFIED,
     * SQL_RESULT_SET_TYPE_SCROLL_INSENSITIVE];
     * - return 6   (\b110)   => [SQL_RESULT_SET_TYPE_FORWARD_ONLY,
     * SQL_RESULT_SET_TYPE_SCROLL_INSENSITIVE];
     * - return 7   (\b111)   => [SQL_RESULT_SET_TYPE_UNSPECIFIED,
     * SQL_RESULT_SET_TYPE_FORWARD_ONLY, SQL_RESULT_SET_TYPE_SCROLL_INSENSITIVE];
     * - return 8   (\b1000)  => [SQL_RESULT_SET_TYPE_SCROLL_SENSITIVE];
     * - ...
     * Valid result set types are described under
     * `arrow.flight.protocol.sql.SqlSupportedResultSetType`.
     */
    SQL_SUPPORTED_RESULT_SET_TYPES = 567,

    /*
     * Returns an int32 bitmask value concurrency types supported for
     * `arrow.flight.protocol.sql.SqlSupportedResultSetType.SQL_RESULT_SET_TYPE_UNSPECIFIED`.
     *
     * For instance:
     * - return 0 (\b0)   => [] (no supported concurrency types for this result set type)
     * - return 1 (\b1)   => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED]
     * - return 2 (\b10)  => [SQL_RESULT_SET_CONCURRENCY_READ_ONLY]
     * - return 3 (\b11)  => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_READ_ONLY]
     * - return 4 (\b100) => [SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 5 (\b101) => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 6 (\b110)  => [SQL_RESULT_SET_CONCURRENCY_READ_ONLY,
     * SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 7 (\b111)  => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_READ_ONLY, SQL_RESULT_SET_CONCURRENCY_UPDATABLE] Valid
     * result set types are described under
     * `arrow.flight.protocol.sql.SqlSupportedResultSetConcurrency`.
     */
    SQL_SUPPORTED_CONCURRENCIES_FOR_RESULT_SET_UNSPECIFIED = 568,

    /*
     * Returns an int32 bitmask value concurrency types supported for
     * `arrow.flight.protocol.sql.SqlSupportedResultSetType.SQL_RESULT_SET_TYPE_FORWARD_ONLY`.
     *
     * For instance:
     * - return 0 (\b0)   => [] (no supported concurrency types for this result set type)
     * - return 1 (\b1)   => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED]
     * - return 2 (\b10)  => [SQL_RESULT_SET_CONCURRENCY_READ_ONLY]
     * - return 3 (\b11)  => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_READ_ONLY]
     * - return 4 (\b100) => [SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 5 (\b101) => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 6 (\b110)  => [SQL_RESULT_SET_CONCURRENCY_READ_ONLY,
     * SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 7 (\b111)  => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_READ_ONLY, SQL_RESULT_SET_CONCURRENCY_UPDATABLE] Valid
     * result set types are described under
     * `arrow.flight.protocol.sql.SqlSupportedResultSetConcurrency`.
     */
    SQL_SUPPORTED_CONCURRENCIES_FOR_RESULT_SET_FORWARD_ONLY = 569,

    /*
     * Returns an int32 bitmask value concurrency types supported for
     * `arrow.flight.protocol.sql.SqlSupportedResultSetType.SQL_RESULT_SET_TYPE_SCROLL_SENSITIVE`.
     *
     * For instance:
     * - return 0 (\b0)   => [] (no supported concurrency types for this result set type)
     * - return 1 (\b1)   => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED]
     * - return 2 (\b10)  => [SQL_RESULT_SET_CONCURRENCY_READ_ONLY]
     * - return 3 (\b11)  => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_READ_ONLY]
     * - return 4 (\b100) => [SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 5 (\b101) => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 6 (\b110)  => [SQL_RESULT_SET_CONCURRENCY_READ_ONLY,
     * SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 7 (\b111)  => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_READ_ONLY, SQL_RESULT_SET_CONCURRENCY_UPDATABLE] Valid
     * result set types are described under
     * `arrow.flight.protocol.sql.SqlSupportedResultSetConcurrency`.
     */
    SQL_SUPPORTED_CONCURRENCIES_FOR_RESULT_SET_SCROLL_SENSITIVE = 570,

    /*
     * Returns an int32 bitmask value concurrency types supported for
     * `arrow.flight.protocol.sql.SqlSupportedResultSetType.SQL_RESULT_SET_TYPE_SCROLL_INSENSITIVE`.
     *
     * For instance:
     * - return 0 (\b0)   => [] (no supported concurrency types for this result set type)
     * - return 1 (\b1)   => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED]
     * - return 2 (\b10)  => [SQL_RESULT_SET_CONCURRENCY_READ_ONLY]
     * - return 3 (\b11)  => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_READ_ONLY]
     * - return 4 (\b100) => [SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 5 (\b101) => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 6 (\b110)  => [SQL_RESULT_SET_CONCURRENCY_READ_ONLY,
     * SQL_RESULT_SET_CONCURRENCY_UPDATABLE]
     * - return 7 (\b111)  => [SQL_RESULT_SET_CONCURRENCY_UNSPECIFIED,
     * SQL_RESULT_SET_CONCURRENCY_READ_ONLY, SQL_RESULT_SET_CONCURRENCY_UPDATABLE] Valid
     * result set types are described under
     * `arrow.flight.protocol.sql.SqlSupportedResultSetConcurrency`.
     */
    SQL_SUPPORTED_CONCURRENCIES_FOR_RESULT_SET_SCROLL_INSENSITIVE = 571,

    /*
     * Retrieves a boolean value indicating whether this database supports batch updates.
     *
     * - false: if this database does not support batch updates;
     * - true: if this database supports batch updates.
     */
    SQL_BATCH_UPDATES_SUPPORTED = 572,

    /*
     * Retrieves a boolean value indicating whether this database supports savepoints.
     *
     * Returns:
     * - false: if this database does not support savepoints;
     * - true: if this database supports savepoints.
     */
    SQL_SAVEPOINTS_SUPPORTED = 573,

    /*
     * Retrieves a boolean value indicating whether named parameters are supported in
     * callable statements.
     *
     * Returns:
     * - false: if named parameters in callable statements are unsupported;
     * - true: if named parameters in callable statements are supported.
     */
    SQL_NAMED_PARAMETERS_SUPPORTED = 574,

    /*
     * Retrieves a boolean value indicating whether updates made to a LOB are made on a
     * copy or directly to the LOB.
     *
     * Returns:
     * - false: if updates made to a LOB are made directly to the LOB;
     * - true: if updates made to a LOB are made on a copy.
     */
    SQL_LOCATORS_UPDATE_COPY = 575,

    /*
     * Retrieves a boolean value indicating whether invoking user-defined or vendor
     * functions using the stored procedure escape syntax is supported.
     *
     * Returns:
     * - false: if invoking user-defined or vendor functions using the stored procedure
     * escape syntax is unsupported;
     * - true: if invoking user-defined or vendor functions using the stored procedure
     * escape syntax is supported.
     */
    SQL_STORED_FUNCTIONS_USING_CALL_SYNTAX_SUPPORTED = 576,
  };

  enum SqlSupportedCaseSensitivity {
    SQL_CASE_SENSITIVITY_UNKNOWN = 0,
    SQL_CASE_SENSITIVITY_CASE_INSENSITIVE = 1,
    SQL_CASE_SENSITIVITY_UPPERCASE = 2,
  };

  enum SqlNullOrdering {
    SQL_NULLS_SORTED_HIGH = 0,
    SQL_NULLS_SORTED_LOW = 1,
    SQL_NULLS_SORTED_AT_START = 2,
    SQL_NULLS_SORTED_AT_END = 3,
  };

  enum SqlSupportsConvert {
    SQL_CONVERT_BIGINT = 0,
    SQL_CONVERT_BINARY = 1,
    SQL_CONVERT_BIT = 2,
    SQL_CONVERT_CHAR = 3,
    SQL_CONVERT_DATE = 4,
    SQL_CONVERT_DECIMAL = 5,
    SQL_CONVERT_FLOAT = 6,
    SQL_CONVERT_INTEGER = 7,
    SQL_CONVERT_INTERVAL_DAY_TIME = 8,
    SQL_CONVERT_INTERVAL_YEAR_MONTH = 9,
    SQL_CONVERT_LONGVARBINARY = 10,
    SQL_CONVERT_LONGVARCHAR = 11,
    SQL_CONVERT_NUMERIC = 12,
    SQL_CONVERT_REAL = 13,
    SQL_CONVERT_SMALLINT = 14,
    SQL_CONVERT_TIME = 15,
    SQL_CONVERT_TIMESTAMP = 16,
    SQL_CONVERT_TINYINT = 17,
    SQL_CONVERT_VARBINARY = 18,
    SQL_CONVERT_VARCHAR = 19,
  };
};

/// \brief Table reference, optionally containing table's catalog and db_schema.
struct TableRef {
  util::optional<std::string> catalog;
  util::optional<std::string> db_schema;
  std::string table;
};

}  // namespace sql
}  // namespace flight
}  // namespace arrow
