You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1369 lines
25 KiB
1369 lines
25 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2004 Lucijan Busch <lucijan@kde.org>
|
|
Copyright (C) 2004, 2006 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
%token UMINUS
|
|
|
|
%token SQL_TYPE
|
|
%token SQL_ABS
|
|
%token ACOS
|
|
%token AMPERSAND
|
|
%token SQL_ABSOLUTE
|
|
%token ADA
|
|
%token ADD
|
|
%token ADD_DAYS
|
|
%token ADD_HOURS
|
|
%token ADD_MINUTES
|
|
%token ADD_MONTHS
|
|
%token ADD_SECONDS
|
|
%token ADD_YEARS
|
|
%token ALL
|
|
%token ALLOCATE
|
|
%token ALTER
|
|
%token AND
|
|
%token ANY
|
|
%token ARE
|
|
%token AS
|
|
%token ASIN
|
|
%token ASC
|
|
%token ASCII
|
|
%token ASSERTION
|
|
%token ATAN
|
|
%token ATAN2
|
|
%token AUTHORIZATION
|
|
%token AUTO_INCREMENT
|
|
%token AVG
|
|
%token BEFORE
|
|
%token SQL_BEGIN
|
|
%token BETWEEN
|
|
%token BIGINT
|
|
%token BINARY
|
|
%token BIT
|
|
%token BIT_LENGTH
|
|
%token BITWISE_SHIFT_LEFT
|
|
%token BITWISE_SHIFT_RIGHT
|
|
%token BREAK
|
|
%token BY
|
|
%token CASCADE
|
|
%token CASCADED
|
|
%token CASE
|
|
%token CAST
|
|
%token CATALOG
|
|
%token CEILING
|
|
%token CENTER
|
|
%token SQL_CHAR
|
|
%token CHAR_LENGTH
|
|
%token CHARACTER_STRING_LITERAL
|
|
%token CHECK
|
|
%token CLOSE
|
|
%token COALESCE
|
|
%token COBOL
|
|
%token COLLATE
|
|
%token COLLATION
|
|
%token COLUMN
|
|
%token COMMIT
|
|
%token COMPUTE
|
|
%token CONCAT
|
|
%token CONCATENATION /* || */
|
|
%token CONNECT
|
|
%token CONNECTION
|
|
%token CONSTRAINT
|
|
%token CONSTRAINTS
|
|
%token CONTINUE
|
|
%token CONVERT
|
|
%token CORRESPONDING
|
|
%token COS
|
|
%token COT
|
|
%token COUNT
|
|
%token CREATE
|
|
%token CURDATE
|
|
%token CURRENT
|
|
%token CURRENT_DATE
|
|
%token CURRENT_TIME
|
|
%token CURRENT_TIMESTAMP
|
|
%token CURTIME
|
|
%token CURSOR
|
|
%token DATABASE
|
|
%token SQL_DATE
|
|
%token DATE_FORMAT
|
|
%token DATE_REMAINDER
|
|
%token DATE_VALUE
|
|
%token DAY
|
|
%token DAYOFMONTH
|
|
%token DAYOFWEEK
|
|
%token DAYOFYEAR
|
|
%token DAYS_BETWEEN
|
|
%token DEALLOCATE
|
|
%token DEC
|
|
%token DECLARE
|
|
%token DEFAULT
|
|
%token DEFERRABLE
|
|
%token DEFERRED
|
|
%token SQL_DELETE
|
|
%token DESC
|
|
%token DESCRIBE
|
|
%token DESCRIPTOR
|
|
%token DIAGNOSTICS
|
|
%token DICTIONARY
|
|
%token DIRECTORY
|
|
%token DISCONNECT
|
|
%token DISPLACEMENT
|
|
%token DISTINCT
|
|
%token DOMAIN_TOKEN
|
|
%token SQL_DOUBLE
|
|
%token DOUBLE_QUOTED_STRING
|
|
%token DROP
|
|
%token ELSE
|
|
%token END
|
|
%token END_EXEC
|
|
%token EQUAL
|
|
%token ESCAPE
|
|
%token EXCEPT
|
|
%token SQL_EXCEPTION
|
|
%token EXEC
|
|
%token EXECUTE
|
|
%token EXISTS
|
|
%token EXP
|
|
%token EXPONENT
|
|
%token EXTERNAL
|
|
%token EXTRACT
|
|
%token SQL_FALSE
|
|
%token FETCH
|
|
%token FIRST
|
|
%token SQL_FLOAT
|
|
%token FLOOR
|
|
%token FN
|
|
%token FOR
|
|
%token FOREIGN
|
|
%token FORTRAN
|
|
%token FOUND
|
|
%token FOUR_DIGITS
|
|
%token FROM
|
|
%token FULL
|
|
%token GET
|
|
%token GLOBAL
|
|
%token GO
|
|
%token GOTO
|
|
%token GRANT
|
|
%token GREATER_OR_EQUAL
|
|
//%token GREATER_THAN
|
|
//conflict %token GROUP
|
|
%token HAVING
|
|
%token HOUR
|
|
%token HOURS_BETWEEN
|
|
%token IDENTITY
|
|
%token IFNULL
|
|
%token SQL_IGNORE
|
|
%token IMMEDIATE
|
|
%token SQL_IN
|
|
%token INCLUDE
|
|
%token INDEX
|
|
%token INDICATOR
|
|
%token INITIALLY
|
|
%token INNER
|
|
%token INPUT
|
|
%token INSENSITIVE
|
|
%token INSERT
|
|
%token INTEGER
|
|
%token INTERSECT
|
|
%token INTERVAL
|
|
%token INTO
|
|
%token IS
|
|
%token ISOLATION
|
|
%token JOIN
|
|
%token JUSTIFY
|
|
%token KEY
|
|
%token LANGUAGE
|
|
%token LAST
|
|
%token LCASE
|
|
%token LEFT
|
|
%token LENGTH
|
|
%token LESS_OR_EQUAL
|
|
//%token LESS_THAN
|
|
%token LEVEL
|
|
%token LIKE
|
|
%token LINE_WIDTH
|
|
%token LOCAL
|
|
%token LOCATE
|
|
%token LOG
|
|
%token SQL_LONG
|
|
%token LOWER
|
|
%token LTRIM
|
|
%token LTRIP
|
|
%token MATCH
|
|
%token SQL_MAX
|
|
%token MICROSOFT
|
|
%token SQL_MIN
|
|
%token MINUS
|
|
%token MINUTE
|
|
%token MINUTES_BETWEEN
|
|
%token MOD
|
|
%token MODIFY
|
|
%token MODULE
|
|
%token MONTH
|
|
%token MONTHS_BETWEEN
|
|
%token MUMPS
|
|
%token NAMES
|
|
%token NATIONAL
|
|
%token NCHAR
|
|
%token NEXT
|
|
%token NODUP
|
|
%token NONE
|
|
%token NOT
|
|
%token NOT_EQUAL //<>
|
|
%token NOT_EQUAL2 //!=
|
|
%token NOW
|
|
%token SQL_NULL
|
|
%token SQL_IS
|
|
%token SQL_IS_NULL /*helper */
|
|
%token SQL_IS_NOT_NULL /*helper */
|
|
%token NULLIF
|
|
%token NUMERIC
|
|
%token OCTET_LENGTH
|
|
%token ODBC
|
|
%token OF
|
|
%token SQL_OFF
|
|
%token SQL_ON
|
|
%token ONLY
|
|
%token OPEN
|
|
%token OPTION
|
|
%token OR
|
|
%token ORDER
|
|
%token OUTER
|
|
%token OUTPUT
|
|
%token OVERLAPS
|
|
%token PAGE
|
|
%token PARTIAL
|
|
%token SQL_PASCAL
|
|
%token PERSISTENT
|
|
%token CQL_PI
|
|
%token PLI
|
|
%token POSITION
|
|
%token PRECISION
|
|
%token PREPARE
|
|
%token PRESERVE
|
|
%token PRIMARY
|
|
%token PRIOR
|
|
%token PRIVILEGES
|
|
%token PROCEDURE
|
|
%token PRODUCT
|
|
%token PUBLIC
|
|
%token QUARTER
|
|
%token QUIT
|
|
%token RAND
|
|
%token READ_ONLY
|
|
%token REAL
|
|
%token REFERENCES
|
|
%token REPEAT
|
|
%token REPLACE
|
|
%token RESTRICT
|
|
%token REVOKE
|
|
%token RIGHT
|
|
%token ROLLBACK
|
|
%token ROWS
|
|
%token RPAD
|
|
%token RTRIM
|
|
%token SCHEMA
|
|
%token SCREEN_WIDTH
|
|
%token SCROLL
|
|
%token SECOND
|
|
%token SECONDS_BETWEEN
|
|
%token SELECT
|
|
%token SEQUENCE
|
|
%token SETOPT
|
|
%token SET
|
|
%token SHOWOPT
|
|
%token SIGN
|
|
//%token SIMILAR
|
|
%token SIMILAR_TO /* helper */
|
|
%token NOT_SIMILAR_TO /* helper */
|
|
%token INTEGER_CONST
|
|
%token REAL_CONST
|
|
%token DATE_CONST
|
|
%token DATETIME_CONST
|
|
%token TIME_CONST
|
|
%token SIN
|
|
%token SQL_SIZE
|
|
%token SMALLINT
|
|
%token SOME
|
|
%token SPACE
|
|
%token SQL
|
|
%token SQL_TRUE
|
|
%token SQLCA
|
|
%token SQLCODE
|
|
%token SQLERROR
|
|
%token SQLSTATE
|
|
%token SQLWARNING
|
|
%token SQRT
|
|
%token STDEV
|
|
%token SUBSTRING
|
|
%token SUM
|
|
%token SYSDATE
|
|
%token SYSDATE_FORMAT
|
|
%token SYSTEM
|
|
%token TABLE
|
|
%token TAN
|
|
%token TEMPORARY
|
|
%token THEN
|
|
%token THREE_DIGITS
|
|
%token TIME
|
|
%token TIMESTAMP
|
|
%token TIMEZONE_HOUR
|
|
%token TIMEZONE_MINUTE
|
|
%token TINYINT
|
|
%token TO
|
|
%token TO_CHAR
|
|
%token TO_DATE
|
|
%token TRANSACTION
|
|
%token TRANSLATE
|
|
%token TRANSLATION
|
|
%token TRUNCATE
|
|
%token GENERAL_TITLE
|
|
%token TWO_DIGITS
|
|
%token UCASE
|
|
%token UNION
|
|
%token UNIQUE
|
|
%token SQL_UNKNOWN
|
|
//%token UNSIGNED_INTEGER
|
|
%token UPDATE
|
|
%token UPPER
|
|
%token USAGE
|
|
%token USER
|
|
%token IDENTIFIER
|
|
%token IDENTIFIER_DOT_ASTERISK
|
|
%token QUERY_PARAMETER
|
|
//%token ERROR_DIGIT_BEFORE_IDENTIFIER
|
|
%token USING
|
|
%token VALUE
|
|
%token VALUES
|
|
%token VARBINARY
|
|
%token VARCHAR
|
|
%token VARYING
|
|
%token VENDOR
|
|
%token VIEW
|
|
%token WEEK
|
|
%token WHEN
|
|
%token WHENEVER
|
|
%token WHERE
|
|
%token WHERE_CURRENT_OF
|
|
%token WITH
|
|
%token WORD_WRAPPED
|
|
%token WORK
|
|
%token WRAPPED
|
|
%token XOR
|
|
%token YEAR
|
|
%token YEARS_BETWEEN
|
|
|
|
%token SCAN_ERROR
|
|
%token __LAST_TOKEN /* sentinel */
|
|
|
|
%token '-' '+'
|
|
%token '*'
|
|
%token '%'
|
|
%token '@'
|
|
%token ';'
|
|
%token ','
|
|
%token '.'
|
|
%token '$'
|
|
//%token '<'
|
|
//%token '>'
|
|
%token '(' ')'
|
|
%token '?'
|
|
%token '\''
|
|
%token '/'
|
|
|
|
%type <stringValue> IDENTIFIER
|
|
%type <stringValue> IDENTIFIER_DOT_ASTERISK
|
|
%type <stringValue> QUERY_PARAMETER
|
|
%type <stringValue> CHARACTER_STRING_LITERAL
|
|
%type <stringValue> DOUBLE_QUOTED_STRING
|
|
|
|
/*
|
|
%type <field> ColExpression
|
|
%type <field> ColView
|
|
*/
|
|
%type <expr> ColExpression
|
|
%type <expr> ColWildCard
|
|
//%type <expr> ColView
|
|
%type <expr> ColItem
|
|
%type <exprList> ColViews
|
|
%type <expr> aExpr
|
|
%type <expr> aExpr2
|
|
%type <expr> aExpr3
|
|
%type <expr> aExpr4
|
|
%type <expr> aExpr5
|
|
%type <expr> aExpr6
|
|
%type <expr> aExpr7
|
|
%type <expr> aExpr8
|
|
%type <expr> aExpr9
|
|
%type <expr> aExpr10
|
|
%type <exprList> aExprList
|
|
%type <exprList> aExprList2
|
|
%type <expr> WhereClause
|
|
%type <orderByColumns> OrderByClause
|
|
%type <booleanValue> OrderByOption
|
|
%type <variantValue> OrderByColumnId
|
|
%type <selectOptions> SelectOptions
|
|
%type <expr> FlatTable
|
|
%type <exprList> Tables
|
|
%type <exprList> FlatTableList
|
|
%type <querySchema> SelectStatement
|
|
%type <querySchema> Select
|
|
/*todo : list*/
|
|
%type <querySchema> StatementList
|
|
/*todo: not onlu select*/
|
|
%type <querySchema> Statement
|
|
|
|
%type <colType> SQL_TYPE
|
|
%type <integerValue> INTEGER_CONST
|
|
%type <realValue> REAL_CONST
|
|
/*%type <integerValue> SIGNED_INTEGER */
|
|
|
|
%{
|
|
#ifndef YYDEBUG /* compat. */
|
|
# define YYDEBUG 0
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <assert.h>
|
|
#include <limits.h>
|
|
//TODO OK?
|
|
#ifdef Q_WS_WIN
|
|
//workaround for bug on msvc
|
|
# undef LLONG_MIN
|
|
#endif
|
|
#ifndef LLONG_MAX
|
|
# define LLONG_MAX 0x7fffffffffffffffLL
|
|
#endif
|
|
#ifndef LLONG_MIN
|
|
# define LLONG_MIN 0x8000000000000000LL
|
|
#endif
|
|
#ifndef LLONG_MAX
|
|
# define ULLONG_MAX 0xffffffffffffffffLL
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
# include <malloc.h>
|
|
#endif
|
|
|
|
#include <tqobject.h>
|
|
#include <kdebug.h>
|
|
#include <klocale.h>
|
|
#include <tqptrlist.h>
|
|
#include <tqcstring.h>
|
|
#include <tqvariant.h>
|
|
|
|
#include <connection.h>
|
|
#include <queryschema.h>
|
|
#include <field.h>
|
|
#include <tableschema.h>
|
|
|
|
#include "parser.h"
|
|
#include "parser_p.h"
|
|
#include "sqltypes.h"
|
|
|
|
int yylex();
|
|
|
|
// using namespace std;
|
|
using namespace KexiDB;
|
|
|
|
#define YY_NO_UNPUT
|
|
#define YYSTACK_USE_ALLOCA 1
|
|
#define YYMAXDEPTH 255
|
|
|
|
extern "C"
|
|
{
|
|
int yywrap()
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
struct yyval
|
|
{
|
|
TQString parserUserName;
|
|
int integerValue;
|
|
KexiDBField::ColumnType coltype;
|
|
}
|
|
#endif
|
|
|
|
%}
|
|
|
|
%union {
|
|
TQString* stringValue;
|
|
TQ_LLONG integerValue;
|
|
bool booleanValue;
|
|
struct realType realValue;
|
|
KexiDB::Field::Type colType;
|
|
KexiDB::Field *field;
|
|
KexiDB::BaseExpr *expr;
|
|
KexiDB::NArgExpr *exprList;
|
|
KexiDB::ConstExpr *constExpr;
|
|
KexiDB::QuerySchema *querySchema;
|
|
SelectOptionsInternal *selectOptions;
|
|
OrderByColumnInternal::List *orderByColumns;
|
|
QVariant *variantValue;
|
|
}
|
|
|
|
//%left '=' NOT_EQUAL '>' GREATER_OR_EQUAL '<' LESS_OR_EQUAL LIKE '%' NOT
|
|
//%left '+' '-'
|
|
//%left ASTERISK SLASH
|
|
|
|
/* precedence: lowest to highest */
|
|
%left UNION EXCEPT
|
|
%left INTERSECT
|
|
%left OR
|
|
%left AND XOR
|
|
%right NOT
|
|
//%right '='
|
|
//%nonassoc '<' '>'
|
|
//%nonassoc '=' '<' '>' "<=" ">=" "<>" ":=" LIKE ILIKE SIMILAR
|
|
//%nonassoc '=' LESS_THAN GREATER_THAN LESS_OR_EQUAL GREATER_OR_EQUAL NOT_EQUAL
|
|
%nonassoc '=' '<' '>'
|
|
//LESS_THAN GREATER_THAN
|
|
%nonassoc LESS_OR_EQUAL GREATER_OR_EQUAL
|
|
%nonassoc NOT_EQUAL NOT_EQUAL2
|
|
%nonassoc SQL_IN LIKE ILIKE SIMILAR_TO NOT_SIMILAR_TO
|
|
//%nonassoc LIKE ILIKE SIMILAR
|
|
//%nonassoc ESCAPE
|
|
//%nonassoc OVERLAPS
|
|
%nonassoc BETWEEN
|
|
//%nonassoc IN_P
|
|
//%left POSTFIXOP // dummy for postfix Op rules
|
|
//%left Op OPERATOR // multi-character ops and user-defined operators
|
|
//%nonassoc NOTNULL
|
|
//%nonassoc ISNULL
|
|
//%nonassoc IS NULL_P TRUE_P FALSE_P UNKNOWN // sets precedence for IS NULL, etc
|
|
%left '+' '-'
|
|
%left '*' '/' '%'
|
|
%left '^'
|
|
%left UMINUS
|
|
// Unary Operators
|
|
//%left AT ZONE // sets precedence for AT TIME ZONE
|
|
//%right UMINUS
|
|
%left '[' ']'
|
|
%left '(' ')'
|
|
//%left TYPECAST
|
|
%left '.'
|
|
|
|
/*
|
|
* These might seem to be low-precedence, but actually they are not part
|
|
* of the arithmetic hierarchy at all in their use as JOIN operators.
|
|
* We make them high-precedence to support their use as function names.
|
|
* They wouldn't be given a precedence at all, were it not that we need
|
|
* left-associativity among the JOIN rules themselves.
|
|
*/
|
|
/*%left JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
|
|
*/
|
|
%%
|
|
|
|
TopLevelStatement :
|
|
StatementList
|
|
{
|
|
//todo: multiple statements
|
|
//todo: not only "select" statements
|
|
parser->setOperation(Parser::OP_Select);
|
|
parser->setQuerySchema($1);
|
|
}
|
|
;
|
|
|
|
StatementList:
|
|
Statement ';' StatementList
|
|
{
|
|
//todo: multiple statements
|
|
}
|
|
| Statement
|
|
| Statement ';'
|
|
{
|
|
$$ = $1;
|
|
}
|
|
;
|
|
|
|
/* Statement CreateTableStatement { YYACCEPT; }
|
|
| Statement SelectStatement { }
|
|
*/
|
|
Statement :
|
|
CreateTableStatement
|
|
{
|
|
YYACCEPT;
|
|
}
|
|
| SelectStatement
|
|
{
|
|
$$ = $1;
|
|
}
|
|
;
|
|
|
|
CreateTableStatement :
|
|
CREATE TABLE IDENTIFIER
|
|
{
|
|
parser->setOperation(Parser::OP_CreateTable);
|
|
parser->createTable($3->latin1());
|
|
delete $3;
|
|
}
|
|
'(' ColDefs ')'
|
|
;
|
|
|
|
ColDefs:
|
|
ColDefs ',' ColDef|ColDef
|
|
{
|
|
}
|
|
;
|
|
|
|
ColDef:
|
|
IDENTIFIER ColType
|
|
{
|
|
KexiDBDbg << "adding field " << *$1 << endl;
|
|
field->setName($1->latin1());
|
|
parser->table()->addField(field);
|
|
field = 0;
|
|
delete $1;
|
|
}
|
|
| IDENTIFIER ColType ColKeys
|
|
{
|
|
KexiDBDbg << "adding field " << *$1 << endl;
|
|
field->setName(*$1);
|
|
delete $1;
|
|
parser->table()->addField(field);
|
|
|
|
// if(field->isPrimaryKey())
|
|
// parser->table()->addPrimaryKey(field->name());
|
|
|
|
// delete field;
|
|
// field = 0;
|
|
}
|
|
;
|
|
|
|
ColKeys:
|
|
ColKeys ColKey|ColKey
|
|
{
|
|
}
|
|
;
|
|
|
|
ColKey:
|
|
PRIMARY KEY
|
|
{
|
|
field->setPrimaryKey(true);
|
|
KexiDBDbg << "primary" << endl;
|
|
}
|
|
| NOT SQL_NULL
|
|
{
|
|
field->setNotNull(true);
|
|
KexiDBDbg << "not_null" << endl;
|
|
}
|
|
| AUTO_INCREMENT
|
|
{
|
|
field->setAutoIncrement(true);
|
|
KexiDBDbg << "ainc" << endl;
|
|
}
|
|
;
|
|
|
|
ColType:
|
|
SQL_TYPE
|
|
{
|
|
field = new Field();
|
|
field->setType($1);
|
|
}
|
|
| SQL_TYPE '(' INTEGER_CONST ')'
|
|
{
|
|
KexiDBDbg << "sql + length" << endl;
|
|
field = new Field();
|
|
field->setPrecision($3);
|
|
field->setType($1);
|
|
}
|
|
| VARCHAR '(' INTEGER_CONST ')'
|
|
{
|
|
field = new Field();
|
|
field->setPrecision($3);
|
|
field->setType(Field::Text);
|
|
}
|
|
|
|
|
{
|
|
// SQLITE compatibillity
|
|
field = new Field();
|
|
field->setType(Field::InvalidType);
|
|
}
|
|
;
|
|
|
|
SelectStatement:
|
|
Select ColViews
|
|
{
|
|
KexiDBDbg << "Select ColViews=" << $2->debugString() << endl;
|
|
|
|
if (!($$ = buildSelectQuery( $1, $2 )))
|
|
return 0;
|
|
}
|
|
| Select ColViews Tables
|
|
{
|
|
if (!($$ = buildSelectQuery( $1, $2, $3 )))
|
|
return 0;
|
|
}
|
|
| Select Tables
|
|
{
|
|
KexiDBDbg << "Select ColViews Tables" << endl;
|
|
if (!($$ = buildSelectQuery( $1, 0, $2 )))
|
|
return 0;
|
|
}
|
|
| Select ColViews SelectOptions
|
|
{
|
|
KexiDBDbg << "Select ColViews Conditions" << endl;
|
|
if (!($$ = buildSelectQuery( $1, $2, 0, $3 )))
|
|
return 0;
|
|
}
|
|
| Select ColViews Tables SelectOptions
|
|
{
|
|
KexiDBDbg << "Select ColViews Tables SelectOptions" << endl;
|
|
if (!($$ = buildSelectQuery( $1, $2, $3, $4 )))
|
|
return 0;
|
|
}
|
|
;
|
|
|
|
Select:
|
|
SELECT
|
|
{
|
|
KexiDBDbg << "SELECT" << endl;
|
|
// parser->createSelect();
|
|
// parser->setOperation(Parser::OP_Select);
|
|
$$ = new TQuerySchema();
|
|
}
|
|
;
|
|
|
|
SelectOptions: /* todo: more options (having, group by, limit...) */
|
|
WhereClause
|
|
{
|
|
KexiDBDbg << "WhereClause" << endl;
|
|
$$ = new SelectOptionsInternal;
|
|
$$->whereExpr = $1;
|
|
}
|
|
| ORDER BY OrderByClause
|
|
{
|
|
KexiDBDbg << "OrderByClause" << endl;
|
|
$$ = new SelectOptionsInternal;
|
|
$$->orderByColumns = $3;
|
|
}
|
|
| WhereClause ORDER BY OrderByClause
|
|
{
|
|
KexiDBDbg << "WhereClause ORDER BY OrderByClause" << endl;
|
|
$$ = new SelectOptionsInternal;
|
|
$$->whereExpr = $1;
|
|
$$->orderByColumns = $4;
|
|
}
|
|
| ORDER BY OrderByClause WhereClause
|
|
{
|
|
KexiDBDbg << "OrderByClause WhereClause" << endl;
|
|
$$ = new SelectOptionsInternal;
|
|
$$->whereExpr = $4;
|
|
$$->orderByColumns = $3;
|
|
}
|
|
;
|
|
|
|
WhereClause:
|
|
WHERE aExpr
|
|
{
|
|
$$ = $2;
|
|
}
|
|
;
|
|
|
|
/* todo: support "ORDER BY NULL" as described here http://dev.mysql.com/doc/refman/5.1/en/select.html */
|
|
/* todo: accept expr and position as well */
|
|
OrderByClause:
|
|
OrderByColumnId
|
|
{
|
|
KexiDBDbg << "ORDER BY IDENTIFIER" << endl;
|
|
$$ = new OrderByColumnInternal::List;
|
|
OrderByColumnInternal orderByColumn;
|
|
orderByColumn.setColumnByNameOrNumber( *$1 );
|
|
$$->append( orderByColumn );
|
|
delete $1;
|
|
}
|
|
| OrderByColumnId OrderByOption
|
|
{
|
|
KexiDBDbg << "ORDER BY IDENTIFIER OrderByOption" << endl;
|
|
$$ = new OrderByColumnInternal::List;
|
|
OrderByColumnInternal orderByColumn;
|
|
orderByColumn.setColumnByNameOrNumber( *$1 );
|
|
orderByColumn.ascending = $2;
|
|
$$->append( orderByColumn );
|
|
delete $1;
|
|
}
|
|
| OrderByColumnId ',' OrderByClause
|
|
{
|
|
$$ = $3;
|
|
OrderByColumnInternal orderByColumn;
|
|
orderByColumn.setColumnByNameOrNumber( *$1 );
|
|
$$->append( orderByColumn );
|
|
delete $1;
|
|
}
|
|
| OrderByColumnId OrderByOption ',' OrderByClause
|
|
{
|
|
$$ = $4;
|
|
OrderByColumnInternal orderByColumn;
|
|
orderByColumn.setColumnByNameOrNumber( *$1 );
|
|
orderByColumn.ascending = $2;
|
|
$$->append( orderByColumn );
|
|
delete $1;
|
|
}
|
|
;
|
|
|
|
OrderByColumnId:
|
|
IDENTIFIER
|
|
{
|
|
$$ = new TQVariant( *$1 );
|
|
KexiDBDbg << "OrderByColumnId: " << *$$ << endl;
|
|
delete $1;
|
|
}
|
|
| IDENTIFIER '.' IDENTIFIER
|
|
{
|
|
$$ = new TQVariant( *$1 + "." + *$3 );
|
|
KexiDBDbg << "OrderByColumnId: " << *$$ << endl;
|
|
delete $1;
|
|
delete $3;
|
|
}
|
|
| INTEGER_CONST
|
|
{
|
|
$$ = new TQVariant($1);
|
|
KexiDBDbg << "OrderByColumnId: " << *$$ << endl;
|
|
}
|
|
|
|
OrderByOption:
|
|
ASC
|
|
{
|
|
$$ = true;
|
|
}
|
|
| DESC
|
|
{
|
|
$$ = false;
|
|
}
|
|
;
|
|
|
|
aExpr:
|
|
aExpr2
|
|
;
|
|
|
|
/* --- binary logical --- */
|
|
aExpr2:
|
|
aExpr3 AND aExpr2
|
|
{
|
|
// KexiDBDbg << "AND " << $3.debugString() << endl;
|
|
$$ = new BinaryExpr( KexiDBExpr_Logical, $1, AND, $3 );
|
|
}
|
|
| aExpr3 OR aExpr2
|
|
{
|
|
$$ = new BinaryExpr( KexiDBExpr_Logical, $1, OR, $3 );
|
|
}
|
|
| aExpr3 XOR aExpr2
|
|
{
|
|
$$ = new BinaryExpr( KexiDBExpr_Arithm, $1, XOR, $3 );
|
|
}
|
|
|
|
|
aExpr3
|
|
;
|
|
|
|
/* relational op precedence */
|
|
aExpr3:
|
|
aExpr4 '>' %prec GREATER_OR_EQUAL aExpr3
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, '>', $3);
|
|
}
|
|
| aExpr4 GREATER_OR_EQUAL aExpr3
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, GREATER_OR_EQUAL, $3);
|
|
}
|
|
| aExpr4 '<' %prec LESS_OR_EQUAL aExpr3
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, '<', $3);
|
|
}
|
|
| aExpr4 LESS_OR_EQUAL aExpr3
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, LESS_OR_EQUAL, $3);
|
|
}
|
|
| aExpr4 '=' aExpr3
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, '=', $3);
|
|
}
|
|
|
|
|
aExpr4
|
|
;
|
|
|
|
/* relational (equality) op precedence */
|
|
aExpr4:
|
|
aExpr5 NOT_EQUAL aExpr4
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, NOT_EQUAL, $3);
|
|
}
|
|
|
|
|
aExpr5 NOT_EQUAL2 aExpr4
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, NOT_EQUAL2, $3);
|
|
}
|
|
| aExpr5 LIKE aExpr4
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, LIKE, $3);
|
|
}
|
|
| aExpr5 SQL_IN aExpr4
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, SQL_IN, $3);
|
|
}
|
|
| aExpr5 SIMILAR_TO aExpr4
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, SIMILAR_TO, $3);
|
|
}
|
|
| aExpr5 NOT_SIMILAR_TO aExpr4
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Relational, $1, NOT_SIMILAR_TO, $3);
|
|
}
|
|
|
|
|
aExpr5
|
|
;
|
|
|
|
/* --- unary logical right --- */
|
|
aExpr5:
|
|
aExpr5 SQL_IS_NULL
|
|
{
|
|
$$ = new UnaryExpr( SQL_IS_NULL, $1 );
|
|
}
|
|
| aExpr5 SQL_IS_NOT_NULL
|
|
{
|
|
$$ = new UnaryExpr( SQL_IS_NOT_NULL, $1 );
|
|
}
|
|
|
|
|
aExpr6
|
|
;
|
|
|
|
/* arithm. lowest precedence */
|
|
aExpr6:
|
|
aExpr7 BITWISE_SHIFT_LEFT aExpr6
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, BITWISE_SHIFT_LEFT, $3);
|
|
}
|
|
| aExpr7 BITWISE_SHIFT_RIGHT aExpr6
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, BITWISE_SHIFT_RIGHT, $3);
|
|
}
|
|
|
|
|
aExpr7
|
|
;
|
|
|
|
/* arithm. lower precedence */
|
|
aExpr7:
|
|
aExpr8 '+' aExpr7
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, '+', $3);
|
|
$$->debug();
|
|
}
|
|
| aExpr8 '-' %prec UMINUS aExpr7
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, '-', $3);
|
|
}
|
|
| aExpr8 '&' aExpr7
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, '&', $3);
|
|
}
|
|
| aExpr8 '|' aExpr7
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, '|', $3);
|
|
}
|
|
|
|
|
aExpr8
|
|
;
|
|
|
|
/* arithm. higher precedence */
|
|
aExpr8:
|
|
aExpr9 '/' aExpr8
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, '/', $3);
|
|
}
|
|
| aExpr9 '*' aExpr8
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, '*', $3);
|
|
}
|
|
| aExpr9 '%' aExpr8
|
|
{
|
|
$$ = new BinaryExpr(KexiDBExpr_Arithm, $1, '%', $3);
|
|
}
|
|
|
|
|
aExpr9
|
|
;
|
|
|
|
/* parenthesis, unary operators, and terminals precedence */
|
|
aExpr9:
|
|
/* --- unary logical left --- */
|
|
'-' aExpr9
|
|
{
|
|
$$ = new UnaryExpr( '-', $2 );
|
|
}
|
|
| '+' aExpr9
|
|
{
|
|
$$ = new UnaryExpr( '+', $2 );
|
|
}
|
|
| '~' aExpr9
|
|
{
|
|
$$ = new UnaryExpr( '~', $2 );
|
|
}
|
|
| NOT aExpr9
|
|
{
|
|
$$ = new UnaryExpr( NOT, $2 );
|
|
}
|
|
| IDENTIFIER
|
|
{
|
|
$$ = new VariableExpr( *$1 );
|
|
|
|
//TODO: simplify this later if that's 'only one field name' expression
|
|
KexiDBDbg << " + identifier: " << *$1 << endl;
|
|
delete $1;
|
|
}
|
|
| QUERY_PARAMETER
|
|
{
|
|
$$ = new QueryParameterExpr( *$1 );
|
|
KexiDBDbg << " + query parameter: " << $$->debugString() << endl;
|
|
delete $1;
|
|
}
|
|
| IDENTIFIER aExprList
|
|
{
|
|
KexiDBDbg << " + function: " << *$1 << "(" << $2->debugString() << ")" << endl;
|
|
$$ = new FunctionExpr(*$1, $2);
|
|
delete $1;
|
|
}
|
|
/*TODO: shall we also support db name? */
|
|
| IDENTIFIER '.' IDENTIFIER
|
|
{
|
|
$$ = new VariableExpr( *$1 + "." + *$3 );
|
|
KexiDBDbg << " + identifier.identifier: " << *$1 << "." << *$3 << endl;
|
|
delete $1;
|
|
delete $3;
|
|
}
|
|
| SQL_NULL
|
|
{
|
|
$$ = new ConstExpr( SQL_NULL, TQVariant() );
|
|
KexiDBDbg << " + NULL" << endl;
|
|
// $$ = new Field();
|
|
//$$->setName(TQString::null);
|
|
}
|
|
| CHARACTER_STRING_LITERAL
|
|
{
|
|
$$ = new ConstExpr( CHARACTER_STRING_LITERAL, *$1 );
|
|
KexiDBDbg << " + constant " << $1 << endl;
|
|
delete $1;
|
|
}
|
|
| INTEGER_CONST
|
|
{
|
|
QVariant val;
|
|
if ($1 <= INT_MAX && $1 >= INT_MIN)
|
|
val = (int)$1;
|
|
else if ($1 <= UINT_MAX && $1 >= 0)
|
|
val = (uint)$1;
|
|
else if ($1 <= (TQ_LLONG)LLONG_MAX && $1 >= (TQ_LLONG)LLONG_MIN)
|
|
val = (TQ_LLONG)$1;
|
|
|
|
// if ($1 < ULLONG_MAX)
|
|
// val = (TQ_ULLONG)$1;
|
|
//TODO ok?
|
|
|
|
$$ = new ConstExpr( INTEGER_CONST, val );
|
|
KexiDBDbg << " + int constant: " << val.toString() << endl;
|
|
}
|
|
| REAL_CONST
|
|
{
|
|
$$ = new ConstExpr( REAL_CONST, TQPoint( $1.integer, $1.fractional ) );
|
|
KexiDBDbg << " + real constant: " << $1.integer << "." << $1.fractional << endl;
|
|
}
|
|
|
|
|
aExpr10
|
|
;
|
|
|
|
|
|
aExpr10:
|
|
'(' aExpr ')'
|
|
{
|
|
KexiDBDbg << "(expr)" << endl;
|
|
$$ = new UnaryExpr('(', $2);
|
|
}
|
|
;
|
|
|
|
aExprList:
|
|
'(' aExprList2 ')'
|
|
{
|
|
// $$ = new NArgExpr(0, 0);
|
|
// $$->add( $1 );
|
|
// $$->add( $3 );
|
|
$$ = $2;
|
|
}
|
|
;
|
|
|
|
aExprList2:
|
|
aExpr ',' aExprList2
|
|
{
|
|
$$ = $3;
|
|
$$->prepend( $1 );
|
|
}
|
|
| aExpr ',' aExpr
|
|
{
|
|
$$ = new NArgExpr(0, 0);
|
|
$$->add( $1 );
|
|
$$->add( $3 );
|
|
}
|
|
;
|
|
|
|
Tables:
|
|
FROM FlatTableList
|
|
{
|
|
$$ = $2;
|
|
}
|
|
/*
|
|
| Tables LEFT JOIN IDENTIFIER SQL_ON ColExpression
|
|
{
|
|
KexiDBDbg << "LEFT JOIN: '" << *$4 << "' ON " << $6 << endl;
|
|
addTable($4->toQString());
|
|
delete $4;
|
|
}
|
|
| Tables LEFT OUTER JOIN IDENTIFIER SQL_ON ColExpression
|
|
{
|
|
KexiDBDbg << "LEFT OUTER JOIN: '" << $5 << "' ON " << $7 << endl;
|
|
addTable($5);
|
|
}
|
|
| Tables INNER JOIN IDENTIFIER SQL_ON ColExpression
|
|
{
|
|
KexiDBDbg << "INNER JOIN: '" << *$4 << "' ON " << $6 << endl;
|
|
addTable($4->toQString());
|
|
delete $4;
|
|
}
|
|
| Tables RIGHT JOIN IDENTIFIER SQL_ON ColExpression
|
|
{
|
|
KexiDBDbg << "RIGHT JOIN: '" << *$4 << "' ON " << $6 << endl;
|
|
addTable(*$4);
|
|
delete $4;
|
|
}
|
|
| Tables RIGHT OUTER JOIN IDENTIFIER SQL_ON ColExpression
|
|
{
|
|
KexiDBDbg << "RIGHT OUTER JOIN: '" << *$5 << "' ON " << $7 << endl;
|
|
addTable($5->toQString());
|
|
delete $5;
|
|
}*/
|
|
;
|
|
|
|
/*
|
|
FlatTableList:
|
|
aFlatTableList
|
|
{
|
|
$$
|
|
}
|
|
;*/
|
|
|
|
FlatTableList:
|
|
FlatTableList ',' FlatTable
|
|
{
|
|
$$ = $1;
|
|
$$->add($3);
|
|
}
|
|
|FlatTable
|
|
{
|
|
$$ = new NArgExpr(KexiDBExpr_TableList, IDENTIFIER); //ok?
|
|
$$->add($1);
|
|
}
|
|
;
|
|
|
|
FlatTable:
|
|
IDENTIFIER
|
|
{
|
|
KexiDBDbg << "FROM: '" << *$1 << "'" << endl;
|
|
$$ = new VariableExpr(*$1);
|
|
|
|
/*
|
|
//TODO: this isn't ok for more tables:
|
|
Field::ListIterator it = parser->select()->fieldsIterator();
|
|
for(Field *item; (item = it.current()); ++it)
|
|
{
|
|
if(item->table() == dummy)
|
|
{
|
|
item->setTable(schema);
|
|
}
|
|
|
|
if(item->table() && !item->isQueryAsterisk())
|
|
{
|
|
Field *f = item->table()->field(item->name());
|
|
if(!f)
|
|
{
|
|
ParserError err(i18n("Field List Error"), i18n("Unknown column '%1' in table '%2'").arg(item->name()).arg(schema->name()), ctoken, current);
|
|
parser->setError(err);
|
|
yyerror("fieldlisterror");
|
|
}
|
|
}
|
|
}*/
|
|
delete $1;
|
|
}
|
|
| IDENTIFIER IDENTIFIER
|
|
{
|
|
//table + alias
|
|
$$ = new BinaryExpr(
|
|
KexiDBExpr_SpecialBinary,
|
|
new VariableExpr(*$1), 0,
|
|
new VariableExpr(*$2)
|
|
);
|
|
delete $1;
|
|
delete $2;
|
|
}
|
|
| IDENTIFIER AS IDENTIFIER
|
|
{
|
|
//table + alias
|
|
$$ = new BinaryExpr(
|
|
KexiDBExpr_SpecialBinary,
|
|
new VariableExpr(*$1), AS,
|
|
new VariableExpr(*$3)
|
|
);
|
|
delete $1;
|
|
delete $3;
|
|
}
|
|
;
|
|
|
|
|
|
|
|
ColViews:
|
|
ColViews ',' ColItem
|
|
{
|
|
$$ = $1;
|
|
$$->add( $3 );
|
|
KexiDBDbg << "ColViews: ColViews , ColItem" << endl;
|
|
}
|
|
|ColItem
|
|
{
|
|
$$ = new NArgExpr(0,0);
|
|
$$->add( $1 );
|
|
KexiDBDbg << "ColViews: ColItem" << endl;
|
|
}
|
|
;
|
|
|
|
ColItem:
|
|
ColExpression
|
|
{
|
|
// $$ = new Field();
|
|
// dummy->addField($$);
|
|
// $$->setExpression( $1 );
|
|
// parser->select()->addField($$);
|
|
$$ = $1;
|
|
KexiDBDbg << " added column expr: '" << $1->debugString() << "'" << endl;
|
|
}
|
|
| ColWildCard
|
|
{
|
|
$$ = $1;
|
|
KexiDBDbg << " added column wildcard: '" << $1->debugString() << "'" << endl;
|
|
}
|
|
| ColExpression AS IDENTIFIER
|
|
{
|
|
$$ = new BinaryExpr(
|
|
KexiDBExpr_SpecialBinary, $1, AS,
|
|
new VariableExpr(*$3)
|
|
);
|
|
KexiDBDbg << " added column expr: " << $$->debugString() << endl;
|
|
delete $3;
|
|
}
|
|
| ColExpression IDENTIFIER
|
|
{
|
|
$$ = new BinaryExpr(
|
|
KexiDBExpr_SpecialBinary, $1, 0,
|
|
new VariableExpr(*$2)
|
|
);
|
|
KexiDBDbg << " added column expr: " << $$->debugString() << endl;
|
|
delete $2;
|
|
}
|
|
;
|
|
|
|
ColExpression:
|
|
aExpr
|
|
{
|
|
$$ = $1;
|
|
}
|
|
/* HANDLED BY 'IDENTIFIER aExprList'
|
|
| IDENTIFIER '(' ColViews ')'
|
|
{
|
|
$$ = new FunctionExpr( $1, $3 );
|
|
}*/
|
|
/*
|
|
| SUM '(' ColExpression ')'
|
|
{
|
|
FunctionExpr(
|
|
// $$ = new AggregationExpr( SUM, );
|
|
//TODO
|
|
// $$->setName("SUM(" + $3->name() + ")");
|
|
//wait $$->containsGroupingAggregate(true);
|
|
//wait parser->select()->grouped(true);
|
|
}
|
|
| SQL_MIN '(' ColExpression ')'
|
|
{
|
|
$$ = $3;
|
|
//TODO
|
|
// $$->setName("MIN(" + $3->name() + ")");
|
|
//wait $$->containsGroupingAggregate(true);
|
|
//wait parser->select()->grouped(true);
|
|
}
|
|
| SQL_MAX '(' ColExpression ')'
|
|
{
|
|
$$ = $3;
|
|
//TODO
|
|
// $$->setName("MAX(" + $3->name() + ")");
|
|
//wait $$->containsGroupingAggregate(true);
|
|
//wait parser->select()->grouped(true);
|
|
}
|
|
| AVG '(' ColExpression ')'
|
|
{
|
|
$$ = $3;
|
|
//TODO
|
|
// $$->setName("AVG(" + $3->name() + ")");
|
|
//wait $$->containsGroupingAggregate(true);
|
|
//wait parser->select()->grouped(true);
|
|
}*/
|
|
//?
|
|
| DISTINCT '(' ColExpression ')'
|
|
{
|
|
$$ = $3;
|
|
//TODO
|
|
// $$->setName("DISTINCT(" + $3->name() + ")");
|
|
}
|
|
;
|
|
|
|
ColWildCard:
|
|
'*'
|
|
{
|
|
$$ = new VariableExpr("*");
|
|
KexiDBDbg << "all columns" << endl;
|
|
|
|
// QueryAsterisk *ast = new QueryAsterisk(parser->select(), dummy);
|
|
// parser->select()->addAsterisk(ast);
|
|
// requiresTable = true;
|
|
}
|
|
| IDENTIFIER '.' '*'
|
|
{
|
|
TQString s( *$1 );
|
|
s += ".*";
|
|
$$ = new VariableExpr(s);
|
|
KexiDBDbg << " + all columns from " << s << endl;
|
|
delete $1;
|
|
}
|
|
/*| ERROR_DIGIT_BEFORE_IDENTIFIER
|
|
{
|
|
$$ = new VariableExpr($1);
|
|
KexiDBDbg << " Invalid identifier! " << $1 << endl;
|
|
setError(i18n("Invalid identifier \"%1\"").arg($1));
|
|
}*/
|
|
;
|
|
|
|
%%
|
|
|