Warning, /libraries/kdb/src/parser/KDbSqlParser.y is written in an unsupported language. File is not indexed.

0001 /* This file is part of the KDE project
0002    Copyright (C) 2004 Lucijan Busch <lucijan@kde.org>
0003    Copyright (C) 2004-2018 Jarosław Staniek <staniek@kde.org>
0004 
0005    This library is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU Library General Public
0007    License as published by the Free Software Foundation; either
0008    version 2 of the License, or (at your option) any later version.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 // To keep binary compatibility, do not reorder tokens! Add new only at the end.
0022 %token SQL_TYPE
0023 %token AS
0024 %token AS_EMPTY /* used for aliases with skipped AS keyword */
0025 %token ASC
0026 %token AUTO_INCREMENT
0027 %token BIT
0028 %token BITWISE_SHIFT_LEFT
0029 %token BITWISE_SHIFT_RIGHT
0030 %token BY
0031 %token CHARACTER_STRING_LITERAL
0032 %token CONCATENATION /* || */
0033 %token CREATE
0034 %token DESC
0035 %token DISTINCT
0036 %token DOUBLE_QUOTED_STRING
0037 %token FROM
0038 %token JOIN
0039 %token KEY
0040 %token LEFT
0041 %token LESS_OR_EQUAL
0042 %token GREATER_OR_EQUAL
0043 %token SQL_NULL
0044 %token SQL_IS
0045 %token SQL_IS_NULL /*helper */
0046 %token SQL_IS_NOT_NULL /*helper */
0047 %token ORDER
0048 %token PRIMARY
0049 %token SELECT
0050 %token INTEGER_CONST
0051 %token REAL_CONST
0052 %token RIGHT
0053 %token SQL_ON
0054 %token DATE_CONST
0055 %token DATETIME_CONST
0056 %token TIME_CONST
0057 %token TABLE
0058 %token IDENTIFIER
0059 %token IDENTIFIER_DOT_ASTERISK
0060 %token QUERY_PARAMETER
0061 %token VARCHAR
0062 %token WHERE
0063 %token SQL
0064 %token SQL_TRUE
0065 %token SQL_FALSE
0066 %token UNION
0067 
0068 %token SCAN_ERROR
0069 
0070 //%token SQL_ABS
0071 //%token ACOS
0072 //%token AMPERSAND
0073 //%token SQL_ABSOLUTE
0074 //%token ADA
0075 //%token ADD
0076 //%token ADD_DAYS
0077 //%token ADD_HOURS
0078 //%token ADD_MINUTES
0079 //%token ADD_MONTHS
0080 //%token ADD_SECONDS
0081 //%token ADD_YEARS
0082 //%token ALL
0083 //%token ALLOCATE
0084 //%token ALTER
0085 %token AND
0086 //%token ANY
0087 //%token ARE
0088 //%token ASIN
0089 //%token ASCII
0090 //%token ASSERTION
0091 //%token ATAN
0092 //%token ATAN2
0093 //%token AUTHORIZATION
0094 //%token AVG
0095 //%token BEFORE
0096 %token BETWEEN
0097 %token NOT_BETWEEN
0098 //%token SQL_BEGIN
0099 //%token BIGINT
0100 //%token BINARY
0101 //%token BIT_LENGTH
0102 //%token BREAK
0103 //%token CASCADE
0104 //%token CASCADED
0105 //%token CASE
0106 //%token CAST
0107 //%token CATALOG
0108 //%token CEILING
0109 //%token CENTER
0110 //%token SQL_CHAR
0111 //%token CHAR_LENGTH
0112 //%token CHECK
0113 //%token CLOSE
0114 //%token COALESCE
0115 //%token COBOL
0116 //%token COLLATE
0117 //%token COLLATION
0118 //%token COLUMN
0119 //%token COMMIT
0120 //%token COMPUTE
0121 //%token CONCAT
0122 //%token CONNECT
0123 //%token CONNECTION
0124 //%token CONSTRAINT
0125 //%token CONSTRAINTS
0126 //%token CONTINUE
0127 //%token CONVERT
0128 //%token CORRESPONDING
0129 //%token COS
0130 //%token COT
0131 //%token COUNT
0132 //%token CURDATE
0133 //%token CURRENT
0134 //%token CURRENT_DATE
0135 //%token CURRENT_TIME
0136 //%token CURRENT_TIMESTAMP
0137 //%token CURTIME
0138 //%token CURSOR
0139 //%token DATABASE
0140 //%token SQL_DATE
0141 //%token DATE_FORMAT
0142 //%token DATE_REMAINDER
0143 //%token DATE_VALUE
0144 //%token DAY
0145 //%token DAYOFMONTH
0146 //%token DAYOFWEEK
0147 //%token DAYOFYEAR
0148 //%token DAYS_BETWEEN
0149 //%token DEALLOCATE
0150 //%token DEC
0151 //%token DECLARE
0152 //%token DEFAULT
0153 //%token DEFERRABLE
0154 //%token DEFERRED
0155 //%token SQL_DELETE
0156 //%token DESCRIBE
0157 //%token DESCRIPTOR
0158 //%token DIAGNOSTICS
0159 //%token DICTIONARY
0160 //%token DIRECTORY
0161 //%token DISCONNECT
0162 //%token DISPLACEMENT
0163 //%token DOMAIN_TOKEN
0164 //%token SQL_DOUBLE
0165 //%token DROP
0166 //%token ELSE
0167 //%token END
0168 //%token END_EXEC
0169 //%token ESCAPE
0170 %token EXCEPT
0171 //%token SQL_EXCEPTION
0172 //%token EXEC
0173 //%token EXECUTE
0174 //%token EXISTS
0175 //%token EXP
0176 //%token EXPONENT
0177 //%token EXTERNAL
0178 //%token EXTRACT
0179 //%token FETCH
0180 //%token FIRST
0181 //%token SQL_FLOAT
0182 //%token FLOOR
0183 //%token FN
0184 //%token FOR
0185 //%token FOREIGN
0186 //%token FORTRAN
0187 //%token FOUND
0188 //%token FOUR_DIGITS
0189 //%token FULL
0190 //%token GET
0191 //%token GLOBAL
0192 //%token GO
0193 //%token GOTO
0194 //%token GRANT
0195 //conflict %token GROUP
0196 //%token HAVING
0197 //%token HOUR
0198 //%token HOURS_BETWEEN
0199 //%token IDENTITY
0200 //%token IFNULL
0201 //%token SQL_IGNORE
0202 //%token IMMEDIATE
0203 //%token INCLUDE
0204 //%token INDEX
0205 //%token INDICATOR
0206 //%token INITIALLY
0207 //%token INNER
0208 //%token SQL_INPUT
0209 %token SQL_IN
0210 //%token INSENSITIVE
0211 //%token INSERT
0212 //%token INTEGER
0213 %token INTERSECT
0214 //%token INTERVAL
0215 //%token INTO
0216 //%token IS
0217 //%token ISOLATION
0218 //%token JUSTIFY
0219 //%token LANGUAGE
0220 //%token LAST
0221 //%token LCASE
0222 //%token LENGTH
0223 //%token LEVEL
0224 %token LIKE
0225 %token ILIKE
0226 %token NOT_LIKE
0227 //%token LINE_WIDTH
0228 //%token LOCAL
0229 //%token LOCATE
0230 //%token LOG
0231 //%token SQL_LONG
0232 //%token LOWER
0233 //%token LTRIM
0234 //%token LTRIP
0235 //%token MATCH
0236 //%token SQL_MAX
0237 //%token MICROSOFT
0238 //%token SQL_MIN
0239 //%token MINUTE
0240 //%token MINUTES_BETWEEN
0241 //%token MOD
0242 //%token MODIFY
0243 //%token MODULE
0244 //%token MONTH
0245 //%token MONTHS_BETWEEN
0246 //%token MUMPS
0247 //%token NAMES
0248 //%token NATIONAL
0249 //%token NCHAR
0250 //%token NEXT
0251 //%token NODUP
0252 //%token NONE
0253 %token NOT
0254 %token NOT_EQUAL
0255 %token NOT_EQUAL2
0256 //%token NOW
0257 //%token NULLIF
0258 //%token NUMERIC
0259 //%token OCTET_LENGTH
0260 //%token ODBC
0261 //%token OF
0262 //%token SQL_OFF
0263 //%token ONLY
0264 //%token OPEN
0265 //%token OPTION
0266 //%token OUTER
0267 //%token OUTPUT
0268 //%token OVERLAPS
0269 //%token PAGE
0270 //%token PARTIAL
0271 //%token SQL_PASCAL
0272 //%token PERSISTENT
0273 //%token CQL_PI
0274 %token OR
0275 //%token PLI
0276 //%token POSITION
0277 //%token PRECISION
0278 //%token PREPARE
0279 //%token PRESERVE
0280 //%token PRIOR
0281 //%token PRIVILEGES
0282 //%token PROCEDURE
0283 //%token PRODUCT
0284 //%token PUBLIC
0285 //%token QUARTER
0286 //%token QUIT
0287 //%token RAND
0288 //%token READ_ONLY
0289 //%token REAL
0290 //%token REFERENCES
0291 //%token REPEAT
0292 //%token REPLACE
0293 //%token RESTRICT
0294 //%token REVOKE
0295 //%token ROLLBACK
0296 //%token ROWS
0297 //%token RPAD
0298 //%token RTRIM
0299 //%token SCHEMA
0300 //%token SCREEN_WIDTH
0301 //%token SCROLL
0302 //%token SECOND
0303 //%token SECONDS_BETWEEN
0304 //%token SEQUENCE
0305 //%token SETOPT
0306 //%token SET
0307 //%token SHOWOPT
0308 //%token SIGN
0309 %token SIMILAR_TO
0310 %token NOT_SIMILAR_TO
0311 //%token SIN
0312 //%token SQL_SIZE
0313 //%token SMALLINT
0314 //%token SOME
0315 //%token SPACE
0316 //%token SQLCA
0317 //%token SQLCODE
0318 //%token SQLERROR
0319 //%token SQLSTATE
0320 //%token SQLWARNING
0321 //%token SQRT
0322 //%token STDEV
0323 //%token SUBSTRING
0324 //%token SUM
0325 //%token SYSDATE
0326 //%token SYSDATE_FORMAT
0327 //%token SYSTEM
0328 //%token TAN
0329 //%token TEMPORARY
0330 //%token THEN
0331 //%token THREE_DIGITS
0332 //%token TIME
0333 //%token TIMESTAMP
0334 //%token TIMEZONE_HOUR
0335 //%token TIMEZONE_MINUTE
0336 //%token TINYINT
0337 //%token TO
0338 //%token TO_CHAR
0339 //%token TO_DATE
0340 //%token TRANSACTION
0341 //%token TRANSLATE
0342 //%token TRANSLATION
0343 //%token TRUNCATE
0344 //%token GENERAL_TITLE
0345 //%token TWO_DIGITS
0346 //%token UCASE
0347 //%token UNIQUE
0348 //%token SQL_UNKNOWN
0349 //%token UNSIGNED_INTEGER
0350 //%token UPDATE
0351 //%token UPPER
0352 //%token USAGE
0353 //%token USER
0354 //%token ERROR_DIGIT_BEFORE_IDENTIFIER
0355 //%token USING
0356 //%token VALUE
0357 //%token VALUES
0358 //%token VARBINARY
0359 //%token VARYING
0360 //%token VENDOR
0361 //%token VIEW
0362 //%token WEEK
0363 //%token WHEN
0364 //%token WHENEVER
0365 //%token WHERE_CURRENT_OF
0366 //%token WITH
0367 //%token WORD_WRAPPED
0368 //%token WORK
0369 //%token WRAPPED
0370 %token XOR
0371 //%token YEAR
0372 //%token YEARS_BETWEEN
0373 %token UMINUS
0374 %token TABS_OR_SPACES    // e.g. inside of date or time constants
0375 %token DATE_TIME_INTEGER // inside of date or time constants
0376 %token TIME_AM
0377 %token TIME_PM
0378 
0379 %type <stringValue> IDENTIFIER
0380 %type <stringValue> IDENTIFIER_DOT_ASTERISK
0381 %type <stringValue> QUERY_PARAMETER
0382 %type <stringValue> CHARACTER_STRING_LITERAL
0383 %type <stringValue> DOUBLE_QUOTED_STRING
0384 
0385 /*
0386 %type <field> ColExpression
0387 %type <field> ColView
0388 */
0389 %type <expr> ColExpression
0390 %type <expr> ColWildCard
0391 //%type <expr> ColView
0392 %type <expr> ColItem
0393 %type <exprList> ColViews
0394 %type <expr> aExpr
0395 %type <expr> aExpr2
0396 %type <expr> aExpr3
0397 %type <expr> aExpr4
0398 %type <expr> aExpr5
0399 %type <expr> aExpr6
0400 %type <expr> aExpr7
0401 %type <expr> aExpr8
0402 %type <expr> aExpr9
0403 %type <expr> aExpr10
0404 %type <dateValue> DateConst
0405 %type <dateValue> DateValue
0406 %type <yearValue> YearConst
0407 %type <timeValue> TimeConst
0408 %type <timeValue> TimeValue
0409 %type <dateTimeValue> DateTimeConst
0410 %type <binaryValue> TimeMs
0411 %type <timePeriodValue> TimePeriod
0412 %type <exprList> aExprList
0413 %type <exprList> aExprList2
0414 %type <expr> WhereClause
0415 %type <orderByColumns> OrderByClause
0416 %type <sortOrderValue> OrderByOption
0417 %type <variantValue> OrderByColumnId
0418 %type <selectOptions> SelectOptions
0419 %type <expr> FlatTable
0420 %type <exprList> Tables
0421 %type <exprList> FlatTableList
0422 %type <querySchema> SelectStatement
0423 %type <querySchema> Select
0424 /*todo : list*/
0425 %type <querySchema> StatementList
0426 /*todo: not only select*/
0427 %type <querySchema> Statement
0428 
0429 %type <colType> SQL_TYPE
0430 %type <integerValue> INTEGER_CONST
0431 %type <binaryValue> REAL_CONST
0432 %type <binaryValue> DATE_TIME_INTEGER
0433 /*%type <integerValue> SIGNED_INTEGER */
0434 
0435 %{
0436 #include <stdio.h>
0437 #include <string.h>
0438 #include <string>
0439 #include <iostream>
0440 #include <limits.h>
0441 //! @todo OK?
0442 #ifdef Q_OS_WIN
0443 //workaround for bug on msvc
0444 # undef LLONG_MIN
0445 #endif
0446 #ifndef LLONG_MAX
0447 # define LLONG_MAX     0x7fffffffffffffffLL
0448 #endif
0449 #ifndef LLONG_MIN
0450 # define LLONG_MIN     0x8000000000000000LL
0451 #endif
0452 #ifndef LLONG_MAX
0453 # define ULLONG_MAX    0xffffffffffffffffLL
0454 #endif
0455 
0456 #ifdef _WIN32
0457 # include <malloc.h>
0458 #endif
0459 
0460 #include <QObject>
0461 #include <QVariant>
0462 #include <QPoint>
0463 
0464 #include "KDbConnection.h"
0465 #include "KDbDateTime.h"
0466 #include "KDbExpression.h"
0467 #include "KDbField.h"
0468 #include "KDbOrderByColumn.h"
0469 #include "KDbParser.h"
0470 #include "KDbParser_p.h"
0471 #include "KDbQuerySchema.h"
0472 #include "KDbQuerySchema_p.h"
0473 #include "KDbSqlTypes.h"
0474 #include "KDbTableSchema.h"
0475 #include "kdb_debug.h"
0476 
0477 struct OrderByColumnInternal;
0478 
0479 #ifdef Q_OS_SOLARIS
0480 #include <alloca.h>
0481 #endif
0482 
0483 QDebug operator<<(QDebug dbg, const KDbExpressionPtr& expr)
0484 {
0485     dbg.nospace() << expr.e;
0486     return dbg.space();
0487 }
0488 
0489 int yylex();
0490 
0491 #define YY_NO_UNPUT
0492 #define YYSTACK_USE_ALLOCA 1
0493 #define YYMAXDEPTH 255
0494 
0495     extern "C"
0496     {
0497         int yywrap()
0498         {
0499             return 1;
0500         }
0501     }
0502 
0503 %}
0504 
0505 %union {
0506     QString* stringValue;
0507     QByteArray* binaryValue;
0508     qint64 integerValue;
0509     bool booleanValue;
0510     KDbDate* dateValue;
0511     KDbYear* yearValue;
0512     KDbTime* timeValue;
0513     KDbTime::Period timePeriodValue;
0514     KDbDateTime* dateTimeValue;
0515     KDbOrderByColumn::SortOrder sortOrderValue;
0516     KDbField::Type colType;
0517     KDbField *field;
0518     KDbExpression *expr;
0519     KDbNArgExpression *exprList;
0520     KDbConstExpression *constExpression;
0521     KDbQuerySchema *querySchema;
0522     SelectOptionsInternal *selectOptions;
0523     QList<OrderByColumnInternal> *orderByColumns;
0524     QVariant *variantValue;
0525 }
0526 
0527 /* precedence: lowest to highest */
0528 //%nonassoc    SIMILAR
0529 //%nonassoc    ESCAPE
0530 //%nonassoc    OVERLAPS
0531 //%nonassoc    IN_P
0532 //%left        POSTFIXOP        // dummy for postfix Op rules
0533 //%left        Op OPERATOR        // multi-character ops and user-defined operators
0534 //%nonassoc    NOTNULL
0535 //%nonassoc    ISNULL
0536 //%nonassoc    IS               // sets precedence for IS NULL, etc
0537 //%nonassoc    NULL_P
0538 //%nonassoc    TRUE_P
0539 //%nonassoc    FALSE_P
0540 
0541 // <-- To keep binary compatibility insert new tokens here.
0542 
0543 /*
0544  * These might seem to be low-precedence, but actually they are not part
0545  * of the arithmetic hierarchy at all in their use as JOIN operators.
0546  * We make them high-precedence to support their use as function names.
0547  * They wouldn't be given a precedence at all, were it not that we need
0548  * left-associativity among the JOIN rules themselves.
0549  */
0550 /*
0551 %left JOIN
0552 %left UNIONJOIN
0553 %left CROSS
0554 %left LEFT
0555 %left FULL
0556 %left RIGHT
0557 %left INNER_P
0558 %left NATURAL
0559 */
0560 
0561 %%
0562 
0563 TopLevelStatement :
0564 StatementList
0565 {
0566 //todo: multiple statements
0567 //todo: not only "select" statements
0568     KDbParserPrivate::get(globalParser)->setStatementType(KDbParser::Select);
0569     KDbParserPrivate::get(globalParser)->setQuerySchema($1);
0570 }
0571 ;
0572 
0573 StatementList:
0574 Statement ';' StatementList
0575 {
0576 //todo: multiple statements
0577 }
0578 | Statement
0579 | Statement ';'
0580 {
0581     $$ = $1;
0582 }
0583 ;
0584 
0585 /*        Statement CreateTableStatement         { YYACCEPT; }
0586     | Statement SelectStatement         {  }
0587 */
0588 Statement :
0589 /*CreateTableStatement
0590 {
0591 YYACCEPT;
0592 }
0593 | */
0594 SelectStatement
0595 {
0596     $$ = $1;
0597 }
0598 ;
0599 
0600 /*CreateTableStatement :
0601 CREATE TABLE IDENTIFIER
0602 {
0603     globalParser->setStatementType(KDbParser::CreateTable);
0604     globalParser->createTable($3->toLatin1());
0605     delete $3;
0606 }
0607 '(' ColDefs ')'
0608 ;
0609 
0610 ColDefs:
0611 ColDefs ',' ColDef|ColDef
0612 {
0613 }
0614 ;
0615 
0616 ColDef:
0617 IDENTIFIER ColType
0618 {
0619     sqlParserDebug() << "adding field " << *$1;
0620     globalField->setName(*$1);
0621     globalParser->table()->addField(globalField);
0622     globalField = nullptr;
0623     delete $1;
0624 }
0625 | IDENTIFIER ColType ColKeys
0626 {
0627     sqlParserDebug() << "adding field " << *$1;
0628     globalField->setName(*$1);
0629     delete $1;
0630     globalParser->table()->addField(globalField);
0631 
0632 //    if(globalField->isPrimaryKey())
0633 //        globalParser->table()->addPrimaryKey(globalField->name());
0634 
0635 //    delete globalField;
0636 //    globalField = nullptr;
0637 }
0638 ;
0639 
0640 ColKeys:
0641 ColKeys ColKey|ColKey
0642 {
0643 }
0644 ;
0645 
0646 ColKey:
0647 PRIMARY KEY
0648 {
0649     globalField->setPrimaryKey(true);
0650     sqlParserDebug() << "primary";
0651 }
0652 | NOT SQL_NULL
0653 {
0654     globalField->setNotNull(true);
0655     sqlParserDebug() << "not_null";
0656 }
0657 | AUTO_INCREMENT
0658 {
0659     globalField->setAutoIncrement(true);
0660     sqlParserDebug() << "ainc";
0661 }
0662 ;
0663 
0664 ColType:
0665 SQL_TYPE
0666 {
0667     globalField = new KDbField();
0668     globalField->setType($1);
0669 }
0670 | SQL_TYPE '(' INTEGER_CONST ')'
0671 {
0672     sqlParserDebug() << "sql + length";
0673     globalField = new KDbField();
0674     globalField->setPrecision($3);
0675     globalField->setType($1);
0676 }
0677 | VARCHAR '(' INTEGER_CONST ')'
0678 {
0679     globalField = new KDbField();
0680     globalField->setPrecision($3);
0681     globalField->setType(KDbField::Text);
0682 }
0683 |
0684 %empty
0685 {
0686     // SQLITE compatibillity
0687     globalField = new KDbField();
0688     globalField->setType(KDbField::InvalidType);
0689 }
0690 ;*/
0691 
0692 SelectStatement:
0693 Select
0694 {
0695     sqlParserDebug() << "Select";
0696     if (!($$ = buildSelectQuery( $1, nullptr )))
0697         YYABORT;
0698 }
0699 | Select ColViews
0700 {
0701     sqlParserDebug() << "Select ColViews=" << *$2;
0702 
0703     if (!($$ = buildSelectQuery( $1, $2 )))
0704         YYABORT;
0705 }
0706 | Select ColViews Tables
0707 {
0708     if (!($$ = buildSelectQuery( $1, $2, $3 )))
0709         YYABORT;
0710 }
0711 | Select Tables
0712 {
0713     sqlParserDebug() << "Select ColViews Tables";
0714     if (!($$ = buildSelectQuery( $1, nullptr, $2 )))
0715         YYABORT;
0716 }
0717 | Select ColViews SelectOptions
0718 {
0719     sqlParserDebug() << "Select ColViews Conditions";
0720     if (!($$ = buildSelectQuery( $1, $2, nullptr, $3 )))
0721         YYABORT;
0722 }
0723 | Select Tables SelectOptions
0724 {
0725     sqlParserDebug() << "Select Tables SelectOptions";
0726     if (!($$ = buildSelectQuery( $1, nullptr, $2, $3 )))
0727         YYABORT;
0728 }
0729 | Select ColViews Tables SelectOptions
0730 {
0731     sqlParserDebug() << "Select ColViews Tables SelectOptions";
0732     if (!($$ = buildSelectQuery( $1, $2, $3, $4 )))
0733         YYABORT;
0734 }
0735 ;
0736 
0737 Select:
0738 SELECT
0739 {
0740     sqlParserDebug() << "SELECT";
0741     $$ = KDbParserPrivate::get(globalParser)->createQuery();
0742 }
0743 ;
0744 
0745 SelectOptions: /* todo: more options (having, group by, limit...) */
0746 WhereClause
0747 {
0748     sqlParserDebug() << "WhereClause";
0749     $$ = new SelectOptionsInternal;
0750     $$->whereExpr = *$1;
0751     delete $1;
0752 }
0753 | ORDER BY OrderByClause
0754 {
0755     sqlParserDebug() << "OrderByClause";
0756     $$ = new SelectOptionsInternal;
0757     $$->orderByColumns = $3;
0758 }
0759 | WhereClause ORDER BY OrderByClause
0760 {
0761     sqlParserDebug() << "WhereClause ORDER BY OrderByClause";
0762     $$ = new SelectOptionsInternal;
0763     $$->whereExpr = *$1;
0764     delete $1;
0765     $$->orderByColumns = $4;
0766 }
0767 | ORDER BY OrderByClause WhereClause
0768 {
0769     sqlParserDebug() << "OrderByClause WhereClause";
0770     $$ = new SelectOptionsInternal;
0771     $$->whereExpr = *$4;
0772     delete $4;
0773     $$->orderByColumns = $3;
0774 }
0775 ;
0776 
0777 WhereClause:
0778 WHERE aExpr
0779 {
0780     $$ = $2;
0781 }
0782 ;
0783 
0784 /* todo: support "ORDER BY NULL" as described here https://dev.mysql.com/doc/refman/5.1/en/select.html */
0785 /* todo: accept expr and position as well */
0786 OrderByClause:
0787 OrderByColumnId
0788 {
0789     sqlParserDebug() << "ORDER BY IDENTIFIER";
0790     $$ = new QList<OrderByColumnInternal>;
0791     OrderByColumnInternal orderByColumn;
0792     orderByColumn.setColumnByNameOrNumber( *$1 );
0793     $$->append( orderByColumn );
0794     delete $1;
0795 }
0796 | OrderByColumnId OrderByOption
0797 {
0798     sqlParserDebug() << "ORDER BY IDENTIFIER OrderByOption";
0799     $$ = new QList<OrderByColumnInternal>;
0800     OrderByColumnInternal orderByColumn;
0801     orderByColumn.setColumnByNameOrNumber( *$1 );
0802     orderByColumn.order = $2;
0803     $$->append( orderByColumn );
0804     delete $1;
0805 }
0806 | OrderByColumnId ',' OrderByClause
0807 {
0808     $$ = $3;
0809     OrderByColumnInternal orderByColumn;
0810     orderByColumn.setColumnByNameOrNumber( *$1 );
0811     $$->append( orderByColumn );
0812     delete $1;
0813 }
0814 | OrderByColumnId OrderByOption ',' OrderByClause
0815 {
0816     $$ = $4;
0817     OrderByColumnInternal orderByColumn;
0818     orderByColumn.setColumnByNameOrNumber( *$1 );
0819     orderByColumn.order = $2;
0820     $$->append( orderByColumn );
0821     delete $1;
0822 }
0823 ;
0824 
0825 OrderByColumnId:
0826 IDENTIFIER
0827 {
0828     $$ = new QVariant( *$1 );
0829     sqlParserDebug() << "OrderByColumnId: " << *$$;
0830     delete $1;
0831 }
0832 | IDENTIFIER '.' IDENTIFIER
0833 {
0834     $$ = new QVariant( *$1 + QLatin1Char('.') + *$3 );
0835     sqlParserDebug() << "OrderByColumnId: " << *$$;
0836     delete $1;
0837     delete $3;
0838 }
0839 | INTEGER_CONST
0840 {
0841     $$ = new QVariant($1);
0842     sqlParserDebug() << "OrderByColumnId: " << *$$;
0843 }
0844 
0845 OrderByOption:
0846 ASC
0847 {
0848     $$ = KDbOrderByColumn::SortOrder::Ascending;
0849 }
0850 | DESC
0851 {
0852     $$ = KDbOrderByColumn::SortOrder::Descending;
0853 }
0854 ;
0855 
0856 aExpr:
0857 aExpr2
0858 ;
0859 
0860 /* --- binary logical --- */
0861 aExpr2:
0862 aExpr3 AND aExpr2
0863 {
0864 //    sqlParserDebug() << "AND " << $3.debugString();
0865     $$ = new KDbBinaryExpression(*$1, KDbToken::AND, *$3);
0866     delete $1;
0867     delete $3;
0868 }
0869 | aExpr3 OR aExpr2
0870 {
0871     $$ = new KDbBinaryExpression(*$1, KDbToken::OR, *$3);
0872     delete $1;
0873     delete $3;
0874 }
0875 | aExpr3 XOR aExpr2
0876 {
0877     $$ = new KDbBinaryExpression(*$1, KDbToken::XOR, *$3);
0878     delete $1;
0879     delete $3;
0880 }
0881 |
0882 aExpr3
0883 ;
0884 
0885 /* relational op precedence */
0886 aExpr3:
0887 aExpr4 '>' %prec GREATER_OR_EQUAL aExpr3
0888 {
0889     $$ = new KDbBinaryExpression(*$1, '>', *$3);
0890     delete $1;
0891     delete $3;
0892 }
0893 | aExpr4 GREATER_OR_EQUAL aExpr3
0894 {
0895     $$ = new KDbBinaryExpression(*$1, KDbToken::GREATER_OR_EQUAL, *$3);
0896     delete $1;
0897     delete $3;
0898 }
0899 | aExpr4 '<' %prec LESS_OR_EQUAL aExpr3
0900 {
0901     $$ = new KDbBinaryExpression(*$1, '<', *$3);
0902     delete $1;
0903     delete $3;
0904 }
0905 | aExpr4 LESS_OR_EQUAL aExpr3
0906 {
0907     $$ = new KDbBinaryExpression(*$1, KDbToken::LESS_OR_EQUAL, *$3);
0908     delete $1;
0909     delete $3;
0910 }
0911 | aExpr4 '=' aExpr3
0912 {
0913     $$ = new KDbBinaryExpression(*$1, '=', *$3);
0914     delete $1;
0915     delete $3;
0916 }
0917 |
0918 aExpr4
0919 ;
0920 
0921 /* relational (equality) op precedence */
0922 aExpr4:
0923 aExpr5 NOT_EQUAL aExpr4
0924 {
0925     $$ = new KDbBinaryExpression(*$1, KDbToken::NOT_EQUAL, *$3);
0926     delete $1;
0927     delete $3;
0928 }
0929 | aExpr5 NOT_EQUAL2 aExpr4
0930 {
0931     $$ = new KDbBinaryExpression(*$1, KDbToken::NOT_EQUAL2, *$3);
0932     delete $1;
0933     delete $3;
0934 }
0935 | aExpr5 LIKE aExpr4
0936 {
0937     $$ = new KDbBinaryExpression(*$1, KDbToken::LIKE, *$3);
0938     delete $1;
0939     delete $3;
0940 }
0941 | aExpr5 NOT_LIKE aExpr4
0942 {
0943     $$ = new KDbBinaryExpression(*$1, KDbToken::NOT_LIKE, *$3);
0944     delete $1;
0945     delete $3;
0946 }
0947 | aExpr5 SQL_IN aExpr4
0948 {
0949     $$ = new KDbBinaryExpression(*$1, KDbToken::SQL_IN, *$3);
0950     delete $1;
0951     delete $3;
0952 }
0953 | aExpr5 SIMILAR_TO aExpr4
0954 {
0955     $$ = new KDbBinaryExpression(*$1, KDbToken::SIMILAR_TO, *$3);
0956     delete $1;
0957     delete $3;
0958 }
0959 | aExpr5 NOT_SIMILAR_TO aExpr4
0960 {
0961     $$ = new KDbBinaryExpression(*$1, KDbToken::NOT_SIMILAR_TO, *$3);
0962     delete $1;
0963     delete $3;
0964 }
0965 | aExpr5 BETWEEN aExpr4 AND aExpr4
0966 {
0967     $$ = new KDbNArgExpression(KDb::RelationalExpression, KDbToken::BETWEEN_AND);
0968     $$->toNArg().append( *$1 );
0969     $$->toNArg().append( *$3 );
0970     $$->toNArg().append( *$5 );
0971     delete $1;
0972     delete $3;
0973     delete $5;
0974 }
0975 | aExpr5 NOT_BETWEEN aExpr4 AND aExpr4
0976 {
0977     $$ = new KDbNArgExpression(KDb::RelationalExpression, KDbToken::NOT_BETWEEN_AND);
0978     $$->toNArg().append( *$1 );
0979     $$->toNArg().append( *$3 );
0980     $$->toNArg().append( *$5 );
0981     delete $1;
0982     delete $3;
0983     delete $5;
0984 }
0985 |
0986 aExpr5
0987 ;
0988 
0989 /* --- unary logical right --- */
0990 aExpr5:
0991 aExpr5 SQL_IS_NULL
0992 {
0993     $$ = new KDbUnaryExpression( KDbToken::SQL_IS_NULL, *$1 );
0994     delete $1;
0995 }
0996 | aExpr5 SQL_IS_NOT_NULL
0997 {
0998     $$ = new KDbUnaryExpression( KDbToken::SQL_IS_NOT_NULL, *$1 );
0999     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