xref: /PHP-7.4/ext/pdo_sqlite/sqlite_statement.c (revision e6160e99)
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: Wez Furlong <wez@php.net>                                    |
16   +----------------------------------------------------------------------+
17 */
18 
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include "php.h"
24 #include "php_ini.h"
25 #include "ext/standard/info.h"
26 #include "pdo/php_pdo.h"
27 #include "pdo/php_pdo_driver.h"
28 #include "php_pdo_sqlite.h"
29 #include "php_pdo_sqlite_int.h"
30 
31 
pdo_sqlite_stmt_dtor(pdo_stmt_t * stmt)32 static int pdo_sqlite_stmt_dtor(pdo_stmt_t *stmt)
33 {
34 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
35 
36 	if (S->stmt) {
37 		sqlite3_finalize(S->stmt);
38 		S->stmt = NULL;
39 	}
40 	efree(S);
41 	return 1;
42 }
43 
44 /**
45  * Change the column count on the statement.
46  *
47  * Since PHP 7.2 sqlite3_prepare_v2 is used which auto recompile prepared statement on schema change.
48  * Instead of raise an error on schema change, the result set will change, and the statement's columns must be updated.
49  *
50  * See bug #78192
51  */
pdo_sqlite_stmt_set_column_count(pdo_stmt_t * stmt,int new_count)52 static void pdo_sqlite_stmt_set_column_count(pdo_stmt_t *stmt, int new_count)
53 {
54 	/* Columns not yet "described" */
55 	if (!stmt->columns) {
56 		stmt->column_count = new_count;
57 
58 		return;
59 	}
60 
61 	/*
62 	 * The column count has not changed : no need to reload columns description
63 	 * Note: Do not handle attribute name change, without column count change
64 	 */
65 	if (new_count == stmt->column_count) {
66 		return;
67 	}
68 
69 	/* Free previous columns to force reload description */
70 	int i;
71 
72 	for (i = 0; i < stmt->column_count; i++) {
73 		if (stmt->columns[i].name) {
74 			zend_string_release(stmt->columns[i].name);
75 			stmt->columns[i].name = NULL;
76 		}
77 	}
78 
79 	efree(stmt->columns);
80 	stmt->columns = NULL;
81 	stmt->column_count = new_count;
82 }
83 
pdo_sqlite_stmt_execute(pdo_stmt_t * stmt)84 static int pdo_sqlite_stmt_execute(pdo_stmt_t *stmt)
85 {
86 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
87 
88 	if (stmt->executed && !S->done) {
89 		sqlite3_reset(S->stmt);
90 	}
91 
92 	S->done = 0;
93 	switch (sqlite3_step(S->stmt)) {
94 		case SQLITE_ROW:
95 			S->pre_fetched = 1;
96 			pdo_sqlite_stmt_set_column_count(stmt, sqlite3_data_count(S->stmt));
97 			return 1;
98 
99 		case SQLITE_DONE:
100 			pdo_sqlite_stmt_set_column_count(stmt, sqlite3_column_count(S->stmt));
101 			stmt->row_count = sqlite3_changes(S->H->db);
102 			sqlite3_reset(S->stmt);
103 			S->done = 1;
104 			return 1;
105 
106 		case SQLITE_ERROR:
107 			sqlite3_reset(S->stmt);
108 		case SQLITE_MISUSE:
109 		case SQLITE_BUSY:
110 		default:
111 			pdo_sqlite_error_stmt(stmt);
112 			return 0;
113 	}
114 }
115 
pdo_sqlite_stmt_param_hook(pdo_stmt_t * stmt,struct pdo_bound_param_data * param,enum pdo_param_event event_type)116 static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
117 		enum pdo_param_event event_type)
118 {
119 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
120 	zval *parameter;
121 
122 	switch (event_type) {
123 		case PDO_PARAM_EVT_EXEC_PRE:
124 			if (stmt->executed && !S->done) {
125 				sqlite3_reset(S->stmt);
126 				S->done = 1;
127 			}
128 
129 			if (param->is_param) {
130 
131 				if (param->paramno == -1) {
132 					param->paramno = sqlite3_bind_parameter_index(S->stmt, ZSTR_VAL(param->name)) - 1;
133 				}
134 
135 				switch (PDO_PARAM_TYPE(param->param_type)) {
136 					case PDO_PARAM_STMT:
137 						return 0;
138 
139 					case PDO_PARAM_NULL:
140 						if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
141 							return 1;
142 						}
143 						pdo_sqlite_error_stmt(stmt);
144 						return 0;
145 
146 					case PDO_PARAM_INT:
147 					case PDO_PARAM_BOOL:
148 						if (Z_ISREF(param->parameter)) {
149 							parameter = Z_REFVAL(param->parameter);
150 						} else {
151 							parameter = &param->parameter;
152 						}
153 						if (Z_TYPE_P(parameter) == IS_NULL) {
154 							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
155 								return 1;
156 							}
157 						} else {
158 							convert_to_long(parameter);
159 #if ZEND_LONG_MAX > 2147483647
160 							if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
161 								return 1;
162 							}
163 #else
164 							if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
165 								return 1;
166 							}
167 #endif
168 						}
169 						pdo_sqlite_error_stmt(stmt);
170 						return 0;
171 
172 					case PDO_PARAM_LOB:
173 						if (Z_ISREF(param->parameter)) {
174 							parameter = Z_REFVAL(param->parameter);
175 						} else {
176 							parameter = &param->parameter;
177 						}
178 						if (Z_TYPE_P(parameter) == IS_RESOURCE) {
179 							php_stream *stm = NULL;
180 							php_stream_from_zval_no_verify(stm, parameter);
181 							if (stm) {
182 								zend_string *mem = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
183 								zval_ptr_dtor(parameter);
184 								ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
185 							} else {
186 								pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
187 								return 0;
188 							}
189 						} else if (Z_TYPE_P(parameter) == IS_NULL) {
190 							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
191 								return 1;
192 							}
193 							pdo_sqlite_error_stmt(stmt);
194 							return 0;
195 						} else {
196 							if (!try_convert_to_string(parameter)) {
197 								return 0;
198 							}
199 						}
200 
201 						if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
202 								Z_STRVAL_P(parameter),
203 								Z_STRLEN_P(parameter),
204 								SQLITE_STATIC)) {
205 							return 1;
206 						}
207 						return 0;
208 
209 					case PDO_PARAM_STR:
210 					default:
211 						if (Z_ISREF(param->parameter)) {
212 							parameter = Z_REFVAL(param->parameter);
213 						} else {
214 							parameter = &param->parameter;
215 						}
216 						if (Z_TYPE_P(parameter) == IS_NULL) {
217 							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
218 								return 1;
219 							}
220 						} else {
221 							if (!try_convert_to_string(parameter)) {
222 								return 0;
223 							}
224 							if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
225 									Z_STRVAL_P(parameter),
226 									Z_STRLEN_P(parameter),
227 									SQLITE_STATIC)) {
228 								return 1;
229 							}
230 						}
231 						pdo_sqlite_error_stmt(stmt);
232 						return 0;
233 				}
234 			}
235 			break;
236 
237 		default:
238 			;
239 	}
240 	return 1;
241 }
242 
pdo_sqlite_stmt_fetch(pdo_stmt_t * stmt,enum pdo_fetch_orientation ori,zend_long offset)243 static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
244 	enum pdo_fetch_orientation ori, zend_long offset)
245 {
246 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
247 	int i;
248 	if (!S->stmt) {
249 		return 0;
250 	}
251 	if (S->pre_fetched) {
252 		S->pre_fetched = 0;
253 		return 1;
254 	}
255 	if (S->done) {
256 		return 0;
257 	}
258 	i = sqlite3_step(S->stmt);
259 	switch (i) {
260 		case SQLITE_ROW:
261 			return 1;
262 
263 		case SQLITE_DONE:
264 			S->done = 1;
265 			sqlite3_reset(S->stmt);
266 			return 0;
267 
268 		case SQLITE_ERROR:
269 			sqlite3_reset(S->stmt);
270 		default:
271 			pdo_sqlite_error_stmt(stmt);
272 			return 0;
273 	}
274 }
275 
pdo_sqlite_stmt_describe(pdo_stmt_t * stmt,int colno)276 static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno)
277 {
278 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
279 	const char *str;
280 
281 	if(colno >= sqlite3_column_count(S->stmt)) {
282 		/* error invalid column */
283 		pdo_sqlite_error_stmt(stmt);
284 		return 0;
285 	}
286 
287 	str = sqlite3_column_name(S->stmt, colno);
288 	stmt->columns[colno].name = zend_string_init(str, strlen(str), 0);
289 	stmt->columns[colno].maxlen = SIZE_MAX;
290 	stmt->columns[colno].precision = 0;
291 
292 	switch (sqlite3_column_type(S->stmt, colno)) {
293 		case SQLITE_INTEGER:
294 		case SQLITE_FLOAT:
295 		case SQLITE3_TEXT:
296 		case SQLITE_BLOB:
297 		case SQLITE_NULL:
298 		default:
299 			stmt->columns[colno].param_type = PDO_PARAM_STR;
300 			break;
301 	}
302 
303 	return 1;
304 }
305 
pdo_sqlite_stmt_get_col(pdo_stmt_t * stmt,int colno,char ** ptr,size_t * len,int * caller_frees)306 static int pdo_sqlite_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_t *len, int *caller_frees)
307 {
308 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
309 	if (!S->stmt) {
310 		return 0;
311 	}
312 	if(colno >= sqlite3_data_count(S->stmt)) {
313 		/* error invalid column */
314 		pdo_sqlite_error_stmt(stmt);
315 		return 0;
316 	}
317 	switch (sqlite3_column_type(S->stmt, colno)) {
318 		case SQLITE_NULL:
319 			*ptr = NULL;
320 			*len = 0;
321 			return 1;
322 
323 		case SQLITE_BLOB:
324 			*ptr = (char*)sqlite3_column_blob(S->stmt, colno);
325 			*len = sqlite3_column_bytes(S->stmt, colno);
326 			return 1;
327 
328 		default:
329 			*ptr = (char*)sqlite3_column_text(S->stmt, colno);
330 			*len = sqlite3_column_bytes(S->stmt, colno);
331 			return 1;
332 	}
333 }
334 
pdo_sqlite_stmt_col_meta(pdo_stmt_t * stmt,zend_long colno,zval * return_value)335 static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
336 {
337 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
338 	const char *str;
339 	zval flags;
340 
341 	if (!S->stmt) {
342 		return FAILURE;
343 	}
344 	if(colno >= sqlite3_column_count(S->stmt)) {
345 		/* error invalid column */
346 		pdo_sqlite_error_stmt(stmt);
347 		return FAILURE;
348 	}
349 
350 	array_init(return_value);
351 	array_init(&flags);
352 
353 	switch (sqlite3_column_type(S->stmt, colno)) {
354 		case SQLITE_NULL:
355 			add_assoc_string(return_value, "native_type", "null");
356 			break;
357 
358 		case SQLITE_FLOAT:
359 			add_assoc_string(return_value, "native_type", "double");
360 			break;
361 
362 		case SQLITE_BLOB:
363 			add_next_index_string(&flags, "blob");
364 		case SQLITE_TEXT:
365 			add_assoc_string(return_value, "native_type", "string");
366 			break;
367 
368 		case SQLITE_INTEGER:
369 			add_assoc_string(return_value, "native_type", "integer");
370 			break;
371 	}
372 
373 	str = sqlite3_column_decltype(S->stmt, colno);
374 	if (str) {
375 		add_assoc_string(return_value, "sqlite:decl_type", (char *)str);
376 	}
377 
378 #ifdef HAVE_SQLITE3_COLUMN_TABLE_NAME
379 	str = sqlite3_column_table_name(S->stmt, colno);
380 	if (str) {
381 		add_assoc_string(return_value, "table", (char *)str);
382 	}
383 #endif
384 
385 	add_assoc_zval(return_value, "flags", &flags);
386 
387 	return SUCCESS;
388 }
389 
pdo_sqlite_stmt_cursor_closer(pdo_stmt_t * stmt)390 static int pdo_sqlite_stmt_cursor_closer(pdo_stmt_t *stmt)
391 {
392 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
393 	sqlite3_reset(S->stmt);
394 	return 1;
395 }
396 
pdo_sqlite_stmt_get_attribute(pdo_stmt_t * stmt,zend_long attr,zval * val)397 static int pdo_sqlite_stmt_get_attribute(pdo_stmt_t *stmt, zend_long attr, zval *val)
398 {
399 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
400 
401 	switch (attr) {
402 		case PDO_SQLITE_ATTR_READONLY_STATEMENT:
403 			ZVAL_FALSE(val);
404 
405 #if SQLITE_VERSION_NUMBER >= 3007004
406 				if (sqlite3_stmt_readonly(S->stmt)) {
407 					ZVAL_TRUE(val);
408 				}
409 #endif
410 			break;
411 
412 		default:
413 			return 0;
414 	}
415 
416 	return 1;
417 }
418 
419 const struct pdo_stmt_methods sqlite_stmt_methods = {
420 	pdo_sqlite_stmt_dtor,
421 	pdo_sqlite_stmt_execute,
422 	pdo_sqlite_stmt_fetch,
423 	pdo_sqlite_stmt_describe,
424 	pdo_sqlite_stmt_get_col,
425 	pdo_sqlite_stmt_param_hook,
426 	NULL, /* set_attr */
427 	pdo_sqlite_stmt_get_attribute, /* get_attr */
428 	pdo_sqlite_stmt_col_meta,
429 	NULL, /* next_rowset */
430 	pdo_sqlite_stmt_cursor_closer
431 };
432