Skip to content

speed-up SQLite3Result::fetchArray(SQLITE3_ASSOC) by caching column names #7505

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

Closed
wants to merge 3 commits into from

Conversation

kaja47
Copy link
Contributor

@kaja47 kaja47 commented Sep 20, 2021

No description provided.

Copy link
Member

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this only cached per-execute and not across executions, this looks reasonable to me.

/* Cache column names to speed up repeated fetchArray calls.
* Names are deallocated in php_sqlite3_result_object_free_storage. */
if (mode & PHP_SQLITE3_ASSOC && !result_obj->column_names) {
result_obj->column_names = pemalloc(n_cols * sizeof(zend_string*), 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result_obj->column_names = pemalloc(n_cols * sizeof(zend_string*), 0);
result_obj->column_names = emalloc(n_cols * sizeof(zend_string*));

result_obj->column_names = pemalloc(n_cols * sizeof(zend_string*), 0);

for (int i = 0; i < n_cols; i++) {
const char* column = sqlite3_column_name(result_obj->stmt_obj->stmt, i);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const char* column = sqlite3_column_name(result_obj->stmt_obj->stmt, i);
const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i);

@@ -107,6 +107,9 @@ struct _php_sqlite3_result_object {
php_sqlite3_stmt *stmt_obj;
zval stmt_obj_zval;

zend_long column_count;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zend_long column_count;
int column_count;

To match type returned by sqlite.

@cmb69
Copy link
Member

cmb69 commented Sep 21, 2021

Wouldn't that basically introduce https://bugs.php.net/bug.php?id=78227 for SQLite3?

@nikic
Copy link
Member

nikic commented Sep 21, 2021

@cmb69 As this only caches for one execute, not one prepare, I don't think so.

@cmb69
Copy link
Member

cmb69 commented Sep 21, 2021

As this only caches for one execute, not one prepare, I don't think so.

Ah, fine then. :)

@kaja47
Copy link
Contributor Author

kaja47 commented Sep 22, 2021

Well, that bug you mentioned was indeed introduced. In sqlite changed column names are visible only after sqlite3_reset() call (SQLite3Stmt::reset() on PHP side). Cache is now cleared also in this case. I added one test to make sure this is the case.

result_obj->column_count = sqlite3_column_count(result_obj->stmt_obj->stmt);
}

zend_long n_cols = result_obj->column_count;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zend_long n_cols = result_obj->column_count;
int n_cols = result_obj->column_count;

result->column_count = -1;
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Newline too much.


for (int i = 0; i < n_cols; i++) {
const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i);
result_obj->column_names[i] = zend_string_init(column, strlen(column), 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to check whether using zend_string_init_existing_interned() would be beneficial in practice (you'd have to measure that together with code using the data).

@nikic nikic closed this in 1487dd0 Sep 24, 2021
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

Successfully merging this pull request may close these issues.

3 participants