xref: /PHP-7.3/ext/mysqli/mysqli_api.c (revision a7544411)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2018 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   | Authors: Georg Richter <georg@php.net>                               |
16   |          Andrey Hristov <andrey@php.net>                             |
17   |          Ulf Wendel <uw@php.net>                                     |
18   +----------------------------------------------------------------------+
19 */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <signal.h>
26 
27 #include "php.h"
28 #include "php_ini.h"
29 #include "php_globals.h"
30 #include "ext/standard/info.h"
31 #include "zend_smart_str.h"
32 #include "php_mysqli_structs.h"
33 #include "mysqli_priv.h"
34 #include "ext/mysqlnd/mysql_float_to_double.h"
35 
36 
37 #if !defined(MYSQLI_USE_MYSQLND)
38 /* {{{ mysqli_tx_cor_options_to_string */
mysqli_tx_cor_options_to_string(const MYSQL * const conn,smart_str * str,const uint32_t mode)39 static void mysqli_tx_cor_options_to_string(const MYSQL * const conn, smart_str * str, const uint32_t mode)
40 {
41 	if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) {
42 		if (str->s && ZSTR_LEN(str->s)) {
43 			smart_str_appendl(str, " ", sizeof(" ") - 1);
44 		}
45 		smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1);
46 	} else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) {
47 		if (str->s && ZSTR_LEN(str->s)) {
48 			smart_str_appendl(str, " ", sizeof(" ") - 1);
49 		}
50 		smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1);
51 	}
52 
53 	if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) {
54 		if (str->s && ZSTR_LEN(str->s)) {
55 			smart_str_appendl(str, " ", sizeof(" ") - 1);
56 		}
57 		smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1);
58 	} else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) {
59 		if (str->s && ZSTR_LEN(str->s)) {
60 			smart_str_appendl(str, " ", sizeof(" ") - 1);
61 		}
62 		smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1);
63 	}
64 	smart_str_0(str);
65 }
66 /* }}} */
67 
68 /* {{{ mysqlnd_escape_string_for_tx_name_in_comment */
69 char *
mysqli_escape_string_for_tx_name_in_comment(const char * const name)70 mysqli_escape_string_for_tx_name_in_comment(const char * const name)
71 {
72 	char * ret = NULL;
73 	if (name) {
74 		zend_bool warned = FALSE;
75 		const char * p_orig = name;
76 		char * p_copy;
77 		p_copy = ret = emalloc(strlen(name) + 1 + 2 + 2 + 1); /* space, open, close, NullS */
78 		*p_copy++ = ' ';
79 		*p_copy++ = '/';
80 		*p_copy++ = '*';
81 		while (1) {
82 			register char v = *p_orig;
83 			if (v == 0) {
84 				break;
85 			}
86 			if ((v >= '0' && v <= '9') ||
87 				(v >= 'a' && v <= 'z') ||
88 				(v >= 'A' && v <= 'Z') ||
89 				v == '-' ||
90 				v == '_' ||
91 				v == ' ' ||
92 				v == '=')
93 			{
94 				*p_copy++ = v;
95 			} else if (warned == FALSE) {
96 				php_error_docref(NULL, E_WARNING, "Transaction name truncated. Must be only [0-9A-Za-z\\-_=]+");
97 				warned = TRUE;
98 			}
99 			++p_orig;
100 		}
101 		*p_copy++ = '*';
102 		*p_copy++ = '/';
103 		*p_copy++ = 0;
104 	}
105 	return ret;
106 }
107 /* }}} */
108 
109 /* {{{ mysqli_commit_or_rollback_libmysql */
mysqli_commit_or_rollback_libmysql(MYSQL * conn,zend_bool commit,const uint32_t mode,const char * const name)110 static int mysqli_commit_or_rollback_libmysql(MYSQL * conn, zend_bool commit, const uint32_t mode, const char * const name)
111 {
112 	int ret;
113 	smart_str tmp_str = {0};
114 	mysqli_tx_cor_options_to_string(conn, &tmp_str, mode);
115 	smart_str_0(&tmp_str);
116 
117 	{
118 		char *query;
119 		char *name_esc = mysqli_escape_string_for_tx_name_in_comment(name);
120 		size_t query_len;
121 
122 		query_len = spprintf(&query, 0,
123 				(commit? "COMMIT%s %s":"ROLLBACK%s %s"), name_esc? name_esc:"", tmp_str.s? ZSTR_VAL(tmp_str.s):"");
124 		smart_str_free(&tmp_str);
125 		if (name_esc) {
126 			efree(name_esc);
127 			name_esc = NULL;
128 		}
129 
130 		ret = mysql_real_query(conn, query, query_len);
131 		efree(query);
132 	}
133 	return ret;
134 }
135 /* }}} */
136 #endif
137 
138 /* {{{ proto mixed mysqli_affected_rows(object link)
139    Get number of affected rows in previous MySQL operation */
PHP_FUNCTION(mysqli_affected_rows)140 PHP_FUNCTION(mysqli_affected_rows)
141 {
142 	MY_MYSQL 		*mysql;
143 	zval  			*mysql_link;
144 	my_ulonglong	rc;
145 
146 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
147 		return;
148 	}
149 
150 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
151 
152 	rc = mysql_affected_rows(mysql->mysql);
153 	if (rc == (my_ulonglong) -1) {
154 		RETURN_LONG(-1);
155 	}
156 	MYSQLI_RETURN_LONG_INT(rc);
157 }
158 /* }}} */
159 
160 /* {{{ proto bool mysqli_autocommit(object link, bool mode)
161    Turn auto commit on or of */
PHP_FUNCTION(mysqli_autocommit)162 PHP_FUNCTION(mysqli_autocommit)
163 {
164 	MY_MYSQL	*mysql;
165 	zval		*mysql_link;
166 	zend_bool	automode;
167 
168 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) {
169 		return;
170 	}
171 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
172 
173 	if (mysql_autocommit(mysql->mysql, (my_bool)automode)) {
174 		RETURN_FALSE;
175 	}
176 	RETURN_TRUE;
177 }
178 /* }}} */
179 
180 /* {{{ mysqli_stmt_bind_param_do_bind */
181 #ifndef MYSQLI_USE_MYSQLND
182 static
mysqli_stmt_bind_param_do_bind(MY_STMT * stmt,unsigned int argc,unsigned int num_vars,zval * args,unsigned int start,const char * const types)183 int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
184 								   zval *args, unsigned int start, const char * const types)
185 {
186 	int				i, ofs;
187 	MYSQL_BIND		*bind;
188 	unsigned long	rc;
189 
190 	/* prevent leak if variables are already bound */
191 	if (stmt->param.var_cnt) {
192 		php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
193 	}
194 
195 	stmt->param.is_null = ecalloc(num_vars, sizeof(char));
196 	bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND));
197 
198 	ofs = 0;
199 	for (i = start; i < argc; i++) {
200 		zval *param;
201 		if (Z_ISREF(args[i])) {
202 			param = Z_REFVAL(args[i]);
203 		} else {
204 			param = &args[i];
205 		}
206 		/* set specified type */
207 		switch (types[ofs]) {
208 			case 'd': /* Double */
209 				bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
210 				bind[ofs].buffer = &Z_DVAL_P(param);
211 				bind[ofs].is_null = &stmt->param.is_null[ofs];
212 				break;
213 
214 			case 'i': /* Integer */
215 #if SIZEOF_ZEND_LONG==8
216 				bind[ofs].buffer_type = MYSQL_TYPE_LONGLONG;
217 #elif SIZEOF_ZEND_LONG==4
218 				bind[ofs].buffer_type = MYSQL_TYPE_LONG;
219 #endif
220 				bind[ofs].buffer = &Z_LVAL_P(param);
221 				bind[ofs].is_null = &stmt->param.is_null[ofs];
222 				break;
223 
224 			case 'b': /* Blob (send data) */
225 				bind[ofs].buffer_type = MYSQL_TYPE_LONG_BLOB;
226 				/* don't initialize is_null and length to 0 because we use ecalloc */
227 				break;
228 
229 			case 's': /* string */
230 				bind[ofs].buffer_type = MYSQL_TYPE_VAR_STRING;
231 				/* don't initialize buffer and buffer_length because we use ecalloc */
232 				bind[ofs].is_null = &stmt->param.is_null[ofs];
233 				break;
234 
235 			default:
236 				php_error_docref(NULL, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1);
237 				rc = 1;
238 				goto end_1;
239 		}
240 		ofs++;
241 	}
242 	rc = mysql_stmt_bind_param(stmt->stmt, bind);
243 
244 end_1:
245 	if (rc) {
246 		efree(stmt->param.is_null);
247 	} else {
248 		stmt->param.var_cnt = num_vars;
249 		stmt->param.vars = safe_emalloc(num_vars, sizeof(zval), 0);
250 		for (i = 0; i < num_vars; i++) {
251 			if (bind[i].buffer_type != MYSQL_TYPE_LONG_BLOB) {
252 				ZVAL_COPY(&stmt->param.vars[i], &args[i+start]);
253 			} else {
254 				ZVAL_UNDEF(&stmt->param.vars[i]);
255 			}
256 		}
257 	}
258 	efree(bind);
259 
260 	return rc;
261 }
262 #else
263 static
mysqli_stmt_bind_param_do_bind(MY_STMT * stmt,unsigned int argc,unsigned int num_vars,zval * args,unsigned int start,const char * const types)264 int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
265 								   zval *args, unsigned int start, const char * const types)
266 {
267 	unsigned int i;
268 	MYSQLND_PARAM_BIND	*params;
269 	enum_func_status	ret = FAIL;
270 
271 	/* If no params -> skip binding and return directly */
272 	if (argc == start) {
273 		return PASS;
274 	}
275 	params = mysqlnd_stmt_alloc_param_bind(stmt->stmt);
276 	if (!params) {
277 		goto end;
278 	}
279 	for (i = 0; i < (argc - start); i++) {
280 		zend_uchar type;
281 		switch (types[i]) {
282 			case 'd': /* Double */
283 				type = MYSQL_TYPE_DOUBLE;
284 				break;
285 			case 'i': /* Integer */
286 #if SIZEOF_ZEND_LONG==8
287 				type = MYSQL_TYPE_LONGLONG;
288 #elif SIZEOF_ZEND_LONG==4
289 				type = MYSQL_TYPE_LONG;
290 #endif
291 				break;
292 			case 'b': /* Blob (send data) */
293 				type = MYSQL_TYPE_LONG_BLOB;
294 				break;
295 			case 's': /* string */
296 				type = MYSQL_TYPE_VAR_STRING;
297 				break;
298 			default:
299 				/* We count parameters from 1 */
300 				php_error_docref(NULL, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1);
301 				ret = FAIL;
302 				mysqlnd_stmt_free_param_bind(stmt->stmt, params);
303 				goto end;
304 		}
305 		ZVAL_COPY_VALUE(&params[i].zv, &args[i + start]);
306 		params[i].type = type;
307 	}
308 	ret = mysqlnd_stmt_bind_param(stmt->stmt, params);
309 
310 end:
311 	return ret;
312 }
313 #endif
314 /* }}} */
315 
316 /* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed ...])
317    Bind variables to a prepared statement as parameters */
PHP_FUNCTION(mysqli_stmt_bind_param)318 PHP_FUNCTION(mysqli_stmt_bind_param)
319 {
320 	zval			*args;
321 	int				argc = ZEND_NUM_ARGS();
322 	int				num_vars;
323 	int				start = 2;
324 	MY_STMT			*stmt;
325 	zval			*mysql_stmt;
326 	char			*types;
327 	size_t			types_len;
328 	zend_ulong	rc;
329 
330 	/* calculate and check number of parameters */
331 	if (argc < 2) {
332 		/* there has to be at least one pair */
333 		WRONG_PARAM_COUNT;
334 	}
335 
336 	if (zend_parse_method_parameters((getThis()) ? 1:2, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry,
337 									&types, &types_len) == FAILURE) {
338 		return;
339 	}
340 
341 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
342 
343 	num_vars = argc - 1;
344 	if (getThis()) {
345 		start = 1;
346 	} else {
347 		/* ignore handle parameter in procedural interface*/
348 		--num_vars;
349 	}
350 	if (!types_len) {
351 		php_error_docref(NULL, E_WARNING, "Invalid type or no types specified");
352 		RETURN_FALSE;
353 	}
354 
355 	if (types_len != (size_t)(argc - start)) {
356 		/* number of bind variables doesn't match number of elements in type definition string */
357 		php_error_docref(NULL, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables");
358 		RETURN_FALSE;
359 	}
360 
361 	if (types_len != mysql_stmt_param_count(stmt->stmt)) {
362 		php_error_docref(NULL, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement");
363 		RETURN_FALSE;
364 	}
365 
366 	args = safe_emalloc(argc, sizeof(zval), 0);
367 
368 	if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
369 		zend_wrong_param_count();
370 		rc = 1;
371 	} else {
372 		rc = mysqli_stmt_bind_param_do_bind(stmt, argc, num_vars, args, start, types);
373 		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
374 	}
375 
376 	efree(args);
377 
378 	RETURN_BOOL(!rc);
379 }
380 /* }}} */
381 
382 /* {{{ mysqli_stmt_bind_result_do_bind */
383 #ifndef MYSQLI_USE_MYSQLND
384 /* TODO:
385    do_alloca, free_alloca
386 */
387 static int
mysqli_stmt_bind_result_do_bind(MY_STMT * stmt,zval * args,unsigned int argc)388 mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc)
389 {
390 	MYSQL_BIND	*bind;
391 	int			i, ofs;
392 	int			var_cnt = argc;
393 	zend_long		col_type;
394 	zend_ulong		rc;
395 
396 	/* prevent leak if variables are already bound */
397 	if (stmt->result.var_cnt) {
398 		php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
399 	}
400 
401 	bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND));
402 	{
403 		int size;
404 		char *p = emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER)));
405 		stmt->result.buf = (VAR_BUFFER *) p;
406 		stmt->result.is_null = p + var_cnt * sizeof(VAR_BUFFER);
407 		memset(p, 0, size);
408 	}
409 
410 	for (i = 0; i < var_cnt; i++) {
411 		ofs = i;
412 		col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
413 
414 		switch (col_type) {
415 			case MYSQL_TYPE_FLOAT:
416 				stmt->result.buf[ofs].type = IS_DOUBLE;
417 				stmt->result.buf[ofs].buflen = sizeof(float);
418 
419 				stmt->result.buf[ofs].val = (char *)emalloc(sizeof(float));
420 				bind[ofs].buffer_type = MYSQL_TYPE_FLOAT;
421 				bind[ofs].buffer = stmt->result.buf[ofs].val;
422 				bind[ofs].is_null = &stmt->result.is_null[ofs];
423 				break;
424 
425 			case MYSQL_TYPE_DOUBLE:
426 				stmt->result.buf[ofs].type = IS_DOUBLE;
427 				stmt->result.buf[ofs].buflen = sizeof(double);
428 
429 				/* allocate buffer for double */
430 				stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double));
431 				bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
432 				bind[ofs].buffer = stmt->result.buf[ofs].val;
433 				bind[ofs].is_null = &stmt->result.is_null[ofs];
434 				break;
435 
436 			case MYSQL_TYPE_NULL:
437 				stmt->result.buf[ofs].type = IS_NULL;
438 				/*
439 				  don't initialize to 0 :
440 				  1. stmt->result.buf[ofs].buflen
441 				  2. bind[ofs].buffer
442 				  3. bind[ofs].buffer_length
443 				  because memory was allocated with ecalloc
444 				*/
445 				bind[ofs].buffer_type = MYSQL_TYPE_NULL;
446 				bind[ofs].is_null = &stmt->result.is_null[ofs];
447 				break;
448 
449 			case MYSQL_TYPE_SHORT:
450 			case MYSQL_TYPE_TINY:
451 			case MYSQL_TYPE_LONG:
452 			case MYSQL_TYPE_INT24:
453 			case MYSQL_TYPE_YEAR:
454 				stmt->result.buf[ofs].type = IS_LONG;
455 				/* don't set stmt->result.buf[ofs].buflen to 0, we used ecalloc */
456 				stmt->result.buf[ofs].val = (char *)emalloc(sizeof(int));
457 				bind[ofs].buffer_type = MYSQL_TYPE_LONG;
458 				bind[ofs].buffer = stmt->result.buf[ofs].val;
459 				bind[ofs].is_null = &stmt->result.is_null[ofs];
460 				bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
461 				break;
462 
463 			case MYSQL_TYPE_LONGLONG:
464 #if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND)
465 			case MYSQL_TYPE_BIT:
466 #endif
467 				stmt->result.buf[ofs].type = IS_STRING;
468 				stmt->result.buf[ofs].buflen = sizeof(my_ulonglong);
469 				stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
470 				bind[ofs].buffer_type = col_type;
471 				bind[ofs].buffer = stmt->result.buf[ofs].val;
472 				bind[ofs].is_null = &stmt->result.is_null[ofs];
473 				bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
474 				bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
475 				bind[ofs].length = &stmt->result.buf[ofs].output_len;
476 				break;
477 
478 			case MYSQL_TYPE_DATE:
479 			case MYSQL_TYPE_TIME:
480 			case MYSQL_TYPE_DATETIME:
481 			case MYSQL_TYPE_NEWDATE:
482 			case MYSQL_TYPE_VAR_STRING:
483 			case MYSQL_TYPE_STRING:
484 			case MYSQL_TYPE_TINY_BLOB:
485 			case MYSQL_TYPE_BLOB:
486 			case MYSQL_TYPE_MEDIUM_BLOB:
487 			case MYSQL_TYPE_LONG_BLOB:
488 			case MYSQL_TYPE_TIMESTAMP:
489 			case MYSQL_TYPE_DECIMAL:
490 			case MYSQL_TYPE_GEOMETRY:
491 #ifdef FIELD_TYPE_NEWDECIMAL
492 			case MYSQL_TYPE_NEWDECIMAL:
493 #endif
494 			{
495 #if MYSQL_VERSION_ID >= 50107
496 				/* Changed to my_bool in MySQL 5.1. See MySQL Bug #16144 */
497 				my_bool tmp;
498 #else
499 				zend_ulong tmp = 0;
500 #endif
501 				stmt->result.buf[ofs].type = IS_STRING;
502 				/*
503 					If the user has called $stmt->store_result() then we have asked
504 					max_length to be updated. this is done only for BLOBS because we don't want to allocate
505 					big chunkgs of memory 2^16 or 2^24
506 				*/
507 				if (stmt->stmt->fields[ofs].max_length == 0 &&
508 					!mysql_stmt_attr_get(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
509 				{
510 					/*
511 					  Allocate directly 256 because it's easier to allocate a bit more
512 					  than update max length even for text columns. Try SELECT UNION SELECT UNION with
513 					  different lengths and you will see that we get different lengths in stmt->stmt->fields[ofs].length
514 					  The just take 256 and saves us from realloc-ing.
515 					*/
516 					stmt->result.buf[ofs].buflen =
517 						(stmt->stmt->fields) ? (stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
518 
519 				} else {
520 					/*
521 						the user has called store_result(). if he does not there is no way to determine the
522 						libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
523 					*/
524 					if (!(stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length))
525 						++stmt->result.buf[ofs].buflen;
526 				}
527 				stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
528 				bind[ofs].buffer_type = MYSQL_TYPE_STRING;
529 				bind[ofs].buffer = stmt->result.buf[ofs].val;
530 				bind[ofs].is_null = &stmt->result.is_null[ofs];
531 				bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
532 				bind[ofs].length = &stmt->result.buf[ofs].output_len;
533 				break;
534 			}
535 			default:
536 				php_error_docref(NULL, E_WARNING, "Server returned unknown type %ld. Probably your client library is incompatible with the server version you use!", col_type);
537 				break;
538 		}
539 	}
540 
541 	rc = mysql_stmt_bind_result(stmt->stmt, bind);
542 	MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
543 
544 	if (rc) {
545 		/* don't close the statement or subsequent usage (for example ->execute()) will lead to crash */
546 		for (i=0; i < var_cnt ; i++) {
547 			if (stmt->result.buf[i].val) {
548 				efree(stmt->result.buf[i].val);
549 			}
550 		}
551 		/* Don't free stmt->result.is_null because is_null & buf are one block of memory  */
552 		efree(stmt->result.buf);
553 	} else {
554 		stmt->result.var_cnt = var_cnt;
555 		stmt->result.vars = safe_emalloc((var_cnt), sizeof(zval), 0);
556 		for (i = 0; i < var_cnt; i++) {
557 			ZVAL_COPY(&stmt->result.vars[i], &args[i]);
558 		}
559 	}
560 	efree(bind);
561 
562 	return rc;
563 }
564 #else
565 static int
mysqli_stmt_bind_result_do_bind(MY_STMT * stmt,zval * args,unsigned int argc)566 mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc)
567 {
568 	unsigned int i;
569 	MYSQLND_RESULT_BIND *params = mysqlnd_stmt_alloc_result_bind(stmt->stmt);
570 	if (params) {
571 		for (i = 0; i < argc; i++) {
572 			ZVAL_COPY_VALUE(&params[i].zv, &args[i]);
573 		}
574 		return mysqlnd_stmt_bind_result(stmt->stmt, params);
575 	}
576 	return FAIL;
577 }
578 #endif
579 /* }}} */
580 
581 /* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var [,mixed ...])
582    Bind variables to a prepared statement for result storage */
PHP_FUNCTION(mysqli_stmt_bind_result)583 PHP_FUNCTION(mysqli_stmt_bind_result)
584 {
585 	zval		*args;
586 	int			argc;
587 	zend_ulong		rc;
588 	MY_STMT		*stmt;
589 	zval		*mysql_stmt;
590 
591 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O+", &mysql_stmt, mysqli_stmt_class_entry, &args, &argc) == FAILURE) {
592 		return;
593 	}
594 
595 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
596 
597 	if ((uint32_t)argc != mysql_stmt_field_count(stmt->stmt)) {
598 		php_error_docref(NULL, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement");
599 		RETURN_FALSE;
600 	}
601 
602 	rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc);
603 	RETURN_BOOL(!rc);
604 }
605 /* }}} */
606 
607 /* {{{ proto bool mysqli_change_user(object link, string user, string password, string database)
608    Change logged-in user of the active connection */
PHP_FUNCTION(mysqli_change_user)609 PHP_FUNCTION(mysqli_change_user)
610 {
611 	MY_MYSQL	*mysql;
612 	zval		*mysql_link = NULL;
613 	char		*user, *password, *dbname;
614 	size_t			user_len, password_len, dbname_len;
615 	zend_ulong		rc;
616 #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
617 	MY_CHARSET_INFO old_charset;
618 #endif
619 
620 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Osss!", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) {
621 		return;
622 	}
623 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
624 
625 #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
626 	mysql_get_character_set_info(mysql->mysql, &old_charset);
627 #endif
628 
629 #if defined(MYSQLI_USE_MYSQLND)
630 	rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, FALSE, (size_t) password_len);
631 #else
632 	rc = mysql_change_user(mysql->mysql, user, password, dbname);
633 #endif
634 	MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
635 
636 	if (rc) {
637 		RETURN_FALSE;
638 	}
639 #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
640 	if (mysql_get_server_version(mysql->mysql) < 50123L) {
641 		/*
642 		  Request the current charset, or it will be reset to the system one.
643 		  5.0 doesn't support it. Support added in 5.1.23 by fixing the following bug :
644 		  Bug #30472 libmysql doesn't reset charset, insert_id after succ. mysql_change_user() call
645 		*/
646 		rc = mysql_set_character_set(mysql->mysql, old_charset.csname);
647 	}
648 #endif
649 
650 	RETURN_TRUE;
651 }
652 /* }}} */
653 
654 /* {{{ proto string mysqli_character_set_name(object link)
655    Returns the name of the character set used for this connection */
PHP_FUNCTION(mysqli_character_set_name)656 PHP_FUNCTION(mysqli_character_set_name)
657 {
658 	MY_MYSQL	*mysql;
659 	zval		*mysql_link;
660 	const char	*cs_name;
661 
662 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
663 		return;
664 	}
665 
666 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
667 	cs_name = mysql_character_set_name(mysql->mysql);
668 	if (cs_name) {
669 		RETURN_STRING(cs_name);
670 	}
671 }
672 /* }}} */
673 
674 /* {{{ php_mysqli_close */
php_mysqli_close(MY_MYSQL * mysql,int close_type,int resource_status)675 void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status)
676 {
677 	if (resource_status > MYSQLI_STATUS_INITIALIZED) {
678 		MyG(num_links)--;
679 	}
680 
681 	if (!mysql->persistent) {
682 		mysqli_close(mysql->mysql, close_type);
683 	} else {
684 		zend_resource *le;
685 		if ((le = zend_hash_find_ptr(&EG(persistent_list), mysql->hash_key)) != NULL) {
686 			if (le->type == php_le_pmysqli()) {
687 				mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
688 #if defined(MYSQLI_USE_MYSQLND)
689 				mysqlnd_end_psession(mysql->mysql);
690 #endif
691 
692 				if (MyG(rollback_on_cached_plink) &&
693 #if !defined(MYSQLI_USE_MYSQLND)
694 					mysqli_commit_or_rollback_libmysql(mysql->mysql, FALSE, TRANS_COR_NO_OPT, NULL))
695 #else
696 					FAIL == mysqlnd_rollback(mysql->mysql, TRANS_COR_NO_OPT, NULL))
697 #endif
698 				{
699 					mysqli_close(mysql->mysql, close_type);
700 				} else {
701 					zend_ptr_stack_push(&plist->free_links, mysql->mysql);
702 					MyG(num_inactive_persistent)++;
703 				}
704 				MyG(num_active_persistent)--;
705 			}
706 		}
707 		mysql->persistent = FALSE;
708 	}
709 	mysql->mysql = NULL;
710 
711 	php_clear_mysql(mysql);
712 }
713 /* }}} */
714 
715 /* {{{ proto bool mysqli_close(object link)
716    Close connection */
PHP_FUNCTION(mysqli_close)717 PHP_FUNCTION(mysqli_close)
718 {
719 	zval		*mysql_link;
720 	MY_MYSQL	*mysql;
721 
722 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
723 		return;
724 	}
725 
726 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
727 
728 	php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, ((MYSQLI_RESOURCE *)(Z_MYSQLI_P(mysql_link))->ptr)->status);
729 	((MYSQLI_RESOURCE *)(Z_MYSQLI_P(mysql_link))->ptr)->status = MYSQLI_STATUS_UNKNOWN;
730 
731 	MYSQLI_CLEAR_RESOURCE(mysql_link);
732 	efree(mysql);
733 	RETURN_TRUE;
734 }
735 /* }}} */
736 
737 /* {{{ proto bool mysqli_commit(object link[, int flags [, string name ]])
738    Commit outstanding actions and close transaction */
PHP_FUNCTION(mysqli_commit)739 PHP_FUNCTION(mysqli_commit)
740 {
741 	MY_MYSQL	*mysql;
742 	zval		*mysql_link;
743 	zend_long		flags = TRANS_COR_NO_OPT;
744 	char *		name = NULL;
745 	size_t			name_len = 0;
746 
747 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
748 		return;
749 	}
750 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
751 
752 #if !defined(MYSQLI_USE_MYSQLND)
753 	if (mysqli_commit_or_rollback_libmysql(mysql->mysql, TRUE, flags, name)) {
754 #else
755 	if (FAIL == mysqlnd_commit(mysql->mysql, flags, name)) {
756 #endif
757 		RETURN_FALSE;
758 	}
759 	RETURN_TRUE;
760 }
761 /* }}} */
762 
763 /* {{{ proto bool mysqli_data_seek(object result, int offset)
764    Move internal result pointer */
765 PHP_FUNCTION(mysqli_data_seek)
766 {
767 	MYSQL_RES	*result;
768 	zval		*mysql_result;
769 	zend_long		offset;
770 
771 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
772 		return;
773 	}
774 
775 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
776 
777 	if (mysqli_result_is_unbuffered(result)) {
778 		php_error_docref(NULL, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
779 		RETURN_FALSE;
780 	}
781 
782 	if (offset < 0 || (uint64_t)offset >= mysql_num_rows(result)) {
783 		RETURN_FALSE;
784 	}
785 
786 	mysql_data_seek(result, offset);
787 	RETURN_TRUE;
788 }
789 /* }}} */
790 
791 /* {{{ proto void mysqli_debug(string debug)
792 */
793 PHP_FUNCTION(mysqli_debug)
794 {
795 	char	*debug;
796 	size_t		debug_len;
797 
798 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &debug, &debug_len) == FAILURE) {
799 		return;
800 	}
801 
802 	mysql_debug(debug);
803 	RETURN_TRUE;
804 }
805 /* }}} */
806 
807 /* {{{ proto bool mysqli_dump_debug_info(object link)
808 */
809 PHP_FUNCTION(mysqli_dump_debug_info)
810 {
811 	MY_MYSQL	*mysql;
812 	zval		*mysql_link;
813 
814 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
815 		return;
816 	}
817 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
818 
819 	RETURN_BOOL(!mysql_dump_debug_info(mysql->mysql))
820 }
821 /* }}} */
822 
823 /* {{{ proto int mysqli_errno(object link)
824    Returns the numerical value of the error message from previous MySQL operation */
825 PHP_FUNCTION(mysqli_errno)
826 {
827 	MY_MYSQL	*mysql;
828 	zval		*mysql_link;
829 
830 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
831 		return;
832 	}
833 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
834 	RETURN_LONG(mysql_errno(mysql->mysql));
835 }
836 /* }}} */
837 
838 /* {{{ proto string mysqli_error(object link)
839    Returns the text of the error message from previous MySQL operation */
840 PHP_FUNCTION(mysqli_error)
841 {
842 	MY_MYSQL	*mysql;
843 	zval		*mysql_link;
844 	const char	*err;
845 
846 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
847 		return;
848 	}
849 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
850 	err = mysql_error(mysql->mysql);
851 	if (err) {
852 		RETURN_STRING(err);
853 	}
854 }
855 /* }}} */
856 
857 /* {{{ proto bool mysqli_stmt_execute(object stmt)
858    Execute a prepared statement */
859 PHP_FUNCTION(mysqli_stmt_execute)
860 {
861 	MY_STMT		*stmt;
862 	zval		*mysql_stmt;
863 #ifndef MYSQLI_USE_MYSQLND
864 	unsigned int	i;
865 #endif
866 
867 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
868 		return;
869 	}
870 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
871 
872 #ifndef MYSQLI_USE_MYSQLND
873 	if (stmt->param.var_cnt) {
874 		int j;
875 		for (i = 0; i < stmt->param.var_cnt; i++) {
876 			if (!Z_ISREF(stmt->param.vars[i])) {
877 				continue;
878 			}
879 			for (j = i + 1; j < stmt->param.var_cnt; j++) {
880 				/* Oops, someone binding the same variable - clone */
881 				if (Z_ISREF(stmt->param.vars[j]) &&
882 					   	Z_REFVAL(stmt->param.vars[j]) == Z_REFVAL(stmt->param.vars[i])) {
883 					/*SEPARATE_ZVAL(&stmt->param.vars[j]);*/
884 					Z_DELREF_P(&stmt->param.vars[j]);
885 					ZVAL_COPY(&stmt->param.vars[j], Z_REFVAL(stmt->param.vars[j]));
886 					break;
887 				}
888 			}
889 		}
890 	}
891 	for (i = 0; i < stmt->param.var_cnt; i++) {
892 		if (!Z_ISUNDEF(stmt->param.vars[i])) {
893 			zval *param;
894 			if (Z_ISREF(stmt->param.vars[i])) {
895 				param = Z_REFVAL(stmt->param.vars[i]);
896 			} else {
897 				param = &stmt->param.vars[i];
898 			}
899 			if (!(stmt->param.is_null[i] = (Z_ISNULL_P(param)))) {
900 				switch (stmt->stmt->params[i].buffer_type) {
901 					case MYSQL_TYPE_VAR_STRING:
902 						convert_to_string_ex(param);
903 						stmt->stmt->params[i].buffer = Z_STRVAL_P(param);
904 						stmt->stmt->params[i].buffer_length = Z_STRLEN_P(param);
905 						break;
906 					case MYSQL_TYPE_DOUBLE:
907 						convert_to_double_ex(param);
908 						stmt->stmt->params[i].buffer = &Z_DVAL_P(param);
909 						break;
910 					case MYSQL_TYPE_LONGLONG:
911 					case MYSQL_TYPE_LONG:
912 						convert_to_long_ex(param);
913 						stmt->stmt->params[i].buffer = &Z_LVAL_P(param);
914 						break;
915 					default:
916 						break;
917 				}
918 			}
919 		}
920 	}
921 #endif
922 
923 	if (mysql_stmt_execute(stmt->stmt)) {
924 		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
925 		RETVAL_FALSE;
926 	} else {
927 		RETVAL_TRUE;
928 	}
929 
930 	if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
931 		php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt));
932 	}
933 }
934 /* }}} */
935 
936 #ifndef MYSQLI_USE_MYSQLND
937 /* {{{ void mysqli_stmt_fetch_libmysql
938    Fetch results from a prepared statement into the bound variables */
939 void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
940 {
941 	MY_STMT		*stmt;
942 	zval			*mysql_stmt;
943 	unsigned int	i;
944 	zend_ulong			ret;
945 	unsigned int	uval;
946 	my_ulonglong	llval;
947 
948 
949 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
950 		return;
951 	}
952 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
953 
954 	/* reset buffers */
955 	for (i = 0; i < stmt->result.var_cnt; i++) {
956 		if (stmt->result.buf[i].type == IS_STRING) {
957 			memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen);
958 		}
959 	}
960 	ret = mysql_stmt_fetch(stmt->stmt);
961 #ifdef MYSQL_DATA_TRUNCATED
962 	if (!ret || ret == MYSQL_DATA_TRUNCATED) {
963 #else
964 	if (!ret) {
965 #endif
966 		for (i = 0; i < stmt->result.var_cnt; i++) {
967 			zval *result;
968 			/* it must be a reference, isn't it? */
969 			if (Z_ISREF(stmt->result.vars[i])) {
970 				result = Z_REFVAL(stmt->result.vars[i]);
971 			} else {
972 				result = &stmt->result.vars[i];
973 			}
974 			/*
975 			  QQ: Isn't it quite better to call zval_dtor(). What if the user has
976 			  assigned a resource, or an array to the bound variable? We are going
977 			  to leak probably. zval_dtor() will handle also Unicode/Non-unicode mode.
978 			*/
979 			/* Even if the string is of length zero there is one byte alloced so efree() in all cases */
980 			zval_ptr_dtor(result);
981 			if (!stmt->result.is_null[i]) {
982 				switch (stmt->result.buf[i].type) {
983 					case IS_LONG:
984 						if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG)
985 						    && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG))
986 						{
987 							/* unsigned int (11) */
988 							uval= *(unsigned int *) stmt->result.buf[i].val;
989 #if SIZEOF_ZEND_LONG==4
990 							if (uval > INT_MAX) {
991 								char *tmp, *p;
992 								int j = 10;
993 								tmp = emalloc(11);
994 								p= &tmp[9];
995 								do {
996 									*p-- = (uval % 10) + 48;
997 									uval = uval / 10;
998 								} while (--j > 0);
999 								tmp[10]= '\0';
1000 								/* unsigned int > INT_MAX is 10 digits - ALWAYS */
1001 								ZVAL_STRINGL(result, tmp, 10);
1002 								efree(tmp);
1003 								break;
1004 							}
1005 #endif
1006 						}
1007 						if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) {
1008 							ZVAL_LONG(result, *(unsigned int *)stmt->result.buf[i].val);
1009 						} else {
1010 							ZVAL_LONG(result, *(int *)stmt->result.buf[i].val);
1011 						}
1012 						break;
1013 					case IS_DOUBLE:
1014 					{
1015 						double dval;
1016 						if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_FLOAT) {
1017 #ifndef NOT_FIXED_DEC
1018 # define NOT_FIXED_DEC 31
1019 #endif
1020 							dval = mysql_float_to_double(*(float *)stmt->result.buf[i].val,
1021 										(stmt->stmt->fields[i].decimals >= NOT_FIXED_DEC) ? -1 :
1022 										stmt->stmt->fields[i].decimals);
1023 						} else {
1024 							dval = *((double *)stmt->result.buf[i].val);
1025 						}
1026 
1027 						ZVAL_DOUBLE(result, dval);
1028 						break;
1029 					}
1030 					case IS_STRING:
1031 						if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG
1032 #if MYSQL_VERSION_ID > 50002
1033 						 || stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT
1034 #endif
1035 						 ) {
1036 							my_bool uns = (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;
1037 #if MYSQL_VERSION_ID > 50002
1038 							if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) {
1039 								switch (stmt->result.buf[i].output_len) {
1040 									case 8:llval = (my_ulonglong)  bit_uint8korr(stmt->result.buf[i].val);break;
1041 									case 7:llval = (my_ulonglong)  bit_uint7korr(stmt->result.buf[i].val);break;
1042 									case 6:llval = (my_ulonglong)  bit_uint6korr(stmt->result.buf[i].val);break;
1043 									case 5:llval = (my_ulonglong)  bit_uint5korr(stmt->result.buf[i].val);break;
1044 									case 4:llval = (my_ulonglong)  bit_uint4korr(stmt->result.buf[i].val);break;
1045 									case 3:llval = (my_ulonglong)  bit_uint3korr(stmt->result.buf[i].val);break;
1046 									case 2:llval = (my_ulonglong)  bit_uint2korr(stmt->result.buf[i].val);break;
1047 									case 1:llval = (my_ulonglong)  uint1korr(stmt->result.buf[i].val);break;
1048 								}
1049 							} else
1050 #endif
1051 							{
1052 								llval= *(my_ulonglong *) stmt->result.buf[i].val;
1053 							}
1054 #if SIZEOF_ZEND_LONG==8
1055 							if (uns && llval > 9223372036854775807L) {
1056 #elif SIZEOF_ZEND_LONG==4
1057 							if ((uns && llval > L64(2147483647)) ||
1058 								(!uns && (( L64(2147483647) < (my_longlong) llval) ||
1059 								(L64(-2147483648) > (my_longlong) llval))))
1060 							{
1061 #endif
1062 								char tmp[22];
1063 								/* even though lval is declared as unsigned, the value
1064 								 * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
1065 								 * use MYSQLI_LL_SPEC.
1066 								 */
1067 								snprintf(tmp, sizeof(tmp), (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
1068 								ZVAL_STRING(result, tmp);
1069 							} else {
1070 								ZVAL_LONG(result, llval);
1071 							}
1072 						} else {
1073 #if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002
1074 							if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
1075 								/* result was truncated */
1076 								ZVAL_STRINGL(result, stmt->result.buf[i].val, stmt->stmt->bind[i].buffer_length);
1077 							} else {
1078 #else
1079 							{
1080 #endif
1081 								ZVAL_STRINGL(result, stmt->result.buf[i].val, stmt->result.buf[i].output_len);
1082 							}
1083 						}
1084 						break;
1085 					default:
1086 						break;
1087 				}
1088 			} else {
1089 				ZVAL_NULL(result);
1090 			}
1091 		}
1092 	} else {
1093 		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
1094 	}
1095 
1096 	switch (ret) {
1097 		case 0:
1098 #ifdef MYSQL_DATA_TRUNCATED
1099 		/* according to SQL standard truncation (e.g. loss of precision is
1100 		   not an error) - for detecting possible truncation you have to
1101 		   check mysqli_stmt_warning
1102 		*/
1103 		case MYSQL_DATA_TRUNCATED:
1104 #endif
1105 			RETURN_TRUE;
1106 		break;
1107 		case 1:
1108 			RETURN_FALSE;
1109 		break;
1110 		default:
1111 			RETURN_NULL();
1112 		break;
1113 	}
1114 }
1115 /* }}} */
1116 #else
1117 /* {{{ mixed mysqli_stmt_fetch_mysqlnd */
1118 void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)
1119 {
1120 	MY_STMT		*stmt;
1121 	zval		*mysql_stmt;
1122 	zend_bool	fetched_anything;
1123 
1124 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1125 		return;
1126 	}
1127 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1128 
1129 	if (FAIL  == mysqlnd_stmt_fetch(stmt->stmt, &fetched_anything)) {
1130 		RETURN_BOOL(FALSE);
1131 	} else if (fetched_anything == TRUE) {
1132 		RETURN_BOOL(TRUE);
1133 	} else {
1134 		RETURN_NULL();
1135 	}
1136 }
1137 #endif
1138 /* }}} */
1139 
1140 /* {{{ proto mixed mysqli_stmt_fetch(object stmt)
1141    Fetch results from a prepared statement into the bound variables */
1142 PHP_FUNCTION(mysqli_stmt_fetch)
1143 {
1144 #if !defined(MYSQLI_USE_MYSQLND)
1145 	mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1146 #else
1147 	mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1148 #endif
1149 }
1150 /* }}} */
1151 
1152 /* {{{  php_add_field_properties */
1153 static void php_add_field_properties(zval *value, const MYSQL_FIELD *field)
1154 {
1155 #ifdef MYSQLI_USE_MYSQLND
1156 	add_property_str(value, "name", zend_string_copy(field->sname));
1157 #else
1158 	add_property_stringl(value, "name",(field->name ? field->name : ""), field->name_length);
1159 #endif
1160 
1161 	add_property_stringl(value, "orgname", (field->org_name ? field->org_name : ""), field->org_name_length);
1162 	add_property_stringl(value, "table", (field->table ? field->table : ""), field->table_length);
1163 	add_property_stringl(value, "orgtable", (field->org_table ? field->org_table : ""), field->org_table_length);
1164 	add_property_stringl(value, "def", (field->def ? field->def : ""), field->def_length);
1165 	add_property_stringl(value, "db", (field->db ? field->db : ""), field->db_length);
1166 
1167 	/* FIXME: manually set the catalog to "def" due to bug in
1168 	 * libmysqlclient which does not initialize field->catalog
1169 	 * and in addition, the catalog is always be "def"
1170 	 */
1171 	add_property_string(value, "catalog", "def");
1172 
1173 	add_property_long(value, "max_length", field->max_length);
1174 	add_property_long(value, "length", field->length);
1175 	add_property_long(value, "charsetnr", field->charsetnr);
1176 	add_property_long(value, "flags", field->flags);
1177 	add_property_long(value, "type", field->type);
1178 	add_property_long(value, "decimals", field->decimals);
1179 }
1180 /* }}} */
1181 
1182 /* {{{ proto mixed mysqli_fetch_field(object result)
1183    Get column information from a result and return as an object */
1184 PHP_FUNCTION(mysqli_fetch_field)
1185 {
1186 	MYSQL_RES	*result;
1187 	zval		*mysql_result;
1188 	const MYSQL_FIELD	*field;
1189 
1190 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1191 		return;
1192 	}
1193 
1194 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1195 
1196 	if (!(field = mysql_fetch_field(result))) {
1197 		RETURN_FALSE;
1198 	}
1199 
1200 	object_init(return_value);
1201 	php_add_field_properties(return_value, field);
1202 }
1203 /* }}} */
1204 
1205 /* {{{ proto mixed mysqli_fetch_fields(object result)
1206    Return array of objects containing field meta-data */
1207 PHP_FUNCTION(mysqli_fetch_fields)
1208 {
1209 	MYSQL_RES	*result;
1210 	zval		*mysql_result;
1211 	zval		obj;
1212 
1213 	unsigned int i, num_fields;
1214 
1215 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1216 		return;
1217 	}
1218 
1219 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1220 
1221 	array_init(return_value);
1222 	num_fields = mysql_num_fields(result);
1223 
1224 	for (i = 0; i < num_fields; i++) {
1225 		const MYSQL_FIELD *field = mysql_fetch_field_direct(result, i);
1226 
1227 		object_init(&obj);
1228 
1229 		php_add_field_properties(&obj, field);
1230 		add_index_zval(return_value, i, &obj);
1231 	}
1232 }
1233 /* }}} */
1234 
1235 /* {{{ proto mixed mysqli_fetch_field_direct(object result, int offset)
1236    Fetch meta-data for a single field */
1237 PHP_FUNCTION(mysqli_fetch_field_direct)
1238 {
1239 	MYSQL_RES	*result;
1240 	zval		*mysql_result;
1241 	const MYSQL_FIELD	*field;
1242 	zend_long		offset;
1243 
1244 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
1245 		return;
1246 	}
1247 
1248 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1249 
1250 	if (offset < 0 || offset >= (zend_long) mysql_num_fields(result)) {
1251 		php_error_docref(NULL, E_WARNING, "Field offset is invalid for resultset");
1252 		RETURN_FALSE;
1253 	}
1254 
1255 	if (!(field = mysql_fetch_field_direct(result,offset))) {
1256 		RETURN_FALSE;
1257 	}
1258 
1259 	object_init(return_value);
1260 	php_add_field_properties(return_value, field);
1261 }
1262 /* }}} */
1263 
1264 /* {{{ proto mixed mysqli_fetch_lengths(object result)
1265    Get the length of each output in a result */
1266 PHP_FUNCTION(mysqli_fetch_lengths)
1267 {
1268 	MYSQL_RES		*result;
1269 	zval			*mysql_result;
1270 	unsigned int	i, num_fields;
1271 #if defined(MYSQLI_USE_MYSQLND)
1272 	const size_t	*ret;
1273 #else
1274 	const zend_ulong *ret;
1275 #endif
1276 
1277 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1278 		return;
1279 	}
1280 
1281 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1282 
1283 	if (!(ret = mysql_fetch_lengths(result))) {
1284 		RETURN_FALSE;
1285 	}
1286 
1287 	array_init(return_value);
1288 	num_fields = mysql_num_fields(result);
1289 
1290 	for (i = 0; i < num_fields; i++) {
1291 		add_index_long(return_value, i, ret[i]);
1292 	}
1293 }
1294 /* }}} */
1295 
1296 /* {{{ proto array mysqli_fetch_row(object result)
1297    Get a result row as an enumerated array */
1298 PHP_FUNCTION(mysqli_fetch_row)
1299 {
1300 	php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0);
1301 }
1302 /* }}} */
1303 
1304 /* {{{ proto int mysqli_field_count(object link)
1305    Fetch the number of fields returned by the last query for the given link
1306 */
1307 PHP_FUNCTION(mysqli_field_count)
1308 {
1309 	MY_MYSQL	*mysql;
1310 	zval		*mysql_link;
1311 
1312 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1313 		return;
1314 	}
1315 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1316 
1317 	RETURN_LONG(mysql_field_count(mysql->mysql));
1318 }
1319 /* }}} */
1320 
1321 /* {{{ proto int mysqli_field_seek(object result, int fieldnr)
1322    Set result pointer to a specified field offset
1323 */
1324 PHP_FUNCTION(mysqli_field_seek)
1325 {
1326 	MYSQL_RES		*result;
1327 	zval			*mysql_result;
1328 	zend_long	fieldnr;
1329 
1330 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &fieldnr) == FAILURE) {
1331 		return;
1332 	}
1333 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1334 
1335 	if (fieldnr < 0 || (uint32_t)fieldnr >= mysql_num_fields(result)) {
1336 		php_error_docref(NULL, E_WARNING, "Invalid field offset");
1337 		RETURN_FALSE;
1338 	}
1339 
1340 	mysql_field_seek(result, fieldnr);
1341 	RETURN_TRUE;
1342 }
1343 /* }}} */
1344 
1345 /* {{{ proto int mysqli_field_tell(object result)
1346    Get current field offset of result pointer */
1347 PHP_FUNCTION(mysqli_field_tell)
1348 {
1349 	MYSQL_RES	*result;
1350 	zval		*mysql_result;
1351 
1352 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1353 		return;
1354 	}
1355 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1356 
1357 	RETURN_LONG(mysql_field_tell(result));
1358 }
1359 /* }}} */
1360 
1361 /* {{{ proto void mysqli_free_result(object result)
1362    Free query result memory for the given result handle */
1363 PHP_FUNCTION(mysqli_free_result)
1364 {
1365 	MYSQL_RES	*result;
1366 	zval		*mysql_result;
1367 
1368 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1369 		return;
1370 	}
1371 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1372 
1373 	mysqli_free_result(result, FALSE);
1374 	MYSQLI_CLEAR_RESOURCE(mysql_result);
1375 }
1376 /* }}} */
1377 
1378 /* {{{ proto string mysqli_get_client_info(void)
1379    Get MySQL client info */
1380 PHP_FUNCTION(mysqli_get_client_info)
1381 {
1382 	const char * info = mysql_get_client_info();
1383 	if (info) {
1384 		RETURN_STRING(info);
1385 	}
1386 }
1387 /* }}} */
1388 
1389 /* {{{ proto int mysqli_get_client_version(void)
1390    Get MySQL client info */
1391 PHP_FUNCTION(mysqli_get_client_version)
1392 {
1393 	RETURN_LONG((zend_long)mysql_get_client_version());
1394 }
1395 /* }}} */
1396 
1397 /* {{{ proto string mysqli_get_host_info(object link)
1398    Get MySQL host info */
1399 PHP_FUNCTION(mysqli_get_host_info)
1400 {
1401 	MY_MYSQL	*mysql;
1402 	zval		*mysql_link = NULL;
1403 
1404 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1405 		return;
1406 	}
1407 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1408 #if !defined(MYSQLI_USE_MYSQLND)
1409 	RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "");
1410 #else
1411 	RETURN_STRING((mysql->mysql->data->host_info) ? mysql->mysql->data->host_info : "");
1412 #endif
1413 }
1414 /* }}} */
1415 
1416 /* {{{ proto int mysqli_get_proto_info(object link)
1417    Get MySQL protocol information */
1418 PHP_FUNCTION(mysqli_get_proto_info)
1419 {
1420 	MY_MYSQL	*mysql;
1421 	zval		*mysql_link = NULL;
1422 
1423 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1424 		return;
1425 	}
1426 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1427 	RETURN_LONG(mysql_get_proto_info(mysql->mysql));
1428 }
1429 /* }}} */
1430 
1431 /* {{{ proto string mysqli_get_server_info(object link)
1432    Get MySQL server info */
1433 PHP_FUNCTION(mysqli_get_server_info)
1434 {
1435 	MY_MYSQL	*mysql;
1436 	zval		*mysql_link = NULL;
1437 	const char	*info;
1438 
1439 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1440 		return;
1441 	}
1442 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1443 
1444 	info = mysql_get_server_info(mysql->mysql);
1445 	if (info) {
1446 		RETURN_STRING(info);
1447 	}
1448 }
1449 /* }}} */
1450 
1451 /* {{{ proto int mysqli_get_server_version(object link)
1452    Return the MySQL version for the server referenced by the given link */
1453 PHP_FUNCTION(mysqli_get_server_version)
1454 {
1455 	MY_MYSQL	*mysql;
1456 	zval		*mysql_link = NULL;
1457 
1458 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1459 		return;
1460 	}
1461 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1462 
1463 	RETURN_LONG(mysql_get_server_version(mysql->mysql));
1464 }
1465 /* }}} */
1466 
1467 /* {{{ proto string mysqli_info(object link)
1468    Get information about the most recent query */
1469 PHP_FUNCTION(mysqli_info)
1470 {
1471 	MY_MYSQL	*mysql;
1472 	zval		*mysql_link = NULL;
1473 	const char	*info;
1474 
1475 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1476 		return;
1477 	}
1478 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1479 
1480 	info = mysql_info(mysql->mysql);
1481 	if (info) {
1482 		RETURN_STRING(info);
1483 	}
1484 }
1485 /* }}} */
1486 
1487 /* {{{ php_mysqli_init() */
1488 void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_method)
1489 {
1490 	MYSQLI_RESOURCE *mysqli_resource;
1491 	MY_MYSQL *mysql;
1492 
1493 	if (is_method && (Z_MYSQLI_P(getThis()))->ptr) {
1494 		return;
1495 	}
1496 
1497 	mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL));
1498 
1499 #if !defined(MYSQLI_USE_MYSQLND)
1500 	if (!(mysql->mysql = mysql_init(NULL)))
1501 #else
1502 	/*
1503 	  We create always persistent, as if the user want to connecto
1504 	  to p:somehost, we can't convert the handle then
1505 	*/
1506 	if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, TRUE)))
1507 #endif
1508 	{
1509 		efree(mysql);
1510 		RETURN_FALSE;
1511 	}
1512 
1513 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1514 	mysqli_resource->ptr = (void *)mysql;
1515 	mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
1516 
1517 	if (!is_method) {
1518 		MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
1519 	} else {
1520 		(Z_MYSQLI_P(getThis()))->ptr = mysqli_resource;
1521 	}
1522 }
1523 /* }}} */
1524 
1525 /* {{{ proto resource mysqli_init(void)
1526    Initialize mysqli and return a resource for use with mysql_real_connect */
1527 PHP_FUNCTION(mysqli_init)
1528 {
1529 	php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE);
1530 }
1531 /* }}} */
1532 
1533 /* {{{ proto resource mysqli::init(void)
1534    Initialize mysqli and return a resource for use with mysql_real_connect */
1535 PHP_FUNCTION(mysqli_init_method)
1536 {
1537 	php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE);
1538 }
1539 /* }}} */
1540 
1541 /* {{{ proto mixed mysqli_insert_id(object link)
1542    Get the ID generated from the previous INSERT operation */
1543 PHP_FUNCTION(mysqli_insert_id)
1544 {
1545 	MY_MYSQL		*mysql;
1546 	my_ulonglong	rc;
1547 	zval			*mysql_link;
1548 
1549 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1550 		return;
1551 	}
1552 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1553 	rc = mysql_insert_id(mysql->mysql);
1554 	MYSQLI_RETURN_LONG_INT(rc)
1555 }
1556 /* }}} */
1557 
1558 /* {{{ proto bool mysqli_kill(object link, int processid)
1559    Kill a mysql process on the server */
1560 PHP_FUNCTION(mysqli_kill)
1561 {
1562 	MY_MYSQL	*mysql;
1563 	zval		*mysql_link;
1564 	zend_long		processid;
1565 
1566 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) {
1567 		return;
1568 	}
1569 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1570 
1571 	if (processid <= 0) {
1572 		php_error_docref(NULL, E_WARNING, "processid should have positive value");
1573 		RETURN_FALSE;
1574 	}
1575 
1576 	if (mysql_kill(mysql->mysql, processid)) {
1577 		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1578 		RETURN_FALSE;
1579 	}
1580 	RETURN_TRUE;
1581 }
1582 /* }}} */
1583 
1584 /* {{{ proto bool mysqli_more_results(object link)
1585    check if there any more query results from a multi query */
1586 PHP_FUNCTION(mysqli_more_results)
1587 {
1588 	MY_MYSQL	*mysql;
1589 	zval		*mysql_link;
1590 
1591 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1592 		return;
1593 	}
1594 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1595 
1596 	RETURN_BOOL(mysql_more_results(mysql->mysql));
1597 }
1598 /* }}} */
1599 
1600 /* {{{ proto bool mysqli_next_result(object link)
1601    read next result from multi_query */
1602 PHP_FUNCTION(mysqli_next_result) {
1603 	MY_MYSQL	*mysql;
1604 	zval		*mysql_link;
1605 
1606 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1607 		return;
1608 	}
1609 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1610 
1611 	if (!mysql_more_results(mysql->mysql)) {
1612 		php_error_docref(NULL, E_STRICT, "There is no next result set. "
1613 						"Please, call mysqli_more_results()/mysqli::more_results() to check "
1614 						"whether to call this function/method");
1615 	}
1616 
1617 	RETURN_BOOL(!mysql_next_result(mysql->mysql));
1618 }
1619 /* }}} */
1620 
1621 #if defined(HAVE_STMT_NEXT_RESULT) && defined(MYSQLI_USE_MYSQLND)
1622 /* {{{ proto bool mysqli_stmt_next_result(object link)
1623    check if there any more query results from a multi query */
1624 PHP_FUNCTION(mysqli_stmt_more_results)
1625 {
1626 	MY_STMT		*stmt;
1627 	zval		*mysql_stmt;
1628 
1629 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1630 		return;
1631 	}
1632 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1633 
1634 	RETURN_BOOL(mysqlnd_stmt_more_results(stmt->stmt));
1635 }
1636 /* }}} */
1637 
1638 /* {{{ proto bool mysqli_stmt_next_result(object link)
1639    read next result from multi_query */
1640 PHP_FUNCTION(mysqli_stmt_next_result) {
1641 	MY_STMT		*stmt;
1642 	zval		*mysql_stmt;
1643 
1644 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1645 		return;
1646 	}
1647 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1648 
1649 	if (!mysqlnd_stmt_more_results(stmt->stmt)) {
1650 		php_error_docref(NULL, E_STRICT, "There is no next result set. "
1651 						"Please, call mysqli_stmt_more_results()/mysqli_stmt::more_results() to check "
1652 						"whether to call this function/method");
1653 	}
1654 
1655 	RETURN_BOOL(!mysql_stmt_next_result(stmt->stmt));
1656 }
1657 /* }}} */
1658 #endif
1659 
1660 /* {{{ proto int mysqli_num_fields(object result)
1661    Get number of fields in result */
1662 PHP_FUNCTION(mysqli_num_fields)
1663 {
1664 	MYSQL_RES	*result;
1665 	zval		*mysql_result;
1666 
1667 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1668 		return;
1669 	}
1670 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1671 
1672 	RETURN_LONG(mysql_num_fields(result));
1673 }
1674 /* }}} */
1675 
1676 /* {{{ proto mixed mysqli_num_rows(object result)
1677    Get number of rows in result */
1678 PHP_FUNCTION(mysqli_num_rows)
1679 {
1680 	MYSQL_RES	*result;
1681 	zval		*mysql_result;
1682 
1683 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1684 		return;
1685 	}
1686 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1687 
1688 	if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) {
1689 		php_error_docref(NULL, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
1690 		RETURN_LONG(0);
1691 	}
1692 
1693 	MYSQLI_RETURN_LONG_INT(mysql_num_rows(result));
1694 }
1695 /* }}} */
1696 
1697 /* {{{ mysqli_options_get_option_zval_type */
1698 static int mysqli_options_get_option_zval_type(int option)
1699 {
1700 	switch (option) {
1701 #ifdef MYSQLI_USE_MYSQLND
1702 		case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
1703 		case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
1704 #ifdef MYSQLND_STRING_TO_INT_CONVERSION
1705 		case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
1706 #endif
1707 #endif /* MYSQLI_USE_MYSQLND */
1708 		case MYSQL_OPT_CONNECT_TIMEOUT:
1709 #ifdef MYSQL_REPORT_DATA_TRUNCATION
1710 		case MYSQL_REPORT_DATA_TRUNCATION:
1711 #endif
1712 		case MYSQL_OPT_LOCAL_INFILE:
1713 		case MYSQL_OPT_NAMED_PIPE:
1714 #ifdef MYSQL_OPT_PROTOCOL
1715                 case MYSQL_OPT_PROTOCOL:
1716 #endif /* MySQL 4.1.0 */
1717 		case MYSQL_OPT_READ_TIMEOUT:
1718 		case MYSQL_OPT_WRITE_TIMEOUT:
1719 #ifdef MYSQL_OPT_GUESS_CONNECTION /* removed in MySQL-8.0 */
1720 		case MYSQL_OPT_GUESS_CONNECTION:
1721 		case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
1722 		case MYSQL_OPT_USE_REMOTE_CONNECTION:
1723 		case MYSQL_SECURE_AUTH:
1724 #endif
1725 #ifdef MYSQL_OPT_RECONNECT
1726 		case MYSQL_OPT_RECONNECT:
1727 #endif /* MySQL 5.0.13 */
1728 #ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
1729 		case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
1730 #endif /* MySQL 5.0.23 */
1731 #ifdef MYSQL_OPT_COMPRESS
1732 		case MYSQL_OPT_COMPRESS:
1733 #endif /* mysqlnd @ PHP 5.3.2 */
1734 #if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
1735 		case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
1736 #endif
1737 			return IS_LONG;
1738 
1739 #ifdef MYSQL_SHARED_MEMORY_BASE_NAME
1740 		case MYSQL_SHARED_MEMORY_BASE_NAME:
1741 #endif /* MySQL 4.1.0 */
1742 #ifdef MYSQL_SET_CLIENT_IP
1743 		case MYSQL_SET_CLIENT_IP:
1744 #endif /* MySQL 4.1.1 */
1745 		case MYSQL_READ_DEFAULT_FILE:
1746 		case MYSQL_READ_DEFAULT_GROUP:
1747 		case MYSQL_INIT_COMMAND:
1748 		case MYSQL_SET_CHARSET_NAME:
1749 		case MYSQL_SET_CHARSET_DIR:
1750 #if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
1751 		case MYSQL_SERVER_PUBLIC_KEY:
1752 #endif
1753 			return IS_STRING;
1754 
1755 		default:
1756 			return IS_NULL;
1757 	}
1758 }
1759 /* }}} */
1760 
1761 /* {{{ proto bool mysqli_options(object link, int flags, mixed values)
1762    Set options */
1763 PHP_FUNCTION(mysqli_options)
1764 {
1765 	MY_MYSQL		*mysql;
1766 	zval			*mysql_link = NULL;
1767 	zval			*mysql_value;
1768 	zend_long			mysql_option;
1769 	unsigned int	l_value;
1770 	zend_long			ret;
1771 	int				expected_type;
1772 
1773 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Olz", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) {
1774 		return;
1775 	}
1776 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
1777 
1778 #if !defined(MYSQLI_USE_MYSQLND)
1779 	if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
1780 		if(mysql_option == MYSQL_OPT_LOCAL_INFILE) {
1781 			RETURN_FALSE;
1782 		}
1783 	}
1784 #endif
1785 	expected_type = mysqli_options_get_option_zval_type(mysql_option);
1786 	if (expected_type != Z_TYPE_P(mysql_value)) {
1787 		switch (expected_type) {
1788 			case IS_STRING:
1789 				convert_to_string_ex(mysql_value);
1790 				break;
1791 			case IS_LONG:
1792 				convert_to_long_ex(mysql_value);
1793 				break;
1794 			default:
1795 				break;
1796 		}
1797 	}
1798 	switch (expected_type) {
1799 		case IS_STRING:
1800 			ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_P(mysql_value));
1801 			break;
1802 		case IS_LONG:
1803 			l_value = Z_LVAL_P(mysql_value);
1804 			ret = mysql_options(mysql->mysql, mysql_option, (char *)&l_value);
1805 			break;
1806 		default:
1807 			ret = 1;
1808 			break;
1809 	}
1810 
1811 	RETURN_BOOL(!ret);
1812 }
1813 /* }}} */
1814 
1815 /* {{{ proto bool mysqli_ping(object link)
1816    Ping a server connection or reconnect if there is no connection */
1817 PHP_FUNCTION(mysqli_ping)
1818 {
1819 	MY_MYSQL	*mysql;
1820 	zval		*mysql_link;
1821 	zend_long		rc;
1822 
1823 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1824 		return;
1825 	}
1826 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1827 	rc = mysql_ping(mysql->mysql);
1828 	MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1829 
1830 	RETURN_BOOL(!rc);
1831 }
1832 /* }}} */
1833 
1834 /* {{{ proto mixed mysqli_prepare(object link, string query)
1835    Prepare a SQL statement for execution */
1836 PHP_FUNCTION(mysqli_prepare)
1837 {
1838 	MY_MYSQL		*mysql;
1839 	MY_STMT			*stmt;
1840 	char			*query = NULL;
1841 	size_t				query_len;
1842 	zval			*mysql_link;
1843 	MYSQLI_RESOURCE	*mysqli_resource;
1844 
1845 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
1846 		return;
1847 	}
1848 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1849 
1850 #if !defined(MYSQLI_USE_MYSQLND)
1851 	if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) {
1852 		php_error_docref(NULL, E_WARNING, "All data must be fetched before a new statement prepare takes place");
1853 		RETURN_FALSE;
1854 	}
1855 #endif
1856 
1857 	stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
1858 
1859 	if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
1860 		if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
1861 			/* mysql_stmt_close() clears errors, so we have to store them temporarily */
1862 #if !defined(MYSQLI_USE_MYSQLND)
1863 			char  last_error[MYSQL_ERRMSG_SIZE];
1864 			char  sqlstate[SQLSTATE_LENGTH+1];
1865 			unsigned int last_errno;
1866 
1867 			last_errno = stmt->stmt->last_errno;
1868 			memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);
1869 			memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1);
1870 #else
1871 			MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
1872 			mysql->mysql->data->error_info->error_list.head = NULL;
1873 			mysql->mysql->data->error_info->error_list.tail = NULL;
1874 			mysql->mysql->data->error_info->error_list.count = 0;
1875 #endif
1876 			mysqli_stmt_close(stmt->stmt, FALSE);
1877 			stmt->stmt = NULL;
1878 
1879 			/* restore error messages */
1880 #if !defined(MYSQLI_USE_MYSQLND)
1881 			mysql->mysql->net.last_errno = last_errno;
1882 			memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);
1883 			memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1);
1884 #else
1885 			zend_llist_clean(&mysql->mysql->data->error_info->error_list);
1886 			*mysql->mysql->data->error_info = error_info;
1887 #endif
1888 		}
1889 	}
1890 
1891 	/* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
1892 	/* Get performance boost if reporting is switched off */
1893 	if (stmt->stmt && query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
1894 		stmt->query = (char *)emalloc(query_len + 1);
1895 		memcpy(stmt->query, query, query_len);
1896 		stmt->query[query_len] = '\0';
1897 	}
1898 
1899 	/* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */
1900 	if (!stmt->stmt) {
1901 		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1902 		efree(stmt);
1903 		RETURN_FALSE;
1904 	}
1905 #ifndef MYSQLI_USE_MYSQLND
1906 	ZVAL_COPY(&stmt->link_handle, mysql_link);
1907 #endif
1908 
1909 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1910 	mysqli_resource->ptr = (void *)stmt;
1911 
1912 	/* change status */
1913 	mysqli_resource->status = MYSQLI_STATUS_VALID;
1914 	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
1915 }
1916 /* }}} */
1917 
1918 /* {{{ proto bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])
1919    Open a connection to a mysql server */
1920 PHP_FUNCTION(mysqli_real_connect)
1921 {
1922 	mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE, FALSE);
1923 }
1924 /* }}} */
1925 
1926 /* {{{ proto bool mysqli_real_query(object link, string query)
1927    Binary-safe version of mysql_query() */
1928 PHP_FUNCTION(mysqli_real_query)
1929 {
1930 	MY_MYSQL	*mysql;
1931 	zval		*mysql_link;
1932 	char		*query = NULL;
1933 	size_t		query_len;
1934 
1935 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
1936 		return;
1937 	}
1938 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1939 
1940 	MYSQLI_DISABLE_MQ; /* disable multi statements/queries */
1941 
1942 	if (mysql_real_query(mysql->mysql, query, query_len)) {
1943 		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1944 		RETURN_FALSE;
1945 	}
1946 
1947 	if (!mysql_field_count(mysql->mysql)) {
1948 		if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
1949 			php_mysqli_report_index(query, mysqli_server_status(mysql->mysql));
1950 		}
1951 	}
1952 
1953 	RETURN_TRUE;
1954 }
1955 /* }}} */
1956 
1957 #if defined(MYSQLI_USE_MYSQLND) || MYSQL_VERSION_ID < 50707 || defined(MARIADB_BASE_VERSION)
1958 # define mysql_real_escape_string_quote(mysql, to, from, length, quote) \
1959 	mysql_real_escape_string(mysql, to, from, length)
1960 #endif
1961 
1962 /* {{{ proto string mysqli_real_escape_string(object link, string escapestr)
1963    Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
1964 PHP_FUNCTION(mysqli_real_escape_string) {
1965 	MY_MYSQL	*mysql;
1966 	zval		*mysql_link = NULL;
1967 	char		*escapestr;
1968 	size_t			escapestr_len;
1969 	zend_string *newstr;
1970 
1971 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) {
1972 		return;
1973 	}
1974 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1975 
1976 	newstr = zend_string_alloc(2 * escapestr_len, 0);
1977 	ZSTR_LEN(newstr) = mysql_real_escape_string_quote(mysql->mysql, ZSTR_VAL(newstr), escapestr, escapestr_len, '\'');
1978 	newstr = zend_string_truncate(newstr, ZSTR_LEN(newstr), 0);
1979 
1980 	RETURN_NEW_STR(newstr);
1981 }
1982 /* }}} */
1983 
1984 /* {{{ proto bool mysqli_rollback(object link)
1985    Undo actions from current transaction */
1986 PHP_FUNCTION(mysqli_rollback)
1987 {
1988 	MY_MYSQL	*mysql;
1989 	zval		*mysql_link;
1990 	zend_long		flags = TRANS_COR_NO_OPT;
1991 	char *		name = NULL;
1992 	size_t			name_len = 0;
1993 
1994 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
1995 		return;
1996 	}
1997 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1998 
1999 #if !defined(MYSQLI_USE_MYSQLND)
2000 	if (mysqli_commit_or_rollback_libmysql(mysql->mysql, FALSE, flags, name)) {
2001 #else
2002 	if (FAIL == mysqlnd_rollback(mysql->mysql, flags, name)) {
2003 #endif
2004 		RETURN_FALSE;
2005 	}
2006 	RETURN_TRUE;
2007 }
2008 /* }}} */
2009 
2010 /* {{{ proto bool mysqli_stmt_send_long_data(object stmt, int param_nr, string data)
2011 */
2012 PHP_FUNCTION(mysqli_stmt_send_long_data)
2013 {
2014 	MY_STMT *stmt;
2015 	zval	*mysql_stmt;
2016 	char	*data;
2017 	zend_long	param_nr;
2018 	size_t		data_len;
2019 
2020 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, &param_nr, &data, &data_len) == FAILURE) {
2021 		return;
2022 	}
2023 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2024 
2025 	if (param_nr < 0) {
2026 		php_error_docref(NULL, E_WARNING, "Invalid parameter number");
2027 		RETURN_FALSE;
2028 	}
2029 	if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) {
2030 		RETURN_FALSE;
2031 	}
2032 	RETURN_TRUE;
2033 }
2034 /* }}} */
2035 
2036 /* {{{ proto string|int|false mysqli_stmt_affected_rows(object stmt)
2037    Return the number of rows affected in the last query for the given link. */
2038 PHP_FUNCTION(mysqli_stmt_affected_rows)
2039 {
2040 	MY_STMT			*stmt;
2041 	zval			*mysql_stmt;
2042 	my_ulonglong	rc;
2043 
2044 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2045 		return;
2046 	}
2047 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2048 
2049 	rc = mysql_stmt_affected_rows(stmt->stmt);
2050 	if (rc == (my_ulonglong) -1) {
2051 		RETURN_LONG(-1);
2052 	}
2053 	MYSQLI_RETURN_LONG_INT(rc)
2054 }
2055 /* }}} */
2056 
2057 /* {{{ proto bool mysqli_stmt_close(object stmt)
2058    Close statement */
2059 PHP_FUNCTION(mysqli_stmt_close)
2060 {
2061 	MY_STMT		*stmt;
2062 	zval		*mysql_stmt;
2063 
2064 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2065 		return;
2066 	}
2067 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2068 
2069 	mysqli_stmt_close(stmt->stmt, FALSE);
2070 	stmt->stmt = NULL;
2071 	php_clear_stmt_bind(stmt);
2072 	MYSQLI_CLEAR_RESOURCE(mysql_stmt);
2073 	RETURN_TRUE;
2074 }
2075 /* }}} */
2076 
2077 /* {{{ proto void mysqli_stmt_data_seek(object stmt, int offset)
2078    Move internal result pointer */
2079 PHP_FUNCTION(mysqli_stmt_data_seek)
2080 {
2081 	MY_STMT		*stmt;
2082 	zval		*mysql_stmt;
2083 	zend_long		offset;
2084 
2085 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) {
2086 		return;
2087 	}
2088 	if (offset < 0) {
2089 		php_error_docref(NULL, E_WARNING, "Offset must be positive");
2090 		RETURN_FALSE;
2091 	}
2092 
2093 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2094 
2095 	mysql_stmt_data_seek(stmt->stmt, offset);
2096 }
2097 /* }}} */
2098 
2099 /* {{{ proto int mysqli_stmt_field_count(object stmt) {
2100    Return the number of result columns for the given statement */
2101 PHP_FUNCTION(mysqli_stmt_field_count)
2102 {
2103 	MY_STMT		*stmt;
2104 	zval		*mysql_stmt;
2105 
2106 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2107 		return;
2108 	}
2109 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2110 
2111 	RETURN_LONG(mysql_stmt_field_count(stmt->stmt));
2112 }
2113 /* }}} */
2114 
2115 /* {{{ proto void mysqli_stmt_free_result(object stmt)
2116    Free stored result memory for the given statement handle */
2117 PHP_FUNCTION(mysqli_stmt_free_result)
2118 {
2119 	MY_STMT		*stmt;
2120 	zval		*mysql_stmt;
2121 
2122 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2123 		return;
2124 	}
2125 
2126 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2127 
2128 	mysql_stmt_free_result(stmt->stmt);
2129 }
2130 /* }}} */
2131 
2132 /* {{{ proto mixed mysqli_stmt_insert_id(object stmt)
2133    Get the ID generated from the previous INSERT operation */
2134 PHP_FUNCTION(mysqli_stmt_insert_id)
2135 {
2136 	MY_STMT			*stmt;
2137 	my_ulonglong	rc;
2138 	zval			*mysql_stmt;
2139 
2140 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2141 		return;
2142 	}
2143 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2144 	rc = mysql_stmt_insert_id(stmt->stmt);
2145 	MYSQLI_RETURN_LONG_INT(rc)
2146 }
2147 /* }}} */
2148 
2149 /* {{{ proto int mysqli_stmt_param_count(object stmt)
2150    Return the number of parameter for the given statement */
2151 PHP_FUNCTION(mysqli_stmt_param_count)
2152 {
2153 	MY_STMT		*stmt;
2154 	zval		*mysql_stmt;
2155 
2156 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2157 		return;
2158 	}
2159 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2160 
2161 	RETURN_LONG(mysql_stmt_param_count(stmt->stmt));
2162 }
2163 /* }}} */
2164 
2165 /* {{{ proto bool mysqli_stmt_reset(object stmt)
2166    reset a prepared statement */
2167 PHP_FUNCTION(mysqli_stmt_reset)
2168 {
2169 	MY_STMT		*stmt;
2170 	zval		*mysql_stmt;
2171 
2172 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2173 		return;
2174 	}
2175 
2176 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2177 
2178 	if (mysql_stmt_reset(stmt->stmt)) {
2179 		RETURN_FALSE;
2180 	}
2181 	RETURN_TRUE;
2182 }
2183 /* }}} */
2184 
2185 /* {{{ proto mixed mysqli_stmt_num_rows(object stmt)
2186    Return the number of rows in statements result set */
2187 PHP_FUNCTION(mysqli_stmt_num_rows)
2188 {
2189 	MY_STMT			*stmt;
2190 	zval			*mysql_stmt;
2191 	my_ulonglong	rc;
2192 
2193 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2194 		return;
2195 	}
2196 
2197 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2198 
2199 	rc = mysql_stmt_num_rows(stmt->stmt);
2200 	MYSQLI_RETURN_LONG_INT(rc)
2201 }
2202 /* }}} */
2203 
2204 /* {{{ proto bool mysqli_select_db(object link, string dbname)
2205    Select a MySQL database */
2206 PHP_FUNCTION(mysqli_select_db)
2207 {
2208 	MY_MYSQL	*mysql;
2209 	zval		*mysql_link;
2210 	char		*dbname;
2211 	size_t			dbname_len;
2212 
2213 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) {
2214 		return;
2215 	}
2216 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2217 
2218 	if (mysql_select_db(mysql->mysql, dbname)) {
2219 		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
2220 		RETURN_FALSE;
2221 	}
2222 	RETURN_TRUE;
2223 }
2224 /* }}} */
2225 
2226 /* {{{ proto string mysqli_sqlstate(object link)
2227    Returns the SQLSTATE error from previous MySQL operation */
2228 PHP_FUNCTION(mysqli_sqlstate)
2229 {
2230 	MY_MYSQL	*mysql;
2231 	zval		*mysql_link;
2232 	const char	*state;
2233 
2234 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2235 		return;
2236 	}
2237 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2238 	state = mysql_sqlstate(mysql->mysql);
2239 	if (state) {
2240 		RETURN_STRING(state);
2241 	}
2242 }
2243 /* }}} */
2244 
2245 /* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher])
2246 */
2247 PHP_FUNCTION(mysqli_ssl_set)
2248 {
2249 	MY_MYSQL	*mysql;
2250 	zval		*mysql_link;
2251 	char		*ssl_parm[5];
2252 	size_t			ssl_parm_len[5], i;
2253 
2254 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Osssss", &mysql_link, mysqli_link_class_entry, &ssl_parm[0], &ssl_parm_len[0], &ssl_parm[1], &ssl_parm_len[1], &ssl_parm[2], &ssl_parm_len[2], &ssl_parm[3], &ssl_parm_len[3], &ssl_parm[4], &ssl_parm_len[4])   == FAILURE) {
2255 		return;
2256 	}
2257 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
2258 
2259 	for (i = 0; i < 5; i++) {
2260 		if (!ssl_parm_len[i]) {
2261 			ssl_parm[i] = NULL;
2262 		}
2263 	}
2264 
2265 	mysql_ssl_set(mysql->mysql, ssl_parm[0], ssl_parm[1], ssl_parm[2], ssl_parm[3], ssl_parm[4]);
2266 
2267 	RETURN_TRUE;
2268 }
2269 /* }}} */
2270 
2271 /* {{{ proto mixed mysqli_stat(object link)
2272    Get current system status */
2273 PHP_FUNCTION(mysqli_stat)
2274 {
2275 	MY_MYSQL	*mysql;
2276 	zval		*mysql_link;
2277 #if defined(MYSQLI_USE_MYSQLND)
2278 	zend_string *stat;
2279 #else
2280 	char		*stat;
2281 #endif
2282 
2283 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2284 		return;
2285 	}
2286 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2287 
2288 #if !defined(MYSQLI_USE_MYSQLND)
2289 	if ((stat = (char *)mysql_stat(mysql->mysql)))
2290 	{
2291 		RETURN_STRING(stat);
2292 #else
2293 	if (mysqlnd_stat(mysql->mysql, &stat) == PASS)
2294 	{
2295 		RETURN_STR(stat);
2296 #endif
2297 	} else {
2298 		RETURN_FALSE;
2299 	}
2300 }
2301 
2302 /* }}} */
2303 
2304 /* {{{ proto bool mysqli_refresh(object link, int options)
2305    Flush tables or caches, or reset replication server information */
2306 PHP_FUNCTION(mysqli_refresh)
2307 {
2308 	MY_MYSQL *mysql;
2309 	zval *mysql_link = NULL;
2310 	zend_long options;
2311 
2312 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &options) == FAILURE) {
2313 		return;
2314 	}
2315 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
2316 #ifdef MYSQLI_USE_MYSQLND
2317 	RETURN_BOOL(!mysql_refresh(mysql->mysql, (uint8_t) options));
2318 #else
2319 	RETURN_BOOL(!mysql_refresh(mysql->mysql, options));
2320 #endif
2321 }
2322 /* }}} */
2323 
2324 /* {{{ proto int mysqli_stmt_attr_set(object stmt, int attr, int mode)
2325 */
2326 PHP_FUNCTION(mysqli_stmt_attr_set)
2327 {
2328 	MY_STMT	*stmt;
2329 	zval	*mysql_stmt;
2330 	zend_long	mode_in;
2331 #if MYSQL_VERSION_ID >= 50107
2332 	my_bool	mode_b;
2333 #endif
2334 	unsigned long	mode;
2335 	zend_long	attr;
2336 	void	*mode_p;
2337 
2338 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) {
2339 		return;
2340 	}
2341 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2342 
2343 	if (mode_in < 0) {
2344 		php_error_docref(NULL, E_WARNING, "mode should be non-negative, " ZEND_LONG_FMT " passed", mode_in);
2345 		RETURN_FALSE;
2346 	}
2347 
2348 	switch (attr) {
2349 #if MYSQL_VERSION_ID >= 50107
2350 	case STMT_ATTR_UPDATE_MAX_LENGTH:
2351 		mode_b = (my_bool) mode_in;
2352 		mode_p = &mode_b;
2353 		break;
2354 #endif
2355 	default:
2356 		mode = mode_in;
2357 		mode_p = &mode;
2358 		break;
2359 	}
2360 #if !defined(MYSQLI_USE_MYSQLND)
2361 	if (mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
2362 #else
2363 	if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
2364 #endif
2365 		RETURN_FALSE;
2366 	}
2367 	RETURN_TRUE;
2368 }
2369 /* }}} */
2370 
2371 /* {{{ proto int mysqli_stmt_attr_get(object stmt, int attr)
2372 */
2373 PHP_FUNCTION(mysqli_stmt_attr_get)
2374 {
2375 	MY_STMT	*stmt;
2376 	zval	*mysql_stmt;
2377 	unsigned long	value = 0;
2378 	zend_long	attr;
2379 	int		rc;
2380 
2381 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &attr) == FAILURE) {
2382 		return;
2383 	}
2384 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2385 
2386 	if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) {
2387 		RETURN_FALSE;
2388 	}
2389 
2390 #if MYSQL_VERSION_ID >= 50107
2391 	if (attr == STMT_ATTR_UPDATE_MAX_LENGTH)
2392 		value = *((my_bool *)&value);
2393 #endif
2394 	RETURN_LONG((unsigned long)value);
2395 }
2396 /* }}} */
2397 
2398 /* {{{ proto int mysqli_stmt_errno(object stmt)
2399 */
2400 PHP_FUNCTION(mysqli_stmt_errno)
2401 {
2402 	MY_STMT	*stmt;
2403 	zval	*mysql_stmt;
2404 
2405 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2406 		return;
2407 	}
2408 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
2409 
2410 	RETURN_LONG(mysql_stmt_errno(stmt->stmt));
2411 }
2412 /* }}} */
2413 
2414 /* {{{ proto string mysqli_stmt_error(object stmt)
2415 */
2416 PHP_FUNCTION(mysqli_stmt_error)
2417 {
2418 	MY_STMT	*stmt;
2419 	zval 	*mysql_stmt;
2420 	const char * err;
2421 
2422 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2423 		return;
2424 	}
2425 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
2426 
2427 	err = mysql_stmt_error(stmt->stmt);
2428 	if (err) {
2429 		RETURN_STRING(err);
2430 	}
2431 }
2432 /* }}} */
2433 
2434 /* {{{ proto mixed mysqli_stmt_init(object link)
2435    Initialize statement object
2436 */
2437 PHP_FUNCTION(mysqli_stmt_init)
2438 {
2439 	MY_MYSQL		*mysql;
2440 	MY_STMT			*stmt;
2441 	zval			*mysql_link;
2442 	MYSQLI_RESOURCE	*mysqli_resource;
2443 
2444 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",&mysql_link, mysqli_link_class_entry) == FAILURE) {
2445 		return;
2446 	}
2447 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2448 
2449 	stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
2450 
2451 	if (!(stmt->stmt = mysql_stmt_init(mysql->mysql))) {
2452 		efree(stmt);
2453 		RETURN_FALSE;
2454 	}
2455 #ifndef MYSQLI_USE_MYSQLND
2456 	ZVAL_COPY(&stmt->link_handle, mysql_link);
2457 #endif
2458 
2459 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
2460 	mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
2461 	mysqli_resource->ptr = (void *)stmt;
2462 	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
2463 }
2464 /* }}} */
2465 
2466 /* {{{ proto bool mysqli_stmt_prepare(object stmt, string query)
2467    prepare server side statement with query
2468 */
2469 PHP_FUNCTION(mysqli_stmt_prepare)
2470 {
2471 	MY_STMT	*stmt;
2472 	zval 	*mysql_stmt;
2473 	char	*query;
2474 	size_t		query_len;
2475 
2476 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &query, &query_len) == FAILURE) {
2477 		return;
2478 	}
2479 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
2480 
2481 	if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
2482 		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
2483 		RETURN_FALSE;
2484 	}
2485 	/* change status */
2486 	MYSQLI_SET_STATUS(mysql_stmt, MYSQLI_STATUS_VALID);
2487 	RETURN_TRUE;
2488 }
2489 /* }}} */
2490 
2491 /* {{{ proto mixed mysqli_stmt_result_metadata(object stmt)
2492    return result set from statement */
2493 PHP_FUNCTION(mysqli_stmt_result_metadata)
2494 {
2495 	MY_STMT			*stmt;
2496 	MYSQL_RES		*result;
2497 	zval			*mysql_stmt;
2498 	MYSQLI_RESOURCE	*mysqli_resource;
2499 
2500 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2501 		return;
2502 	}
2503 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2504 
2505 	if (!(result = mysql_stmt_result_metadata(stmt->stmt))){
2506 		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
2507 		RETURN_FALSE;
2508 	}
2509 
2510 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
2511 	mysqli_resource->ptr = (void *)result;
2512 	mysqli_resource->status = MYSQLI_STATUS_VALID;
2513 	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
2514 }
2515 /* }}} */
2516 
2517 /* {{{ proto bool mysqli_stmt_store_result(object stmt)
2518 */
2519 PHP_FUNCTION(mysqli_stmt_store_result)
2520 {
2521 	MY_STMT	*stmt;
2522 	zval	*mysql_stmt;
2523 
2524 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2525 		return;
2526 	}
2527 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2528 
2529 #if !defined(MYSQLI_USE_MYSQLND)
2530 	{
2531 		/*
2532 		  If the user wants to store the data and we have BLOBs/TEXTs we try to allocate
2533 		  not the maximal length of the type (which is 16MB even for LONGBLOB) but
2534 		  the maximal length of the field in the result set. If he/she has quite big
2535 		  BLOB/TEXT columns after calling store_result() the memory usage of PHP will
2536 		  double - but this is a known problem of the simple MySQL API ;)
2537 		*/
2538 		int	i = 0;
2539 
2540 		for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
2541 			if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB ||
2542 				stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB ||
2543 				stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB ||
2544 				stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY))
2545 			{
2546 #if MYSQL_VERSION_ID >= 50107
2547 				my_bool	tmp=1;
2548 #else
2549 				uint32_t tmp=1;
2550 #endif
2551 				mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
2552 				break;
2553 			}
2554 		}
2555 	}
2556 #endif
2557 
2558 	if (mysql_stmt_store_result(stmt->stmt)){
2559 		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
2560 		RETURN_FALSE;
2561 	}
2562 	RETURN_TRUE;
2563 }
2564 /* }}} */
2565 
2566 /* {{{ proto string mysqli_stmt_sqlstate(object stmt)
2567 */
2568 PHP_FUNCTION(mysqli_stmt_sqlstate)
2569 {
2570 	MY_STMT	*stmt;
2571 	zval	*mysql_stmt;
2572 	const char * state;
2573 
2574 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2575 		return;
2576 	}
2577 	MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
2578 
2579 	state = mysql_stmt_sqlstate(stmt->stmt);
2580 	if (state) {
2581 		RETURN_STRING(state);
2582 	}
2583 }
2584 /* }}} */
2585 
2586 /* {{{ proto object mysqli_store_result(object link [, int flags])
2587    Buffer result set on client */
2588 PHP_FUNCTION(mysqli_store_result)
2589 {
2590 	MY_MYSQL		*mysql;
2591 	MYSQL_RES		*result;
2592 	zval			*mysql_link;
2593 	MYSQLI_RESOURCE	*mysqli_resource;
2594 	zend_long flags = 0;
2595 
2596 
2597 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_link, mysqli_link_class_entry, &flags) == FAILURE) {
2598 		return;
2599 	}
2600 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2601 #if MYSQLI_USE_MYSQLND
2602 	result = flags & MYSQLI_STORE_RESULT_COPY_DATA? mysqlnd_store_result_ofs(mysql->mysql) : mysqlnd_store_result(mysql->mysql);
2603 #else
2604 	result = mysql_store_result(mysql->mysql);
2605 #endif
2606 	if (!result) {
2607 		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
2608 		RETURN_FALSE;
2609 	}
2610 	if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
2611 		php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql));
2612 	}
2613 
2614 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
2615 	mysqli_resource->ptr = (void *)result;
2616 	mysqli_resource->status = MYSQLI_STATUS_VALID;
2617 	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
2618 }
2619 /* }}} */
2620 
2621 /* {{{ proto int mysqli_thread_id(object link)
2622    Return the current thread ID */
2623 PHP_FUNCTION(mysqli_thread_id)
2624 {
2625 	MY_MYSQL	*mysql;
2626 	zval		*mysql_link;
2627 
2628 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2629 		return;
2630 	}
2631 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2632 
2633 	RETURN_LONG((zend_long) mysql_thread_id(mysql->mysql));
2634 }
2635 /* }}} */
2636 
2637 /* {{{ proto bool mysqli_thread_safe(void)
2638    Return whether thread safety is given or not */
2639 PHP_FUNCTION(mysqli_thread_safe)
2640 {
2641 	RETURN_BOOL(mysql_thread_safe());
2642 }
2643 /* }}} */
2644 
2645 /* {{{ proto mixed mysqli_use_result(object link)
2646    Directly retrieve query results - do not buffer results on client side */
2647 PHP_FUNCTION(mysqli_use_result)
2648 {
2649 	MY_MYSQL		*mysql;
2650 	MYSQL_RES		*result;
2651 	zval			*mysql_link;
2652 	MYSQLI_RESOURCE	*mysqli_resource;
2653 
2654 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2655 		return;
2656 	}
2657 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2658 
2659 	if (!(result = mysql_use_result(mysql->mysql))) {
2660 		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
2661 		RETURN_FALSE;
2662 	}
2663 
2664 	if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
2665 		php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql));
2666 	}
2667 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
2668 	mysqli_resource->ptr = (void *)result;
2669 	mysqli_resource->status = MYSQLI_STATUS_VALID;
2670 	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
2671 }
2672 /* }}} */
2673 
2674 /* {{{ proto int mysqli_warning_count(object link)
2675    Return number of warnings from the last query for the given link */
2676 PHP_FUNCTION(mysqli_warning_count)
2677 {
2678 	MY_MYSQL	*mysql;
2679 	zval		*mysql_link;
2680 
2681 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2682 		return;
2683 	}
2684 	MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2685 
2686 	RETURN_LONG(mysql_warning_count(mysql->mysql));
2687 }
2688 /* }}} */
2689 
2690 /*
2691  * Local variables:
2692  * tab-width: 4
2693  * c-basic-offset: 4
2694  * End:
2695  * vim600: noet sw=4 ts=4 fdm=marker
2696  * vim<600: noet sw=4 ts=4
2697  */
2698