snowflake-odbc v4.0.0-rc1
Pre-release
Pre-release
Changelog
Breaking changes
- Changed
SQL_C_CHARconversion of DECIMAL/NUMERIC to returnSQL_ERROR(22003) when whole digits do not fit in the buffer; previously returnedSQL_SUCCESS_WITH_INFOwith truncated digits. - Changed
SQL_C_BINARYconversion of DECIMAL/NUMERIC/DECFLOAT to returnSQL_ERROR(22003) when the buffer is smaller thansizeof(SQL_NUMERIC_STRUCT); previouslyBufferLengthwas ignored, risking buffer overflows. - Changed conversion of NaN
FLOAT/DOUBLEto integer andSQL_C_BITtargets to returnSQL_ERROR(22003); previously returnedSQL_SUCCESS_WITH_INFOwith a silent0. - Enforced interval leading-field precision for
SQL_C_INTERVAL_*types: values that exceed the default precision of 2 now returnSQL_ERROR(22015), andSQL_DESC_DATETIME_INTERVAL_PRECISIONis respected; previously neither was enforced. - Changed
SQLRowCountwith aNULLRowCountPtrto returnSQL_ERROR(HY009); previously returnedSQL_SUCCESS. - Changed
SQLBindParameterto returnSQL_ERROR(HY104) for a negativeDecimalDigitsvalue; previously accepted negative scale silently. - Changed conversion of DECFLOAT values with extreme exponents to
SQL_C_BINARYto returnSQL_ERROR(22003) instead of silently clamping. - Changed
SQL_C_NUMERICtoVARCHARconversion to apply the scale fromSQL_NUMERIC_STRUCT(e.g. magnitude12345with scale2produces"123.45"); previously scale was ignored. - Changed binding of subnormal double values near
DBL_MINto preserve the value; previously stored as0.0. - Changed
TIMEtoSQL_C_CHAR/SQL_C_WCHARbuffer-too-small handling: a buffer that cannot hold the base time (HH:MM:SS) now returnsSQL_ERROR(22003); a buffer that truncates only fractional seconds returnsSQL_SUCCESS_WITH_INFO(01004). - Changed
DATEtoSQL_C_BINARYconversion with an undersized buffer to returnSQL_ERROR(22003); previously returnedSQL_SUCCESSwith truncated data. - Changed
SQLGetFunctionsto reportSQL_API_SQLCANCELHANDLEas supported; previously returnedSQL_FALSEdespite the function being exported. - Tightened conversion from VARCHAR to
SQL_C_INTERVAL_*types. Truncation returnsSQL_SUCCESS_WITH_INFO(01S07) and interval-field overflow returnsSQL_ERROR(22015). - Changed
SQL_C_INTERVAL_SECONDwith fractional seconds bound to exact-numeric SQL types to truncate the fraction and succeed; previously returnedSQL_ERROR(22015). - Changed
SQLCancelduring data-at-execution to discard all accumulatedSQLPutDatadata so a re-entered sequence starts fresh; previously accumulated data from an interrupted sequence could be concatenated into the next sequence. - Changed
SQLForeignKeysto resolve aNULLFK catalog and schema from the connection context; previously returned an empty result set unlessCLIENT_METADATA_REQUEST_USE_CONNECTION_CTXwas enabled. - Changed
SQLSetConnectAttr(SQL_ATTR_LOGIN_TIMEOUT)called after connect to returnSQL_ERROR(HY011); previously returnedSQL_SUCCESSas a silent no-op. - Changed
SQLSetStmtAttr(SQL_ATTR_CURSOR_TYPE)for unsupported cursor types to substituteSQL_CURSOR_FORWARD_ONLYand returnSQL_SUCCESS_WITH_INFO(01S02); previously accepted any value silently. - Changed the ODBC diagnostic vendor prefix from
[Snowflake][Support]to[Snowflake][Snowflake ODBC Driver], matching the ODBC spec format[vendor][ODBC-component-identifier]. - Changed
SQLGetInfo(SQL_DRIVER_NAME)to return the loaded driver library's file name (e.g.libsfodbc.so,libsfodbc.dylib,sfodbc.dll) as the ODBC specification prescribes; previously returned the fixed stringSnowflake. - Changed
SQLCancelHandle(SQL_HANDLE_DBC)to returnSQL_ERROR(HY010) when an associated statement is asynchronously executing or mid data-at-execution; previously returnedSQL_SUCCESSas a no-op. - Changed DECFLOAT fetched as
SQL_C_CHAR/SQL_C_WCHARto return normalized scientific notation (e.g.1.2e200instead of12e199). - Changed stage array-binding threshold comparison from
>to>=and added support for thearrayBindSupportedandCLIENT_STAGE_ARRAY_BINDING_THRESHOLDsession parameters; previously the server-providedarrayBindSupportedflag was ignored. - Removed support for the
SQL_SF_CONN_ATTR_PRIV_KEY(rawEVP_PKEY*) connection attribute; usePRIV_KEY_CONTENT,PRIV_KEY_BASE64, orPRIV_KEY_FILEinstead. - Changed OAuth token and authorization endpoint URL validation to require HTTPS;
http://is allowed only for loopback addresses. - Changed the SQLSTATE for OAuth IdP token-exchange rejection from
HY000to28000(invalid authorization specification). - Changed connection setup to reject WIF-only parameters (e.g.
WORKLOAD_IDENTITY_PROVIDER) unlessAUTHENTICATOR=WORKLOAD_IDENTITY; previously silently ignored them with any other authenticator. - Changed
WORKLOAD_IDENTITY_IMPERSONATION_PATHwithIDENTITY_PROVIDER=OIDCto return a connection error; previously silently ignored the combination. - Changed catalog
REMARKSandSQLColumnsCOLUMN_DEFto returnSQL_NULL_DATAwhen absent instead of an empty string, andSQLTablesREMARKSnow surfaces aSHOW OBJECTScomment when present. - Changed
SQL_SF_STMT_ATTR_LAST_QUERY_IDto be read-only and fully populated after every statement execution; changedSQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNTto support get/set with a default of-1(auto-detect); neither attribute was fully implemented in ODBC 3.x. - Changed
SQLGetDiagRec/SQLGetDiagFieldmessage text to append an internal error trace by default; setErrorTraceEnabled=falseinsf.odbc.inito restore 3.x-shaped message text. - Fixed return codes and diagnostics under iODBC to match the ODBC specification: zero-row DML returns
SQL_NO_DATA, length-only queries returnSQL_SUCCESS, and requiredSUCCESS_WITH_INFO/HY012diagnostics are posted correctly. - Fixed orphaned child statement handles under iODBC:
SQLDisconnectandSQLFreeStmt(SQL_DROP)now invalidate all associated handles through iODBC's alloc table so a subsequentSQLFreeHandleon an orphaned handle returnsSQL_INVALID_HANDLEinstead ofSQL_SUCCESS. - Fixed
SQLGetDescFieldandSQLSetDescFieldcalled duringSQL_NEED_DATAstate under iODBC to returnSQL_ERROR(HY010); previously returnedSQL_SUCCESS. - Fixed ODBC 3.x-standard SQLSTATEs under iODBC (e.g.
HY090,HY010,HY017,HY092,07009,HY008); previously returned vendorHY000or ODBC 2.x aliases. - Fixed
SQL_C_WCHARfetch encoding under iODBC to use a uniformUTF-32width driven byDriverManagerEncodinginsf.odbc.ini; previously the code-unit width varied by Snowflake source column type. - Changed proxy resolution so
HTTP_PROXY/HTTPS_PROXY/NO_PROXYenvironment variables are ignored unlessUSE_PROXY_ENV=true(aliasPROXYWITHENV); explicitPROXY=/NO_PROXY=connection parameters still apply. ODBC 3.x fell back to those environment variables when no DSN/simba.snowflake.iniproxy was set.PROXYWITHENVno longer writes the connection'sPROXYvalue into the process environment. - Changed
SF_GLOBAL_SSL_VERSION(and TLS settings) below TLS 1.2 to fail the connection; previously logged a deprecation warning and still negotiated. - Removed support of OCSP certificate validation in favor of CRL validation.
New features
- Added VECTOR column fetch: VECTOR columns are returned as compact JSON array strings (e.g.
[1,2,3]) viaSQL_C_CHAR,SQL_C_WCHAR, andSQL_C_BINARY;SQLDescribeColreportsSQL_VARCHARandSQL_DESC_TYPE_NAMEreturnsVECTOR. - Added
ALTER USER ADD PROGRAMMATIC ACCESS TOKENresult-set support: the generated token is returned as a result row; ODBC 3.x returned an invalid cursor state for this DDL. - Implemented
SQLTransact(ODBC 2.x) as a mapping toSQLEndTran, restoring compatibility with ODBC 2.x applications that bypass the Driver Manager. - Added
TIMEtoSQL_C_BINARYconversion support. - Added
SQL_C_BINARYasSQLBindParametersource type forSQL_DECIMAL,SQL_NUMERIC,SQL_TIME, andSQL_TIMESTAMPwhen the buffer length matches the SQL data length. - Added PUT local-path tilde expansion: a leading
~/or~in the source path is expanded to the user's home directory. - Added automatic creation of a missing destination directory for
GEToperations. - Added
SQLGetDiagField(SQL_DIAG_SERVER_NAME)population: returns the connected server name instead of an empty string. - Added
SQLGetDiagField(SQL_DIAG_DYNAMIC_FUNCTION)/SQL_DIAG_DYNAMIC_FUNCTION_CODEpopulation after statement execution (e.g. SELECT →85/SQL_DIAG_SELECT_CURSOR); previously returned empty /0. - Added
SQL_C_BINARYtoVARCHARbinding: binary bytes are hex-encoded before send (e.g.0xDEADBEEF→"deadbeef"); ODBC 3.x forwarded raw bytes and the server rejected the request with HTTP 400. - Added
SQL_SF_TIMESTAMP_TZparameter binding forSQL_C_TYPE_TIMESTAMP(stored at UTC) andSQL_C_CHAR/SQL_C_WCHARstrings with a+/-HH:MMoffset. - Added
SQLBindParametersupport for binding toSQL_INTERVAL_*parameters from same-familySQL_C_INTERVAL_*,SQL_C_CHAR/SQL_C_WCHAR, and exact-numeric C sources (approximate-numeric sources are rejected withSQL_ERROR07006). - Added
SQL_SF_CONN_ATTR_APPLICATIONas a pre-connect get/set attribute that forwards the application name to the server. - Added
SQLGetFunctionsreporting ofSQL_API_SQLSETSCROLLOPTIONSandSQL_API_SQLPARAMOPTIONSas supported under iODBC.
Changes
- Renamed the default driver registration name to
Snowflake ODBC; update DSNDriver=entries that referenceSnowflakeDSIIDriver(custom names still configurable viaDRIVER_NAME=/SF_DRIVER_NAME). - Changed distributable ODBC package filenames to
snowflake-odbc-<version>.<arch>.<extension>with unified architecturesaarch64/x86_64/x86_32/universal. - Changed
SQLGetInfo(SQL_DRIVER_VER)to return the zero-paddedMM.mm.bbbbformat (e.g.04.00.0000) per the ODBC specification instead of the unpadded semver string (e.g.3.16.0). - Changed process-wide driver configuration to use
sf.odbc.ini(searched in$SF_ODBC_INI,~/.config/snowflake/sf.odbc.ini,~/.snowflake/sf.odbc.ini, and/opt/snowflake/snowflakeodbc/sf.odbc.ini); update deployment scripts that writesimba.snowflake.ini. - Changed
PASSCODEINPASSWORDconnection parameter to accepttrueand1in addition toon. - Changed
QUERY_TAGconnection parameter to be applied as a server session parameter at connection time. - Changed the on-disk credential cache file from
credential_cache_v1.jsontocredential_cache_v2.json(same lookup order:$SF_TEMPORARY_CREDENTIAL_CACHE_DIR,$XDG_CACHE_HOME/snowflake,$HOME/.cache/snowflake). Tokens cached by ODBC 3.x are not read by 4.x, so expect one extra authentication after upgrading. - Changed GET downloads on Unix to create files with owner-only (
0600) permissions by default; setUNSAFE_FILE_WRITE=trueto use the process umask. - Changed
PRIV_KEY_FILE/private_key_filereads on Unix to require owner-only permissions (mode0600); overly permissive key files now fail unlessUNSAFE_SKIP_CONFIG_FILE_PERMISSIONS_CHECK=true. - Changed
AUTHENTICATOR=WORKLOAD_IDENTITYto reject hosts outside the recognized Snowflake suffixes (snowflakecomputing.com/.cn/.mil) before fetching cloud credentials; extend the list only via theSNOWFLAKE_WIF_ALLOWED_HOST_SUFFIXESenvironment variable. - Changed client-side-encryption
KeyWrappingMetadata.EncryptionLibrarymetadata to"Rust(OpenSSL)". - Changed client-side rejection of invalid
ACCOUNT/SERVER/PORTcharacters to SQLSTATE01S00(native error0); ODBC 3.x returned28000(native error20032). - Changed
CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCYto be sent as a server session parameter during login (queryable viaSHOW PARAMETERS) in addition to configuring the client heartbeat interval; ODBC 3.x used it client-side only. - Changed control-plane response body reads with a cap of 20MB (OAuth, browser, GCP metadata, CRL)
- Changed strict owner-only permissions and single-open I/O in CRL cache handling
Bug fixes
- Fixed failed
GETdownloads to leave no partial or corrupt file at the destination; the driver now writes to a.parttemporary file and renames it on successful completion. - Fixed concurrent
SQLDisconnectto be thread-safe. - Fixed
SQLDisconnectto free child statement handles and explicitly allocated descriptors after a successful disconnect so a laterSQLFreeHandleon those handles returnsSQL_INVALID_HANDLE. - Fixed
SQLDisconnectto returnSQL_ERROR(HY010) without disconnecting when a child statement is asynchronously executing or mid data-at-execution. - Fixed
SQLCancelon a statement withSQL_ATTR_ASYNC_ENABLEto actually interrupt the in-progress operation: subsequent polling returnsSQL_ERROR(HY008) once the cancellation is acknowledged. Previously polling kept returningSQL_STILL_EXECUTINGuntil the query completed naturally. - Fixed cross-thread
SQLCancelandSQLCancelHandleto always returnSQL_SUCCESSand post no diagnostics of their own, per the ODBC specification; previously they intermittently returnedSQL_ERROR(HY008, native error 604) when the server-side abort raced the query's completion. Only the canceled function returnsHY008. - Fixed FLOAT/DOUBLE boundary values (
FLT_MAX,DBL_MAX) being incorrectly rejected with a numeric out-of-range error; they are now returned successfully. - Fixed a crash during
TIMESTAMPtoSQL_C_CHAR/SQL_C_WCHARconversion when the destination buffer was too small. - Fixed
SQLNumResultColsandSQLDescribeColto return the correct column count and metadata after a prepared statement's cursor is closed - including the asyncSQLPrepare+SQLExecute+SQLCloseCursorpath - instead of returning incorrect results or errors. - Fixed
SQLDescribeColcolumn size forSQL_DOUBLE/SQL_FLOATto report15(decimal digit precision) instead of53(binary mantissa bits). - Fixed
SQLColumnsNUM_PREC_RADIXfor FLOAT/DOUBLE/REAL to return10, matching decimalCOLUMN_SIZE(query-resultSQLColAttributeradix for DOUBLE remains2). - Fixed
SQLFreeHandle(SQL_HANDLE_DESC)on an implicitly allocated descriptor to returnSQL_ERROR(HY017) and leave the handle valid. - Fixed external-browser SSO/OAuth on WSL/Linux to validate the browser URL before launching the browser.
- Fixed
SQL_C_CHARfetch ofFLOAT/DOUBLE/REALwith a truncated buffer to post SQLSTATE01004. - Fixed
SQL_C_WCHARchunkedSQLGetDatabuffer capacity to usesizeof(SQLWCHAR)so an 8-byte buffer fits three data characters plus NUL. - Fixed
SQL_C_WCHARdecimal-string binding toSQL_DECIMALto convert correctly on all platforms. - Fixed crashes under iODBC during some
SQLFreeHandle/SQLDisconnect/SQLCopyDeschandle-hierarchy sequences that aborted or segfaulted. - Fixed connection-attribute state after
SQLDisconnectunder iODBC:SQL_ATTR_CONNECTION_DEADreportsSQL_CD_TRUEand reads of other connection attributes returnSQL_ERRORinstead of stale cached values. - Fixed
SQLGetDataconversion fromDECFLOATtoSQL_C_WCHARunder iODBC to convert the value instead of returningSQL_SUCCESSwithSQL_NULL_DATAand an untouched buffer. - Fixed
SQLColAttributeto map ODBC 2.x field identifiers (SQL_COLUMN_NAME,SQL_COLUMN_TYPE, etc.) to theirSQL_DESC_*equivalents as previous behavior was inconsistent (empty strings, wrong values, orHY091). - Fixed
SQLPrimaryKeys/SQLForeignKeyswithSQL_ATTR_METADATA_ID=TRUEto case-fold unquoted identifiers to uppercase before matching instead of comparing case-sensitively and returning empty results for lowercase names. - Fixed
SQLProcedures/SQLProcedureColumnswithSQL_ATTR_METADATA_ID=TRUEto case-fold unquoted identifiers to uppercase before matching instead of returning empty results for lowercase names. - Fixed
SQLTableswithSQL_ATTR_METADATA_ID=TRUEto case-fold unquoted identifiers to uppercase before matching instead of returning empty results for lowercase names. - Fixed
SQLGetDatawithSQL_C_NUMERICto honorSQL_DESC_PRECISIONandSQL_DESC_SCALEset on the ARD viaSQLSetDescFieldinstead of hardcoded precision38/ scale0. - Fixed
DATEtoSQL_C_CHAR/SQL_C_WCHARconversion with an undersized buffer to returnSQL_ERROR(22003) instead of truncating. - Fixed
SQLGetDescFieldon an empty IPD (no parameters bound) to returnSQL_NO_DATAinstead ofSQL_ERROR. - Fixed
SQLGetStmtAttr/SQLGetConnectAttrwith a negative stringBufferLengthto returnSQL_ERROR(HY090). - Fixed
SQLGetConnectAttrwith an out-of-range attribute identifier to returnSQL_ERROR(HY092). - Fixed
SQLSetConnectAttrwith ODBC 2.x statement-level attribute IDs (SQL_ATTR_MAX_ROWS,SQL_ATTR_QUERY_TIMEOUT) to returnSQL_ERROR(HY092) instead ofSQL_SUCCESSas a silent no-op. - Fixed fractional truncation on a numeric-to-character fetch to return
SQL_SUCCESS_WITH_INFOwith SQLSTATE01S07. - Fixed
FLOAT/REALto single-field interval fetch with a nonzero fractional part to returnSQL_SUCCESS_WITH_INFO(01S07). - Fixed numeric-to-interval conversion so a value that truncates to zero always yields
+0(no negative-zero interval sign).
Known issues
- Binding
"Infinity","-Infinity", or"NaN"asSQL_C_CHAR/SQL_C_WCHARto a float SQL type returnsSQL_ERROR(22018); ODBC 3.x forwarded the literal and stored a non-finiteFLOAT. SQLForeignKeyswithSQL_ATTR_METADATA_ID=TRUEallows unused FK-sideNULLpointers instead of returningHY009; ODBC 3.x rejected the call withSQL_ERROR.- Conversion from
FLOAT/DOUBLE/REALtoSQL_C_BINARYreturns a 19-byteSQL_NUMERIC_STRUCT; ODBC 3.x returned the raw 8-byte IEEE 754 double. - Any nonzero
SQL_C_NUMERICvalue bound toSQL_BITconverts totrue; ODBC 3.x rejected values outside{0, 1}withSQL_ERROR(22003). SQL_C_CHAR/SQL_C_WCHARhex literals bound toSQL_BINARYare hex-decoded (e.g."DEADBEEF"→ 4 bytes); ODBC 3.x forwarded the raw ASCII bytes.- PUT compression type is returned in uppercase (e.g.
GZIP); ODBC 3.x returned lowercase (e.g.gzip). - Gzip-compressed PUT uploads omit the original filename from the gzip
FNAMEheader and zero the mtime; ODBC 3.x included the filename in the header. - OAuth Authorization Code token caching is disabled by default; set
CLIENT_STORE_TEMPORARY_CREDENTIAL=trueto re-enable. ODBC 3.x cached by default on all platforms. SQLDescribeParamnormalizes Snowflake vendor TIMESTAMP type codes (2000/2001/2002) toSQL_TYPE_TIMESTAMP(93); ODBC 3.x preserved the vendor codes.- Under iODBC, the driver manager may return different return codes or SQLSTATEs for identical calls because ODBC 4.x and ODBC 3.x advertise different driver capabilities (e.g. DSN-name lookup, catalog calls,
SQLGetFunctionsprobes). SQLBrowseConnectunder iODBC returnsSQL_ERRORfor partial connection input instead ofSQL_NEED_DATAfor the iterative protocol.