-/* Generated by re2c 0.5 on Fri May 21 17:33:58 2004 */
-#line 1 "/home/george/src/pecl/pdo/pdo_sql_parser.re"
+/* Generated by re2c 0.9.3 on Thu Jan 20 22:49:12 2005 */
+#line 1 "pdo_sql_parser.re"
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2005 The PHP Group |
+ | Copyright (c) 1997-2004 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
char *cursor = s->cur;
std:
s->tok = cursor;
- #line 54
+ #line 54 "pdo_sql_parser.re"
- {
+
+#line 7 "<stdout>"
+{
YYCTYPE yych;
unsigned int yyaccept;
static unsigned char yybm[] = {
yy2: yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if(yych >= '\001') goto yy24;
+ goto yy3;
yy3:
-#line 61
- { RET(PDO_PARSER_TEXT); }
+#line 61 "pdo_sql_parser.re"
+{ RET(PDO_PARSER_TEXT); }
+#line 63 "<stdout>"
yy4: yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if(yych <= '\000') goto yy3;
yy5: yych = *++YYCURSOR;
if(yybm[0+yych] & 16) goto yy13;
goto yy3;
-yy6: yych = *++YYCURSOR;
+yy6: ++YYCURSOR;
+ goto yy7;
yy7:
-#line 60
- { RET(PDO_PARSER_BIND_POS); }
+#line 60 "pdo_sql_parser.re"
+{ RET(PDO_PARSER_BIND_POS); }
+#line 77 "<stdout>"
yy8: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
+ goto yy9;
yy9: if(yybm[0+yych] & 8) goto yy8;
+ goto yy10;
yy10:
-#line 62
- { RET(PDO_PARSER_TEXT); }
-yy11: yych = *++YYCURSOR;
+#line 62 "pdo_sql_parser.re"
+{ RET(PDO_PARSER_TEXT); }
+#line 88 "<stdout>"
+yy11: ++YYCURSOR;
+ goto yy12;
yy12:
-#line 63
- { RET(PDO_PARSER_EOI); }
+#line 63 "pdo_sql_parser.re"
+{ RET(PDO_PARSER_EOI); }
+#line 94 "<stdout>"
yy13: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
+ goto yy14;
yy14: if(yybm[0+yych] & 16) goto yy13;
+ goto yy15;
yy15:
-#line 59
- { RET(PDO_PARSER_BIND); }
+#line 59 "pdo_sql_parser.re"
+{ RET(PDO_PARSER_BIND); }
+#line 105 "<stdout>"
yy16: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
+ goto yy17;
yy17: if(yybm[0+yych] & 32) goto yy16;
if(yych <= '&') goto yy18;
if(yych <= '\'') goto yy19;
YYMARKER = ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
+ goto yy20;
yy20: if(yybm[0+yych] & 32) goto yy16;
if(yych <= '&') goto yy21;
if(yych <= '\'') goto yy19;
goto yy22;
yy21:
-#line 58
- { RET(PDO_PARSER_TEXT); }
+#line 58 "pdo_sql_parser.re"
+{ RET(PDO_PARSER_TEXT); }
+#line 132 "<stdout>"
yy22: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy23: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
+ goto yy24;
yy24: if(yybm[0+yych] & 128) goto yy23;
if(yych <= '\000') goto yy18;
if(yych <= '[') goto yy26;
+ goto yy25;
yy25: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yych == '"') goto yy23;
goto yy18;
-yy26: yych = *++YYCURSOR;
+yy26: ++YYCURSOR;
+ goto yy27;
yy27:
-#line 57
- { RET(PDO_PARSER_TEXT); }
+#line 57 "pdo_sql_parser.re"
+{ RET(PDO_PARSER_TEXT); }
+#line 159 "<stdout>"
}
-#line 64
+#line 64 "pdo_sql_parser.re"
+
+}
+
+struct placeholder {
+ char *pos;
+ int len;
+ int bindno;
+ int qlen; /* quoted length of value */
+ char *quoted; /* quoted value */
+ int freeq;
+ struct placeholder *next;
+};
+
+PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
+ char **outquery, int *outquery_len TSRMLS_DC)
+{
+ Scanner s;
+ char *ptr, *newbuffer;
+ int t;
+ int bindno = 0;
+ int ret = 0;
+ int newbuffer_len;
+ int padding;
+ HashTable *params;
+ struct pdo_bound_param_data *param;
+ int query_type = PDO_PLACEHOLDER_NONE;
+ struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
+
+ ptr = *outquery;
+ s.cur = inquery;
+ s.lim = inquery + inquery_len;
+
+ /* phase 1: look for args */
+ while((t = scan(&s)) != PDO_PARSER_EOI) {
+ if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
+ if (t == PDO_PARSER_BIND) {
+ query_type |= PDO_PLACEHOLDER_NAMED;
+ } else {
+ query_type |= PDO_PLACEHOLDER_POSITIONAL;
+ }
+
+ plc = emalloc(sizeof(*plc));
+ memset(plc, 0, sizeof(*plc));
+ plc->next = NULL;
+ plc->pos = s.tok;
+ plc->len = s.cur - s.tok;
+ plc->bindno = bindno++;
+
+ if (placetail) {
+ placetail->next = plc;
+ } else {
+ placeholders = plc;
+ }
+ placetail = plc;
+ }
+ }
+
+ if (bindno == 0) {
+ /* nothing to do; good! */
+ return 0;
+ }
+
+ /* did the query make sense to me? */
+ if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
+ /* they mixed both types; punt */
+ strcpy(stmt->error_code, "HY093"); /* invalid parameter number */
+ return -1;
+ }
+
+ if (stmt->supports_placeholders == query_type) {
+ /* query matches native syntax */
+ ret = 0;
+ goto clean_up;
+ }
+
+ params = stmt->bound_params;
+
+ /* what are we going to do ? */
+ if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
+ /* query generation */
+
+ newbuffer_len = inquery_len;
+
+ /* let's quote all the values */
+ for (plc = placeholders; plc; plc = plc->next) {
+ if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
+ ret = zend_hash_index_find(params, plc->bindno, (void**) ¶m);
+ } else {
+ ret = zend_hash_find(params, plc->pos, plc->len, (void**) ¶m);
+ }
+ if (ret == FAILURE) {
+ /* parameter was not defined */
+ ret = -1;
+ strcpy(stmt->error_code, "HY093"); /* invalid parameter number */
+ goto clean_up;
+ }
+ if (stmt->dbh->methods->quoter) {
+ if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
+ Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen TSRMLS_CC)) {
+ /* bork */
+ ret = -1;
+ strcpy(stmt->error_code, stmt->dbh->error_code);
+ goto clean_up;
+ }
+ plc->freeq = 1;
+ } else {
+ plc->quoted = Z_STRVAL_P(param->parameter);
+ plc->qlen = Z_STRLEN_P(param->parameter);
+ }
+ newbuffer_len += plc->qlen;
+ }
+
+rewrite:
+ /* allocate output buffer */
+ newbuffer = emalloc(newbuffer_len + 1);
+ *outquery = newbuffer;
+
+ /* and build the query */
+ plc = placeholders;
+ ptr = inquery;
+
+ do {
+ t = plc->pos - ptr;
+ if (t) {
+ memcpy(newbuffer, ptr, t);
+ newbuffer += t;
+ }
+ memcpy(newbuffer, plc->quoted, plc->qlen);
+ newbuffer += plc->qlen;
+ ptr = plc->pos + plc->len;
+
+ plc = plc->next;
+ } while (plc);
+
+ t = (inquery + inquery_len) - ptr;
+ if (t) {
+ memcpy(newbuffer, ptr, t);
+ newbuffer += t;
+ }
+ *newbuffer = '\0';
+ *outquery_len = newbuffer - *outquery;
+
+ ret = 1;
+ goto clean_up;
+
+ } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
+ /* rewrite ? to :pdoX */
+ char idxbuf[32];
+
+ newbuffer_len = inquery_len;
+
+ for (plc = placeholders; plc; plc = plc->next) {
+ snprintf(idxbuf, sizeof(idxbuf), ":pdo%d", plc->bindno);
+ plc->quoted = estrdup(idxbuf);
+ plc->qlen = strlen(plc->quoted);
+ plc->freeq = 1;
+ newbuffer_len += plc->qlen;
+ }
+
+ goto rewrite;
+
+ } else {
+ /* rewrite :name to ? */
+
+ /* HARD!. We need to remember the mapping and bind those positions. */
+ strcpy(stmt->error_code, "IM001"); /* Driver does not support this function */
+
+ ret = -1;
+ }
+
+clean_up:
+
+ while (placeholders) {
+ plc = placeholders;
+ placeholders = plc->next;
+
+ if (plc->freeq) {
+ efree(plc->quoted);
+ }
+
+ efree(plc);
+ }
+
+ return ret;
}
-int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
+#if 0
+int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
int *outquery_len TSRMLS_DC)
{
Scanner s;
*ptr = '\0';
return 0;
}
+#endif
/*
* Local variables: