/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * 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. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include "todbc_util.h" #include "todbc_log.h" #include #include #define SQL_CASE(type) case type: return #type const char* sql_sql_type(int type) { switch (type) { SQL_CASE(SQL_BIT); SQL_CASE(SQL_TINYINT); SQL_CASE(SQL_SMALLINT); SQL_CASE(SQL_INTEGER); SQL_CASE(SQL_BIGINT); SQL_CASE(SQL_FLOAT); SQL_CASE(SQL_DOUBLE); SQL_CASE(SQL_DECIMAL); SQL_CASE(SQL_NUMERIC); SQL_CASE(SQL_REAL); SQL_CASE(SQL_CHAR); SQL_CASE(SQL_VARCHAR); SQL_CASE(SQL_LONGVARCHAR); SQL_CASE(SQL_WCHAR); SQL_CASE(SQL_WVARCHAR); SQL_CASE(SQL_WLONGVARCHAR); SQL_CASE(SQL_BINARY); SQL_CASE(SQL_VARBINARY); SQL_CASE(SQL_LONGVARBINARY); SQL_CASE(SQL_DATE); SQL_CASE(SQL_TIME); SQL_CASE(SQL_TIMESTAMP); SQL_CASE(SQL_TYPE_DATE); SQL_CASE(SQL_TYPE_TIME); SQL_CASE(SQL_TYPE_TIMESTAMP); SQL_CASE(SQL_INTERVAL_MONTH); SQL_CASE(SQL_INTERVAL_YEAR); SQL_CASE(SQL_INTERVAL_YEAR_TO_MONTH); SQL_CASE(SQL_INTERVAL_DAY); SQL_CASE(SQL_INTERVAL_HOUR); SQL_CASE(SQL_INTERVAL_MINUTE); SQL_CASE(SQL_INTERVAL_SECOND); SQL_CASE(SQL_INTERVAL_DAY_TO_HOUR); SQL_CASE(SQL_INTERVAL_DAY_TO_MINUTE); SQL_CASE(SQL_INTERVAL_DAY_TO_SECOND); SQL_CASE(SQL_INTERVAL_HOUR_TO_MINUTE); SQL_CASE(SQL_INTERVAL_HOUR_TO_SECOND); SQL_CASE(SQL_INTERVAL_MINUTE_TO_SECOND); SQL_CASE(SQL_GUID); SQL_CASE(SQL_ALL_TYPES); default: return "UNKNOWN"; } } const char* sql_c_type(int type) { switch (type) { SQL_CASE(SQL_C_CHAR); SQL_CASE(SQL_C_WCHAR); SQL_CASE(SQL_C_SHORT); SQL_CASE(SQL_C_SSHORT); SQL_CASE(SQL_C_USHORT); SQL_CASE(SQL_C_LONG); SQL_CASE(SQL_C_SLONG); SQL_CASE(SQL_C_ULONG); SQL_CASE(SQL_C_FLOAT); SQL_CASE(SQL_C_DOUBLE); SQL_CASE(SQL_C_BIT); SQL_CASE(SQL_C_TINYINT); SQL_CASE(SQL_C_STINYINT); SQL_CASE(SQL_C_UTINYINT); SQL_CASE(SQL_C_SBIGINT); SQL_CASE(SQL_C_UBIGINT); SQL_CASE(SQL_C_BINARY); SQL_CASE(SQL_C_DATE); SQL_CASE(SQL_C_TIME); SQL_CASE(SQL_C_TIMESTAMP); SQL_CASE(SQL_C_TYPE_DATE); SQL_CASE(SQL_C_TYPE_TIME); SQL_CASE(SQL_C_TYPE_TIMESTAMP); SQL_CASE(SQL_C_NUMERIC); SQL_CASE(SQL_C_GUID); default: return "UNKNOWN"; } } // https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdiagfield-function?view=sql-server-ver15 const char* sql_diag_identifier(int type) { switch (type) { // header fields SQL_CASE(SQL_DIAG_CURSOR_ROW_COUNT); SQL_CASE(SQL_DIAG_DYNAMIC_FUNCTION); SQL_CASE(SQL_DIAG_DYNAMIC_FUNCTION_CODE); SQL_CASE(SQL_DIAG_NUMBER); SQL_CASE(SQL_DIAG_RETURNCODE); SQL_CASE(SQL_DIAG_ROW_COUNT); // record fields SQL_CASE(SQL_DIAG_CLASS_ORIGIN); SQL_CASE(SQL_DIAG_COLUMN_NUMBER); SQL_CASE(SQL_DIAG_CONNECTION_NAME); SQL_CASE(SQL_DIAG_MESSAGE_TEXT); SQL_CASE(SQL_DIAG_NATIVE); SQL_CASE(SQL_DIAG_ROW_NUMBER); SQL_CASE(SQL_DIAG_SERVER_NAME); SQL_CASE(SQL_DIAG_SQLSTATE); SQL_CASE(SQL_DIAG_SUBCLASS_ORIGIN); default: return "UNKNOWN"; } } const char* sql_handle_type(int type) { switch(type) { SQL_CASE(SQL_HANDLE_ENV); SQL_CASE(SQL_HANDLE_DBC); SQL_CASE(SQL_HANDLE_STMT); SQL_CASE(SQL_HANDLE_DESC); // SQL_CASE(SQL_HANDLE_DBC_INFO_TOKEN); default: return "UNKNOWN"; } } const char* sql_env_attr_type(int type) { switch(type) { SQL_CASE(SQL_ATTR_OUTPUT_NTS); SQL_CASE(SQL_ATTR_ODBC_VERSION); SQL_CASE(SQL_ATTR_CONNECTION_POOLING); SQL_CASE(SQL_ATTR_CP_MATCH); default: return "UNKNOWN"; } } // https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetconnectattr-function?view=sql-server-ver15 const char* sql_conn_attr_type(int type) { switch(type) { SQL_CASE(SQL_ATTR_ACCESS_MODE); // ODBC 3.8 // SQL_CASE(SQL_ATTR_ASYNC_DBC_EVENT); SQL_CASE(SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE); // ODBC 3.8 // SQL_CASE(SQL_ATTR_ASYNC_DBC_PCALLBACK); // ODBC 3.8 // SQL_CASE(SQL_ATTR_ASYNC_DBC_PCONTEXT); SQL_CASE(SQL_ATTR_ASYNC_ENABLE); SQL_CASE(SQL_ATTR_AUTO_IPD); SQL_CASE(SQL_ATTR_AUTOCOMMIT); SQL_CASE(SQL_ATTR_CONNECTION_DEAD); SQL_CASE(SQL_ATTR_CONNECTION_TIMEOUT); SQL_CASE(SQL_ATTR_CURRENT_CATALOG); // ODBC 3.8 // SQL_CASE(SQL_ATTR_DBC_INFO_TOKEN); SQL_CASE(SQL_ATTR_ENLIST_IN_DTC); SQL_CASE(SQL_ATTR_LOGIN_TIMEOUT); SQL_CASE(SQL_ATTR_METADATA_ID); SQL_CASE(SQL_ATTR_ODBC_CURSORS); SQL_CASE(SQL_ATTR_PACKET_SIZE); SQL_CASE(SQL_ATTR_QUIET_MODE); SQL_CASE(SQL_ATTR_TRACE); SQL_CASE(SQL_ATTR_TRACEFILE); SQL_CASE(SQL_ATTR_TRANSLATE_LIB); SQL_CASE(SQL_ATTR_TRANSLATE_OPTION); SQL_CASE(SQL_ATTR_TXN_ISOLATION); default: return "UNKNOWN"; } } // https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function?view=sql-server-ver15 const char* sql_info_type(int type) { switch(type) { SQL_CASE(SQL_ACTIVE_ENVIRONMENTS); SQL_CASE(SQL_ASYNC_DBC_FUNCTIONS); SQL_CASE(SQL_ASYNC_MODE); SQL_CASE(SQL_ASYNC_NOTIFICATION); SQL_CASE(SQL_BATCH_ROW_COUNT); SQL_CASE(SQL_BATCH_SUPPORT); SQL_CASE(SQL_DATA_SOURCE_NAME); SQL_CASE(SQL_DRIVER_AWARE_POOLING_SUPPORTED); SQL_CASE(SQL_DRIVER_HDBC); SQL_CASE(SQL_DRIVER_HDESC); SQL_CASE(SQL_DRIVER_HENV); SQL_CASE(SQL_DRIVER_HLIB); SQL_CASE(SQL_DRIVER_HSTMT); SQL_CASE(SQL_DRIVER_NAME); SQL_CASE(SQL_DRIVER_ODBC_VER); SQL_CASE(SQL_DRIVER_VER); SQL_CASE(SQL_DYNAMIC_CURSOR_ATTRIBUTES1); SQL_CASE(SQL_DYNAMIC_CURSOR_ATTRIBUTES2); SQL_CASE(SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1); SQL_CASE(SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2); SQL_CASE(SQL_FILE_USAGE); SQL_CASE(SQL_GETDATA_EXTENSIONS); SQL_CASE(SQL_INFO_SCHEMA_VIEWS); SQL_CASE(SQL_KEYSET_CURSOR_ATTRIBUTES1); SQL_CASE(SQL_KEYSET_CURSOR_ATTRIBUTES2); SQL_CASE(SQL_MAX_ASYNC_CONCURRENT_STATEMENTS); SQL_CASE(SQL_MAX_CONCURRENT_ACTIVITIES); SQL_CASE(SQL_MAX_DRIVER_CONNECTIONS); SQL_CASE(SQL_ODBC_INTERFACE_CONFORMANCE); // SQL_CASE(SQL_ODBC_STANDARD_CLI_CONFORMANCE); SQL_CASE(SQL_ODBC_VER); SQL_CASE(SQL_PARAM_ARRAY_ROW_COUNTS); SQL_CASE(SQL_PARAM_ARRAY_SELECTS); SQL_CASE(SQL_ROW_UPDATES); SQL_CASE(SQL_SEARCH_PATTERN_ESCAPE); SQL_CASE(SQL_SERVER_NAME); SQL_CASE(SQL_STATIC_CURSOR_ATTRIBUTES1); SQL_CASE(SQL_STATIC_CURSOR_ATTRIBUTES2); SQL_CASE(SQL_DATABASE_NAME); SQL_CASE(SQL_DBMS_NAME); SQL_CASE(SQL_DBMS_VER); SQL_CASE(SQL_ACCESSIBLE_PROCEDURES); SQL_CASE(SQL_ACCESSIBLE_TABLES); SQL_CASE(SQL_BOOKMARK_PERSISTENCE); SQL_CASE(SQL_CATALOG_TERM); SQL_CASE(SQL_COLLATION_SEQ); SQL_CASE(SQL_CONCAT_NULL_BEHAVIOR); SQL_CASE(SQL_CURSOR_COMMIT_BEHAVIOR); SQL_CASE(SQL_CURSOR_ROLLBACK_BEHAVIOR); SQL_CASE(SQL_CURSOR_SENSITIVITY); SQL_CASE(SQL_DATA_SOURCE_READ_ONLY); SQL_CASE(SQL_DEFAULT_TXN_ISOLATION); SQL_CASE(SQL_DESCRIBE_PARAMETER); SQL_CASE(SQL_MULT_RESULT_SETS); SQL_CASE(SQL_MULTIPLE_ACTIVE_TXN); SQL_CASE(SQL_NEED_LONG_DATA_LEN); SQL_CASE(SQL_NULL_COLLATION); SQL_CASE(SQL_PROCEDURE_TERM); SQL_CASE(SQL_SCHEMA_TERM); SQL_CASE(SQL_SCROLL_OPTIONS); SQL_CASE(SQL_TABLE_TERM); SQL_CASE(SQL_TXN_CAPABLE); SQL_CASE(SQL_TXN_ISOLATION_OPTION); SQL_CASE(SQL_USER_NAME); SQL_CASE(SQL_AGGREGATE_FUNCTIONS); SQL_CASE(SQL_ALTER_DOMAIN); // SQL_CASE(SQL_ALTER_SCHEMA); SQL_CASE(SQL_ALTER_TABLE); // SQL_CASE(SQL_ANSI_SQL_DATETIME_LITERALS); SQL_CASE(SQL_CATALOG_LOCATION); SQL_CASE(SQL_CATALOG_NAME); SQL_CASE(SQL_CATALOG_NAME_SEPARATOR); SQL_CASE(SQL_CATALOG_USAGE); SQL_CASE(SQL_COLUMN_ALIAS); SQL_CASE(SQL_CORRELATION_NAME); SQL_CASE(SQL_CREATE_ASSERTION); SQL_CASE(SQL_CREATE_CHARACTER_SET); SQL_CASE(SQL_CREATE_COLLATION); SQL_CASE(SQL_CREATE_DOMAIN); SQL_CASE(SQL_CREATE_SCHEMA); SQL_CASE(SQL_CREATE_TABLE); SQL_CASE(SQL_CREATE_TRANSLATION); SQL_CASE(SQL_DDL_INDEX); SQL_CASE(SQL_DROP_ASSERTION); SQL_CASE(SQL_DROP_CHARACTER_SET); SQL_CASE(SQL_DROP_COLLATION); SQL_CASE(SQL_DROP_DOMAIN); SQL_CASE(SQL_DROP_SCHEMA); SQL_CASE(SQL_DROP_TABLE); SQL_CASE(SQL_DROP_TRANSLATION); SQL_CASE(SQL_DROP_VIEW); SQL_CASE(SQL_EXPRESSIONS_IN_ORDERBY); SQL_CASE(SQL_GROUP_BY); SQL_CASE(SQL_IDENTIFIER_CASE); SQL_CASE(SQL_IDENTIFIER_QUOTE_CHAR); SQL_CASE(SQL_INDEX_KEYWORDS); SQL_CASE(SQL_INSERT_STATEMENT); SQL_CASE(SQL_INTEGRITY); SQL_CASE(SQL_KEYWORDS); SQL_CASE(SQL_LIKE_ESCAPE_CLAUSE); SQL_CASE(SQL_NON_NULLABLE_COLUMNS); SQL_CASE(SQL_OJ_CAPABILITIES); SQL_CASE(SQL_ORDER_BY_COLUMNS_IN_SELECT); SQL_CASE(SQL_OUTER_JOINS); SQL_CASE(SQL_PROCEDURES); SQL_CASE(SQL_QUOTED_IDENTIFIER_CASE); SQL_CASE(SQL_SCHEMA_USAGE); SQL_CASE(SQL_SPECIAL_CHARACTERS); SQL_CASE(SQL_SQL_CONFORMANCE); SQL_CASE(SQL_SUBQUERIES); SQL_CASE(SQL_UNION); SQL_CASE(SQL_MAX_BINARY_LITERAL_LEN); SQL_CASE(SQL_MAX_CATALOG_NAME_LEN); SQL_CASE(SQL_MAX_CHAR_LITERAL_LEN); SQL_CASE(SQL_MAX_COLUMN_NAME_LEN); SQL_CASE(SQL_MAX_COLUMNS_IN_GROUP_BY); SQL_CASE(SQL_MAX_COLUMNS_IN_INDEX); SQL_CASE(SQL_MAX_COLUMNS_IN_ORDER_BY); SQL_CASE(SQL_MAX_COLUMNS_IN_SELECT); SQL_CASE(SQL_MAX_COLUMNS_IN_TABLE); SQL_CASE(SQL_MAX_CURSOR_NAME_LEN); SQL_CASE(SQL_MAX_IDENTIFIER_LEN); SQL_CASE(SQL_MAX_INDEX_SIZE); SQL_CASE(SQL_MAX_PROCEDURE_NAME_LEN); SQL_CASE(SQL_MAX_ROW_SIZE); SQL_CASE(SQL_MAX_ROW_SIZE_INCLUDES_LONG); SQL_CASE(SQL_MAX_SCHEMA_NAME_LEN); SQL_CASE(SQL_MAX_STATEMENT_LEN); SQL_CASE(SQL_MAX_TABLE_NAME_LEN); SQL_CASE(SQL_MAX_TABLES_IN_SELECT); SQL_CASE(SQL_MAX_USER_NAME_LEN); SQL_CASE(SQL_CONVERT_FUNCTIONS); SQL_CASE(SQL_NUMERIC_FUNCTIONS); SQL_CASE(SQL_STRING_FUNCTIONS); SQL_CASE(SQL_SYSTEM_FUNCTIONS); SQL_CASE(SQL_TIMEDATE_ADD_INTERVALS); SQL_CASE(SQL_TIMEDATE_DIFF_INTERVALS); SQL_CASE(SQL_TIMEDATE_FUNCTIONS); SQL_CASE(SQL_CONVERT_BIGINT); SQL_CASE(SQL_CONVERT_BINARY); SQL_CASE(SQL_CONVERT_BIT); SQL_CASE(SQL_CONVERT_CHAR); SQL_CASE(SQL_CONVERT_DATE); SQL_CASE(SQL_CONVERT_DECIMAL); SQL_CASE(SQL_CONVERT_DOUBLE); SQL_CASE(SQL_CONVERT_FLOAT); SQL_CASE(SQL_CONVERT_INTEGER); SQL_CASE(SQL_CONVERT_INTERVAL_DAY_TIME); SQL_CASE(SQL_CONVERT_INTERVAL_YEAR_MONTH); SQL_CASE(SQL_CONVERT_LONGVARBINARY); SQL_CASE(SQL_CONVERT_LONGVARCHAR); SQL_CASE(SQL_CONVERT_NUMERIC); SQL_CASE(SQL_CONVERT_REAL); SQL_CASE(SQL_CONVERT_SMALLINT); SQL_CASE(SQL_CONVERT_TIME); SQL_CASE(SQL_CONVERT_TIMESTAMP); SQL_CASE(SQL_CONVERT_TINYINT); SQL_CASE(SQL_CONVERT_VARBINARY); SQL_CASE(SQL_CONVERT_VARCHAR); SQL_CASE(SQL_DM_VER); SQL_CASE(SQL_XOPEN_CLI_YEAR); SQL_CASE(SQL_DTC_TRANSITION_COST); default: return "UNKNOWN"; } } // https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolattribute-function?view=sql-server-ver15 const char* sql_field_identifier(int type) { switch (type) { SQL_CASE(SQL_DESC_AUTO_UNIQUE_VALUE); SQL_CASE(SQL_DESC_BASE_COLUMN_NAME); SQL_CASE(SQL_DESC_BASE_TABLE_NAME); SQL_CASE(SQL_DESC_CASE_SENSITIVE); SQL_CASE(SQL_DESC_CATALOG_NAME); SQL_CASE(SQL_DESC_CONCISE_TYPE); SQL_CASE(SQL_DESC_COUNT); SQL_CASE(SQL_DESC_DISPLAY_SIZE); SQL_CASE(SQL_DESC_FIXED_PREC_SCALE); SQL_CASE(SQL_DESC_LABEL); SQL_CASE(SQL_DESC_LENGTH); SQL_CASE(SQL_DESC_LITERAL_PREFIX); SQL_CASE(SQL_DESC_LITERAL_SUFFIX); SQL_CASE(SQL_DESC_LOCAL_TYPE_NAME); SQL_CASE(SQL_DESC_NAME); SQL_CASE(SQL_DESC_NULLABLE); SQL_CASE(SQL_DESC_NUM_PREC_RADIX); SQL_CASE(SQL_DESC_OCTET_LENGTH); SQL_CASE(SQL_DESC_PRECISION); SQL_CASE(SQL_DESC_SCALE); SQL_CASE(SQL_DESC_SCHEMA_NAME); SQL_CASE(SQL_DESC_SEARCHABLE); SQL_CASE(SQL_DESC_TABLE_NAME); SQL_CASE(SQL_DESC_TYPE); SQL_CASE(SQL_DESC_TYPE_NAME); SQL_CASE(SQL_DESC_UNNAMED); SQL_CASE(SQL_DESC_UNSIGNED); SQL_CASE(SQL_DESC_UPDATABLE); default: return "UNKNOWN"; } } // https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function?view=sql-server-ver15 const char* sql_input_output_type(int type) { switch (type) { SQL_CASE(SQL_PARAM_INPUT); SQL_CASE(SQL_PARAM_OUTPUT); SQL_CASE(SQL_PARAM_OUTPUT_STREAM); SQL_CASE(SQL_PARAM_INPUT_OUTPUT); SQL_CASE(SQL_PARAM_INPUT_OUTPUT_STREAM); default: return "UNKNOWN"; } } // https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetstmtattr-function?view=sql-server-ver15 const char* sql_stmt_attr_type(int type) { switch (type) { SQL_CASE(SQL_ATTR_APP_PARAM_DESC); SQL_CASE(SQL_ATTR_APP_ROW_DESC); SQL_CASE(SQL_ATTR_ASYNC_ENABLE); SQL_CASE(SQL_ATTR_ASYNC_STMT_EVENT); // ODBC 3.8 // SQL_CASE(SQL_ATTR_ASYNC_STMT_PCALLBACK); // ODBC 3.8 // SQL_CASE(SQL_ATTR_ASYNC_STMT_PCONTEXT); SQL_CASE(SQL_ATTR_CONCURRENCY); SQL_CASE(SQL_ATTR_CURSOR_SCROLLABLE); SQL_CASE(SQL_ATTR_CURSOR_SENSITIVITY); SQL_CASE(SQL_ATTR_CURSOR_TYPE); SQL_CASE(SQL_ATTR_ENABLE_AUTO_IPD); SQL_CASE(SQL_ATTR_FETCH_BOOKMARK_PTR); SQL_CASE(SQL_ATTR_IMP_PARAM_DESC); SQL_CASE(SQL_ATTR_IMP_ROW_DESC); SQL_CASE(SQL_ATTR_KEYSET_SIZE); SQL_CASE(SQL_ATTR_MAX_LENGTH); SQL_CASE(SQL_ATTR_MAX_ROWS); SQL_CASE(SQL_ATTR_METADATA_ID); SQL_CASE(SQL_ATTR_NOSCAN); SQL_CASE(SQL_ATTR_PARAM_BIND_OFFSET_PTR); SQL_CASE(SQL_ATTR_PARAM_BIND_TYPE); SQL_CASE(SQL_ATTR_PARAM_OPERATION_PTR); SQL_CASE(SQL_ATTR_PARAM_STATUS_PTR); SQL_CASE(SQL_ATTR_PARAMS_PROCESSED_PTR); SQL_CASE(SQL_ATTR_PARAMSET_SIZE); SQL_CASE(SQL_ATTR_QUERY_TIMEOUT); SQL_CASE(SQL_ATTR_RETRIEVE_DATA); SQL_CASE(SQL_ATTR_ROW_ARRAY_SIZE); SQL_CASE(SQL_ATTR_ROW_BIND_OFFSET_PTR); SQL_CASE(SQL_ATTR_ROW_BIND_TYPE); SQL_CASE(SQL_ATTR_ROW_NUMBER); SQL_CASE(SQL_ATTR_ROW_OPERATION_PTR); SQL_CASE(SQL_ATTR_ROW_STATUS_PTR); SQL_CASE(SQL_ATTR_ROWS_FETCHED_PTR); SQL_CASE(SQL_ATTR_SIMULATE_CURSOR); SQL_CASE(SQL_ATTR_USE_BOOKMARKS); default: return "UNKNOWN"; } } const char* sql_function_type(int type) { switch (type) { // SQL_CASE(SQL_API_ALL_FUNCTIONS); SQL_CASE(SQL_API_ODBC3_ALL_FUNCTIONS); // ISO 92 standards-compliance SQL_CASE(SQL_API_SQLALLOCHANDLE); SQL_CASE(SQL_API_SQLGETDESCFIELD); SQL_CASE(SQL_API_SQLBINDCOL); SQL_CASE(SQL_API_SQLGETDESCREC); SQL_CASE(SQL_API_SQLCANCEL); SQL_CASE(SQL_API_SQLGETDIAGFIELD); SQL_CASE(SQL_API_SQLCLOSECURSOR); SQL_CASE(SQL_API_SQLGETDIAGREC); SQL_CASE(SQL_API_SQLCOLATTRIBUTE); SQL_CASE(SQL_API_SQLGETENVATTR); SQL_CASE(SQL_API_SQLCONNECT); SQL_CASE(SQL_API_SQLGETFUNCTIONS); SQL_CASE(SQL_API_SQLCOPYDESC); SQL_CASE(SQL_API_SQLGETINFO); SQL_CASE(SQL_API_SQLDATASOURCES); SQL_CASE(SQL_API_SQLGETSTMTATTR); SQL_CASE(SQL_API_SQLDESCRIBECOL); SQL_CASE(SQL_API_SQLGETTYPEINFO); SQL_CASE(SQL_API_SQLDISCONNECT); SQL_CASE(SQL_API_SQLNUMRESULTCOLS); SQL_CASE(SQL_API_SQLDRIVERS); SQL_CASE(SQL_API_SQLPARAMDATA); SQL_CASE(SQL_API_SQLENDTRAN); SQL_CASE(SQL_API_SQLPREPARE); SQL_CASE(SQL_API_SQLEXECDIRECT); SQL_CASE(SQL_API_SQLPUTDATA); SQL_CASE(SQL_API_SQLEXECUTE); SQL_CASE(SQL_API_SQLROWCOUNT); SQL_CASE(SQL_API_SQLFETCH); SQL_CASE(SQL_API_SQLSETCONNECTATTR); SQL_CASE(SQL_API_SQLFETCHSCROLL); SQL_CASE(SQL_API_SQLSETCURSORNAME); SQL_CASE(SQL_API_SQLFREEHANDLE); SQL_CASE(SQL_API_SQLSETDESCFIELD); SQL_CASE(SQL_API_SQLFREESTMT); SQL_CASE(SQL_API_SQLSETDESCREC); SQL_CASE(SQL_API_SQLGETCONNECTATTR); SQL_CASE(SQL_API_SQLSETENVATTR); SQL_CASE(SQL_API_SQLGETCURSORNAME); SQL_CASE(SQL_API_SQLSETSTMTATTR); SQL_CASE(SQL_API_SQLGETDATA); // Open Group standards-compliance); SQL_CASE(SQL_API_SQLCOLUMNS); SQL_CASE(SQL_API_SQLSTATISTICS); SQL_CASE(SQL_API_SQLSPECIALCOLUMNS); SQL_CASE(SQL_API_SQLTABLES); // ODBC standards-compliance); SQL_CASE(SQL_API_SQLBINDPARAMETER); SQL_CASE(SQL_API_SQLNATIVESQL); SQL_CASE(SQL_API_SQLBROWSECONNECT); SQL_CASE(SQL_API_SQLNUMPARAMS); SQL_CASE(SQL_API_SQLBULKOPERATIONS); SQL_CASE(SQL_API_SQLPRIMARYKEYS); SQL_CASE(SQL_API_SQLCOLUMNPRIVILEGES); SQL_CASE(SQL_API_SQLPROCEDURECOLUMNS); SQL_CASE(SQL_API_SQLDESCRIBEPARAM); SQL_CASE(SQL_API_SQLPROCEDURES); SQL_CASE(SQL_API_SQLDRIVERCONNECT); SQL_CASE(SQL_API_SQLSETPOS); SQL_CASE(SQL_API_SQLFOREIGNKEYS); SQL_CASE(SQL_API_SQLTABLEPRIVILEGES); SQL_CASE(SQL_API_SQLMORERESULTS); SQL_CASE(SQL_API_SQLALLOCCONNECT); SQL_CASE(SQL_API_SQLALLOCENV); SQL_CASE(SQL_API_SQLALLOCSTMT); SQL_CASE(SQL_API_SQLBINDPARAM); SQL_CASE(SQL_API_SQLERROR); SQL_CASE(SQL_API_SQLFREECONNECT); SQL_CASE(SQL_API_SQLFREEENV); SQL_CASE(SQL_API_SQLGETCONNECTOPTION); SQL_CASE(SQL_API_SQLGETSTMTOPTION); SQL_CASE(SQL_API_SQLSETCONNECTOPTION); SQL_CASE(SQL_API_SQLSETPARAM); SQL_CASE(SQL_API_SQLSETSTMTOPTION); SQL_CASE(SQL_API_SQLTRANSACT); SQL_CASE(SQL_API_SQLCANCELHANDLE); default: return "UNKNOWN"; } } const char* sql_freestmt_option_type(int type) { switch (type) { SQL_CASE(SQL_CLOSE); SQL_CASE(SQL_DROP); SQL_CASE(SQL_UNBIND); SQL_CASE(SQL_RESET_PARAMS); default: return "UNKNOWN"; } } const char* sql_soi_type(int soi) { switch (soi) { SQL_CASE(SQL_NTS); SQL_CASE(SQL_NULL_DATA); SQL_CASE(SQL_DEFAULT_PARAM); SQL_CASE(SQL_DATA_AT_EXEC); default: { if (soi >= 0) return ""; return "SQL_LEN_DATA_AT_EXEC(?)"; } break; } } const char* sql_nullable_type(int type) { switch (type) { SQL_CASE(SQL_NO_NULLS); SQL_CASE(SQL_NULLABLE); SQL_CASE(SQL_NULLABLE_UNKNOWN); default: { return "UNKNOWN"; } break; } } int is_valid_sql_c_type(int type) { const char *ctype = sql_c_type(type); if (strcmp(ctype, "UNKNOWN")==0) return 0; return 1; } int is_valid_sql_sql_type(int type) { const char *sqltype = sql_sql_type(type); if (strcmp(sqltype, "UNKNOWN")==0) return 0; return 1; } int utf8_chars(const char *src) { const char *fromcode = "UTF-8"; const char *tocode = "UCS-2LE"; iconv_t conv = iconv_open(tocode, fromcode); if (!conv) return -1; size_t slen = strlen(src); char buf[4096]; size_t dlen = sizeof(buf); char *ps = (char*)src; char *pd = buf; iconv(conv, &ps, &slen, &pd, &dlen); DASSERT(slen==0); size_t chars = (sizeof(buf) - dlen) / 2; iconv_close(conv); return (int)chars; } static int do_charset_chars(iconv_t cnv, const unsigned char *src) { int chars = 0; char *ps = (char*)src; char buf[16]; size_t sn = 1; while (1) { char *ds = buf; size_t dn = sizeof(buf); size_t n = iconv(cnv, &ps, &sn, &ds, &dn); if (n==(size_t)-1) { int e = errno; switch (e) { case EILSEQ: return -1; case E2BIG: return -1; case EINVAL: sn += 1; continue; default: return -1; } } if (sn) return -1; if (n>0) return -1; int i=0; for (i=0; i<(sizeof(buf)-dn); ++i) { if (buf[i]) break; } if (i>=(sizeof(buf)-dn)) break; chars += (int)1; sn = 1; } return chars; } int charset_chars(const char *charset, const unsigned char *src) { iconv_t cnv = iconv_open(charset, charset); if (cnv==(iconv_t)-1) return -1; int chars = do_charset_chars(cnv, src); iconv_close(cnv); return chars; }