Implement a generic SQL parser for userspace.

$ret = PDO_User::parseSQL($sql);
Will return a complex nested array structure containing a script navigable
representation of a given SQL statement.
No, this isn't a complete implementation of SQL99.
No, this doesn't allow multiple statements separated by a semicolon.
No, the parser generation isn't built into the Makefile.frag (yet).
This commit is contained in:
Sara Golemon
2006-05-09 01:58:46 +00:00
parent 24ca72b90a
commit dcc7e0b411
10 changed files with 4949 additions and 1589 deletions

View File

@@ -28,7 +28,7 @@ if test "$PHP_PDO_USER" != "no"; then
])
PHP_NEW_EXTENSION(pdo_user, pdo_user.c pdo_user_driver.c pdo_user_statement.c pdo_user_object.c \
pdo_user_sql_tokenizer.c, $ext_shared,,-I$pdo_inc_path)
pdo_user_sql_tokenizer.c pdo_user_sql_parser.c, $ext_shared,,-I$pdo_inc_path)
PHP_ADD_MAKEFILE_FRAGMENT

View File

@@ -5,7 +5,7 @@ ARG_ENABLE("pdo-user", "for pdo_user support", "no");
if (PHP_PDO_USER != "no") {
EXTENSION("pdo_user", "pdo_user.c pdo_user_driver.c pdo_user_statement.c pdo_user_object.c pdo_user_sql_tokenizer.c");
EXTENSION("pdo_user", "pdo_user.c pdo_user_driver.c pdo_user_statement.c pdo_user_object.c pdo_user_sql_tokenizer.c pdo_user_sql_parser.c");
ADD_EXTENSION_DEP('pdo_user', 'pdo');
}

View File

