JuliaDatabases/ODBC.jl

SQLPrepare fails on long SQL strings

xitology opened this issue · 0 comments

When you prepare a query with ODBC, it fails when the SQL string is longer than 2^15 characters.

Here is an example:

using ODBC, Tables

# Specify the ODBC connection string using this environment variable.
const ODBC_CONNECTION_STRING = ENV["ODBC_CONNECTION_STRING"]

conn = DBInterface.connect(ODBC.Connection, ODBC_CONNECTION_STRING)
sql = "SELECT" * " "^(2^16) * "1 AS x"

# Succeeds.
cr = DBInterface.execute(conn, sql)
display(Tables.rowtable(cr))

# Fails on the next line!
stmt = DBInterface.prepare(conn, sql)
cr = DBInterface.execute(stmt)
display(Tables.rowtable(cr))
1-element Vector{@NamedTuple{x::Int32}}:
 (x = 1,)
ERROR: LoadError: InexactError: trunc(Int16, 65548)
Stacktrace:
  [1] throw_inexacterror(f::Symbol, ::Type{Int16}, val::Int64)
    @ Core ./boot.jl:631
  [2] checked_trunc_sint(::Type{Int16}, x::Int64)
    @ Core ./boot.jl:653 [inlined]
  [3] toInt16(x::Int64)
    @ Core ./boot.jl:679 [inlined]
  [4] Int16(x::Int64)
    @ Core ./boot.jl:779 [inlined]
  [5] convert
    @ Base ./number.jl:7 [inlined]
  [6] cconvert
    @ Base ./essentials.jl:538 [inlined]
  [7] SQLPrepare(stmt::Ptr{Nothing}, query::String)
    @ ODBC.API ~/MechanicalRabbit/ODBC.jl/src/API.jl:89
  [8] prepare(dbc::ODBC.API.Handle, sql::String)
    @ ODBC.API ~/MechanicalRabbit/ODBC.jl/src/API.jl:119
  [9] prepare(conn::ODBC.Connection, sql::String)
    @ ODBC ~/MechanicalRabbit/ODBC.jl/src/dbinterface.jl:142
 [10] top-level scope
    @ ~/MechanicalRabbit/ODBC.jl/long-sql.jl:14
in expression starting at /home/xi/MechanicalRabbit/ODBC.jl/long-sql.jl:14

This is caused by invalid type specification in SQLPrepare. In fact, both SQLPrepare and SQLExecDirect specify the type of the query length parameter incorrectly: the former uses Int16 and the latter Int. But according to the documentation these functions expect a SQLINTEGER, that is, Int32.