#include "windef.h"\r
#include "winbase.h"\r
#include "query.h"\r
+#include "wine/list.h"\r
#include "wine/debug.h"\r
#include "wine/unicode.h"\r
\r
LPCWSTR command;\r
DWORD n, len;\r
MSIVIEW **view; /* view structure for the resulting query */\r
+ struct list *mem;\r
} SQL_input;\r
\r
-static LPWSTR SQL_getstring( struct sql_str *str );\r
-static INT SQL_getint( SQL_input *sql );\r
-static int SQL_lex( void *SQL_lval, SQL_input *info);\r
+static LPWSTR SQL_getstring( void *info, struct sql_str *str );\r
+static INT SQL_getint( void *info );\r
+static int SQL_lex( void *SQL_lval, SQL_input *info );\r
\r
-static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in, \r
- string_list *columns );\r
-static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in, \r
- string_list *columns );\r
+static void *parser_alloc( void *info, unsigned int sz );\r
\r
-static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,\r
- string_list *keys);\r
+static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, string_list *keys);\r
\r
-static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );\r
-static struct expr * EXPR_column( LPWSTR );\r
-static struct expr * EXPR_ival( struct sql_str *, int sign);\r
-static struct expr * EXPR_sval( struct sql_str *);\r
-static struct expr * EXPR_wildcard();\r
+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );\r
+static struct expr * EXPR_column( void *info, LPWSTR column );\r
+static struct expr * EXPR_ival( void *info, struct sql_str *, int sign );\r
+static struct expr * EXPR_sval( void *info, struct sql_str * );\r
+static struct expr * EXPR_wildcard( void *info );\r
\r
%}\r
\r
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION\r
COLUMN AGG_FUNCTION.\r
\r
-%type <string> column table string_or_id\r
+%type <string> column table id\r
%type <column_list> selcollist\r
-%type <query> from unorderedsel oneselect onequery onecreate oneinsert\r
-%type <query> oneupdate onedelete\r
+%type <query> query from fromtable unorderedsel selectfrom\r
+%type <query> oneupdate onedelete oneselect onequery onecreate oneinsert\r
%type <expr> expr val column_val const_val\r
%type <column_type> column_type data_type data_type_l data_count\r
%type <column_info> column_def table_def\r
\r
%%\r
\r
-onequery:\r
- oneselect\r
+query:\r
+ onequery\r
{\r
SQL_input* sql = (SQL_input*) info;\r
*sql->view = $1;\r
}\r
+ ;\r
+\r
+onequery:\r
+ oneselect\r
| onecreate\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- *sql->view = $1;\r
- }\r
| oneinsert\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- *sql->view = $1;\r
- }\r
| oneupdate\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- *sql->view = $1;\r
- }\r
| onedelete\r
- {\r
- SQL_input* sql = (SQL_input*) info;\r
- *sql->view = $1;\r
- }\r
;\r
\r
oneinsert:\r
TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP\r
- {\r
- SQL_input *sql = (SQL_input*) info;\r
- MSIVIEW *insert = NULL; \r
+ {\r
+ SQL_input *sql = (SQL_input*) info;\r
+ MSIVIEW *insert = NULL; \r
+ UINT r;\r
\r
- INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE ); \r
- $$ = insert;\r
- }\r
+ r = INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE ); \r
+ if( !insert )\r
+ YYABORT;\r
+ $$ = insert;\r
+ }\r
| TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMP\r
- {\r
- SQL_input *sql = (SQL_input*) info;\r
- MSIVIEW *insert = NULL; \r
+ {\r
+ SQL_input *sql = (SQL_input*) info;\r
+ MSIVIEW *insert = NULL; \r
\r
- INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE ); \r
- $$ = insert;\r
- }\r
+ INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE ); \r
+ if( !insert )\r
+ YYABORT;\r
+ $$ = insert;\r
+ }\r
;\r
\r
onecreate:\r
if( !$5 )\r
YYABORT;\r
CREATE_CreateView( sql->db, &create, $3, $5, FALSE );\r
+ if( !create )\r
+ YYABORT;\r
$$ = create;\r
}\r
| TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD\r
if( !$5 )\r
YYABORT;\r
CREATE_CreateView( sql->db, &create, $3, $5, TRUE );\r
+ if( !create )\r
+ YYABORT;\r
$$ = create;\r
}\r
;\r
MSIVIEW *update = NULL; \r
\r
UPDATE_CreateView( sql->db, &update, $2, &$4, $6 );\r
+ if( !update )\r
+ YYABORT;\r
$$ = update;\r
}\r
;\r
MSIVIEW *delete = NULL; \r
\r
DELETE_CreateView( sql->db, &delete, $2 );\r
+ if( !delete )\r
+ YYABORT;\r
$$ = delete;\r
}\r
;\r
{\r
SQL_input* sql = (SQL_input*) info;\r
\r
- if( !$1 )\r
- YYABORT;\r
+ $$ = NULL;\r
if( $4 )\r
- $$ = do_order_by( sql->db, $1, $4 );\r
+ ORDER_CreateView( sql->db, &$$, $1, $4 );\r
else\r
$$ = $1;\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| unorderedsel\r
;\r
\r
unorderedsel:\r
- TK_SELECT selcollist from \r
+ TK_SELECT selectfrom\r
+ {\r
+ $$ = $2;\r
+ }\r
+ | TK_SELECT TK_DISTINCT selectfrom\r
{\r
SQL_input* sql = (SQL_input*) info;\r
- if( !$3 )\r
+\r
+ $$ = NULL;\r
+ DISTINCT_CreateView( sql->db, &$$, $3 );\r
+ if( !$$ )\r
YYABORT;\r
- if( $2 )\r
- {\r
- $$ = do_one_select( sql->db, $3, $2 );\r
- if( !$$ )\r
- YYABORT;\r
- }\r
- else\r
- $$ = $3;\r
}\r
- | TK_SELECT TK_DISTINCT selcollist from \r
+ ;\r
+\r
+selectfrom:\r
+ selcollist from \r
{\r
SQL_input* sql = (SQL_input*) info;\r
- MSIVIEW *view = $4;\r
\r
- if( !view )\r
+ $$ = NULL;\r
+ if( $1 )\r
+ SELECT_CreateView( sql->db, &$$, $2, $1 );\r
+ else\r
+ $$ = $2;\r
+\r
+ if( !$$ )\r
YYABORT;\r
- if( $3 )\r
- {\r
- view = do_one_select( sql->db, view, $3 );\r
- if( !view )\r
- YYABORT;\r
- }\r
- DISTINCT_CreateView( sql->db, & $$, view );\r
}\r
;\r
\r
;\r
\r
from:\r
- TK_FROM table\r
+ fromtable\r
+ | fromtable TK_WHERE expr\r
{ \r
SQL_input* sql = (SQL_input*) info;\r
UINT r;\r
\r
$$ = NULL;\r
- TRACE("From table: %s\n",debugstr_w($2));\r
- r = TABLE_CreateView( sql->db, $2, & $$ );\r
- if( r != ERROR_SUCCESS )\r
+ r = WHERE_CreateView( sql->db, &$$, $1, $3 );\r
+ if( r != ERROR_SUCCESS || !$$ )\r
YYABORT;\r
}\r
- | TK_FROM table TK_WHERE expr\r
- { \r
+ ;\r
+\r
+fromtable:\r
+ TK_FROM table\r
+ {\r
SQL_input* sql = (SQL_input*) info;\r
- MSIVIEW *view = NULL;\r
UINT r;\r
\r
$$ = NULL;\r
- TRACE("From table: %s\n",debugstr_w($2));\r
- r = TABLE_CreateView( sql->db, $2, &view );\r
- if( r != ERROR_SUCCESS )\r
- YYABORT;\r
- r = WHERE_CreateView( sql->db, &view, view, $4 );\r
- if( r != ERROR_SUCCESS )\r
+ r = TABLE_CreateView( sql->db, $2, &$$ );\r
+ if( r != ERROR_SUCCESS || !$$ )\r
YYABORT;\r
- $$ = view;\r
}\r
;\r
\r
TK_LP expr TK_RP\r
{\r
$$ = $2;\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_EQ column_val\r
{\r
- $$ = EXPR_complex( $1, OP_EQ, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_EQ, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| expr TK_AND expr\r
{\r
- $$ = EXPR_complex( $1, OP_AND, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_AND, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| expr TK_OR expr\r
{\r
- $$ = EXPR_complex( $1, OP_OR, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_OR, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_EQ val\r
{\r
- $$ = EXPR_complex( $1, OP_EQ, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_EQ, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_GT val\r
{\r
- $$ = EXPR_complex( $1, OP_GT, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_GT, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_LT val\r
{\r
- $$ = EXPR_complex( $1, OP_LT, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_LT, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_LE val\r
{\r
- $$ = EXPR_complex( $1, OP_LE, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_LE, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_GE val\r
{\r
- $$ = EXPR_complex( $1, OP_GE, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_GE, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_NE val\r
{\r
- $$ = EXPR_complex( $1, OP_NE, $3 );\r
+ $$ = EXPR_complex( info, $1, OP_NE, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_IS TK_NULL\r
{\r
- $$ = EXPR_complex( $1, OP_ISNULL, NULL );\r
+ $$ = EXPR_complex( info, $1, OP_ISNULL, NULL );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| column_val TK_IS TK_NOT TK_NULL\r
{\r
- $$ = EXPR_complex( $1, OP_NOTNULL, NULL );\r
+ $$ = EXPR_complex( info, $1, OP_NOTNULL, NULL );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
;\r
\r
{\r
value_list *vals;\r
\r
- vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals );\r
- if( vals )\r
- {\r
- vals->val = $1;\r
- vals->next = NULL;\r
- }\r
+ vals = parser_alloc( info, sizeof *vals );\r
+ if( !vals )\r
+ YYABORT;\r
+ vals->val = $1;\r
+ vals->next = NULL;\r
$$ = vals;\r
}\r
| const_val TK_COMMA constlist\r
{\r
value_list *vals;\r
\r
- vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals );\r
- if( vals )\r
- {\r
- vals->val = $1;\r
- vals->next = $3;\r
- }\r
+ vals = parser_alloc( info, sizeof *vals );\r
+ if( !vals )\r
+ YYABORT;\r
+ vals->val = $1;\r
+ vals->next = $3;\r
$$ = vals;\r
}\r
;\r
const_val:\r
TK_INTEGER\r
{\r
- $$ = EXPR_ival( &$1, 1 );\r
+ $$ = EXPR_ival( info, &$1, 1 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| TK_MINUS TK_INTEGER\r
{\r
- $$ = EXPR_ival( &$2, -1 );\r
+ $$ = EXPR_ival( info, &$2, -1 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| TK_STRING\r
{\r
- $$ = EXPR_sval( &$1 );\r
+ $$ = EXPR_sval( info, &$1 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| TK_WILDCARD\r
{\r
- $$ = EXPR_wildcard();\r
+ $$ = EXPR_wildcard( info );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
;\r
\r
column_val:\r
column \r
{\r
- $$ = EXPR_column( $1 );\r
+ $$ = EXPR_column( info, $1 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
;\r
\r
column:\r
- table TK_DOT string_or_id\r
+ table TK_DOT id\r
{\r
$$ = $3; /* FIXME */\r
}\r
- | string_or_id\r
+ | id\r
{\r
$$ = $1;\r
}\r
;\r
\r
table:\r
- string_or_id\r
+ id\r
{\r
$$ = $1;\r
}\r
;\r
\r
-string_or_id:\r
+id:\r
TK_ID\r
{\r
- $$ = SQL_getstring( &$1 );\r
- }\r
- | TK_STRING\r
- {\r
- $$ = SQL_getstring( &$1 );\r
+ $$ = SQL_getstring( info, &$1 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
;\r
\r
%%\r
\r
-int SQL_lex( void *SQL_lval, SQL_input *sql)\r
+static void *parser_alloc( void *info, unsigned int sz )\r
+{\r
+ SQL_input* sql = (SQL_input*) info;\r
+ struct list *mem;\r
+\r
+ mem = HeapAlloc( GetProcessHeap(), 0, sizeof (struct list) + sz );\r
+ list_add_tail( sql->mem, mem );\r
+ return &mem[1];\r
+}\r
+\r
+int SQL_lex( void *SQL_lval, SQL_input *sql )\r
{\r
int token;\r
struct sql_str * str = SQL_lval;\r
return token;\r
}\r
\r
-LPWSTR SQL_getstring( struct sql_str *strdata)\r
+LPWSTR SQL_getstring( void *info, struct sql_str *strdata )\r
{\r
LPCWSTR p = strdata->data;\r
UINT len = strdata->len;\r
p++;\r
len -= 2;\r
}\r
- str = HeapAlloc( GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));\r
- if(!str )\r
+ str = parser_alloc( info, (len + 1)*sizeof(WCHAR) );\r
+ if( !str )\r
return str;\r
- memcpy(str, p, len*sizeof(WCHAR) );\r
+ memcpy( str, p, len*sizeof(WCHAR) );\r
str[len]=0;\r
\r
return str;\r
}\r
\r
-INT SQL_getint( SQL_input *sql )\r
+INT SQL_getint( void *info )\r
{\r
+ SQL_input* sql = (SQL_input*) info;\r
LPCWSTR p = &sql->command[sql->n];\r
\r
return atoiW( p );\r
}\r
\r
-int SQL_error(const char *str)\r
+int SQL_error( const char *str )\r
{\r
return 0;\r
}\r
\r
-static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in, \r
- string_list *columns )\r
-{\r
- MSIVIEW *view = NULL;\r
-\r
- SELECT_CreateView( db, &view, in, columns );\r
- delete_string_list( columns );\r
- if( !view )\r
- ERR("Error creating select query\n");\r
- return view;\r
-}\r
-\r
-static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in, \r
- string_list *columns )\r
+static struct expr * EXPR_wildcard( void *info )\r
{\r
- MSIVIEW *view = NULL;\r
-\r
- ORDER_CreateView( db, &view, in );\r
- if( view )\r
- {\r
- string_list *x = columns;\r
-\r
- for( x = columns; x ; x = x->next )\r
- ORDER_AddColumn( view, x->string );\r
- }\r
- else\r
- ERR("Error creating select query\n");\r
- delete_string_list( columns );\r
- return view;\r
-}\r
-\r
-static struct expr * EXPR_wildcard()\r
-{\r
- struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );\r
+ struct expr *e = parser_alloc( info, sizeof *e );\r
if( e )\r
{\r
e->type = EXPR_WILDCARD;\r
return e;\r
}\r
\r
-static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r )\r
+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r )\r
{\r
- struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );\r
+ struct expr *e = parser_alloc( info, sizeof *e );\r
if( e )\r
{\r
e->type = EXPR_COMPLEX;\r
return e;\r
}\r
\r
-static struct expr * EXPR_column( LPWSTR str )\r
+static struct expr * EXPR_column( void *info, LPWSTR column )\r
{\r
- struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );\r
+ struct expr *e = parser_alloc( info, sizeof *e );\r
if( e )\r
{\r
e->type = EXPR_COLUMN;\r
- e->u.sval = str;\r
+ e->u.sval = column;\r
}\r
return e;\r
}\r
\r
-static struct expr * EXPR_ival( struct sql_str *str , int sign)\r
+static struct expr * EXPR_ival( void *info, struct sql_str *str, int sign )\r
{\r
- struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );\r
+ struct expr *e = parser_alloc( info, sizeof *e );\r
if( e )\r
{\r
e->type = EXPR_IVAL;\r
return e;\r
}\r
\r
-static struct expr * EXPR_sval( struct sql_str *str )\r
+static struct expr * EXPR_sval( void *info, struct sql_str *str )\r
{\r
- struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );\r
+ struct expr *e = parser_alloc( info, sizeof *e );\r
if( e )\r
{\r
e->type = EXPR_SVAL;\r
- e->u.sval = SQL_getstring( str );\r
+ e->u.sval = SQL_getstring( info, str );\r
}\r
return e;\r
}\r
\r
-void delete_expr( struct expr *e )\r
-{\r
- if( !e )\r
- return;\r
- if( e->type == EXPR_COMPLEX )\r
- {\r
- delete_expr( e->u.expr.left );\r
- delete_expr( e->u.expr.right );\r
- }\r
- else if( e->type == EXPR_UTF8 )\r
- HeapFree( GetProcessHeap(), 0, e->u.utf8 );\r
- else if( e->type == EXPR_SVAL )\r
- HeapFree( GetProcessHeap(), 0, e->u.sval );\r
- HeapFree( GetProcessHeap(), 0, e );\r
-}\r
-\r
-void delete_string_list( string_list *sl )\r
-{\r
- while( sl )\r
- {\r
- string_list *t = sl->next;\r
- HeapFree( GetProcessHeap(), 0, sl->string );\r
- HeapFree( GetProcessHeap(), 0, sl );\r
- sl = t;\r
- }\r
-}\r
-\r
-void delete_value_list( value_list *vl )\r
-{\r
- while( vl )\r
- {\r
- value_list *t = vl->next;\r
- delete_expr( vl->val );\r
- HeapFree( GetProcessHeap(), 0, vl );\r
- vl = t;\r
- }\r
-}\r
-\r
-static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,\r
- string_list *keys )\r
+static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, string_list *keys)\r
{\r
string_list *k;\r
BOOL found = TRUE;\r
return found;\r
}\r
\r
-UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview )\r
+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,\r
+ struct list *mem )\r
{\r
SQL_input sql;\r
int r;\r
sql.n = 0;\r
sql.len = 0;\r
sql.view = phview;\r
+ sql.mem = mem;\r
\r
r = SQL_parse(&sql);\r
\r