@@ -252,6 +252,43 @@ PHP_METHOD(pdo_user,tokenizesql)
}
/* }}} */
static void *pdo_user_malloc_wrapper(size_t x) { return emalloc(x); }
static void pdo_user_free_wrapper(size_t x) { efree(x); }
/* {{{ proto array PDO_User::parseSQL(string sql)
Compile a SQL statement into a query structure */
PHP_METHOD(pdo_user,parsesql)
{
char *sql;
int sql_len;
php_pdo_user_sql_tokenizer T;
php_pdo_user_sql_token token;
void *pParser;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &sql, &sql_len) == FAILURE) {
return;
}
T.start = sql;
T.end = sql + sql_len;
pParser = php_pdo_user_sql_parserAlloc( pdo_user_malloc_wrapper );
while (PU_END != php_pdo_user_sql_get_token(&T, &token)) {
if (token.id != PU_WHITESPACE) {
php_pdo_user_sql_parser(pParser, token.id, token, return_value);
}
if (Z_TYPE_P(return_value) == IS_BOOL) {
/* FALSE implied */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failure parsing SQL statement at: %s", token.token);
php_pdo_user_sql_parserFree(pParser, pdo_user_free_wrapper);
return;
}
}
php_pdo_user_sql_parser(pParser, 0, token, return_value);
php_pdo_user_sql_parserFree(pParser, pdo_user_free_wrapper);
}
/* }}} */
static zend_class_entry *php_pdo_user_ce;
static zend_class_entry *php_pdo_user_driver_interface;
static zend_class_entry *php_pdo_user_statement_interface;
@@ -261,6 +298,7 @@ static zend_function_entry php_pdo_user_class_functions[] = {
PHP_MALIAS(pdo_user, statementparam, driverparam, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(pdo_user, parsedsn, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(pdo_user, tokenizesql, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(pdo_user, parsesql, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
{ NULL, NULL, NULL }
};

2124
pdo_user_sql_parser.c Normal file

File diff suppressed because it is too large Load Diff

94
pdo_user_sql_parser.h Normal file
View File

@@ -0,0 +1,94 @@
#define PU_NOT 1
#define PU_GROUP 2
#define PU_ORDER 3
#define PU_BY 4
#define PU_LIMIT 5
#define PU_WHERE 6
#define PU_HAVING 7
#define PU_SELECT 8
#define PU_INSERT 9
#define PU_INTO 10
#define PU_COMMA 11
#define PU_AND 12
#define PU_OR 13
#define PU_XOR 14
#define PU_AS 15
#define PU_BETWEEN 16
#define PU_LIKE 17
#define PU_RLIKE 18
#define PU_EQUALS 19
#define PU_LESSER 20
#define PU_GREATER 21
#define PU_LESS_EQUAL 22
#define PU_GREATER_EQUAL 23
#define PU_DISTINCT 24
#define PU_MUL 25
#define PU_DIV 26
#define PU_MOD 27
#define PU_RPAREN 28
#define PU_PLUS 29
#define PU_MINUS 30
#define PU_LPAREN 31
#define PU_LABEL 32
#define PU_LNUM 33
#define PU_HNUM 34
#define PU_STRING 35
#define PU_SEMICOLON 36
#define PU_VALUES 37
#define PU_UPDATE 38
#define PU_SET 39
#define PU_DELETE 40
#define PU_RENAME 41
#define PU_TABLE 42
#define PU_CREATE 43
#define PU_DROP 44
#define PU_FROM 45
#define PU_NULL 46
#define PU_DEFAULT 47
#define PU_PRIMARY 48
#define PU_KEY 49
#define PU_UNIQUE 50
#define PU_AUTO_INCREMENT 51
#define PU_BIT 52
#define PU_INT 53
#define PU_INTEGER 54
#define PU_TINYINT 55
#define PU_SMALLINT 56
#define PU_MEDIUMINT 57
#define PU_BIGINT 58
#define PU_YEAR 59
#define PU_FLOAT 60
#define PU_REAL 61
#define PU_DECIMAL 62
#define PU_DOUBLE 63
#define PU_CHAR 64
#define PU_VARCHAR 65
#define PU_DATE 66
#define PU_TIME 67
#define PU_DATETIME 68
#define PU_TIMESTAMP 69
#define PU_TEXT 70
#define PU_TINYTEXT 71
#define PU_MEDIUMTEXT 72
#define PU_LONGTEXT 73
#define PU_BLOB 74
#define PU_TINYBLOB 75
#define PU_MEDIUMBLOB 76
#define PU_LONGBLOB 77
#define PU_BINARY 78
#define PU_VARBINARY 79
#define PU_ENUM 80
#define PU_UNSIGNED 81
#define PU_ZEROFILL 82
#define PU_TO 83
#define PU_ON 84
#define PU_INNER 85
#define PU_JOIN 86
#define PU_OUTER 87
#define PU_LEFT 88
#define PU_RIGHT 89
#define PU_NOT_EQUAL 90
#define PU_UNEQUAL 91
#define PU_LESSER_EQUAL 92
#define PU_ASC 93
#define PU_DESC 94

532
pdo_user_sql_parser.lemon Normal file
View File

@@ -0,0 +1,532 @@
%token_prefix PU_
%token_type {php_pdo_user_sql_token}
%default_type {zval*}
%extra_argument {zval *return_value}
%name php_pdo_user_sql_parser
%start_symbol terminal_statement
%right NOT GROUP ORDER BY LIMIT WHERE HAVING.
%right SELECT INSERT INTO.
%left COMMA AND OR XOR AS BETWEEN LIKE RLIKE EQUALS LESSER GREATER LESS_EQUAL GREATER_EQUAL.
%right DISTINCT.
%left MUL DIV MOD.
%left RPAREN PLUS MINUS.
%right LPAREN.
%nonassoc LABEL LNUM HNUM STRING.
%include {
#include "php.h"
#include "php_pdo_user_sql.h"
static inline zval *pusp_zvalize_hnum(php_pdo_user_sql_token *T) {
zval *ret;
int val = 0;
char *s = T->token, *e = T->token + T->token_len;
MAKE_STD_ZVAL(ret);
if (strncmp("0x", s, 2) == 0) {
s += 2;
}
while (s < e) {
/* illegal characters aren't possible, the lexer wouldn't give us any */
val <<=4;
if (*s >= '0' && *s <= '9') {
val |= *s - '0';
} else if (*s >= 'A' && *s <= 'F') {
val |= (*s - 'A') + 10;
} else {
val |= (*s - 'a') + 10;
}
s++;
}
ZVAL_LONG(ret, val);
return ret;
}
static inline zval *pusp_zvalize_lnum(php_pdo_user_sql_token *T) {
zval *ret;
int val = 0;
unsigned char *s = T->token, *e = T->token + T->token_len;
MAKE_STD_ZVAL(ret);
while (s < e) {
/* illegal characters aren't possible, the lexer wouldn't give us any */
val *= 10;
val += *s - '0';
s++;
}
ZVAL_LONG(ret, val);
return ret;
}
static inline zval *pusp_zvalize_token(php_pdo_user_sql_token *T)
{
zval *ret;
MAKE_STD_ZVAL(ret);
ZVAL_STRINGL(ret, T->token, T->token_len, !T->freeme);
return ret;
}
#define pusp_zvalize_static_string(str) pusp_zvalize_stringl((str), sizeof(str) - 1, 1)
static inline zval *pusp_zvalize_stringl(char *str, int strlen, int dup)
{
zval *ret;
MAKE_STD_ZVAL(ret);
ZVAL_STRINGL(ret, str, strlen, dup);
return ret;
}
static inline void pusp_do_push_labeled_zval(zval *ret, zval **pair)
{
add_assoc_zval(ret, Z_STRVAL_P(pair[0]), pair[1]);
zval_ptr_dtor(&pair[0]);
efree(pair);
}
/* ----------- */
static inline void pusp_do_terminal_statement(zval **return_value, zval *statement, zend_bool have_semicolon)
{
**return_value = *statement;
efree(statement);
add_assoc_bool(*return_value, "terminating-semicolon", have_semicolon);
}
static inline zval *pusp_do_join_expression(zval *table1, zval *jointype, zval *table2, zval *oncondition)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "join", sizeof("join") - 1, 1);
add_assoc_zval(ret, "table1", table1);
add_assoc_zval(ret, "join-type", jointype);
add_assoc_zval(ret, "table2", table2);
add_assoc_zval(ret, "on", oncondition);
return ret;
}
static inline zval *pusp_do_function(zval *fname, zval *arguments)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "fcall", sizeof("fcall") - 1, 1);
add_assoc_zval(ret, "fname", fname);
add_assoc_zval(ret, "args", arguments);
return ret;
}
static inline zval *pusp_do_add_query_modifier(zval *ret, char *lbl, zval *val)
{
if (Z_TYPE_P(ret) == IS_NULL) { /* substitute for: ret == EG(uninitialized_zval_ptr), avoid the TSRMLS_FETCH(); */
MAKE_STD_ZVAL(ret);
array_init(ret);
}
add_assoc_zval(ret, lbl, val);
return ret;
}
static zval *pusp_do_declare_num(char *fieldtype, zval *precision, zval *unsgn, zval *zerofill)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "field", sizeof("field") - 1, 1);
add_assoc_string(ret, "fieldtype", fieldtype, 1);
add_assoc_zval(ret, "precision", precision);
add_assoc_zval(ret, "unsigned", unsgn);
add_assoc_zval(ret, "zerofill", zerofill);
return ret;
}
static zval *pusp_do_declare_type(char *type, char *attr, zval *zattr)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "field", sizeof("field") - 1, 1);
add_assoc_string(ret, "fieldtype", type, 1);
if (attr) {
add_assoc_zval(ret, attr, zattr);
}
return ret;
}
/* ---------------- */
static inline zval *pusp_do_select_statement(zval *fieldlist, zval *tableexpr, zval *modifiers)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "statement", sizeof("statement") - 1, 1);
add_assoc_stringl(ret, "statement", "select", sizeof("select") - 1, 1);
add_assoc_zval(ret, "fields", fieldlist);
add_assoc_zval(ret, "from", tableexpr);
add_assoc_zval(ret, "modifiers", modifiers);
return ret;
}
static inline zval *pusp_do_insert_select_statement(zval *table, zval *fields, zval *selectstmt)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "statement", sizeof("statement") - 1, 1);
add_assoc_stringl(ret, "statement", "insert-select", sizeof("insert-select") - 1, 1);
add_assoc_zval(ret, "table", table);
add_assoc_zval(ret, "fields", fields);
add_assoc_zval(ret, "query", selectstmt);
return ret;
}
static inline zval *pusp_do_insert_statement(zval *table, zval *fields, zval *insertgroup)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "statement", sizeof("statement") - 1, 1);
add_assoc_stringl(ret, "statement", "insert", sizeof("insert") - 1, 1);
add_assoc_zval(ret, "table", table);
add_assoc_zval(ret, "fields", fields);
add_assoc_zval(ret, "data", insertgroup);
return ret;
}
static inline zval *pusp_do_update_statement(zval *table, zval *setlist, zval *wherestmt)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "statement", sizeof("statement") - 1, 1);
add_assoc_stringl(ret, "statement", "update", sizeof("update") - 1, 1);
add_assoc_zval(ret, "table", table);
add_assoc_zval(ret, "set", setlist);
add_assoc_zval(ret, "where", wherestmt);
return ret;
}
static inline zval *pusp_do_delete_statement(zval *table, zval *wherestmt)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "statement", sizeof("statement") - 1, 1);
add_assoc_stringl(ret, "statement", "delete", sizeof("delete") - 1, 1);
add_assoc_zval(ret, "table", table);
add_assoc_zval(ret, "where", wherestmt);
return ret;
}
static inline zval *pusp_do_rename_statement(zval *renlist)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "statement", sizeof("statement") - 1, 1);
add_assoc_stringl(ret, "statement", "rename table", sizeof("rename table") - 1, 1);
add_assoc_zval(ret, "tables", renlist);
return ret;
}
static inline zval *pusp_do_create_statement(zval *table, zval *fields)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "statement", sizeof("statement") - 1, 1);
add_assoc_stringl(ret, "statement", "create table", sizeof("create table") - 1, 1);
add_assoc_zval(ret, "table", table);
add_assoc_zval(ret, "fields", fields);
return ret;
}
static inline zval *pusp_do_drop_statement(zval *table)
{
zval *ret;
MAKE_STD_ZVAL(ret);
array_init(ret);
add_assoc_stringl(ret, "type", "statement", sizeof("statement") - 1, 1);
add_assoc_stringl(ret, "statement", "drop table", sizeof("drop table") - 1, 1);
add_assoc_zval(ret, "table", table);
return ret;
}
#define DO_COND(R, T, A, B) { \
MAKE_STD_ZVAL(R); \
array_init(R); \
add_assoc_stringl(R, "type", "condition", sizeof("condition") - 1, 1); \
add_assoc_zval(R, "op1", A); \
add_assoc_stringl(R, "condition", T, sizeof(T) - 1, 1); \
add_assoc_zval(R, "op2", B); \
}
#define DO_MATHOP(R, A, O, B) { \
MAKE_STD_ZVAL(R); \
array_init(R); \
add_assoc_stringl(R, "type", "math", sizeof("math") - 1, 1); \
add_assoc_zval(R, "op1", A); \
add_assoc_stringl(R, "operation", O, sizeof(O) - 1, 1); \
add_assoc_zval(R, "op2", B); \
}
} /* %include */
%syntax_error {
RETVAL_FALSE;
}
terminal_statement ::= statement(S) SEMICOLON. { pusp_do_terminal_statement(&return_value, S, 1); }
terminal_statement ::= statement(S). { pusp_do_terminal_statement(&return_value, S, 0); }
%destructor statement { zval_ptr_dtor(&$$); }
statement(R) ::= selectstatement(S). { R = S; }
statement(R) ::= INSERT INTO LABEL(T) optionalinsertfieldlist(F) selectstatement(S). { R = pusp_do_insert_select_statement(pusp_zvalize_token(&T), F, S); }
statement(R) ::= INSERT INTO LABEL(T) optionalinsertfieldlist(F) VALUES insertgrouplist(G). { R = pusp_do_insert_statement(pusp_zvalize_token(&T), F, G); }
statement(R) ::= UPDATE LABEL(T) SET setlist(L) optionalwhereclause(W). { R = pusp_do_update_statement(pusp_zvalize_token(&T), L, W); }
statement(R) ::= DELETE LABEL(T) optionalwhereclause(W). { R = pusp_do_delete_statement(pusp_zvalize_token(&T), W); }
statement(R) ::= RENAME TABLE togrouplist(T). { R = pusp_do_rename_statement(T); }
statement(R) ::= CREATE TABLE LABEL(T) LPAREN fielddescriptorlist(L) RPAREN. { R = pusp_do_create_statement(pusp_zvalize_token(&T), L); }
statement(R) ::= DROP TABLE LABEL(T). { R = pusp_do_drop_statement(pusp_zvalize_token(&T)); }
%destructor selectstatement { zval_ptr_dtor(&$$); }
selectstatement(R) ::= SELECT fieldlist(F) FROM tableexpr(T) optionalquerymodifiers(M). { R = pusp_do_select_statement(F,T,M); }
%destructor fielddescriptorlist { zval_ptr_dtor(&$$); }
fielddescriptorlist(R) ::= fielddescriptorlist(L) COMMA fielddescriptor(D). { add_next_index_zval(L, D); R = L; }
fielddescriptorlist(R) ::= fielddescriptor(D). { MAKE_STD_ZVAL(R); array_init(R); add_next_index_zval(R, D); }
%destructor fielddescriptor { zval_ptr_dtor(&$$); }
fielddescriptor(R) ::= LABEL(F) fielddescriptortype(T) optionalfielddescriptormodifierlist(M). { add_assoc_zval(T, "name", pusp_zvalize_token(&F)); add_assoc_zval(T, "flags", M); R = T; }
%destructor optionalfielddescriptormodifierlist { zval_ptr_dtor(&$$); }
optionalfielddescriptormodifierlist(R) ::= optionalfielddescriptormodifierlist(L) NOT NULL. { add_next_index_string(L, "not null", 1); R = L; }
optionalfielddescriptormodifierlist(R) ::= optionalfielddescriptormodifierlist(L) DEFAULT literal(V). { add_assoc_zval(L, "default", V); R = L; }
optionalfielddescriptormodifierlist(R) ::= optionalfielddescriptormodifierlist(L) PRIMARY KEY. { add_next_index_string(L, "primary key", 1); R = L; }
optionalfielddescriptormodifierlist(R) ::= optionalfielddescriptormodifierlist(L) UNIQUE KEY. { add_next_index_string(L, "unique key", 1); R = L; }
optionalfielddescriptormodifierlist(R) ::= optionalfielddescriptormodifierlist(L) KEY. { add_next_index_string(L, "key", 1); R = L; }
optionalfielddescriptormodifierlist(R) ::= optionalfielddescriptormodifierlist(L) AUTO_INCREMENT. { add_next_index_string(L, "auto_increment", 1); R = L; }
optionalfielddescriptormodifierlist(R) ::= . { MAKE_STD_ZVAL(R); array_init(R); }
%destructor fielddescriptortype { zval_ptr_dtor(&$$); }
fielddescriptortype(R) ::= BIT. { R = pusp_do_declare_type("bit", NULL, NULL); }
fielddescriptortype(R) ::= INT optionalprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("int", P, U, Z); }
fielddescriptortype(R) ::= INTEGER optionalprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("integer", P, U, Z); }
fielddescriptortype(R) ::= TINYINT optionalprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("tinyint", P, U, Z); }
fielddescriptortype(R) ::= SMALLINT optionalprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("smallint", P, U, Z); }
fielddescriptortype(R) ::= MEDIUMINT optionalprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("mediumint", P, U, Z); }
fielddescriptortype(R) ::= BIGINT optionalprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("bigint", P, U, Z); }
fielddescriptortype(R) ::= YEAR optionalprecision(P). { R = pusp_do_declare_type("year", "precision", P); }
fielddescriptortype(R) ::= FLOAT optionalfloatprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("float", P, U, Z); }
fielddescriptortype(R) ::= REAL optionalfloatprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("real", P, U, Z); }
fielddescriptortype(R) ::= DECIMAL optionalfloatprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("decimal", P, U, Z); }
fielddescriptortype(R) ::= DOUBLE optionalfloatprecision(P) optionalunsigned(U) optionalzerofill(Z). { R = pusp_do_declare_num("double", P, U, Z); }
fielddescriptortype(R) ::= CHAR LPAREN intnum(P) RPAREN. { R = pusp_do_declare_type("char", "length", P); }
fielddescriptortype(R) ::= VARCHAR LPAREN intnum(P) RPAREN. { R = pusp_do_declare_type("varchar", "length", P); }
fielddescriptortype(R) ::= DATE. { R = pusp_do_declare_type("text", "date", NULL); }
fielddescriptortype(R) ::= TIME. { R = pusp_do_declare_type("text", "time", NULL); }
fielddescriptortype(R) ::= DATETIME optionalprecision(P). { R = pusp_do_declare_type("datetime", "precision", P); }
fielddescriptortype(R) ::= TIMESTAMP optionalprecision(P). { R = pusp_do_declare_type("timestamp", "precision", P); }
fielddescriptortype(R) ::= TEXT. { R = pusp_do_declare_type("text", "precision", NULL); }
fielddescriptortype(R) ::= TINYTEXT. { zval *p; MAKE_STD_ZVAL(p); ZVAL_STRING(p, "tiny", 1); R = pusp_do_declare_type("text", "precision", p); }
fielddescriptortype(R) ::= MEDIUMTEXT. { zval *p; MAKE_STD_ZVAL(p); ZVAL_STRING(p, "medium", 1); R = pusp_do_declare_type("text", "precision", p); }
fielddescriptortype(R) ::= LONGTEXT. { zval *p; MAKE_STD_ZVAL(p); ZVAL_STRING(p, "long", 1); R = pusp_do_declare_type("text", "precision", p); }
fielddescriptortype(R) ::= BLOB. { R = pusp_do_declare_type("blob", "precision", NULL); }
fielddescriptortype(R) ::= TINYBLOB. { zval *p; MAKE_STD_ZVAL(p); ZVAL_STRING(p, "tiny", 1); R = pusp_do_declare_type("blob", "precision", p); }
fielddescriptortype(R) ::= MEDIUMBLOB. { zval *p; MAKE_STD_ZVAL(p); ZVAL_STRING(p, "medium", 1); R = pusp_do_declare_type("blob", "precision", p); }
fielddescriptortype(R) ::= LONGBLOB. { zval *p; MAKE_STD_ZVAL(p); ZVAL_STRING(p, "long", 1); R = pusp_do_declare_type("blob", "precision", p); }
fielddescriptortype(R) ::= BINARY LPAREN intnum(P) RPAREN. { R = pusp_do_declare_type("binary", "length", P); }
fielddescriptortype(R) ::= VARBINARY LPAREN intnum(P) RPAREN. { R = pusp_do_declare_type("varbinary", "length", P); }
fielddescriptortype(R) ::= SET LPAREN literallist(L) RPAREN. { R = pusp_do_declare_type("set", "flags", L); }
fielddescriptortype(R) ::= ENUM LPAREN literallist(L) RPAREN. { R = pusp_do_declare_type("enum", "values", L); }
%destructor optionalunsigned { zval_ptr_dtor(&$$); }
optionalunsigned(R) ::= UNSIGNED. { MAKE_STD_ZVAL(R); ZVAL_TRUE(R); }
optionalunsigned(R) ::= . { MAKE_STD_ZVAL(R); ZVAL_FALSE(R); }
%destructor optionalzerofill { zval_ptr_dtor(&$$); }
optionalzerofill(R) ::= ZEROFILL. { MAKE_STD_ZVAL(R); ZVAL_TRUE(R); }
optionalzerofill(R) ::= . { MAKE_STD_ZVAL(R); ZVAL_FALSE(R); }
%destructor optionalprecision { zval_ptr_dtor(&$$); }
optionalprecision(R) ::= LPAREN intnum(P) RPAREN. { R = P; }
optionalprecision(R) ::= . { TSRMLS_FETCH(); R = EG(uninitialized_zval_ptr); }
%destructor optionalfloatprecision { zval_ptr_dtor(&$$); }
optionalfloatprecision(R) ::= LPAREN intnum(L) COMMA intnum(D) RPAREN. { MAKE_STD_ZVAL(R); array_init(R); add_assoc_zval(R, "length", L); add_assoc_zval(R, "decimals", D); }
optionalfloatprecision(R) ::= . { TSRMLS_FETCH(); R = EG(uninitialized_zval_ptr); }
%destructor literallist { zval_ptr_dtor(&$$); }
literallist(R) ::= literallist(L) COMMA literal(E). { add_next_index_zval(L, E); R = L; }
literallist(R) ::= literal(E). { MAKE_STD_ZVAL(R); array_init(R); add_next_index_zval(R, E); }
%destructor togrouplist { zval_ptr_dtor(&$$); }
togrouplist(R) ::= togrouplist(L) COMMA togroup(V). { pusp_do_push_labeled_zval(L, V); R = L; }
togrouplist(R) ::= togroup(V). { MAKE_STD_ZVAL(R); array_init(R); pusp_do_push_labeled_zval(R, V); }
%type togroup {zval**}
%destructor togroup { zval_ptr_dtor(&$$[0]); zval_ptr_dtor(&$$[1]); efree($$); }
togroup(R) ::= LABEL(F) TO LABEL(T). { zval **tmp = safe_emalloc(2, sizeof(zval*), 0); tmp[0] = pusp_zvalize_token(&F); tmp[1] = pusp_zvalize_token(&T); R = tmp; }
%destructor setlist { zval_ptr_dtor(&$$); }
setlist(R) ::= setlist(L) COMMA setexpr(V). { pusp_do_push_labeled_zval(L, (zval**)V); R = L; }
setlist(R) ::= setexpr(V). { MAKE_STD_ZVAL(R); array_init(R); pusp_do_push_labeled_zval(R, V); }
%type setexpr {zval**}
%destructor setexpr { zval_ptr_dtor(&$$[0]); zval_ptr_dtor(&$$[1]); efree($$); }
setexpr(R) ::= LABEL(F) EQUALS expr(E). { zval **tmp = safe_emalloc(2, sizeof(zval*), 0); tmp[0] = pusp_zvalize_token(&F); tmp[1] = E; R = tmp; }
%destructor insertgrouplist { zval_ptr_dtor(&$$); }
insertgrouplist(R) ::= insertgrouplist(L) COMMA insertgroup(G). { add_next_index_zval(L, G); R = L; }
insertgrouplist(R) ::= insertgroup(G). { MAKE_STD_ZVAL(R); array_init(R); add_next_index_zval(R, G); }
%destructor insertgroup { zval_ptr_dtor(&$$); }
insertgroup(R) ::= LPAREN exprlist(L) RPAREN. { R = L; }
%destructor labellist { zval_ptr_dtor(&$$); }
labellist(R) ::= labellist(L) COMMA LABEL(F). { add_next_index_zval(L, pusp_zvalize_token(&F)); R = L; }
labellist(R) ::= LABEL(F). { MAKE_STD_ZVAL(R); array_init(R); add_next_index_zval(R, pusp_zvalize_token(&F)); }
%destructor optionalinsertfieldlist { zval_ptr_dtor(&$$); }
optionalinsertfieldlist(R) ::= LPAREN labellist(L) RPAREN. { R = L; }
optionalinsertfieldlist(R) ::= . { TSRMLS_FETCH(); R = EG(uninitialized_zval_ptr); }
%destructor fieldlist { zval_ptr_dtor(&$$); }
fieldlist(R) ::= fieldlist(L) COMMA field(F). { add_next_index_zval(L, F); R = L; }
fieldlist(R) ::= field(F). { MAKE_STD_ZVAL(R); array_init(R); add_next_index_zval(R, F); }
%destructor field { zval_ptr_dtor(&$$); }
field(R) ::= expr(E). { R = E; }
field(R) ::= field(E) AS LABEL(A). { MAKE_STD_ZVAL(R); array_init(R); add_assoc_stringl(R, "type", "alias", sizeof("alias") - 1, 1); add_assoc_zval(R, "field", E); add_assoc_zval(R, "as", pusp_zvalize_token(&A)); }
%destructor tableexpr { zval_ptr_dtor(&$$); }
tableexpr(R) ::= LPAREN tableexpr(T) RPAREN. { R = T; }
tableexpr(R) ::= tableexpr(A) joinclause(J) tableexpr(B) ON cond(O). { R = pusp_do_join_expression(A, J, B, O); }
tableexpr(R) ::= tableexpr(E) AS LABEL(A). { MAKE_STD_ZVAL(R); array_init(R); add_assoc_stringl(R, "type", "alias", sizeof("alias") - 1, 1); add_assoc_zval(R, "table", E); add_assoc_zval(R, "as", pusp_zvalize_token(&A)); }
tableexpr(R) ::= LABEL(L). { R = pusp_zvalize_token(&L); }
/*
TODO: Make this work, there's a ornery reduce conflict going on somewhere...
tableexpr(R) ::= tableexprlist(L) COMMA tableexpr(T). { add_next_index_zval(L, T); R = L; }
tableexprlist(R) ::= tableexprlist(L) COMMA tableexpr(T). { add_next_index_zval(L, T); R = L; }
tableexprlist(R) ::= tableexpr(T). { MAKE_STD_ZVAL(R); add_assoc_stringl(R, "type", "table-list", sizeof("table-list") - 1, 1); add_next_index_zval(R, T); }
*/
%destructor joinclause { zval_ptr_dtor(&$$); }
joinclause(R) ::= INNER JOIN. { R = pusp_zvalize_static_string("inner"); }
joinclause(R) ::= OUTER JOIN. { R = pusp_zvalize_static_string("outer"); }
joinclause(R) ::= LEFT JOIN. { R = pusp_zvalize_static_string("left"); }
joinclause(R) ::= RIGHT JOIN. { R = pusp_zvalize_static_string("right"); }
%destructor optionalquerymodifiers { zval_ptr_dtor(&$$); }
optionalquerymodifiers(R) ::= optionalquerymodifiers(O) whereclause(W). { R = pusp_do_add_query_modifier(O, "where", W); }
optionalquerymodifiers(R) ::= optionalquerymodifiers(O) limitclause(L). { R = pusp_do_add_query_modifier(O, "limit", L); }
optionalquerymodifiers(R) ::= optionalquerymodifiers(O) havingclause(H). { R = pusp_do_add_query_modifier(O, "having", H); }
optionalquerymodifiers(R) ::= optionalquerymodifiers(O) groupclause(G). { R = pusp_do_add_query_modifier(O, "group-by", G); }
optionalquerymodifiers(R) ::= optionalquerymodifiers(O) orderclause(B). { R = pusp_do_add_query_modifier(O, "order-by", B); }
optionalquerymodifiers(R) ::= . { TSRMLS_FETCH(); R = EG(uninitialized_zval_ptr); }
%destructor whereclause { zval_ptr_dtor(&$$); }
whereclause(R) ::= WHERE cond(C). { R = C; }
%destructor limitclause { zval_ptr_dtor(&$$); }
limitclause(R) ::= LIMIT intnum(F) COMMA intnum(T). { MAKE_STD_ZVAL(R); array_init(R); add_assoc_zval(R, "from", F); add_assoc_zval(R, "to", T); }
%destructor havingclause { zval_ptr_dtor(&$$); }
havingclause(R) ::= HAVING cond(C). { R = C; }
%destructor groupclause { zval_ptr_dtor(&$$); }
groupclause(R) ::= GROUP BY grouplist(G). { R = G; }
%destructor orderclause { zval_ptr_dtor(&$$); }
orderclause(R) ::= ORDER BY orderlist(O). { R = O; }
%destructor optionalwhereclause { zval_ptr_dtor(&$$); }
optionalwhereclause(R) ::= whereclause(W). { R = W; }
optionalwhereclause(R) ::= . { TSRMLS_FETCH(); R = EG(uninitialized_zval_ptr); }
%destructor cond { zval_ptr_dtor(&$$); }
cond(R) ::= cond(A) AND cond(B). { DO_COND(R, "and", A, B); }
cond(R) ::= cond(A) OR cond(B). { DO_COND(R, "or", A, B); }
cond(R) ::= cond(A) XOR cond(B). { DO_COND(R, "xor", A, B); }
cond(R) ::= expr(A) EQUALS expr(B). { DO_COND(R, "=", A, B); }
cond(R) ::= expr(A) NOT_EQUAL expr(B). { DO_COND(R, "!=", A, B); }
cond(R) ::= expr(A) UNEQUAL expr(B). { DO_COND(R, "<>", A, B); }
cond(R) ::= expr(A) LESSER expr(B). { DO_COND(R, "<", A, B); }
cond(R) ::= expr(A) GREATER expr(B). { DO_COND(R, ">", A, B); }
cond(R) ::= expr(A) LESSER_EQUAL expr(B). { DO_COND(R, "<=", A, B); }
cond(R) ::= expr(A) GREATER_EQUAL expr(B). { DO_COND(R, ">=", A, B); }
cond(R) ::= expr(A) LIKE expr(B). { DO_COND(R, "like", A, B); }
cond(R) ::= expr(A) RLIKE expr(B). { DO_COND(R, "rlike", A, B); }
cond(R) ::= expr(A) BETWEEN expr(B) AND expr(C). { DO_COND(R, "between", A, B); add_assoc_zval(R, "op-c", C); }
cond(R) ::= expr(A) NOT LIKE expr(B). { DO_COND(R, "not like", A, B); }
cond(R) ::= expr(A) NOT RLIKE expr(B). { DO_COND(R, "not rlike", A, B); }
cond(R) ::= expr(A) NOT BETWEEN expr(B) AND expr(C). { DO_COND(R, "not between", A, B); add_assoc_zval(R, "op-c", C); }
cond(R) ::= LPAREN cond(C) RPAREN. { R = C; }
%destructor exprlist { zval_ptr_dtor(&$$); }
exprlist(R) ::= exprlist(L) COMMA expr(E). { add_next_index_zval(L, E); R = L; }
exprlist(R) ::= expr(E). { MAKE_STD_ZVAL(R); array_init(R); add_next_index_zval(R, E); }
%destructor expr { zval_ptr_dtor(&$$); }
expr(R) ::= literal(L). { R = L; }
expr(R) ::= LABEL(L). { R = pusp_zvalize_token(&L); }
expr(R) ::= LABEL(F) LPAREN exprlist(A) RPAREN. { R = pusp_do_function(pusp_zvalize_token(&F), A); }
expr(R) ::= LPAREN expr(E) RPAREN. { R = E; }
expr(R) ::= expr(A) PLUS expr(B). { DO_MATHOP(R,A,"+",B); }
expr(R) ::= expr(A) MINUS expr(B). { DO_MATHOP(R,A,"-",B); }
expr(R) ::= expr(A) MUL expr(B). { DO_MATHOP(R,A,"*",B); }
expr(R) ::= expr(A) DIV expr(B). { DO_MATHOP(R,A,"/",B); }
expr(R) ::= expr(A) MOD expr(B). { DO_MATHOP(R,A,"%",B); }
expr(R) ::= DISTINCT expr(E). { MAKE_STD_ZVAL(R); array_init(R); add_assoc_stringl(R, "type", "distinct", sizeof("distinct") - 1, 1); add_assoc_zval(R, "distinct", E); }
%destructor intnum { zval_ptr_dtor(&$$); }
intnum(R) ::= LNUM(L). { R = pusp_zvalize_lnum(&L); }
intnum(R) ::= HNUM(H). { R = pusp_zvalize_hnum(&H); }
%destructor literal { zval_ptr_dtor(&$$); }
literal(R) ::= STRING(S). { R = pusp_zvalize_token(&S); }
literal(R) ::= intnum(I). { R = I; }
literal(R) ::= NULL. { TSRMLS_FETCH(); R = EG(uninitialized_zval_ptr); }
%destructor grouplist { zval_ptr_dtor(&$$); }
grouplist(R) ::= grouplist(L) COMMA expr(E). { add_next_index_zval(L, E); R = L; }
grouplist(R) ::= expr(E). { MAKE_STD_ZVAL(R); array_init(R); add_next_index_zval(R, E); }
%destructor orderlist { zval_ptr_dtor(&$$); }
orderlist(R) ::= orderlist(L) COMMA orderelement(E). { add_next_index_zval(L, E); R = L; }
orderlist(R) ::= orderelement(E). { MAKE_STD_ZVAL(R); array_init(R); add_next_index_zval(R, E); }
%destructor orderelement { zval_ptr_dtor(&$$); }
orderelement(R) ::= expr(E) ASC. { MAKE_STD_ZVAL(R); add_assoc_stringl(R, "direction", "asc", sizeof("asc") - 1, 1); add_assoc_zval(R, "by", E); }
orderelement(R) ::= expr(E) DESC. { MAKE_STD_ZVAL(R); add_assoc_stringl(R, "direction", "desc", sizeof("desc") - 1, 1); add_assoc_zval(R, "by", E); }
orderelement(R) ::= expr(E). { MAKE_STD_ZVAL(R); add_assoc_null(R, "direction"); add_assoc_zval(R, "by", E); }

