Skip to content

Commit 0d72926

Browse files
authored
Merge pull request #156 from duckdb/jray/support-pivot
add support for pivot
2 parents 17be068 + bffad99 commit 0d72926

File tree

1 file changed

+55
-3
lines changed

1 file changed

+55
-3
lines changed

src/http_server.cpp

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,13 +401,63 @@ void HttpServer::DoHandleRun(const httplib::Request &req,
401401
});
402402
}
403403

404+
unique_ptr<SQLStatement> last_statement;
405+
406+
auto statements = connection->ExtractStatements(content);
407+
auto statement_count = statements.size();
408+
409+
if (statement_count == 0) {
410+
SetResponseErrorResult(res, "No statements");
411+
return;
412+
}
413+
414+
// If there's more than one statement, run all but the last.
415+
if (statement_count > 1) {
416+
for (auto i = 0; i < statement_count - 1; ++i) {
417+
auto pending = connection->PendingQuery(std::move(statements[i]));
418+
// Return any error found before execution.
419+
if (pending->HasError()) {
420+
SetResponseErrorResult(res, pending->GetError());
421+
return;
422+
}
423+
// Execute tasks until result is ready (or there's an error).
424+
auto exec_result = PendingExecutionResult::RESULT_NOT_READY;
425+
while (!PendingQueryResult::IsResultReady(exec_result)) {
426+
exec_result = pending->ExecuteTask();
427+
if (exec_result == PendingExecutionResult::BLOCKED ||
428+
exec_result == PendingExecutionResult::NO_TASKS_AVAILABLE) {
429+
std::this_thread::sleep_for(std::chrono::milliseconds(1));
430+
}
431+
}
432+
// Return any error found during execution.
433+
switch (exec_result) {
434+
case PendingExecutionResult::EXECUTION_ERROR:
435+
SetResponseErrorResult(res, pending->GetError());
436+
return;
437+
case PendingExecutionResult::EXECUTION_FINISHED:
438+
case PendingExecutionResult::RESULT_READY:
439+
// ignore the result
440+
pending->Execute();
441+
break;
442+
default:
443+
SetResponseErrorResult(
444+
res, StringUtil::Format("Unexpected PendingExecutionResult: %s",
445+
exec_result));
446+
return;
447+
}
448+
}
449+
}
450+
451+
// Get the last statement.
452+
auto &statement_to_run = statements[statement_count - 1];
453+
404454
// We use a pending query so we can execute tasks and fetch chunks
405455
// incrementally. This enables cancellation.
406456
unique_ptr<PendingQueryResult> pending;
407457

408458
// Create pending query, with request content as SQL.
409459
if (parameter_values.size() > 0) {
410-
auto prepared = connection->Prepare(content);
460+
auto prepared = connection->Prepare(std::move(statement_to_run));
411461
if (prepared->HasError()) {
412462
SetResponseErrorResult(res, prepared->GetError());
413463
return;
@@ -420,7 +470,7 @@ void HttpServer::DoHandleRun(const httplib::Request &req,
420470
}
421471
pending = prepared->PendingQuery(values, true);
422472
} else {
423-
pending = connection->PendingQuery(content, true);
473+
pending = connection->PendingQuery(std::move(statement_to_run), true);
424474
}
425475

426476
if (pending->HasError()) {
@@ -468,7 +518,9 @@ void HttpServer::DoHandleRun(const httplib::Request &req,
468518
break;
469519
}
470520
default:
471-
SetResponseErrorResult(res, "Unexpected PendingExecutionResult");
521+
SetResponseErrorResult(
522+
res, StringUtil::Format("Unexpected PendingExecutionResult: %s",
523+
exec_result));
472524
break;
473525
}
474526
}

0 commit comments

Comments
 (0)