Skip to content

ext/pdo: Fail nextRowset() when the column describer fails - #23849

Closed
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:promote/pdo-nextrowset-describe
Closed

iliaal wants to merge 1 commit into
php:masterfrom
iliaal:promote/pdo-nextrowset-describe

Conversation

@iliaal

@iliaal iliaal commented Sep 22, 2026

Copy link
Copy Markdown
Member

pdo_stmt_do_next_rowset() dropped the return value of pdo_stmt_describe_columns(), so a driver whose describer failed after the rowset advance left columns[] partially initialized while nextRowset() still reported success, and the next fetch read that incomplete state. pdo_stmt_do_execute(), do_fetch() and PDO::prepare() already check it. No test: odbc_stmt_describe() fails when SQLDescribeCol() or SQLColAttribute() does, which needs a server driven into that state, and the bundled sqlite describer only fails for a column index past its own count, which the describe loop never passes it.

@kamil-tekiela

Copy link
Copy Markdown
Member

This does not sound right. At first sight, I think the return value was ignored here on purpose, but I will try to look into this more. Either way, this is not a bug fix so it should go on master.

pdo_stmt_do_next_rowset() dropped the return value of
pdo_stmt_describe_columns(), so a driver whose describer failed after the
rowset advance left columns[] partially initialized while nextRowset() still
reported success, and the next fetch read that incomplete state. Check the
result, as pdo_stmt_do_execute(), do_fetch() and PDO::query() already do,
and release the partial columns so a fetch after the failure cannot read
them.
@iliaal
iliaal changed the base branch from PHP-8.4 to master September 24, 2026 18:36
@iliaal
iliaal force-pushed the promote/pdo-nextrowset-describe branch from 5cccffb to 3d31c58 Compare September 24, 2026 18:36
@iliaal

iliaal commented Sep 24, 2026

Copy link
Copy Markdown
Member Author

You're right. pdo_mysql's describer returns 0 on the empty result set that ends a CALL, so this check turns that nextRowset() into a failure: pdo_mysql_stmt_nextrowset.phpt, pdo_mysql_multi_stmt_nextrowset.phpt, bug_39858.phpt and pdo_mysql_attr_oracle_nulls.phpt all fail with it. Closing.

@iliaal iliaal closed this Sep 24, 2026
@kamil-tekiela

Copy link
Copy Markdown
Member

You're right. pdo_mysql's describer returns 0 on the empty result set that ends a CALL, so this check turns that nextRowset() into a failure: pdo_mysql_stmt_nextrowset.phpt, pdo_mysql_multi_stmt_nextrowset.phpt, bug_39858.phpt and pdo_mysql_attr_oracle_nulls.phpt all fail with it. Closing.

I wouldn't be so quick. I believe the test failures are unrelated. It seems that mysqlnd didn't act according to the standard and didn't clear the field_count on next_result, which is why the PDO code failed. See my new PR. I haven't decided yet whether what you are proposing is correct or not.

@kamil-tekiela

Copy link
Copy Markdown
Member

My final judgement: let's not add this check. Let's follow up with the mysqlnd fix only. I cannot find a way in which this check would make any difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants