crypt32: Introduce function to encode an array of items as a set.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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
36 #define YYLEX_PARAM info
37 #define YYPARSE_PARAM info
38
39 static int sql_error(const char *str);
40
41 WINE_DEFAULT_DEBUG_CHANNEL(msi);
42
43 typedef struct tag_SQL_input
44 {
45     MSIDATABASE *db;
46     LPCWSTR command;
47     DWORD n, len;
48     MSIVIEW **view;  /* view structure for the resulting query */
49     struct list *mem;
50 } SQL_input;
51
52 static LPWSTR SQL_getstring( void *info, const struct sql_str *str );
53 static INT SQL_getint( void *info );
54 static int sql_lex( void *SQL_lval, SQL_input *info );
55
56 static void *parser_alloc( void *info, unsigned int sz );
57 static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column );
58
59 static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys);
60
61 static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );
62 static struct expr * EXPR_unary( void *info, struct expr *l, UINT op );
63 static struct expr * EXPR_column( void *info, const column_info *column );
64 static struct expr * EXPR_ival( void *info, int val );
65 static struct expr * EXPR_sval( void *info, const struct sql_str *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     MSIVIEW *query;
78     struct expr *expr;
79     USHORT column_type;
80     int integer;
81 }
82
83 %token TK_ALTER TK_AND TK_BY TK_CHAR TK_COMMA TK_CREATE TK_DELETE
84 %token TK_DISTINCT TK_DOT TK_EQ TK_FREE TK_FROM TK_GE TK_GT TK_HOLD TK_ADD
85 %token <str> TK_ID
86 %token TK_ILLEGAL TK_INSERT TK_INT
87 %token <str> TK_INTEGER
88 %token TK_INTO TK_IS TK_KEY TK_LE TK_LONG TK_LONGCHAR TK_LP TK_LT
89 %token TK_LOCALIZABLE TK_MINUS TK_NE TK_NOT TK_NULL
90 %token TK_OBJECT TK_OR TK_ORDER TK_PRIMARY TK_RP
91 %token TK_SELECT TK_SET TK_SHORT TK_SPACE TK_STAR
92 %token <str> TK_STRING
93 %token TK_TABLE TK_TEMPORARY TK_UPDATE TK_VALUES TK_WHERE TK_WILDCARD
94
95 /*
96  * These are extra tokens used by the lexer but never seen by the
97  * parser.  We put them in a rule so that the parser generator will
98  * add them to the parse.h output file.
99  *
100  */
101 %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
102           COLUMN AGG_FUNCTION.
103
104 %type <string> table id
105 %type <column_list> selcollist column column_and_type column_def table_def
106 %type <column_list> column_assignment update_assign_list constlist
107 %type <query> query from fromtable selectfrom unorderedsel
108 %type <query> oneupdate onedelete oneselect onequery onecreate oneinsert onealter
109 %type <expr> expr val column_val const_val
110 %type <column_type> column_type data_type data_type_l data_count
111 %type <integer> number alterop
112
113 /* Reference: http://mates.ms.mff.cuni.cz/oracle/doc/ora815nt/server.815/a67779/operator.htm */
114 %left TK_OR
115 %left TK_AND
116 %left TK_NOT
117 %left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE
118 %right TK_NEGATION
119
120 %%
121
122 query:
123     onequery
124     {
125         SQL_input* sql = (SQL_input*) info;
126         *sql->view = $1;
127     }
128     ;
129
130 onequery:
131     oneselect
132   | onecreate
133   | oneinsert
134   | oneupdate
135   | onedelete
136   | onealter
137     ;
138
139 oneinsert:
140     TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP
141         {
142             SQL_input *sql = (SQL_input*) info;
143             MSIVIEW *insert = NULL;
144             UINT r;
145
146             r = INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE );
147             if( !insert )
148                 YYABORT;
149             $$ = insert;
150         }
151   | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMPORARY
152         {
153             SQL_input *sql = (SQL_input*) info;
154             MSIVIEW *insert = NULL;
155
156             INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE );
157             if( !insert )
158                 YYABORT;
159             $$ = insert;
160         }
161     ;
162
163 onecreate:
164     TK_CREATE TK_TABLE table TK_LP table_def TK_RP
165         {
166             SQL_input* sql = (SQL_input*) info;
167             MSIVIEW *create = NULL;
168
169             if( !$5 )
170                 YYABORT;
171             CREATE_CreateView( sql->db, &create, $3, $5, FALSE );
172             if( !create )
173                 YYABORT;
174             $$ = create;
175         }
176   | TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD
177         {
178             SQL_input* sql = (SQL_input*) info;
179             MSIVIEW *create = NULL;
180
181             if( !$5 )
182                 YYABORT;
183             CREATE_CreateView( sql->db, &create, $3, $5, TRUE );
184             if( !create )
185                 YYABORT;
186             $$ = create;
187         }
188     ;
189
190 oneupdate:
191     TK_UPDATE table TK_SET update_assign_list TK_WHERE expr
192         {
193             SQL_input* sql = (SQL_input*) info;
194             MSIVIEW *update = NULL;
195
196             UPDATE_CreateView( sql->db, &update, $2, $4, $6 );
197             if( !update )
198                 YYABORT;
199             $$ = update;
200         }
201   | TK_UPDATE table TK_SET update_assign_list
202         {
203             SQL_input* sql = (SQL_input*) info;
204             MSIVIEW *update = NULL;
205
206             UPDATE_CreateView( sql->db, &update, $2, $4, NULL );
207             if( !update )
208                 YYABORT;
209             $$ = update;
210         }
211     ;
212
213 onedelete:
214     TK_DELETE from
215         {
216             SQL_input* sql = (SQL_input*) info;
217             MSIVIEW *delete = NULL;
218
219             DELETE_CreateView( sql->db, &delete, $2 );
220             if( !delete )
221                 YYABORT;
222             $$ = delete;
223         }
224     ;
225
226 onealter:
227     TK_ALTER TK_TABLE table alterop
228         {
229             SQL_input* sql = (SQL_input*) info;
230             MSIVIEW *alter = NULL;
231
232             ALTER_CreateView( sql->db, &alter, $3, NULL, $4 );
233             if( !alter )
234                 YYABORT;
235             $$ = alter;
236         }
237   | TK_ALTER TK_TABLE table TK_ADD column_and_type
238         {
239             SQL_input *sql = (SQL_input *)info;
240             MSIVIEW *alter = NULL;
241
242             ALTER_CreateView( sql->db, &alter, $3, $5, 0 );
243             if (!alter)
244                 YYABORT;
245             $$ = alter;
246         }
247   | TK_ALTER TK_TABLE table TK_ADD column_and_type TK_HOLD
248         {
249             SQL_input *sql = (SQL_input *)info;
250             MSIVIEW *alter = NULL;
251
252             ALTER_CreateView( sql->db, &alter, $3, $5, 1 );
253             if (!alter)
254                 YYABORT;
255             $$ = alter;
256         }
257     ;
258
259 alterop:
260     TK_HOLD
261         {
262             $$ = 1;
263         }
264   | TK_FREE
265         {
266             $$ = -1;
267         }
268   ;
269
270 table_def:
271     column_def TK_PRIMARY TK_KEY selcollist
272         {
273             if( SQL_MarkPrimaryKeys( $1, $4 ) )
274                 $$ = $1;
275             else
276                 $$ = NULL;
277         }
278     ;
279
280 column_def:
281     column_def TK_COMMA column_and_type
282         {
283             column_info *ci;
284
285             for( ci = $1; ci->next; ci = ci->next )
286                 ;
287
288             ci->next = $3;
289             $$ = $1;
290         }
291   | column_and_type
292         {
293             $$ = $1;
294         }
295     ;
296
297 column_and_type:
298     column column_type
299         {
300             $$ = $1;
301             $$->type = ($2 | MSITYPE_VALID);
302             $$->temporary = $2 & MSITYPE_TEMPORARY ? TRUE : FALSE;
303         }
304     ;
305
306 column_type:
307     data_type_l
308         {
309             $$ = $1;
310         }
311   | data_type_l TK_LOCALIZABLE
312         {
313             $$ = $1 | MSITYPE_LOCALIZABLE;
314         }
315   | data_type_l TK_TEMPORARY
316         {
317             $$ = $1 | MSITYPE_TEMPORARY;
318         }
319     ;
320
321 data_type_l:
322     data_type
323         {
324             $$ |= MSITYPE_NULLABLE;
325         }
326   | data_type TK_NOT TK_NULL
327         {
328             $$ = $1;
329         }
330     ;
331
332 data_type:
333     TK_CHAR
334         {
335             $$ = MSITYPE_STRING | 1;
336         }
337   | TK_CHAR TK_LP data_count TK_RP
338         {
339             $$ = MSITYPE_STRING | 0x400 | $3;
340         }
341   | TK_LONGCHAR
342         {
343             $$ = 2;
344         }
345   | TK_SHORT
346         {
347             $$ = 2;
348         }
349   | TK_INT
350         {
351             $$ = 2;
352         }
353   | TK_LONG
354         {
355             $$ = 4;
356         }
357   | TK_OBJECT
358         {
359             $$ = MSITYPE_STRING | MSITYPE_VALID;
360         }
361     ;
362
363 data_count:
364     number
365         {
366             if( ( $1 > 255 ) || ( $1 < 0 ) )
367                 YYABORT;
368             $$ = $1;
369         }
370     ;
371
372 oneselect:
373     unorderedsel TK_ORDER TK_BY selcollist
374         {
375             SQL_input* sql = (SQL_input*) info;
376
377             $$ = NULL;
378             if( $4 )
379                 ORDER_CreateView( sql->db, &$$, $1, $4 );
380             else
381                 $$ = $1;
382             if( !$$ )
383                 YYABORT;
384         }
385   | unorderedsel
386     ;
387
388 unorderedsel:
389     TK_SELECT selectfrom
390         {
391             $$ = $2;
392         }
393   | TK_SELECT TK_DISTINCT selectfrom
394         {
395             SQL_input* sql = (SQL_input*) info;
396             UINT r;
397
398             $$ = NULL;
399             r = DISTINCT_CreateView( sql->db, &$$, $3 );
400             if (r != ERROR_SUCCESS)
401             {
402                 $3->ops->delete($3);
403                 YYABORT;
404             }
405         }
406     ;
407
408 selectfrom:
409     selcollist from
410         {
411             SQL_input* sql = (SQL_input*) info;
412             UINT r;
413
414             $$ = NULL;
415             if( $1 )
416             {
417                 r = SELECT_CreateView( sql->db, &$$, $2, $1 );
418                 if (r != ERROR_SUCCESS)
419                 {
420                     $2->ops->delete($2);
421                     YYABORT;
422                 }
423             }
424             else
425                 $$ = $2;
426         }
427     ;
428
429 selcollist:
430     column
431   | column TK_COMMA selcollist
432         {
433             $1->next = $3;
434         }
435   | TK_STAR
436         {
437             $$ = NULL;
438         }
439     ;
440
441 from:
442     fromtable
443   | fromtable TK_WHERE expr
444         {
445             SQL_input* sql = (SQL_input*) info;
446             UINT r;
447
448             $$ = NULL;
449             r = WHERE_CreateView( sql->db, &$$, $1, $3 );
450             if( r != ERROR_SUCCESS )
451             {
452                 $1->ops->delete( $1 );
453                 YYABORT;
454             }
455         }
456     ;
457
458 fromtable:
459     TK_FROM table
460         {
461             SQL_input* sql = (SQL_input*) info;
462             UINT r;
463
464             $$ = NULL;
465             r = TABLE_CreateView( sql->db, $2, &$$ );
466             if( r != ERROR_SUCCESS || !$$ )
467                 YYABORT;
468         }
469   | TK_FROM table TK_COMMA table
470         {
471             SQL_input* sql = (SQL_input*) info;
472             UINT r;
473
474             /* only support inner joins on two tables */
475             r = JOIN_CreateView( sql->db, &$$, $2, $4 );
476             if( r != ERROR_SUCCESS )
477                 YYABORT;
478         }
479     ;
480
481 expr:
482     TK_LP expr TK_RP
483         {
484             $$ = $2;
485             if( !$$ )
486                 YYABORT;
487         }
488   | expr TK_AND expr
489         {
490             $$ = EXPR_complex( info, $1, OP_AND, $3 );
491             if( !$$ )
492                 YYABORT;
493         }
494   | expr TK_OR expr
495         {
496             $$ = EXPR_complex( info, $1, OP_OR, $3 );
497             if( !$$ )
498                 YYABORT;
499         }
500   | column_val TK_EQ val
501         {
502             $$ = EXPR_complex( info, $1, OP_EQ, $3 );
503             if( !$$ )
504                 YYABORT;
505         }
506   | column_val TK_GT val
507         {
508             $$ = EXPR_complex( info, $1, OP_GT, $3 );
509             if( !$$ )
510                 YYABORT;
511         }
512   | column_val TK_LT val
513         {
514             $$ = EXPR_complex( info, $1, OP_LT, $3 );
515             if( !$$ )
516                 YYABORT;
517         }
518   | column_val TK_LE val
519         {
520             $$ = EXPR_complex( info, $1, OP_LE, $3 );
521             if( !$$ )
522                 YYABORT;
523         }
524   | column_val TK_GE val
525         {
526             $$ = EXPR_complex( info, $1, OP_GE, $3 );
527             if( !$$ )
528                 YYABORT;
529         }
530   | column_val TK_NE val
531         {
532             $$ = EXPR_complex( info, $1, OP_NE, $3 );
533             if( !$$ )
534                 YYABORT;
535         }
536   | column_val TK_IS TK_NULL
537         {
538             $$ = EXPR_unary( info, $1, OP_ISNULL );
539             if( !$$ )
540                 YYABORT;
541         }
542   | column_val TK_IS TK_NOT TK_NULL
543         {
544             $$ = EXPR_unary( info, $1, OP_NOTNULL );
545             if( !$$ )
546                 YYABORT;
547         }
548     ;
549
550 val:
551     column_val
552   | const_val
553     ;
554
555 constlist:
556     const_val
557         {
558             $$ = parser_alloc_column( info, NULL, NULL );
559             if( !$$ )
560                 YYABORT;
561             $$->val = $1;
562         }
563   | const_val TK_COMMA constlist
564         {
565             $$ = parser_alloc_column( info, NULL, NULL );
566             if( !$$ )
567                 YYABORT;
568             $$->val = $1;
569             $$->next = $3;
570         }
571     ;
572
573 update_assign_list:
574     column_assignment
575   | column_assignment TK_COMMA update_assign_list
576         {
577             $$ = $1;
578             $$->next = $3;
579         }
580     ;
581
582 column_assignment:
583     column TK_EQ const_val
584         {
585             $$ = $1;
586             $$->val = $3;
587         }
588     ;
589
590 const_val:
591     number
592         {
593             $$ = EXPR_ival( info, $1 );
594             if( !$$ )
595                 YYABORT;
596         }
597   | TK_MINUS number %prec TK_NEGATION
598         {
599             $$ = EXPR_ival( info, -$2 );
600             if( !$$ )
601                 YYABORT;
602         }
603   | TK_STRING
604         {
605             $$ = EXPR_sval( info, &$1 );
606             if( !$$ )
607                 YYABORT;
608         }
609   | TK_WILDCARD
610         {
611             $$ = EXPR_wildcard( info );
612             if( !$$ )
613                 YYABORT;
614         }
615     ;
616
617 column_val:
618     column
619         {
620             $$ = EXPR_column( info, $1 );
621             if( !$$ )
622                 YYABORT;
623         }
624     ;
625
626 column:
627     table TK_DOT id
628         {
629             $$ = parser_alloc_column( info, $1, $3 );
630             if( !$$ )
631                 YYABORT;
632         }
633   | id
634         {
635             $$ = parser_alloc_column( info, NULL, $1 );
636             if( !$$ )
637                 YYABORT;
638         }
639     ;
640
641 table:
642     id
643         {
644             $$ = $1;
645         }
646     ;
647
648 id:
649     TK_ID
650         {
651             $$ = SQL_getstring( info, &$1 );
652             if( !$$ )
653                 YYABORT;
654         }
655     ;
656
657 number:
658     TK_INTEGER
659         {
660             $$ = SQL_getint( info );
661         }
662     ;
663
664 %%
665
666 static void *parser_alloc( void *info, unsigned int sz )
667 {
668     SQL_input* sql = (SQL_input*) info;
669     struct list *mem;
670
671     mem = msi_alloc( sizeof (struct list) + sz );
672     list_add_tail( sql->mem, mem );
673     return &mem[1];
674 }
675
676 static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column )
677 {
678     column_info *col;
679
680     col = parser_alloc( info, sizeof (*col) );
681     if( col )
682     {
683         col->table = table;
684         col->column = column;
685         col->val = NULL;
686         col->type = 0;
687         col->next = NULL;
688     }
689
690     return col;
691 }
692
693 static int sql_lex( void *SQL_lval, SQL_input *sql )
694 {
695     int token;
696     struct sql_str * str = SQL_lval;
697
698     do
699     {
700         sql->n += sql->len;
701         if( ! sql->command[sql->n] )
702             return 0;  /* end of input */
703
704         /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */
705         sql->len = sqliteGetToken( &sql->command[sql->n], &token );
706         if( sql->len==0 )
707             break;
708         str->data = &sql->command[sql->n];
709         str->len = sql->len;
710     }
711     while( token == TK_SPACE );
712
713     /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */
714
715     return token;
716 }
717
718 LPWSTR SQL_getstring( void *info, const struct sql_str *strdata )
719 {
720     LPCWSTR p = strdata->data;
721     UINT len = strdata->len;
722     LPWSTR str;
723
724     /* if there's quotes, remove them */
725     if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
726         ( (p[0]=='\'') && (p[len-1]=='\'') ) )
727     {
728         p++;
729         len -= 2;
730     }
731     str = parser_alloc( info, (len + 1)*sizeof(WCHAR) );
732     if( !str )
733         return str;
734     memcpy( str, p, len*sizeof(WCHAR) );
735     str[len]=0;
736
737     return str;
738 }
739
740 INT SQL_getint( void *info )
741 {
742     SQL_input* sql = (SQL_input*) info;
743     LPCWSTR p = &sql->command[sql->n];
744     INT i, r = 0;
745
746     for( i=0; i<sql->len; i++ )
747     {
748         if( '0' > p[i] || '9' < p[i] )
749         {
750             ERR("should only be numbers here!\n");
751             break;
752         }
753         r = (p[i]-'0') + r*10;
754     }
755
756     return r;
757 }
758
759 static int sql_error( const char *str )
760 {
761     return 0;
762 }
763
764 static struct expr * EXPR_wildcard( void *info )
765 {
766     struct expr *e = parser_alloc( info, sizeof *e );
767     if( e )
768     {
769         e->type = EXPR_WILDCARD;
770     }
771     return e;
772 }
773
774 static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r )
775 {
776     struct expr *e = parser_alloc( info, sizeof *e );
777     if( e )
778     {
779         e->type = EXPR_COMPLEX;
780         e->u.expr.left = l;
781         e->u.expr.op = op;
782         e->u.expr.right = r;
783     }
784     return e;
785 }
786
787 static struct expr * EXPR_unary( void *info, struct expr *l, UINT op )
788 {
789     struct expr *e = parser_alloc( info, sizeof *e );
790     if( e )
791     {
792         e->type = EXPR_UNARY;
793         e->u.expr.left = l;
794         e->u.expr.op = op;
795         e->u.expr.right = NULL;
796     }
797     return e;
798 }
799
800 static struct expr * EXPR_column( void *info, const column_info *column )
801 {
802     struct expr *e = parser_alloc( info, sizeof *e );
803     if( e )
804     {
805         e->type = EXPR_COLUMN;
806         e->u.sval = column->column;
807     }
808     return e;
809 }
810
811 static struct expr * EXPR_ival( void *info, int val )
812 {
813     struct expr *e = parser_alloc( info, sizeof *e );
814     if( e )
815     {
816         e->type = EXPR_IVAL;
817         e->u.ival = val;
818     }
819     return e;
820 }
821
822 static struct expr * EXPR_sval( void *info, const struct sql_str *str )
823 {
824     struct expr *e = parser_alloc( info, sizeof *e );
825     if( e )
826     {
827         e->type = EXPR_SVAL;
828         e->u.sval = SQL_getstring( info, str );
829     }
830     return e;
831 }
832
833 static BOOL SQL_MarkPrimaryKeys( column_info *cols,
834                                  column_info *keys )
835 {
836     column_info *k;
837     BOOL found = TRUE;
838
839     for( k = keys; k && found; k = k->next )
840     {
841         column_info *c;
842
843         found = FALSE;
844         for( c = cols; c && !found; c = c->next )
845         {
846              if( lstrcmpW( k->column, c->column ) )
847                  continue;
848              c->type |= MSITYPE_KEY;
849              found = TRUE;
850         }
851     }
852
853     return found;
854 }
855
856 UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,
857                    struct list *mem )
858 {
859     SQL_input sql;
860     int r;
861
862     *phview = NULL;
863
864     sql.db = db;
865     sql.command = command;
866     sql.n = 0;
867     sql.len = 0;
868     sql.view = phview;
869     sql.mem = mem;
870
871     r = sql_parse(&sql);
872
873     TRACE("Parse returned %d\n", r);
874     if( r )
875     {
876         *sql.view = NULL;
877         return ERROR_BAD_QUERY_SYNTAX;
878     }
879
880     return ERROR_SUCCESS;
881 }