Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error converting ODBC.Cursor to DataFrame #306

Closed
ElOceanografo opened this issue Jul 1, 2020 · 5 comments
Closed

Error converting ODBC.Cursor to DataFrame #306

ElOceanografo opened this issue Jul 1, 2020 · 5 comments

Comments

@ElOceanografo
Copy link

I'm attempting to update some of my code to the ODBC 1.0 interface, and it no longer works. Specifically, when I try to convert the results of a query to a DataFrame, I get this error:

result = DBInterface.execute(connection, sql_query)
DataFrame(result)


ERROR: BoundsError: attempt to access 11-element Array{UInt8,1} at index [1:12]
Stacktrace:
 [1] throw_boundserror(::Array{UInt8,1}, ::Tuple{UnitRange{Int64}}) at .\abstractarray.jl:537
 [2] checkbounds at .\abstractarray.jl:502 [inlined]
 [3] getindex at .\array.jl:793 [inlined]
 [4] getcolumn(::ODBC.Row, ::Type{Dec64}, ::Int64, ::Symbol) at C:\...\.julia\packages\ODBC\2MEHX\src\dbinterface.jl:336
 [5] macro expansion at C:\...\.julia\packages\Tables\okt7x\src\utils.jl:144 [inlined]
 [6] eachcolumns at C:\...\.julia\packages\Tables\okt7x\src\utils.jl:139 [inlined]
 [7] buildcolumns(::Tables.Schema{(:SURVEY, :TRANSECT, :INTERVAL, :START_LONGITUDE, :START_LATITUDE),Tuple{Dec64,Union{Missing, Dec64},Dec64,Dec64,Dec64}}, ::ODBC.Cursor{false,false}) at C:\...\.julia\packages\Tables\okt7x\src\fallbacks.jl:127      
 [8] columns at C:\...\.julia\packages\Tables\okt7x\src\fallbacks.jl:228 [inlined]
 [9] DataFrame(::ODBC.Cursor{false,false}; copycols::Bool) at C:\...\.julia\packages\DataFrames\htZzm\src\other\tables.jl:43
 [10] DataFrame(::ODBC.Cursor{false,false}) at C:\...\.julia\packages\DataFrames\htZzm\src\other\tables.jl:34
 [11] top-level scope at none:0

The same query worked in the pre-1.0 interface (i.e. using ODBC.query(connection, sql_query)), and when I copy-paste the sql_query as a string into Oracle SQL Developer it returns the expected table, so that isn't the issue. Other queries to other tables in the same database also run and convert to DataFrame without problems.

In case it helps, this is what the result of the execute call looks like:

ODBC.Cursor{false,false}(ODBC.API.Handle(3, Ptr{Nothing} @0x0000000041691900), -1, 5, [:SURVEY, :TRANSECT, :INTERVAL, :START_LONGITUDE, :START_LATITUDE], Type[Dec64, Union{Missing, Dec64}, Dec64, Dec64, Dec64], Dict(:START_LATITUDE => 5,:TRANSECT => 2,:SURVEY 
=> 1,:START_LONGITUDE => 4,:INTERVAL => 3), 1, 1, ODBC.Binding[ODBC.Binding(1, 3, ODBC.Buffer(UInt8[0x32, 0x30, 0x31, 0x38, 0x30, 
0x37, 0x00, 0x00, 0x60]), 9, [6], false, 6), ODBC.Binding(1, 3, ODBC.Buffer(UInt8[0x31, 0x00, 0xc4, 0x17, 0x00, 0x00, 0x00, 0x00]), 8, [1], false, 1), ODBC.Binding(1, 3, ODBC.Buffer(UInt8[0x32, 0x30, 0x31, 0x38, 0x30, 0x36, 0x30, 0x38, 0x30, 0x35, 0x35, 0x33, 
0x32, 0x30, 0x00]), 15, [14], false, 14), ODBC.Binding(1, 3, ODBC.Buffer(UInt8[0x2d, 0x31, 0x36, 0x30, 0x2e, 0x39, 0x31, 0x35, 0x34, 0x32, 0x00]), 11, [12], false, 12), ODBC.Binding(1, 3, ODBC.Buffer(UInt8[0x35, 0x37, 0x2e, 0x31, 0x37, 0x33, 0x35, 0x35, 0x33, 
0x34, 0x00]), 11, [10], false, 10)], AbstractArray{T,1} where T[], Any["column name" "column type" … "nullable" "long data"; :SURVEY Dec64 … false false; … ; :START_LONGITUDE Dec64 … false false; :START_LATITUDE Dec64 … false false])
@quinnj
Copy link
Member

quinnj commented Jul 28, 2020

@ElOceanografo , sorry for the delay here; could you share which database you're connected to here? What version? Are you running on linux/osx/windows? I'd like to try and reproduce the error you're seeing to figure out what's going on.

quinnj added a commit that referenced this issue Jul 28, 2020
Attempt at fixing #306. It's a little unclear what's going on here; for
some reason, our length indicator is coming back with a value of 12,
even though the column size told us it wouldn't be more than 11 bytes. I
think we're correctly incrementing the columnsize of Dec64 by 1 because
the C storage is SQL_C_CHAR, but yeah, I don't understand why it's
coming back w/ more bytes that we're expecting.

My main worry with this fix is if we're actually missing a byte that
should be included in the final Dec64 number, but this should at least
allow us to materialize the full result.
@quinnj
Copy link
Member

quinnj commented Jul 28, 2020

@ElOceanografo , could you try the fix I have in #308 to see if it fixes your issue? I'm a little worried that the solution in that PR is missing out on a byte that the result should have for the START_LONGITUDE column. You can checkout the fix by doing ] add ODBC#jq/fixdec, then restart julia and run your query.

@ElOceanografo
Copy link
Author

Sorry for the slow response. I'm not sure what happened, but after updating Julia from 1.4 to 1.5 and updating ODBC to v1.0.3, I am no longer getting this error. I'll try out a few more queries on different databases and close the issue if it doesn't crop up again.

@caligo-mentis
Copy link

Just faced similar problem on MS SQL Server, ODBC v1.0.4, julia 1.5: iteration through Table rows failed with similar BoundsError on

bytes = data[1:b.totallen]

Branch jq/fixdec works normally.

Would try to isolate data later this week.

@quinnj
Copy link
Member

quinnj commented Mar 31, 2021

@caligo-mentis , if you run into issues on the current release, please open a new issue. I'm going to close this one as I think the original issue is resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants