php-src/ext/pdo/pdo_sql_parser.c

243 lines
6.8 KiB
C
Raw Normal View History

/* Generated by re2c 0.5 on Tue May 18 15:32:50 2004 */
#line 1 "/home/rei/php5/ext/pdo/pdo_sql_parser.re"
2004-05-19 03:30:43 +08:00
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| 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 |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_0.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: George Schlossnagle <george@omniti.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
2004-05-18 23:38:25 +08:00
#include "php.h"
#include "php_pdo_driver.h"
2004-05-18 23:58:17 +08:00
#define PDO_PARSER_TEXT 1
#define PDO_PARSER_BIND 2
#define PDO_PARSER_EOI 3
2004-05-18 23:38:25 +08:00
#define RET(i) {s->cur = cursor; return i; }
#define YYCTYPE char
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL(n)
typedef struct Scanner {
char *lim, *ptr, *cur, *tok;
} Scanner;
static int scan(Scanner *s)
{
char *cursor = s->cur;
std:
s->tok = cursor;
2004-05-19 03:30:43 +08:00
#line 51
2004-05-18 23:38:25 +08:00
{
YYCTYPE yych;
unsigned int yyaccept;
static unsigned char yybm[] = {
0, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 0, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
224, 224, 224, 224, 224, 224, 224, 224,
224, 224, 128, 160, 160, 160, 160, 160,
160, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 160, 32, 160, 160, 160,
160, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160,
};
goto yy0;
yy1: ++YYCURSOR;
yy0:
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if(yybm[0+yych] & 32) goto yy5;
if(yych <= '\000') goto yy8;
if(yych >= ':') goto yy4;
yy2: yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if(yych >= '\001') goto yy14;
yy3:
2004-05-19 03:30:43 +08:00
#line 56
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_TEXT); }
2004-05-18 23:38:25 +08:00
yy4: yych = *++YYCURSOR;
if(yybm[0+yych] & 64) goto yy10;
goto yy3;
yy5: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy6: if(yybm[0+yych] & 32) goto yy5;
yy7:
2004-05-19 03:30:43 +08:00
#line 57
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_TEXT); }
2004-05-18 23:38:25 +08:00
yy8: yych = *++YYCURSOR;
yy9:
2004-05-19 03:30:43 +08:00
#line 58
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_EOI); }
2004-05-18 23:38:25 +08:00
yy10: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy11: if(yybm[0+yych] & 64) goto yy10;
yy12:
2004-05-19 03:30:43 +08:00
#line 55
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_BIND); }
2004-05-18 23:38:25 +08:00
yy13: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy14: if(yybm[0+yych] & 128) goto yy13;
if(yych <= '\000') goto yy15;
if(yych <= '[') goto yy17;
goto yy16;
yy15: YYCURSOR = YYMARKER;
switch(yyaccept){
case 0: goto yy3;
}
yy16: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yych == '"') goto yy13;
goto yy15;
yy17: yych = *++YYCURSOR;
yy18:
2004-05-19 03:30:43 +08:00
#line 54
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_TEXT); }
2004-05-18 23:38:25 +08:00
}
2004-05-19 03:30:43 +08:00
#line 59
2004-05-18 23:38:25 +08:00
}
int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
2004-05-18 23:58:17 +08:00
int *outquery_len TSRMLS_DC)
2004-05-18 23:38:25 +08:00
{
Scanner s;
char *ptr;
int t;
int bindno = 0;
int newbuffer_len;
2004-05-19 03:30:43 +08:00
int padding;
2004-05-18 23:38:25 +08:00
HashTable *params = stmt->bound_params;
struct pdo_bound_param_data *param;
/* allocate buffer for query with expanded binds, ptr is our writing pointer */
newbuffer_len = inquery_len;
2004-05-19 03:30:43 +08:00
/* calculate the possible padding factor due to quoting */
if(stmt->dbh->max_escaped_char_length) {
padding = stmt->dbh->max_escaped_char_length;
} else {
padding = 3;
}
2004-05-18 23:38:25 +08:00
if(params) {
zend_hash_internal_pointer_reset(params);
while (SUCCESS == zend_hash_get_current_data(params, (void**)&param)) {
if(param->parameter) {
convert_to_string(param->parameter);
/* accomodate a string that needs to be fully quoted
bind placeholders are at least 2 characters, so
the accomodate their own "'s
*/
2004-05-19 03:30:43 +08:00
newbuffer_len += padding * Z_STRLEN_P(param->parameter);
2004-05-18 23:38:25 +08:00
}
zend_hash_move_forward(params);
}
}
*outquery = (char *) emalloc(newbuffer_len + 1);
*outquery_len = 0;
ptr = *outquery;
s.cur = inquery;
s.lim = inquery + inquery_len;
2004-05-18 23:58:17 +08:00
while((t = scan(&s)) != PDO_PARSER_EOI) {
if(t == PDO_PARSER_TEXT) {
2004-05-18 23:38:25 +08:00
memcpy(ptr, s.tok, s.cur - s.tok);
ptr += (s.cur - s.tok);
*outquery_len += (s.cur - s.tok);
}
2004-05-18 23:58:17 +08:00
else if(t == PDO_PARSER_BIND) {
2004-05-18 23:38:25 +08:00
if(!params) {
/* error */
efree(*outquery);
return 0;
}
/* lookup bind first via hash and then index */
if((SUCCESS == zend_hash_find(params, s.tok+1, s.cur-s.tok,(void **)&param))
||
(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 0;
}
bindno++;
}
}
*ptr = '\0';
return 1;
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
2004-05-19 03:30:43 +08:00
* vim600: noet sw=4 ts=4 fdm=marker ft=c
2004-05-18 23:38:25 +08:00
* vim<600: noet sw=4 ts=4
*/