driver/info.cc (1,029 lines of code) (raw):
// Modifications Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Copyright (c) 2000, 2024, Oracle and/or its affiliates.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 2.0, as
// published by the Free Software Foundation.
//
// This program is designed to work with certain software (including
// but not limited to OpenSSL) that is licensed under separate terms, as
// designated in a particular file or component or in included license
// documentation. The authors of MySQL hereby grant you an additional
// permission to link the program and your derivative works with the
// separately licensed software that they have either included with
// the program or referenced in the documentation.
//
// Without limiting anything contained in the foregoing, this file,
// which is part of Connector/ODBC, is also subject to the
// Universal FOSS Exception, version 1.0, a copy of which can be found at
// https://oss.oracle.com/licenses/universal-foss-exception.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License, version 2.0, for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/**
@file info.c
@brief Driver information functions.
*/
#include "driver.h"
#define MYINFO_SET_ULONG(val) \
do { \
*((SQLUINTEGER *)num_info)= (val); \
*value_len= sizeof(SQLUINTEGER); \
return SQL_SUCCESS; \
} while(0)
#define MYINFO_SET_USHORT(val) \
do { \
*((SQLUSMALLINT *)num_info)= (SQLUSMALLINT)(val); \
*value_len= sizeof(SQLUSMALLINT); \
return SQL_SUCCESS; \
} while(0)
#define MYINFO_SET_STR(val) \
do { \
*char_info= (SQLCHAR *)(val); \
return SQL_SUCCESS; \
} while(0)
static my_bool myodbc_ov2_inited = 0;
/**
Return general information about the driver and data source
associated with a connection.
@param[in] hdbc Handle of database connection
@param[in] fInfoType Type of information to retrieve
@param[out] char_info Pointer to buffer for returning string
@param[out] num_info Pointer to buffer for returning numeric info
@param[out] value_len Pointer to buffer for returning length (only
used for numeric data)
*/
SQLRETURN SQL_API
MySQLGetInfo(SQLHDBC hdbc, SQLUSMALLINT fInfoType,
SQLCHAR **char_info, SQLPOINTER num_info, SQLSMALLINT *value_len)
{
DBC *dbc = (DBC *)hdbc;
SQLSMALLINT dummy;
SQLINTEGER dummy_value;
if (!value_len)
value_len = &dummy;
if (!num_info)
num_info = &dummy_value;
switch (fInfoType) {
case SQL_ACTIVE_ENVIRONMENTS:
MYINFO_SET_USHORT(0);
case SQL_AGGREGATE_FUNCTIONS:
MYINFO_SET_ULONG(SQL_AF_ALL | SQL_AF_AVG | SQL_AF_COUNT | SQL_AF_DISTINCT |
SQL_AF_MAX | SQL_AF_MIN | SQL_AF_SUM);
case SQL_ALTER_DOMAIN:
MYINFO_SET_ULONG(0);
case SQL_ALTER_TABLE:
/** @todo check if we should report more */
MYINFO_SET_ULONG(SQL_AT_ADD_COLUMN | SQL_AT_DROP_COLUMN);
#ifndef USE_IODBC
case SQL_ASYNC_DBC_FUNCTIONS:
MYINFO_SET_ULONG(SQL_ASYNC_DBC_NOT_CAPABLE);
#endif
case SQL_ASYNC_MODE:
MYINFO_SET_ULONG(SQL_AM_NONE);
case SQL_BATCH_ROW_COUNT:
MYINFO_SET_ULONG(SQL_BRC_EXPLICIT);
case SQL_BATCH_SUPPORT:
MYINFO_SET_ULONG(SQL_BS_SELECT_EXPLICIT | SQL_BS_ROW_COUNT_EXPLICIT |
SQL_BS_SELECT_PROC | SQL_BS_ROW_COUNT_PROC);
case SQL_BOOKMARK_PERSISTENCE:
MYINFO_SET_ULONG(SQL_BP_UPDATE | SQL_BP_DELETE);
case SQL_CATALOG_LOCATION:
MYINFO_SET_USHORT(SQL_CL_START);
case SQL_CATALOG_NAME:
MYINFO_SET_STR(dbc->ds->opt_NO_CATALOG ? "" : "Y");
case SQL_CATALOG_NAME_SEPARATOR:
MYINFO_SET_STR(dbc->ds->opt_NO_CATALOG ? "" : ".");
case SQL_CATALOG_TERM:
MYINFO_SET_STR(dbc->ds->opt_NO_CATALOG ? "" : "database");
case SQL_CATALOG_USAGE:
MYINFO_SET_ULONG(!dbc->ds->opt_NO_CATALOG ?
(SQL_CU_DML_STATEMENTS | SQL_CU_PROCEDURE_INVOCATION |
SQL_CU_TABLE_DEFINITION | SQL_CU_INDEX_DEFINITION |
SQL_CU_PRIVILEGE_DEFINITION) :
0);
case SQL_COLLATION_SEQ:
MYINFO_SET_STR(dbc->connection_proxy->get_character_set()->name);
case SQL_COLUMN_ALIAS:
MYINFO_SET_STR("Y");
case SQL_CONCAT_NULL_BEHAVIOR:
MYINFO_SET_USHORT(SQL_CB_NULL);
case SQL_CONVERT_BIGINT:
case SQL_CONVERT_BIT:
case SQL_CONVERT_CHAR:
case SQL_CONVERT_DATE:
case SQL_CONVERT_DECIMAL:
case SQL_CONVERT_DOUBLE:
case SQL_CONVERT_FLOAT:
case SQL_CONVERT_INTEGER:
case SQL_CONVERT_LONGVARCHAR:
case SQL_CONVERT_NUMERIC:
case SQL_CONVERT_REAL:
case SQL_CONVERT_SMALLINT:
case SQL_CONVERT_TIME:
case SQL_CONVERT_TIMESTAMP:
case SQL_CONVERT_TINYINT:
case SQL_CONVERT_VARCHAR:
case SQL_CONVERT_WCHAR:
case SQL_CONVERT_WVARCHAR:
case SQL_CONVERT_WLONGVARCHAR:
MYINFO_SET_ULONG(SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT |
SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_VARCHAR |
SQL_CVT_LONGVARCHAR | SQL_CVT_BIT | SQL_CVT_TINYINT |
SQL_CVT_BIGINT | SQL_CVT_DATE | SQL_CVT_TIME |
SQL_CVT_TIMESTAMP | SQL_CVT_WCHAR | SQL_CVT_WVARCHAR |
SQL_CVT_WLONGVARCHAR);
case SQL_CONVERT_BINARY:
case SQL_CONVERT_VARBINARY:
case SQL_CONVERT_LONGVARBINARY:
case SQL_CONVERT_INTERVAL_DAY_TIME:
case SQL_CONVERT_INTERVAL_YEAR_MONTH:
MYINFO_SET_ULONG(0);
case SQL_CONVERT_FUNCTIONS:
/* MySQL's CONVERT() and CAST() functions aren't SQL compliant yet. */
MYINFO_SET_ULONG(0);
case SQL_CORRELATION_NAME:
MYINFO_SET_USHORT(SQL_CN_DIFFERENT);
case SQL_CREATE_ASSERTION:
case SQL_CREATE_CHARACTER_SET:
case SQL_CREATE_COLLATION:
case SQL_CREATE_DOMAIN:
case SQL_CREATE_SCHEMA:
MYINFO_SET_ULONG(0);
case SQL_CREATE_TABLE:
MYINFO_SET_ULONG(SQL_CT_CREATE_TABLE | SQL_CT_COMMIT_DELETE |
SQL_CT_LOCAL_TEMPORARY | SQL_CT_COLUMN_DEFAULT |
SQL_CT_COLUMN_COLLATION);
case SQL_CREATE_TRANSLATION:
MYINFO_SET_ULONG(0);
case SQL_CREATE_VIEW:
/** @todo SQL_CV_LOCAL ? */
if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.0"))
MYINFO_SET_ULONG(SQL_CV_CREATE_VIEW | SQL_CV_CHECK_OPTION |
SQL_CV_CASCADED);
else
MYINFO_SET_ULONG(0);
case SQL_CURSOR_COMMIT_BEHAVIOR:
case SQL_CURSOR_ROLLBACK_BEHAVIOR:
MYINFO_SET_USHORT(SQL_CB_PRESERVE);
#ifdef SQL_CURSOR_SENSITIVITY
case SQL_CURSOR_SENSITIVITY:
MYINFO_SET_ULONG(SQL_UNSPECIFIED);
#endif
#ifdef SQL_CURSOR_ROLLBACK_SQL_CURSOR_SENSITIVITY
case SQL_CURSOR_ROLLBACK_SQL_CURSOR_SENSITIVITY:
MYINFO_SET_ULONG(SQL_UNSPECIFIED);
#endif
case SQL_DATA_SOURCE_NAME:
MYINFO_SET_STR(dbc->ds->opt_DSN);
case SQL_DATA_SOURCE_READ_ONLY:
MYINFO_SET_STR("N");
case SQL_DATABASE_NAME:
if (dbc->connection_proxy->is_connected() && reget_current_catalog(dbc))
return dbc->set_error("HY000",
"SQLGetInfo() failed to return current catalog.",
0);
MYINFO_SET_STR(!dbc->database.empty() ? dbc->database.c_str() : "null");
case SQL_DATETIME_LITERALS:
MYINFO_SET_ULONG(SQL_DL_SQL92_DATE | SQL_DL_SQL92_TIME |
SQL_DL_SQL92_TIMESTAMP);
case SQL_DBMS_NAME:
MYINFO_SET_STR("MySQL");
case SQL_DBMS_VER:
/** @todo technically this is not right: should be ##.##.#### */
MYINFO_SET_STR(dbc->connection_proxy->get_server_version());
case SQL_DDL_INDEX:
MYINFO_SET_ULONG(SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX);
case SQL_DEFAULT_TXN_ISOLATION:
MYINFO_SET_ULONG(DEFAULT_TXN_ISOLATION);
case SQL_DESCRIBE_PARAMETER:
MYINFO_SET_STR("N");
case SQL_DRIVER_NAME:
#ifdef MYODBC_UNICODEDRIVER
# ifdef WIN32
MYINFO_SET_STR("awsmysqlodbcw.dll");
# else
MYINFO_SET_STR("awsmysqlodbcw.so");
# endif
#else
# ifdef WIN32
MYINFO_SET_STR("awsmysqlodbca.dll");
# else
MYINFO_SET_STR("awsmysqlodbca.so");
# endif
#endif
case SQL_DRIVER_ODBC_VER:
MYINFO_SET_STR("03.80"); /* What standard we implement */
case SQL_DRIVER_VER:
MYINFO_SET_STR(DRIVER_VERSION);
case SQL_DROP_ASSERTION:
case SQL_DROP_CHARACTER_SET:
case SQL_DROP_COLLATION:
case SQL_DROP_DOMAIN:
case SQL_DROP_SCHEMA:
case SQL_DROP_TRANSLATION:
MYINFO_SET_ULONG(0);
case SQL_DROP_TABLE:
MYINFO_SET_ULONG(SQL_DT_DROP_TABLE | SQL_DT_CASCADE | SQL_DT_RESTRICT);
case SQL_DROP_VIEW:
if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.0"))
MYINFO_SET_ULONG(SQL_DV_DROP_VIEW | SQL_DV_CASCADE | SQL_DV_RESTRICT);
else
MYINFO_SET_ULONG(0);
case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
if (!dbc->ds->opt_FORWARD_CURSOR &&
dbc->ds->opt_DYNAMIC_CURSOR)
MYINFO_SET_ULONG(SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | SQL_CA1_RELATIVE |
SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION |
SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE |
SQL_CA1_POS_REFRESH | SQL_CA1_POSITIONED_UPDATE |
SQL_CA1_POSITIONED_DELETE | SQL_CA1_BULK_ADD);
else
MYINFO_SET_ULONG(0);
case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
if (!dbc->ds->opt_FORWARD_CURSOR &&
dbc->ds->opt_DYNAMIC_CURSOR)
MYINFO_SET_ULONG(SQL_CA2_SENSITIVITY_ADDITIONS |
SQL_CA2_SENSITIVITY_DELETIONS |
SQL_CA2_SENSITIVITY_UPDATES |
SQL_CA2_MAX_ROWS_SELECT | SQL_CA2_MAX_ROWS_INSERT |
SQL_CA2_MAX_ROWS_DELETE | SQL_CA2_MAX_ROWS_UPDATE |
SQL_CA2_CRC_EXACT | SQL_CA2_SIMULATE_TRY_UNIQUE);
else
MYINFO_SET_ULONG(0);
case SQL_EXPRESSIONS_IN_ORDERBY:
MYINFO_SET_STR("Y");
case SQL_FILE_USAGE:
MYINFO_SET_USHORT(SQL_FILE_NOT_SUPPORTED);
case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
MYINFO_SET_ULONG(dbc->ds->opt_FORWARD_CURSOR ?
SQL_CA1_NEXT :
SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | SQL_CA1_RELATIVE |
SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION |
SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE |
SQL_CA1_POS_REFRESH | SQL_CA1_POSITIONED_UPDATE |
SQL_CA1_POSITIONED_DELETE | SQL_CA1_BULK_ADD);
case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
MYINFO_SET_ULONG(SQL_CA2_MAX_ROWS_SELECT | SQL_CA2_MAX_ROWS_INSERT |
SQL_CA2_MAX_ROWS_DELETE | SQL_CA2_MAX_ROWS_UPDATE |
(dbc->ds->opt_FORWARD_CURSOR ?
0 : SQL_CA2_CRC_EXACT));
case SQL_GETDATA_EXTENSIONS:
#ifndef USE_IODBC
MYINFO_SET_ULONG(SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BLOCK |
SQL_GD_BOUND | SQL_GD_OUTPUT_PARAMS);
#else
MYINFO_SET_ULONG(SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BLOCK |
SQL_GD_BOUND);
#endif
case SQL_GROUP_BY:
MYINFO_SET_USHORT(SQL_GB_NO_RELATION);
case SQL_IDENTIFIER_CASE:
MYINFO_SET_USHORT(SQL_IC_MIXED);
case SQL_IDENTIFIER_QUOTE_CHAR:
MYINFO_SET_STR("`");
case SQL_INDEX_KEYWORDS:
MYINFO_SET_ULONG(SQL_IK_ALL);
case SQL_INFO_SCHEMA_VIEWS:
/*
We have INFORMATION_SCHEMA.SCHEMATA, but we don't report it
because the driver exposes databases (schema) as catalogs.
*/
if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.1"))
MYINFO_SET_ULONG(SQL_ISV_CHARACTER_SETS | SQL_ISV_COLLATIONS |
SQL_ISV_COLUMN_PRIVILEGES | SQL_ISV_COLUMNS |
SQL_ISV_KEY_COLUMN_USAGE |
SQL_ISV_REFERENTIAL_CONSTRAINTS |
/* SQL_ISV_SCHEMATA | */ SQL_ISV_TABLE_CONSTRAINTS |
SQL_ISV_TABLE_PRIVILEGES | SQL_ISV_TABLES |
SQL_ISV_VIEWS);
else if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.0"))
MYINFO_SET_ULONG(SQL_ISV_CHARACTER_SETS | SQL_ISV_COLLATIONS |
SQL_ISV_COLUMN_PRIVILEGES | SQL_ISV_COLUMNS |
SQL_ISV_KEY_COLUMN_USAGE | /* SQL_ISV_SCHEMATA | */
SQL_ISV_TABLE_CONSTRAINTS | SQL_ISV_TABLE_PRIVILEGES |
SQL_ISV_TABLES | SQL_ISV_VIEWS);
else
MYINFO_SET_ULONG(0);
case SQL_INSERT_STATEMENT:
MYINFO_SET_ULONG(SQL_IS_INSERT_LITERALS | SQL_IS_INSERT_SEARCHED |
SQL_IS_SELECT_INTO);
case SQL_INTEGRITY:
MYINFO_SET_STR("N");
case SQL_KEYSET_CURSOR_ATTRIBUTES1:
case SQL_KEYSET_CURSOR_ATTRIBUTES2:
MYINFO_SET_ULONG(0);
case SQL_KEYWORDS:
/*
These lists were generated by taking the list of reserved words from
the MySQL Reference Manual (which is, in turn, generated from the source)
with the pre-reserved ODBC keywords removed.
*/
if (is_minimum_version(dbc->connection_proxy->get_server_version(), "8.0.22"))
MYINFO_SET_STR("ACCESSIBLE,ANALYZE,ASENSITIVE,BEFORE,BIGINT,BINARY,BLOB,"
"CALL,CHANGE,CONDITION,DATABASE,DATABASES,DAY_HOUR,"
"DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DELAYED,"
"DETERMINISTIC,DISTINCTROW,DIV,DUAL,EACH,ELSEIF,ENCLOSED,"
"ESCAPED,EXIT,EXPLAIN,FLOAT4,FLOAT8,FORCE,FULLTEXT,GENERAL,"
"GET,HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,"
"HOUR_SECOND,IF,IGNORE,IGNORE_SERVER_IDS,INFILE,INOUT,INT1,"
"INT2,INT3,INT4,INT8,IO_AFTER_GTIDS,IO_BEFORE_GTIDS,"
"ITERATE,KEYS,KILL,LEAVE,LIMIT,LINEAR,LINES,LOAD,LOCALTIME,"
"LOCALTIMESTAMP,LOCK,LONG,LONGBLOB,LONGTEXT,LOOP,"
"LOW_PRIORITY,SOURCE_BIND,SOURCE_HEARTBEAT_PERIOD,"
"SOURCE_SSL_VERIFY_SERVER_CERT,MAXVALUE,MEDIUMBLOB,"
"MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,"
"MINUTE_SECOND,MOD,MODIFIES,NO_WRITE_TO_BINLOG,NONBLOCKING,ONE_SHOT,"
"OPTIMIZE,OPTIONALLY,OUT,OUTFILE,PARTITION,PURGE,RANGE,"
"READ_ONLY,READS,READ_WRITE,REGEXP,RELEASE,RENAME,REPEAT,"
"REPLACE,REQUIRE,RESIGNAL,RETURN,RLIKE,SCHEMAS,"
"SECOND_MICROSECOND,SENSITIVE,SEPARATOR,SHOW,SIGNAL,SLOW,"
"SPATIAL,SPECIFIC,SQL_AFTER_GTIDS,SQL_BEFORE_GTIDS,"
"SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQLEXCEPTION,"
"SQL_SMALL_RESULT,SSL,STARTING,STRAIGHT_JOIN,TERMINATED,"
"TINYBLOB,TINYINT,TINYTEXT,TRIGGER,UNDO,UNLOCK,UNSIGNED,"
"USE,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VARBINARY,"
"VARCHARACTER,WHILE,X509,XOR,YEAR_MONTH,ZEROFILL");
else if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.7"))
MYINFO_SET_STR("ACCESSIBLE,ANALYZE,ASENSITIVE,BEFORE,BIGINT,BINARY,BLOB,"
"CALL,CHANGE,CONDITION,DATABASE,DATABASES,DAY_HOUR,"
"DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DELAYED,"
"DETERMINISTIC,DISTINCTROW,DIV,DUAL,EACH,ELSEIF,ENCLOSED,"
"ESCAPED,EXIT,EXPLAIN,FLOAT4,FLOAT8,FORCE,FULLTEXT,GENERAL,"
"GET,HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,"
"HOUR_SECOND,IF,IGNORE,IGNORE_SERVER_IDS,INFILE,INOUT,INT1,"
"INT2,INT3,INT4,INT8,IO_AFTER_GTIDS,IO_BEFORE_GTIDS,"
"ITERATE,KEYS,KILL,LEAVE,LIMIT,LINEAR,LINES,LOAD,LOCALTIME,"
"LOCALTIMESTAMP,LOCK,LONG,LONGBLOB,LONGTEXT,LOOP,"
"LOW_PRIORITY,\x4D\x41\x53\x54\x45\x52_BIND,\x4D\x41\x53\x54\x45\x52_HEARTBEAT_PERIOD,"
"\x4D\x41\x53\x54\x45\x52_SSL_VERIFY_SERVER_CERT,MAXVALUE,MEDIUMBLOB,"
"MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,"
"MINUTE_SECOND,MOD,MODIFIES,NO_WRITE_TO_BINLOG,NONBLOCKING,ONE_SHOT,"
"OPTIMIZE,OPTIONALLY,OUT,OUTFILE,PARTITION,PURGE,RANGE,"
"READ_ONLY,READS,READ_WRITE,REGEXP,RELEASE,RENAME,REPEAT,"
"REPLACE,REQUIRE,RESIGNAL,RETURN,RLIKE,SCHEMAS,"
"SECOND_MICROSECOND,SENSITIVE,SEPARATOR,SHOW,SIGNAL,SLOW,"
"SPATIAL,SPECIFIC,SQL_AFTER_GTIDS,SQL_BEFORE_GTIDS,"
"SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQLEXCEPTION,"
"SQL_SMALL_RESULT,SSL,STARTING,STRAIGHT_JOIN,TERMINATED,"
"TINYBLOB,TINYINT,TINYTEXT,TRIGGER,UNDO,UNLOCK,UNSIGNED,"
"USE,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VARBINARY,"
"VARCHARACTER,WHILE,X509,XOR,YEAR_MONTH,ZEROFILL");
else if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.6"))
MYINFO_SET_STR("ACCESSIBLE,ANALYZE,ASENSITIVE,BEFORE,BIGINT,BINARY,BLOB,"
"CALL,CHANGE,CONDITION,DATABASE,DATABASES,DAY_HOUR,"
"DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DELAYED,"
"DETERMINISTIC,DISTINCTROW,DIV,DUAL,EACH,ELSEIF,ENCLOSED,"
"ESCAPED,EXIT,EXPLAIN,FLOAT4,FLOAT8,FORCE,FULLTEXT,GENERAL,"
"GET,HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,"
"HOUR_SECOND,IF,IGNORE,IGNORE_SERVER_IDS,INFILE,INOUT,INT1,"
"INT2,INT3,INT4,INT8,IO_AFTER_GTIDS,IO_BEFORE_GTIDS,"
"ITERATE,KEYS,KILL,LEAVE,LIMIT,LINEAR,LINES,LOAD,LOCALTIME,"
"LOCALTIMESTAMP,LOCK,LONG,LONGBLOB,LONGTEXT,LOOP,"
"LOW_PRIORITY,\x4D\x41\x53\x54\x45\x52_BIND,\x4D\x41\x53\x54\x45\x52_HEARTBEAT_PERIOD,"
"\x4D\x41\x53\x54\x45\x52_SSL_VERIFY_SERVER_CERT,MAXVALUE,MEDIUMBLOB,"
"MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,"
"MINUTE_SECOND,MOD,MODIFIES,NO_WRITE_TO_BINLOG,ONE_SHOT,"
"OPTIMIZE,OPTIONALLY,OUT,OUTFILE,PARTITION,PURGE,RANGE,"
"READ_ONLY,READS,READ_WRITE,REGEXP,RELEASE,RENAME,REPEAT,"
"REPLACE,REQUIRE,RESIGNAL,RETURN,RLIKE,SCHEMAS,"
"SECOND_MICROSECOND,SENSITIVE,SEPARATOR,SHOW,SIGNAL,SLOW,"
"SPATIAL,SPECIFIC,SQL_AFTER_GTIDS,SQL_BEFORE_GTIDS,"
"SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQLEXCEPTION,"
"SQL_SMALL_RESULT,SSL,STARTING,STRAIGHT_JOIN,TERMINATED,"
"TINYBLOB,TINYINT,TINYTEXT,TRIGGER,UNDO,UNLOCK,UNSIGNED,"
"USE,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VARBINARY,"
"VARCHARACTER,WHILE,X509,XOR,YEAR_MONTH,ZEROFILL");
else if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.5"))
MYINFO_SET_STR("ACCESSIBLE,ANALYZE,ASENSITIVE,BEFORE,BIGINT,BINARY,BLOB,"
"CALL,CHANGE,CONDITION,DATABASE,DATABASES,DAY_HOUR,"
"DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DELAYED,"
"DETERMINISTIC,DISTINCTROW,DIV,DUAL,EACH,ELSEIF,ENCLOSED,"
"ESCAPED,EXIT,EXPLAIN,FLOAT4,FLOAT8,FORCE,FULLTEXT,GENERAL,"
"HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,"
"IF,IGNORE,IGNORE_SERVER_IDS,INFILE,INOUT,INT1,INT2,INT3,"
"INT4,INT8,ITERATE,KEYS,KILL,LEAVE,LIMIT,LINEAR,LINES,"
"LOAD,LOCALTIME,LOCALTIMESTAMP,LOCK,LONG,LONGBLOB,"
"LONGTEXT,LOOP,LOW_PRIORITY,\x4D\x41\x53\x54\x45\x52_HEARTBEAT_PERIOD,"
"\x4D\x41\x53\x54\x45\x52_SSL_VERIFY_SERVER_CERT,MAXVALUE,MEDIUMBLOB,"
"MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,"
"MINUTE_SECOND,MOD,MODIFIES,NO_WRITE_TO_BINLOG,OPTIMIZE,"
"OPTIONALLY,OUT,OUTFILE,PURGE,RANGE,READ_ONLY,READS,"
"READ_WRITE,REGEXP,RELEASE,RENAME,REPEAT,REPLACE,REQUIRE,"
"RESIGNAL,RETURN,RLIKE,SCHEMAS,SECOND_MICROSECOND,"
"SENSITIVE,SEPARATOR,SHOW,SIGNAL,SLOW,SPATIAL,SPECIFIC,"
"SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQLEXCEPTION,"
"SQL_SMALL_RESULT,SSL,STARTING,STRAIGHT_JOIN,TERMINATED,"
"TINYBLOB,TINYINT,TINYTEXT,TRIGGER,UNDO,UNLOCK,UNSIGNED,"
"USE,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VARBINARY,"
"VARCHARACTER,WHILE,X509,XOR,YEAR_MONTH,ZEROFILL");
else if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.1"))
MYINFO_SET_STR("ACCESSIBLE,ANALYZE,ASENSITIVE,BEFORE,BIGINT,BINARY,BLOB,"
"CALL,CHANGE,CONDITION,DATABASE,DATABASES,DAY_HOUR,"
"DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DELAYED,"
"DETERMINISTIC,DISTINCTROW,DIV,DUAL,EACH,ELSEIF,ENCLOSED,"
"ESCAPED,EXIT,EXPLAIN,FLOAT4,FLOAT8,FORCE,FULLTEXT,"
"HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,"
"IF,IGNORE,INFILE,INOUT,INT1,INT2,INT3,INT4,INT8,ITERATE,"
"KEYS,KILL,LEAVE,LIMIT,LINEAR,LINES,LOAD,LOCALTIME,"
"LOCALTIMESTAMP,LOCK,LONG,LONGBLOB,LONGTEXT,LOOP,"
"LOW_PRIORITY,\x4D\x41\x53\x54\x45\x52_SSL_VERIFY_SERVER_CERT,MEDIUMBLOB,"
"MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,"
"MINUTE_SECOND,MOD,MODIFIES,NO_WRITE_TO_BINLOG,OPTIMIZE,"
"OPTIONALLY,OUT,OUTFILE,PURGE,RANGE,READ_ONLY,READS,"
"READ_WRITE,REGEXP,RELEASE,RENAME,REPEAT,REPLACE,REQUIRE,"
"RETURN,RLIKE,SCHEMAS,SECOND_MICROSECOND,SENSITIVE,"
"SEPARATOR,SHOW,SPATIAL,SPECIFIC,SQL_BIG_RESULT,"
"SQL_CALC_FOUND_ROWS,SQLEXCEPTION,SQL_SMALL_RESULT,SSL,"
"STARTING,STRAIGHT_JOIN,TERMINATED,TINYBLOB,TINYINT,"
"TINYTEXT,TRIGGER,UNDO,UNLOCK,UNSIGNED,USE,UTC_DATE,"
"UTC_TIME,UTC_TIMESTAMP,VARBINARY,VARCHARACTER,WHILE,X509,"
"XOR,YEAR_MONTH,ZEROFILL");
else if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.0"))
MYINFO_SET_STR("ANALYZE,ASENSITIVE,BEFORE,BIGINT,BINARY,BLOB,CALL,CHANGE,"
"CONDITION,DATABASE,DATABASES,DAY_HOUR,DAY_MICROSECOND,"
"DAY_MINUTE,DAY_SECOND,DELAYED,DETERMINISTIC,DISTINCTROW,"
"DIV,DUAL,EACH,ELSEIF,ENCLOSED,ESCAPED,EXIT,EXPLAIN,"
"FLOAT4,FLOAT8,FORCE,FULLTEXT,HIGH_PRIORITY,"
"HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,IF,IGNORE,"
"INFILE,INOUT,INT1,INT2,INT3,INT4,INT8,ITERATE,KEYS,KILL,"
"LEAVE,LIMIT,LINES,LOAD,LOCALTIME,LOCALTIMESTAMP,LOCK,"
"LONG,LONGBLOB,LONGTEXT,LOOP,LOW_PRIORITY,MEDIUMBLOB,"
"MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,"
"MINUTE_SECOND,MOD,MODIFIES,NO_WRITE_TO_BINLOG,OPTIMIZE,"
"OPTIONALLY,OUT,OUTFILE,PURGE,RAID0,READS,REGEXP,RELEASE,"
"RENAME,REPEAT,REPLACE,REQUIRE,RETURN,RLIKE,SCHEMAS,"
"SECOND_MICROSECOND,SENSITIVE,SEPARATOR,SHOW,SONAME,"
"SPATIAL,SPECIFIC,SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,"
"SQLEXCEPTION,SQL_SMALL_RESULT,SSL,STARTING,STRAIGHT_JOIN,"
"TERMINATED,TINYBLOB,TINYINT,TINYTEXT,TRIGGER,UNDO,UNLOCK,"
"UNSIGNED,USE,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VARBINARY,"
"VARCHARACTER,WHILE,X509,XOR,YEAR_MONTH,ZEROFILL");
else
MYINFO_SET_STR("ANALYZE,BEFORE,BIGINT,BINARY,BLOB,CHANGE,COLUMNS,"
"DATABASE,DATABASES,DAY_HOUR,DAY_MICROSECOND,DAY_MINUTE,"
"DAY_SECOND,DELAYED,DISTINCTROW,DIV,DUAL,ENCLOSED,ESCAPED,"
"EXPLAIN,FIELDS,FLOAT4,FLOAT8,FORCE,FULLTEXT,"
"HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,"
"IF,IGNORE,INFILE,INT1,INT2,INT3,INT4,INT8,KEYS,KILL,"
"LIMIT,LINES,LOAD,LOCALTIME,LOCALTIMESTAMP,LOCK,LONG,"
"LONGBLOB,LONGTEXT,LOW_PRIORITY,MEDIUMBLOB,MEDIUMINT,"
"MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,MINUTE_SECOND,"
"MOD,NO_WRITE_TO_BINLOG,OPTIMIZE,OPTIONALLY,OUTFILE,PURGE,"
"RAID0,REGEXP,RENAME,REPLACE,REQUIRE,RLIKE,"
"SECOND_MICROSECOND,SEPARATOR,SHOW,SONAME,SPATIAL,"
"SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQL_SMALL_RESULT,SSL,"
"STARTING,STRAIGHT_JOIN,TABLES,TERMINATED,TINYBLOB,"
"TINYINT,TINYTEXT,UNLOCK,UNSIGNED,USE,UTC_DATE,UTC_TIME,"
"UTC_TIMESTAMP,VARBINARY,VARCHARACTER,X509,XOR,YEAR_MONTH,"
"ZEROFILL");
case SQL_LIKE_ESCAPE_CLAUSE:
MYINFO_SET_STR("Y");
case SQL_MAX_ASYNC_CONCURRENT_STATEMENTS:
MYINFO_SET_ULONG(0);
case SQL_MAX_BINARY_LITERAL_LEN:
MYINFO_SET_ULONG(0);
// SQL_MAX_QUALIFIER_NAME_LEN is also defined as SQL_MAX_CATALOG_NAME_LEN
case SQL_MAX_CATALOG_NAME_LEN:
if (!dbc->ds->opt_NO_CATALOG)
MYINFO_SET_USHORT(64);
else
MYINFO_SET_USHORT(0);
case SQL_MAX_CHAR_LITERAL_LEN:
MYINFO_SET_ULONG(0);
case SQL_MAX_COLUMN_NAME_LEN:
MYINFO_SET_USHORT(NAME_LEN);
case SQL_MAX_COLUMNS_IN_GROUP_BY:
MYINFO_SET_USHORT(0); /* No specific limit */
case SQL_MAX_COLUMNS_IN_INDEX:
MYINFO_SET_USHORT(32);
case SQL_MAX_COLUMNS_IN_ORDER_BY:
MYINFO_SET_USHORT(0); /* No specific limit */
case SQL_MAX_COLUMNS_IN_SELECT:
MYINFO_SET_USHORT(0); /* No specific limit */
case SQL_MAX_COLUMNS_IN_TABLE:
MYINFO_SET_USHORT(0); /* No specific limit */
// SQL_ACTIVE_STATEMENTS in ODBC v1 has the same definition as
// SQL_MAX_CONCURRENT_ACTIVITIES in ODBC v3.
case SQL_MAX_CONCURRENT_ACTIVITIES:
// TODO: Fix Bug#34916959
MYINFO_SET_USHORT(0); /* No specific limit */
case SQL_MAX_CURSOR_NAME_LEN:
MYINFO_SET_USHORT(MYSQL_MAX_CURSOR_LEN);
case SQL_MAX_DRIVER_CONNECTIONS:
MYINFO_SET_USHORT(0); /* No specific limit */
case SQL_MAX_IDENTIFIER_LEN:
MYINFO_SET_USHORT(NAME_LEN);
case SQL_MAX_INDEX_SIZE:
if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.0"))
MYINFO_SET_USHORT(3072);
else
MYINFO_SET_USHORT(1024);
case SQL_MAX_PROCEDURE_NAME_LEN:
MYINFO_SET_USHORT(NAME_LEN);
case SQL_MAX_ROW_SIZE:
MYINFO_SET_ULONG(0); /* No specific limit */
case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
MYINFO_SET_STR("Y");
// SQL_MAX_OWNER_NAME_LEN is also defined as SQL_MAX_SCHEMA_NAME_LEN
case SQL_MAX_SCHEMA_NAME_LEN:
if (!dbc->ds->opt_NO_SCHEMA)
MYINFO_SET_USHORT(64);
else
MYINFO_SET_USHORT(0);
case SQL_MAX_STATEMENT_LEN:
MYINFO_SET_ULONG(dbc->net_buffer_len);
case SQL_MAX_TABLE_NAME_LEN:
MYINFO_SET_USHORT(NAME_LEN);
case SQL_MAX_TABLES_IN_SELECT:
if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.0"))
MYINFO_SET_USHORT(63);
else
MYINFO_SET_USHORT(31);
case SQL_MAX_USER_NAME_LEN:
MYINFO_SET_USHORT(USERNAME_LENGTH);
case SQL_MULT_RESULT_SETS:
MYINFO_SET_STR("Y");
case SQL_MULTIPLE_ACTIVE_TXN:
MYINFO_SET_STR("Y");
case SQL_NEED_LONG_DATA_LEN:
MYINFO_SET_STR("N");
case SQL_NON_NULLABLE_COLUMNS:
MYINFO_SET_USHORT(SQL_NNC_NON_NULL);
case SQL_NULL_COLLATION:
MYINFO_SET_USHORT(SQL_NC_LOW);
case SQL_NUMERIC_FUNCTIONS:
MYINFO_SET_ULONG(SQL_FN_NUM_ABS | SQL_FN_NUM_ACOS | SQL_FN_NUM_ASIN |
SQL_FN_NUM_ATAN | SQL_FN_NUM_ATAN2 | SQL_FN_NUM_CEILING |
SQL_FN_NUM_COS | SQL_FN_NUM_COT | SQL_FN_NUM_EXP |
SQL_FN_NUM_FLOOR | SQL_FN_NUM_LOG | SQL_FN_NUM_MOD |
SQL_FN_NUM_SIGN | SQL_FN_NUM_SIN | SQL_FN_NUM_SQRT |
SQL_FN_NUM_TAN | SQL_FN_NUM_PI | SQL_FN_NUM_RAND |
SQL_FN_NUM_DEGREES | SQL_FN_NUM_LOG10 | SQL_FN_NUM_POWER |
SQL_FN_NUM_RADIANS | SQL_FN_NUM_ROUND |
SQL_FN_NUM_TRUNCATE);
case SQL_ODBC_API_CONFORMANCE:
MYINFO_SET_USHORT(SQL_OAC_LEVEL1);
case SQL_ODBC_INTERFACE_CONFORMANCE:
MYINFO_SET_ULONG(SQL_OIC_LEVEL1);
case SQL_ODBC_SQL_CONFORMANCE:
MYINFO_SET_USHORT(SQL_OSC_CORE);
case SQL_OJ_CAPABILITIES:
MYINFO_SET_ULONG(SQL_OJ_LEFT | SQL_OJ_RIGHT | SQL_OJ_NESTED |
SQL_OJ_NOT_ORDERED | SQL_OJ_INNER |
SQL_OJ_ALL_COMPARISON_OPS);
case SQL_ORDER_BY_COLUMNS_IN_SELECT:
MYINFO_SET_STR("N");
case SQL_PARAM_ARRAY_ROW_COUNTS:
MYINFO_SET_ULONG(SQL_PARC_NO_BATCH);
case SQL_PARAM_ARRAY_SELECTS:
MYINFO_SET_ULONG(SQL_PAS_NO_BATCH);
case SQL_PROCEDURE_TERM:
if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.0"))
MYINFO_SET_STR("stored procedure");
else
MYINFO_SET_STR("");
case SQL_PROCEDURES:
if (is_minimum_version(dbc->connection_proxy->get_server_version(), "5.0"))
MYINFO_SET_STR("Y");
else
MYINFO_SET_STR("N");
case SQL_POS_OPERATIONS:
if (dbc->ds->opt_FORWARD_CURSOR)
MYINFO_SET_ULONG(0);
else
MYINFO_SET_ULONG(SQL_POS_POSITION | SQL_POS_UPDATE | SQL_POS_DELETE |
SQL_POS_ADD | SQL_POS_REFRESH);
case SQL_QUOTED_IDENTIFIER_CASE:
MYINFO_SET_USHORT(SQL_IC_SENSITIVE);
case SQL_ROW_UPDATES:
MYINFO_SET_STR("N");
case SQL_SCHEMA_TERM:
MYINFO_SET_STR((dbc->ds->opt_NO_SCHEMA) ? "" : "database");
case SQL_SCHEMA_USAGE:
if (!dbc->ds->opt_NO_SCHEMA)
MYINFO_SET_ULONG(SQL_SU_DML_STATEMENTS | SQL_SU_PROCEDURE_INVOCATION |
SQL_SU_TABLE_DEFINITION | SQL_SU_INDEX_DEFINITION |
SQL_SU_PRIVILEGE_DEFINITION);
else
MYINFO_SET_ULONG(0);
case SQL_SCROLL_OPTIONS:
MYINFO_SET_ULONG(SQL_SO_FORWARD_ONLY |
(dbc->ds->opt_FORWARD_CURSOR ?
0 : SQL_SO_STATIC |
(dbc->ds->opt_DYNAMIC_CURSOR ? SQL_SO_DYNAMIC : 0)));
case SQL_SEARCH_PATTERN_ESCAPE:
MYINFO_SET_STR("\\");
case SQL_SERVER_NAME:
MYINFO_SET_STR(dbc->connection_proxy->get_host_info());
case SQL_SPECIAL_CHARACTERS:
/* We can handle anything but / and \xff. */
MYINFO_SET_STR(" !\"#%&'()*+,-.:;<=>?@[\\]^`{|}~");
case SQL_SQL_CONFORMANCE:
MYINFO_SET_ULONG(SQL_SC_SQL92_INTERMEDIATE);
case SQL_SQL92_DATETIME_FUNCTIONS:
MYINFO_SET_ULONG(SQL_SDF_CURRENT_DATE | SQL_SDF_CURRENT_TIME |
SQL_SDF_CURRENT_TIMESTAMP);
case SQL_SQL92_FOREIGN_KEY_DELETE_RULE:
case SQL_SQL92_FOREIGN_KEY_UPDATE_RULE:
MYINFO_SET_ULONG(0);
case SQL_SQL92_GRANT:
MYINFO_SET_ULONG(SQL_SG_DELETE_TABLE | SQL_SG_INSERT_COLUMN |
SQL_SG_INSERT_TABLE | SQL_SG_REFERENCES_TABLE |
SQL_SG_REFERENCES_COLUMN | SQL_SG_SELECT_TABLE |
SQL_SG_UPDATE_COLUMN | SQL_SG_UPDATE_TABLE |
SQL_SG_WITH_GRANT_OPTION);
case SQL_SQL92_NUMERIC_VALUE_FUNCTIONS:
MYINFO_SET_ULONG(SQL_SNVF_BIT_LENGTH | SQL_SNVF_CHAR_LENGTH |
SQL_SNVF_CHARACTER_LENGTH | SQL_SNVF_EXTRACT |
SQL_SNVF_OCTET_LENGTH | SQL_SNVF_POSITION);
case SQL_SQL92_PREDICATES:
MYINFO_SET_ULONG(SQL_SP_BETWEEN | SQL_SP_COMPARISON | SQL_SP_EXISTS |
SQL_SP_IN | SQL_SP_ISNOTNULL | SQL_SP_ISNULL |
SQL_SP_LIKE /*| SQL_SP_MATCH_FULL |SQL_SP_MATCH_PARTIAL |
SQL_SP_MATCH_UNIQUE_FULL | SQL_SP_MATCH_UNIQUE_PARTIAL |
SQL_SP_OVERLAPS */ | SQL_SP_QUANTIFIED_COMPARISON /*|
SQL_SP_UNIQUE */);
case SQL_SQL92_RELATIONAL_JOIN_OPERATORS:
MYINFO_SET_ULONG(SQL_SRJO_CROSS_JOIN | SQL_SRJO_INNER_JOIN |
SQL_SRJO_LEFT_OUTER_JOIN | SQL_SRJO_NATURAL_JOIN |
SQL_SRJO_RIGHT_OUTER_JOIN);
case SQL_SQL92_REVOKE:
MYINFO_SET_ULONG(SQL_SR_DELETE_TABLE | SQL_SR_INSERT_COLUMN |
SQL_SR_INSERT_TABLE | SQL_SR_REFERENCES_TABLE |
SQL_SR_REFERENCES_COLUMN | SQL_SR_SELECT_TABLE |
SQL_SR_UPDATE_COLUMN | SQL_SR_UPDATE_TABLE);
case SQL_SQL92_ROW_VALUE_CONSTRUCTOR:
MYINFO_SET_ULONG(SQL_SRVC_VALUE_EXPRESSION | SQL_SRVC_NULL |
SQL_SRVC_DEFAULT | SQL_SRVC_ROW_SUBQUERY);
case SQL_SQL92_STRING_FUNCTIONS:
MYINFO_SET_ULONG(SQL_SSF_CONVERT | SQL_SSF_LOWER | SQL_SSF_UPPER |
SQL_SSF_SUBSTRING | SQL_SSF_TRANSLATE | SQL_SSF_TRIM_BOTH |
SQL_SSF_TRIM_LEADING | SQL_SSF_TRIM_TRAILING);
case SQL_SQL92_VALUE_EXPRESSIONS:
MYINFO_SET_ULONG(SQL_SVE_CASE | SQL_SVE_CAST | SQL_SVE_COALESCE |
SQL_SVE_NULLIF);
case SQL_STANDARD_CLI_CONFORMANCE:
MYINFO_SET_ULONG(SQL_SCC_ISO92_CLI);
case SQL_STATIC_CURSOR_ATTRIBUTES1:
MYINFO_SET_ULONG(SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | SQL_CA1_RELATIVE |
SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION |
SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE |
SQL_CA1_POS_REFRESH | SQL_CA1_POSITIONED_UPDATE |
SQL_CA1_POSITIONED_DELETE | SQL_CA1_BULK_ADD);
case SQL_STATIC_CURSOR_ATTRIBUTES2:
MYINFO_SET_ULONG(SQL_CA2_MAX_ROWS_SELECT | SQL_CA2_MAX_ROWS_INSERT |
SQL_CA2_MAX_ROWS_DELETE | SQL_CA2_MAX_ROWS_UPDATE |
SQL_CA2_CRC_EXACT);
case SQL_STRING_FUNCTIONS:
MYINFO_SET_ULONG(SQL_FN_STR_ASCII | SQL_FN_STR_BIT_LENGTH |
SQL_FN_STR_CHAR | SQL_FN_STR_CHAR_LENGTH |
SQL_FN_STR_CONCAT | SQL_FN_STR_INSERT | SQL_FN_STR_LCASE |
SQL_FN_STR_LEFT | SQL_FN_STR_LENGTH | SQL_FN_STR_LOCATE |
SQL_FN_STR_LOCATE_2 | SQL_FN_STR_LTRIM |
SQL_FN_STR_OCTET_LENGTH | SQL_FN_STR_POSITION |
SQL_FN_STR_REPEAT | SQL_FN_STR_REPLACE | SQL_FN_STR_RIGHT |
SQL_FN_STR_RTRIM | SQL_FN_STR_SOUNDEX | SQL_FN_STR_SPACE |
SQL_FN_STR_SUBSTRING | SQL_FN_STR_UCASE);
case SQL_SUBQUERIES:
MYINFO_SET_ULONG(SQL_SQ_CORRELATED_SUBQUERIES | SQL_SQ_COMPARISON |
SQL_SQ_EXISTS | SQL_SQ_IN | SQL_SQ_QUANTIFIED);
case SQL_SYSTEM_FUNCTIONS:
MYINFO_SET_ULONG(SQL_FN_SYS_DBNAME | SQL_FN_SYS_IFNULL |
SQL_FN_SYS_USERNAME);
case SQL_TABLE_TERM:
MYINFO_SET_STR("table");
case SQL_TIMEDATE_ADD_INTERVALS:
case SQL_TIMEDATE_DIFF_INTERVALS:
MYINFO_SET_ULONG(0);
case SQL_TIMEDATE_FUNCTIONS:
MYINFO_SET_ULONG(SQL_FN_TD_CURRENT_DATE | SQL_FN_TD_CURRENT_TIME |
SQL_FN_TD_CURRENT_TIMESTAMP | SQL_FN_TD_CURDATE |
SQL_FN_TD_CURTIME | SQL_FN_TD_DAYNAME |
SQL_FN_TD_DAYOFMONTH | SQL_FN_TD_DAYOFWEEK |
SQL_FN_TD_DAYOFYEAR | SQL_FN_TD_EXTRACT | SQL_FN_TD_HOUR |
/* SQL_FN_TD_JULIAN_DAY | */ SQL_FN_TD_MINUTE |
SQL_FN_TD_MONTH | SQL_FN_TD_MONTHNAME | SQL_FN_TD_NOW |
SQL_FN_TD_QUARTER | SQL_FN_TD_SECOND |
/*SQL_FN_TD_SECONDS_SINCE_MIDNIGHT | */
SQL_FN_TD_TIMESTAMPADD | SQL_FN_TD_TIMESTAMPDIFF |
SQL_FN_TD_WEEK | SQL_FN_TD_YEAR);
case SQL_TXN_CAPABLE:
if (trans_supported(dbc) && (!dbc->ds->opt_NO_TRANSACTIONS))
MYINFO_SET_USHORT(SQL_TC_DDL_COMMIT);
else
MYINFO_SET_USHORT(SQL_TC_NONE);
case SQL_TXN_ISOLATION_OPTION:
if (!trans_supported(dbc) || (dbc->ds->opt_NO_TRANSACTIONS))
MYINFO_SET_ULONG(SQL_TXN_READ_COMMITTED);
else
MYINFO_SET_ULONG(SQL_TXN_READ_COMMITTED | SQL_TXN_READ_UNCOMMITTED |
SQL_TXN_REPEATABLE_READ | SQL_TXN_SERIALIZABLE);
case SQL_UNION:
MYINFO_SET_ULONG(SQL_U_UNION | SQL_U_UNION_ALL);
case SQL_USER_NAME:
MYINFO_SET_STR(dbc->ds->opt_UID);
case SQL_XOPEN_CLI_YEAR:
MYINFO_SET_STR("1992");
/* The following aren't listed in the MSDN documentation. */
case SQL_ACCESSIBLE_PROCEDURES:
case SQL_ACCESSIBLE_TABLES:
MYINFO_SET_STR("N");
case SQL_LOCK_TYPES:
MYINFO_SET_ULONG(0);
case SQL_OUTER_JOINS:
MYINFO_SET_STR("Y");
case SQL_POSITIONED_STATEMENTS:
if (dbc->ds->opt_FORWARD_CURSOR)
MYINFO_SET_ULONG(0);
else
MYINFO_SET_ULONG(SQL_PS_POSITIONED_DELETE | SQL_PS_POSITIONED_UPDATE);
case SQL_SCROLL_CONCURRENCY:
/** @todo this is wrong. */
MYINFO_SET_ULONG(SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES);
case SQL_STATIC_SENSITIVITY:
MYINFO_SET_ULONG(SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES);
case SQL_FETCH_DIRECTION:
if (dbc->ds->opt_FORWARD_CURSOR)
MYINFO_SET_ULONG(SQL_FD_FETCH_NEXT);
else
MYINFO_SET_ULONG(SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
SQL_FD_FETCH_LAST |
(dbc->ds->opt_NO_DEFAULT_CURSOR ? 0 : SQL_FD_FETCH_PRIOR) |
SQL_FD_FETCH_ABSOLUTE | SQL_FD_FETCH_RELATIVE);
case SQL_ODBC_SAG_CLI_CONFORMANCE:
MYINFO_SET_USHORT(SQL_OSCC_COMPLIANT);
default:
{
char buff[80];
myodbc_snprintf(buff, sizeof(buff),
"Unsupported option: %d to SQLGetInfo",
fInfoType);
return ((DBC*)hdbc)->set_error(MYERR_S1C00, buff, 4000);
}
}
}
/*
Function sets up a result set containing details of the types
supported by mysql.
*/
MYSQL_FIELD SQL_GET_TYPE_INFO_fields[] =
{
MYODBC_FIELD_STRING("TYPE_NAME", 32, NOT_NULL_FLAG),
MYODBC_FIELD_SHORT("DATA_TYPE", NOT_NULL_FLAG),
MYODBC_FIELD_LONG("COLUMN_SIZE", 0),
MYODBC_FIELD_STRING("LITERAL_PREFIX", 2, 0),
MYODBC_FIELD_STRING("LITERAL_SUFFIX", 1, 0),
MYODBC_FIELD_STRING("CREATE_PARAMS", 15, 0),
MYODBC_FIELD_SHORT("NULLABLE", NOT_NULL_FLAG),
MYODBC_FIELD_SHORT("CASE_SENSITIVE", NOT_NULL_FLAG),
MYODBC_FIELD_SHORT("SEARCHABLE", NOT_NULL_FLAG),
MYODBC_FIELD_SHORT("UNSIGNED_ATTRIBUTE", 0),
MYODBC_FIELD_SHORT("FIXED_PREC_SCALE", NOT_NULL_FLAG),
MYODBC_FIELD_SHORT("AUTO_UNIQUE_VALUE", 0),
MYODBC_FIELD_STRING("LOCAL_TYPE_NAME", 60, 0),
MYODBC_FIELD_SHORT("MINIMUM_SCALE", 0),
MYODBC_FIELD_SHORT("MAXIMUM_SCALE", 0),
MYODBC_FIELD_SHORT("SQL_DATATYPE", NOT_NULL_FLAG),
MYODBC_FIELD_SHORT("SQL_DATETIME_SUB", 0),
MYODBC_FIELD_LONG("NUM_PREC_RADIX", 0),
MYODBC_FIELD_SHORT("INTERVAL_PRECISION", 0),
};
const uint SQL_GET_TYPE_INFO_FIELDS = (uint)array_elements(SQL_GET_TYPE_INFO_fields);
#define MYSQL_DATA_TYPES 61
char sql_searchable[6], sql_unsearchable[6], sql_nullable[6], sql_no_nulls[6],
sql_bit[6], sql_tinyint[6], sql_smallint[6], sql_integer[6], sql_bigint[6],
sql_float[6], sql_real[6], sql_double[6], sql_char[6], sql_varchar[6],
sql_longvarchar[6], sql_timestamp[6], sql_decimal[6], sql_numeric[6],
sql_varbinary[6], sql_time[6], sql_date[6], sql_binary[6],
sql_longvarbinary[6], sql_datetime[6], sql_wchar[6], sql_wvarchar[6],
sql_wlongvarchar[6];
char *SQL_GET_TYPE_INFO_values[MYSQL_DATA_TYPES][19] =
{
/* SQL_BIT= -7 */
{ "bit",sql_bit,"1","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"bit",NULL,NULL,sql_bit,NULL,NULL,NULL },
/* SQL_TINY= -6 */
{ "tinyint",sql_tinyint,"3","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","tinyint",NULL,NULL,sql_tinyint,NULL,"10",NULL },
{ "tinyint unsigned",sql_tinyint,"3","'","'",NULL,sql_nullable,"0",sql_searchable,"1","0","0","tinyint unsigned",NULL,NULL,sql_tinyint,NULL,"10",NULL },
{ "tinyint auto_increment",sql_tinyint,"3","'","'",NULL,sql_no_nulls,"0",sql_searchable,"0","0","1","tinyint auto_increment",NULL,NULL,sql_tinyint, NULL,"10",NULL },
{ "tinyint unsigned auto_increment",sql_tinyint,"3","'","'",NULL,sql_no_nulls, "0",sql_searchable,"1","0","1","tinyint unsigned auto_increment",NULL,NULL, sql_tinyint,NULL,"10",NULL },
/* SQL_BIGINT= -5 */
{ "bigint",sql_bigint,"19","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","bigint",NULL,NULL,sql_bigint,NULL,"10",NULL },
{ "bigint unsigned",sql_bigint,"20","'","'",NULL,sql_nullable,"0",sql_searchable,"1","0","0","bigint unsigned",NULL,NULL,sql_bigint,NULL,"10",NULL },
{ "bigint auto_increment",sql_bigint,"19","'","'",NULL,sql_no_nulls,"0",sql_searchable,"0","0","1","bigint auto_increment",NULL,NULL,sql_bigint,NULL,"10",NULL },
{ "bigint unsigned auto_increment",sql_bigint,"20","'","'",NULL,sql_no_nulls, "0",sql_searchable,"1","0","1","bigint unsigned auto_increment",NULL,NULL,sql_bigint, NULL,"10",NULL },
/* SQL_LONGVARBINARY= -4 */
{ "long varbinary",sql_longvarbinary,"16777215","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"long varbinary",NULL,NULL,sql_longvarbinary,NULL,NULL,NULL },
{ "blob",sql_longvarbinary,"65535","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"blob",NULL,NULL,sql_longvarbinary,NULL,NULL,NULL },
{ "longblob",sql_longvarbinary,"2147483647","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"longblob",NULL,NULL,sql_longvarbinary,NULL,NULL,NULL },
{ "tinyblob",sql_longvarbinary,"255","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"tinyblob",NULL,NULL,sql_longvarbinary,NULL,NULL,NULL },
{ "mediumblob",sql_longvarbinary,"16777215","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"mediumblob",NULL,NULL,sql_longvarbinary,NULL,NULL,NULL },
/* SQL_VARBINARY= -3 */
{ "varbinary",sql_varbinary,"255","'","'","length",sql_nullable,"0",sql_searchable,NULL,"0",NULL,"varbinary",NULL,NULL,sql_varbinary,NULL,NULL,NULL },
/* SQL_BINARY= -2 */
{ "binary",sql_binary,"255","'","'","length",sql_nullable,"0",sql_searchable,NULL,"0",NULL,"binary",NULL,NULL,sql_binary,NULL,NULL,NULL },
/* SQL_LONGVARCHAR= -1 */
{ "long varchar",sql_longvarchar,"16777215","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"mediumtext",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "text",sql_longvarchar,"65535","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"text",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "mediumtext",sql_longvarchar,"16777215","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"mediumtext",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "longtext",sql_longvarchar,"2147483647","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"longtext",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "tinytext",sql_longvarchar,"255","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"tinytext",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
// For JSON maximum column length (in characters) is taken to be maximum
// octet length of LONGTEXT (4G) divided by 4 bytes/character for
// utf8mb4 encoding.
{ "json",sql_longvarchar,"1073741823","'","'",NULL,sql_nullable,"1","1",NULL,"0",NULL,"json",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "long varchar",sql_wlongvarchar,"16777215","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"mediumtext",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "text",sql_wlongvarchar,"65535","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"text",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "mediumtext",sql_wlongvarchar,"16777215","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"mediumtext",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "longtext",sql_wlongvarchar,"2147483647","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"longtext",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
{ "tinytext",sql_wlongvarchar,"255","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"tinytext",NULL,NULL,sql_longvarchar,NULL,NULL,NULL },
// For JSON maximum column length (in characters) is taken to be maximum
// octet length of LONGTEXT (4G) divided by 4 bytes/character for
// utf8mb4 encoding.
{ "json",sql_wlongvarchar,"1073741823","'","'",NULL,sql_nullable,"1","1",NULL,"0",NULL,"json",NULL,NULL,sql_wlongvarchar,NULL,NULL,NULL},
/* SQL_CHAR= 1 */
{ "char",sql_char, "255","'","'","length",sql_nullable,"0",sql_searchable,NULL,"0",NULL,"char",NULL,NULL,sql_char,"0",NULL,NULL },
{ "char",sql_wchar,"255","'","'","length",sql_nullable,"0",sql_searchable,NULL,"0",NULL,"char",NULL,NULL,sql_wchar,"0",NULL,NULL },
/* SQL_NUMERIC= 2 */
{ "numeric",sql_numeric,"19","'","'","precision,scale",sql_nullable,"0",sql_searchable,"0","0","0","numeric","0","19",sql_numeric,NULL,"10",NULL },
/* SQL_DECIMAL= 3 */
{ "decimal",sql_decimal,"19","'","'","precision,scale",sql_nullable,"0",sql_searchable,"0","0","0","decimal","0","19",sql_decimal,NULL,"10",NULL },
/* SQL_INTEGER= 4 */
{ "integer",sql_integer,"10","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","integer",NULL,NULL,sql_integer,NULL,"10",NULL },
{ "integer unsigned",sql_integer,"10","'","'",NULL,sql_nullable,"0",sql_searchable,"1","0","0","integer unsigned",NULL,NULL,sql_integer,NULL,"10",NULL },
{ "int",sql_integer,"10","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","integer",NULL,NULL,sql_integer,NULL,"10",NULL },
{ "int unsigned",sql_integer,"10","'","'",NULL,sql_nullable,"0",sql_searchable,"1","0","0","integer unsigned",NULL,NULL,sql_integer,NULL,"10",NULL },
{ "mediumint",sql_integer,"7","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","Medium integer",NULL,NULL,sql_integer,NULL,"10",NULL },
{ "mediumint unsigned",sql_integer,"8","'","'",NULL,sql_nullable,"0",sql_searchable,"1","0","0","Medium integer unsigned",NULL,NULL,sql_integer,NULL,"10",NULL },
{ "integer auto_increment",sql_integer,"10","'","'",NULL,sql_no_nulls,"0",sql_searchable,"0","0","1","integer auto_increment",NULL,NULL,sql_integer, NULL,"10",NULL },
{ "integer unsigned auto_increment",sql_integer,"10","'","'",NULL,sql_no_nulls, "0",sql_searchable,"1","0","1","integer unsigned auto_increment",NULL,NULL, sql_integer,NULL,"10",NULL },
{ "int auto_increment",sql_integer,"10","'","'",NULL,sql_no_nulls,"0",sql_searchable,"0","0","1","integer auto_increment",NULL,NULL,sql_integer, NULL,"10",NULL },
{ "int unsigned auto_increment",sql_integer,"10","'","'",NULL,sql_no_nulls,"0",sql_searchable,"1","0","1","integer unsigned auto_increment",NULL,NULL,sql_integer,NULL,"10",NULL },
{ "mediumint auto_increment",sql_integer,"7","'","'",NULL,sql_no_nulls,"0",sql_searchable,"0","0","1","Medium integer auto_increment",NULL,NULL,sql_integer,NULL,"10",NULL },
{ "mediumint unsigned auto_increment",sql_integer,"8","'","'",NULL,sql_no_nulls, "0",sql_searchable,"1","0","1","Medium integer unsigned auto_increment",NULL,NULL, sql_integer,NULL,"10",NULL },
/* SQL_SMALLINT= 5 */
{ "smallint",sql_smallint,"5","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","smallint",NULL,NULL,sql_smallint,NULL,"10",NULL },
{ "smallint unsigned",sql_smallint,"5","'","'",NULL,sql_nullable,"0",sql_searchable,"1","0","0","smallint unsigned",NULL,NULL,sql_smallint,NULL,"10",NULL },
{ "smallint auto_increment",sql_smallint,"5","'","'",NULL,sql_no_nulls,"0",sql_searchable,"0","0","1","smallint auto_increment",NULL,NULL,sql_smallint,NULL,"10",NULL },
{ "smallint unsigned auto_increment",sql_smallint,"5","'","'",NULL,sql_no_nulls, "0",sql_searchable,"1","0","1","smallint unsigned auto_increment",NULL,NULL, sql_smallint,NULL,"10",NULL },
/* SQL_FLOAT= 6 */
{ "double",sql_float,"15","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","double","0","4",sql_float, NULL,"2",NULL },
{ "double auto_increment",sql_float,"15","'","'",NULL,sql_no_nulls,"0",sql_searchable,"0","0","1","double auto_increment","0","4",sql_float,NULL,"2",NULL },
/* SQL_REAL= 7 */
{ "float",sql_real,"7","'","'",NULL,sql_nullable, "0",sql_unsearchable,"0","0","0","float","0","2",sql_real, NULL,"2",NULL },
{ "float auto_increment",sql_real,"7","'","'",NULL,sql_no_nulls,"0",sql_unsearchable,"0","0","1","float auto_increment","0","2",sql_real,NULL,"2",NULL },
/* SQL_DOUBLE= 8 */
{ "double",sql_double,"15","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","double","0","4",sql_double,NULL,"2",NULL },
{ "double auto_increment",sql_double,"15","'","'",NULL,sql_no_nulls,"0",sql_searchable,"0","0","1","double auto_increment","0","4",sql_double,NULL,"2",NULL },
/* SQL_TYPE_DATE= 91 */
{ "date",sql_date,"10","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"date",NULL,NULL,sql_datetime,sql_date,NULL,NULL },
/* SQL_TYPE_TIME= 92 */
{ "time",sql_time,"8","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"time",NULL,NULL,sql_datetime,sql_time,NULL,NULL },
/* YEAR - SQL_SMALLINT */
{ "year",sql_smallint,"4","'","'",NULL,sql_nullable,"0",sql_searchable,"0","0","0","year",NULL,NULL,sql_smallint,NULL,"10",NULL },
/* SQL_TYPE_TIMESTAMP= 93 */
{ "datetime",sql_timestamp,"21","'","'",NULL,sql_nullable,"0",sql_searchable,NULL,"0",NULL,"datetime","0","0",sql_datetime,sql_timestamp,NULL,NULL },
{ "timestamp",sql_timestamp,"14","'","'",NULL,sql_no_nulls,"0",sql_searchable,NULL,"0",NULL,"timestamp","0","0",sql_datetime,sql_timestamp,NULL,NULL },
/* SQL_VARCHAR= 12 */
{ "varchar",sql_varchar,"255","'","'","length",sql_nullable,"0",sql_searchable,NULL,"0",NULL,"varchar","0","0",sql_varchar,NULL,"10",NULL },
{ "varchar",sql_wvarchar,"255","'","'","length",sql_nullable,"0",sql_searchable,NULL,"0",NULL,"varchar","0","0",sql_wvarchar,NULL,"10",NULL },
/* ENUM and SET are not included -- it confuses some applications. */
};
/**
Return information about data types supported by the server.
@param[in] hstmt Handle of statement
@param[in] fSqlType SQL data type or @c SQL_ALL_TYPES
@since ODBC 1.0
@since ISO SQL 92
*/
SQLRETURN SQL_API MySQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
{
STMT *stmt = (STMT *)hstmt;
uint i;
my_SQLFreeStmt(hstmt, FREE_STMT_RESET);
/* use ODBC2 types if called with ODBC3 types on an ODBC2 handle */
if (stmt->dbc->env->odbc_ver == SQL_OV_ODBC2)
{
switch (fSqlType)
{
case SQL_TYPE_DATE:
fSqlType = SQL_DATE;
break;
case SQL_TYPE_TIME:
fSqlType = SQL_TIME;
break;
case SQL_TYPE_TIMESTAMP:
fSqlType = SQL_TIMESTAMP;
break;
}
}
/* Set up result Data dictionary. */
stmt->result = (MYSQL_RES *)myodbc_malloc(sizeof(MYSQL_RES), MYF(MY_ZEROFILL));
stmt->fake_result = 1;
if (!stmt->result) {
stmt_result_free(stmt);
return stmt->set_error("S1001", "Not enough memory", 4001);
}
stmt->result_array.set_size(sizeof(SQL_GET_TYPE_INFO_values));
if (fSqlType == SQL_ALL_TYPES)
{
memcpy(stmt->result_array,
SQL_GET_TYPE_INFO_values,
sizeof(SQL_GET_TYPE_INFO_values));
stmt->result->row_count = MYSQL_DATA_TYPES;
}
else
{
stmt->result->row_count= 0;
for (i = 0; i < MYSQL_DATA_TYPES; ++i)
{
if (atoi(SQL_GET_TYPE_INFO_values[i][1]) == fSqlType ||
atoi(SQL_GET_TYPE_INFO_values[i][15]) == fSqlType)
{
memcpy(&stmt->result_array[stmt->result->row_count++ *
SQL_GET_TYPE_INFO_FIELDS],
&SQL_GET_TYPE_INFO_values[i][0],
sizeof(char *) * SQL_GET_TYPE_INFO_FIELDS);
}
}
}
myodbc_link_fields(stmt, SQL_GET_TYPE_INFO_fields, SQL_GET_TYPE_INFO_FIELDS);
return SQL_SUCCESS;
}
/**
Create strings from some integers for easy initialization of string arrays.
@todo get rid of this. it is evil.
*/
void init_getfunctions(void)
{
my_int2str(SQL_SEARCHABLE, sql_searchable, -10, 0);
my_int2str(SQL_UNSEARCHABLE, sql_unsearchable, -10, 0);
my_int2str(SQL_NULLABLE, sql_nullable, -10, 0);
my_int2str(SQL_NO_NULLS, sql_no_nulls, -10, 0);
my_int2str(SQL_BIT, sql_bit, -10, 0);
my_int2str(SQL_TINYINT, sql_tinyint, -10, 0);
my_int2str(SQL_SMALLINT, sql_smallint, -10, 0);
my_int2str(SQL_INTEGER, sql_integer, -10, 0);
my_int2str(SQL_BIGINT, sql_bigint, -10, 0);
my_int2str(SQL_FLOAT, sql_float, -10, 0);
my_int2str(SQL_REAL, sql_real, -10, 0);
my_int2str(SQL_DOUBLE, sql_double, -10, 0);
my_int2str(SQL_CHAR, sql_char, -10, 0);
my_int2str(SQL_VARCHAR, sql_varchar, -10, 0);
my_int2str(SQL_LONGVARCHAR, sql_longvarchar, -10, 0);
my_int2str(SQL_TYPE_TIMESTAMP, sql_timestamp, -10, 0);
my_int2str(SQL_DECIMAL, sql_decimal, -10, 0);
my_int2str(SQL_NUMERIC, sql_numeric, -10, 0);
my_int2str(SQL_VARBINARY, sql_varbinary, -10, 0);
my_int2str(SQL_TYPE_TIME, sql_time, -10, 0);
my_int2str(SQL_TYPE_DATE, sql_date, -10, 0);
my_int2str(SQL_LONGVARBINARY, sql_longvarbinary, -10, 0);
my_int2str(SQL_BINARY, sql_binary, -10, 0);
my_int2str(SQL_DATETIME, sql_datetime, -10, 0);
my_int2str(SQL_WCHAR, sql_wchar, -10, 0);
my_int2str(SQL_WVARCHAR, sql_wvarchar, -10, 0);
my_int2str(SQL_WLONGVARCHAR, sql_wlongvarchar, -10, 0);
# if (ODBCVER < 0x0300)
myodbc_sqlstate2_init();
myodbc_ov2_inited = 1;
# endif
}
/**
Fix some initializations based on the ODBC version.
*/
void myodbc_ov_init(SQLINTEGER odbc_version)
{
if (odbc_version == SQL_OV_ODBC2)
{
my_int2str(SQL_TIMESTAMP, sql_timestamp, -10, 0);
my_int2str(SQL_DATE, sql_date, -10, 0);
my_int2str(SQL_TIME, sql_time, -10, 0);
myodbc_sqlstate2_init();
myodbc_ov2_inited = 1;
}
else
{
if (!myodbc_ov2_inited)
return;
myodbc_ov2_inited = 0;
my_int2str(SQL_TYPE_TIMESTAMP, sql_timestamp, -10, 0);
my_int2str(SQL_TYPE_DATE, sql_date, -10, 0);
my_int2str(SQL_TYPE_TIME, sql_time, -10, 0);
myodbc_sqlstate3_init();
}
}
/**
List of functions supported in the driver.
*/
SQLUSMALLINT myodbc3_functions[] =
{
SQL_API_SQLALLOCCONNECT,
SQL_API_SQLALLOCENV,
SQL_API_SQLALLOCHANDLE,
SQL_API_SQLALLOCSTMT,
SQL_API_SQLBINDCOL,
/* SQL_API_SQLBINDPARAM */
SQL_API_SQLCANCEL,
#ifndef USE_IODBC
SQL_API_SQLCANCELHANDLE,
#endif
SQL_API_SQLCLOSECURSOR,
SQL_API_SQLCOLATTRIBUTE,
SQL_API_SQLCOLUMNS,
SQL_API_SQLCONNECT,
SQL_API_SQLCOPYDESC,
SQL_API_SQLDATASOURCES,
SQL_API_SQLDESCRIBECOL,
SQL_API_SQLDISCONNECT,
SQL_API_SQLENDTRAN,
SQL_API_SQLERROR,
SQL_API_SQLEXECDIRECT,
SQL_API_SQLEXECUTE,
SQL_API_SQLFETCH,
SQL_API_SQLFETCHSCROLL,
SQL_API_SQLFREECONNECT,
SQL_API_SQLFREEENV,
SQL_API_SQLFREEHANDLE,
SQL_API_SQLFREESTMT,
SQL_API_SQLGETCONNECTATTR,
SQL_API_SQLGETCONNECTOPTION,
SQL_API_SQLGETCURSORNAME,
SQL_API_SQLGETDATA,
SQL_API_SQLGETDESCFIELD,
SQL_API_SQLGETDESCREC,
SQL_API_SQLGETDIAGFIELD,
SQL_API_SQLGETDIAGREC,
SQL_API_SQLGETENVATTR,
SQL_API_SQLGETFUNCTIONS,
SQL_API_SQLGETINFO,
SQL_API_SQLGETSTMTATTR,
SQL_API_SQLGETSTMTOPTION,
SQL_API_SQLGETTYPEINFO,
SQL_API_SQLNUMRESULTCOLS,
SQL_API_SQLPARAMDATA,
SQL_API_SQLPREPARE,
SQL_API_SQLPUTDATA,
SQL_API_SQLROWCOUNT,
SQL_API_SQLSETCONNECTATTR,
SQL_API_SQLSETCONNECTOPTION,
SQL_API_SQLSETCURSORNAME,
SQL_API_SQLSETDESCFIELD,
SQL_API_SQLSETDESCREC,
SQL_API_SQLSETENVATTR,
SQL_API_SQLSETPARAM,
SQL_API_SQLSETSTMTATTR,
SQL_API_SQLSETSTMTOPTION,
SQL_API_SQLSPECIALCOLUMNS,
SQL_API_SQLSTATISTICS,
SQL_API_SQLTABLES,
SQL_API_SQLTRANSACT,
/* SQL_API_SQLALLOCHANDLESTD */
SQL_API_SQLBULKOPERATIONS,
SQL_API_SQLBINDPARAMETER,
SQL_API_SQLBROWSECONNECT,
SQL_API_SQLCOLATTRIBUTES,
SQL_API_SQLCOLUMNPRIVILEGES ,
SQL_API_SQLDESCRIBEPARAM,
SQL_API_SQLDRIVERCONNECT,
SQL_API_SQLDRIVERS,
SQL_API_SQLEXTENDEDFETCH,
SQL_API_SQLFOREIGNKEYS,
SQL_API_SQLMORERESULTS,
SQL_API_SQLNATIVESQL,
SQL_API_SQLNUMPARAMS,
SQL_API_SQLPARAMOPTIONS,
SQL_API_SQLPRIMARYKEYS,
SQL_API_SQLPROCEDURECOLUMNS,
SQL_API_SQLPROCEDURES,
SQL_API_SQLSETPOS,
SQL_API_SQLSETSCROLLOPTIONS,
SQL_API_SQLTABLEPRIVILEGES
};
/**
Get information on which functions are supported by the driver.
@param[in] hdbc Handle of database connection
@param[in] fFunction Function to check, @c SQL_API_ODBC3_ALL_FUNCTIONS,
or @c SQL_API_ALL_FUNCTIONS
@param[out] pfExists Pointer to either one @c SQLUSMALLINT or an array
of SQLUSMALLINT for returning results
@since ODBC 1.0
@since ISO SQL 92
*/
SQLRETURN SQL_API SQLGetFunctions(SQLHDBC hdbc __attribute__((unused)),
SQLUSMALLINT fFunction,
SQLUSMALLINT *pfExists)
{
SQLUSMALLINT index, myodbc_func_size;
myodbc_func_size = sizeof(myodbc3_functions) / sizeof(myodbc3_functions[0]);
if (fFunction == SQL_API_ODBC3_ALL_FUNCTIONS)
{
/* Clear and set bits in the 4000 bit vector */
memset(pfExists, 0,
sizeof(SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
for (index = 0; index < myodbc_func_size; ++index)
{
SQLUSMALLINT id = myodbc3_functions[index];
pfExists[id >> 4] |= (1 << (id & 0x000F));
}
return SQL_SUCCESS;
}
if (fFunction == SQL_API_ALL_FUNCTIONS)
{
/* Clear and set elements in the SQLUSMALLINT 100 element array */
memset(pfExists, 0, sizeof(SQLUSMALLINT) * 100);
for (index = 0; index < myodbc_func_size; ++index)
{
if (myodbc3_functions[index] < 100)
pfExists[myodbc3_functions[index]] = SQL_TRUE;
}
return SQL_SUCCESS;
}
*pfExists = SQL_FALSE;
for (index = 0; index < myodbc_func_size; ++index)
{
if (myodbc3_functions[index] == fFunction)
{
*pfExists = SQL_TRUE;
break;
}
}
return SQL_SUCCESS;
}