Skip to content

SELECT of a PostgreSQL CHAR/VARCHAR/TEXT Column Using multiple calls SQLGetData results in data truncation (last byte) #98

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

Open
raddakal opened this issue Mar 18, 2025 · 3 comments

Comments

@raddakal
Copy link

When We execute the SELECT query on a table containing a TEXT column with one record of size 1048000 bytes, our ODBC application is able to retrieve one byte less than the actual data.

DDL and DML used in the test

postgres=# create table public.rantexttab(textcol text);
CREATE TABLE

postgres=# insert into public.rantexttab values(repeat('A', 1048000) || 'BB');
INSERT 0 1
postgres=# select length(textcol) from public.rantexttab;
length

1048002
(1 row)

Please note that We are using SQL_C_BINARY as the c type to receive the text column data.

We had allocated a buffer of 1048000 in our ODBC program and the size of teh actual data was 1048002, so 2 subsequent SQLGetData calls were made. In the first call, driver returned correctly 1048000 bytes and the in the second call with the same buffer, driver returns two bytes the last byte contained a null (instead of teh actual last byte in the data).

When we did some more analysis, it seems multiple calls to SQLGetData is causing the issue (i.e., there seems to be some gap in the driver code when multiple calls to SQLGetData are made to retrieve the data of the same column in the result set).

Tried to shorten the test case, and instead of using the size of 1048002 bytes, we could reproduce the same issue using 12 bytes of data in TEXT column. When a buffer of size 10 bytes is used and 2 calls to SQLGetData being made, in the second call we could see the last byte was null instead of actual last byte in the column data.

In the shortened test case, the data used:

postgres=# select length(textcol) from public.rantexttab;
length

 12

(1 row)

postgres=# SELECT textcol from public.rantexttab
postgres-# ;
textcol

AAAAAAAAAABB
(1 row)

Standalone ODBC program output:

bash-4.4$ ./a.out
Connecting to database.
Connected to database.
Fetching results...
First Call to GetData:
ind : 12
Data: AAAAAAAAAA

Second Call to GetData:
ind : 2
Data: B
Free handles.

We can see that in the second call instead of getting BB, we get only B.

Thanks.

pglob.cpp.txt

@raddakal
Copy link
Author

The same issue is seen with CHAR and VARCHAR type columns as well, along with the TEXT type column. The BYTEA type column does not have this issue.

@raddakal raddakal changed the title SELECT of a PostgreSQL TEXT Column Using multiple calls SQLGetData results in data truncation (last byte) SELECT of a PostgreSQL CHAR/VARCHAR/TEXT Column Using multiple calls SQLGetData results in data truncation (last byte) Mar 18, 2025
@davecramer
Copy link
Contributor

cool, thanks for the report

@davecramer
Copy link
Contributor

Are you using the latest version?
I just ran your code with some slight changes to connect and the result was

./pglob                                                                        
Connecting to database.
Connected to database.
Fetching results...
First Call to GetData: 
ind : 1048002
Data: AAAAAAAAAA��
Second Call to GetData: 
ind : 1047992
Data: AAAAAAAAAA��
Free handles.

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

2 participants