|
|
|
@ -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**) ¶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; |
|
|
|
@ -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: |
|
|
|
|