Odbc_prepare error when using library(odbc) with DuckDB

Hi,

I am using SWI-Prolog library(odbc) with DuckDB through ODBC.

I can run a query successfully with:

odbc_query(opnt, SQL, Row).

But the equivalent prepared-statement version fails at prepare time with:

ERROR: odbc:odbc_prepare/5: Not enough resources: memory

This happens even when I avoid default and provide explicit parameter types.

Minimal shape:

:- use_module(library(odbc)).

open_db :-
    odbc_connect('DuckDB', _,
                 [ alias(opnt),
                   open(once),
                   access_mode(read),
                   encoding(utf8)
                 ]).

test_prepare(RsId, K, IntervalId) :-
    open_db,
    odbc_prepare(
        opnt,
        'SELECT DISTINCT e.intervalId
           FROM variant v
           JOIN enhancer e
             ON e.chromosome = v.chromosome
          WHERE list_contains(v.rsIds, ?)
            AND CASE
                  WHEN v.position BETWEEN e.start AND e."end" THEN 0
                  WHEN v.position < e.start THEN e.start - v.position
                  ELSE v.position - e."end"
                END <= ?',
        [atom > varchar(64), integer],
        Statement,
        []
    ),
    call_cleanup(
        odbc_execute(Statement, [RsId, K], row(IntervalId)),
        odbc_free_statement(Statement)
    ).

The same SQL runs fine:

  1. in DuckDB shell
  2. via odbc_query/3

So this seems specific to the prepared-statement ODBC path.

Questions:

  1. Is there any doc on the error? I couldn’t find much searching online
  2. Is this likely a DuckDB ODBC driver limitation rather than a SWI-Prolog issue?
  3. Is there a recommended SWI-Prolog workaround besides using odbc_query/3?

Thanks.

Its a failing malloc(). Of course, it could be some false alarm or something causing it to allocate too much memory.

Unclear. SWI-Prolog ODNC is pretty old and heavily used in several production settings. But, the code contains quite a few work arounds for driver bugs and maybe this driver has yet another :frowning:

Find the cause. Basically use a C debugger or add print statements to see where exactly it is failing. That could give a hint.