Commit 8bce4b2
committed
Fix silent data loss binding numeric to VARCHAR via stored procedure
Binding a SQL_C_SLONG (or any numeric/datetime C-type) to a Firebird
VARCHAR parameter and executing the statement many times — e.g. a
stored-procedure `EXECUTE PROCEDURE sp(?, ?)` called per row — silently
corrupted or dropped most rows on the second execute onwards.
Two cooperating bugs caused this, both fixed in this commit:
1. `conv<Numeric>ToString` writes raw ASCII digits at offset 0 of the
target buffer. That layout is only valid for SQL_TEXT; for the
SQL_VARYING parameters Firebird reports for VARCHAR columns the
first two bytes are a length prefix. Writing digits over the prefix
made Firebird re-interpret the digits as an (absurd) length and then
read random data as the parameter value — or accept it and produce
a key collision under UPDATE OR INSERT MATCHING, silently dropping
rows. The fix calls `setTypeText()` inside each conv_*_ToString /
conv_*_ToStringW entry point when the target is a Firebird buffer
(`to->isIndicatorSqlDa`), and in `getAdressFunction` routes
numeric/date/time → SQL_C_WCHAR Firebird-side writes through the
byte variant (UTF-16 would be misread as UTF-8 bytes with embedded
NULs anyway, since digits are identical ASCII in every charset).
2. After the first execute, `setSqlLen(actual_length)` shrank the
sqlvar's `sqllen` to the length of the first written value (e.g. 1
for "3"). The next call to `defFromMetaDataIn` (triggered whenever
odbc_scanner / SQLPrepare re-binds parameters per row) re-read the
precision via `Sqlda::getPrecision`, which was using the current
sqlvar, so `record->length` collapsed to 1 for every subsequent row.
Multi-digit values then got truncated to their first character
(e.g. 10 → "1", 27 → "2"), collapsing hundreds of rows onto a
handful of keys. `Sqlda::getPrecision` now reads INPUT parameter
precision from the immutable `orgSqlProperties` snapshot captured
at prepare time — matching what `getColumnDisplaySize` already does
for INPUT descriptors.
Adds ParamConversionsTest.Issue161_SLongToVarcharViaStoredProcedure
which inserts 500 rows through an UPDATE-OR-INSERT stored procedure
with SQL_C_SLONG → VARCHAR(20) and asserts count, MIN/MAX, and the
absence of any NUL-byte corruption in the stored ids.
Fixes: duckdb/odbc-scanner#1611 parent ca97f46 commit 8bce4b2
3 files changed
Lines changed: 204 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
759 | 759 | | |
760 | 760 | | |
761 | 761 | | |
762 | | - | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
763 | 776 | | |
764 | 777 | | |
765 | 778 | | |
| |||
798 | 811 | | |
799 | 812 | | |
800 | 813 | | |
801 | | - | |
802 | | - | |
| 814 | + | |
| 815 | + | |
803 | 816 | | |
804 | 817 | | |
805 | 818 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
208 | 208 | | |
209 | 209 | | |
210 | 210 | | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
211 | 219 | | |
212 | 220 | | |
213 | 221 | | |
| |||
263 | 271 | | |
264 | 272 | | |
265 | 273 | | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
266 | 277 | | |
267 | 278 | | |
268 | 279 | | |
| |||
320 | 331 | | |
321 | 332 | | |
322 | 333 | | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
323 | 337 | | |
324 | 338 | | |
325 | 339 | | |
| |||
357 | 371 | | |
358 | 372 | | |
359 | 373 | | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
360 | 377 | | |
361 | 378 | | |
362 | 379 | | |
| |||
391 | 408 | | |
392 | 409 | | |
393 | 410 | | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
394 | 414 | | |
395 | 415 | | |
396 | 416 | | |
| |||
435 | 455 | | |
436 | 456 | | |
437 | 457 | | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
438 | 461 | | |
439 | 462 | | |
440 | 463 | | |
| |||
523 | 546 | | |
524 | 547 | | |
525 | 548 | | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
526 | 552 | | |
527 | 553 | | |
528 | 554 | | |
| |||
560 | 586 | | |
561 | 587 | | |
562 | 588 | | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
563 | 592 | | |
564 | 593 | | |
565 | 594 | | |
| |||
596 | 625 | | |
597 | 626 | | |
598 | 627 | | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
599 | 631 | | |
600 | 632 | | |
601 | 633 | | |
| |||
1303 | 1335 | | |
1304 | 1336 | | |
1305 | 1337 | | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
1306 | 1348 | | |
1307 | 1349 | | |
1308 | 1350 | | |
| |||
1384 | 1426 | | |
1385 | 1427 | | |
1386 | 1428 | | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
| 1434 | + | |
1387 | 1435 | | |
1388 | 1436 | | |
1389 | 1437 | | |
| |||
1766 | 1814 | | |
1767 | 1815 | | |
1768 | 1816 | | |
| 1817 | + | |
| 1818 | + | |
| 1819 | + | |
| 1820 | + | |
1769 | 1821 | | |
1770 | 1822 | | |
1771 | 1823 | | |
| |||
1788 | 1840 | | |
1789 | 1841 | | |
1790 | 1842 | | |
| 1843 | + | |
| 1844 | + | |
| 1845 | + | |
| 1846 | + | |
1791 | 1847 | | |
1792 | 1848 | | |
1793 | 1849 | | |
| |||
1873 | 1929 | | |
1874 | 1930 | | |
1875 | 1931 | | |
| 1932 | + | |
| 1933 | + | |
| 1934 | + | |
| 1935 | + | |
1876 | 1936 | | |
1877 | 1937 | | |
1878 | 1938 | | |
| |||
1895 | 1955 | | |
1896 | 1956 | | |
1897 | 1957 | | |
| 1958 | + | |
| 1959 | + | |
| 1960 | + | |
| 1961 | + | |
1898 | 1962 | | |
1899 | 1963 | | |
1900 | 1964 | | |
| |||
1987 | 2051 | | |
1988 | 2052 | | |
1989 | 2053 | | |
| 2054 | + | |
| 2055 | + | |
| 2056 | + | |
| 2057 | + | |
1990 | 2058 | | |
1991 | 2059 | | |
1992 | 2060 | | |
| |||
2014 | 2082 | | |
2015 | 2083 | | |
2016 | 2084 | | |
| 2085 | + | |
| 2086 | + | |
| 2087 | + | |
| 2088 | + | |
2017 | 2089 | | |
2018 | 2090 | | |
2019 | 2091 | | |
| |||
2164 | 2236 | | |
2165 | 2237 | | |
2166 | 2238 | | |
| 2239 | + | |
| 2240 | + | |
| 2241 | + | |
| 2242 | + | |
2167 | 2243 | | |
2168 | 2244 | | |
2169 | 2245 | | |
| |||
2196 | 2272 | | |
2197 | 2273 | | |
2198 | 2274 | | |
| 2275 | + | |
| 2276 | + | |
| 2277 | + | |
| 2278 | + | |
2199 | 2279 | | |
2200 | 2280 | | |
2201 | 2281 | | |
| |||
2356 | 2436 | | |
2357 | 2437 | | |
2358 | 2438 | | |
| 2439 | + | |
| 2440 | + | |
| 2441 | + | |
| 2442 | + | |
2359 | 2443 | | |
2360 | 2444 | | |
2361 | 2445 | | |
| |||
2392 | 2476 | | |
2393 | 2477 | | |
2394 | 2478 | | |
| 2479 | + | |
| 2480 | + | |
| 2481 | + | |
| 2482 | + | |
2395 | 2483 | | |
2396 | 2484 | | |
2397 | 2485 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
277 | 277 | | |
278 | 278 | | |
279 | 279 | | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
280 | 380 | | |
281 | 381 | | |
282 | 382 | | |
| |||
0 commit comments