From 3abbde09da81cd6a2aa6409e86ee6e888a305b8b Mon Sep 17 00:00:00 2001 From: Admnwk <220553748+Admnwk@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:07:43 -0300 Subject: [PATCH 1/2] =?UTF-8?q?fix(odbc=20driver):=20x86=20(32-bit)=20buil?= =?UTF-8?q?d=20=E2=80=94=20C4100=20+=20C2733?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ODBC driver failed to compile on MSVC x86 /WX (CI only builds x64, so these slipped past). Two x86-only issues: 1. C4100: SQLSetStmtAttr's SQLINTEGER param was named 'a' but unused → /WX error. Drop the name. 2. C2733: SQLColAttribute's final parameter is SQLLEN* on 64-bit but SQLPOINTER on 32-bit per the Windows SDK sqlext.h (guarded by 'defined(_WIN64) || defined(SQLCOLATTRIBUTE_SQLLEN)'). Our fixed SQLLEN* definition conflicted with the 32-bit declaration, which MSVC rejects as an extern "C" overload. Mirror the SDK guard and alias back to SQLLEN* internally. x64 is unchanged: the _WIN64 branch is byte-identical to the prior signature. Verified: - x86 /WX full build clean; x86 unit suite 873/873, 0 failed. - x64 openads_odbc.cpp compiles clean /W4 /WX. Addresses the x86 build gap reported in issue #3. Co-Authored-By: Claude Opus 4.8 (1M context) --- bindings/odbc/openads_odbc.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/bindings/odbc/openads_odbc.cpp b/bindings/odbc/openads_odbc.cpp index f38befa2..e28de294 100644 --- a/bindings/odbc/openads_odbc.cpp +++ b/bindings/odbc/openads_odbc.cpp @@ -429,7 +429,7 @@ SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER, if (out) *out = 0; return SQL_SUCCESS; } -SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT, SQLINTEGER a, SQLPOINTER, SQLINTEGER) { +SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER) { return SQL_SUCCESS; } SQLRETURN SQL_API SQLGetStmtAttr(SQLHSTMT hstmt, SQLINTEGER a, SQLPOINTER val, @@ -601,10 +601,23 @@ SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT col, SQLCHAR* name return SQL_SUCCESS; } +// The ODBC header switches the final parameter's type by bitness: SQLLEN* on +// 64-bit, SQLPOINTER on 32-bit (Windows SDK sqlext.h guards this with +// `defined(_WIN64) || defined(SQLCOLATTRIBUTE_SQLLEN)`). The definition must +// match the declaration exactly or MSVC rejects it as an extern "C" overload +// (C2733) on x86. Mirror the SDK guard and alias back to SQLLEN* internally. +#if defined(_WIN64) || defined(SQLCOLATTRIBUTE_SQLLEN) SQLRETURN SQL_API SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT col, SQLUSMALLINT field, SQLPOINTER charattr, SQLSMALLINT bufmax, SQLSMALLINT* strlen, SQLLEN* numattr) { +#else +SQLRETURN SQL_API SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT col, + SQLUSMALLINT field, SQLPOINTER charattr, + SQLSMALLINT bufmax, SQLSMALLINT* strlen, + SQLPOINTER numattr_) { + SQLLEN* numattr = reinterpret_cast(numattr_); +#endif if (!hstmt) return SQL_ERROR; switch (field) { case SQL_DESC_NAME: From 115495df58fc084865b59322cc9d96a0c2ffa8ab Mon Sep 17 00:00:00 2001 From: Admnwk <220553748+Admnwk@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:12:38 -0300 Subject: [PATCH 2/2] fix(abi): use real AE_PARSE_ERROR in INDEX ON guard (unbreak build) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The INDEX ON SELECT-result guard (PR #118) referenced openads::AE_SYNTAX_ERROR, which is not a member of the openads error enum. On Windows the SAP ACE SDK headers define AE_SYNTAX_ERROR as a macro (see the #undef block in error.h), so a local MSVC build with that header present silently accepted it — but clang/gcc and a clean MSVC build reject it, breaking main on Linux/macOS/PHP and x64. Use AE_PARSE_ERROR (7200), the existing parse/syntax error code the SQL parser already emits, which exists in the enum on all toolchains. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/abi/ace_exports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abi/ace_exports.cpp b/src/abi/ace_exports.cpp index 399f9fd0..6db9ca44 100644 --- a/src/abi/ace_exports.cpp +++ b/src/abi/ace_exports.cpp @@ -13613,7 +13613,7 @@ UNSIGNED32 AdsExecuteSQLDirect(ADSHANDLE hStatement, UNSIGNED8* pucSQL, // Enforce that table name is a simple identifier/filename. const auto& tname = ci.value().table; if (tname.empty() || tname[0] == '(' || tname.find("SELECT") != std::string::npos) { - return fail(openads::AE_SYNTAX_ERROR, + return fail(openads::AE_PARSE_ERROR, "INDEX ON requires a table name, not a SELECT result; " "use SELECT ... ORDER BY/DISTINCT/LIMIT to materialize first"); }