mirror of
https://github.com/php/pecl-database-pdo_user.git
synced 2026-03-23 22:42:10 +01:00
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:
@@ -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
|
||||
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
|
||||
@@ -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
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
94
pdo_user_sql_parser.h
Normal 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
532
pdo_user_sql_parser.lemon
Normal 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
@@ -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)
|
||||
|
||||
|
||||
@@ -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*));
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user