Add and correct some function declarations.
[wine] / dlls / msi / sql.y
1 %{
2
3 /*
4  * Implementation of the Microsoft Installer (msi.dll)
5  *
6  * Copyright 2002-2004 Mike McCormack for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23
24 #include "config.h"
25
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "query.h"
33 #include "wine/list.h"
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36
37 #define YYLEX_PARAM info
38 #define YYPARSE_PARAM info
39
40 extern int SQL_error(const char *str);
41
42 WINE_DEFAULT_DEBUG_CHANNEL(msi);
43
44 typedef struct tag_SQL_input
45 {
46     MSIDATABASE *db;
47     LPCWSTR command;
48     DWORD n, len;
49     MSIVIEW **view;  /* view structure for the resulting query */
50     struct list *mem;
51 } SQL_input;
52
53 static LPWSTR SQL_getstring( void *info, struct sql_str *str );
54 static INT SQL_getint( void *info );
55 static int SQL_lex( void *SQL_lval, SQL_input *info );
56
57 static void *parser_alloc( void *info, unsigned int sz );
58 static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column );
59
60 static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys);
61
62 static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );
63 static struct expr * EXPR_column( void *info, column_info *column );
64 static struct expr * EXPR_ival( void *info, struct sql_str *, int sign );
65 static struct expr * EXPR_sval( void *info, struct sql_str * );
66 static struct expr * EXPR_wildcard( void *info );
67
68 %}
69
70 %pure-parser
71
72 %union
73 {
74     struct sql_str str;
75     LPWSTR string;
76     column_info *column_list;
77     value_list *val_list;
78     MSIVIEW *query;
79     struct expr *expr;
80     USHORT column_type;
81 }
82
83 %token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_AND TK_AS TK_ASC
84 %token TK_BEFORE TK_BEGIN TK_BETWEEN TK_BITAND TK_BITNOT TK_BITOR TK_BY
85 %token TK_CASCADE TK_CASE TK_CHAR TK_CHECK TK_CLUSTER TK_COLLATE TK_COLUMN
86 %token TK_COMMA TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT 
87 %token TK_CONSTRAINT TK_COPY TK_CREATE
88 %token TK_DEFAULT TK_DEFERRABLE TK_DEFERRED TK_DELETE TK_DELIMITERS TK_DESC
89 %token TK_DISTINCT TK_DOT TK_DROP TK_EACH
90 %token TK_ELSE TK_END TK_END_OF_FILE TK_EQ TK_EXCEPT TK_EXPLAIN
91 %token TK_FAIL TK_FLOAT TK_FOR TK_FOREIGN TK_FROM TK_FUNCTION
92 %token TK_GE TK_GLOB TK_GROUP TK_GT
93 %token TK_HAVING TK_HOLD
94 %token TK_IGNORE TK_ILLEGAL TK_IMMEDIATE TK_IN TK_INDEX TK_INITIALLY
95 %token <str> TK_ID 
96 %token TK_INSERT TK_INSTEAD TK_INT 
97 %token <str> TK_INTEGER
98 %token TK_INTERSECT TK_INTO TK_IS
99 %token TK_ISNULL
100 %token TK_JOIN TK_JOIN_KW
101 %token TK_KEY
102 %token TK_LE TK_LIKE TK_LIMIT TK_LONG TK_LONGCHAR TK_LP TK_LSHIFT TK_LT
103 %token TK_LOCALIZABLE
104 %token TK_MATCH TK_MINUS
105 %token TK_NE TK_NOT TK_NOTNULL TK_NULL
106 %token TK_OBJECT TK_OF TK_OFFSET TK_ON TK_OR TK_ORACLE_OUTER_JOIN TK_ORDER
107 %token TK_PLUS TK_PRAGMA TK_PRIMARY
108 %token TK_RAISE TK_REFERENCES TK_REM TK_REPLACE TK_RESTRICT TK_ROLLBACK
109 %token TK_ROW TK_RP TK_RSHIFT
110 %token TK_SELECT TK_SEMI TK_SET TK_SHORT TK_SLASH TK_SPACE TK_STAR TK_STATEMENT 
111 %token <str> TK_STRING
112 %token TK_TABLE TK_TEMP TK_THEN TK_TRANSACTION TK_TRIGGER
113 %token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE
114 %token TK_UPDATE TK_UPLUS TK_USING
115 %token TK_VACUUM TK_VALUES TK_VIEW
116 %token TK_WHEN TK_WHERE TK_WILDCARD
117
118 /*
119  * These are extra tokens used by the lexer but never seen by the
120  * parser.  We put them in a rule so that the parser generator will
121  * add them to the parse.h output file.
122  *
123  */
124 %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
125           COLUMN AGG_FUNCTION.
126
127 %type <string> table id
128 %type <column_list> selcollist column column_and_type column_def table_def
129 %type <column_list> column_assignment update_assign_list
130 %type <query> query from fromtable selectfrom unorderedsel
131 %type <query> oneupdate onedelete oneselect onequery onecreate oneinsert
132 %type <expr> expr val column_val const_val
133 %type <column_type> column_type data_type data_type_l data_count
134 %type <val_list> constlist
135
136 %%
137
138 query:
139     onequery
140     {
141         SQL_input* sql = (SQL_input*) info;
142         *sql->view = $1;
143     }
144     ;
145
146 onequery:
147     oneselect
148   | onecreate
149   | oneinsert
150   | oneupdate
151   | onedelete
152     ;
153
154 oneinsert:
155     TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP
156         {
157             SQL_input *sql = (SQL_input*) info;
158             MSIVIEW *insert = NULL; 
159             UINT r;
160
161             r = INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE ); 
162             if( !insert )
163                 YYABORT;
164             $$ = insert;
165         }
166   | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMP
167         {
168             SQL_input *sql = (SQL_input*) info;
169             MSIVIEW *insert = NULL; 
170
171             INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE ); 
172             if( !insert )
173                 YYABORT;
174             $$ = insert;
175         }
176     ;
177
178 onecreate:
179     TK_CREATE TK_TABLE table TK_LP table_def TK_RP
180         {
181             SQL_input* sql = (SQL_input*) info;
182             MSIVIEW *create = NULL; 
183
184             if( !$5 )
185                 YYABORT;
186             CREATE_CreateView( sql->db, &create, $3, $5, FALSE );
187             if( !create )
188                 YYABORT;
189             $$ = create;
190         }
191   | TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD
192         {
193             SQL_input* sql = (SQL_input*) info;
194             MSIVIEW *create = NULL; 
195
196             if( !$5 )
197                 YYABORT;
198             CREATE_CreateView( sql->db, &create, $3, $5, TRUE );
199             if( !create )
200                 YYABORT;
201             $$ = create;
202         }
203     ;
204
205 oneupdate:
206     TK_UPDATE table TK_SET update_assign_list TK_WHERE expr
207         {
208             SQL_input* sql = (SQL_input*) info;
209             MSIVIEW *update = NULL; 
210
211             UPDATE_CreateView( sql->db, &update, $2, $4, $6 );
212             if( !update )
213                 YYABORT;
214             $$ = update;
215         }
216     ;
217
218 onedelete:
219     TK_DELETE from
220         {
221             SQL_input* sql = (SQL_input*) info;
222             MSIVIEW *delete = NULL; 
223
224             DELETE_CreateView( sql->db, &delete, $2 );
225             if( !delete )
226                 YYABORT;
227             $$ = delete;
228         }
229     ;
230
231 table_def:
232     column_def TK_PRIMARY TK_KEY selcollist
233         {
234             if( SQL_MarkPrimaryKeys( $1, $4 ) )
235                 $$ = $1;
236             else
237                 $$ = NULL;
238         }
239     ;
240
241 column_def:
242     column_def TK_COMMA column_and_type
243         {
244             column_info *ci;
245
246             for( ci = $1; ci->next; ci = ci->next )
247                 ;
248
249             ci->next = $3;
250             $$ = $1;
251         }
252   | column_and_type
253         {
254             $$ = $1;
255         }
256     ;
257
258 column_and_type:
259     column column_type
260         {
261             $$ = $1;
262             $$->type = $2;
263         }
264     ;
265
266 column_type:
267     data_type_l
268         {
269             $$ = $1 | MSITYPE_VALID;
270         }
271   | data_type_l TK_LOCALIZABLE
272         {
273             FIXME("LOCALIZABLE ignored\n");
274             $$ = $1 | MSITYPE_VALID;
275         }
276     ;
277
278 data_type_l:
279     data_type
280         {
281             $$ |= MSITYPE_NULLABLE;
282         }
283   | data_type TK_NOT TK_NULL
284         {
285             $$ = $1;
286         }
287     ;
288
289 data_type:
290     TK_CHAR
291         {
292             $$ = MSITYPE_STRING | 1;
293         }
294   | TK_CHAR TK_LP data_count TK_RP
295         {
296             $$ = MSITYPE_STRING | 0x400 | $3;
297         }
298   | TK_LONGCHAR
299         {
300             $$ = 2;
301         }
302   | TK_SHORT
303         {
304             $$ = 2;
305         }
306   | TK_INT
307         {
308             $$ = 2;
309         }
310   | TK_LONG
311         {
312             $$ = 4;
313         }
314   | TK_OBJECT
315         {
316             $$ = 0;
317         }
318     ;
319
320 data_count:
321     TK_INTEGER
322         {
323             SQL_input* sql = (SQL_input*) info;
324             int val = SQL_getint(sql);
325             if( ( val > 255 ) || ( val < 0 ) )
326                 YYABORT;
327             $$ = val;
328         }
329     ;
330
331 oneselect:
332     unorderedsel TK_ORDER TK_BY selcollist
333         {
334             SQL_input* sql = (SQL_input*) info;
335
336             $$ = NULL;
337             if( $4 )
338                 ORDER_CreateView( sql->db, &$$, $1, $4 );
339             else
340                 $$ = $1;
341             if( !$$ )
342                 YYABORT;
343         }
344   | unorderedsel
345     ;
346
347 unorderedsel:
348     TK_SELECT selectfrom
349         {
350             $$ = $2;
351         }
352   | TK_SELECT TK_DISTINCT selectfrom
353         {
354             SQL_input* sql = (SQL_input*) info;
355
356             $$ = NULL;
357             DISTINCT_CreateView( sql->db, &$$, $3 );
358             if( !$$ )
359                 YYABORT;
360         }
361     ;
362
363 selectfrom:
364     selcollist from 
365         {
366             SQL_input* sql = (SQL_input*) info;
367
368             $$ = NULL;
369             if( $1 )
370                 SELECT_CreateView( sql->db, &$$, $2, $1 );
371             else
372                 $$ = $2;
373
374             if( !$$ )
375                 YYABORT;
376         }
377     ;
378
379 selcollist:
380     column 
381   | column TK_COMMA selcollist
382         { 
383             $1->next = $3;
384         }
385   | TK_STAR
386         {
387             $$ = NULL;
388         }
389     ;
390
391 from:
392     fromtable
393   | fromtable TK_WHERE expr
394         { 
395             SQL_input* sql = (SQL_input*) info;
396             UINT r;
397
398             $$ = NULL;
399             r = WHERE_CreateView( sql->db, &$$, $1, $3 );
400             if( r != ERROR_SUCCESS || !$$ )
401                 YYABORT;
402         }
403     ;
404
405 fromtable:
406     TK_FROM table
407         {
408             SQL_input* sql = (SQL_input*) info;
409             UINT r;
410
411             $$ = NULL;
412             r = TABLE_CreateView( sql->db, $2, &$$ );
413             if( r != ERROR_SUCCESS || !$$ )
414                 YYABORT;
415         }
416     ;
417
418 expr:
419     TK_LP expr TK_RP
420         {
421             $$ = $2;
422             if( !$$ )
423                 YYABORT;
424         }
425   | column_val TK_EQ column_val
426         {
427             $$ = EXPR_complex( info, $1, OP_EQ, $3 );
428             if( !$$ )
429                 YYABORT;
430         }
431   | expr TK_AND expr
432         {
433             $$ = EXPR_complex( info, $1, OP_AND, $3 );
434             if( !$$ )
435                 YYABORT;
436         }
437   | expr TK_OR expr
438         {
439             $$ = EXPR_complex( info, $1, OP_OR, $3 );
440             if( !$$ )
441                 YYABORT;
442         }
443   | column_val TK_EQ val
444         {
445             $$ = EXPR_complex( info, $1, OP_EQ, $3 );
446             if( !$$ )
447                 YYABORT;
448         }
449   | column_val TK_GT val
450         {
451             $$ = EXPR_complex( info, $1, OP_GT, $3 );
452             if( !$$ )
453                 YYABORT;
454         }
455   | column_val TK_LT val
456         {
457             $$ = EXPR_complex( info, $1, OP_LT, $3 );
458             if( !$$ )
459                 YYABORT;
460         }
461   | column_val TK_LE val
462         {
463             $$ = EXPR_complex( info, $1, OP_LE, $3 );
464             if( !$$ )
465                 YYABORT;
466         }
467   | column_val TK_GE val
468         {
469             $$ = EXPR_complex( info, $1, OP_GE, $3 );
470             if( !$$ )
471                 YYABORT;
472         }
473   | column_val TK_NE val
474         {
475             $$ = EXPR_complex( info, $1, OP_NE, $3 );
476             if( !$$ )
477                 YYABORT;
478         }
479   | column_val TK_IS TK_NULL
480         {
481             $$ = EXPR_complex( info, $1, OP_ISNULL, NULL );
482             if( !$$ )
483                 YYABORT;
484         }
485   | column_val TK_IS TK_NOT TK_NULL
486         {
487             $$ = EXPR_complex( info, $1, OP_NOTNULL, NULL );
488             if( !$$ )
489                 YYABORT;
490         }
491     ;
492
493 val:
494     column_val
495   | const_val
496     ;
497
498 constlist:
499     const_val
500         {
501             value_list *vals;
502
503             vals = parser_alloc( info, sizeof *vals );
504             if( !vals )
505                 YYABORT;
506             vals->val = $1;
507             vals->next = NULL;
508             $$ = vals;
509         }
510   | const_val TK_COMMA constlist
511         {
512             value_list *vals;
513
514             vals = parser_alloc( info, sizeof *vals );
515             if( !vals )
516                 YYABORT;
517             vals->val = $1;
518             vals->next = $3;
519             $$ = vals;
520         }
521     ;
522
523 update_assign_list:
524     column_assignment
525   | column_assignment TK_COMMA update_assign_list
526         {
527             $$ = $1;
528             $$->next = $3;
529         }
530     ;
531
532 column_assignment:
533     column TK_EQ const_val
534         {
535             $$ = $1;
536             $$->val = $3;
537         }
538     ;
539
540 const_val:
541     TK_INTEGER
542         {
543             $$ = EXPR_ival( info, &$1, 1 );
544             if( !$$ )
545                 YYABORT;
546         }
547   | TK_MINUS  TK_INTEGER
548         {
549             $$ = EXPR_ival( info, &$2, -1 );
550             if( !$$ )
551                 YYABORT;
552         }
553   | TK_STRING
554         {
555             $$ = EXPR_sval( info, &$1 );
556             if( !$$ )
557                 YYABORT;
558         }
559   | TK_WILDCARD
560         {
561             $$ = EXPR_wildcard( info );
562             if( !$$ )
563                 YYABORT;
564         }
565     ;
566
567 column_val:
568     column 
569         {
570             $$ = EXPR_column( info, $1 );
571             if( !$$ )
572                 YYABORT;
573         }
574     ;
575
576 column:
577     table TK_DOT id
578         {
579             $$ = parser_alloc_column( info, $1, $3 );
580             if( !$$ )
581                 YYABORT;
582         }
583   | id
584         {
585             $$ = parser_alloc_column( info, NULL, $1 );
586             if( !$$ )
587                 YYABORT;
588         }
589     ;
590
591 table:
592     id
593         {
594             $$ = $1;
595         }
596     ;
597
598 id:
599     TK_ID
600         {
601             $$ = SQL_getstring( info, &$1 );
602             if( !$$ )
603                 YYABORT;
604         }
605     ;
606
607 %%
608
609 static void *parser_alloc( void *info, unsigned int sz )
610 {
611     SQL_input* sql = (SQL_input*) info;
612     struct list *mem;
613
614     mem = HeapAlloc( GetProcessHeap(), 0, sizeof (struct list) + sz );
615     list_add_tail( sql->mem, mem );
616     return &mem[1];
617 }
618
619 static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column )
620 {
621     column_info *col;
622
623     col = parser_alloc( info, sizeof (*col) );
624     if( col )
625     {
626         col->table = table;
627         col->column = column;
628         col->val = NULL;
629         col->type = 0;
630         col->next = NULL;
631     }
632
633     return col;
634 }
635
636 int SQL_lex( void *SQL_lval, SQL_input *sql )
637 {
638     int token;
639     struct sql_str * str = SQL_lval;
640
641     do
642     {
643         sql->n += sql->len;
644         if( ! sql->command[sql->n] )
645             return 0;  /* end of input */
646
647         TRACE("string : %s\n", debugstr_w(&sql->command[sql->n]));
648         sql->len = sqliteGetToken( &sql->command[sql->n], &token );
649         if( sql->len==0 )
650             break;
651         str->data = &sql->command[sql->n];
652         str->len = sql->len;
653     }
654     while( token == TK_SPACE );
655
656     TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len));
657     
658     return token;
659 }
660
661 LPWSTR SQL_getstring( void *info, struct sql_str *strdata )
662 {
663     LPCWSTR p = strdata->data;
664     UINT len = strdata->len;
665     LPWSTR str;
666
667     /* if there's quotes, remove them */
668     if( ( (p[0]=='`') && (p[len-1]=='`') ) || 
669         ( (p[0]=='\'') && (p[len-1]=='\'') ) )
670     {
671         p++;
672         len -= 2;
673     }
674     str = parser_alloc( info, (len + 1)*sizeof(WCHAR) );
675     if( !str )
676         return str;
677     memcpy( str, p, len*sizeof(WCHAR) );
678     str[len]=0;
679
680     return str;
681 }
682
683 INT SQL_getint( void *info )
684 {
685     SQL_input* sql = (SQL_input*) info;
686     LPCWSTR p = &sql->command[sql->n];
687
688     return atoiW( p );
689 }
690
691 int SQL_error( const char *str )
692 {
693     return 0;
694 }
695
696 static struct expr * EXPR_wildcard( void *info )
697 {
698     struct expr *e = parser_alloc( info, sizeof *e );
699     if( e )
700     {
701         e->type = EXPR_WILDCARD;
702     }
703     return e;
704 }
705
706 static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r )
707 {
708     struct expr *e = parser_alloc( info, sizeof *e );
709     if( e )
710     {
711         e->type = EXPR_COMPLEX;
712         e->u.expr.left = l;
713         e->u.expr.op = op;
714         e->u.expr.right = r;
715     }
716     return e;
717 }
718
719 static struct expr * EXPR_column( void *info, column_info *column )
720 {
721     struct expr *e = parser_alloc( info, sizeof *e );
722     if( e )
723     {
724         e->type = EXPR_COLUMN;
725         e->u.sval = column->column;
726     }
727     return e;
728 }
729
730 static struct expr * EXPR_ival( void *info, struct sql_str *str, int sign )
731 {
732     struct expr *e = parser_alloc( info, sizeof *e );
733     if( e )
734     {
735         e->type = EXPR_IVAL;
736         e->u.ival = atoiW( str->data ) * sign;
737     }
738     return e;
739 }
740
741 static struct expr * EXPR_sval( void *info, struct sql_str *str )
742 {
743     struct expr *e = parser_alloc( info, sizeof *e );
744     if( e )
745     {
746         e->type = EXPR_SVAL;
747         e->u.sval = SQL_getstring( info, str );
748     }
749     return e;
750 }
751
752 static BOOL SQL_MarkPrimaryKeys( column_info *cols,
753                                  column_info *keys )
754 {
755     column_info *k;
756     BOOL found = TRUE;
757
758     for( k = keys; k && found; k = k->next )
759     {
760         column_info *c;
761
762         found = FALSE;
763         for( c = cols; c && !found; c = c->next )
764         {
765              if( lstrcmpW( k->column, c->column ) )
766                  continue;
767              c->type |= MSITYPE_KEY;
768              found = TRUE;
769         }
770     }
771
772     return found;
773 }
774
775 UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,
776                    struct list *mem )
777 {
778     SQL_input sql;
779     int r;
780
781     *phview = NULL;
782
783     sql.db = db;
784     sql.command = command;
785     sql.n = 0;
786     sql.len = 0;
787     sql.view = phview;
788     sql.mem = mem;
789
790     r = SQL_parse(&sql);
791
792     TRACE("Parse returned %d\n", r);
793     if( r )
794     {
795         if( *sql.view )
796             (*sql.view)->ops->delete( *sql.view );
797         *sql.view = NULL;
798         return ERROR_BAD_QUERY_SYNTAX;
799     }
800
801     return ERROR_SUCCESS;
802 }