File diff suppressed because it is too large Load Diff

View File

@@ -194,20 +194,38 @@ int php_pdo_user_sql_get_token(php_pdo_user_sql_tokenizer *t, php_pdo_user_sql_t
'on' { RET(PU_ON); }
'asc' { RET(PU_ASC); }
'desc' { RET(PU_DESC); }
'unsigned' { RET(PU_UNSIGNED); }
'zerofill' { RET(PU_ZEROFILL); }
/* SQL Types */
'int' { RET(PU_INT); }
'bit' { RET(PU_BIT); }
'int' { RET(PU_INT); }
'integer' { RET(PU_INTEGER); }
'tinyint' { RET(PU_TINYINT); }
'smallint' { RET(PU_SMALLINT); }
'mediumint' { RET(PU_MEDIUMINT); }
'bigint' { RET(PU_BIGINT); }
'char' { RET(PU_CHAR); }
'varchar' { RET(PU_VARCHAR); }
'binary' { RET(PU_BINARY); }
'varbinary' { RET(PU_VARBINARY); }
'datetime' { RET(PU_DATETIME); }
'date' { RET(PU_DATE); }
'time' { RET(PU_TIME); }
'timestamp' { RET(PU_TIMESTAMP); }
'year' { RET(PU_YEAR); }
'real' { RET(PU_REAL); }
'double' { RET(PU_DOUBLE); }
'float' { RET(PU_FLOAT); }
'decimal' { RET(PU_DECIMAL); }
'text' { RET(PU_TEXT); }
'tinytext' { RET(PU_TINYTEXT); }
'mediumtext' { RET(PU_MEDIUMTEXT); }
'longtext' { RET(PU_LONGTEXT); }
'blob' { RET(PU_BLOB); }
'tinyblob' { RET(PU_TINYBLOB); }
'mediumblob' { RET(PU_MEDIUMBLOB); }
'longblob' { RET(PU_LONGBLOB); }
'set' { RET(PU_SET); }
'enum' { RET(PU_ENUM); }
@@ -305,20 +323,38 @@ php_pdo_user_sql_token_label php_pdo_user_sql_token_labels[] = {
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_ON)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_ASC)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_DESC)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_UNSIGNED)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_ZEROFILL)
/* SQL Types */
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_INT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_BIT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_INT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_INTEGER)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_TINYINT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_SMALLINT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_MEDIUMINT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_BIGINT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_CHAR)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_VARCHAR)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_BINARY)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_VARBINARY)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_DATETIME)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_DATE)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_TIME)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_TIMESTAMP)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_YEAR)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_REAL)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_DECIMAL)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_DOUBLE)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_FLOAT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_TEXT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_TINYTEXT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_MEDIUMTEXT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_LONGTEXT)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_BLOB)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_TINYBLOB)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_MEDIUMBLOB)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_LONGBLOB)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_SET)
PHP_PDO_USER_SQL_TOKEN_LABEL_ENTRY(PU_ENUM)

