]> granicus.if.org Git - php/commitdiff
and check in the generated c file later, to avoid remaking it in fresh checkouts.
authorWez Furlong <wez@php.net>
Fri, 21 Jan 2005 03:58:09 +0000 (03:58 +0000)
committerWez Furlong <wez@php.net>
Fri, 21 Jan 2005 03:58:09 +0000 (03:58 +0000)
ext/pdo/pdo_sql_parser.c

index 26bdf21a2c622a65a21abbba89276ed2aa3504b3..550c43154d1fd186f0cf57a9454d649b170e448f 100644 (file)
@@ -1,10 +1,10 @@
-/* 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        |
@@ -45,10 +45,12 @@ static int scan(Scanner *s)
        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[] = {
@@ -99,9 +101,11 @@ yy0:
 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;
@@ -110,31 +114,42 @@ yy4:      yyaccept = 0;
 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;
@@ -148,13 +163,15 @@ yy19:     yyaccept = 1;
        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;
@@ -163,24 +180,213 @@ yy22:    ++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**) &param);
+                       } else {
+                               ret = zend_hash_find(params, plc->pos, plc->len, (void**) &param);
+                       }
+                       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;
@@ -306,6 +512,7 @@ int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **ou
        *ptr = '\0';
        return 0;
 }
+#endif
 
 /*
  * Local variables: