Skip to content

Commit d8ecb68

Browse files
committed
speed-up SQLite3Result::fetchArray(SQLITE3_ASSOC) by caching column names
1 parent 3fd322b commit d8ecb68

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

ext/sqlite3/php_sqlite3_structs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ struct _php_sqlite3_result_object {
107107
php_sqlite3_stmt *stmt_obj;
108108
zval stmt_obj_zval;
109109

110+
zend_long column_count;
111+
zend_string **column_names;
112+
110113
int is_prepared_statement;
111114
zend_object zo;
112115
};

ext/sqlite3/sqlite3.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,8 @@ PHP_METHOD(SQLite3, query)
586586
result = Z_SQLITE3_RESULT_P(return_value);
587587
result->db_obj = db_obj;
588588
result->stmt_obj = stmt_obj;
589+
result->column_names = NULL;
590+
result->column_count = -1;
589591
ZVAL_OBJ(&result->stmt_obj_zval, Z_OBJ(stmt));
590592

591593
return_code = sqlite3_step(result->stmt_obj->stmt);
@@ -1792,6 +1794,8 @@ PHP_METHOD(SQLite3Stmt, execute)
17921794
result->is_prepared_statement = 1;
17931795
result->db_obj = stmt_obj->db_obj;
17941796
result->stmt_obj = stmt_obj;
1797+
result->column_names = NULL;
1798+
result->column_count = -1;
17951799
ZVAL_OBJ_COPY(&result->stmt_obj_zval, Z_OBJ_P(object));
17961800

17971801
break;
@@ -1945,11 +1949,26 @@ PHP_METHOD(SQLite3Result, fetchArray)
19451949
RETURN_FALSE;
19461950
}
19471951

1952+
if (result_obj->column_count == -1) {
1953+
result_obj->column_count = sqlite3_column_count(result_obj->stmt_obj->stmt);
1954+
}
1955+
1956+
zend_long n_cols = result_obj->column_count;
1957+
1958+
/* Cache column names to speed up repeated fetchArray calls.
1959+
* Names are deallocated in php_sqlite3_result_object_free_storage. */
1960+
if (mode & PHP_SQLITE3_ASSOC && !result_obj->column_names) {
1961+
result_obj->column_names = pemalloc(n_cols * sizeof(zend_string*), 0);
1962+
1963+
for (int i = 0; i < n_cols; i++) {
1964+
const char* column = sqlite3_column_name(result_obj->stmt_obj->stmt, i);
1965+
result_obj->column_names[i] = zend_string_init(column, strlen(column), 0);
1966+
}
1967+
}
1968+
19481969
array_init(return_value);
1949-
1950-
int column_count = sqlite3_data_count(result_obj->stmt_obj->stmt);
19511970

1952-
for (i = 0; i < column_count; i++) {
1971+
for (i = 0; i < n_cols; i++) {
19531972
zval data;
19541973

19551974
sqlite_value_to_zval(result_obj->stmt_obj->stmt, i, &data);
@@ -1964,7 +1983,7 @@ PHP_METHOD(SQLite3Result, fetchArray)
19641983
Z_ADDREF(data);
19651984
}
19661985
}
1967-
add_assoc_zval(return_value, (char*)sqlite3_column_name(result_obj->stmt_obj->stmt, i), &data);
1986+
zend_symtable_add_new(Z_ARR_P(return_value), result_obj->column_names[i], &data);
19681987
}
19691988
}
19701989
break;
@@ -2235,6 +2254,13 @@ static void php_sqlite3_result_object_free_storage(zend_object *object) /* {{{ *
22352254
return;
22362255
}
22372256

2257+
if (intern->column_names) {
2258+
for (int i = 0; i < intern->column_count; i++) {
2259+
zend_string_release(intern->column_names[i]);
2260+
}
2261+
efree(intern->column_names);
2262+
}
2263+
22382264
if (!Z_ISNULL(intern->stmt_obj_zval)) {
22392265
if (intern->stmt_obj && intern->stmt_obj->initialised) {
22402266
sqlite3_reset(intern->stmt_obj->stmt);

0 commit comments

Comments
 (0)