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