summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Schlossnagle <gschlossnagle@php.net>2004-05-20 17:56:09 +0000
committerGeorge Schlossnagle <gschlossnagle@php.net>2004-05-20 17:56:09 +0000
commitd16625b80305244ae53de992c332a15e56871dbd (patch)
tree3dd80f50422c2f0a15b8e64d00434736450e80d4
parentaafb2b158153233cf1c88cc992e8389d1cee6015 (diff)
downloadphp-git-d16625b80305244ae53de992c332a15e56871dbd.tar.gz
Support ? as a bind in emulated prepares
Throw informative error when pdo_parse_param fails
-rw-r--r--ext/pdo/pdo_sql_parser.re49
-rwxr-xr-xext/pdo/pdo_stmt.c6
2 files changed, 47 insertions, 8 deletions
diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re
index 654d41dc49..87427131b2 100644
--- a/ext/pdo/pdo_sql_parser.re
+++ b/ext/pdo/pdo_sql_parser.re
@@ -23,7 +23,8 @@
#define PDO_PARSER_TEXT 1
#define PDO_PARSER_BIND 2
-#define PDO_PARSER_EOI 3
+#define PDO_PARSER_BIND_POS 3
+#define PDO_PARSER_EOI 4
#define RET(i) {s->cur = cursor; return i; }
@@ -44,7 +45,8 @@ static int scan(Scanner *s)
s->tok = cursor;
/*!re2c
BINDCHR = [:][a-zA-Z0-9_]+;
- SPECIALS = [:"];
+ QUESTION = [?];
+ SPECIALS = [:?"];
ESC = [\\]["];
EOF = [\000];
ANYNOEOF = [\001-\377];
@@ -53,6 +55,7 @@ static int scan(Scanner *s)
/*!re2c
(["] (ESC|ANYNOEOF\[\\"])* ["]) { RET(PDO_PARSER_TEXT); }
BINDCHR { RET(PDO_PARSER_BIND); }
+ QUESTION { RET(PDO_PARSER_BIND_POS); }
SPECIALS { RET(PDO_PARSER_TEXT); }
(ANYNOEOF\SPECIALS)+ { RET(PDO_PARSER_TEXT); }
EOF { RET(PDO_PARSER_EOI); }
@@ -111,7 +114,7 @@ int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **ou
if(!params) {
/* error */
efree(*outquery);
- return 0;
+ return (int) (s.cur - inquery);
}
/* lookup bind first via hash and then index */
/* stupid keys need to be null-terminated, even though we know their length */
@@ -144,13 +147,47 @@ int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **ou
else {
/* error and cleanup */
efree(*outquery);
- return 0;
+ return (int) (s.cur - inquery);
}
bindno++;
- }
+ }
+ else if(t == PDO_PARSER_BIND_POS) {
+ if(!params) {
+ /* error */
+ efree(*outquery);
+ return (int) (s.cur - inquery);
+ }
+ /* lookup bind by index */
+ if(SUCCESS == zend_hash_index_find(params, bindno, (void **)&param))
+ {
+ char *quotedstr;
+ int quotedstrlen;
+ /* currently everything is a string here */
+
+ /* quote the bind value if necessary */
+ if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
+ Z_STRLEN_P(param->parameter), &quotedstr, &quotedstrlen TSRMLS_CC))
+ {
+ memcpy(ptr, quotedstr, quotedstrlen);
+ ptr += quotedstrlen;
+ *outquery_len += quotedstrlen;
+ efree(quotedstr);
+ } else {
+ memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
+ ptr += Z_STRLEN_P(param->parameter);
+ *outquery_len += (Z_STRLEN_P(param->parameter));
+ }
+ }
+ else {
+ /* error and cleanup */
+ efree(*outquery);
+ return (int) (s.cur - inquery);
+ }
+ bindno++;
+ }
}
*ptr = '\0';
- return 1;
+ return 0;
}
/*
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index dce3736695..b6aefbfc41 100755
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -278,13 +278,15 @@ static PHP_METHOD(PDOStatement, execute)
}
if (stmt->dbh->emulate_prepare) {
+ int error_pos;
/* handle the emulated parameter binding,
* stmt->active_query_string holds the query with binds expanded and
* quoted.
*/
- if(pdo_parse_params(stmt, stmt->query_string, stmt->query_stringlen,
- &stmt->active_query_string, &stmt->active_query_stringlen) == 0) {
+ if((error_pos = pdo_parse_params(stmt, stmt->query_string, stmt->query_stringlen,
+ &stmt->active_query_string, &stmt->active_query_stringlen)) != 0) {
// parse error in handling the query
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error emulating placeholder binding in query at %.*s....", error_pos, stmt->query_string);
RETURN_FALSE;
}
} else if (!dispatch_param_event(stmt, PDO_PARAM_EVT_EXEC_PRE TSRMLS_CC)) {