Skip to content

Commit

Permalink
Fix case when SQLGetData data size exceeds column size (#346)
Browse files Browse the repository at this point in the history
* Fix case when SQLGetData data size exceeds column size

Fixes #328. Ok, a bit nasty, but here's the rundown:
  * This is mostly outlined [here](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdata-function?view=sql-server-ver16#retrieving-data-with-sqlgetdata)
  * The issue is that for our result set, the cursor may be told that a give column has a certain size in bytes, particularly for variable-sized columns like VARCHAR
  * BUT, the driver then may have to "convert to the target type" and this conversion may result in the _actual_ data size being larger than we orignally allocated for
  * But wait, you may ask, don't we already account for this case [here](https://github.com/JuliaDatabases/ODBC.jl/blob/f38f771557a5763f777ed0f441c2cc5a72f41c70/src/utils.jl#L328) by resizing the buffer and calling SQLGetData again to retrieve the rest of the data?
  * Why yes, we do, but only for "long" data types, which is the primary use case for the multiple SQLGetData calls
  * So basically this is _another_ case where, totally depending on the db driver, we might end up with truncated data which will result in `API.SQL_SUCCESS_WITH_INFO` being returned from SQLGetData

Thankfully the fix is relatively easy: we just need to use our buffer-resizing branch if the data type is long OR SQLGetData returns this success with info status code.

* bump some versions and update ci
  • Loading branch information
quinnj authored Aug 11, 2022
1 parent f38f771 commit a7ce136
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
fail-fast: false
matrix:
version:
- 1.0
- 1.6
- 1 # automatically expands to the latest stable 1.x release of Julia
- nightly
os:
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ODBC"
uuid = "be6f12e9-ca4f-5eb2-a339-a4f995cc0291"
version = "1.0.4"
version = "1.1.0"

[deps]
DBInterface = "a10d1c49-ce27-4219-8d33-6db1a4562965"
Expand All @@ -22,7 +22,7 @@ DecFP = "0.4.10, 1"
Tables = "1"
Scratch = "1"
iODBC_jll = "3.52"
julia = "1.5"
julia = "1.6"
unixODBC_jll = "2.3"

[extras]
Expand Down
2 changes: 1 addition & 1 deletion src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ getbindings(stmt, columnar, ctypes, sqltypes, columnsizes, nullables, longtexts,
function getdata(stmt, i, b::Binding)
status = API.SQLGetData(API.getptr(stmt), i, b.valuetype, pointer(b.value), b.bufferlength, b.strlen_or_indptr)
b.totallen = b.strlen_or_indptr[1]
if b.long && b.strlen_or_indptr[1] != API.SQL_NULL_DATA
if (b.long || status == API.SQL_SUCCESS_WITH_INFO) && b.strlen_or_indptr[1] != API.SQL_NULL_DATA
chardata = b.valuetype != API.SQL_C_BINARY
if b.strlen_or_indptr[1] == API.SQL_NO_TOTAL
b.totallen = b.bufferlength - 1
Expand Down

2 comments on commit a7ce136

@quinnj
Copy link
Member Author

@quinnj quinnj commented on a7ce136 Aug 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/66084

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.1.0 -m "<description of version>" a7ce1365d6ab070196dedc8dfab4ea8f30213587
git push origin v1.1.0

Please sign in to comment.