ClickHouse / clickhouse-cpp

C++ client library for ClickHouse
Apache License 2.0
306 stars 159 forks source link

Function of select called lambda response three times, also if i try call delete record in labda - I have exception Sig fault #315

Closed MimikFc7 closed 1 year ago

MimikFc7 commented 1 year ago
 client_database->Select("select time from base order by time DESC limit 1;",[=](const Block &output){
        qDebug() << " ROW_CMT " << output.GetRowCount();
        if(output.GetRowCount() > 0){
            time_t last_record = output[0]->As<ColumnDateTime>()->At(0);
            QString record_delete_cmd =  QString::asprintf("delete from stock_currency where time =%lu",last_record);
            client_database->Execute(record_delete_cmd.toLocal8Bit().data());
            client_database->ResetConnection();
         }});
Enmk commented 1 year ago

Hi @MimikFc7, thank you for reporting an issue!

Callback is supposed to be called multiple times: CH pushes data to client in multiple blocks, callback is called for each of those blocks + 1 time for the last, empty block in the end.

Also, your example effectively tries to execute another query while the current one is still in the process, messing up the library's internals, which is not supported by clickhouse-cpp (but still a poor excuse for crashing and will be fixed).

Your example can be re-written to something like this:

// event #1
std::optional<time_t> last_record;
// event #2
client_database->Select("select time from base order by time DESC limit 1;",[=, &last_record](const Block &output){
  // events ## 3, 4, ... up to N 
  qDebug() << " ROW_CMT " << output.GetRowCount();
  if(output.GetRowCount() == 0)
    return;

  last_record = output[0]->As<ColumnDateTime>()->At(0);
});

// event #N+1
if (last_record) {
  QString record_delete_cmd =  QString::asprintf("delete from stock_currency where time =%lu", *last_record);
  client_database->Execute(record_delete_cmd.toLocal8Bit().data());
  client_database->ResetConnection();
}

Note that ALL methods of Client are synchronous and non-tread-safe, meaning that callbacks are executed on the same thread, and are triggered BEFORE Select returns.

So all events from the example above are sequential and are on the same thread: