| 520 | } |
| 521 | |
| 522 | std::vector<bolt::RowVectorPtr> PrestoQueryRunner::executeVector( |
| 523 | const std::string& sql, |
| 524 | const std::vector<bolt::RowVectorPtr>& input, |
| 525 | const bolt::RowTypePtr& resultType) { |
| 526 | auto inputType = asRowType(input[0]->type()); |
| 527 | if (inputType->size() == 0) { |
| 528 | // The query doesn't need to read any columns, but it needs to see a |
| 529 | // specific number of rows. Make new 'input' as single all-null BIGINT |
| 530 | // column with as many rows as original input. This way we'll be able to |
| 531 | // create a 'tmp' table will the necessary number of rows. |
| 532 | vector_size_t numInput = 0; |
| 533 | for (const auto& v : input) { |
| 534 | numInput += v->size(); |
| 535 | } |
| 536 | |
| 537 | auto column = BaseVector::createNullConstant(BIGINT(), numInput, pool()); |
| 538 | auto rowVector = std::make_shared<RowVector>( |
| 539 | pool(), |
| 540 | ROW({"x"}, {BIGINT()}), |
| 541 | nullptr, |
| 542 | numInput, |
| 543 | std::vector<VectorPtr>{column}); |
| 544 | return executeVector(sql, {rowVector}, resultType); |
| 545 | } |
| 546 | |
| 547 | // Create tmp table in Presto using DWRF file format and add a single |
| 548 | // all-null row to it. |
| 549 | |
| 550 | std::stringstream nullValues; |
| 551 | for (auto i = 0; i < inputType->size(); ++i) { |
| 552 | appendComma(i, nullValues); |
| 553 | nullValues << fmt::format( |
| 554 | "cast(null as {})", toTypeSql(inputType->childAt(i))); |
| 555 | } |
| 556 | |
| 557 | execute("DROP TABLE IF EXISTS tmp"); |
| 558 | |
| 559 | execute(fmt::format( |
| 560 | "CREATE TABLE tmp({}) WITH (format = 'DWRF') AS SELECT {}", |
| 561 | folly::join(", ", inputType->names()), |
| 562 | nullValues.str())); |
| 563 | |
| 564 | // Query Presto to find out table's location on disk. |
| 565 | auto results = execute("SELECT \"$path\" FROM tmp"); |
| 566 | |
| 567 | auto filePath = extractSingleValue<StringView>(results); |
| 568 | auto tableDirectoryPath = fs::path(filePath).parent_path(); |
| 569 | |
| 570 | // Delete the all-null row. |
| 571 | execute("DELETE FROM tmp"); |
| 572 | |
| 573 | // Create a new file in table's directory with fuzzer-generated data. |
| 574 | auto newFilePath = fs::path(tableDirectoryPath) |
| 575 | .append("fuzzer.dwrf") |
| 576 | .string() |
| 577 | .substr(strlen("file:")); |
| 578 | |
| 579 | auto writerPool = rootPool()->addAggregateChild("writer"); |
no test coverage detected