php-src/ext/pdo/pdo_sql_parser.c

319 lines
8.9 KiB
C
Raw Normal View History

/* Generated by re2c 0.5 on Thu May 20 13:12:59 2004 */
#line 1 "/home/george/src/pecl/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_BIND_POS 3
#define PDO_PARSER_EOI 4
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;
#line 54
2004-05-18 23:38:25 +08:00
{
YYCTYPE yych;
unsigned int yyaccept;
static unsigned char yybm[] = {
0, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 0, 168, 168, 168, 168, 192,
168, 168, 168, 168, 168, 168, 168, 168,
184, 184, 184, 184, 184, 184, 184, 184,
184, 184, 160, 168, 168, 168, 168, 160,
168, 184, 184, 184, 184, 184, 184, 184,
184, 184, 184, 184, 184, 184, 184, 184,
184, 184, 184, 184, 184, 184, 184, 184,
184, 184, 184, 168, 8, 168, 168, 184,
168, 184, 184, 184, 184, 184, 184, 184,
184, 184, 184, 184, 184, 184, 184, 184,
184, 184, 184, 184, 184, 184, 184, 184,
184, 184, 184, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
168, 168, 168, 168, 168, 168, 168, 168,
2004-05-18 23:38:25 +08:00
};
goto yy0;
yy1: ++YYCURSOR;
yy0:
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if(yybm[0+yych] & 8) goto yy8;
if(yych <= '\000') goto yy11;
if(yych <= '&') goto yy2;
if(yych <= '\'') goto yy4;
if(yych <= '>') goto yy5;
goto yy6;
2004-05-18 23:38:25 +08:00
yy2: yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if(yych >= '\001') goto yy24;
2004-05-18 23:38:25 +08:00
yy3:
#line 61
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_TEXT); }
yy4: yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if(yych <= '\000') goto yy3;
if(yych == '"') goto yy3;
goto yy17;
yy5: yych = *++YYCURSOR;
if(yybm[0+yych] & 16) goto yy13;
2004-05-18 23:38:25 +08:00
goto yy3;
yy6: yych = *++YYCURSOR;
yy7:
#line 60
{ RET(PDO_PARSER_BIND_POS); }
yy8: ++YYCURSOR;
2004-05-18 23:38:25 +08:00
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy9: if(yybm[0+yych] & 8) goto yy8;
yy10:
#line 62
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_TEXT); }
yy11: yych = *++YYCURSOR;
yy12:
#line 63
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_EOI); }
yy13: ++YYCURSOR;
2004-05-18 23:38:25 +08:00
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy14: if(yybm[0+yych] & 16) goto yy13;
yy15:
#line 59
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_BIND); }
yy16: ++YYCURSOR;
2004-05-18 23:38:25 +08:00
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy17: if(yybm[0+yych] & 32) goto yy16;
if(yych <= '&') goto yy18;
if(yych <= '\'') goto yy19;
goto yy22;
yy18: YYCURSOR = YYMARKER;
2004-05-18 23:38:25 +08:00
switch(yyaccept){
case 1: goto yy21;
2004-05-18 23:38:25 +08:00
case 0: goto yy3;
}
yy19: yyaccept = 1;
YYMARKER = ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
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); }
yy22: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yych == '\'') goto yy16;
goto yy18;
yy23: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy24: if(yybm[0+yych] & 128) goto yy23;
if(yych <= '\000') goto yy18;
if(yych <= '[') goto yy26;
yy25: ++YYCURSOR;
2004-05-18 23:38:25 +08:00
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yych == '"') goto yy23;
goto yy18;
yy26: yych = *++YYCURSOR;
yy27:
#line 57
2004-05-18 23:58:17 +08:00
{ RET(PDO_PARSER_TEXT); }
2004-05-18 23:38:25 +08:00
}
#line 64
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) {
char crutch;
2004-05-18 23:38:25 +08:00
if(!params) {
/* error */
efree(*outquery);
return (int) (s.cur - inquery);
2004-05-18 23:38:25 +08:00
}
/* lookup bind first via hash and then index */
/* stupid keys need to be null-terminated, even though we know their length */
crutch = s.tok[s.cur-s.tok + 1];
s.tok[s.cur-s.tok] = '\0';
if((SUCCESS == zend_hash_find(params, s.tok, s.cur-s.tok + 1,(void **)&param))
2004-05-18 23:38:25 +08:00
||
(SUCCESS == zend_hash_index_find(params, bindno, (void **)&param)))
{
char *quotedstr;
int quotedstrlen;
/* restore the in-string key, doesn't need null-termination here */
s.tok[s.cur-s.tok] = crutch;
2004-05-18 23:38:25 +08:00
/* 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++;
}
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);
2004-05-18 23:38:25 +08:00
}
bindno++;
}
2004-05-18 23:38:25 +08:00
}
*ptr = '\0';
return 0;
2004-05-18 23:38:25 +08:00
}
/*
* 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
*/