xref: /PHP-7.4/ext/mysqli/mysqli_prop.c (revision d39edebb)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) The PHP Group                                          |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Author: Georg Richter <georg@php.net>                                |
16   |         Andrey Hristov <andrey@php.net>                              |
17   +----------------------------------------------------------------------+
18 */
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include <signal.h>
25 
26 #include "php.h"
27 #include "php_ini.h"
28 #include "ext/standard/info.h"
29 #include "php_mysqli_structs.h"
30 #include "mysqli_priv.h"
31 
32 #define CHECK_STATUS(value, quiet) \
33 	if (!obj->ptr || ((MYSQLI_RESOURCE *)obj->ptr)->status < value ) { \
34 		if (!quiet) { \
35 			php_error_docref(NULL, E_WARNING, "Property access is not allowed yet"); \
36 		} \
37 		ZVAL_FALSE(retval); \
38 		return FAILURE; \
39 	} \
40 
41 #define MYSQLI_GET_MYSQL(statusval) \
42 MYSQL *p; \
43 if (!obj->ptr || !(MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { \
44 	if (!quiet) { \
45 		php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \
46 	} \
47 	ZVAL_FALSE(retval);\
48 	return FAILURE; \
49 } else { \
50 	CHECK_STATUS(statusval, quiet);\
51     p = (MYSQL *)((MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->mysql;\
52 }
53 
54 #define MYSQLI_GET_RESULT(statusval) \
55 MYSQL_RES *p; \
56 if (!obj->ptr) { \
57 	if (!quiet) { \
58 		php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \
59 	} \
60 	ZVAL_NULL(retval);\
61 	return FAILURE; \
62 } else { \
63 	CHECK_STATUS(statusval, quiet);\
64 	p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; \
65 }
66 
67 #define MYSQLI_GET_STMT(statusval) \
68 MYSQL_STMT *p; \
69 if (!obj->ptr) { \
70 	if (!quiet) { \
71 		php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \
72 	} \
73 	ZVAL_NULL(retval);\
74 	return FAILURE; \
75 } else { \
76 	CHECK_STATUS(statusval, quiet); \
77 	p = (MYSQL_STMT *)((MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->stmt; \
78 }
79 
80 #define MYSQLI_MAP_PROPERTY_FUNC_LONG( __func, __int_func, __get_type, __ret_type, __ret_type_sprint_mod)\
81 static int __func(mysqli_object *obj, zval *retval, zend_bool quiet) \
82 {\
83 	__ret_type l;\
84 	__get_type;\
85 	if (!p) {\
86 		ZVAL_NULL(retval);\
87 	} else {\
88 		l = (__ret_type)__int_func(p);\
89 		if (l < ZEND_LONG_MAX) {\
90 			ZVAL_LONG(retval, (zend_long) l);\
91 		} else { \
92 			ZVAL_NEW_STR(retval, strpprintf(0, __ret_type_sprint_mod, l)); \
93 		} \
94 	} \
95 	return SUCCESS; \
96 }
97 
98 #define MYSQLI_MAP_PROPERTY_FUNC_STRING(__func, __int_func, __get_type)\
99 static int __func(mysqli_object *obj, zval *retval, zend_bool quiet)\
100 {\
101 	char *c;\
102 	__get_type;\
103 	if (!p) {\
104 		ZVAL_NULL(retval);\
105 	} else {\
106 		c = (char *)__int_func(p);\
107 		if (!c) {\
108 			ZVAL_NULL(retval);\
109 		} else {\
110 			ZVAL_STRING(retval, c);\
111 		}\
112 	}\
113 	return SUCCESS; \
114 }
115 
116 /* {{{ property link_client_version_read */
link_client_version_read(mysqli_object * obj,zval * retval,zend_bool quiet)117 static int link_client_version_read(mysqli_object *obj, zval *retval, zend_bool quiet)
118 {
119 	ZVAL_LONG(retval, MYSQL_VERSION_ID);
120 
121 	return SUCCESS;
122 }
123 /* }}} */
124 
125 /* {{{ property link_client_info_read */
link_client_info_read(mysqli_object * obj,zval * retval,zend_bool quiet)126 static int link_client_info_read(mysqli_object *obj, zval *retval, zend_bool quiet)
127 {
128 	CHECK_STATUS(MYSQLI_STATUS_INITIALIZED, quiet);
129 	ZVAL_STRING(retval, MYSQL_SERVER_VERSION);
130 
131 	return SUCCESS;
132 }
133 /* }}} */
134 
135 /* {{{ property link_connect_errno_read */
link_connect_errno_read(mysqli_object * obj,zval * retval,zend_bool quiet)136 static int link_connect_errno_read(mysqli_object *obj, zval *retval, zend_bool quiet)
137 {
138 	ZVAL_LONG(retval, (zend_long)MyG(error_no));
139 
140 	return SUCCESS;
141 }
142 /* }}} */
143 
144 /* {{{ property link_connect_error_read */
link_connect_error_read(mysqli_object * obj,zval * retval,zend_bool quiet)145 static int link_connect_error_read(mysqli_object *obj, zval *retval, zend_bool quiet)
146 {
147 	if (MyG(error_msg)) {
148 		ZVAL_STRING(retval, MyG(error_msg));
149 	} else {
150 		ZVAL_NULL(retval);
151 	}
152 
153 	return SUCCESS;
154 }
155 /* }}} */
156 
157 /* {{{ property link_affected_rows_read */
link_affected_rows_read(mysqli_object * obj,zval * retval,zend_bool quiet)158 static int link_affected_rows_read(mysqli_object *obj, zval *retval, zend_bool quiet)
159 {
160 	MY_MYSQL *mysql;
161 	my_ulonglong rc;
162 
163 	CHECK_STATUS(MYSQLI_STATUS_INITIALIZED, quiet);
164 
165  	mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
166 
167 	if (!mysql) {
168 		ZVAL_NULL(retval);
169 	} else {
170 		CHECK_STATUS(MYSQLI_STATUS_VALID, quiet);
171 
172 		rc = mysql_affected_rows(mysql->mysql);
173 
174 		if (rc == (my_ulonglong) -1) {
175 			ZVAL_LONG(retval, -1);
176 			return SUCCESS;
177 		}
178 
179 		if (rc < ZEND_LONG_MAX) {
180 			ZVAL_LONG(retval, (zend_long) rc);
181 		} else {
182 			ZVAL_NEW_STR(retval, strpprintf(0, MYSQLI_LLU_SPEC, rc));
183 		}
184 	}
185 
186 	return SUCCESS;
187 }
188 /* }}} */
189 
190 /* {{{ property link_error_list_read */
link_error_list_read(mysqli_object * obj,zval * retval,zend_bool quiet)191 static int link_error_list_read(mysqli_object *obj, zval *retval, zend_bool quiet)
192 {
193 	MY_MYSQL *mysql;
194 
195 	CHECK_STATUS(MYSQLI_STATUS_VALID, quiet);
196 
197  	mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
198 
199 	if (mysql) {
200 		array_init(retval);
201 #if defined(MYSQLI_USE_MYSQLND)
202 		if (1) {
203 			MYSQLND_ERROR_LIST_ELEMENT * message;
204 			zend_llist_position pos;
205 			for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(&mysql->mysql->data->error_info->error_list, &pos);
206 				 message;
207 				 message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(&mysql->mysql->data->error_info->error_list, &pos))
208 			{
209 				zval single_error;
210 				array_init(&single_error);
211 				add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, message->error_no);
212 				add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, message->sqlstate);
213 				add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
214 				add_next_index_zval(retval, &single_error);
215 			}
216 		}
217 #else
218 		if (mysql_errno(mysql->mysql)) {
219 			zval single_error;
220 			array_init(&single_error);
221 			add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_errno(mysql->mysql));
222 			add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_sqlstate(mysql->mysql));
223 			add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_error(mysql->mysql));
224 			add_next_index_zval(retval, &single_error);
225 		}
226 #endif
227 	} else {
228 		ZVAL_EMPTY_ARRAY(retval);
229 	}
230 
231 	return SUCCESS;
232 }
233 /* }}} */
234 
235 /* link properties */
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read,mysql_errno,MYSQLI_GET_MYSQL (MYSQLI_STATUS_INITIALIZED),zend_ulong,ZEND_ULONG_FMT)236 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED), zend_ulong, ZEND_ULONG_FMT)
237 MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED))
238 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_field_count_read, mysql_field_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
239 MYSQLI_MAP_PROPERTY_FUNC_STRING(link_host_info_read, mysql_get_host_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID))
240 MYSQLI_MAP_PROPERTY_FUNC_STRING(link_info_read, mysql_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID))
241 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_insert_id_read, mysql_insert_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
242 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_protocol_version_read, mysql_get_proto_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
243 MYSQLI_MAP_PROPERTY_FUNC_STRING(link_server_info_read, mysql_get_server_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID))
244 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_server_version_read, mysql_get_server_version, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
245 MYSQLI_MAP_PROPERTY_FUNC_STRING(link_sqlstate_read, mysql_sqlstate, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID))
246 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
247 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
248 
249 /* result properties */
250 
251 /* {{{ property result_type_read */
252 static int result_type_read(mysqli_object *obj, zval *retval, zend_bool quiet)
253 {
254 	MYSQL_RES *p;
255 
256 	CHECK_STATUS(MYSQLI_STATUS_VALID, quiet);
257  	p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
258 
259 	if (!p) {
260 		ZVAL_NULL(retval);
261 	} else {
262 		ZVAL_LONG(retval, mysqli_result_is_unbuffered(p) ? MYSQLI_USE_RESULT:MYSQLI_STORE_RESULT);
263 	}
264 
265 	return SUCCESS;
266 }
267 /* }}} */
268 
269 /* {{{ property result_lengths_read */
result_lengths_read(mysqli_object * obj,zval * retval,zend_bool quiet)270 static int result_lengths_read(mysqli_object *obj, zval *retval, zend_bool quiet)
271 {
272 	MYSQL_RES *p;
273 #if defined(MYSQLI_USE_MYSQLND)
274 	const size_t *ret;
275 #else
276 	const zend_ulong *ret;
277 #endif
278 	uint32_t field_count;
279 
280 	CHECK_STATUS(MYSQLI_STATUS_VALID, quiet);
281 	p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
282 	field_count = mysql_num_fields(p);
283 	if (!p || !field_count || !(ret = mysql_fetch_lengths(p))) {
284 		ZVAL_NULL(retval);
285 	} else {
286 		zend_ulong i;
287 
288 		array_init(retval);
289 
290 		for (i = 0; i < field_count; i++) {
291 			add_index_long(retval, i, ret[i]);
292 		}
293 	}
294 
295 	return SUCCESS;
296 }
297 /* }}} */
298 
MYSQLI_MAP_PROPERTY_FUNC_LONG(result_current_field_read,mysql_field_tell,MYSQLI_GET_RESULT (MYSQLI_STATUS_VALID),zend_ulong,ZEND_ULONG_FMT)299 MYSQLI_MAP_PROPERTY_FUNC_LONG(result_current_field_read, mysql_field_tell, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
300 MYSQLI_MAP_PROPERTY_FUNC_LONG(result_field_count_read, mysql_num_fields, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
301 MYSQLI_MAP_PROPERTY_FUNC_LONG(result_num_rows_read, mysql_num_rows, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
302 
303 /* statement properties */
304 
305 /* {{{ property stmt_id_read */
306 static int stmt_id_read(mysqli_object *obj, zval *retval, zend_bool quiet)
307 {
308 	MY_STMT *p;
309 
310 	CHECK_STATUS(MYSQLI_STATUS_VALID, quiet);
311 
312  	p = (MY_STMT*)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
313 
314 	if (!p) {
315 		ZVAL_NULL(retval);
316 	} else {
317 		ZVAL_LONG(retval, mysqli_stmt_get_id(p->stmt));
318 	}
319 
320 	return SUCCESS;
321 }
322 /* }}} */
323 
324 /* {{{ property stmt_affected_rows_read */
stmt_affected_rows_read(mysqli_object * obj,zval * retval,zend_bool quiet)325 static int stmt_affected_rows_read(mysqli_object *obj, zval *retval, zend_bool quiet)
326 {
327 	MY_STMT *p;
328 	my_ulonglong rc;
329 
330 	CHECK_STATUS(MYSQLI_STATUS_VALID, quiet);
331 
332  	p = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
333 
334 	if (!p) {
335 		ZVAL_NULL(retval);
336 	} else {
337 		rc = mysql_stmt_affected_rows(p->stmt);
338 
339 		if (rc == (my_ulonglong) -1) {
340 			ZVAL_LONG(retval, -1);
341 			return SUCCESS;
342 		}
343 
344 		if (rc < ZEND_LONG_MAX) {
345 			ZVAL_LONG(retval, (zend_long) rc);
346 		} else {
347 			ZVAL_NEW_STR(retval, strpprintf(0, MYSQLI_LLU_SPEC, rc));
348 		}
349 	}
350 
351 	return SUCCESS;
352 }
353 /* }}} */
354 
355 /* {{{ property stmt_error_list_read */
stmt_error_list_read(mysqli_object * obj,zval * retval,zend_bool quiet)356 static int stmt_error_list_read(mysqli_object *obj, zval *retval, zend_bool quiet)
357 {
358 	MY_STMT * stmt;
359 
360 	CHECK_STATUS(MYSQLI_STATUS_INITIALIZED, quiet);
361 
362  	stmt = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
363 	if (stmt && stmt->stmt) {
364 		array_init(retval);
365 #if defined(MYSQLI_USE_MYSQLND)
366 		if (stmt->stmt->data && stmt->stmt->data->error_info) {
367 			MYSQLND_ERROR_LIST_ELEMENT * message;
368 			zend_llist_position pos;
369 			for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(&stmt->stmt->data->error_info->error_list, &pos);
370 				 message;
371 				 message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(&stmt->stmt->data->error_info->error_list, &pos))
372 			{
373 				zval single_error;
374 				array_init(&single_error);
375 				add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, message->error_no);
376 				add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, message->sqlstate);
377 				add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
378 				add_next_index_zval(retval, &single_error);
379 			}
380 		}
381 #else
382 		if (mysql_stmt_errno(stmt->stmt)) {
383 			zval single_error;
384 			array_init(&single_error);
385 			add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_stmt_errno(stmt->stmt));
386 			add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_stmt_sqlstate(stmt->stmt));
387 			add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_stmt_error(stmt->stmt));
388 			add_next_index_zval(retval, &single_error);
389 		}
390 #endif
391 	} else {
392 		ZVAL_EMPTY_ARRAY(retval);
393 	}
394 
395 	return SUCCESS;
396 }
397 /* }}} */
398 
399 MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
400 MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
401 MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
402 MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_field_count_read, mysql_stmt_field_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), zend_ulong, ZEND_ULONG_FMT)
403 MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_errno_read, mysql_stmt_errno, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED), zend_ulong, ZEND_ULONG_FMT)
404 MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_error_read, mysql_stmt_error, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED))
405 MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_sqlstate_read, mysql_stmt_sqlstate, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED))
406 
407 /* }}} */
408 const mysqli_property_entry mysqli_link_property_entries[] = {
409 	{"affected_rows", 	sizeof("affected_rows") - 1,	link_affected_rows_read, NULL},
410 	{"client_info", 	sizeof("client_info") - 1,		link_client_info_read, NULL},
411 	{"client_version",	sizeof("client_version") - 1,	link_client_version_read, NULL},
412 	{"connect_errno",	sizeof("connect_errno") - 1,	link_connect_errno_read, NULL},
413 	{"connect_error",	sizeof("connect_error") - 1,	link_connect_error_read, NULL},
414 	{"errno",			sizeof("errno") - 1,			link_errno_read, NULL},
415 	{"error",			sizeof("error") - 1,			link_error_read, NULL},
416 	{"error_list",		sizeof("error_list") - 1,		link_error_list_read, NULL},
417 	{"field_count",		sizeof("field_count") - 1,		link_field_count_read, NULL},
418 	{"host_info",		sizeof("host_info") - 1,		link_host_info_read, NULL},
419 	{"info",			sizeof("info") - 1,				link_info_read, NULL},
420 	{"insert_id",		sizeof("insert_id") - 1,		link_insert_id_read, NULL},
421 	{"server_info",		sizeof("server_info") - 1,		link_server_info_read, NULL},
422 	{"server_version",	sizeof("server_version") - 1,	link_server_version_read, NULL},
423 	{"sqlstate",		sizeof("sqlstate") - 1,			link_sqlstate_read, NULL},
424 	{"protocol_version",sizeof("protocol_version") - 1,	link_protocol_version_read, NULL},
425 	{"thread_id",		sizeof("thread_id") - 1, 		link_thread_id_read, NULL},
426 	{"warning_count",	sizeof("warning_count") - 1, 	link_warning_count_read, NULL},
427 	{NULL, 0, NULL, NULL}
428 };
429 
430 
431 const mysqli_property_entry mysqli_result_property_entries[] = {
432 	{"current_field",sizeof("current_field")-1,	result_current_field_read, NULL},
433 	{"field_count", sizeof("field_count") - 1,	result_field_count_read, NULL},
434 	{"lengths", 	sizeof("lengths") - 1,		result_lengths_read, NULL},
435 	{"num_rows", 	sizeof("num_rows") - 1,		result_num_rows_read, NULL},
436 	{"type", 		sizeof("type") - 1,			result_type_read, NULL},
437 	{NULL, 0, NULL, NULL}
438 };
439 
440 const mysqli_property_entry mysqli_stmt_property_entries[] = {
441 	{"affected_rows", sizeof("affected_rows")-1,stmt_affected_rows_read, NULL},
442 	{"insert_id",	sizeof("insert_id") - 1, 	stmt_insert_id_read, NULL},
443 	{"num_rows",	sizeof("num_rows") - 1, 	stmt_num_rows_read, NULL},
444 	{"param_count", sizeof("param_count") - 1,	stmt_param_count_read, NULL},
445 	{"field_count", sizeof("field_count") - 1,	stmt_field_count_read, NULL},
446 	{"errno",		sizeof("errno") - 1,		stmt_errno_read, NULL},
447 	{"error",		sizeof("error") - 1, 		stmt_error_read, NULL},
448 	{"error_list",	sizeof("error_list") - 1, 	stmt_error_list_read, NULL},
449 	{"sqlstate",	sizeof("sqlstate") - 1,		stmt_sqlstate_read, NULL},
450 	{"id",			sizeof("id") - 1,			stmt_id_read, NULL},
451 	{NULL, 0, NULL, NULL}
452 };
453