| 508 | } |
| 509 | |
| 510 | void SQLDAMetadata::gatherData(DataBuffer& to) |
| 511 | { |
| 512 | fb_assert(sqlda); // Ensure that data is gathered before take off because later they can be already changed |
| 513 | if (sqlda->sqld <= 0) |
| 514 | { |
| 515 | to.clear(); |
| 516 | return; |
| 517 | } |
| 518 | |
| 519 | const unsigned l = getMessageLength(NULL); |
| 520 | if (speedHackEnabled) |
| 521 | { |
| 522 | to.assign(reinterpret_cast<UCHAR*>(sqlda->sqlvar[0].sqldata), l); |
| 523 | return; |
| 524 | } |
| 525 | |
| 526 | UCHAR* result = to.getBuffer(l, false); |
| 527 | for (unsigned i = 0; i < count; i++) |
| 528 | { |
| 529 | SSHORT* nullInd = (SSHORT*)(result + offsets[i].indOffset); |
| 530 | UCHAR* data = result + offsets[i].offset; |
| 531 | |
| 532 | const XSQLVAR& var = sqlda->sqlvar[i]; |
| 533 | unsigned len = var.sqllen; |
| 534 | if ((var.sqltype & ~1) == SQL_VARYING) |
| 535 | len += sizeof(USHORT); |
| 536 | |
| 537 | if (var.sqltype & 1) |
| 538 | { |
| 539 | // Make sure user has specified a location for null indicator. |
| 540 | if (!var.sqlind) |
| 541 | { |
| 542 | (Arg::Gds(isc_dsql_sqlda_value_err) << |
| 543 | Arg::Gds(isc_dsql_no_sqlind) << |
| 544 | Arg::Gds(isc_dsql_sqlvar_index) << Arg::Num(i) |
| 545 | ).raise(); |
| 546 | } |
| 547 | |
| 548 | *nullInd = *var.sqlind; |
| 549 | } |
| 550 | else |
| 551 | *nullInd = 0; |
| 552 | |
| 553 | // Make sure user has specified a data location (unless NULL). |
| 554 | if (!var.sqldata && !*nullInd && (var.sqltype & ~1) != SQL_NULL) |
| 555 | { |
| 556 | (Arg::Gds(isc_dsql_sqlda_value_err) << |
| 557 | Arg::Gds(isc_dsql_no_sqldata) << |
| 558 | Arg::Gds(isc_dsql_sqlvar_index) << Arg::Num(i) |
| 559 | ).raise(); |
| 560 | } |
| 561 | |
| 562 | // This is assertion instead of error check because such situation is next to impossible: buffer size is calculated a routine above |
| 563 | fb_assert(data + len < result + length); |
| 564 | |
| 565 | // Copy data - unless known to be NULL. |
| 566 | if (!*nullInd) |
| 567 | memcpy(data, var.sqldata, len); |
no test coverage detected