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

Standardize get_info() return types #398

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

gaborcsardi
Copy link

What does this PR do?

Use the official return types in get_info(), as in the docs. See
https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function?view=sql-server-ver16

InfoValuePtr
[Output] Pointer to a buffer in which to return the information.
Depending on the InfoType requested, the information returned will
be one of the following: a null-terminated character string, an
SQLUSMALLINT value, an SQLUINTEGER bitmask, an SQLUINTEGER flag,
a SQLUINTEGER binary value, or a SQLULEN value.

It seems better to use these types instead of matching them to the C data types, which can be platform dependent. For example SQLUINTEGER is currently different on Linux and Windows. Specifying the wrong type can cause undefined behavior and crashes, see e.g. r-dbi/odbc#677

What are related issues/pull requests?

None.

Tasklist

  • Add test case(s) (they were already there)
  • Review
  • Adjust for comments
  • All CI builds and checks have passed

Environment

Provide environment details, if relevant:

  • DBMS name/version:
  • ODBC connection string:
  • OS and Compiler:

Use the official types, as in the docs. See
https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function?view=sql-server-ver16

> InfoValuePtr
> [Output] Pointer to a buffer in which to return the information.
> Depending on the InfoType requested, the information returned will
> be one of the following: a null-terminated character string, an
> SQLUSMALLINT value, an SQLUINTEGER bitmask, an SQLUINTEGER flag,
> a SQLUINTEGER binary value, or a SQLULEN value.

It seems better to use these types instead of matching them to
the C data types, which can be platform dependent. For example
SQLUINTEGER is currently different on Linux and Windows.
Specifying the wrong type can cause undefined behavior and crashes,
see e.g. r-dbi/odbc#677
@mloskot
Copy link
Member

mloskot commented Dec 17, 2023

Hi @gaborcsardi Thank you for your PR. Although it is technically valid, I don't want to merge it before having a brief discussion about the issue from nanodbc perspective.

One of the aims of nanodbc is to let its users interact with databases using C++ native types only. It means, it avoids uses of ODBC types in its public interface. It also tries to avoid use of platform-dependant types like unsigned short and prefer std::uint16_t instead - this clean up has not been complete though.

So, instead of exposing the ODBC types to fix your problem, can we correct nanodbc to avoid uses of unsigned short?
Would such alternative fix work for the r-odbc folks?
(I am willing to do the clean up, not expecting you @gaborcsardi to do it, of course.)

We could release the types clean up as 2.15

@lexicalunit Please, share your thoughts on that.

@gaborcsardi
Copy link
Author

One of the aims of nanodbc is to let its users interact with databases using C++ native types only. It means, it avoids uses of ODBC types in its public interface

I think that is reasonable, but it comes with a drawback.

The current principle means that it is not trivial to write cross-platform code using nanodbc, because e.g. SQLUINTEGER means different types on different OSes, and nanodbc users need to manually find the correct types on each platform, and if they do this wrong (which is easy, e.g. there are no compiler warnings for mistakes), then they potentially get undefined behavior e.g. crashes.

But I understand that this PR is a radical deviation from your rule. Maybe you could internally convert betweeen the standard integer type and the SQL types. So your API would stay the same, but internally you'd call the ODBC functions with the standard SQL types. I can try to modify this PR if you think that this is a good idea.

@mloskot
Copy link
Member

mloskot commented Dec 17, 2023

@gaborcsardi

SQLUINTEGER means different types on different OSes, and nanodbc users need to manually find the correct types on each platform, and if they do this wrong, then they potentially get undefined behavior e.g. crashes.
(...)
Maybe you could internally convert betweeen the standard integer type and the SQL types.

I think you've nailed there both, the problem and the solution. The nanodbc as a wrapper - facade pattern - which goal is to hide complexity of the underlaying system and free users from having to make those decisions.

Let's first try solve it as you suggest, moving the mapping into the nanodbc internal details and resort to the modification of the public interface only if it turns impossible to figure mapping for all possible platform variants.

@mloskot mloskot added status/need-feedback category/enhancement status/help-wanted Looking for help or expertise on a subject labels Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants