diff --git a/convert.c b/convert.c index d31a783b..829071f0 100644 --- a/convert.c +++ b/convert.c @@ -4760,7 +4760,7 @@ MYLOG(DETAIL_LOG_LEVEL, "ipara=%p paramName=%s paramType=%d %d proc_return=%d\n" } if (qb->param_mode == RPM_BUILDING_PREPARE_STATEMENT) { - char pnum[16]; + char pnum[32]; qb->dollar_number++; if (ipara && diff --git a/test/expected/many-params.out b/test/expected/many-params.out new file mode 100644 index 00000000..d11d853c --- /dev/null +++ b/test/expected/many-params.out @@ -0,0 +1,3 @@ +connected +column 1000: 2026-10-08 12:34:56 +disconnecting diff --git a/test/src/many-params-test.c b/test/src/many-params-test.c new file mode 100644 index 00000000..93f8f7f8 --- /dev/null +++ b/test/src/many-params-test.c @@ -0,0 +1,71 @@ +/* + * A statement with 1000 parameters, all bound as SQL_TYPE_TIMESTAMP. + * + * With server-side prepare, the driver writes each placeholder with a + * type cast, e.g. "$1000::timestamp". The placeholder must reach the + * server whole, whatever the parameter number. + */ +#include +#include +#include + +#include "common.h" + +#define NPARAMS 1000 + +int +main(int argc, char **argv) +{ + SQLRETURN rc; + HSTMT hstmt = SQL_NULL_HSTMT; + char sql[16 + NPARAMS * 3]; + char *p; + int i; + SQL_TIMESTAMP_STRUCT ts; + SQLLEN cbTs = sizeof(ts); + char buf[64]; + SQLLEN ind; + + test_connect_ext("UseServerSidePrepare=1"); + + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt); + CHECK_CONN_RESULT(rc, "SQLAllocHandle failed", conn); + + /* SELECT ?, ?, ... with NPARAMS placeholders */ + p = sql + sprintf(sql, "SELECT ?"); + for (i = 1; i < NPARAMS; i++) + p += sprintf(p, ", ?"); + + memset(&ts, 0, sizeof(ts)); + ts.year = 2026; + ts.month = 10; + ts.day = 8; + ts.hour = 12; + ts.minute = 34; + ts.second = 56; + + for (i = 1; i <= NPARAMS; i++) + { + rc = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, + SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, + 19, 0, &ts, sizeof(ts), &cbTs); + CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt); + } + + rc = SQLExecDirect(hstmt, (SQLCHAR *) sql, SQL_NTS); + CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); + + rc = SQLFetch(hstmt); + CHECK_STMT_RESULT(rc, "SQLFetch failed", hstmt); + + rc = SQLGetData(hstmt, NPARAMS, SQL_C_CHAR, buf, sizeof(buf), &ind); + CHECK_STMT_RESULT(rc, "SQLGetData failed", hstmt); + printf("column %d: %s\n", NPARAMS, buf); + + rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + CHECK_STMT_RESULT(rc, "SQLFreeHandle failed", hstmt); + + test_disconnect(); + + return 0; +} diff --git a/test/tests b/test/tests index 359c351b..b90dd3ec 100644 --- a/test/tests +++ b/test/tests @@ -71,4 +71,5 @@ TESTBINS = exe/connect-test \ exe/percent-decode-test \ exe/connstring-escape-test \ exe/dbms-version-test \ - exe/surrogate-pair-test + exe/surrogate-pair-test \ + exe/many-params-test