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 #include <stdarg.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 27 #include "windef.h" 28 #include "winbase.h" 29 #include "query.h" 30 #include "wine/list.h" 31 #include "wine/debug.h" 32 33 WINE_DEFAULT_DEBUG_CHANNEL(msi); 34 35 static UINT SQL_getstring( void *info, const struct sql_str *strdata, LPWSTR *str ); 36 static INT SQL_getint( void *info ); 37 static int sql_lex( void *SQL_lval, SQL_input *info ); 38 static int sql_error( SQL_input *info, const char *str); 39 40 static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table ); 41 static void *parser_alloc( void *info, unsigned int sz ); 42 static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ); 43 44 static BOOL SQL_MarkPrimaryKeys( column_info **cols, column_info *keys); 45 46 static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ); 47 static struct expr * EXPR_unary( void *info, struct expr *l, UINT op ); 48 static struct expr * EXPR_column( void *info, const column_info *column ); 49 static struct expr * EXPR_ival( void *info, int val ); 50 static struct expr * EXPR_sval( void *info, const struct sql_str *str ); 51 static struct expr * EXPR_wildcard( void *info ); 52 53 #define PARSER_BUBBLE_UP_VIEW( sql, result, current_view ) \ 54 *sql->view = current_view; \ 55 result = current_view 56 57 %} 58 59 %lex-param { SQL_input *info } 60 %parse-param { SQL_input *info } 61 %define api.prefix {sql_} 62 %define api.pure 63 64 %union 65 { 66 struct sql_str str; 67 LPWSTR string; 68 column_info *column_list; 69 MSIVIEW *query; 70 struct expr *expr; 71 USHORT column_type; 72 int integer; 73 } 74 75 %token TK_ALTER TK_AND TK_BY TK_CHAR TK_COMMA TK_CREATE TK_DELETE TK_DROP 76 %token TK_DISTINCT TK_DOT TK_EQ TK_FREE TK_FROM TK_GE TK_GT TK_HOLD TK_ADD 77 %token <str> TK_ID 78 %token TK_ILLEGAL TK_INSERT TK_INT 79 %token <str> TK_INTEGER 80 %token TK_INTO TK_IS TK_KEY TK_LE TK_LONG TK_LONGCHAR TK_LP TK_LT 81 %token TK_LOCALIZABLE TK_MINUS TK_NE TK_NOT TK_NULL 82 %token TK_OBJECT TK_OR TK_ORDER TK_PRIMARY TK_RP 83 %token TK_SELECT TK_SET TK_SHORT TK_SPACE TK_STAR 84 %token <str> TK_STRING 85 %token TK_TABLE TK_TEMPORARY TK_UPDATE TK_VALUES TK_WHERE TK_WILDCARD 86 87 /* 88 * These are extra tokens used by the lexer but never seen by the 89 * parser. We put them in a rule so that the parser generator will 90 * add them to the parse.h output file. 91 * 92 */ 93 %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION 94 COLUMN AGG_FUNCTION. 95 96 %type <string> table tablelist id string 97 %type <column_list> selcollist collist selcolumn column column_and_type column_def table_def 98 %type <column_list> column_assignment update_assign_list constlist 99 %type <query> query from selectfrom unorderdfrom 100 %type <query> oneupdate onedelete oneselect onequery onecreate oneinsert onealter onedrop 101 %type <expr> expr val column_val const_val 102 %type <column_type> column_type data_type data_type_l data_count 103 %type <integer> number alterop 104 105 %left TK_OR 106 %left TK_AND 107 %left TK_NOT 108 %left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE 109 %right TK_NEGATION 110 111 %% 112 113 query: 114 onequery 115 { 116 SQL_input* sql = (SQL_input*) info; 117 *sql->view = $1; 118 } 119 ; 120 121 onequery: 122 oneselect 123 | onecreate 124 | oneinsert 125 | oneupdate 126 | onedelete 127 | onealter 128 | onedrop 129 ; 130 131 oneinsert: 132 TK_INSERT TK_INTO table TK_LP collist TK_RP TK_VALUES TK_LP constlist TK_RP 133 { 134 SQL_input *sql = (SQL_input*) info; 135 MSIVIEW *insert = NULL; 136 137 INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE ); 138 if( !insert ) 139 YYABORT; 140 141 PARSER_BUBBLE_UP_VIEW( sql, $$, insert ); 142 } 143 | TK_INSERT TK_INTO table TK_LP collist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMPORARY 144 { 145 SQL_input *sql = (SQL_input*) info; 146 MSIVIEW *insert = NULL; 147 148 INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE ); 149 if( !insert ) 150 YYABORT; 151 152 PARSER_BUBBLE_UP_VIEW( sql, $$, insert ); 153 } 154 ; 155 156 onecreate: 157 TK_CREATE TK_TABLE table TK_LP table_def TK_RP 158 { 159 SQL_input* sql = (SQL_input*) info; 160 MSIVIEW *create = NULL; 161 UINT r; 162 163 if( !$5 ) 164 YYABORT; 165 r = CREATE_CreateView( sql->db, &create, $3, $5, FALSE ); 166 if( !create ) 167 { 168 sql->r = r; 169 YYABORT; 170 } 171 172 PARSER_BUBBLE_UP_VIEW( sql, $$, create ); 173 } 174 | TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD 175 { 176 SQL_input* sql = (SQL_input*) info; 177 MSIVIEW *create = NULL; 178 179 if( !$5 ) 180 YYABORT; 181 CREATE_CreateView( sql->db, &create, $3, $5, TRUE ); 182 if( !create ) 183 YYABORT; 184 185 PARSER_BUBBLE_UP_VIEW( sql, $$, 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 199 PARSER_BUBBLE_UP_VIEW( sql, $$, 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 210 PARSER_BUBBLE_UP_VIEW( sql, $$, update ); 211 } 212 ; 213 214 onedelete: 215 TK_DELETE from 216 { 217 SQL_input* sql = (SQL_input*) info; 218 MSIVIEW *delete = NULL; 219 220 DELETE_CreateView( sql->db, &delete, $2 ); 221 if( !delete ) 222 YYABORT; 223 224 PARSER_BUBBLE_UP_VIEW( sql, $$, delete ); 225 } 226 ; 227 228 onealter: 229 TK_ALTER TK_TABLE table alterop 230 { 231 SQL_input* sql = (SQL_input*) info; 232 MSIVIEW *alter = NULL; 233 234 ALTER_CreateView( sql->db, &alter, $3, NULL, $4 ); 235 if( !alter ) 236 YYABORT; 237 238 PARSER_BUBBLE_UP_VIEW( sql, $$, alter ); 239 } 240 | TK_ALTER TK_TABLE table TK_ADD column_and_type 241 { 242 SQL_input *sql = (SQL_input *)info; 243 MSIVIEW *alter = NULL; 244 245 ALTER_CreateView( sql->db, &alter, $3, $5, 0 ); 246 if (!alter) 247 YYABORT; 248 249 PARSER_BUBBLE_UP_VIEW( sql, $$, alter ); 250 } 251 | TK_ALTER TK_TABLE table TK_ADD column_and_type TK_HOLD 252 { 253 SQL_input *sql = (SQL_input *)info; 254 MSIVIEW *alter = NULL; 255 256 ALTER_CreateView( sql->db, &alter, $3, $5, 1 ); 257 if (!alter) 258 YYABORT; 259 260 PARSER_BUBBLE_UP_VIEW( sql, $$, alter ); 261 } 262 ; 263 264 alterop: 265 TK_HOLD 266 { 267 $$ = 1; 268 } 269 | TK_FREE 270 { 271 $$ = -1; 272 } 273 ; 274 275 onedrop: 276 TK_DROP TK_TABLE table 277 { 278 SQL_input* sql = (SQL_input*) info; 279 MSIVIEW* drop = NULL; 280 UINT r; 281 282 r = DROP_CreateView( sql->db, &drop, $3 ); 283 if( r != ERROR_SUCCESS || !$$ ) 284 YYABORT; 285 286 PARSER_BUBBLE_UP_VIEW( sql, $$, drop ); 287 } 288 ; 289 290 table_def: 291 column_def TK_PRIMARY TK_KEY collist 292 { 293 if( SQL_MarkPrimaryKeys( &$1, $4 ) ) 294 $$ = $1; 295 else 296 $$ = NULL; 297 } 298 ; 299 300 column_def: 301 column_def TK_COMMA column_and_type 302 { 303 column_info *ci; 304 305 for( ci = $1; ci->next; ci = ci->next ) 306 ; 307 308 ci->next = $3; 309 $$ = $1; 310 } 311 | column_and_type 312 { 313 $$ = $1; 314 } 315 ; 316 317 column_and_type: 318 column column_type 319 { 320 $$ = $1; 321 $$->type = ($2 | MSITYPE_VALID); 322 } 323 ; 324 325 column_type: 326 data_type_l 327 { 328 $$ = $1; 329 } 330 | data_type_l TK_LOCALIZABLE 331 { 332 $$ = $1 | MSITYPE_LOCALIZABLE; 333 } 334 | data_type_l TK_TEMPORARY 335 { 336 $$ = $1 | MSITYPE_TEMPORARY; 337 } 338 ; 339 340 data_type_l: 341 data_type 342 { 343 $$ |= MSITYPE_NULLABLE; 344 } 345 | data_type TK_NOT TK_NULL 346 { 347 $$ = $1; 348 } 349 ; 350 351 data_type: 352 TK_CHAR 353 { 354 $$ = MSITYPE_STRING | 0x400; 355 } 356 | TK_CHAR TK_LP data_count TK_RP 357 { 358 $$ = MSITYPE_STRING | 0x400 | $3; 359 } 360 | TK_LONGCHAR 361 { 362 $$ = MSITYPE_STRING | 0x400; 363 } 364 | TK_SHORT 365 { 366 $$ = 2 | 0x400; 367 } 368 | TK_INT 369 { 370 $$ = 2 | 0x400; 371 } 372 | TK_LONG 373 { 374 $$ = 4; 375 } 376 | TK_OBJECT 377 { 378 $$ = MSITYPE_STRING | MSITYPE_VALID; 379 } 380 ; 381 382 data_count: 383 number 384 { 385 if( ( $1 > 255 ) || ( $1 < 0 ) ) 386 YYABORT; 387 $$ = $1; 388 } 389 ; 390 391 oneselect: 392 TK_SELECT selectfrom 393 { 394 $$ = $2; 395 } 396 | TK_SELECT TK_DISTINCT selectfrom 397 { 398 SQL_input* sql = (SQL_input*) info; 399 MSIVIEW* distinct = NULL; 400 UINT r; 401 402 r = DISTINCT_CreateView( sql->db, &distinct, $3 ); 403 if (r != ERROR_SUCCESS) 404 YYABORT; 405 406 PARSER_BUBBLE_UP_VIEW( sql, $$, distinct ); 407 } 408 ; 409 410 selectfrom: 411 selcollist from 412 { 413 SQL_input* sql = (SQL_input*) info; 414 MSIVIEW* select = NULL; 415 UINT r; 416 417 if( $1 ) 418 { 419 r = SELECT_CreateView( sql->db, &select, $2, $1 ); 420 if (r != ERROR_SUCCESS) 421 YYABORT; 422 423 PARSER_BUBBLE_UP_VIEW( sql, $$, select ); 424 } 425 else 426 $$ = $2; 427 } 428 ; 429 430 selcollist: 431 selcolumn 432 | selcolumn TK_COMMA selcollist 433 { 434 $1->next = $3; 435 } 436 | TK_STAR 437 { 438 $$ = NULL; 439 } 440 ; 441 442 collist: 443 column 444 | column TK_COMMA collist 445 { 446 $1->next = $3; 447 } 448 | TK_STAR 449 { 450 $$ = NULL; 451 } 452 ; 453 454 from: 455 TK_FROM table 456 { 457 SQL_input* sql = (SQL_input*) info; 458 MSIVIEW* table = NULL; 459 UINT r; 460 461 r = TABLE_CreateView( sql->db, $2, &table ); 462 if( r != ERROR_SUCCESS || !$$ ) 463 YYABORT; 464 465 PARSER_BUBBLE_UP_VIEW( sql, $$, table ); 466 } 467 | unorderdfrom TK_ORDER TK_BY collist 468 { 469 UINT r; 470 471 if( $4 ) 472 { 473 r = $1->ops->sort( $1, $4 ); 474 if ( r != ERROR_SUCCESS) 475 YYABORT; 476 } 477 478 $$ = $1; 479 } 480 | unorderdfrom 481 ; 482 483 unorderdfrom: 484 TK_FROM tablelist 485 { 486 SQL_input* sql = (SQL_input*) info; 487 MSIVIEW* where = NULL; 488 UINT r; 489 490 r = WHERE_CreateView( sql->db, &where, $2, NULL ); 491 if( r != ERROR_SUCCESS ) 492 YYABORT; 493 494 PARSER_BUBBLE_UP_VIEW( sql, $$, where ); 495 } 496 | TK_FROM tablelist TK_WHERE expr 497 { 498 SQL_input* sql = (SQL_input*) info; 499 MSIVIEW* where = NULL; 500 UINT r; 501 502 r = WHERE_CreateView( sql->db, &where, $2, $4 ); 503 if( r != ERROR_SUCCESS ) 504 YYABORT; 505 506 PARSER_BUBBLE_UP_VIEW( sql, $$, where ); 507 } 508 ; 509 510 tablelist: 511 table 512 { 513 $$ = $1; 514 } 515 | table TK_COMMA tablelist 516 { 517 $$ = parser_add_table( info, $3, $1 ); 518 if (!$$) 519 YYABORT; 520 } 521 ; 522 523 expr: 524 TK_LP expr TK_RP 525 { 526 $$ = $2; 527 if( !$$ ) 528 YYABORT; 529 } 530 | expr TK_AND expr 531 { 532 $$ = EXPR_complex( info, $1, OP_AND, $3 ); 533 if( !$$ ) 534 YYABORT; 535 } 536 | expr TK_OR expr 537 { 538 $$ = EXPR_complex( info, $1, OP_OR, $3 ); 539 if( !$$ ) 540 YYABORT; 541 } 542 | column_val TK_EQ val 543 { 544 $$ = EXPR_complex( info, $1, OP_EQ, $3 ); 545 if( !$$ ) 546 YYABORT; 547 } 548 | column_val TK_GT val 549 { 550 $$ = EXPR_complex( info, $1, OP_GT, $3 ); 551 if( !$$ ) 552 YYABORT; 553 } 554 | column_val TK_LT val 555 { 556 $$ = EXPR_complex( info, $1, OP_LT, $3 ); 557 if( !$$ ) 558 YYABORT; 559 } 560 | column_val TK_LE val 561 { 562 $$ = EXPR_complex( info, $1, OP_LE, $3 ); 563 if( !$$ ) 564 YYABORT; 565 } 566 | column_val TK_GE val 567 { 568 $$ = EXPR_complex( info, $1, OP_GE, $3 ); 569 if( !$$ ) 570 YYABORT; 571 } 572 | column_val TK_NE val 573 { 574 $$ = EXPR_complex( info, $1, OP_NE, $3 ); 575 if( !$$ ) 576 YYABORT; 577 } 578 | column_val TK_IS TK_NULL 579 { 580 $$ = EXPR_unary( info, $1, OP_ISNULL ); 581 if( !$$ ) 582 YYABORT; 583 } 584 | column_val TK_IS TK_NOT TK_NULL 585 { 586 $$ = EXPR_unary( info, $1, OP_NOTNULL ); 587 if( !$$ ) 588 YYABORT; 589 } 590 ; 591 592 val: 593 column_val 594 | const_val 595 ; 596 597 constlist: 598 const_val 599 { 600 $$ = parser_alloc_column( info, NULL, NULL ); 601 if( !$$ ) 602 YYABORT; 603 $$->val = $1; 604 } 605 | const_val TK_COMMA constlist 606 { 607 $$ = parser_alloc_column( info, NULL, NULL ); 608 if( !$$ ) 609 YYABORT; 610 $$->val = $1; 611 $$->next = $3; 612 } 613 ; 614 615 update_assign_list: 616 column_assignment 617 | column_assignment TK_COMMA update_assign_list 618 { 619 $$ = $1; 620 $$->next = $3; 621 } 622 ; 623 624 column_assignment: 625 column TK_EQ const_val 626 { 627 $$ = $1; 628 $$->val = $3; 629 } 630 ; 631 632 const_val: 633 number 634 { 635 $$ = EXPR_ival( info, $1 ); 636 if( !$$ ) 637 YYABORT; 638 } 639 | TK_MINUS number %prec TK_NEGATION 640 { 641 $$ = EXPR_ival( info, -$2 ); 642 if( !$$ ) 643 YYABORT; 644 } 645 | TK_STRING 646 { 647 $$ = EXPR_sval( info, &$1 ); 648 if( !$$ ) 649 YYABORT; 650 } 651 | TK_WILDCARD 652 { 653 $$ = EXPR_wildcard( info ); 654 if( !$$ ) 655 YYABORT; 656 } 657 | TK_NULL 658 { 659 $$ = EXPR_sval( info, NULL ); 660 if ( !$$ ) 661 YYABORT; 662 } 663 ; 664 665 column_val: 666 column 667 { 668 $$ = EXPR_column( info, $1 ); 669 if( !$$ ) 670 YYABORT; 671 } 672 ; 673 674 column: 675 table TK_DOT id 676 { 677 $$ = parser_alloc_column( info, $1, $3 ); 678 if( !$$ ) 679 YYABORT; 680 } 681 | id 682 { 683 $$ = parser_alloc_column( info, NULL, $1 ); 684 if( !$$ ) 685 YYABORT; 686 } 687 ; 688 689 selcolumn: 690 table TK_DOT id 691 { 692 $$ = parser_alloc_column( info, $1, $3 ); 693 if( !$$ ) 694 YYABORT; 695 } 696 | id 697 { 698 $$ = parser_alloc_column( info, NULL, $1 ); 699 if( !$$ ) 700 YYABORT; 701 } 702 | string 703 { 704 $$ = parser_alloc_column( info, NULL, $1 ); 705 if( !$$ ) 706 YYABORT; 707 } 708 ; 709 710 table: 711 id 712 { 713 $$ = $1; 714 } 715 ; 716 717 id: 718 TK_ID 719 { 720 if ( SQL_getstring( info, &$1, &$$ ) != ERROR_SUCCESS || !$$ ) 721 YYABORT; 722 } 723 ; 724 725 string: 726 TK_STRING 727 { 728 if ( SQL_getstring( info, &$1, &$$ ) != ERROR_SUCCESS || !$$ ) 729 YYABORT; 730 } 731 ; 732 733 number: 734 TK_INTEGER 735 { 736 $$ = SQL_getint( info ); 737 } 738 ; 739 740 %% 741 742 static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table ) 743 { 744 DWORD len = lstrlenW( list ) + lstrlenW( table ) + 2; 745 LPWSTR ret; 746 747 ret = parser_alloc( info, len * sizeof(WCHAR) ); 748 if( ret ) 749 { 750 lstrcpyW( ret, list ); 751 lstrcatW( ret, L" " ); 752 lstrcatW( ret, table ); 753 } 754 return ret; 755 } 756 757 static void *parser_alloc( void *info, unsigned int sz ) 758 { 759 SQL_input* sql = (SQL_input*) info; 760 struct list *mem; 761 762 mem = malloc( sizeof (struct list) + sz ); 763 list_add_tail( sql->mem, mem ); 764 return &mem[1]; 765 } 766 767 static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ) 768 { 769 column_info *col; 770 771 col = parser_alloc( info, sizeof (*col) ); 772 if( col ) 773 { 774 col->table = table; 775 col->column = column; 776 col->val = NULL; 777 col->type = 0; 778 col->next = NULL; 779 } 780 781 return col; 782 } 783 784 static int sql_lex( void *SQL_lval, SQL_input *sql ) 785 { 786 int token, skip; 787 struct sql_str * str = SQL_lval; 788 789 do 790 { 791 sql->n += sql->len; 792 if( ! sql->command[sql->n] ) 793 return 0; /* end of input */ 794 795 /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */ 796 sql->len = sqliteGetToken( &sql->command[sql->n], &token, &skip ); 797 if( sql->len==0 ) 798 break; 799 str->data = &sql->command[sql->n]; 800 str->len = sql->len; 801 sql->n += skip; 802 } 803 while( token == TK_SPACE ); 804 805 /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */ 806 807 return token; 808 } 809 810 UINT SQL_getstring( void *info, const struct sql_str *strdata, LPWSTR *str ) 811 { 812 LPCWSTR p = strdata->data; 813 UINT len = strdata->len; 814 815 /* match quotes */ 816 if( ( (p[0]=='`') && (p[len-1]!='`') ) || 817 ( (p[0]=='\'') && (p[len-1]!='\'') ) ) 818 return ERROR_FUNCTION_FAILED; 819 820 /* if there are quotes, remove them */ 821 if( ( (p[0]=='`') && (p[len-1]=='`') ) || 822 ( (p[0]=='\'') && (p[len-1]=='\'') ) ) 823 { 824 p++; 825 len -= 2; 826 } 827 *str = parser_alloc( info, (len + 1)*sizeof(WCHAR) ); 828 if( !*str ) 829 return ERROR_OUTOFMEMORY; 830 memcpy( *str, p, len*sizeof(WCHAR) ); 831 (*str)[len]=0; 832 833 return ERROR_SUCCESS; 834 } 835 836 INT SQL_getint( void *info ) 837 { 838 SQL_input* sql = (SQL_input*) info; 839 LPCWSTR p = &sql->command[sql->n]; 840 INT i, r = 0; 841 842 for( i=0; i<sql->len; i++ ) 843 { 844 if( '0' > p[i] || '9' < p[i] ) 845 { 846 ERR("should only be numbers here!\n"); 847 break; 848 } 849 r = (p[i]-'0') + r*10; 850 } 851 852 return r; 853 } 854 855 static int sql_error( SQL_input *info, const char *str ) 856 { 857 return 0; 858 } 859 860 static struct expr * EXPR_wildcard( void *info ) 861 { 862 struct expr *e = parser_alloc( info, sizeof *e ); 863 if( e ) 864 { 865 e->type = EXPR_WILDCARD; 866 } 867 return e; 868 } 869 870 static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ) 871 { 872 struct expr *e = parser_alloc( info, sizeof *e ); 873 if( e ) 874 { 875 e->type = EXPR_COMPLEX; 876 e->u.expr.left = l; 877 e->u.expr.op = op; 878 e->u.expr.right = r; 879 } 880 return e; 881 } 882 883 static struct expr * EXPR_unary( void *info, struct expr *l, UINT op ) 884 { 885 struct expr *e = parser_alloc( info, sizeof *e ); 886 if( e ) 887 { 888 e->type = EXPR_UNARY; 889 e->u.expr.left = l; 890 e->u.expr.op = op; 891 e->u.expr.right = NULL; 892 } 893 return e; 894 } 895 896 static struct expr * EXPR_column( void *info, const column_info *column ) 897 { 898 struct expr *e = parser_alloc( info, sizeof *e ); 899 if( e ) 900 { 901 e->type = EXPR_COLUMN; 902 e->u.column.unparsed.column = column->column; 903 e->u.column.unparsed.table = column->table; 904 } 905 return e; 906 } 907 908 static struct expr * EXPR_ival( void *info, int val ) 909 { 910 struct expr *e = parser_alloc( info, sizeof *e ); 911 if( e ) 912 { 913 e->type = EXPR_IVAL; 914 e->u.ival = val; 915 } 916 return e; 917 } 918 919 static struct expr * EXPR_sval( void *info, const struct sql_str *str ) 920 { 921 struct expr *e = parser_alloc( info, sizeof *e ); 922 if( e ) 923 { 924 e->type = EXPR_SVAL; 925 if( !str) e->u.sval = NULL; 926 else if( SQL_getstring( info, str, (LPWSTR *)&e->u.sval ) != ERROR_SUCCESS ) 927 return NULL; /* e will be freed by query destructor */ 928 } 929 return e; 930 } 931 932 static void swap_columns( column_info **cols, column_info *A, int idx ) 933 { 934 column_info *preA = NULL, *preB = NULL, *B, *ptr; 935 int i = 0; 936 937 B = NULL; 938 ptr = *cols; 939 while( ptr ) 940 { 941 if( i++ == idx ) 942 B = ptr; 943 else if( !B ) 944 preB = ptr; 945 946 if( ptr->next == A ) 947 preA = ptr; 948 949 ptr = ptr->next; 950 } 951 952 if( preB ) preB->next = A; 953 if( preA ) preA->next = B; 954 ptr = A->next; 955 A->next = B->next; 956 B->next = ptr; 957 if( idx == 0 ) 958 *cols = A; 959 } 960 961 static BOOL SQL_MarkPrimaryKeys( column_info **cols, 962 column_info *keys ) 963 { 964 column_info *k; 965 BOOL found = TRUE; 966 int count; 967 968 for( k = keys, count = 0; k && found; k = k->next, count++ ) 969 { 970 column_info *c; 971 int idx; 972 973 found = FALSE; 974 for( c = *cols, idx = 0; c && !found; c = c->next, idx++ ) 975 { 976 if( wcscmp( k->column, c->column ) ) 977 continue; 978 c->type |= MSITYPE_KEY; 979 found = TRUE; 980 if (idx != count) 981 swap_columns( cols, c, count ); 982 } 983 } 984 985 return found; 986 } 987 988 UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, 989 struct list *mem ) 990 { 991 SQL_input sql; 992 int r; 993 994 *phview = NULL; 995 996 sql.db = db; 997 sql.command = command; 998 sql.n = 0; 999 sql.len = 0; 1000 sql.r = ERROR_BAD_QUERY_SYNTAX; 1001 sql.view = phview; 1002 sql.mem = mem; 1003 1004 r = sql_parse(&sql); 1005 1006 TRACE("Parse returned %d\n", r); 1007 if( r ) 1008 { 1009 if (*sql.view) 1010 { 1011 (*sql.view)->ops->delete(*sql.view); 1012 *sql.view = NULL; 1013 } 1014 return sql.r; 1015 } 1016 1017 return ERROR_SUCCESS; 1018 } 1019