Keep SQL_ATTR_KEYSET_SIZE apart from the rowset size; HY007 for an unprepared IRD (#307) - #314
Open
fdcastel wants to merge 3 commits into
Open
Keep SQL_ATTR_KEYSET_SIZE apart from the rowset size; HY007 for an unprepared IRD (#307)#314fdcastel wants to merge 3 commits into
fdcastel wants to merge 3 commits into
Conversation
fdcastel
force-pushed
the
fix/issue-307-keyset-size-hy007
branch
from
September 7, 2026 06:09
eab3f08 to
c0da6ac
Compare
KeysetSizeDoesNotChangeRowArraySize sets SQL_ATTR_KEYSET_SIZE and reads both it and SQL_ATTR_ROW_ARRAY_SIZE back, then sets SQL_ROWSET_SIZE and checks the two stay independent. IrdHeaderFieldsReadableBeforePrepare reads SQL_DESC_ROWS_PROCESSED_PTR, SQL_DESC_ARRAY_STATUS_PTR and SQL_DESC_ALLOC_TYPE from the IRD of a statement that has not been prepared. IrdRecordFieldsBeforePrepareAreHY007 expects HY007 for SQL_DESC_COUNT and a record field in that state, and success for both once the statement is prepared.
sqlSetStmtAttr handled SQL_ATTR_KEYSET_SIZE in the same case as the ODBC 2 SQL_ROWSET_SIZE and stored it in the ARD's array size. An application that set a keyset size (ODBC 2 applications and generic layers do, with values such as 100) silently got a rowset of that size, and the next SQLFetch wrote that many rows into buffers bound for one, with no rows-fetched counter or status array to warn it. The value now goes to its own field, read back by sqlGetStmtAttr; the driver has no keyset-driven cursors, so the number is stored and returned as the specification allows.
sqlGetDescField refused every field of an undefined descriptor with HY091 "Invalid descriptor field identifier". For the IRD that state means "not prepared yet", and the header fields (the array-status and rows-processed pointers among them, which the application itself set through SQLSetStmtAttr) do not depend on the result set at all. The header fields are now returned regardless of the prepared state. SQL_DESC_COUNT and the record fields of an unprepared IRD answer HY007 "Associated statement is not prepared"; other descriptor types keep the HY091 they gave before.
fdcastel
force-pushed
the
fix/issue-307-keyset-size-hy007
branch
from
September 7, 2026 06:11
c0da6ac to
dc6f9e6
Compare
This was referenced Sep 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #307. Three commits on current master, independent of the other open PRs: the
sqlGetStmtAttrcase sits next toSQL_ROWSET_SIZE, fifty lines away from the block #304 adds.1.
SQL_ATTR_KEYSET_SIZEoverwrote the rowset sizesqlSetStmtAttrhandledSQL_ATTR_KEYSET_SIZEin the samecaseas the ODBC 2SQL_ROWSET_SIZEand stored it in the ARD's array size, so an application that set a keyset size got a rowset of that size and the nextSQLFetchwrote that many rows into buffers bound for one. ReadingSQL_ATTR_KEYSET_SIZEback answeredHYC00.The value now goes to its own field and comes back from
sqlGetStmtAttr. The driver has no keyset-driven cursors, so storing and returning the number is what the specification allows;SQL_ROWSET_SIZEstill sets the rowset size.2.
SQLGetDescFieldon an unprepared IRD answeredHY091sqlGetDescFieldrefused every field of an undefined descriptor withHY091. For the IRD that state means "not prepared yet", and the header fields do not depend on the result set, including the two pointers the application itself just set throughSQLSetStmtAttr.The header fields (
SQL_DESC_ALLOC_TYPE,SQL_DESC_ARRAY_SIZE,SQL_DESC_ARRAY_STATUS_PTR,SQL_DESC_BIND_OFFSET_PTR,SQL_DESC_BIND_TYPE,SQL_DESC_ROWS_PROCESSED_PTR) are now returned regardless of the prepared state.SQL_DESC_COUNTand the record fields of an unprepared IRD answerHY007; other descriptor types keep theHY091they gave before.Tests
ScrollableCursorTest.KeysetSizeDoesNotChangeRowArraySize: keyset size 7 leaves the rowset at 1 and reads back as 7;SQL_ROWSET_SIZE3 then sets the rowset and leaves the keyset size alone.DescriptorTest.IrdHeaderFieldsReadableBeforePrepare: the two pointers and the alloc type come back from the IRD of an unprepared statement.DescriptorTest.IrdRecordFieldsBeforePrepareAreHY007:SQL_DESC_COUNTand a record field answerHY007beforeSQLPrepareand succeed after it.All three fail against the master driver (
HYC00from the keyset read-back, the rowset at 7,HY091for both descriptor reads) and pass with this branch. Through unixODBC the driver manager answersHY007for an unprepared IRD before the driver sees the call, so the header-field case skips there and runs through the Microsoft driver manager; theHY007case holds under both. Full suite with this branch,CHARSET=UTF8andNONE: 391 ran, 226 passed, 165 skipped, 0 failed.Still open
SQLSetScrollOptionsmapscrowKeyset > 0toSQL_ATTR_KEYSET_SIZEand only otherwise setsSQL_ROWSET_SIZEfromcrowRowset; with this change a keyset-driven request no longer alters the rowset size at all. The ODBC 1 entry point is left as it is.SQLGetDescRecandSQLSetDescFieldkeep theHY091answer for an undefined descriptor.