ReactOS 0.4.15-dev-7942-gd23573b
where.c
Go to the documentation of this file.
1/*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 2002 Mike McCormack for CodeWeavers
5 * Copyright 2011 Bernhard Loos
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23#include <assert.h>
24
25#include "windef.h"
26#include "winbase.h"
27#include "winerror.h"
28#include "wine/debug.h"
29#include "msi.h"
30#include "msiquery.h"
31#include "objbase.h"
32#include "objidl.h"
33#include "msipriv.h"
34#include "winnls.h"
35
36#include "query.h"
37
39
40/* below is the query interface to a table */
41typedef struct tagMSIROWENTRY
42{
43 struct tagMSIWHEREVIEW *wv; /* used during sorting */
46
47typedef struct tagJOINTABLE
48{
55
56typedef struct tagMSIORDERINFO
57{
62
63typedef struct tagMSIWHEREVIEW
64{
72 UINT reorder_size; /* number of entries available in reorder */
73 struct expr *cond;
77
78static UINT WHERE_evaluate( MSIWHEREVIEW *wv, const UINT rows[],
79 struct expr *cond, INT *val, MSIRECORD *record );
80
81#define INITIAL_REORDER_SIZE 16
82
83#define INVALID_ROW_INDEX (-1)
84
85static void free_reorder(MSIWHEREVIEW *wv)
86{
87 UINT i;
88
89 if (!wv->reorder)
90 return;
91
92 for (i = 0; i < wv->row_count; i++)
93 msi_free(wv->reorder[i]);
94
95 msi_free( wv->reorder );
96 wv->reorder = NULL;
97 wv->reorder_size = 0;
98 wv->row_count = 0;
99}
100
102{
104 if (!new)
105 return ERROR_OUTOFMEMORY;
106
107 free_reorder(wv);
108
109 wv->reorder = new;
111
112 return ERROR_SUCCESS;
113}
114
115static inline UINT find_row(MSIWHEREVIEW *wv, UINT row, UINT *(values[]))
116{
117 if (row >= wv->row_count)
118 return ERROR_NO_MORE_ITEMS;
119
120 *values = wv->reorder[row]->values;
121
122 return ERROR_SUCCESS;
123}
124
125static UINT add_row(MSIWHEREVIEW *wv, UINT vals[])
126{
127 MSIROWENTRY *new;
128
129 if (wv->reorder_size <= wv->row_count)
130 {
131 MSIROWENTRY **new_reorder;
132 UINT newsize = wv->reorder_size * 2;
133
134 new_reorder = msi_realloc(wv->reorder, newsize * sizeof(*new_reorder));
135 if (!new_reorder)
136 return ERROR_OUTOFMEMORY;
137 memset(new_reorder + wv->reorder_size, 0, (newsize - wv->reorder_size) * sizeof(*new_reorder));
138
139 wv->reorder = new_reorder;
140 wv->reorder_size = newsize;
141 }
142
144
145 if (!new)
146 return ERROR_OUTOFMEMORY;
147
148 wv->reorder[wv->row_count++] = new;
149
150 memcpy(new->values, vals, wv->table_count * sizeof(UINT));
151 new->wv = wv;
152
153 return ERROR_SUCCESS;
154}
155
156static JOINTABLE *find_table(MSIWHEREVIEW *wv, UINT col, UINT *table_col)
157{
158 JOINTABLE *table = wv->tables;
159
160 if(col == 0 || col > wv->col_count)
161 return NULL;
162
163 while (col > table->col_count)
164 {
165 col -= table->col_count;
166 table = table->next;
167 assert(table);
168 }
169
170 *table_col = col;
171 return table;
172}
173
175 UINT *column_type)
176{
177 JOINTABLE *table = wv->tables;
178 UINT i, r;
179
180 do
181 {
182 LPCWSTR table_name;
183
184 if (column->unparsed.table)
185 {
186 r = table->view->ops->get_column_info(table->view, 1, NULL, NULL,
187 NULL, &table_name);
188 if (r != ERROR_SUCCESS)
189 return r;
190 if (wcscmp(table_name, column->unparsed.table) != 0)
191 continue;
192 }
193
194 for(i = 1; i <= table->col_count; i++)
195 {
196 LPCWSTR col_name;
197
198 r = table->view->ops->get_column_info(table->view, i, &col_name, column_type,
199 NULL, NULL);
200 if(r != ERROR_SUCCESS )
201 return r;
202
203 if(wcscmp(col_name, column->unparsed.column))
204 continue;
205 column->parsed.column = i;
206 column->parsed.table = table;
207 return ERROR_SUCCESS;
208 }
209 }
210 while ((table = table->next));
211
212 WARN("Couldn't find column %s.%s\n", debugstr_w( column->unparsed.table ), debugstr_w( column->unparsed.column ) );
214}
215
217{
220 UINT *rows;
221 UINT r;
222
223 TRACE("%p %d %d %p\n", wv, row, col, val );
224
225 if( !wv->tables )
227
228 r = find_row(wv, row, &rows);
229 if (r != ERROR_SUCCESS)
230 return r;
231
232 table = find_table(wv, col, &col);
233 if (!table)
235
236 return table->view->ops->fetch_int(table->view, rows[table->table_index], col, val);
237}
238
240{
243 UINT *rows;
244 UINT r;
245
246 TRACE("%p %d %d %p\n", wv, row, col, stm );
247
248 if( !wv->tables )
250
251 r = find_row(wv, row, &rows);
252 if (r != ERROR_SUCCESS)
253 return r;
254
255 table = find_table(wv, col, &col);
256 if (!table)
258
259 return table->view->ops->fetch_stream( table->view, rows[table->table_index], col, stm );
260}
261
262static UINT WHERE_set_int(struct tagMSIVIEW *view, UINT row, UINT col, int val)
263{
266 UINT *rows;
267 UINT r;
268
269 TRACE("view %p, row %u, col %u, val %d.\n", wv, row, col, val );
270
271 r = find_row(wv, row, &rows);
272 if (r != ERROR_SUCCESS)
273 return r;
274
275 table = find_table(wv, col, &col);
276 if (!table)
278
279 return table->view->ops->set_int(table->view, rows[table->table_index], col, val);
280}
281
282static UINT WHERE_set_string(struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len)
283{
286 UINT *rows;
287 UINT r;
288
289 TRACE("view %p, row %u, col %u, val %s.\n", wv, row, col, debugstr_wn(val, len));
290
291 r = find_row(wv, row, &rows);
292 if (r != ERROR_SUCCESS)
293 return r;
294
295 table = find_table(wv, col, &col);
296 if (!table)
298
299 return table->view->ops->set_string(table->view, rows[table->table_index], col, val, len);
300}
301
303{
306 UINT *rows;
307 UINT r;
308
309 TRACE("view %p, row %u, col %u, stream %p.\n", wv, row, col, stream);
310
311 r = find_row(wv, row, &rows);
312 if (r != ERROR_SUCCESS)
313 return r;
314
315 table = find_table(wv, col, &col);
316 if (!table)
318
319 return table->view->ops->set_stream(table->view, rows[table->table_index], col, stream);
320}
321
323{
325 UINT i, r, offset = 0;
326 JOINTABLE *table = wv->tables;
327 UINT *rows;
328 UINT mask_copy = mask;
329
330 TRACE("%p %d %p %08x\n", wv, row, rec, mask );
331
332 if( !wv->tables )
334
335 r = find_row(wv, row, &rows);
336 if (r != ERROR_SUCCESS)
337 return r;
338
339 if (mask >= 1 << wv->col_count)
341
342 do
343 {
344 for (i = 0; i < table->col_count; i++) {
345 UINT type;
346
347 if (!(mask_copy & (1 << i)))
348 continue;
349 r = table->view->ops->get_column_info(table->view, i + 1, NULL,
350 &type, NULL, NULL );
351 if (r != ERROR_SUCCESS)
352 return r;
353 if (type & MSITYPE_KEY)
355 }
356 mask_copy >>= table->col_count;
357 }
358 while (mask_copy && (table = table->next));
359
360 table = wv->tables;
361
362 do
363 {
364 const UINT col_count = table->col_count;
365 UINT i;
366 MSIRECORD *reduced;
367 UINT reduced_mask = (mask >> offset) & ((1 << col_count) - 1);
368
369 if (!reduced_mask)
370 {
371 offset += col_count;
372 continue;
373 }
374
375 reduced = MSI_CreateRecord(col_count);
376 if (!reduced)
378
379 for (i = 1; i <= col_count; i++)
380 {
381 r = MSI_RecordCopyField(rec, i + offset, reduced, i);
382 if (r != ERROR_SUCCESS)
383 break;
384 }
385
386 offset += col_count;
387
388 if (r == ERROR_SUCCESS)
389 r = table->view->ops->set_row(table->view, rows[table->table_index], reduced, reduced_mask);
390
391 msiobj_release(&reduced->hdr);
392 }
393 while ((table = table->next));
394 return r;
395}
396
398{
400 UINT r;
401 UINT *rows;
402
403 TRACE("(%p %d)\n", view, row);
404
405 if (!wv->tables)
407
408 r = find_row(wv, row, &rows);
409 if ( r != ERROR_SUCCESS )
410 return r;
411
412 if (wv->table_count > 1)
414
415 return wv->tables->view->ops->delete_row(wv->tables->view, rows[0]);
416}
417
418static INT INT_evaluate_binary( MSIWHEREVIEW *wv, const UINT rows[],
419 const struct complex_expr *expr, INT *val, MSIRECORD *record )
420{
421 UINT rl, rr;
422 INT lval, rval;
423
424 rl = WHERE_evaluate(wv, rows, expr->left, &lval, record);
425 if (rl != ERROR_SUCCESS && rl != ERROR_CONTINUE)
426 return rl;
427 rr = WHERE_evaluate(wv, rows, expr->right, &rval, record);
428 if (rr != ERROR_SUCCESS && rr != ERROR_CONTINUE)
429 return rr;
430
431 if (rl == ERROR_CONTINUE || rr == ERROR_CONTINUE)
432 {
433 if (rl == rr)
434 {
435 *val = TRUE;
436 return ERROR_CONTINUE;
437 }
438
439 if (expr->op == OP_AND)
440 {
441 if ((rl == ERROR_CONTINUE && !rval) || (rr == ERROR_CONTINUE && !lval))
442 {
443 *val = FALSE;
444 return ERROR_SUCCESS;
445 }
446 }
447 else if (expr->op == OP_OR)
448 {
449 if ((rl == ERROR_CONTINUE && rval) || (rr == ERROR_CONTINUE && lval))
450 {
451 *val = TRUE;
452 return ERROR_SUCCESS;
453 }
454 }
455
456 *val = TRUE;
457 return ERROR_CONTINUE;
458 }
459
460 switch( expr->op )
461 {
462 case OP_EQ:
463 *val = ( lval == rval );
464 break;
465 case OP_AND:
466 *val = ( lval && rval );
467 break;
468 case OP_OR:
469 *val = ( lval || rval );
470 break;
471 case OP_GT:
472 *val = ( lval > rval );
473 break;
474 case OP_LT:
475 *val = ( lval < rval );
476 break;
477 case OP_LE:
478 *val = ( lval <= rval );
479 break;
480 case OP_GE:
481 *val = ( lval >= rval );
482 break;
483 case OP_NE:
484 *val = ( lval != rval );
485 break;
486 default:
487 ERR("Unknown operator %d\n", expr->op );
489 }
490
491 return ERROR_SUCCESS;
492}
493
494static inline UINT expr_fetch_value(const union ext_column *expr, const UINT rows[], UINT *val)
495{
496 JOINTABLE *table = expr->parsed.table;
497
498 if( rows[table->table_index] == INVALID_ROW_INDEX )
499 {
500 *val = 1;
501 return ERROR_CONTINUE;
502 }
503 return table->view->ops->fetch_int(table->view, rows[table->table_index],
504 expr->parsed.column, val);
505}
506
507
508static UINT INT_evaluate_unary( MSIWHEREVIEW *wv, const UINT rows[],
509 const struct complex_expr *expr, INT *val, MSIRECORD *record )
510{
511 UINT r;
512 UINT lval;
513
514 r = expr_fetch_value(&expr->left->u.column, rows, &lval);
515 if(r != ERROR_SUCCESS)
516 return r;
517
518 switch( expr->op )
519 {
520 case OP_ISNULL:
521 *val = !lval;
522 break;
523 case OP_NOTNULL:
524 *val = lval;
525 break;
526 default:
527 ERR("Unknown operator %d\n", expr->op );
529 }
530 return ERROR_SUCCESS;
531}
532
533static UINT STRING_evaluate( MSIWHEREVIEW *wv, const UINT rows[],
534 const struct expr *expr,
535 const MSIRECORD *record,
536 const WCHAR **str )
537{
538 UINT val = 0, r = ERROR_SUCCESS;
539
540 switch( expr->type )
541 {
543 r = expr_fetch_value(&expr->u.column, rows, &val);
544 if (r == ERROR_SUCCESS)
546 else
547 *str = NULL;
548 break;
549
550 case EXPR_SVAL:
551 *str = expr->u.sval;
552 break;
553
554 case EXPR_WILDCARD:
556 break;
557
558 default:
559 ERR("Invalid expression type\n");
561 *str = NULL;
562 break;
563 }
564 return r;
565}
566
567static UINT STRCMP_Evaluate( MSIWHEREVIEW *wv, const UINT rows[], const struct complex_expr *expr,
568 INT *val, const MSIRECORD *record )
569{
570 int sr;
571 const WCHAR *l_str, *r_str;
572 UINT r;
573
574 *val = TRUE;
575 r = STRING_evaluate(wv, rows, expr->left, record, &l_str);
576 if (r == ERROR_CONTINUE)
577 return r;
578 r = STRING_evaluate(wv, rows, expr->right, record, &r_str);
579 if (r == ERROR_CONTINUE)
580 return r;
581
582 if( l_str == r_str ||
583 ((!l_str || !*l_str) && (!r_str || !*r_str)) )
584 sr = 0;
585 else if( l_str && ! r_str )
586 sr = 1;
587 else if( r_str && ! l_str )
588 sr = -1;
589 else
590 sr = wcscmp( l_str, r_str );
591
592 *val = ( expr->op == OP_EQ && ( sr == 0 ) ) ||
593 ( expr->op == OP_NE && ( sr != 0 ) );
594
595 return ERROR_SUCCESS;
596}
597
598static UINT WHERE_evaluate( MSIWHEREVIEW *wv, const UINT rows[],
599 struct expr *cond, INT *val, MSIRECORD *record )
600{
601 UINT r, tval;
602
603 if( !cond )
604 {
605 *val = TRUE;
606 return ERROR_SUCCESS;
607 }
608
609 switch( cond->type )
610 {
611 case EXPR_COL_NUMBER:
612 r = expr_fetch_value(&cond->u.column, rows, &tval);
613 if( r != ERROR_SUCCESS )
614 return r;
615 *val = tval - 0x8000;
616 return ERROR_SUCCESS;
617
619 r = expr_fetch_value(&cond->u.column, rows, &tval);
620 if( r != ERROR_SUCCESS )
621 return r;
622 *val = tval - 0x80000000;
623 return r;
624
625 case EXPR_UVAL:
626 *val = cond->u.uval;
627 return ERROR_SUCCESS;
628
629 case EXPR_COMPLEX:
630 return INT_evaluate_binary(wv, rows, &cond->u.expr, val, record);
631
632 case EXPR_UNARY:
633 return INT_evaluate_unary( wv, rows, &cond->u.expr, val, record );
634
635 case EXPR_STRCMP:
636 return STRCMP_Evaluate( wv, rows, &cond->u.expr, val, record );
637
638 case EXPR_WILDCARD:
640 return ERROR_SUCCESS;
641
642 default:
643 ERR("Invalid expression type\n");
645 }
646
647 return ERROR_SUCCESS;
648}
649
651 UINT table_rows[] )
652{
654 INT val;
655
656 for (table_rows[(*tables)->table_index] = 0;
657 table_rows[(*tables)->table_index] < (*tables)->row_count;
658 table_rows[(*tables)->table_index]++)
659 {
660 val = 0;
661 wv->rec_index = 0;
662 r = WHERE_evaluate( wv, table_rows, wv->cond, &val, record );
663 if (r != ERROR_SUCCESS && r != ERROR_CONTINUE)
664 break;
665 if (val)
666 {
667 if (*(tables + 1))
668 {
669 r = check_condition(wv, record, tables + 1, table_rows);
670 if (r != ERROR_SUCCESS)
671 break;
672 }
673 else
674 {
675 if (r != ERROR_SUCCESS)
676 break;
677 add_row (wv, table_rows);
678 }
679 }
680 }
681 table_rows[(*tables)->table_index] = INVALID_ROW_INDEX;
682 return r;
683}
684
685static int __cdecl compare_entry( const void *left, const void *right )
686{
687 const MSIROWENTRY *le = *(const MSIROWENTRY**)left;
688 const MSIROWENTRY *re = *(const MSIROWENTRY**)right;
689 const MSIWHEREVIEW *wv = le->wv;
691 UINT i, j, r, l_val, r_val;
692
693 assert(le->wv == re->wv);
694
695 if (order)
696 {
697 for (i = 0; i < order->col_count; i++)
698 {
699 const union ext_column *column = &order->columns[i];
700
701 r = column->parsed.table->view->ops->fetch_int(column->parsed.table->view,
702 le->values[column->parsed.table->table_index],
703 column->parsed.column, &l_val);
704 if (r != ERROR_SUCCESS)
705 {
706 order->error = r;
707 return 0;
708 }
709
710 r = column->parsed.table->view->ops->fetch_int(column->parsed.table->view,
711 re->values[column->parsed.table->table_index],
712 column->parsed.column, &r_val);
713 if (r != ERROR_SUCCESS)
714 {
715 order->error = r;
716 return 0;
717 }
718
719 if (l_val != r_val)
720 return l_val < r_val ? -1 : 1;
721 }
722 }
723
724 for (j = 0; j < wv->table_count; j++)
725 {
726 if (le->values[j] != re->values[j])
727 return le->values[j] < re->values[j] ? -1 : 1;
728 }
729 return 0;
730}
731
733{
734 while (*array && *array != elem)
735 array++;
736 if (!*array)
737 *array = elem;
738}
739
741{
742 while (*array && *array != elem)
743 array++;
744 return *array != NULL;
745}
746
747#define CONST_EXPR 1 /* comparison to a constant value */
748#define JOIN_TO_CONST_EXPR 0x10000 /* comparison to a table involved with
749 a CONST_EXPR comaprison */
751static UINT reorder_check( const struct expr *expr, JOINTABLE **ordered_tables,
752 BOOL process_joins, JOINTABLE **lastused )
753{
754 UINT res = 0;
755
756 switch (expr->type)
757 {
758 case EXPR_WILDCARD:
759 case EXPR_SVAL:
760 case EXPR_UVAL:
761 return 0;
762 case EXPR_COL_NUMBER:
765 if (in_array(ordered_tables, expr->u.column.parsed.table))
766 return JOIN_TO_CONST_EXPR;
767 *lastused = expr->u.column.parsed.table;
768 return CONST_EXPR;
769 case EXPR_STRCMP:
770 case EXPR_COMPLEX:
771 res = reorder_check(expr->u.expr.right, ordered_tables, process_joins, lastused);
772 /* fall through */
773 case EXPR_UNARY:
774 res += reorder_check(expr->u.expr.left, ordered_tables, process_joins, lastused);
775 if (res == 0)
776 return 0;
777 if (res == CONST_EXPR)
778 add_to_array(ordered_tables, *lastused);
779 if (process_joins && res == JOIN_TO_CONST_EXPR + CONST_EXPR)
780 add_to_array(ordered_tables, *lastused);
781 return res;
782 default:
783 ERR("Unknown expr type: %i\n", expr->type);
784 assert(0);
785 return 0x1000000;
786 }
787}
788
789/* reorders the tablelist in a way to evaluate the condition as fast as possible */
790static JOINTABLE **ordertables( MSIWHEREVIEW *wv )
791{
794
795 tables = msi_alloc_zero( (wv->table_count + 1) * sizeof(*tables) );
796
797 if (wv->cond)
798 {
799 table = NULL;
801 table = NULL;
803 }
804
805 table = wv->tables;
806 while (table)
807 {
809 table = table->next;
810 }
811 return tables;
812}
815{
817 UINT r;
818 JOINTABLE *table = wv->tables;
819 UINT *rows;
820 JOINTABLE **ordered_tables;
821 UINT i = 0;
822
823 TRACE("%p %p\n", wv, record);
824
825 if( !table )
827
828 r = init_reorder(wv);
829 if (r != ERROR_SUCCESS)
830 return r;
831
832 do
833 {
834 table->view->ops->execute(table->view, NULL);
835
836 r = table->view->ops->get_dimensions(table->view, &table->row_count, NULL);
837 if (r != ERROR_SUCCESS)
838 {
839 ERR("failed to get table dimensions\n");
840 return r;
841 }
842
843 /* each table must have at least one row */
844 if (table->row_count == 0)
845 return ERROR_SUCCESS;
846 }
847 while ((table = table->next));
848
849 ordered_tables = ordertables( wv );
850
851 rows = msi_alloc( wv->table_count * sizeof(*rows) );
852 for (i = 0; i < wv->table_count; i++)
853 rows[i] = INVALID_ROW_INDEX;
854
855 r = check_condition(wv, record, ordered_tables, rows);
856
857 if (wv->order_info)
859
860 qsort(wv->reorder, wv->row_count, sizeof(MSIROWENTRY *), compare_entry);
861
862 if (wv->order_info)
863 r = wv->order_info->error;
864
865 msi_free( rows );
866 msi_free( ordered_tables );
867 return r;
868}
870static UINT WHERE_close( struct tagMSIVIEW *view )
871{
873 JOINTABLE *table = wv->tables;
874
875 TRACE("%p\n", wv );
876
877 if (!table)
879
880 do
881 table->view->ops->close(table->view);
882 while ((table = table->next));
883
884 return ERROR_SUCCESS;
885}
887static UINT WHERE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
888{
890
891 TRACE("%p %p %p\n", wv, rows, cols );
892
893 if(!wv->tables)
895
896 if (rows)
897 {
898 if (!wv->reorder)
900 *rows = wv->row_count;
901 }
902
903 if (cols)
904 *cols = wv->col_count;
905
906 return ERROR_SUCCESS;
907}
910 UINT *type, BOOL *temporary, LPCWSTR *table_name )
911{
914
915 TRACE("%p %d %p %p %p %p\n", wv, n, name, type, temporary, table_name );
916
917 if(!wv->tables)
919
920 table = find_table(wv, n, &n);
921 if (!table)
923
924 return table->view->ops->get_column_info(table->view, n, name,
925 type, temporary, table_name);
926}
928static UINT join_find_row( MSIWHEREVIEW *wv, MSIRECORD *rec, UINT *row )
929{
930 LPCWSTR str;
931 UINT r, i, id, data;
932
933 str = MSI_RecordGetString( rec, 1 );
934 r = msi_string2id( wv->db->strings, str, -1, &id );
935 if (r != ERROR_SUCCESS)
936 return r;
937
938 for (i = 0; i < wv->row_count; i++)
939 {
940 WHERE_fetch_int( &wv->view, i, 1, &data );
941
942 if (data == id)
943 {
944 *row = i;
945 return ERROR_SUCCESS;
946 }
947 }
948
950}
952static UINT join_modify_update( struct tagMSIVIEW *view, MSIRECORD *rec )
953{
955 UINT r, row, i, mask = 0;
957
958
959 r = join_find_row( wv, rec, &row );
960 if (r != ERROR_SUCCESS)
961 return r;
962
963 r = msi_view_get_row( wv->db, view, row, &current );
964 if (r != ERROR_SUCCESS)
965 return r;
966
968
969 for (i = MSI_RecordGetFieldCount(rec); i > 0; i--)
970 {
972 mask |= 1 << (i - 1);
973 }
974 msiobj_release(&current->hdr);
975
976 return WHERE_set_row( view, row, rec, mask );
977}
979static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
980 MSIRECORD *rec, UINT row )
981{
983 JOINTABLE *table = wv->tables;
984 UINT r;
985
986 TRACE("%p %d %p\n", wv, eModifyMode, rec);
987
988 if (!table)
990
991 if (!table->next)
992 {
993 UINT *rows;
994
995 if (find_row(wv, row, &rows) == ERROR_SUCCESS)
996 row = rows[0];
997 else
998 row = -1;
999
1000 return table->view->ops->modify(table->view, eModifyMode, rec, row);
1001 }
1002
1003 switch (eModifyMode)
1004 {
1005 case MSIMODIFY_UPDATE:
1006 return join_modify_update( view, rec );
1007
1008 case MSIMODIFY_ASSIGN:
1009 case MSIMODIFY_DELETE:
1010 case MSIMODIFY_INSERT:
1012 case MSIMODIFY_MERGE:
1013 case MSIMODIFY_REPLACE:
1014 case MSIMODIFY_SEEK:
1015 case MSIMODIFY_VALIDATE:
1020 break;
1021
1022 case MSIMODIFY_REFRESH:
1024 break;
1025
1026 default:
1027 WARN("%p %d %p %u - unknown mode\n", view, eModifyMode, rec, row );
1029 break;
1030 }
1031
1032 return r;
1033}
1035static UINT WHERE_delete( struct tagMSIVIEW *view )
1036{
1038 JOINTABLE *table = wv->tables;
1039
1040 TRACE("%p\n", wv );
1041
1042 while(table)
1043 {
1044 JOINTABLE *next;
1045
1046 table->view->ops->delete(table->view);
1047 table->view = NULL;
1048 next = table->next;
1049 msi_free(table);
1050 table = next;
1051 }
1052 wv->tables = NULL;
1053 wv->table_count = 0;
1054
1055 free_reorder(wv);
1056
1057 msi_free(wv->order_info);
1058 wv->order_info = NULL;
1059
1060 msiobj_release( &wv->db->hdr );
1061 msi_free( wv );
1062
1063 return ERROR_SUCCESS;
1064}
1066static UINT WHERE_sort(struct tagMSIVIEW *view, column_info *columns)
1067{
1069 JOINTABLE *table = wv->tables;
1070 column_info *column = columns;
1071 MSIORDERINFO *orderinfo;
1072 UINT r, count = 0;
1073 UINT i;
1074
1075 TRACE("%p %p\n", view, columns);
1076
1077 if (!table)
1078 return ERROR_FUNCTION_FAILED;
1079
1080 while (column)
1081 {
1082 count++;
1083 column = column->next;
1084 }
1085
1086 if (count == 0)
1087 return ERROR_SUCCESS;
1088
1089 orderinfo = msi_alloc(FIELD_OFFSET(MSIORDERINFO, columns[count]));
1090 if (!orderinfo)
1091 return ERROR_OUTOFMEMORY;
1092
1093 orderinfo->col_count = count;
1094
1095 column = columns;
1096
1097 for (i = 0; i < count; i++)
1098 {
1099 orderinfo->columns[i].unparsed.column = column->column;
1100 orderinfo->columns[i].unparsed.table = column->table;
1101
1102 r = parse_column(wv, &orderinfo->columns[i], NULL);
1103 if (r != ERROR_SUCCESS)
1104 goto error;
1105 }
1106
1107 wv->order_info = orderinfo;
1108
1109 return ERROR_SUCCESS;
1110error:
1111 msi_free(orderinfo);
1112 return r;
1113}
1115static const MSIVIEWOPS where_ops =
1116{
1123 NULL,
1131 NULL,
1132 NULL,
1133 NULL,
1134 WHERE_sort,
1135 NULL,
1136};
1138static UINT WHERE_VerifyCondition( MSIWHEREVIEW *wv, struct expr *cond,
1139 UINT *valid )
1140{
1141 UINT r;
1142
1143 switch( cond->type )
1144 {
1145 case EXPR_COLUMN:
1146 {
1147 UINT type;
1148
1149 *valid = FALSE;
1150
1151 r = parse_column(wv, &cond->u.column, &type);
1152 if (r != ERROR_SUCCESS)
1153 break;
1154
1155 if (type&MSITYPE_STRING)
1157 else if ((type&0xff) == 4)
1158 cond->type = EXPR_COL_NUMBER32;
1159 else
1160 cond->type = EXPR_COL_NUMBER;
1161
1162 *valid = TRUE;
1163 break;
1164 }
1165 case EXPR_COMPLEX:
1166 r = WHERE_VerifyCondition( wv, cond->u.expr.left, valid );
1167 if( r != ERROR_SUCCESS )
1168 return r;
1169 if( !*valid )
1170 return ERROR_SUCCESS;
1171 r = WHERE_VerifyCondition( wv, cond->u.expr.right, valid );
1172 if( r != ERROR_SUCCESS )
1173 return r;
1174
1175 /* check the type of the comparison */
1176 if( ( cond->u.expr.left->type == EXPR_SVAL ) ||
1177 ( cond->u.expr.left->type == EXPR_COL_NUMBER_STRING ) ||
1178 ( cond->u.expr.right->type == EXPR_SVAL ) ||
1179 ( cond->u.expr.right->type == EXPR_COL_NUMBER_STRING ) )
1180 {
1181 switch( cond->u.expr.op )
1182 {
1183 case OP_EQ:
1184 case OP_NE:
1185 break;
1186 default:
1187 *valid = FALSE;
1189 }
1190
1191 /* FIXME: check we're comparing a string to a column */
1192
1193 cond->type = EXPR_STRCMP;
1194 }
1195
1196 break;
1197 case EXPR_UNARY:
1198 if ( cond->u.expr.left->type != EXPR_COLUMN )
1199 {
1200 *valid = FALSE;
1202 }
1203 r = WHERE_VerifyCondition( wv, cond->u.expr.left, valid );
1204 if( r != ERROR_SUCCESS )
1205 return r;
1206 break;
1207 case EXPR_IVAL:
1208 *valid = 1;
1209 cond->type = EXPR_UVAL;
1210 cond->u.uval = cond->u.ival;
1211 break;
1212 case EXPR_WILDCARD:
1213 *valid = 1;
1214 break;
1215 case EXPR_SVAL:
1216 *valid = 1;
1217 break;
1218 default:
1219 ERR("Invalid expression type\n");
1220 *valid = 0;
1221 break;
1222 }
1223
1224 return ERROR_SUCCESS;
1225}
1228 struct expr *cond )
1229{
1230 MSIWHEREVIEW *wv = NULL;
1231 UINT r, valid = 0;
1232 WCHAR *ptr;
1233
1234 TRACE("(%s)\n", debugstr_w(tables) );
1235
1236 wv = msi_alloc_zero( sizeof *wv );
1237 if( !wv )
1238 return ERROR_FUNCTION_FAILED;
1239
1240 /* fill the structure */
1241 wv->view.ops = &where_ops;
1242 msiobj_addref( &db->hdr );
1243 wv->db = db;
1244 wv->cond = cond;
1245
1246 while (*tables)
1247 {
1249
1250 if ((ptr = wcschr(tables, ' ')))
1251 *ptr = '\0';
1252
1253 table = msi_alloc(sizeof(JOINTABLE));
1254 if (!table)
1255 {
1257 goto end;
1258 }
1259
1260 r = TABLE_CreateView(db, tables, &table->view);
1261 if (r != ERROR_SUCCESS)
1262 {
1263 WARN("can't create table: %s\n", debugstr_w(tables));
1264 msi_free(table);
1266 goto end;
1267 }
1268
1269 r = table->view->ops->get_dimensions(table->view, NULL,
1270 &table->col_count);
1271 if (r != ERROR_SUCCESS)
1272 {
1273 ERR("can't get table dimensions\n");
1274 table->view->ops->delete(table->view);
1275 msi_free(table);
1276 goto end;
1277 }
1278
1279 wv->col_count += table->col_count;
1280 table->table_index = wv->table_count++;
1281
1282 table->next = wv->tables;
1283 wv->tables = table;
1284
1285 if (!ptr)
1286 break;
1287
1288 tables = ptr + 1;
1289 }
1290
1291 if( cond )
1292 {
1293 r = WHERE_VerifyCondition( wv, cond, &valid );
1294 if( r != ERROR_SUCCESS )
1295 goto end;
1296 if( !valid ) {
1298 goto end;
1299 }
1300 }
1301
1302 *view = (MSIVIEW*) wv;
1303
1304 return ERROR_SUCCESS;
1305end:
1306 WHERE_delete(&wv->view);
1307
1308 return r;
1309}
#define __cdecl
Definition: accygwin.h:79
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
float rval
Definition: cylfrac.c:48
#define ERROR_CONTINUE
Definition: dderror.h:17
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define wcschr
Definition: compat.h:17
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
void msiobj_addref(MSIOBJECTHDR *info)
Definition: handle.c:217
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
static UINT WHERE_close(struct tagMSIVIEW *view)
Definition: where.c:869
static UINT add_row(MSIWHEREVIEW *wv, UINT vals[])
Definition: where.c:125
#define INITIAL_REORDER_SIZE
Definition: where.c:81
static UINT WHERE_set_string(struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len)
Definition: where.c:282
#define JOIN_TO_CONST_EXPR
Definition: where.c:748
static UINT expr_fetch_value(const union ext_column *expr, const UINT rows[], UINT *val)
Definition: where.c:494
static UINT WHERE_execute(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: where.c:813
static UINT WHERE_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
Definition: where.c:322
static void free_reorder(MSIWHEREVIEW *wv)
Definition: where.c:85
static INT INT_evaluate_binary(MSIWHEREVIEW *wv, const UINT rows[], const struct complex_expr *expr, INT *val, MSIRECORD *record)
Definition: where.c:418
struct tagMSIROWENTRY MSIROWENTRY
static UINT WHERE_delete_row(struct tagMSIVIEW *view, UINT row)
Definition: where.c:397
static JOINTABLE * find_table(MSIWHEREVIEW *wv, UINT col, UINT *table_col)
Definition: where.c:156
struct tagMSIORDERINFO MSIORDERINFO
#define CONST_EXPR
Definition: where.c:747
static UINT WHERE_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: where.c:886
static UINT STRING_evaluate(MSIWHEREVIEW *wv, const UINT rows[], const struct expr *expr, const MSIRECORD *record, const WCHAR **str)
Definition: where.c:533
static UINT INT_evaluate_unary(MSIWHEREVIEW *wv, const UINT rows[], const struct complex_expr *expr, INT *val, MSIRECORD *record)
Definition: where.c:508
struct tagMSIWHEREVIEW MSIWHEREVIEW
static UINT join_modify_update(struct tagMSIVIEW *view, MSIRECORD *rec)
Definition: where.c:951
static UINT WHERE_set_int(struct tagMSIVIEW *view, UINT row, UINT col, int val)
Definition: where.c:262
static UINT WHERE_get_column_info(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: where.c:908
static int __cdecl compare_entry(const void *left, const void *right)
Definition: where.c:685
static UINT STRCMP_Evaluate(MSIWHEREVIEW *wv, const UINT rows[], const struct complex_expr *expr, INT *val, const MSIRECORD *record)
Definition: where.c:567
#define INVALID_ROW_INDEX
Definition: where.c:83
static UINT WHERE_VerifyCondition(MSIWHEREVIEW *wv, struct expr *cond, UINT *valid)
Definition: where.c:1137
static UINT WHERE_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: where.c:216
static BOOL in_array(JOINTABLE **array, JOINTABLE *elem)
Definition: where.c:740
static UINT WHERE_evaluate(MSIWHEREVIEW *wv, const UINT rows[], struct expr *cond, INT *val, MSIRECORD *record)
Definition: where.c:598
static UINT find_row(MSIWHEREVIEW *wv, UINT row, UINT *(values[]))
Definition: where.c:115
static UINT parse_column(MSIWHEREVIEW *wv, union ext_column *column, UINT *column_type)
Definition: where.c:174
static UINT WHERE_sort(struct tagMSIVIEW *view, column_info *columns)
Definition: where.c:1065
static UINT init_reorder(MSIWHEREVIEW *wv)
Definition: where.c:101
static UINT WHERE_delete(struct tagMSIVIEW *view)
Definition: where.c:1034
static UINT reorder_check(const struct expr *expr, JOINTABLE **ordered_tables, BOOL process_joins, JOINTABLE **lastused)
Definition: where.c:750
static const MSIVIEWOPS where_ops
Definition: where.c:1114
static void add_to_array(JOINTABLE **array, JOINTABLE *elem)
Definition: where.c:732
UINT WHERE_CreateView(MSIDATABASE *db, MSIVIEW **view, LPWSTR tables, struct expr *cond)
Definition: where.c:1226
static JOINTABLE ** ordertables(MSIWHEREVIEW *wv)
Definition: where.c:789
static UINT WHERE_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
Definition: where.c:978
static UINT join_find_row(MSIWHEREVIEW *wv, MSIRECORD *rec, UINT *row)
Definition: where.c:927
static UINT WHERE_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
Definition: where.c:239
static UINT WHERE_set_stream(MSIVIEW *view, UINT row, UINT col, IStream *stream)
Definition: where.c:302
static UINT check_condition(MSIWHEREVIEW *wv, MSIRECORD *record, JOINTABLE **tables, UINT table_rows[])
Definition: where.c:650
struct tagJOINTABLE JOINTABLE
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define assert(x)
Definition: debug.h:53
struct nls_table * tables
Definition: nls_base.c:22
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOLEAN valid
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLenum GLint GLuint mask
Definition: glext.h:6028
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLuint GLfloat * val
Definition: glext.h:7180
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct task_struct * current
Definition: linux.c:32
static PVOID ptr
Definition: dispmode.c:27
static size_t elem
Definition: string.c:68
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
Definition: msipriv.h:1154
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
UINT msi_string2id(const string_table *st, const WCHAR *data, int len, UINT *id) DECLSPEC_HIDDEN
Definition: string.c:400
static void msi_free(void *mem)
Definition: msipriv.h:1159
BOOL MSI_RecordsAreFieldsEqual(MSIRECORD *a, MSIRECORD *b, UINT field) DECLSPEC_HIDDEN
Definition: record.c:957
#define MSITYPE_STRING
Definition: msipriv.h:50
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:213
const WCHAR * msi_string_lookup(const string_table *st, UINT id, int *len) DECLSPEC_HIDDEN
Definition: string.c:343
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
UINT MSI_RecordGetFieldCount(const MSIRECORD *rec) DECLSPEC_HIDDEN
Definition: record.c:108
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:76
UINT msi_view_get_row(MSIDATABASE *, MSIVIEW *, UINT, MSIRECORD **) DECLSPEC_HIDDEN
Definition: msiquery.c:353
#define MSITYPE_KEY
Definition: msipriv.h:52
UINT MSI_RecordCopyField(MSIRECORD *, UINT, MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:166
@ MSIMODIFY_DELETE
Definition: msiquery.h:57
@ MSIMODIFY_REPLACE
Definition: msiquery.h:55
@ MSIMODIFY_MERGE
Definition: msiquery.h:56
@ MSIMODIFY_INSERT_TEMPORARY
Definition: msiquery.h:58
@ MSIMODIFY_UPDATE
Definition: msiquery.h:53
@ MSIMODIFY_VALIDATE_DELETE
Definition: msiquery.h:62
@ MSIMODIFY_SEEK
Definition: msiquery.h:50
@ MSIMODIFY_ASSIGN
Definition: msiquery.h:54
@ MSIMODIFY_VALIDATE_NEW
Definition: msiquery.h:60
@ MSIMODIFY_INSERT
Definition: msiquery.h:52
@ MSIMODIFY_REFRESH
Definition: msiquery.h:51
@ MSIMODIFY_VALIDATE_FIELD
Definition: msiquery.h:61
@ MSIMODIFY_VALIDATE
Definition: msiquery.h:59
unsigned int UINT
Definition: ndis.h:50
#define EXPR_COL_NUMBER32
Definition: query.h:56
#define OP_LT
Definition: query.h:40
#define OP_GT
Definition: query.h:39
#define EXPR_STRCMP
Definition: query.h:53
#define EXPR_COMPLEX
Definition: query.h:47
UINT TABLE_CreateView(MSIDATABASE *db, LPCWSTR name, MSIVIEW **view) DECLSPEC_HIDDEN
Definition: table.c:2189
#define EXPR_WILDCARD
Definition: query.h:54
#define OP_EQ
Definition: query.h:36
#define OP_NOTNULL
Definition: query.h:45
#define EXPR_COL_NUMBER
Definition: query.h:49
#define EXPR_IVAL
Definition: query.h:50
#define OP_GE
Definition: query.h:42
#define EXPR_COL_NUMBER_STRING
Definition: query.h:55
#define OP_ISNULL
Definition: query.h:44
#define EXPR_COLUMN
Definition: query.h:48
#define EXPR_UNARY
Definition: query.h:57
#define OP_AND
Definition: query.h:37
#define EXPR_SVAL
Definition: query.h:51
#define OP_NE
Definition: query.h:43
#define EXPR_UVAL
Definition: query.h:52
#define OP_OR
Definition: query.h:38
#define OP_LE
Definition: query.h:41
static unsigned __int64 next
Definition: rand_nt.c:6
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define memset(x, y, z)
Definition: compat.h:39
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
#define TRACE(s)
Definition: solgame.cpp:4
Definition: query.h:87
struct complex_expr expr
Definition: query.h:91
UINT uval
Definition: query.h:93
union ext_column column
Definition: query.h:95
union expr::@507 u
int type
Definition: query.h:88
LPCWSTR sval
Definition: query.h:94
INT ival
Definition: query.h:92
Definition: name.c:39
Definition: parse.h:23
UINT col_count
Definition: where.c:51
MSIVIEW * view
Definition: where.c:50
UINT row_count
Definition: where.c:52
UINT table_index
Definition: where.c:53
struct tagJOINTABLE * next
Definition: where.c:49
MSIOBJECTHDR hdr
Definition: msipriv.h:108
string_table * strings
Definition: msipriv.h:110
union ext_column columns[1]
Definition: where.c:60
UINT error
Definition: where.c:59
UINT col_count
Definition: where.c:58
MSIOBJECTHDR hdr
Definition: msipriv.h:151
UINT values[1]
Definition: where.c:44
struct tagMSIWHEREVIEW * wv
Definition: where.c:43
UINT(* delete_row)(struct tagMSIVIEW *view, UINT row)
Definition: msipriv.h:288
const MSIVIEWOPS * ops
Definition: msipriv.h:355
UINT reorder_size
Definition: where.c:72
struct expr * cond
Definition: where.c:73
UINT table_count
Definition: where.c:70
MSIVIEW view
Definition: where.c:65
MSIROWENTRY ** reorder
Definition: where.c:71
UINT row_count
Definition: where.c:68
MSIDATABASE * db
Definition: where.c:66
JOINTABLE * tables
Definition: where.c:67
MSIORDERINFO * order_info
Definition: where.c:75
UINT col_count
Definition: where.c:69
UINT rec_index
Definition: where.c:74
#define new(TYPE, numElems)
Definition: treelist.c:54
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
struct ext_column::@506 parsed
LPCWSTR table
Definition: query.h:77
struct ext_column::@505 unparsed
int MSIMODIFY
Definition: winemsi.idl:33
#define ERROR_BAD_QUERY_SYNTAX
Definition: winerror.h:973
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185