View File

@@ -1,3 +1,8 @@
#ifndef PDO_USER_SQL_PARSER_H
#define PDO_USER_SQL_PARSER_H
#include "pdo_user_sql_parser.h"
#endif
typedef struct _php_pdo_user_sql_token {
unsigned char id;
char *token;
@@ -9,104 +14,19 @@ typedef struct _php_pdo_user_sql_tokenizer {
char *start, *end;
} php_pdo_user_sql_tokenizer;
enum php_pdo_user_sql_token_num {
PU_END,
PU_LABEL,
PU_STRING,
PU_WHITESPACE,
/* Verbs */
PU_SELECT,
PU_INSERT,
PU_UPDATE,
PU_DELETE,
PU_CREATE,
PU_RENAME,
PU_ALTER,
PU_GRANT,
PU_REVOKE,
PU_ADD,
PU_DROP,
/* Nouns */
PU_TABLE,
PU_VIEW,
PU_COLUMN,
PU_KEY,
PU_NULL,
PU_AUTO_INCREMENT,
PU_HNUM,
PU_LNUM,
PU_ALL,
/* Prepositions */
PU_INTO,
PU_FROM,
PU_DEFAULT,
PU_WHERE,
PU_GROUP,
PU_LIMIT,
PU_HAVING,
PU_ORDER,
PU_BY,
PU_AS,
PU_TO,
PU_VALUES,
PU_UNIQUE,
PU_PRIMARY,
PU_BEFORE,
PU_AFTER,
PU_IDENTIFIED,
PU_DISTINCT,
PU_INNER,
PU_OUTER,
PU_LEFT,
PU_RIGHT,
PU_JOIN,
PU_ON,
PU_ASC,
PU_DESC,
/* SQL Types */
PU_INT,
PU_BIT,
PU_CHAR,
PU_VARCHAR,
PU_DATETIME,
PU_DATE,
PU_TIME,
PU_TIMESTAMP,
PU_DOUBLE,
PU_FLOAT,
PU_TEXT,
PU_BLOB,
PU_SET,
PU_ENUM,
/* Logicals */
PU_NOT_EQUAL, /* != */
PU_UNEQUAL, /* <> */
PU_LESSER_EQUAL,
PU_GREATER_EQUAL,
PU_LIKE,
PU_RLIKE,
PU_NOT,
PU_AND,
PU_OR,
PU_XOR,
/* Single Character Tokens */
PU_PLUS,
PU_MINUS,
PU_MUL,
PU_DIV,
PU_MOD,
PU_LPAREN,
PU_RPAREN,
PU_COMMA,
PU_EQUALS,
PU_SEMICOLON
};
/* Tokens not identified by or used by the parser */
#define PU_END 0
#define PU_WHITESPACE 0xFF
#define PU_GRANT 0xFE
#define PU_REVOKE 0xFD
#define PU_IDENTIFIED 0xFC
#define PU_ALTER 0xFB
#define PU_ADD 0xFA
#define PU_VIEW 0xF9
#define PU_COLUMN 0xF8
#define PU_BEFORE 0xF7
#define PU_AFTER 0xF6
#define PU_ALL 0xF5
typedef struct _php_pdo_user_sql_token_label {
unsigned char id;
@@ -115,3 +35,7 @@ typedef struct _php_pdo_user_sql_token_label {
extern php_pdo_user_sql_token_label php_pdo_user_sql_token_labels[];
int php_pdo_user_sql_get_token(php_pdo_user_sql_tokenizer *t, php_pdo_user_sql_token *token);
void *php_pdo_user_sql_parserAlloc(void *(*mallocProc)(size_t));
void php_pdo_user_sql_parser(void *yyp, int yymajor, php_pdo_user_sql_token yyminor, zval *return_value);
void php_pdo_user_sql_parserFree(void *p, void (*freeProc)(void*));

View File

@@ -25,28 +25,28 @@ array(4) {
[0]=>
array(2) {
["token"]=>
int(4)
int(8)
["data"]=>
string(6) "SELECT"
}
[1]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "foo"
}
[2]=>
array(2) {
["token"]=>
int(25)
int(37)
["data"]=>
string(4) "FROM"
}
[3]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "bar"
}
@@ -56,140 +56,140 @@ array(20) {
[0]=>
array(2) {
["token"]=>
int(5)
int(9)
["data"]=>
string(6) "INSERT"
}
[1]=>
array(2) {
["token"]=>
int(24)
int(10)
["data"]=>
string(4) "INTO"
}
[2]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "bar"
}
[3]=>
array(2) {
["token"]=>
int(71)
int(31)
["data"]=>
string(1) "("
}
[4]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "foo"
}
[5]=>
array(2) {
["token"]=>
int(73)
int(11)
["data"]=>
string(1) ","
}
[6]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "baz"
}
[7]=>
array(2) {
["token"]=>
int(72)
int(28)
["data"]=>
string(1) ")"
}
[8]=>
array(2) {
["token"]=>
int(35)
int(38)
["data"]=>
string(6) "values"
}
[9]=>
array(2) {
["token"]=>
int(71)
int(31)
["data"]=>
string(1) "("
}
[10]=>
array(2) {
["token"]=>
int(22)
int(33)
["data"]=>
string(1) "1"
}
[11]=>
array(2) {
["token"]=>
int(73)
int(11)
["data"]=>
string(1) ","
}
[12]=>
array(2) {
["token"]=>
int(22)
int(33)
["data"]=>
string(1) "2"
}
[13]=>
array(2) {
["token"]=>
int(72)
int(28)
["data"]=>
string(1) ")"
}
[14]=>
array(2) {
["token"]=>
int(73)
int(11)
["data"]=>
string(1) ","
}
[15]=>
array(2) {
["token"]=>
int(71)
int(31)
["data"]=>
string(1) "("
}
[16]=>
array(2) {
["token"]=>
int(22)
int(33)
["data"]=>
string(1) "2"
}
[17]=>
array(2) {
["token"]=>
int(73)
int(11)
["data"]=>
string(1) ","
}
[18]=>
array(2) {
["token"]=>
int(22)
int(33)
["data"]=>
string(1) "3"
}
[19]=>
array(2) {
["token"]=>
int(72)
int(28)
["data"]=>
string(1) ")"
}
@@ -199,91 +199,91 @@ array(13) {
[0]=>
array(2) {
["token"]=>
int(10)
int(251)
["data"]=>
string(5) "ALTER"
}
[1]=>
array(2) {
["token"]=>
int(15)
int(43)
["data"]=>
string(5) "TABLE"
}
[2]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "bar"
}
[3]=>
array(2) {
["token"]=>
int(5)
int(9)
["data"]=>
string(6) "insert"
}
[4]=>
array(2) {
["token"]=>
int(17)
int(248)
["data"]=>
string(6) "column"
}
[5]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(5) "bling"
}
[6]=>
array(2) {
["token"]=>
int(42)
int(53)
["data"]=>
string(3) "int"
}
[7]=>
array(2) {
["token"]=>
int(62)
int(1)
["data"]=>
string(3) "not"
}
[8]=>
array(2) {
["token"]=>
int(19)
int(46)
["data"]=>
string(4) "null"
}
[9]=>
array(2) {
["token"]=>
int(26)
int(47)
["data"]=>
string(7) "default"
}
[10]=>
array(2) {
["token"]=>
int(2)
int(35)
["data"]=>
string(3) "moo"
}
[11]=>
array(2) {
["token"]=>
int(39)
int(246)
["data"]=>
string(5) "after"
}
[12]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "foo"
}
@@ -293,57 +293,57 @@ array(8) {
[0]=>
array(2) {
["token"]=>
int(4)
int(8)
["data"]=>
string(6) "SELECT"
}
[1]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "foo"
}
[2]=>
array(2) {
["token"]=>
int(25)
int(37)
["data"]=>
string(4) "FROM"
}
[3]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(3) "bar"
}
[4]=>
array(2) {
["token"]=>
int(27)
int(6)
["data"]=>
string(5) "WHERE"
}
[5]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(6) "select"
}
[6]=>
array(2) {
["token"]=>
int(74)
int(19)
["data"]=>
string(1) "="
}
[7]=>
array(2) {
["token"]=>
int(1)
int(32)
["data"]=>
string(7) "ABC 123"
}
}
}