@@ -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