1 /* This file is part of the KDE project 2 Copyright (C) 2004 Lucijan Busch <lucijan@kde.org> 3 Copyright (C) 2004-2018 Jarosław Staniek <staniek@kde.org> 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public License 16 along with this library; see the file COPYING.LIB. If not, write to 17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 21 // To keep binary compatibility, do not reorder tokens! Add new only at the end. 22 %token SQL_TYPE 23 %token AS 24 %token AS_EMPTY /* used for aliases with skipped AS keyword */ 25 %token ASC 26 %token AUTO_INCREMENT 27 %token BIT 28 %token BITWISE_SHIFT_LEFT 29 %token BITWISE_SHIFT_RIGHT 30 %token BY 31 %token CHARACTER_STRING_LITERAL 32 %token CONCATENATION /* || */ 33 %token CREATE 34 %token DESC 35 %token DISTINCT 36 %token DOUBLE_QUOTED_STRING 37 %token FROM 38 %token JOIN 39 %token KEY 40 %token LEFT 41 %token LESS_OR_EQUAL 42 %token GREATER_OR_EQUAL 43 %token SQL_NULL 44 %token SQL_IS 45 %token SQL_IS_NULL /*helper */ 46 %token SQL_IS_NOT_NULL /*helper */ 47 %token ORDER 48 %token PRIMARY 49 %token SELECT 50 %token INTEGER_CONST 51 %token REAL_CONST 52 %token RIGHT 53 %token SQL_ON 54 %token DATE_CONST 55 %token DATETIME_CONST 56 %token TIME_CONST 57 %token TABLE 58 %token IDENTIFIER 59 %token IDENTIFIER_DOT_ASTERISK 60 %token QUERY_PARAMETER 61 %token VARCHAR 62 %token WHERE 63 %token SQL 64 %token SQL_TRUE 65 %token SQL_FALSE 66 %token UNION 67 68 %token SCAN_ERROR 69 70 //%token SQL_ABS 71 //%token ACOS 72 //%token AMPERSAND 73 //%token SQL_ABSOLUTE 74 //%token ADA 75 //%token ADD 76 //%token ADD_DAYS 77 //%token ADD_HOURS 78 //%token ADD_MINUTES 79 //%token ADD_MONTHS 80 //%token ADD_SECONDS 81 //%token ADD_YEARS 82 //%token ALL 83 //%token ALLOCATE 84 //%token ALTER 85 %token AND 86 //%token ANY 87 //%token ARE 88 //%token ASIN 89 //%token ASCII 90 //%token ASSERTION 91 //%token ATAN 92 //%token ATAN2 93 //%token AUTHORIZATION 94 //%token AVG 95 //%token BEFORE 96 %token BETWEEN 97 %token NOT_BETWEEN 98 //%token SQL_BEGIN 99 //%token BIGINT 100 //%token BINARY 101 //%token BIT_LENGTH 102 //%token BREAK 103 //%token CASCADE 104 //%token CASCADED 105 //%token CASE 106 //%token CAST 107 //%token CATALOG 108 //%token CEILING 109 //%token CENTER 110 //%token SQL_CHAR 111 //%token CHAR_LENGTH 112 //%token CHECK 113 //%token CLOSE 114 //%token COALESCE 115 //%token COBOL 116 //%token COLLATE 117 //%token COLLATION 118 //%token COLUMN 119 //%token COMMIT 120 //%token COMPUTE 121 //%token CONCAT 122 //%token CONNECT 123 //%token CONNECTION 124 //%token CONSTRAINT 125 //%token CONSTRAINTS 126 //%token CONTINUE 127 //%token CONVERT 128 //%token CORRESPONDING 129 //%token COS 130 //%token COT 131 //%token COUNT 132 //%token CURDATE 133 //%token CURRENT 134 //%token CURRENT_DATE 135 //%token CURRENT_TIME 136 //%token CURRENT_TIMESTAMP 137 //%token CURTIME 138 //%token CURSOR 139 //%token DATABASE 140 //%token SQL_DATE 141 //%token DATE_FORMAT 142 //%token DATE_REMAINDER 143 //%token DATE_VALUE 144 //%token DAY 145 //%token DAYOFMONTH 146 //%token DAYOFWEEK 147 //%token DAYOFYEAR 148 //%token DAYS_BETWEEN 149 //%token DEALLOCATE 150 //%token DEC 151 //%token DECLARE 152 //%token DEFAULT 153 //%token DEFERRABLE 154 //%token DEFERRED 155 //%token SQL_DELETE 156 //%token DESCRIBE 157 //%token DESCRIPTOR 158 //%token DIAGNOSTICS 159 //%token DICTIONARY 160 //%token DIRECTORY 161 //%token DISCONNECT 162 //%token DISPLACEMENT 163 //%token DOMAIN_TOKEN 164 //%token SQL_DOUBLE 165 //%token DROP 166 //%token ELSE 167 //%token END 168 //%token END_EXEC 169 //%token ESCAPE 170 %token EXCEPT 171 //%token SQL_EXCEPTION 172 //%token EXEC 173 //%token EXECUTE 174 //%token EXISTS 175 //%token EXP 176 //%token EXPONENT 177 //%token EXTERNAL 178 //%token EXTRACT 179 //%token FETCH 180 //%token FIRST 181 //%token SQL_FLOAT 182 //%token FLOOR 183 //%token FN 184 //%token FOR 185 //%token FOREIGN 186 //%token FORTRAN 187 //%token FOUND 188 //%token FOUR_DIGITS 189 //%token FULL 190 //%token GET 191 //%token GLOBAL 192 //%token GO 193 //%token GOTO 194 //%token GRANT 195 //conflict %token GROUP 196 //%token HAVING 197 //%token HOUR 198 //%token HOURS_BETWEEN 199 //%token IDENTITY 200 //%token IFNULL 201 //%token SQL_IGNORE 202 //%token IMMEDIATE 203 //%token INCLUDE 204 //%token INDEX 205 //%token INDICATOR 206 //%token INITIALLY 207 //%token INNER 208 //%token SQL_INPUT 209 %token SQL_IN 210 //%token INSENSITIVE 211 //%token INSERT 212 //%token INTEGER 213 %token INTERSECT 214 //%token INTERVAL 215 //%token INTO 216 //%token IS 217 //%token ISOLATION 218 //%token JUSTIFY 219 //%token LANGUAGE 220 //%token LAST 221 //%token LCASE 222 //%token LENGTH 223 //%token LEVEL 224 %token LIKE 225 %token ILIKE 226 %token NOT_LIKE 227 //%token LINE_WIDTH 228 //%token LOCAL 229 //%token LOCATE 230 //%token LOG 231 //%token SQL_LONG 232 //%token LOWER 233 //%token LTRIM 234 //%token LTRIP 235 //%token MATCH 236 //%token SQL_MAX 237 //%token MICROSOFT 238 //%token SQL_MIN 239 //%token MINUTE 240 //%token MINUTES_BETWEEN 241 //%token MOD 242 //%token MODIFY 243 //%token MODULE 244 //%token MONTH 245 //%token MONTHS_BETWEEN 246 //%token MUMPS 247 //%token NAMES 248 //%token NATIONAL 249 //%token NCHAR 250 //%token NEXT 251 //%token NODUP 252 //%token NONE 253 %token NOT 254 %token NOT_EQUAL 255 %token NOT_EQUAL2 256 //%token NOW 257 //%token NULLIF 258 //%token NUMERIC 259 //%token OCTET_LENGTH 260 //%token ODBC 261 //%token OF 262 //%token SQL_OFF 263 //%token ONLY 264 //%token OPEN 265 //%token OPTION 266 //%token OUTER 267 //%token OUTPUT 268 //%token OVERLAPS 269 //%token PAGE 270 //%token PARTIAL 271 //%token SQL_PASCAL 272 //%token PERSISTENT 273 //%token CQL_PI 274 %token OR 275 //%token PLI 276 //%token POSITION 277 //%token PRECISION 278 //%token PREPARE 279 //%token PRESERVE 280 //%token PRIOR 281 //%token PRIVILEGES 282 //%token PROCEDURE 283 //%token PRODUCT 284 //%token PUBLIC 285 //%token QUARTER 286 //%token QUIT 287 //%token RAND 288 //%token READ_ONLY 289 //%token REAL 290 //%token REFERENCES 291 //%token REPEAT 292 //%token REPLACE 293 //%token RESTRICT 294 //%token REVOKE 295 //%token ROLLBACK 296 //%token ROWS 297 //%token RPAD 298 //%token RTRIM 299 //%token SCHEMA 300 //%token SCREEN_WIDTH 301 //%token SCROLL 302 //%token SECOND 303 //%token SECONDS_BETWEEN 304 //%token SEQUENCE 305 //%token SETOPT 306 //%token SET 307 //%token SHOWOPT 308 //%token SIGN 309 %token SIMILAR_TO 310 %token NOT_SIMILAR_TO 311 //%token SIN 312 //%token SQL_SIZE 313 //%token SMALLINT 314 //%token SOME 315 //%token SPACE 316 //%token SQLCA 317 //%token SQLCODE 318 //%token SQLERROR 319 //%token SQLSTATE 320 //%token SQLWARNING 321 //%token SQRT 322 //%token STDEV 323 //%token SUBSTRING 324 //%token SUM 325 //%token SYSDATE 326 //%token SYSDATE_FORMAT 327 //%token SYSTEM 328 //%token TAN 329 //%token TEMPORARY 330 //%token THEN 331 //%token THREE_DIGITS 332 //%token TIME 333 //%token TIMESTAMP 334 //%token TIMEZONE_HOUR 335 //%token TIMEZONE_MINUTE 336 //%token TINYINT 337 //%token TO 338 //%token TO_CHAR 339 //%token TO_DATE 340 //%token TRANSACTION 341 //%token TRANSLATE 342 //%token TRANSLATION 343 //%token TRUNCATE 344 //%token GENERAL_TITLE 345 //%token TWO_DIGITS 346 //%token UCASE 347 //%token UNIQUE 348 //%token SQL_UNKNOWN 349 //%token UNSIGNED_INTEGER 350 //%token UPDATE 351 //%token UPPER 352 //%token USAGE 353 //%token USER 354 //%token ERROR_DIGIT_BEFORE_IDENTIFIER 355 //%token USING 356 //%token VALUE 357 //%token VALUES 358 //%token VARBINARY 359 //%token VARYING 360 //%token VENDOR 361 //%token VIEW 362 //%token WEEK 363 //%token WHEN 364 //%token WHENEVER 365 //%token WHERE_CURRENT_OF 366 //%token WITH 367 //%token WORD_WRAPPED 368 //%token WORK 369 //%token WRAPPED 370 %token XOR 371 //%token YEAR 372 //%token YEARS_BETWEEN 373 %token UMINUS 374 %token TABS_OR_SPACES // e.g. inside of date or time constants 375 %token DATE_TIME_INTEGER // inside of date or time constants 376 %token TIME_AM 377 %token TIME_PM 378 379 %type <stringValue> IDENTIFIER 380 %type <stringValue> IDENTIFIER_DOT_ASTERISK 381 %type <stringValue> QUERY_PARAMETER 382 %type <stringValue> CHARACTER_STRING_LITERAL 383 %type <stringValue> DOUBLE_QUOTED_STRING 384 385 /* 386 %type <field> ColExpression 387 %type <field> ColView 388 */ 389 %type <expr> ColExpression 390 %type <expr> ColWildCard 391 //%type <expr> ColView 392 %type <expr> ColItem 393 %type <exprList> ColViews 394 %type <expr> aExpr 395 %type <expr> aExpr2 396 %type <expr> aExpr3 397 %type <expr> aExpr4 398 %type <expr> aExpr5 399 %type <expr> aExpr6 400 %type <expr> aExpr7 401 %type <expr> aExpr8 402 %type <expr> aExpr9 403 %type <expr> aExpr10 404 %type <dateValue> DateConst 405 %type <dateValue> DateValue 406 %type <yearValue> YearConst 407 %type <timeValue> TimeConst 408 %type <timeValue> TimeValue 409 %type <dateTimeValue> DateTimeConst 410 %type <binaryValue> TimeMs 411 %type <timePeriodValue> TimePeriod 412 %type <exprList> aExprList 413 %type <exprList> aExprList2 414 %type <expr> WhereClause 415 %type <orderByColumns> OrderByClause 416 %type <sortOrderValue> OrderByOption 417 %type <variantValue> OrderByColumnId 418 %type <selectOptions> SelectOptions 419 %type <expr> FlatTable 420 %type <exprList> Tables 421 %type <exprList> FlatTableList 422 %type <querySchema> SelectStatement 423 %type <querySchema> Select 424 /*todo : list*/ 425 %type <querySchema> StatementList 426 /*todo: not only select*/ 427 %type <querySchema> Statement 428 429 %type <colType> SQL_TYPE 430 %type <integerValue> INTEGER_CONST 431 %type <binaryValue> REAL_CONST 432 %type <binaryValue> DATE_TIME_INTEGER 433 /*%type <integerValue> SIGNED_INTEGER */ 434 435 %{ 436 #include <stdio.h> 437 #include <string.h> 438 #include <string> 439 #include <iostream> 440 #include <limits.h> 441 //! @todo OK? 442 #ifdef Q_OS_WIN 443 //workaround for bug on msvc 444 # undef LLONG_MIN 445 #endif 446 #ifndef LLONG_MAX 447 # define LLONG_MAX 0x7fffffffffffffffLL 448 #endif 449 #ifndef LLONG_MIN 450 # define LLONG_MIN 0x8000000000000000LL 451 #endif 452 #ifndef LLONG_MAX 453 # define ULLONG_MAX 0xffffffffffffffffLL 454 #endif 455 456 #ifdef _WIN32 457 # include <malloc.h> 458 #endif 459 460 #include <QObject> 461 #include <QVariant> 462 #include <QPoint> 463 464 #include "KDbConnection.h" 465 #include "KDbDateTime.h" 466 #include "KDbExpression.h" 467 #include "KDbField.h" 468 #include "KDbOrderByColumn.h" 469 #include "KDbParser.h" 470 #include "KDbParser_p.h" 471 #include "KDbQuerySchema.h" 472 #include "KDbQuerySchema_p.h" 473 #include "KDbSqlTypes.h" 474 #include "KDbTableSchema.h" 475 #include "kdb_debug.h" 476 477 struct OrderByColumnInternal; 478 479 #ifdef Q_OS_SOLARIS 480 #include <alloca.h> 481 #endif 482 483 QDebug operator<<(QDebug dbg, const KDbExpressionPtr& expr) 484 { 485 dbg.nospace() << expr.e; 486 return dbg.space(); 487 } 488 489 int yylex(); 490 491 #define YY_NO_UNPUT 492 #define YYSTACK_USE_ALLOCA 1 493 #define YYMAXDEPTH 255 494 495 extern "C" 496 { yywrap()497 int yywrap() 498 { 499 return 1; 500 } 501 } 502 503 %} 504 505 %union { 506 QString* stringValue; 507 QByteArray* binaryValue; 508 qint64 integerValue; 509 bool booleanValue; 510 KDbDate* dateValue; 511 KDbYear* yearValue; 512 KDbTime* timeValue; 513 KDbTime::Period timePeriodValue; 514 KDbDateTime* dateTimeValue; 515 KDbOrderByColumn::SortOrder sortOrderValue; 516 KDbField::Type colType; 517 KDbField *field; 518 KDbExpression *expr; 519 KDbNArgExpression *exprList; 520 KDbConstExpression *constExpression; 521 KDbQuerySchema *querySchema; 522 SelectOptionsInternal *selectOptions; 523 QList<OrderByColumnInternal> *orderByColumns; 524 QVariant *variantValue; 525 } 526 527 /* precedence: lowest to highest */ 528 //%nonassoc SIMILAR 529 //%nonassoc ESCAPE 530 //%nonassoc OVERLAPS 531 //%nonassoc IN_P 532 //%left POSTFIXOP // dummy for postfix Op rules 533 //%left Op OPERATOR // multi-character ops and user-defined operators 534 //%nonassoc NOTNULL 535 //%nonassoc ISNULL 536 //%nonassoc IS // sets precedence for IS NULL, etc 537 //%nonassoc NULL_P 538 //%nonassoc TRUE_P 539 //%nonassoc FALSE_P 540 541 // <-- To keep binary compatibility insert new tokens here. 542 543 /* 544 * These might seem to be low-precedence, but actually they are not part 545 * of the arithmetic hierarchy at all in their use as JOIN operators. 546 * We make them high-precedence to support their use as function names. 547 * They wouldn't be given a precedence at all, were it not that we need 548 * left-associativity among the JOIN rules themselves. 549 */ 550 /* 551 %left JOIN 552 %left UNIONJOIN 553 %left CROSS 554 %left LEFT 555 %left FULL 556 %left RIGHT 557 %left INNER_P 558 %left NATURAL 559 */ 560 561 %% 562 563 TopLevelStatement : 564 StatementList 565 { 566 //todo: multiple statements 567 //todo: not only "select" statements 568 KDbParserPrivate::get(globalParser)->setStatementType(KDbParser::Select); 569 KDbParserPrivate::get(globalParser)->setQuerySchema($1); 570 } 571 ; 572 573 StatementList: 574 Statement ';' StatementList 575 { 576 //todo: multiple statements 577 } 578 | Statement 579 | Statement ';' 580 { 581 $$ = $1; 582 } 583 ; 584 585 /* Statement CreateTableStatement { YYACCEPT; } 586 | Statement SelectStatement { } 587 */ 588 Statement : 589 /*CreateTableStatement 590 { 591 YYACCEPT; 592 } 593 | */ 594 SelectStatement 595 { 596 $$ = $1; 597 } 598 ; 599 600 /*CreateTableStatement : 601 CREATE TABLE IDENTIFIER 602 { 603 globalParser->setStatementType(KDbParser::CreateTable); 604 globalParser->createTable($3->toLatin1()); 605 delete $3; 606 } 607 '(' ColDefs ')' 608 ; 609 610 ColDefs: 611 ColDefs ',' ColDef|ColDef 612 { 613 } 614 ; 615 616 ColDef: 617 IDENTIFIER ColType 618 { 619 sqlParserDebug() << "adding field " << *$1; 620 globalField->setName(*$1); 621 globalParser->table()->addField(globalField); 622 globalField = nullptr; 623 delete $1; 624 } 625 | IDENTIFIER ColType ColKeys 626 { 627 sqlParserDebug() << "adding field " << *$1; 628 globalField->setName(*$1); 629 delete $1; 630 globalParser->table()->addField(globalField); 631 632 // if(globalField->isPrimaryKey()) 633 // globalParser->table()->addPrimaryKey(globalField->name()); 634 635 // delete globalField; 636 // globalField = nullptr; 637 } 638 ; 639 640 ColKeys: 641 ColKeys ColKey|ColKey 642 { 643 } 644 ; 645 646 ColKey: 647 PRIMARY KEY 648 { 649 globalField->setPrimaryKey(true); 650 sqlParserDebug() << "primary"; 651 } 652 | NOT SQL_NULL 653 { 654 globalField->setNotNull(true); 655 sqlParserDebug() << "not_null"; 656 } 657 | AUTO_INCREMENT 658 { 659 globalField->setAutoIncrement(true); 660 sqlParserDebug() << "ainc"; 661 } 662 ; 663 664 ColType: 665 SQL_TYPE 666 { 667 globalField = new KDbField(); 668 globalField->setType($1); 669 } 670 | SQL_TYPE '(' INTEGER_CONST ')' 671 { 672 sqlParserDebug() << "sql + length"; 673 globalField = new KDbField(); 674 globalField->setPrecision($3); 675 globalField->setType($1); 676 } 677 | VARCHAR '(' INTEGER_CONST ')' 678 { 679 globalField = new KDbField(); 680 globalField->setPrecision($3); 681 globalField->setType(KDbField::Text); 682 } 683 | 684 %empty 685 { 686 // SQLITE compatibillity 687 globalField = new KDbField(); 688 globalField->setType(KDbField::InvalidType); 689 } 690 ;*/ 691 692 SelectStatement: 693 Select 694 { 695 sqlParserDebug() << "Select"; 696 if (!($$ = buildSelectQuery( $1, nullptr ))) 697 YYABORT; 698 } 699 | Select ColViews 700 { 701 sqlParserDebug() << "Select ColViews=" << *$2; 702 703 if (!($$ = buildSelectQuery( $1, $2 ))) 704 YYABORT; 705 } 706 | Select ColViews Tables 707 { 708 if (!($$ = buildSelectQuery( $1, $2, $3 ))) 709 YYABORT; 710 } 711 | Select Tables 712 { 713 sqlParserDebug() << "Select ColViews Tables"; 714 if (!($$ = buildSelectQuery( $1, nullptr, $2 ))) 715 YYABORT; 716 } 717 | Select ColViews SelectOptions 718 { 719 sqlParserDebug() << "Select ColViews Conditions"; 720 if (!($$ = buildSelectQuery( $1, $2, nullptr, $3 ))) 721 YYABORT; 722 } 723 | Select Tables SelectOptions 724 { 725 sqlParserDebug() << "Select Tables SelectOptions"; 726 if (!($$ = buildSelectQuery( $1, nullptr, $2, $3 ))) 727 YYABORT; 728 } 729 | Select ColViews Tables SelectOptions 730 { 731 sqlParserDebug() << "Select ColViews Tables SelectOptions"; 732 if (!($$ = buildSelectQuery( $1, $2, $3, $4 ))) 733 YYABORT; 734 } 735 ; 736 737 Select: 738 SELECT 739 { 740 sqlParserDebug() << "SELECT"; 741 $$ = KDbParserPrivate::get(globalParser)->createQuery(); 742 } 743 ; 744 745 SelectOptions: /* todo: more options (having, group by, limit...) */ 746 WhereClause 747 { 748 sqlParserDebug() << "WhereClause"; 749 $$ = new SelectOptionsInternal; 750 $$->whereExpr = *$1; 751 delete $1; 752 } 753 | ORDER BY OrderByClause 754 { 755 sqlParserDebug() << "OrderByClause"; 756 $$ = new SelectOptionsInternal; 757 $$->orderByColumns = $3; 758 } 759 | WhereClause ORDER BY OrderByClause 760 { 761 sqlParserDebug() << "WhereClause ORDER BY OrderByClause"; 762 $$ = new SelectOptionsInternal; 763 $$->whereExpr = *$1; 764 delete $1; 765 $$->orderByColumns = $4; 766 } 767 | ORDER BY OrderByClause WhereClause 768 { 769 sqlParserDebug() << "OrderByClause WhereClause"; 770 $$ = new SelectOptionsInternal; 771 $$->whereExpr = *$4; 772 delete $4; 773 $$->orderByColumns = $3; 774 } 775 ; 776 777 WhereClause: 778 WHERE aExpr 779 { 780 $$ = $2; 781 } 782 ; 783 784 /* todo: support "ORDER BY NULL" as described here https://dev.mysql.com/doc/refman/5.1/en/select.html */ 785 /* todo: accept expr and position as well */ 786 OrderByClause: 787 OrderByColumnId 788 { 789 sqlParserDebug() << "ORDER BY IDENTIFIER"; 790 $$ = new QList<OrderByColumnInternal>; 791 OrderByColumnInternal orderByColumn; 792 orderByColumn.setColumnByNameOrNumber( *$1 ); 793 $$->append( orderByColumn ); 794 delete $1; 795 } 796 | OrderByColumnId OrderByOption 797 { 798 sqlParserDebug() << "ORDER BY IDENTIFIER OrderByOption"; 799 $$ = new QList<OrderByColumnInternal>; 800 OrderByColumnInternal orderByColumn; 801 orderByColumn.setColumnByNameOrNumber( *$1 ); 802 orderByColumn.order = $2; 803 $$->append( orderByColumn ); 804 delete $1; 805 } 806 | OrderByColumnId ',' OrderByClause 807 { 808 $$ = $3; 809 OrderByColumnInternal orderByColumn; 810 orderByColumn.setColumnByNameOrNumber( *$1 ); 811 $$->append( orderByColumn ); 812 delete $1; 813 } 814 | OrderByColumnId OrderByOption ',' OrderByClause 815 { 816 $$ = $4; 817 OrderByColumnInternal orderByColumn; 818 orderByColumn.setColumnByNameOrNumber( *$1 ); 819 orderByColumn.order = $2; 820 $$->append( orderByColumn ); 821 delete $1; 822 } 823 ; 824 825 OrderByColumnId: 826 IDENTIFIER 827 { 828 $$ = new QVariant( *$1 ); 829 sqlParserDebug() << "OrderByColumnId: " << *$$; 830 delete $1; 831 } 832 | IDENTIFIER '.' IDENTIFIER 833 { 834 $$ = new QVariant( *$1 + QLatin1Char('.') + *$3 ); 835 sqlParserDebug() << "OrderByColumnId: " << *$$; 836 delete $1; 837 delete $3; 838 } 839 | INTEGER_CONST 840 { 841 $$ = new QVariant($1); 842 sqlParserDebug() << "OrderByColumnId: " << *$$; 843 } 844 845 OrderByOption: 846 ASC 847 { 848 $$ = KDbOrderByColumn::SortOrder::Ascending; 849 } 850 | DESC 851 { 852 $$ = KDbOrderByColumn::SortOrder::Descending; 853 } 854 ; 855 856 aExpr: 857 aExpr2 858 ; 859 860 /* --- binary logical --- */ 861 aExpr2: 862 aExpr3 AND aExpr2 863 { 864 // sqlParserDebug() << "AND " << $3.debugString(); 865 $$ = new KDbBinaryExpression(*$1, KDbToken::AND, *$3); 866 delete $1; 867 delete $3; 868 } 869 | aExpr3 OR aExpr2 870 { 871 $$ = new KDbBinaryExpression(*$1, KDbToken::OR, *$3); 872 delete $1; 873 delete $3; 874 } 875 | aExpr3 XOR aExpr2 876 { 877 $$ = new KDbBinaryExpression(*$1, KDbToken::XOR, *$3); 878 delete $1; 879 delete $3; 880 } 881 | 882 aExpr3 883 ; 884 885 /* relational op precedence */ 886 aExpr3: 887 aExpr4 '>' %prec GREATER_OR_EQUAL aExpr3 888 { 889 $$ = new KDbBinaryExpression(*$1, '>', *$3); 890 delete $1; 891 delete $3; 892 } 893 | aExpr4 GREATER_OR_EQUAL aExpr3 894 { 895 $$ = new KDbBinaryExpression(*$1, KDbToken::GREATER_OR_EQUAL, *$3); 896 delete $1; 897 delete $3; 898 } 899 | aExpr4 '<' %prec LESS_OR_EQUAL aExpr3 900 { 901 $$ = new KDbBinaryExpression(*$1, '<', *$3); 902 delete $1; 903 delete $3; 904 } 905 | aExpr4 LESS_OR_EQUAL aExpr3 906 { 907 $$ = new KDbBinaryExpression(*$1, KDbToken::LESS_OR_EQUAL, *$3); 908 delete $1; 909 delete $3; 910 } 911 | aExpr4 '=' aExpr3 912 { 913 $$ = new KDbBinaryExpression(*$1, '=', *$3); 914 delete $1; 915 delete $3; 916 } 917 | 918 aExpr4 919 ; 920 921 /* relational (equality) op precedence */ 922 aExpr4: 923 aExpr5 NOT_EQUAL aExpr4 924 { 925 $$ = new KDbBinaryExpression(*$1, KDbToken::NOT_EQUAL, *$3); 926 delete $1; 927 delete $3; 928 } 929 | aExpr5 NOT_EQUAL2 aExpr4 930 { 931 $$ = new KDbBinaryExpression(*$1, KDbToken::NOT_EQUAL2, *$3); 932 delete $1; 933 delete $3; 934 } 935 | aExpr5 LIKE aExpr4 936 { 937 $$ = new KDbBinaryExpression(*$1, KDbToken::LIKE, *$3); 938 delete $1; 939 delete $3; 940 } 941 | aExpr5 NOT_LIKE aExpr4 942 { 943 $$ = new KDbBinaryExpression(*$1, KDbToken::NOT_LIKE, *$3); 944 delete $1; 945 delete $3; 946 } 947 | aExpr5 SQL_IN aExpr4 948 { 949 $$ = new KDbBinaryExpression(*$1, KDbToken::SQL_IN, *$3); 950 delete $1; 951 delete $3; 952 } 953 | aExpr5 SIMILAR_TO aExpr4 954 { 955 $$ = new KDbBinaryExpression(*$1, KDbToken::SIMILAR_TO, *$3); 956 delete $1; 957 delete $3; 958 } 959 | aExpr5 NOT_SIMILAR_TO aExpr4 960 { 961 $$ = new KDbBinaryExpression(*$1, KDbToken::NOT_SIMILAR_TO, *$3); 962 delete $1; 963 delete $3; 964 } 965 | aExpr5 BETWEEN aExpr4 AND aExpr4 966 { 967 $$ = new KDbNArgExpression(KDb::RelationalExpression, KDbToken::BETWEEN_AND); 968 $$->toNArg().append( *$1 ); 969 $$->toNArg().append( *$3 ); 970 $$->toNArg().append( *$5 ); 971 delete $1; 972 delete $3; 973 delete $5; 974 } 975 | aExpr5 NOT_BETWEEN aExpr4 AND aExpr4 976 { 977 $$ = new KDbNArgExpression(KDb::RelationalExpression, KDbToken::NOT_BETWEEN_AND); 978 $$->toNArg().append( *$1 ); 979 $$->toNArg().append( *$3 ); 980 $$->toNArg().append( *$5 ); 981 delete $1; 982 delete $3; 983 delete $5; 984 } 985 | 986 aExpr5 987 ; 988 989 /* --- unary logical right --- */ 990 aExpr5: 991 aExpr5 SQL_IS_NULL 992 { 993 $$ = new KDbUnaryExpression( KDbToken::SQL_IS_NULL, *$1 ); 994 delete $1; 995 } 996 | aExpr5 SQL_IS_NOT_NULL 997 { 998 $$ = new KDbUnaryExpression( KDbToken::SQL_IS_NOT_NULL, *$1 ); 999 delete $1; 1000 } 1001 | 1002 aExpr6 1003 ; 1004 1005 /* arithm. lowest precedence */ 1006 aExpr6: 1007 aExpr7 BITWISE_SHIFT_LEFT aExpr6 1008 { 1009 $$ = new KDbBinaryExpression(*$1, KDbToken::BITWISE_SHIFT_LEFT, *$3); 1010 delete $1; 1011 delete $3; 1012 } 1013 | aExpr7 BITWISE_SHIFT_RIGHT aExpr6 1014 { 1015 $$ = new KDbBinaryExpression(*$1, KDbToken::BITWISE_SHIFT_RIGHT, *$3); 1016 delete $1; 1017 delete $3; 1018 } 1019 | 1020 aExpr7 1021 ; 1022 1023 /* arithm. lower precedence */ 1024 aExpr7: 1025 aExpr8 '+' aExpr7 1026 { 1027 $$ = new KDbBinaryExpression(*$1, '+', *$3); 1028 delete $1; 1029 delete $3; 1030 } 1031 | aExpr8 CONCATENATION aExpr7 1032 { 1033 $$ = new KDbBinaryExpression(*$1, KDbToken::CONCATENATION, *$3); 1034 delete $1; 1035 delete $3; 1036 } 1037 | aExpr8 '-' %prec UMINUS aExpr7 1038 { 1039 $$ = new KDbBinaryExpression(*$1, '-', *$3); 1040 delete $1; 1041 delete $3; 1042 } 1043 | aExpr8 '&' aExpr7 1044 { 1045 $$ = new KDbBinaryExpression(*$1, '&', *$3); 1046 delete $1; 1047 delete $3; 1048 } 1049 | aExpr8 '|' aExpr7 1050 { 1051 $$ = new KDbBinaryExpression(*$1, '|', *$3); 1052 delete $1; 1053 delete $3; 1054 } 1055 | 1056 aExpr8 1057 ; 1058 1059 /* arithm. higher precedence */ 1060 aExpr8: 1061 aExpr9 '/' aExpr8 1062 { 1063 $$ = new KDbBinaryExpression(*$1, '/', *$3); 1064 delete $1; 1065 delete $3; 1066 } 1067 | aExpr9 '*' aExpr8 1068 { 1069 $$ = new KDbBinaryExpression(*$1, '*', *$3); 1070 delete $1; 1071 delete $3; 1072 } 1073 | aExpr9 '%' aExpr8 1074 { 1075 $$ = new KDbBinaryExpression(*$1, '%', *$3); 1076 delete $1; 1077 delete $3; 1078 } 1079 | 1080 aExpr9 1081 ; 1082 1083 /* parenthesis, unary operators, and terminals precedence */ 1084 aExpr9: 1085 /* --- unary logical left --- */ 1086 '-' aExpr9 1087 { 1088 $$ = new KDbUnaryExpression( '-', *$2 ); 1089 delete $2; 1090 } 1091 | '+' aExpr9 1092 { 1093 $$ = new KDbUnaryExpression( '+', *$2 ); 1094 delete $2; 1095 } 1096 | '~' aExpr9 1097 { 1098 $$ = new KDbUnaryExpression( '~', *$2 ); 1099 delete $2; 1100 } 1101 | NOT aExpr9 1102 { 1103 $$ = new KDbUnaryExpression( KDbToken::NOT, *$2 ); 1104 delete $2; 1105 } 1106 | IDENTIFIER 1107 { 1108 $$ = new KDbVariableExpression( *$1 ); 1109 1110 //! @todo simplify this later if that's 'only one field name' expression 1111 sqlParserDebug() << " + identifier: " << *$1; 1112 delete $1; 1113 } 1114 | QUERY_PARAMETER 1115 { 1116 $$ = new KDbQueryParameterExpression( *$1 ); 1117 sqlParserDebug() << " + query parameter:" << *$$; 1118 delete $1; 1119 } 1120 | IDENTIFIER aExprList 1121 { 1122 sqlParserDebug() << " + function:" << *$1 << "(" << *$2 << ")"; 1123 $$ = new KDbFunctionExpression(*$1, *$2); 1124 delete $1; 1125 delete $2; 1126 } 1127 /*! @todo shall we also support db name? */ 1128 | IDENTIFIER '.' IDENTIFIER 1129 { 1130 $$ = new KDbVariableExpression( *$1 + QLatin1Char('.') + *$3 ); 1131 sqlParserDebug() << " + identifier.identifier:" << *$1 << "." << *$3; 1132 delete $1; 1133 delete $3; 1134 } 1135 | SQL_NULL 1136 { 1137 $$ = new KDbConstExpression( KDbToken::SQL_NULL, QVariant() ); 1138 sqlParserDebug() << " + NULL"; 1139 // $$ = new KDbField(); 1140 //$$->setName(QString::null); 1141 } 1142 | SQL_TRUE 1143 { 1144 $$ = new KDbConstExpression( KDbToken::SQL_TRUE, true ); 1145 } 1146 | SQL_FALSE 1147 { 1148 $$ = new KDbConstExpression( KDbToken::SQL_FALSE, false ); 1149 } 1150 | CHARACTER_STRING_LITERAL 1151 { 1152 $$ = new KDbConstExpression( KDbToken::CHARACTER_STRING_LITERAL, *$1 ); 1153 sqlParserDebug() << " + constant " << $1; 1154 delete $1; 1155 } 1156 | INTEGER_CONST 1157 { 1158 QVariant val; 1159 if ($1 <= INT_MAX && $1 >= INT_MIN) 1160 val = (int)$1; 1161 else if ($1 <= UINT_MAX && $1 >= 0) 1162 val = (uint)$1; 1163 else if ($1 <= LLONG_MAX && $1 >= LLONG_MIN) 1164 val = (qint64)$1; 1165 1166 // if ($1 < ULLONG_MAX) 1167 // val = (quint64)$1; 1168 //! @todo ok? 1169 1170 $$ = new KDbConstExpression( KDbToken::INTEGER_CONST, val ); 1171 sqlParserDebug() << " + int constant: " << val.toString(); 1172 } 1173 | REAL_CONST 1174 { 1175 $$ = new KDbConstExpression( KDbToken::REAL_CONST, *$1 ); 1176 sqlParserDebug() << " + real constant: " << *$1; 1177 delete $1; 1178 } 1179 | DateConst 1180 { 1181 $$ = new KDbConstExpression(KDbToken::DATE_CONST, QVariant::fromValue(*$1)); 1182 sqlParserDebug() << " + date constant:" << *$1; 1183 delete $1; 1184 } 1185 | TimeConst 1186 { 1187 $$ = new KDbConstExpression(KDbToken::TIME_CONST, QVariant::fromValue(*$1)); 1188 sqlParserDebug() << " + time constant:" << *$1; 1189 delete $1; 1190 } 1191 | DateTimeConst 1192 { 1193 $$ = new KDbConstExpression(KDbToken::DATETIME_CONST, QVariant::fromValue(*$1)); 1194 sqlParserDebug() << " + datetime constant:" << *$1; 1195 delete $1; 1196 } 1197 | 1198 aExpr10 1199 ; 1200 1201 DateConst: 1202 '#' DateValue '#' 1203 { 1204 $$ = $2; 1205 sqlParserDebug() << "DateConst:" << *$$; 1206 } 1207 ; 1208 1209 DateValue: 1210 YearConst '-' DATE_TIME_INTEGER '-' DATE_TIME_INTEGER 1211 { 1212 $$ = new KDbDate(*$1, *$3, *$5); 1213 sqlParserDebug() << "DateValue:" << *$$; 1214 delete $1; 1215 delete $3; 1216 delete $5; 1217 } 1218 | DATE_TIME_INTEGER '/' DATE_TIME_INTEGER '/' YearConst /* M/D/Y */ 1219 { 1220 $$ = new KDbDate(*$5, *$1, *$3); 1221 sqlParserDebug() << "DateValue:" << *$$; 1222 delete $1; 1223 delete $3; 1224 delete $5; 1225 } 1226 ; 1227 1228 YearConst: 1229 DATE_TIME_INTEGER 1230 { 1231 $$ = new KDbYear(KDbYear::Sign::None, *$1); 1232 sqlParserDebug() << "YearConst:" << *$$; 1233 delete $1; 1234 } 1235 | '+' DATE_TIME_INTEGER 1236 { 1237 $$ = new KDbYear(KDbYear::Sign::Plus, *$2); 1238 sqlParserDebug() << "YearConst:" << *$$; 1239 delete $2; 1240 } 1241 | '-' DATE_TIME_INTEGER 1242 { 1243 $$ = new KDbYear(KDbYear::Sign::Minus, *$2); 1244 sqlParserDebug() << "YearConst:" << *$$; 1245 delete $2; 1246 } 1247 ; 1248 1249 TimeConst: 1250 '#' TimeValue '#' 1251 { 1252 $$ = $2; 1253 sqlParserDebug() << "TimeConst:" << *$$; 1254 } 1255 ; 1256 1257 TimeValue: 1258 DATE_TIME_INTEGER ':' DATE_TIME_INTEGER TimeMs TimePeriod 1259 { 1260 $$ = new KDbTime(*$1, *$3, {}, *$4, $5); 1261 sqlParserDebug() << "TimeValue:" << *$$; 1262 delete $1; 1263 delete $3; 1264 delete $4; 1265 } 1266 | DATE_TIME_INTEGER ':' DATE_TIME_INTEGER ':' DATE_TIME_INTEGER TimeMs TimePeriod 1267 { 1268 $$ = new KDbTime(*$1, *$3, *$5, *$6, $7); 1269 sqlParserDebug() << "TimeValue:" << *$$; 1270 delete $1; 1271 delete $3; 1272 delete $5; 1273 delete $6; 1274 } 1275 ; 1276 1277 TimeMs: 1278 '.' DATE_TIME_INTEGER 1279 { 1280 $$ = $2; 1281 } 1282 | %empty 1283 { 1284 $$ = new QByteArray; 1285 } 1286 ; 1287 1288 TimePeriod: 1289 TIME_AM 1290 { 1291 $$ = KDbTime::Period::Am; 1292 } 1293 | TIME_PM 1294 { 1295 $$ = KDbTime::Period::Pm; 1296 } 1297 | %empty 1298 { 1299 $$ = KDbTime::Period::None; 1300 } 1301 ; 1302 1303 DateTimeConst: 1304 '#' DateValue TABS_OR_SPACES TimeValue '#' 1305 { 1306 $$ = new KDbDateTime(*$2, *$4); 1307 sqlParserDebug() << "DateTimeConst:" << *$$; 1308 delete $2; 1309 delete $4; 1310 } 1311 ; 1312 1313 aExpr10: 1314 '(' aExpr ')' 1315 { 1316 sqlParserDebug() << "(expr)"; 1317 $$ = new KDbUnaryExpression('(', *$2); 1318 delete $2; 1319 } 1320 ; 1321 1322 aExprList: 1323 '(' aExprList2 ')' 1324 { 1325 $$ = $2; 1326 } 1327 | '(' ')' 1328 { 1329 $$ = new KDbNArgExpression(KDb::ArgumentListExpression, ','); 1330 } 1331 ; 1332 1333 aExprList2: 1334 aExpr ',' aExprList2 1335 { 1336 $$ = $3; 1337 $$->prepend( *$1 ); 1338 delete $1; 1339 } 1340 | aExpr 1341 { 1342 $$ = new KDbNArgExpression(KDb::ArgumentListExpression, ','); 1343 $$->append( *$1 ); 1344 delete $1; 1345 } 1346 ; 1347 1348 Tables: 1349 FROM FlatTableList 1350 { 1351 $$ = $2; 1352 } 1353 /* 1354 | Tables LEFT JOIN IDENTIFIER SQL_ON ColExpression 1355 { 1356 sqlParserDebug() << "LEFT JOIN: '" << *$4 << "' ON " << $6; 1357 addTable($4->toQString()); 1358 delete $4; 1359 } 1360 | Tables LEFT OUTER JOIN IDENTIFIER SQL_ON ColExpression 1361 { 1362 sqlParserDebug() << "LEFT OUTER JOIN: '" << $5 << "' ON " << $7; 1363 addTable($5); 1364 } 1365 | Tables INNER JOIN IDENTIFIER SQL_ON ColExpression 1366 { 1367 sqlParserDebug() << "INNER JOIN: '" << *$4 << "' ON " << $6; 1368 addTable($4->toQString()); 1369 delete $4; 1370 } 1371 | Tables RIGHT JOIN IDENTIFIER SQL_ON ColExpression 1372 { 1373 sqlParserDebug() << "RIGHT JOIN: '" << *$4 << "' ON " << $6; 1374 addTable(*$4); 1375 delete $4; 1376 } 1377 | Tables RIGHT OUTER JOIN IDENTIFIER SQL_ON ColExpression 1378 { 1379 sqlParserDebug() << "RIGHT OUTER JOIN: '" << *$5 << "' ON " << $7; 1380 addTable($5->toQString()); 1381 delete $5; 1382 }*/ 1383 ; 1384 1385 /* 1386 FlatTableList: 1387 aFlatTableList 1388 { 1389 $$ 1390 } 1391 ;*/ 1392 1393 FlatTableList: 1394 FlatTableList ',' FlatTable 1395 { 1396 $$ = $1; 1397 $$->append(*$3); 1398 delete $3; 1399 } 1400 |FlatTable 1401 { 1402 $$ = new KDbNArgExpression(KDb::TableListExpression, KDbToken::IDENTIFIER); //ok? 1403 $$->append(*$1); 1404 delete $1; 1405 } 1406 ; 1407 1408 FlatTable: 1409 IDENTIFIER 1410 { 1411 sqlParserDebug() << "FROM: '" << *$1 << "'"; 1412 $$ = new KDbVariableExpression(*$1); 1413 1414 //! @todo this isn't ok for more tables: 1415 /* 1416 KDbField::ListIterator it = globalParser->query()->fieldsIterator(); 1417 for(KDbField *item; (item = it.current()); ++it) 1418 { 1419 if(item->table() == dummy) 1420 { 1421 item->setTable(schema); 1422 } 1423 1424 if(item->table() && !item->isQueryAsterisk()) 1425 { 1426 KDbField *f = item->table()->field(item->name()); 1427 if(!f) 1428 { 1429 KDbParserError err(KDbParser::tr("Field List Error"), KDbParser::tr("Unknown column '%1' in table '%2'",item->name(),schema->name()), ctoken, current); 1430 globalParser->setError(err); 1431 yyerror("fieldlisterror"); 1432 } 1433 } 1434 }*/ 1435 delete $1; 1436 } 1437 | IDENTIFIER IDENTIFIER 1438 { 1439 //table + alias 1440 $$ = new KDbBinaryExpression( 1441 KDbVariableExpression(*$1), KDbToken::AS_EMPTY, 1442 KDbVariableExpression(*$2) 1443 ); 1444 delete $1; 1445 delete $2; 1446 } 1447 | IDENTIFIER AS IDENTIFIER 1448 { 1449 //table + alias 1450 $$ = new KDbBinaryExpression( 1451 KDbVariableExpression(*$1), KDbToken::AS, 1452 KDbVariableExpression(*$3) 1453 ); 1454 delete $1; 1455 delete $3; 1456 } 1457 ; 1458 1459 1460 1461 ColViews: 1462 ColViews ',' ColItem 1463 { 1464 $$ = $1; 1465 $$->append(*$3); 1466 delete $3; 1467 sqlParserDebug() << "ColViews: ColViews , ColItem"; 1468 } 1469 |ColItem 1470 { 1471 $$ = new KDbNArgExpression(KDb::FieldListExpression, KDbToken()); 1472 $$->append(*$1); 1473 delete $1; 1474 sqlParserDebug() << "ColViews: ColItem"; 1475 } 1476 ; 1477 1478 ColItem: 1479 ColExpression 1480 { 1481 // $$ = new KDbField(); 1482 // dummy->addField($$); 1483 // $$->setExpression( $1 ); 1484 // globalParser->query()->addField($$); 1485 $$ = $1; 1486 sqlParserDebug() << " added column expr:" << *$1; 1487 } 1488 | ColWildCard 1489 { 1490 $$ = $1; 1491 sqlParserDebug() << " added column wildcard:" << *$1; 1492 } 1493 | ColExpression AS IDENTIFIER 1494 { 1495 $$ = new KDbBinaryExpression( 1496 *$1, KDbToken::AS, 1497 KDbVariableExpression(*$3) 1498 ); 1499 sqlParserDebug() << " added column expr:" << *$$; 1500 delete $1; 1501 delete $3; 1502 } 1503 | ColExpression IDENTIFIER 1504 { 1505 $$ = new KDbBinaryExpression( 1506 *$1, KDbToken::AS_EMPTY, 1507 KDbVariableExpression(*$2) 1508 ); 1509 sqlParserDebug() << " added column expr:" << *$$; 1510 delete $1; 1511 delete $2; 1512 } 1513 ; 1514 1515 ColExpression: 1516 aExpr 1517 { 1518 $$ = $1; 1519 } 1520 /* HANDLED BY 'IDENTIFIER aExprList' 1521 | IDENTIFIER '(' ColViews ')' 1522 { 1523 $$ = new KDbFunctionExpression( $1, $3 ); 1524 }*/ 1525 //! @todo 1526 /* 1527 | SUM '(' ColExpression ')' 1528 { 1529 KDbFunctionExpression( 1530 // $$ = new AggregationExpression( SUM, ); 1531 // $$->setName("SUM(" + $3->name() + ")"); 1532 //wait $$->containsGroupingAggregate(true); 1533 //wait globalParser->query()->grouped(true); 1534 }*/ 1535 //! @todo 1536 /* 1537 | SQL_MIN '(' ColExpression ')' 1538 { 1539 $$ = $3; 1540 // $$->setName("MIN(" + $3->name() + ")"); 1541 //wait $$->containsGroupingAggregate(true); 1542 //wait globalParser->query()->grouped(true); 1543 }*/ 1544 //! @todo 1545 /* 1546 | SQL_MAX '(' ColExpression ')' 1547 { 1548 $$ = $3; 1549 // $$->setName("MAX(" + $3->name() + ")"); 1550 //wait $$->containsGroupingAggregate(true); 1551 //wait globalParser->query()->grouped(true); 1552 }*/ 1553 //! @todo 1554 /* 1555 | AVG '(' ColExpression ')' 1556 { 1557 $$ = $3; 1558 // $$->setName("AVG(" + $3->name() + ")"); 1559 //wait $$->containsGroupingAggregate(true); 1560 //wait globalParser->query()->grouped(true); 1561 }*/ 1562 | DISTINCT '(' ColExpression ')' 1563 { 1564 $$ = $3; 1565 //! @todo DISTINCT '(' ColExpression ')' 1566 // $$->setName("DISTINCT(" + $3->name() + ")"); 1567 } 1568 ; 1569 1570 ColWildCard: 1571 '*' 1572 { 1573 $$ = new KDbVariableExpression(QLatin1String("*")); 1574 sqlParserDebug() << "all columns"; 1575 1576 // KDbQueryAsterisk *ast = new KDbQueryAsterisk(globalParser->query(), dummy); 1577 // globalParser->query()->addAsterisk(ast); 1578 // requiresTable = true; 1579 } 1580 | IDENTIFIER '.' '*' 1581 { 1582 QString s( *$1 ); 1583 s += QLatin1String(".*"); 1584 $$ = new KDbVariableExpression(s); 1585 sqlParserDebug() << " + all columns from " << s; 1586 delete $1; 1587 } 1588 /*| ERROR_DIGIT_BEFORE_IDENTIFIER 1589 { 1590 $$ = new KDbVariableExpression($1); 1591 sqlParserDebug() << " Invalid identifier! " << $1; 1592 setError(KDbParser::tr("Invalid identifier \"%1\"",$1)); 1593 }*/ 1594 ; 1595 1596 %% 1597 1598