Repository navigation
Incomplete logging to file when using log_query_path option #288
Description
Activity
- changed the title
[-]Incomplete logging to file when using *log_query_path* option[/-][+]Incomplete logging to file when using log_query_path option[/+]on Aug 27, 2025 After some investigation I found that root cause of such behavior is that
DuckDBCommandalways execute queries using methodPreparedStatement.PrepareMultiple. Which uses these C API methods:duckdb_extract_statementsduckdb_prepare_extracted_statement- group of API calls related to parameters binding (e.g.
duckdb_nparams,duckdb_bind_parameter_index, ...) duckdb_execute_preparedorduckdb_execute_prepared_streaming
But if DuckDBCommand does not have any parameters defined it is possible to execute query using this C API call
duckdb_query.I applied this logic (pseudo code below):
if (parameters.Count > 0 || UseStreamingMode ) // duckdb_query does not support streaming mode { //current execution path using prepared statements } else { var statementCount = // call duckdb_extract_statements; if (statementCount == 1) { //execute `duckdb_query` directly } else { //use current code flow with prepared statements. } }
Using this logic DuckDB.NET logs failed queries as well.
If you are interested in that change I could try to polish it up and create PR.
@joostas I think duckdb_execute_prepared should be updated to log failed queries. In that case, it would also work with DuckDB.NET.
In given case even if
duckdb_execute_preparedwould log failed queries I don't think DuckDB.NET would work "out of the box", because code fails fast earlier:var status = NativeMethods.ExtractStatements.DuckDBPrepareExtractedStatement(connection, extractedStatements, index, out var statement); if (status.IsSuccess()) { using var preparedStatement = new PreparedStatement(statement); yield return preparedStatement.Execute(parameters, useStreamingMode); } else { var errorMessage = NativeMethods.PreparedStatements.DuckDBPrepareError(statement).ToManagedString(false); throw new DuckDBException(string.IsNullOrEmpty(errorMessage) ? "DuckDBQuery failed" : errorMessage); }
But when
DuckDBCommandhas no parameters, I don’t see any reason to execute the query indirectly throughduckdb_prepare_extracted_statementandduckdb_execute_preparedinstead of directly using duckdb_query.Executing directly should be more efficient and will give functionality to improve query logging as well. What do you think @Giorgi?
That code can be changed 🙂
If
log_query_pathis intended to log failed parameterized queries too, the better fix is the one I suggested. If it is not designed for that, I can consider making that changed. I think you should open an issue/discussion in the duckdb repoIMHO from the perspective of the C API, the behavior appears to be correct. When using a Prepared Statement, if the preparation phase fails, the query itself is not executed - hence, it is not logged. This seems consistent with expected behavior.
However, when using DuckDBCommand without any parameters, such as in the following example:
using var command = connection.CreateCommand(); command.CommandText = "SELECT 1 FROM B"; using var reader = command.ExecuteReader(); //...
I would anticipate that the query is executed directly, as there is no preparation involved. In such a case, if the query fails, I would expect it to be logged accordingly.
Therefore, it seems that the issue may lie more in how the C API calls are wrapped within
DuckDBCommand, rather than in the C API itself.With your suggested workaround, the following will still not log an error:
cmd.CommandText = "CREATE TABLE person (name VARCHAR, age BIGINT); INSERT INTO person VALUES ('Alice', ?); SELECT * FROM test"; cmd.Parameters.Add(new DuckDBParameter(5)); cmd.ExecuteNonQuery();
True. The given solution won’t cover all cases, but it will handle the scenario where
CommandTextis a single SQL statement without any parameters. I think this is quite a common case.
DuckDB provides local configuration option that lets log all executed queries to file:
When this setting is enabled and queries are executed through DuckDB.NET, the log file records only successful queries - failed queries are not logged. In contrast, when using the DuckDB CLI, both successful and failed queries are logged.
CLI behavior:
Successful query and failed to execute query are logged. Didn't log failed to parse query.
DuckDB.NET behavior (DuckDBCommand):
Logs
Only successful queries were logged.