tests: rowset fetches on every fetch path and binding layout - #305
Open
fdcastel wants to merge 3 commits into
Open
tests: rowset fetches on every fetch path and binding layout#305fdcastel wants to merge 3 commits into
fdcastel wants to merge 3 commits into
Conversation
…Prepare OdbcDesc::setDefaultImplDesc rebuilds the implementation row descriptor on every prepare and, while doing so, reset SQL_DESC_ROWS_PROCESSED_PTR and SQL_DESC_ARRAY_STATUS_PTR to NULL. An application that set SQL_ATTR_ROWS_FETCHED_PTR / SQL_ATTR_ROW_STATUS_PTR before SQLPrepare or SQLExecDirect never had them written by SQLFetch, so a block cursor could not tell how many rows the last rowset held. The same attributes set after the prepare worked, and the parameter descriptor never reset its own counterparts. Statement attributes persist until the statement is freed or the attribute is set again; SQLPrepare must not clear them. Reported in FirebirdSQL#301.
Three cases fail on master: SQL_ATTR_ROWS_FETCHED_PTR and SQL_ATTR_ROW_STATUS_PTR set before SQLPrepare, before SQLExecDirect, and kept across SQLFreeStmt(SQL_CLOSE) on a reused handle. The fourth sets them between SQLPrepare and SQLExecute and is the control that already passed.
Eight more block-cursor cases: SQLFetchScroll(SQL_FETCH_NEXT) and SQLExtendedFetch on a forward-only cursor, a rowset larger than the result set, row-wise binding, a static scrollable cursor in every orientation, and the two catalog paths (SQLTables results are static cursors, SQLGetTypeInfo results are not). Each asserts the rows-fetched counter, the status array and the bound values on every rowset, and a zero counter on SQL_NO_DATA. ColumnWiseBindingWithOffset is skipped with the reason: any bind-offset pointer sends the statement down the row-wise fetch path, which steps by SQL_ATTR_ROW_BIND_TYPE per row, and that is 0 for column-wise binding, so every row of the rowset lands on the same address.
This was referenced Sep 6, 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.
Builds on #303: the first four cases in
tests/test_block_cursor.cppcome from there, and GitHub shows both commits until it merges.Before #303 nothing in the suite set
SQL_ATTR_ROW_ARRAY_SIZE. This adds eight cases for the other entry points, layouts and cursor kinds a block cursor goes through. Each asserts the rows-fetched counter, the status array and the bound values on every rowset, and a zero counter onSQL_NO_DATA:FetchScrollNextRowsets:SQLFetchScroll(SQL_FETCH_NEXT)on a forward-only cursor.ExtendedFetchRowsets:SQLExtendedFetch, which receives the counter and the status array as arguments.ArraySizeLargerThanResultSet: one partial rowset (6 rows of 10), the unused slotsSQL_ROW_NOROWand untouched, thenSQL_NO_DATA.RowWiseBinding:SQL_ATTR_ROW_BIND_TYPEset to the size of a two-column row structure.StaticCursorRowsets:SQL_CURSOR_STATIC+SQL_SCROLLABLE, rowsets fetched with NEXT, FIRST, ABSOLUTE, LAST and RELATIVE.CatalogRowsetsViaSqlTablesandCatalogRowsetsViaSqlGetTypeInfo: the two catalog paths (SQLTablesresults are static cursors,SQLGetTypeInforesults are not), checked against a row count taken with the default rowset.ColumnWiseBindingWithOffset: skipped, see below.The eleven active cases pass on Windows x64 against Firebird 5.0.3 with the Microsoft driver manager. Full suite: 400 ran, 234 passed, 166 skipped, 0 failed.
Found on the way
Column-wise binding combined with
SQL_ATTR_ROW_BIND_OFFSET_PTRwrites every row of a rowset to the same address.getSchemaFetchData()sends any statement that has a bind-offset pointer down the row-wise branch offetchData(and of its static-cursor twin), which advances the bound addresses bySQL_ATTR_ROW_BIND_TYPEper row; that is 0 for column-wise binding. The counter and the status array still report a full rowset, so the application getsSQL_SUCCESS, "4 rows fetched", and only the last row's data in the first element. Row-wise binding with the same offset pointer works.The test for it is included with a
GTEST_SKIPthat states the defect, so it turns green the day the fetch path is fixed. Not fixed here: the fix touches the row stepping in both fetch functions andreturnDataFromExtendedFetch, which deserves its own PR.