diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(SetKDbCMakePolicies NO_POLICY_SCOPE) -project(KDb VERSION 3.1.0) # Update this +project(KDb VERSION 3.1.1) # Update this include(KDbAddTests) include(KDbAddExamples) diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -40,6 +40,7 @@ ecm_add_tests( ConnectionOptionsTest.cpp ConnectionTest.cpp + DateTimeTest.cpp DriverTest.cpp ExpressionsTest.cpp QuerySchemaTest.cpp diff --git a/src/KDb_p.h b/autotests/DateTimeTest.h copy from src/KDb_p.h copy to autotests/DateTimeTest.h --- a/src/KDb_p.h +++ b/autotests/DateTimeTest.h @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2004-2016 Jarosław Staniek + Copyright (C) 2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -17,18 +17,26 @@ * Boston, MA 02110-1301, USA. */ -#ifndef KDB_P_H -#define KDB_P_H +#ifndef KDB_DATETIMETEST_H +#define KDB_DATETIMETEST_H -#include +#include -//! @internal Dummy class to get simply translation markup expressions -//! of the form kdb::tr("foo") instead of the complicated and harder to read -//! QCoreApplication::translate("KDb", "foo") which also runs the chance of -//! typos in the class context argument -class kdb +/** + * A test for KDbYear, KDbDate, KDbTime, KDbDateTime classes + */ +class DateTimeTest : public QObject { - Q_DECLARE_TR_FUNCTIONS(KDb) + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + + void testYear(); + void testDate(); + void testTime(); + void testDateTime(); + + void cleanupTestCase(); }; #endif diff --git a/autotests/DateTimeTest.cpp b/autotests/DateTimeTest.cpp new file mode 100644 --- /dev/null +++ b/autotests/DateTimeTest.cpp @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2018 Jarosław Staniek + + 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. +*/ + +#include "DateTimeTest.h" + +#include + +#include +#include +#include "parser/generated/sqlparser.h" +#include "parser/KDbParser_p.h" + +QTEST_GUILESS_MAIN(DateTimeTest) + +void DateTimeTest::initTestCase() +{ +} + +void DateTimeTest::testYear() +{ + KDbYear year("2020"); + QVERIFY(year.isValid()); + QCOMPARE(year.toString(), "2020"); + QCOMPARE(year.toQDateValue(), 2020); + QCOMPARE(year.toIsoValue(), 2020); + QVariant yearVariant = QVariant::fromValue(year); + QVERIFY(yearVariant.isValid()); + QCOMPARE(yearVariant.toInt(), 2020); + QCOMPARE(yearVariant.toString(), "2020"); +} + +void DateTimeTest::testDate() +{ + KDbYear year("2020"); + KDbDate date(year, "2", "29"); + QVERIFY(date.isValid()); + QCOMPARE(date.toString(), "2020-2-29"); + QDate qtDate(2020, 2, 29); + QCOMPARE(date.toQDate(), qtDate); + QVariant dateVariant = QVariant::fromValue(date); + QVERIFY(dateVariant.isValid()); + QCOMPARE(dateVariant.toDate(), qtDate); + //! @todo more cases +} + +void DateTimeTest::testTime() +{ + KDbTime time("1", "15", "20", "789", KDbTime::Period::Pm); + QVERIFY(time.isValid()); + QCOMPARE(time.toString(), "1:15:20.789 PM"); + QTime qtTime(13, 15, 20, 789); + QCOMPARE(time.toQTime(), qtTime); + QVariant timeVariant = QVariant::fromValue(time); + QVERIFY(timeVariant.isValid()); + QCOMPARE(timeVariant.toTime(), qtTime); + //! @todo more cases +} + +void DateTimeTest::testDateTime() +{ + KDbYear year("2020"); + KDbTime time("1", "15", "20", "789", KDbTime::Period::Pm); + KDbDate date(year, "2", "29"); + + KDbDateTime dateTime(date, time); + QVERIFY(dateTime.isValid()); + QCOMPARE(dateTime.toString(), "2020-2-29 1:15:20.789 PM"); + QTime qtTime(13, 15, 20, 789); + QDate qtDate(2020, 2, 29); + QDateTime qtDateTime(qtDate, qtTime); + QCOMPARE(dateTime.toQDateTime(), qtDateTime); + QVariant dateTimeVariant = QVariant::fromValue(dateTime); + QVERIFY(dateTimeVariant.isValid()); + QCOMPARE(dateTimeVariant.toDateTime(), qtDateTime); + //! @todo more cases +} + +void DateTimeTest::cleanupTestCase() +{ +} diff --git a/autotests/ExpressionsTest.cpp b/autotests/ExpressionsTest.cpp --- a/autotests/ExpressionsTest.cpp +++ b/autotests/ExpressionsTest.cpp @@ -21,6 +21,7 @@ #include +#include #include #include "parser/generated/sqlparser.h" #include "parser/KDbParser_p.h" @@ -1064,15 +1065,48 @@ QCOMPARE(c.type(), KDbField::Date); QCOMPARE(c.value(), QVariant(date)); QVERIFY(validate(&c)); + testCloneExpression(c); //qDebug() << c; date = date.addDays(17); c.setValue(date); QCOMPARE(c.value(), QVariant(date)); QVERIFY(c.isValid()); QVERIFY(c.isDateTimeType()); QVERIFY(validate(&c)); testCloneExpression(c); - //qDebug() << c; + + KDbDate dateKDb(KDbYear("2018"), "11", "27"); + c.setValue(QVariant::fromValue(dateKDb)); + QCOMPARE(c.value(), QVariant::fromValue(dateKDb)); + QVERIFY(c.isValid()); + QVERIFY(c.isDateTimeType()); + QVERIFY(validate(&c)); + testCloneExpression(c); + + // time + QTime time(QTime::currentTime()); + c = KDbConstExpression(KDbToken::TIME_CONST, time); + QCOMPARE(c.type(), KDbField::Time); + QVERIFY(c.isValid()); + QVERIFY(c.isDateTimeType()); + QCOMPARE(c.value(), QVariant(time)); + testCloneExpression(c); + QVERIFY(validate(&c)); + time = time.addMSecs(1200123); + c.setValue(time); + QCOMPARE(c.value(), QVariant(time)); + QVERIFY(c.isValid()); + QVERIFY(c.isDateTimeType()); + QVERIFY(validate(&c)); + testCloneExpression(c); + + KDbTime timeKDb("12", "34", "56", "789"); + c.setValue(QVariant::fromValue(timeKDb)); + QCOMPARE(c.value(), QVariant::fromValue(timeKDb)); + QVERIFY(c.isValid()); + QVERIFY(c.isDateTimeType()); + QVERIFY(validate(&c)); + testCloneExpression(c); // date/time QDateTime dateTime(QDateTime::currentDateTime()); @@ -1082,6 +1116,7 @@ QVERIFY(c.isDateTimeType()); QCOMPARE(c.value(), QVariant(dateTime)); QVERIFY(validate(&c)); + testCloneExpression(c); //qDebug() << c; dateTime = dateTime.addDays(-17); c.setValue(dateTime); @@ -1091,24 +1126,18 @@ QVERIFY(validate(&c)); testCloneExpression(c); //qDebug() << c; - - // time - QTime time(QTime::currentTime()); - c = KDbConstExpression(KDbToken::TIME_CONST, time); - QCOMPARE(c.type(), KDbField::Time); - QVERIFY(c.isValid()); - QVERIFY(c.isDateTimeType()); - QCOMPARE(c.value(), QVariant(time)); - //qDebug() << c; - QVERIFY(validate(&c)); - time = time.addSecs(1200); - c.setValue(time); - QCOMPARE(c.value(), QVariant(time)); + KDbDateTime dateTimeKDb(dateKDb, timeKDb); + c.setValue(QVariant::fromValue(dateTimeKDb)); +// qDebug() << QVariant::fromValue(dateTimeKDb); +// qDebug() << QVariant::fromValue(dateTimeKDb).isValid(); +// qDebug() << c.value(); +// qDebug() << c.value().isValid(); +// qDebug() << (QVariant::fromValue(dateTimeKDb) == c.value()); + QCOMPARE(c.value(), QVariant::fromValue(dateTimeKDb)); QVERIFY(c.isValid()); QVERIFY(c.isDateTimeType()); QVERIFY(validate(&c)); testCloneExpression(c); - //qDebug() << c; // setValue() c = KDbConstExpression(KDbToken::INTEGER_CONST, 124); diff --git a/autotests/parser/data/statements.txt b/autotests/parser/data/statements.txt --- a/autotests/parser/data/statements.txt +++ b/autotests/parser/data/statements.txt @@ -57,10 +57,255 @@ select 3.14159; select 3.; select NULL; -select TRUE; --- TODO: Date/Time +-- Date Constants (KDbSQL EXTENSION) +-- https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants +-- Date Constants: AD +select #2018-09-17#; +select #09/17/2018#; +select #2018-9-17#; +select #9/17/2018#; +select #2018-9-07#; +select #9/07/2018#; +select #2018-9-7#; +select #9/7/2018#; +select #2018-09-7#; +select #09/7/2018#; +select #1900-01-01#; +select #01/01/1900#; +select #1500-02-02#; +select #02/02/1500#; +select #0001-01-21#; +select #01/21/0001#; +-- ERROR: Date Constants: Invalid month +select #2018-00-17#; +select #00/17/2018#; +select #2018-0-17#; +select #0/17/2018#; +select #2018-13-17#; +select #13/17/2018#; +select #2018-99-17#; +select #99/17/2018#; +-- ERROR: Date Constants: Invalid day +select #2018-01-00#; +select #01/00/2018#; +select #2018-01-0#; +select #01/0/2018#; +select #2018-02-29#; +select #02/29/2018#; +select #2018-01-32#; +select #01/32/2018#; +-- ERROR: Date Constants: too many digits +select #2018-001-30#; +select #001/30/2018#; +select #2018-001-030#; +select #001/030/2018#; +select #2018-01-030#; +select #01/030/2018#; +-- ERROR: Date Constants: invalid characters/format +select #2018-1a-30#; +select #1a/30/2018#; +select #2018--30#; +select #/30/2018#; +select #2018-a-30#; +select #a/30/2018#; +select #2018-01-3o#; +select #01/3o/2018#; +select #2018-01-30; +select #01/30/2018; +select #2018_01-30#; +select #01/30_2018#; +select #2018-01_30; +select #01_30/2018#; +select #2018_01_30; +select #2018-01/30; +select #20180130; +select #2018; +select #2018-; +select #2018/; +select #/2018; +select #2018-01; +select #01/2018; +select #2018-01-; +select #/01/2018; +select #2018/01; +select #-2018-01-; +select #/01/2018; +select #-2018; +select ##-2018; +select ##/2018; +select #; +select ##; +select #2018-01-01-01#; +select #01/01/01/2018#; +select #++18119-10-30#; +select #10/30/++18119#; +select #+-18119-10-30#; +select #10/30/+-18119#; +select #-+18119-10-30#; +select #10/30/-+18119#; +select #--18119-10-30#; +select #10/30/--18119#; +select # 2018-03-08#; +select #2018-03-08 #; +select # 2018-03-08 #; +select # 2018 -03-08 #; +select #2018-03 -08#; +select #2018 - 03 - 08#; +select #201 -03-08 #; +select #2018- 3-08 #; +select #2018-03- 8 #; +-- ERROR: Date Constant: at least 4 digit year required +select #189-12-13#; +select #12/13/189#; +-- Date Constants: optional "+" prefix for years 1-9999 +select #+2018-12-02#; +select #12/02/+2018#; +select #+1500-02-02#; +select #12/02/+1500#; +select #+1500-3-2#; +select #3/02/+1500#; +select #+02012-12-13#; +select #12/13/+02012#; +-- Date Constants, year > 9999 +select #+123456789-12-13#; +select #12/13/+123456789#; +select #+000123456789-12-13#; +select #12/13/+000123456789#; +-- ERROR: Date Constant: More than 4-digit year so "+" prefix is required +select #123456789-12-13#; +select #12/13/123456789#; +-- 1 BC Date Constants +select #+0000-01-30#; +select #01/30/+0000#; +-- ERROR: Date Constant: 1 BC requires +0000 year +select #0000-01-01#; +select #01/01/0000#; +select #-0000-01-01#; +select #01/01/-0000#; +select #+000-01-01#; +select #01/01/+000#; +select #-000-01-01#; +select #01/01/-000#; +select #+00-01-01#; +select #01/01/+00#; +select #-00-01-01#; +select #01/01/-00#; +select #+0-01-01#; +select #01/01/+0#; +select #-0-01-01#; +select #01/01/-0#; +-- 2 BC Date Constants +select #-0001-03-04#; +select #03/04/-0001#; +select #-5001-03-04#; +select #03/04/-5001#; +-- <= 10000 BC Date Constants +select #-9999-03-04#; +select #04/03/-9999#; +select #-10000-03-04#; +select #04/03/-10000#; +select #-543210000-03-04#; +select #04/03/-543210000#; +select #-00543210000-03-04#; +select #04/03/-00543210000#; +-- ERROR: Date Constant: MSA format +select #24 Dec 2014#; +select #24 December 2014#; +select #December 24, 2014#; +select #Dec 24, 2014#; + +-- Time Constants (KDbSQL EXTENSION) +-- https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants +-- Time Constants: 24h mode +select #01:17:59#; +select #01:07:59#; +select #01:07:09#; +select #1:07:09#; +select #01:7:09#; +select #01:07:9#; +select #01:7:9#; +select #1:7:09#; +select #1:07:9#; +select #1:7:9#; +select #0:0:0#; +select #23:11:29#; +select #13:17:59#; +select #23:11#; +select #03:01#; +select #3:01#; +select #03:1#; +select #3:1#; +-- Time Constants: 12h mode +select #11:11:29 AM#; +select #11:11:29 PM#; +select #11:11:29AM#; +select #11:11:29PM#; +select #11:11:29am#; +select #11:11:29pm#; +select #11:11:29 AM#; +select #11:11:29 PM#; +select #1:31:19 aM#; +select #1:31:19 Am#; +select #1:31:19 am#; +select #1:31:19 pM#; +select #1:31:19 pM#; +select #11:11 AM#; +select #11:11 PM#; +select #11:11 AM#; +select #11:11 PM#; +select #11:11AM#; +select #11:11PM#; +select #11:11am#; +select #11:11pm#; +select #1:31 aM#; +select #1:31 Am#; +select #1:31 am#; +select #1:31 pM#; +select #1:31 pM#; +-- ERROR: Time Constants: invalid characters/format +select #001:17:59#; +select #01:017:59#; +select #01:017:059#; +select #001:017:59#; +select #01:017:059#; +select #001:17:059#; +select #001;017:059#; +select #01:17:59; +select #01::17:59#; +select ##01::17:59#; +select #01#; +select #0#; +select #11:17 #; +select #11: 17#; +select #11 : 17#; +select #11 :17#; +select #11::17#; +select # 11:17#; +select #11:17 AM #; +select #1:17 PM #; +select # 11:17 AM#; +select # 11:17 AM #; +select # 1:17 PM#; +select # 1:17 PM #; +select #o1:17#; +select #1:17a#; +select #1:17p#; +select #1:17 p#; +select #1:17 pr#; +-- ERROR: Time Constants: invalid hour +select #24:17:59#; +select #28:17:59#; +select #13:17:59 AM#; +select #23:17:59 PM#; +select #13:17 AM#; +select #23:17 PM#; + +-- Date/Time Constants (KDbSQL EXTENSION) +-- https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants +-- TODO -- TRUE and FALSE constants (KDbSQL EXTENSION) +select TRUE; select TRUE, NOT FALSE; select NOT NOT TRUE; select NOT NULL; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,6 +106,7 @@ tools/transliteration/generate_transliteration_table.sh tools/transliteration/transliteration_table.readme + KDbDateTime.cpp KDbEscapedString.cpp KDbResult.cpp KDbQueryAsterisk.cpp @@ -290,6 +291,7 @@ KDbConnectionOptions KDbConnectionProxy KDbCursor + KDbDateTime KDbDriver KDbDriverBehavior KDbDriverManager diff --git a/src/KDb.h b/src/KDb.h --- a/src/KDb.h +++ b/src/KDb.h @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2004-2017 Jarosław Staniek + Copyright (C) 2004-2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -419,30 +419,30 @@ Returns null QVariant for unsupported values like KDbField::InvalidType. */ KDB_EXPORT QVariant notEmptyValueForFieldType(KDbField::Type type); -/*! @return true if the @a word is an reserved KDbSQL keyword +/*! @return true if the @a word is an reserved KDBSQL keyword See generated/sqlkeywords.cpp. @todo add function returning list of keywords. */ KDB_EXPORT bool isKDbSqlKeyword(const QByteArray& word); -//! @return @a string string with applied KDbSQL identifier escaping +//! @return @a string string with applied KDBSQL identifier escaping /*! This escaping can be used for field, table, database names, etc. Use it for user-visible backend-independent statements. @see KDb::escapeIdentifierAndAddQuotes() */ KDB_EXPORT QString escapeIdentifier(const QString& string); //! @overload QString escapeIdentifier(const QString&) KDB_EXPORT QByteArray escapeIdentifier(const QByteArray& string); -//! @return @a string string with applied KDbSQL identifier escaping and enclosed in " quotes +//! @return @a string string with applied KDBSQL identifier escaping and enclosed in " quotes /*! This escaping can be used for field, table, database names, etc. Use it for user-visible backend-independent statements. @see KDb::escapeIdentifier */ KDB_EXPORT QString escapeIdentifierAndAddQuotes(const QString& string); //! @overload QString escapeIdentifierAndAddQuotes(const QString&) KDB_EXPORT QByteArray escapeIdentifierAndAddQuotes(const QByteArray& string); -/*! @return escaped string @a string for the KDbSQL dialect, +/*! @return escaped string @a string for the KDBSQL dialect, i.e. doubles single quotes ("'") and inserts the string into single quotes. Quotes "'" are prepended and appended. Also escapes \\n, \\r, \\t, \\\\, \\0. @@ -454,7 +454,7 @@ * @brief Returns escaped string @a string * * If @a drv driver is present, it is used to perform escaping, otherwise escapeString() is used - * so the KDbSQL dialect-escaping is performed. + * so the KDBSQL dialect-escaping is performed. * * @since 3.1.0 */ @@ -464,13 +464,13 @@ * @brief Returns escaped string @a string * * If @a conn is present, its driver is used to perform escaping, otherwise escapeString() is used - * so the KDbSQL dialect-escaping is performed. + * so the KDBSQL dialect-escaping is performed. * * @since 3.1.0 */ KDB_EXPORT KDbEscapedString escapeString(KDbConnection *conn, const QString& string); -//! Unescapes characters in string @a string for the KDbSQL dialect. +//! Unescapes characters in string @a string for the KDBSQL dialect. /** The operation depends on @a quote character, which can be be ' or ". * @a string is assumed to be properly constructed. This is assured by the lexer's grammar. * Used by lexer to recognize the CHARACTER_STRING_LITERAL token. @@ -657,17 +657,138 @@ KDB_EXPORT QString defaultFileBasedDriverId(); /*! Escapes and converts value @a v (for type @a ftype) - to string representation required by KDbSQL commands. + to string representation required by KDBSQL commands. For Date/Time type KDb::dateTimeToSql() is used. For BLOB type KDb::escapeBlob() with BLOBEscapingType::ZeroXHex conversion type is used. */ KDB_EXPORT KDbEscapedString valueToSql(KDbField::Type ftype, const QVariant& v); -/*! Converts value @a v to string representation required by KDbSQL commands: - ISO 8601 DateTime format - with "T" delimiter/ - For specification see https://www.w3.org/TR/NOTE-datetime. - Example: "1994-11-05T13:15:30" not "1994-11-05 13:15:30". - @todo Add support for time zones */ -KDB_EXPORT KDbEscapedString dateTimeToSql(const QDateTime& v); +/** + * Converts date/time value to its string representation in ISO 8601 DateTime format - with "T" delimiter + * + * @note This method is deprecated since 3.1.1, use KDb::dateTimeToIsoString() which has identical + * effect. The ISO format is no longer used for creating KDBSQL statements. + * Prior to this version it was used to generate date/time constants in + * KDb::valueToSql(KDbField::Type ftype, const QVariant& v) for KDbField::DateTime type. + * KDb::dateTimeToIsoString() is still used as default implementation for drivers + * in KDbDriver::dateTimeToSql(). + * + * KDb 3.1.0 improved type safety for KDBSQL so Text type are no longer compatible with + * Date/Time types. By implementing wish https://bugs.kde.org/393094 format of date/time constants + * for KDBSQL has been strictly defined in a backend-independent way. + * See https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants for details. + */ +KDB_DEPRECATED_EXPORT KDbEscapedString dateTimeToSql(const QDateTime& v); + +/** + * Converts date value to its string representation in ISO 8601 DateTime format + * + * The string is enclosed with single quotes "'". It is compatible with SQLite format for the + * date type. It is used as default implementation for drivers in KDbDriver::dateToSql(). + * + * If the @a v value is convertible to KDbDate then KDbDate::toString() is used to obtain + * the result. Otherwise the value is converted to QDate and QDate::toString(Qt::ISODate) is + * used to obtain the result. + * + * "" string is returned for invalid (also null) date values. + * + * For specification of the ISO format see https://www.w3.org/TR/NOTE-datetime. + * + * Example value: "'1994-11-05'". + * + * @since 3.1.1 + */ +KDB_EXPORT KDbEscapedString dateToIsoString(const QVariant& v); + +/** + * Converts time value to its string representation in ISO 8601 Time format + * + * The string is enclosed with single quotes "'". It is compatible with SQLite format for the + * time type. It is used as default implementation for drivers in KDbDriver::timeToSql(). + * + * If the @a v value is convertible to KDbTime then KDbTime::toString() is used to obtain the result. + * Otherwise the value is converted to QTime and QTime::toString(Qt::ISODateWithMs) + * or QTime::toString(Qt::ISODate) is used to obtain the result. + * If the time's milliseconds value is zero, it is not included. + * + * "" string is returned for invalid (also null) time values. + * + * For specification of the ISO format see https://www.w3.org/TR/NOTE-datetime. + * + * Example values: "'13:15:30.123'", "'13:15:30'". + * + * @since 3.1.1 + */ +KDB_EXPORT KDbEscapedString timeToIsoString(const QVariant& v); + +/** + * Converts date/time value to its string representation in ISO 8601 DateTime format - with "T" delimiter + * + * The string is enclosed with single quotes "'". It is compatible with SQLite format for the + * date/time type. It is used as default implementation for drivers in KDbDriver::dateTimeToSql(). + * + * If the @a v value is convertible to KDbDateTime then KDbDateTime::toString() is used to obtain + * the result. Otherwise the value is converted to QDateTime and QDate::toString(Qt::ISODate) is + * used as well as QTime::toString(Qt::ISODateWithMs) or QTime::toString(Qt::ISODate) to obtain + * the result. If the time's milliseconds value is zero, it is not included. + * + * "" string is returned for invalid (also null) time values. + * + * For specification of the ISO format see https://www.w3.org/TR/NOTE-datetime. + * + * Example value: "'1994-11-05T13:15:30'", not "'1994-11-05 13:15:30'". + * + * @since 3.1.1 + */ +KDB_EXPORT KDbEscapedString dateTimeToIsoString(const QVariant& v); + +/** + * Converts date value to its string representation required by KDBSQL commands + * + * The value can be of type QDate or KDbDate. If the value is not one of these types or is invalid + * QDate or is a null KDbDate then "" is returned. If the value is of type KDbDate + * that is not null then even if some components of the date are invalid, properly formatted string + * is returned. + * + * Example values: "#1994-11-05", "#1994-9-05#". + * + * See https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants for details. + * + * @since 3.1.1 + */ +KDB_EXPORT KDbEscapedString dateToSql(const QVariant& v); + +/** + * Converts time value to its string representation required by KDBSQL commands + * + * The value can be of type QTime or KDbTime. If the value is not one of these types or is invalid + * QTime or is a null KDbTime then "" is returned. If the value is of type KDbTime + * that is not null then even if some components of the time are invalid, properly formatted string + * is returned. If the time's milliseconds value is zero, it is not included. + * + * See https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants for details. + * + * Example values: "#13:15#", "#13:9:30#", "#13:15:30.921#, "#7:20 AM#". + * + * @since 3.1.1 + */ +KDB_EXPORT KDbEscapedString timeToSql(const QVariant& v); + +/** + * Converts date/time value to its string representation required by KDBSQL commands + * + * The value can be of type QDateTime or KDbDateTime. If the value is not one of these types or + * is invalid QDateTime or is a null KDbDateTime then "" is returned. + * If the value is of type KDbDateTime that is not null then even if some components of the + * date/time are invalid, properly formatted string is returned. + * If the time's milliseconds value is zero, it is not included. + * + * See https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants for details. + * + * Example values: "#1994-11-05 13:15#", "#1994-11-05 13:9:30#", "#1994-9-05 13:15:30.921#". + * + * @since 3.1.1 + */ +KDB_EXPORT KDbEscapedString dateTimeToSql(const QVariant& v); #ifdef KDB_DEBUG_GUI //! A prototype of handler for GUI debugger diff --git a/src/KDb.cpp b/src/KDb.cpp --- a/src/KDb.cpp +++ b/src/KDb.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2004-2017 Jarosław Staniek + Copyright (C) 2004-2018 Jarosław Staniek Copyright (c) 2006, 2007 Thomas Braxton Copyright (c) 1999 Preston Brown Copyright (c) 1997 Matthias Kalle Dalheimer @@ -21,22 +21,23 @@ */ #include "KDb.h" -#include "KDbConnectionData.h" #include "KDbConnection.h" +#include "KDbConnectionData.h" #include "KDbCursor.h" -#include "kdb_debug.h" +#include "KDbDateTime.h" #include "KDbDriverBehavior.h" #include "KDbDriverManager.h" #include "KDbDriver_p.h" #include "KDbLookupFieldSchema.h" #include "KDbMessageHandler.h" #include "KDbNativeStatementBuilder.h" -#include "KDb_p.h" #include "KDbQuerySchema.h" #include "KDbRecordData.h" #include "KDbSqlResult.h" #include "KDbTableOrQuerySchema.h" #include "KDbVersionInfo.h" +#include "KDb_p.h" +#include "kdb_debug.h" #include "transliteration/transliteration_table.h" #include @@ -2203,6 +2204,109 @@ + kdb::tr("\"%1\" is not a valid identifier.").arg(v.toString()) + QLatin1String("

"); } +//--------- + +KDbEscapedString KDb::valueToSql(KDbField::Type ftype, const QVariant& v) +{ + return valueToSqlInternal(nullptr, ftype, v); +} + +static QByteArray dateToSqlInternal(const QVariant& v, bool allowInvalidKDbDate) +{ + QByteArray result(QByteArrayLiteral("")); + if (v.canConvert()) { + const KDbDate date(v.value()); + if (date.isValid() || allowInvalidKDbDate) { + result = date.toString(); // OK even if invalid or null + } + } else if (v.canConvert()) { + const QDate date(v.toDate()); + if (date.isValid()) { + result = date.toString(Qt::ISODate).toLatin1(); + } + } + return result; +} + +KDbEscapedString KDb::dateToSql(const QVariant& v) +{ + return KDbEscapedString('#') + dateToSqlInternal(v, true) + '#'; +} + +static QByteArray timeToSqlInternal(const QVariant& v, bool allowInvalidKDbTime) +{ + QByteArray result(QByteArrayLiteral("")); + if (v.canConvert()) { + const KDbTime time(v.value()); + if (time.isValid() || allowInvalidKDbTime) { + result = time.toString(); // OK even if invalid or null + } + } else if (v.canConvert()) { + const QTime time(v.toTime()); + if (time.isValid()) { + if (time.msec() == 0) { + result = time.toString(Qt::ISODate).toLatin1(); + } else { + result = time.toString(Qt::ISODateWithMs).toLatin1(); + } + } + } + return result; +} + +KDbEscapedString KDb::timeToSql(const QVariant& v) +{ + return KDbEscapedString('#') + timeToSqlInternal(v, true) + '#'; +} + +static QByteArray dateTimeToSqlInternal(const QVariant& v, char separator, bool allowInvalidKDbDateTime) +{ + QByteArray result(QByteArrayLiteral("")); + if (v.canConvert()) { + const KDbDateTime dateTime(v.value()); + if (dateTime.isValid() || allowInvalidKDbDateTime) { + result = dateTime.toString(); // OK even if invalid or null + } + } else if (v.canConvert()) { + const QDateTime dateTime(v.toDateTime()); + if (dateTime.isValid()) { + result = dateTime.date().toString(Qt::ISODate).toLatin1() + separator; + const QTime time(dateTime.time()); + if (time.msec() == 0) { + result += time.toString(Qt::ISODate).toLatin1(); + } else { + result += time.toString(Qt::ISODateWithMs).toLatin1(); + } + } + } + return result; +} + +KDbEscapedString KDb::dateTimeToSql(const QVariant& v) +{ + return KDbEscapedString('#') + dateTimeToSqlInternal(v, ' ', true) + '#'; +} + +KDbEscapedString KDb::dateTimeToSql(const QDateTime& v) +{ + return KDb::dateTimeToIsoString(v); +} + +KDbEscapedString KDb::dateToIsoString(const QVariant& v) +{ + return KDbEscapedString('\'') + dateToSqlInternal(v, false) + KDbEscapedString('\''); +} + +KDbEscapedString KDb::timeToIsoString(const QVariant& v) +{ + return KDbEscapedString('\'') + timeToSqlInternal(v, false) + KDbEscapedString('\''); +} + +KDbEscapedString KDb::dateTimeToIsoString(const QVariant& v) +{ + return KDbEscapedString('\'') + dateTimeToSqlInternal(v, 'T', false) + KDbEscapedString('\''); +} + //-------------------------------------------------------------------------------- #ifdef KDB_DEBUG_GUI diff --git a/src/KDbDateTime.h b/src/KDbDateTime.h new file mode 100644 --- /dev/null +++ b/src/KDbDateTime.h @@ -0,0 +1,475 @@ +/* This file is part of the KDE project + Copyright (C) 2018 Jarosław Staniek + + 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. +*/ + +#ifndef KDB_DATETIME_H +#define KDB_DATETIME_H + +#include "kdb_export.h" + +#include +#include + +/** + * Generic year constant based on extended ISO 8601 specification + * + * This class as well as KDbDate, KDbTime and KDbDateTime is used as a replacement for Qt date/time + * value classes in case when invalid values have to be preserved. Without this, SQL parsers would + * not function properly because they would loose information about mistyped constants. + * The KDb* make it possible for the user to store the constants in SQL expressions and fix them + * at later time. + * + * See this page for specifications of the date/time formats supported: + * https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants#Date_constants + * + * @since 3.1.1 + */ +class KDB_EXPORT KDbYear +{ +public: + /** + * Specifies sign which is used to annotate year + */ + enum class Sign { + None, + Plus, + Minus + }; + + /** + * Constructs year based on given sign and string + * + * Resulting year can be invalid but the string is always preserved. + */ + KDbYear(Sign sign, const QByteArray &string) : m_sign(sign), m_string(string) + { + } + + /** + * Constructs yea based on given string, with sign set to Sign::None + * + * Resulting year can be invalid but the string is always preserved. + */ + explicit KDbYear(const QByteArray &string) : KDbYear(Sign::None, string) + { + } + + /** + * Contructs a null year + */ + KDbYear() : KDbYear(QByteArray()) + { + } + + bool operator==(const KDbYear &other) const; + + inline bool operator!=(const KDbYear &other) const { return !operator==(other); } + + bool operator<(const KDbYear &other) const; + + inline bool operator<=(const KDbYear &other) const { return operator<(other) || operator==(other); } + + inline bool operator>=(const KDbYear &other) const { return !operator<(other); } + + inline bool operator>(const KDbYear &other) const { return !operator<=(other); } + + /** + * Returns @c true if the year is valid + * + * Year is invalid if it is null or if the supplied string is invalid according to specification. + */ + bool isValid() const; + + /** + * Returns @c true if the year is null + * + * A year is null if its sign is equal to Sign::None and string is empty. + */ + bool isNull() const; + + /** + * Returns the sign which is used to annotate year + */ + Sign sign() const { return m_sign; } + + QByteArray signString() const; + + /** + * Returns the string representation of year value even if it is invalid + */ + QByteArray yearString() const { return m_string; } + + /** + * Returns entire year value (with sign) converted to string even if it is invalid + */ + QByteArray toString() const; + + /** + * Returns the integer year value as defined by extended ISO 8601 + * + * 0 is returned for invalid year. + */ + int toIsoValue() const; + + /** + * Returns the integer year value as defined by the QDate API + * + * 0 is returned for invalid year. + */ + int toQDateValue() const; + +private: + std::tuple intValue() const; + + const Sign m_sign; + const QByteArray m_string; + int m_isoValue = -1; //!< Cached value for intValue(), -1 if the cache is missing +}; + +Q_DECLARE_METATYPE(KDbYear) + +//! Sends information about value @a sign to debug output @a dbg. +KDB_EXPORT QDebug operator<<(QDebug dbg, KDbYear::Sign sign); + +//! Sends information about value @a year to debug output @a dbg. +KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbYear &year); + +/** + * Generic date constant + * + * @since 3.1.1 + */ +class KDB_EXPORT KDbDate +{ +public: + KDbDate(const KDbYear &year, const QByteArray &monthString, const QByteArray &dayString) + : m_year(year), m_monthString(monthString), m_dayString(dayString) + { + } + + /** + * Constructs a null date + */ + KDbDate() = default; + + bool operator==(const KDbDate &other) const; + + inline bool operator!=(const KDbDate &other) const { return !operator==(other); } + + bool operator<(const KDbDate &other) const; + + inline bool operator<=(const KDbDate &other) const { return operator<(other) || operator==(other); } + + inline bool operator>=(const KDbDate &other) const { return !operator<(other); } + + inline bool operator>(const KDbDate &other) const { return !operator<=(other); } + + /** + * Returns @c true if the date is valid + * + * Validation is performed by converting to QDate (toQDate()) and checking if it is valid. + */ + bool isValid() const; + + /** + * Returns @c true if the date is null + * + * A date is null if its year is null, month string is empty and date string is empty. + */ + bool isNull() const; + + /** + * Returns the date converted to QDate value + * + * Invalid QDate is returned if the KDbDate is invalid. + */ + QDate toQDate() const; + + /** + * Returns the date value converted to string even if it is invalid + * + * For null dates empty string is returned. + */ + QByteArray toString() const; + + /** + * Returns the year part of the date + */ + KDbYear year() const { return m_year; } + + /** + * Returns the month part of the date converted to integer + * + * Correct values are in range 1..12, -1 is returned for invalid month. + */ + int month() const; + + /** + * Returns the month part of the date + * + * It is original string passed to the KDbDate object and may be invalid. + */ + QByteArray monthString() const { return m_monthString; } + + /** + * Returns the day part of the date converted to integer + * + * Correct values are in range 1..31, -1 is returned for invalid day. + * THe date can be still invalid for valid integer, e.g. February 31st. + */ + int day() const; + + /** + * Returns the day part of the date + * + * It is original string passed to the KDbDate object and may be invalid. + */ + QByteArray dayString() const { return m_dayString; } + +private: + const KDbYear m_year; + const QByteArray m_monthString; + const QByteArray m_dayString; +}; + +Q_DECLARE_METATYPE(KDbDate) + +//! Sends information about value @a date to debug output @a dbg. +KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbDate &date); + +/** + * Generic time constant + * + * @since 3.1.1 + */ +class KDB_EXPORT KDbTime +{ +public: + /** + * Specifies hour period + */ + enum class Period { + None, //!< 2-hour time + Am, //!< AM, before noon + Pm //!< PM, after noon, before midnight + }; + + KDbTime(const QByteArray &hourString, const QByteArray &minuteString, + const QByteArray &secondString = QByteArray(), + const QByteArray &msecString = QByteArray(), Period period = Period::None) + : m_hourString(hourString) + , m_minuteString(minuteString) + , m_secondString(secondString) + , m_msecString(msecString) + , m_period(period) + { + } + + /** + * Constructs a null time + */ + KDbTime() = default; + + bool operator==(const KDbTime &other) const; + + inline bool operator!=(const KDbTime &other) const { return !operator==(other); } + + bool operator<(const KDbTime &other) const; + + inline bool operator<=(const KDbTime &other) const { return operator<(other) || operator==(other); } + + inline bool operator>=(const KDbTime &other) const { return !operator<(other); } + + inline bool operator>(const KDbTime &other) const { return !operator<=(other); } + + /** + * Returns @c true if the time is valid + * + * Validation is performed by converting to QTime (toQTime()) and checking if it is valid. + */ + bool isValid() const; + + /** + * Returns @c true if the time is null + * + * A time is null if its hour string or minute string is empty. + */ + bool isNull() const; + + /** + * Returns the time value converted to QTime type + * + * Invalid QTime is returned if the KDbTime is invalid. + */ + QTime toQTime() const; + + /** + * Returns the time value converted to string even if it is invalid + * + * For null times empty string is returned. + */ + QByteArray toString() const; + + /** + * Returns the hour part of the time converted to integer + * + * Correct values are in range 0..23 for None period, and 1..12 for Am and Pm periods. + * -1 is returned for invalid hour. + */ + int hour() const; + + /** + * Returns the hour part of the date + * + * It is original string passed to the KDbTime object and may be invalid. + */ + QByteArray hourString() const { return m_hourString; } + + /** + * Returns the minute part of the time converted to integer + * + * Correct values are in range 0..59. -1 is returned for invalid minute. + */ + int minute() const; + + /** + * Returns the minute part of the date + * + * It is original string passed to the KDbTime object and may be invalid. + */ + QByteArray minuteString() const { return m_minuteString; } + + /** + * Returns the second part of the time converted to integer + * + * Correct values are in range 0..59. -1 is returned for invalid second. + */ + int second() const; + + /** + * Returns the second part of the date + * + * It is original string passed to the KDbTime object and may be invalid. + */ + QByteArray secondString() const { return m_secondString; } + + int msec() const; + + /** + * Returns the milliseconds part of the date + * + * It is original string passed to the KDbTime object and may be invalid. + */ + QByteArray msecString() const { return m_msecString; } + + /** + * Specifies hour period + */ + Period period() const { return m_period; } + +private: + const QByteArray m_hourString; + const QByteArray m_minuteString; + const QByteArray m_secondString; + const QByteArray m_msecString; + const Period m_period = Period::None; +}; + +Q_DECLARE_METATYPE(KDbTime) + +//! Sends information about value @a time to debug output @a dbg. +KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbTime &time); + +/** + * Generic date/time constant + * + * @since 3.1.1 + */ +class KDB_EXPORT KDbDateTime +{ +public: + KDbDateTime(const KDbDate &date, const KDbTime &time) : m_date(date), m_time(time) + { + } + + /** + * Constructs a null date/time + */ + KDbDateTime() = default; + + bool operator==(const KDbDateTime &other) const; + + inline bool operator!=(const KDbDateTime &other) const { return !operator==(other); } + + bool operator<(const KDbDateTime &other) const; + + inline bool operator<=(const KDbDateTime &other) const { return operator<(other) || operator==(other); } + + inline bool operator>=(const KDbDateTime &other) const { return !operator<(other); } + + inline bool operator>(const KDbDateTime &other) const { return !operator<=(other); } + + /** + * Returns @c true if the date/time is valid + * + * Validation is performed by converting to QDateTime (toQDateTime()) and checking if it is valid. + */ + bool isValid() const; + + /** + * Returns @c true if the date/time is null + * + * A time is null if its date or time is null. + */ + bool isNull() const; + + /** + * Returns the date/time converted to QDateTime value + * + * Invalid QDateTime is returned if the KDbDateTime is invalid. + */ + QDateTime toQDateTime() const; + + /** + * Returns the date/time value converted to string even if it is invalid + * + * For null date/times empty string is returned. + */ + QByteArray toString() const; + + /** + * Returns the date part of the date/time + */ + KDbDate date() const { return m_date; } + + /** + * Returns the time part of the date/time + */ + KDbTime time() const { return m_time; } + +private: + const KDbDate m_date; + const KDbTime m_time; +}; + +Q_DECLARE_METATYPE(KDbDateTime) + +//! Sends information about value @a dateTime to debug output @a dbg. +KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbDateTime &dateTime); + +#endif diff --git a/src/KDbDateTime.cpp b/src/KDbDateTime.cpp new file mode 100644 --- /dev/null +++ b/src/KDbDateTime.cpp @@ -0,0 +1,446 @@ +/* This file is part of the KDE project + Copyright (C) 2018 Jarosław Staniek + + 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 + * Boston, MA 02110-1301, USA. + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + */ + +#include "KDbDateTime.h" + +#include + +const int UNCACHED_YEAR = -1; +const int INVALID_YEAR = -2; + +namespace { +template +std::function byteArrayToString() +{ + return [](const T &v) { return QString::fromLatin1(v.toString()); }; +} + +struct KDbDateTimeMetatypeInitializer { + KDbDateTimeMetatypeInitializer() + { + using namespace std::placeholders; + QMetaType::registerConverter(byteArrayToString()); + QMetaType::registerConverter(std::bind(&KDbYear::toIsoValue, _1)); + QMetaType::registerConverter(byteArrayToString()); + QMetaType::registerConverter(std::bind(&KDbDate::toQDate, _1)); + QMetaType::registerConverter(byteArrayToString()); + QMetaType::registerConverter(std::bind(&KDbTime::toQTime, _1)); + QMetaType::registerConverter(byteArrayToString()); + QMetaType::registerConverter(std::bind(&KDbDateTime::toQDateTime, _1)); + QMetaType::registerComparators(); + QMetaType::registerComparators(); + QMetaType::registerComparators(); + QMetaType::registerComparators(); + } +}; + +KDbDateTimeMetatypeInitializer s_init; +} + +bool KDbYear::operator==(const KDbYear &other) const +{ + return m_sign == other.sign() && m_string == other.yearString(); +} + +bool KDbYear::operator<(const KDbYear &other) const +{ + return toQDateValue() < other.toQDateValue(); +} + +bool KDbYear::isValid() const +{ + return std::get<1>(intValue()); +} + +bool KDbYear::isNull() const +{ + return m_sign == Sign::None && m_string.isEmpty(); +} + +QByteArray KDbYear::signString() const +{ + QByteArray result; + switch (m_sign) { + case Sign::Plus: + result = QByteArrayLiteral("+"); + break; + case Sign::Minus: + result = QByteArrayLiteral("-"); + break; + default: + break; + } + return result; +} + +KDB_EXPORT QDebug operator<<(QDebug dbg, KDbYear::Sign sign) +{ + QDebugStateSaver saver(dbg); + switch (sign) { + case KDbYear::Sign::None: + break; + case KDbYear::Sign::Plus: + dbg.nospace() << '+'; + break; + case KDbYear::Sign::Minus: + dbg.nospace() << '-'; + break; + } + return dbg.maybeSpace(); +} + +KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbYear& year) +{ + QDebugStateSaver saver(dbg); + dbg.nospace().noquote() << "KDbYear(" << year.sign() << year.yearString(); + if (!year.isValid()) { + dbg.nospace() << " INVALID"; + } + dbg.nospace() << ")"; + return dbg.maybeSpace(); +} + +QByteArray KDbYear::toString() const +{ + QByteArray result; + if (isNull()) { + result = QByteArrayLiteral(""); + } else { // can be invalid, that's OK + result = signString() + m_string; + } + return result; +} + +int KDbYear::toIsoValue() const +{ + return std::get<0>(intValue()); +} + +int KDbYear::toQDateValue() const +{ + int result; + bool ok; + std::tie(result, ok) = intValue(); + if (!ok) { + return 0; + } + if (result > 0) { + return result; + } + return result - 1; +} + +namespace { +int intValueInternal(KDbYear::Sign sign, const QByteArray &string) +{ + const int length = string.length(); + if (length < 4) { + // TODO message: at least 4 digits required + return INVALID_YEAR; + } else if (length > 4) { + if (sign == KDbYear::Sign::None) { + // TODO message: more than 4 digits, sign required + return INVALID_YEAR; + } + } + + static QRegularExpression digitsRegExp(QStringLiteral("^\\d+$")); + if (!digitsRegExp.match(QString::fromLatin1(string)).hasMatch()) { + // TODO message: only digits are accepted for year + return INVALID_YEAR; + } + + bool ok; + int result = string.toInt(&ok); + if (!ok || result < 0) { + // TODO message: failed to convert year to integer >= 0 + return INVALID_YEAR; + } + int qDateYear; + if (result == 0) { + if (sign != KDbYear::Sign::Plus) { + // TODO message: + required for 0000 + return INVALID_YEAR; + } + qDateYear = -1; + } else if (sign == KDbYear::Sign::Minus) { + qDateYear = - result - 1; + } else { // Plus or None + qDateYear = result; + } + // verify if this year is within the limits of QDate (see QDate::minJd(), QDate::maxJd()) + if (!QDate(qDateYear, 1, 1).isValid()) { + // TODO message: year is not within limits + return INVALID_YEAR; + } + return result; +} +} + +std::tuple KDbYear::intValue() const +{ + if (m_isoValue == UNCACHED_YEAR) { + const_cast(m_isoValue) = intValueInternal(m_sign, m_string); // cache + } + if (m_isoValue == INVALID_YEAR) { + return std::make_tuple(0, false); + } + return std::make_tuple(m_sign == Sign::Minus ? -m_isoValue : m_isoValue, true); +} + +bool KDbDate::operator==(const KDbDate &other) const +{ + return m_year == other.year() && m_monthString == other.monthString() + && m_dayString == other.dayString(); +} + +bool KDbDate::operator<(const KDbDate &other) const +{ + return toQDate() < other.toQDate(); +} + +bool KDbDate::isValid() const +{ + return toQDate().isValid(); +} + +bool KDbDate::isNull() const +{ + return m_year.isNull() && m_monthString.isEmpty() && m_dayString.isEmpty(); +} + +QDate KDbDate::toQDate() const +{ + return { m_year.toQDateValue(), month(), day() }; +} + +namespace { +int toInt(const QByteArray &string, int min, int max, int minLength, int maxLength) +{ + if (string.length() < minLength || string.length() > maxLength) { + // TODO message: invalid length + return -1; + } + bool ok = true; + const int result = string.isEmpty() ? 0 : string.toInt(&ok); + if (!ok || result < min || result > max) { + // TODO message: could not convert string to integer + return -1; + } + return result; +} +} + +int KDbDate::month() const +{ + return toInt(m_monthString, 1, 12, 1, 2); +} + +int KDbDate::day() const +{ + return toInt(m_dayString, 1, 31, 1, 2); +} + +QByteArray KDbDate::toString() const +{ + QByteArray result; + if (isNull()) { + result = QByteArrayLiteral(""); + } else { // can be invalid, that's OK + result = m_year.toString() + '-' + m_monthString + '-' + m_dayString; + } + return result; +} + +KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbDate &date) +{ + QDebugStateSaver saver(dbg); + dbg.nospace().noquote() << "KDbDate(" << date.toString(); + if (!date.isValid()) { + dbg.nospace() << " INVALID"; + } + dbg.nospace() << ")"; + return dbg.maybeSpace(); +} + +bool KDbTime::operator==(const KDbTime &other) const +{ + return m_hourString == other.hourString() && m_minuteString == other.minuteString() + && m_secondString == other.secondString() && m_msecString == other.msecString() + && m_period == other.period(); +} + +bool KDbTime::operator<(const KDbTime &other) const +{ + return toQTime() < other.toQTime(); +} + +QTime KDbTime::toQTime() const +{ + // Rules for hours based on https://www.timeanddate.com/time/am-and-pm.html#converting + int h = hour(); + if (h == -1) { + return {}; + } + const int m = minute(); + if (m == -1) { + return {}; + } + const int s = second(); + if (s == -1) { + return {}; + } + const int ms = msec(); + if (ms == -1) { + return {}; + } + if (m_period == Period::None) { + return { h, m, s, ms }; + } + return QTime::fromString( + QStringLiteral("%1:%2:%3.%4 %5") + .arg(h) + .arg(m) + .arg(s) + .arg(ms) + .arg(m_period == Period::Am ? QLatin1String("AM") : QLatin1String("PM")), + QStringLiteral("h:m:s.z AP")); +} + +int KDbTime::hour() const +{ + switch (m_period) { + case Period::None: + return toInt(m_hourString, 0, 23, 1, 2); + case Period::Am: + case Period::Pm: + return toInt(m_hourString, 1, 12, 1, 2); + } + return -1; +} + +int KDbTime::minute() const +{ + return toInt(m_minuteString, 0, 59, 1, 2); +} + +int KDbTime::second() const +{ + return toInt(m_secondString, 0, 59, 0, 2); +} + +int KDbTime::msec() const +{ + return toInt(m_msecString, 0, 999, 0, 3); +} + +bool KDbTime::isValid() const +{ + return toQTime().isValid(); +} + +bool KDbTime::isNull() const +{ + return m_hourString.isEmpty() || m_minuteString.isEmpty(); +} + +QByteArray KDbTime::toString() const +{ + QByteArray result; + if (isNull()) { + result = QByteArrayLiteral(""); + } else if (m_msecString.isEmpty()) { // can be invalid, that's OK + if (m_secondString.isEmpty()) { + result = m_hourString + ':' + m_minuteString; + } else { + result = m_hourString + ':' + m_minuteString + ':' + m_secondString; + } + } else { // can be invalid, that's OK + result = m_hourString + ':' + m_minuteString + ':' + m_secondString + '.' + m_msecString; + } + switch (m_period) { + case KDbTime::Period::Am: + result += " AM"; + break; + case KDbTime::Period::Pm: + result += " PM"; + break; + default: + break; + } + return result; +} + +KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbTime &time) +{ + QDebugStateSaver saver(dbg); + dbg.nospace().noquote() << "KDbTime(" << time.toString(); + if (!time.isValid()) { + dbg.nospace() << " INVALID"; + } + dbg.nospace() << ")"; + return dbg.maybeSpace(); +} + +bool KDbDateTime::operator==(const KDbDateTime &other) const +{ + return date() == other.date() && time() == other.time(); +} + +bool KDbDateTime::operator<(const KDbDateTime &other) const +{ + return toQDateTime() < other.toQDateTime(); +} + +bool KDbDateTime::isValid() const +{ + return m_date.isValid() && m_time.isValid(); +} + +bool KDbDateTime::isNull() const +{ + return m_date.isNull() || m_time.isNull(); +} + +QDateTime KDbDateTime::toQDateTime() const +{ + return { m_date.toQDate(), m_time.toQTime() }; +} + +QByteArray KDbDateTime::toString() const +{ + QByteArray result; + if (isNull()) { + result = QByteArrayLiteral(""); + } else { + result = m_date.toString() + ' ' + m_time.toString(); // can be invalid, that's OK + } + return result; +} + +KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbDateTime &dateTime) +{ + QDebugStateSaver saver(dbg); + dbg.nospace().noquote() << "KDbDateTime(" << dateTime.toString(); + if (!dateTime.isValid()) { + dbg.nospace() << "INVALID"; + } + dbg.nospace() << ")"; + return dbg.maybeSpace(); +} diff --git a/src/KDbDriver.h b/src/KDbDriver.h --- a/src/KDbDriver.h +++ b/src/KDbDriver.h @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2003-2017 Jarosław Staniek + Copyright (C) 2003-2018 Jarosław Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -163,8 +163,48 @@ return valueToSql((field ? field->type() : KDbField::InvalidType), v); } - /*! @todo not compatible with all drivers - reimplement */ - virtual KDbEscapedString dateTimeToSql(const QDateTime& v) const; + /** + * Converts date value to string + * + * Default implementation uses KDb::dateToSql(). + * + * Not compatible with all drivers - reimplement. + * + * @since 3.1.1 + */ + virtual KDbEscapedString dateToSql(const QVariant &v) const; + + /** + * Converts time value to string + * + * Default implementation uses KDb::timeToIsoString(). + * + * Not compatible with all drivers - reimplement. + * + * @since 3.1.1 + */ + virtual KDbEscapedString timeToSql(const QVariant &v) const; + + /** + * Converts date/time value to string + * + * Default implementation uses KDb::dateTimeToIsoString(). + * + * Not compatible with all drivers - reimplement. + * + * @since 3.1.1 + */ + virtual KDbEscapedString dateTimeToSql(const QVariant &v) const; + + /** + * Converts date/time value to string + * + * Default implementation uses dateTimeToSql(QVariant). + * Deprecated, use dateTimeToSql(QVariant). + * + * Not compatible with all drivers - reimplement. + */ + KDB_DEPRECATED virtual KDbEscapedString dateTimeToSql(const QDateTime& v) const; /*! Driver-specific SQL string escaping. Implement escaping for any character like " or ' as your diff --git a/src/KDbDriver.cpp b/src/KDbDriver.cpp --- a/src/KDbDriver.cpp +++ b/src/KDbDriver.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2003-2017 Jarosław Staniek + Copyright (C) 2003-2018 Jarosław Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -185,7 +185,7 @@ return drv_isSystemFieldName(name); } -static KDbEscapedString valueToSqlInternal(const KDbDriver *driver, KDbField::Type ftype, const QVariant& v) +KDbEscapedString valueToSqlInternal(const KDbDriver *driver, KDbField::Type ftype, const QVariant& v) { if (v.isNull() || ftype == KDbField::Null) { return KDbEscapedString("NULL"); @@ -217,12 +217,11 @@ : KDbDriverPrivate::behavior(driver)->BOOLEAN_TRUE_LITERAL) : KDbEscapedString(v.toInt() == 0 ? "FALSE" : "TRUE"); case KDbField::Time: - return KDbEscapedString('\'') + v.toTime().toString(Qt::ISODate) + '\''; + return driver ? driver->timeToSql(v) : KDb::timeToSql(v); case KDbField::Date: - return KDbEscapedString('\'') + v.toDate().toString(Qt::ISODate) + '\''; + return driver ? driver->dateToSql(v) : KDb::dateToSql(v); case KDbField::DateTime: - return driver ? driver->dateTimeToSql(v.toDateTime()) - : KDb::dateTimeToSql(v.toDateTime()); + return driver ? driver->dateTimeToSql(v) : KDb::dateTimeToSql(v); case KDbField::BLOB: { if (v.toByteArray().isEmpty()) { return KDbEscapedString("NULL"); @@ -244,29 +243,28 @@ KDbEscapedString KDbDriver::valueToSql(KDbField::Type ftype, const QVariant& v) const { - //! note, it was compatible with SQLite: https://www.sqlite.org/cvstrac/wiki?p=DateAndTimeFunctions. + //! @note it was compatible with SQLite: https://www.sqlite.org/lang_datefunc.html return valueToSqlInternal(this, ftype, v); } -KDbEscapedString KDb::valueToSql(KDbField::Type ftype, const QVariant& v) +KDbEscapedString KDbDriver::dateToSql(const QVariant &v) const { - return valueToSqlInternal(nullptr, ftype, v); + return KDb::dateToIsoString(v); } -KDbEscapedString KDb::dateTimeToSql(const QDateTime& v) +KDbEscapedString KDbDriver::timeToSql(const QVariant& v) const { - /*! (was compatible with SQLite: https://www.sqlite.org/cvstrac/wiki?p=DateAndTimeFunctions) - Now it's ISO 8601 DateTime format - with "T" delimiter: - https://www.w3.org/TR/NOTE-datetime - (e.g. "1994-11-05T13:15:30" not "1994-11-05 13:15:30") - @todo add support for time zones? - */ - return KDbEscapedString('\'') + v.toString(Qt::ISODate) + KDbEscapedString('\''); + return KDb::timeToIsoString(v); +} + +KDbEscapedString KDbDriver::dateTimeToSql(const QVariant& v) const +{ + return KDb::dateTimeToIsoString(v); } KDbEscapedString KDbDriver::dateTimeToSql(const QDateTime& v) const { - return KDb::dateTimeToSql(v); + return dateTimeToSql(QVariant(v)); } QString KDbDriver::escapeIdentifier(const QString& str) const diff --git a/src/KDbField.cpp b/src/KDbField.cpp --- a/src/KDbField.cpp +++ b/src/KDbField.cpp @@ -788,16 +788,16 @@ break; } case DateTime: {//YYYY-MM-DDTHH:MM:SS - QDateTime dt = QDateTime::fromString(QLatin1String(def), Qt::ISODate); + QDateTime dt = QDateTime::fromString(QLatin1String(def), Qt::ISODateWithMs); if (!dt.isValid()) { d->defaultValue = QVariant(); } else { d->defaultValue = QVariant(dt); } break; } case Time: {//HH:MM:SS - QTime time = QTime::fromString(QLatin1String(def), Qt::ISODate); + QTime time = QTime::fromString(QLatin1String(def), Qt::ISODateWithMs); if (!time.isValid()) { d->defaultValue = QVariant(); } else { diff --git a/src/KDbQuerySchema.cpp b/src/KDbQuerySchema.cpp --- a/src/KDbQuerySchema.cpp +++ b/src/KDbQuerySchema.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2003-2017 Jarosław Staniek + Copyright (C) 2003-2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/src/KDb_p.h b/src/KDb_p.h --- a/src/KDb_p.h +++ b/src/KDb_p.h @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2004-2016 Jarosław Staniek + Copyright (C) 2004-2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -20,7 +20,9 @@ #ifndef KDB_P_H #define KDB_P_H -#include +#include "KDbField.h" + +class KDbDriver; //! @internal Dummy class to get simply translation markup expressions //! of the form kdb::tr("foo") instead of the complicated and harder to read @@ -31,4 +33,7 @@ Q_DECLARE_TR_FUNCTIONS(KDb) }; +KDbEscapedString valueToSqlInternal(const KDbDriver *driver, KDbField::Type ftype, + const QVariant &v); + #endif diff --git a/src/drivers/postgresql/PostgresqlCursor.cpp b/src/drivers/postgresql/PostgresqlCursor.cpp --- a/src/drivers/postgresql/PostgresqlCursor.cpp +++ b/src/drivers/postgresql/PostgresqlCursor.cpp @@ -185,9 +185,8 @@ QString s(QString::fromLatin1(data, len)); if (hasTimeZone(s)) { s.chop(3); // skip timezone - return QTime::fromString(s, Qt::ISODate); } - return QTime::fromString(s, Qt::ISODate); + return QTime::fromString(s, Qt::ISODateWithMs); } static inline QDateTime dateTimeFromData(const char *data, int len) @@ -205,7 +204,7 @@ if (s.at(s.length() - 3).isPunct()) { // fix ms, should be three digits s += QLatin1Char('0'); } - return QDateTime::fromString(s, Qt::ISODate); + return QDateTime::fromString(s, Qt::ISODateWithMs); } static inline QByteArray byteArrayFromData(const char *data) diff --git a/src/drivers/sqlite/SqliteCursor.cpp b/src/drivers/sqlite/SqliteCursor.cpp --- a/src/drivers/sqlite/SqliteCursor.cpp +++ b/src/drivers/sqlite/SqliteCursor.cpp @@ -100,7 +100,7 @@ if (text.length() > 10) { text[10] = QLatin1Char('T'); //for ISODate compatibility } - return QDateTime::fromString(text, Qt::ISODate); + return QDateTime::fromString(text, Qt::ISODateWithMs); } else if (t == KDbField::Boolean) { return sqliteStringToBool(text); } else { diff --git a/src/drivers/sqlite/SqlitePreparedStatement.cpp b/src/drivers/sqlite/SqlitePreparedStatement.cpp --- a/src/drivers/sqlite/SqlitePreparedStatement.cpp +++ b/src/drivers/sqlite/SqlitePreparedStatement.cpp @@ -132,7 +132,7 @@ } case KDbField::Time: { int res = sqlite3_bind_text(sqlResult()->prepared_st, par, - qPrintable(value.toTime().toString(Qt::ISODate)), + qPrintable(value.toTime().toString(Qt::ISODateWithMs)), QLatin1String("HH:MM:SS").size(), SQLITE_TRANSIENT /*??*/); if (res != SQLITE_OK) { m_result.setServerErrorCode(res); @@ -154,7 +154,7 @@ } case KDbField::DateTime: { int res = sqlite3_bind_text(sqlResult()->prepared_st, par, - qPrintable(value.toDateTime().toString(Qt::ISODate)), + qPrintable(value.toDateTime().toString(Qt::ISODateWithMs)), QLatin1String("YYYY-MM-DDTHH:MM:SS").size(), SQLITE_TRANSIENT /*??*/); if (res != SQLITE_OK) { m_result.setServerErrorCode(res); diff --git a/src/expression/KDbConstExpression.cpp b/src/expression/KDbConstExpression.cpp --- a/src/expression/KDbConstExpression.cpp +++ b/src/expression/KDbConstExpression.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2003-2012 Jarosław Staniek + Copyright (C) 2003-2018 Jarosław Staniek Based on nexp.cpp : Parser module of Python-like language (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl) @@ -80,11 +80,26 @@ case REAL_CONST: return KDbField::Double; case DATE_CONST: - return KDbField::Date; + if (value.canConvert() && value.value().isValid()) { + return KDbField::Date; + } else if (value.canConvert() && value.toDate().isValid()) { + return KDbField::Date; + } + break; case DATETIME_CONST: - return KDbField::DateTime; + if (value.canConvert() && value.value().isValid()) { + return KDbField::DateTime; + } else if (value.canConvert() && value.toDateTime().isValid()) { + return KDbField::DateTime; + } + break; case TIME_CONST: - return KDbField::Time; + if (value.canConvert() && value.value().isValid()) { + return KDbField::Time; + } else if (value.canConvert() && value.toTime().isValid()) { + return KDbField::Time; + } + break; } return KDbField::InvalidType; } @@ -125,10 +140,7 @@ case DATE_CONST: return KDb::valueToSql(driver, KDbField::Date, value); case DATETIME_CONST: - return driver ? driver->valueToSql(KDbField::DateTime, value) - : KDbEscapedString('\'') - + KDbEscapedString(value.toDateTime().date().toString(Qt::ISODate)) - + ' ' + value.toDateTime().time().toString(Qt::ISODate) + '\''; + return KDb::valueToSql(driver, KDbField::Date, value); case TIME_CONST: return KDb::valueToSql(driver, KDbField::Time, value); case INTEGER_CONST: diff --git a/src/parser/KDbParser.h b/src/parser/KDbParser.h --- a/src/parser/KDbParser.h +++ b/src/parser/KDbParser.h @@ -1,6 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch - Copyright (C) 2004-2017 Jarosław Staniek + Copyright (C) 2004-2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/src/parser/KDbParser.cpp b/src/parser/KDbParser.cpp --- a/src/parser/KDbParser.cpp +++ b/src/parser/KDbParser.cpp @@ -1,6 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch - Copyright (C) 2004-2017 Jarosław Staniek + Copyright (C) 2004-2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -218,9 +218,12 @@ QDebug operator<<(QDebug dbg, const KDbParserError& error) { + QDebugStateSaver saver(dbg); if (error.type().isEmpty() && error.message().isEmpty()) { - return dbg.space() << "KDb:KDbParserError: None"; + dbg.space() << "KDb:KDbParserError: None"; + } else { + dbg.space() << "KDb:KDbParserError: type=" << error.type() << "message=" << error.message() + << "pos=" << error.position() << ")"; } - return dbg.space() << "KDb:KDbParserError: type=" << error.type() << "message=" << error.message() - << "pos=" << error.position() << ")"; + return dbg.maybeSpace(); } diff --git a/src/parser/KDbSqlParser.y b/src/parser/KDbSqlParser.y --- a/src/parser/KDbSqlParser.y +++ b/src/parser/KDbSqlParser.y @@ -1,6 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2004 Lucijan Busch - Copyright (C) 2004-2016 Jarosław Staniek + Copyright (C) 2004-2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -370,6 +370,11 @@ %token XOR //%token YEAR //%token YEARS_BETWEEN +%token UMINUS +%token TABS_OR_SPACES // e.g. inside of date or time constants +%token DATE_TIME_INTEGER // inside of date or time constants +%token TIME_AM +%token TIME_PM %type IDENTIFIER %type IDENTIFIER_DOT_ASTERISK @@ -396,6 +401,14 @@ %type aExpr8 %type aExpr9 %type aExpr10 +%type DateConst +%type DateValue +%type YearConst +%type TimeConst +%type TimeValue +%type DateTimeConst +%type TimeMs +%type TimePeriod %type aExprList %type aExprList2 %type WhereClause @@ -416,6 +429,7 @@ %type SQL_TYPE %type INTEGER_CONST %type REAL_CONST +%type DATE_TIME_INTEGER /*%type SIGNED_INTEGER */ %{ @@ -448,6 +462,7 @@ #include #include "KDbConnection.h" +#include "KDbDateTime.h" #include "KDbExpression.h" #include "KDbField.h" #include "KDbOrderByColumn.h" @@ -492,6 +507,11 @@ QByteArray* binaryValue; qint64 integerValue; bool booleanValue; + KDbDate* dateValue; + KDbYear* yearValue; + KDbTime* timeValue; + KDbTime::Period timePeriodValue; + KDbDateTime* dateTimeValue; KDbOrderByColumn::SortOrder sortOrderValue; KDbField::Type colType; KDbField *field; @@ -517,7 +537,6 @@ //%nonassoc NULL_P //%nonassoc TRUE_P //%nonassoc FALSE_P -%token UMINUS // <-- To keep binary compatibility insert new tokens here. @@ -1157,10 +1176,139 @@ sqlParserDebug() << " + real constant: " << *$1; delete $1; } +| DateConst +{ + $$ = new KDbConstExpression(KDbToken::DATE_CONST, QVariant::fromValue(*$1)); + sqlParserDebug() << " + date constant:" << *$1; + delete $1; +} +| TimeConst +{ + $$ = new KDbConstExpression(KDbToken::TIME_CONST, QVariant::fromValue(*$1)); + sqlParserDebug() << " + time constant:" << *$1; + delete $1; +} +| DateTimeConst +{ + $$ = new KDbConstExpression(KDbToken::DATETIME_CONST, QVariant::fromValue(*$1)); + sqlParserDebug() << " + datetime constant:" << *$1; + delete $1; +} | aExpr10 ; +DateConst: +'#' DateValue '#' +{ + $$ = $2; + sqlParserDebug() << "DateConst:" << *$$; +} +; + +DateValue: +YearConst '-' DATE_TIME_INTEGER '-' DATE_TIME_INTEGER +{ + $$ = new KDbDate(*$1, *$3, *$5); + sqlParserDebug() << "DateValue:" << *$$; + delete $1; + delete $3; + delete $5; +} +| DATE_TIME_INTEGER '/' DATE_TIME_INTEGER '/' YearConst /* M/D/Y */ +{ + $$ = new KDbDate(*$5, *$1, *$3); + sqlParserDebug() << "DateValue:" << *$$; + delete $1; + delete $3; + delete $5; +} +; + +YearConst: +DATE_TIME_INTEGER +{ + $$ = new KDbYear(KDbYear::Sign::None, *$1); + sqlParserDebug() << "YearConst:" << *$$; + delete $1; +} +| '+' DATE_TIME_INTEGER +{ + $$ = new KDbYear(KDbYear::Sign::Plus, *$2); + sqlParserDebug() << "YearConst:" << *$$; + delete $2; +} +| '-' DATE_TIME_INTEGER +{ + $$ = new KDbYear(KDbYear::Sign::Minus, *$2); + sqlParserDebug() << "YearConst:" << *$$; + delete $2; +} +; + +TimeConst: +'#' TimeValue '#' +{ + $$ = $2; + sqlParserDebug() << "TimeConst:" << *$$; +} +; + +TimeValue: +DATE_TIME_INTEGER ':' DATE_TIME_INTEGER TimeMs TimePeriod +{ + $$ = new KDbTime(*$1, *$3, {}, *$4, $5); + sqlParserDebug() << "TimeValue:" << *$$; + delete $1; + delete $3; + delete $4; +} +| DATE_TIME_INTEGER ':' DATE_TIME_INTEGER ':' DATE_TIME_INTEGER TimeMs TimePeriod +{ + $$ = new KDbTime(*$1, *$3, *$5, *$6, $7); + sqlParserDebug() << "TimeValue:" << *$$; + delete $1; + delete $3; + delete $5; + delete $6; +} +; + +TimeMs: +'.' DATE_TIME_INTEGER +{ + $$ = $2; +} +| %empty +{ + $$ = new QByteArray; +} +; + +TimePeriod: +TIME_AM +{ + $$ = KDbTime::Period::Am; +} +| TIME_PM +{ + $$ = KDbTime::Period::Pm; +} +| %empty +{ + $$ = KDbTime::Period::None; +} +; + +DateTimeConst: +'#' DateValue TABS_OR_SPACES TimeValue '#' +{ + $$ = new KDbDateTime(*$2, *$4); + sqlParserDebug() << "DateTimeConst:" << *$$; + delete $2; + delete $4; +} +; aExpr10: '(' aExpr ')' diff --git a/src/parser/KDbSqlScanner.l b/src/parser/KDbSqlScanner.l --- a/src/parser/KDbSqlScanner.l +++ b/src/parser/KDbSqlScanner.l @@ -1,6 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2004 Lucijan Busch - Copyright (C) 2004-2015 Jarosław Staniek + Copyright (C) 2004-2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -43,7 +43,10 @@ %option noyywrap %option never-interactive +%x DATE_OR_TIME + whitespace [ \t\n] +whitespace_1_line [ \t] digit [0-9] e_str1 (\\\'|\'\'|[^']) e_str2 (\\\"|\"\"|[^"]) @@ -59,6 +62,7 @@ %% + int DATE_OR_TIME_caller = 0; "<>" { ECOUNT; @@ -109,6 +113,53 @@ return REAL_CONST; } + /* --- DATE_OR_TIME --- */ +# { + ECOUNT; + sqlParserDebug() << "### begin DATE_OR_TIME" << yytext << "(" << yyleng << ")"; + DATE_OR_TIME_caller = YYSTATE; + BEGIN(DATE_OR_TIME); + return '#'; +} + +{ + +[-+/:] { // year prefix or / or - or : separator + ECOUNT; + return yytext[0]; +} + +{integer} { // year, month, day, hour, minute or second + ECOUNT; + yylval.binaryValue = new QByteArray(yytext, yyleng); + return DATE_TIME_INTEGER; +} + +{whitespace_1_line}+ { + ECOUNT; + return TABS_OR_SPACES; +} + +{whitespace_1_line}*(?i:AM) { + ECOUNT; + return TIME_AM; +} + +{whitespace_1_line}*(?i:PM) { + ECOUNT; + return TIME_PM; +} + +# { + ECOUNT; + sqlParserDebug() << "### begin DATE_OR_TIME" << yytext << "(" << yyleng << ")"; + BEGIN(DATE_OR_TIME_caller); + return '#'; +} + +} + /* -- end of DATE_OR_TIME --- */ + ("AND"|"&&") { ECOUNT; return AND; diff --git a/src/parser/generate_parser_code.sh b/src/parser/generate_parser_code.sh --- a/src/parser/generate_parser_code.sh +++ b/src/parser/generate_parser_code.sh @@ -69,6 +69,7 @@ #ifndef KDBSQLPARSER_H #define KDBSQLPARSER_H +#include "KDbDateTime.h" #include "KDbExpression.h" #include "KDbField.h" #include "KDbOrderByColumn.h" @@ -156,9 +157,11 @@ //! Only characters that belong to the grammar are accepted: EOF (echo -n " //! "; grep "\"'.'\"," generated/sqlparser.cpp \ - | sed -e ":a;N;s/\"\('.'\)\",/\1/g;s/\n//g;s/\".*,//g;s/^ *//g;s/ *$//g;") >> generated/KDbToken.h + | sed -e "s/\"\('.'\)\",/\1/g;s/\"[0-9A-Za-z_$]*\",[ ]*//g;" | tr --delete '\n' \ + | sed -e "s/ $//g;") >> generated/KDbToken.h cat << EOF >> generated/KDbToken.h + //! Invalid KDbToken is created for character that is not accepted. KDbToken(char charToken); diff --git a/src/parser/generated/KDbToken.h b/src/parser/generated/KDbToken.h --- a/src/parser/generated/KDbToken.h +++ b/src/parser/generated/KDbToken.h @@ -45,7 +45,7 @@ //! Creates a single-character token //! Only characters that belong to the grammar are accepted: - //! ';' ',' '.' '>' '<' '=' '+' '-' '&' '|' '/' '*' '%' '~' '(' ')' + //! ';' ',' '.' '>' '<' '=' '+' '-' '&' '|' '/' '*' '%' '~' '#' ':' '(' ')' //! Invalid KDbToken is created for character that is not accepted. KDbToken(char charToken); @@ -162,6 +162,10 @@ static const KDbToken NOT_SIMILAR_TO; static const KDbToken XOR; static const KDbToken UMINUS; + static const KDbToken TABS_OR_SPACES; + static const KDbToken DATE_TIME_INTEGER; + static const KDbToken TIME_AM; + static const KDbToken TIME_PM; //! Custom tokens are not used in parser but used as an extension in expression classes. static const KDbToken BETWEEN_AND; static const KDbToken NOT_BETWEEN_AND; diff --git a/src/parser/generated/KDbToken.cpp b/src/parser/generated/KDbToken.cpp --- a/src/parser/generated/KDbToken.cpp +++ b/src/parser/generated/KDbToken.cpp @@ -187,5 +187,9 @@ const KDbToken KDbToken::NOT_SIMILAR_TO(::NOT_SIMILAR_TO); const KDbToken KDbToken::XOR(::XOR); const KDbToken KDbToken::UMINUS(::UMINUS); +const KDbToken KDbToken::TABS_OR_SPACES(::TABS_OR_SPACES); +const KDbToken KDbToken::DATE_TIME_INTEGER(::DATE_TIME_INTEGER); +const KDbToken KDbToken::TIME_AM(::TIME_AM); +const KDbToken KDbToken::TIME_PM(::TIME_PM); const KDbToken KDbToken::BETWEEN_AND(0x1001); const KDbToken KDbToken::NOT_BETWEEN_AND(0x1002); diff --git a/src/parser/generated/sqlparser.h b/src/parser/generated/sqlparser.h --- a/src/parser/generated/sqlparser.h +++ b/src/parser/generated/sqlparser.h @@ -5,6 +5,7 @@ #ifndef KDBSQLPARSER_H #define KDBSQLPARSER_H +#include "KDbDateTime.h" #include "KDbExpression.h" #include "KDbField.h" #include "KDbOrderByColumn.h" @@ -121,21 +122,30 @@ SIMILAR_TO = 317, NOT_SIMILAR_TO = 318, XOR = 319, - UMINUS = 320 + UMINUS = 320, + TABS_OR_SPACES = 321, + DATE_TIME_INTEGER = 322, + TIME_AM = 323, + TIME_PM = 324 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 490 "KDbSqlParser.y" /* yacc.c:1909 */ +#line 505 "KDbSqlParser.y" /* yacc.c:1909 */ QString* stringValue; QByteArray* binaryValue; qint64 integerValue; bool booleanValue; + KDbDate* dateValue; + KDbYear* yearValue; + KDbTime* timeValue; + KDbTime::Period timePeriodValue; + KDbDateTime* dateTimeValue; KDbOrderByColumn::SortOrder sortOrderValue; KDbField::Type colType; KDbField *field; @@ -147,7 +157,7 @@ QList *orderByColumns; QVariant *variantValue; -#line 137 "KDbSqlParser.tab.h" /* yacc.c:1909 */ +#line 146 "KDbSqlParser.tab.h" /* yacc.c:1909 */ }; typedef union YYSTYPE YYSTYPE; diff --git a/src/parser/generated/sqlparser.cpp b/src/parser/generated/sqlparser.cpp --- a/src/parser/generated/sqlparser.cpp +++ b/src/parser/generated/sqlparser.cpp @@ -62,7 +62,7 @@ /* Copy the first part of user declarations. */ -#line 421 "KDbSqlParser.y" /* yacc.c:339 */ +#line 435 "KDbSqlParser.y" /* yacc.c:339 */ #include #include @@ -93,6 +93,7 @@ #include #include "KDbConnection.h" +#include "KDbDateTime.h" #include "KDbExpression.h" #include "KDbField.h" #include "KDbOrderByColumn.h" @@ -131,7 +132,7 @@ } -#line 135 "sqlparser.cpp" /* yacc.c:339 */ +#line 136 "sqlparser.cpp" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus @@ -228,21 +229,30 @@ SIMILAR_TO = 317, NOT_SIMILAR_TO = 318, XOR = 319, - UMINUS = 320 + UMINUS = 320, + TABS_OR_SPACES = 321, + DATE_TIME_INTEGER = 322, + TIME_AM = 323, + TIME_PM = 324 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 490 "KDbSqlParser.y" /* yacc.c:355 */ +#line 505 "KDbSqlParser.y" /* yacc.c:355 */ QString* stringValue; QByteArray* binaryValue; qint64 integerValue; bool booleanValue; + KDbDate* dateValue; + KDbYear* yearValue; + KDbTime* timeValue; + KDbTime::Period timePeriodValue; + KDbDateTime* dateTimeValue; KDbOrderByColumn::SortOrder sortOrderValue; KDbField::Type colType; KDbField *field; @@ -254,7 +264,7 @@ QList *orderByColumns; QVariant *variantValue; -#line 258 "sqlparser.cpp" /* yacc.c:355 */ +#line 268 "sqlparser.cpp" /* yacc.c:355 */ }; typedef union YYSTYPE YYSTYPE; @@ -271,7 +281,7 @@ /* Copy the second part of user declarations. */ -#line 275 "sqlparser.cpp" /* yacc.c:358 */ +#line 285 "sqlparser.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -513,21 +523,21 @@ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 7 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 221 +#define YYLAST 231 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 82 +#define YYNTOKENS 88 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 30 +#define YYNNTS 38 /* YYNRULES -- Number of rules. */ -#define YYNRULES 101 +#define YYNRULES 119 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 162 +#define YYNSTATES 201 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 320 +#define YYMAXUTOK 324 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -539,16 +549,16 @@ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 78, 74, 2, - 80, 81, 77, 72, 67, 73, 68, 76, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 66, - 70, 71, 69, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 84, 2, 82, 78, 2, + 86, 87, 81, 76, 71, 77, 72, 80, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 85, 70, + 74, 75, 73, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 75, 2, 79, 2, 2, 2, + 2, 2, 2, 2, 79, 2, 83, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -568,24 +578,25 @@ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65 + 65, 66, 67, 68, 69 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 545, 545, 555, 559, 560, 575, 674, 680, 687, - 692, 698, 704, 710, 719, 727, 734, 740, 748, 759, - 768, 777, 787, 795, 807, 813, 820, 827, 831, 838, - 843, 850, 856, 863, 868, 874, 880, 886, 892, 899, - 904, 910, 916, 922, 928, 934, 940, 946, 956, 967, - 972, 977, 983, 988, 994, 1001, 1006, 1012, 1018, 1024, - 1030, 1037, 1042, 1048, 1054, 1061, 1067, 1072, 1077, 1082, - 1087, 1095, 1101, 1109, 1116, 1123, 1127, 1131, 1137, 1154, - 1161, 1166, 1175, 1179, 1186, 1192, 1201, 1246, 1252, 1261, - 1289, 1299, 1314, 1321, 1331, 1340, 1345, 1355, 1368, 1414, - 1423, 1432 + 0, 564, 564, 574, 578, 579, 594, 693, 699, 706, + 711, 717, 723, 729, 738, 746, 753, 759, 767, 778, + 787, 796, 806, 814, 826, 832, 839, 846, 850, 857, + 862, 869, 875, 882, 887, 893, 899, 905, 911, 918, + 923, 929, 935, 941, 947, 953, 959, 965, 975, 986, + 991, 996, 1002, 1007, 1013, 1020, 1025, 1031, 1037, 1043, + 1049, 1056, 1061, 1067, 1073, 1080, 1086, 1091, 1096, 1101, + 1106, 1114, 1120, 1128, 1135, 1142, 1146, 1150, 1156, 1173, + 1179, 1185, 1191, 1198, 1202, 1210, 1218, 1229, 1235, 1241, + 1250, 1258, 1266, 1278, 1282, 1289, 1293, 1297, 1304, 1314, + 1323, 1327, 1334, 1340, 1349, 1394, 1400, 1409, 1437, 1447, + 1462, 1469, 1479, 1488, 1493, 1503, 1516, 1562, 1571, 1580 }; #endif @@ -606,14 +617,17 @@ "UNION", "SCAN_ERROR", "AND", "BETWEEN", "NOT_BETWEEN", "EXCEPT", "SQL_IN", "INTERSECT", "LIKE", "ILIKE", "NOT_LIKE", "NOT", "NOT_EQUAL", "NOT_EQUAL2", "OR", "SIMILAR_TO", "NOT_SIMILAR_TO", "XOR", "UMINUS", - "';'", "','", "'.'", "'>'", "'<'", "'='", "'+'", "'-'", "'&'", "'|'", - "'/'", "'*'", "'%'", "'~'", "'('", "')'", "$accept", "TopLevelStatement", - "StatementList", "Statement", "SelectStatement", "Select", - "SelectOptions", "WhereClause", "OrderByClause", "OrderByColumnId", - "OrderByOption", "aExpr", "aExpr2", "aExpr3", "aExpr4", "aExpr5", - "aExpr6", "aExpr7", "aExpr8", "aExpr9", "aExpr10", "aExprList", - "aExprList2", "Tables", "FlatTableList", "FlatTable", "ColViews", - "ColItem", "ColExpression", "ColWildCard", YY_NULLPTR + "TABS_OR_SPACES", "DATE_TIME_INTEGER", "TIME_AM", "TIME_PM", "';'", + "','", "'.'", "'>'", "'<'", "'='", "'+'", "'-'", "'&'", "'|'", "'/'", + "'*'", "'%'", "'~'", "'#'", "':'", "'('", "')'", "$accept", + "TopLevelStatement", "StatementList", "Statement", "SelectStatement", + "Select", "SelectOptions", "WhereClause", "OrderByClause", + "OrderByColumnId", "OrderByOption", "aExpr", "aExpr2", "aExpr3", + "aExpr4", "aExpr5", "aExpr6", "aExpr7", "aExpr8", "aExpr9", "DateConst", + "DateValue", "YearConst", "TimeConst", "TimeValue", "TimeMs", + "TimePeriod", "DateTimeConst", "aExpr10", "aExprList", "aExprList2", + "Tables", "FlatTableList", "FlatTable", "ColViews", "ColItem", + "ColExpression", "ColWildCard", YY_NULLPTR }; #endif @@ -628,16 +642,16 @@ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 59, 44, 46, 62, - 60, 61, 43, 45, 38, 124, 47, 42, 37, 126, - 40, 41 + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 59, 44, 46, 62, 60, 61, 43, 45, 38, 124, + 47, 42, 37, 126, 35, 58, 40, 41 }; # endif -#define YYPACT_NINF -127 +#define YYPACT_NINF -143 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-127))) + (!!((Yystate) == (-143))) #define YYTABLE_NINF -1 @@ -648,23 +662,27 @@ STATE-NUM. */ static const yytype_int16 yypact[] = { - -15, -127, 39, -127, -21, -127, 12, -127, -15, -127, - -11, 29, -127, -127, -127, -45, -127, -127, -127, 125, - 125, 125, -127, 125, 125, -127, -127, -23, -5, 158, - -127, 52, 58, 23, -127, -12, 9, -127, 10, -127, - -127, 82, 15, 8, -127, -27, 1, -127, -13, -127, - -127, -127, -127, -4, 125, 125, 125, 125, 125, 125, - 125, 125, -127, -127, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 75, 125, -127, 60, 71, -127, -12, - 51, -127, 16, 54, -127, 29, -127, -127, -127, 55, - 53, 57, -127, -127, -127, -127, -127, -127, -127, -127, - -127, 86, 87, -127, -127, -127, -127, -127, -127, -127, - -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, - 17, -127, 127, -127, -127, -127, -127, -127, -127, 125, - -127, 125, 125, -127, 73, 96, 5, 17, -127, -127, - -127, 103, -127, -127, -127, 17, 78, -127, -127, -127, - 17, -127 + 1, -143, 52, -143, -8, -143, 22, -143, 1, -143, + -27, 25, -143, -143, -143, -60, -143, -143, -143, 126, + 126, 126, -143, 126, 44, 126, -143, -143, -16, 13, + 163, -143, 86, 0, 64, -143, -143, -143, -143, -11, + 29, -143, 10, -143, -143, 102, 11, -5, -143, -23, + -2, -143, -21, -143, -143, -143, -143, -61, 4, 26, + -43, 24, 20, 35, 126, 126, 126, 126, 126, 126, + 126, 126, -143, -143, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 96, 126, -143, 84, 78, -143, -11, + 74, -143, 38, 98, -143, 25, -143, -143, -143, 71, + 48, 110, 89, 99, -143, -143, 101, -143, 103, -143, + -143, -143, -143, -143, -143, -143, -143, -143, -143, 114, + 120, -143, -143, -143, -143, -143, -143, -143, -143, -143, + -143, -143, -143, -143, -143, -143, -143, -143, 58, -143, + 172, -143, -143, -143, -143, -143, -143, 126, -143, 111, + -12, 112, 115, 121, 126, 126, -143, 128, 144, 12, + 58, -143, 63, 134, 137, -48, -143, 138, -143, -143, + 167, -143, -143, -143, 58, 136, -143, -143, -143, -143, + 139, -143, -143, -143, -143, -143, -143, 58, -48, -143, + -143 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -674,133 +692,146 @@ { 0, 14, 0, 2, 4, 6, 7, 1, 5, 77, 0, 0, 74, 78, 79, 70, 71, 75, 76, 0, - 0, 0, 100, 0, 0, 98, 29, 33, 39, 49, - 52, 55, 61, 65, 80, 10, 8, 93, 94, 95, - 3, 0, 89, 86, 88, 0, 0, 72, 70, 69, - 67, 66, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 118, 0, 0, 0, 116, 29, 33, 39, + 49, 52, 55, 61, 65, 80, 81, 82, 83, 10, + 8, 111, 112, 113, 3, 0, 107, 104, 106, 0, + 0, 72, 70, 69, 67, 66, 68, 87, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 15, 0, 11, 9, - 0, 97, 0, 0, 90, 0, 73, 101, 83, 85, - 0, 0, 81, 30, 31, 32, 37, 35, 34, 36, - 38, 0, 0, 44, 42, 43, 40, 41, 45, 46, - 53, 54, 57, 56, 58, 59, 60, 62, 63, 64, - 0, 19, 0, 92, 13, 96, 99, 91, 87, 0, - 82, 0, 0, 26, 24, 16, 20, 0, 84, 47, - 48, 0, 18, 27, 28, 0, 21, 17, 25, 22, - 0, 23 + 0, 115, 0, 0, 108, 0, 73, 119, 101, 103, + 0, 0, 0, 0, 88, 89, 0, 84, 0, 90, + 99, 30, 31, 32, 37, 35, 34, 36, 38, 0, + 0, 44, 42, 43, 40, 41, 45, 46, 53, 54, + 57, 56, 58, 59, 60, 62, 63, 64, 0, 19, + 0, 110, 13, 114, 117, 109, 105, 0, 100, 0, + 94, 0, 0, 0, 0, 0, 26, 24, 16, 20, + 0, 102, 0, 0, 0, 97, 98, 0, 47, 48, + 0, 18, 27, 28, 0, 21, 17, 87, 86, 93, + 94, 95, 96, 91, 85, 25, 22, 0, 97, 23, + 92 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -127, -127, 138, -127, -127, -127, -26, 2, -126, -127, - -127, -24, 64, 115, -63, -127, 31, 102, 44, 88, - -127, -127, 13, 117, -127, 63, -127, 72, 119, -127 + -143, -143, 200, -143, -143, -143, -29, 47, -142, -143, + -143, -25, 87, 106, -73, -143, 32, 107, 90, 108, + -143, -143, 45, -143, 105, 34, 21, -143, -143, -143, + 70, 188, -143, 124, -143, 133, 186, -143 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 2, 3, 4, 5, 6, 85, 86, 145, 146, - 156, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 47, 100, 35, 43, 44, 36, 37, 38, 39 + -1, 2, 3, 4, 5, 6, 95, 96, 168, 169, + 185, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 60, 61, 36, 62, 175, 193, 37, 38, 51, + 110, 39, 47, 48, 40, 41, 42, 43 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { - 53, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 88, 153, 96, 9, 90, 1, 83, 57, 58, 93, - 154, 157, 99, 45, 9, 12, 54, 11, 10, 159, - 11, 84, 13, 14, 161, 46, 12, 83, 55, 7, - 48, 56, 16, 13, 14, 8, 17, 18, 143, 91, - 97, 15, 84, 16, 94, 101, 144, 17, 18, 19, - 131, 73, 74, 134, 59, 60, 61, 46, 42, 41, - 19, 75, 155, 20, 21, 95, 87, 102, 149, 150, - 23, 24, 98, 9, 20, 21, 130, 10, 132, 22, - 135, 23, 24, 137, 9, 12, 96, 136, 10, 80, - 81, 82, 13, 14, 120, 121, 12, 49, 50, 51, - 15, 52, 16, 13, 14, 99, 17, 18, 103, 104, - 105, 48, 139, 16, 127, 128, 129, 17, 18, 19, - 76, 77, 78, 79, 140, 141, 142, 9, 147, 84, - 19, 151, 158, 20, 21, 160, 40, 152, 22, 12, - 23, 24, 148, 89, 20, 21, 13, 14, 138, 133, - 92, 23, 24, 0, 48, 0, 16, 0, 0, 0, - 17, 18, 106, 107, 108, 109, 110, 122, 123, 124, - 125, 126, 0, 19, 62, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 21, 0, - 0, 0, 0, 0, 23, 24, 0, 0, 64, 65, - 0, 66, 0, 67, 0, 68, 0, 69, 70, 0, - 71, 72 + 63, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 9, 98, 49, 85, 100, 103, 106, 93, 182, 112, + 191, 192, 12, 116, 113, 109, 50, 183, 186, 13, + 14, 1, 94, 64, 9, 67, 68, 52, 10, 16, + 11, 117, 196, 17, 18, 65, 12, 11, 66, 101, + 104, 111, 7, 13, 14, 199, 19, 93, 107, 45, + 173, 15, 8, 16, 46, 50, 105, 17, 18, 149, + 152, 114, 94, 174, 20, 21, 86, 87, 88, 89, + 19, 23, 24, 184, 25, 108, 69, 70, 71, 166, + 9, 178, 179, 115, 10, 83, 84, 167, 20, 21, + 97, 118, 12, 22, 119, 23, 24, 148, 25, 13, + 14, 57, 150, 153, 9, 138, 139, 15, 10, 16, + 58, 59, 120, 17, 18, 154, 12, 53, 54, 55, + 187, 56, 109, 13, 14, 158, 19, 155, 9, 58, + 59, 52, 157, 16, 90, 91, 92, 17, 18, 106, + 12, 121, 122, 123, 20, 21, 159, 13, 14, 22, + 19, 23, 24, 164, 25, 52, 160, 16, 161, 165, + 163, 17, 18, 124, 125, 126, 127, 128, 20, 21, + 145, 146, 147, 170, 19, 23, 24, 94, 25, 72, + 73, 172, 140, 141, 142, 143, 144, 113, 177, 176, + 180, 189, 20, 21, 190, 194, 195, 197, 44, 23, + 24, 173, 25, 74, 75, 181, 76, 188, 77, 200, + 78, 162, 79, 80, 198, 81, 82, 171, 99, 156, + 151, 102 }; -static const yytype_int16 yycheck[] = +static const yytype_uint8 yycheck[] = { - 24, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 36, 6, 39, 12, 4, 30, 28, 22, 23, 4, - 15, 147, 46, 68, 12, 24, 49, 18, 16, 155, - 18, 43, 31, 32, 160, 80, 24, 28, 61, 0, - 39, 64, 41, 31, 32, 66, 45, 46, 31, 39, - 77, 39, 43, 41, 39, 68, 39, 45, 46, 58, - 84, 9, 10, 89, 69, 70, 71, 80, 39, 80, - 58, 13, 67, 72, 73, 67, 67, 81, 141, 142, - 79, 80, 81, 12, 72, 73, 11, 16, 28, 77, - 39, 79, 80, 39, 12, 24, 39, 81, 16, 76, - 77, 78, 31, 32, 73, 74, 24, 19, 20, 21, - 39, 23, 41, 31, 32, 139, 45, 46, 54, 55, - 56, 39, 67, 41, 80, 81, 82, 45, 46, 58, - 72, 73, 74, 75, 81, 49, 49, 12, 11, 43, - 58, 68, 39, 72, 73, 67, 8, 145, 77, 24, - 79, 80, 139, 36, 72, 73, 31, 32, 95, 87, - 41, 79, 80, -1, 39, -1, 41, -1, -1, -1, - 45, 46, 57, 58, 59, 60, 61, 75, 76, 77, - 78, 79, -1, 58, 26, 27, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 72, 73, -1, - -1, -1, -1, -1, 79, 80, -1, -1, 50, 51, - -1, 53, -1, 55, -1, 57, -1, 59, 60, -1, - 62, 63 + 25, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 12, 40, 72, 13, 4, 4, 39, 28, 6, 80, + 68, 69, 24, 66, 85, 50, 86, 15, 170, 31, + 32, 30, 43, 49, 12, 22, 23, 39, 16, 41, + 18, 84, 184, 45, 46, 61, 24, 18, 64, 39, + 39, 72, 0, 31, 32, 197, 58, 28, 81, 86, + 72, 39, 70, 41, 39, 86, 71, 45, 46, 94, + 99, 67, 43, 85, 76, 77, 76, 77, 78, 79, + 58, 83, 84, 71, 86, 87, 73, 74, 75, 31, + 12, 164, 165, 67, 16, 9, 10, 39, 76, 77, + 71, 77, 24, 81, 84, 83, 84, 11, 86, 31, + 32, 67, 28, 39, 12, 83, 84, 39, 16, 41, + 76, 77, 87, 45, 46, 87, 24, 19, 20, 21, + 67, 23, 157, 31, 32, 87, 58, 39, 12, 76, + 77, 39, 71, 41, 80, 81, 82, 45, 46, 39, + 24, 64, 65, 66, 76, 77, 67, 31, 32, 81, + 58, 83, 84, 49, 86, 39, 67, 41, 67, 49, + 67, 45, 46, 67, 68, 69, 70, 71, 76, 77, + 90, 91, 92, 11, 58, 83, 84, 43, 86, 26, + 27, 80, 85, 86, 87, 88, 89, 85, 77, 84, + 72, 67, 76, 77, 67, 67, 39, 71, 8, 83, + 84, 72, 86, 50, 51, 168, 53, 172, 55, 198, + 57, 116, 59, 60, 190, 62, 63, 157, 40, 105, + 97, 45 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 30, 83, 84, 85, 86, 87, 0, 66, 12, + 0, 30, 89, 90, 91, 92, 93, 0, 70, 12, 16, 18, 24, 31, 32, 39, 41, 45, 46, 58, - 72, 73, 77, 79, 80, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 105, 108, 109, 110, 111, - 84, 80, 39, 106, 107, 68, 80, 103, 39, 101, - 101, 101, 101, 93, 49, 61, 64, 22, 23, 69, - 70, 71, 26, 27, 50, 51, 53, 55, 57, 59, - 60, 62, 63, 9, 10, 13, 72, 73, 74, 75, - 76, 77, 78, 28, 43, 88, 89, 67, 88, 105, - 4, 39, 110, 4, 39, 67, 39, 77, 81, 93, - 104, 68, 81, 94, 94, 94, 95, 95, 95, 95, - 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 98, 98, 99, 99, 99, 99, 99, 100, 100, 100, - 11, 93, 28, 109, 88, 39, 81, 39, 107, 67, - 81, 49, 49, 31, 39, 90, 91, 11, 104, 96, - 96, 68, 89, 6, 15, 67, 92, 90, 39, 90, - 67, 90 + 76, 77, 81, 83, 84, 86, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 111, 115, 116, 119, + 122, 123, 124, 125, 90, 86, 39, 120, 121, 72, + 86, 117, 39, 107, 107, 107, 107, 67, 76, 77, + 109, 110, 112, 99, 49, 61, 64, 22, 23, 73, + 74, 75, 26, 27, 50, 51, 53, 55, 57, 59, + 60, 62, 63, 9, 10, 13, 76, 77, 78, 79, + 80, 81, 82, 28, 43, 94, 95, 71, 94, 119, + 4, 39, 124, 4, 39, 71, 39, 81, 87, 99, + 118, 72, 80, 85, 67, 67, 66, 84, 77, 84, + 87, 100, 100, 100, 101, 101, 101, 101, 101, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 104, 104, + 105, 105, 105, 105, 105, 106, 106, 106, 11, 99, + 28, 123, 94, 39, 87, 39, 121, 71, 87, 67, + 67, 67, 112, 67, 49, 49, 31, 39, 96, 97, + 11, 118, 80, 72, 85, 113, 84, 77, 102, 102, + 72, 95, 6, 15, 71, 98, 96, 67, 110, 67, + 67, 68, 69, 114, 67, 39, 96, 71, 113, 96, + 114 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 82, 83, 84, 84, 84, 85, 86, 86, 86, - 86, 86, 86, 86, 87, 88, 88, 88, 88, 89, - 90, 90, 90, 90, 91, 91, 91, 92, 92, 93, - 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 97, 97, 97, 98, 98, 98, 99, 99, 99, 99, - 99, 99, 100, 100, 100, 100, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 102, 103, 103, 104, 104, 105, 106, 106, 107, - 107, 107, 108, 108, 109, 109, 109, 109, 110, 110, - 111, 111 + 0, 88, 89, 90, 90, 90, 91, 92, 92, 92, + 92, 92, 92, 92, 93, 94, 94, 94, 94, 95, + 96, 96, 96, 96, 97, 97, 97, 98, 98, 99, + 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 103, 103, 103, 104, 104, 104, 105, 105, 105, 105, + 105, 105, 106, 106, 106, 106, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 108, 109, 109, 110, 110, 110, + 111, 112, 112, 113, 113, 114, 114, 114, 115, 116, + 117, 117, 118, 118, 119, 120, 120, 121, 121, 121, + 122, 122, 123, 123, 123, 123, 124, 124, 125, 125 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -814,9 +845,10 @@ 2, 2, 1, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, - 1, 3, 3, 2, 3, 1, 2, 3, 1, 1, - 2, 3, 3, 1, 1, 1, 3, 2, 1, 4, - 1, 3 + 1, 1, 1, 1, 3, 5, 5, 1, 2, 2, + 3, 5, 7, 2, 0, 1, 1, 0, 5, 3, + 3, 2, 3, 1, 2, 3, 1, 1, 2, 3, + 3, 1, 1, 1, 3, 2, 1, 4, 1, 3 }; @@ -1493,187 +1525,187 @@ switch (yyn) { case 2: -#line 546 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 565 "KDbSqlParser.y" /* yacc.c:1646 */ { //todo: multiple statements //todo: not only "select" statements KDbParserPrivate::get(globalParser)->setStatementType(KDbParser::Select); KDbParserPrivate::get(globalParser)->setQuerySchema((yyvsp[0].querySchema)); } -#line 1504 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1536 "sqlparser.cpp" /* yacc.c:1646 */ break; case 3: -#line 556 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 575 "KDbSqlParser.y" /* yacc.c:1646 */ { //todo: multiple statements } -#line 1512 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1544 "sqlparser.cpp" /* yacc.c:1646 */ break; case 5: -#line 561 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 580 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.querySchema) = (yyvsp[-1].querySchema); } -#line 1520 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1552 "sqlparser.cpp" /* yacc.c:1646 */ break; case 6: -#line 576 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 595 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.querySchema) = (yyvsp[0].querySchema); } -#line 1528 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1560 "sqlparser.cpp" /* yacc.c:1646 */ break; case 7: -#line 675 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 694 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "Select"; if (!((yyval.querySchema) = buildSelectQuery( (yyvsp[0].querySchema), nullptr ))) YYABORT; } -#line 1538 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1570 "sqlparser.cpp" /* yacc.c:1646 */ break; case 8: -#line 681 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 700 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "Select ColViews=" << *(yyvsp[0].exprList); if (!((yyval.querySchema) = buildSelectQuery( (yyvsp[-1].querySchema), (yyvsp[0].exprList) ))) YYABORT; } -#line 1549 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1581 "sqlparser.cpp" /* yacc.c:1646 */ break; case 9: -#line 688 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 707 "KDbSqlParser.y" /* yacc.c:1646 */ { if (!((yyval.querySchema) = buildSelectQuery( (yyvsp[-2].querySchema), (yyvsp[-1].exprList), (yyvsp[0].exprList) ))) YYABORT; } -#line 1558 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1590 "sqlparser.cpp" /* yacc.c:1646 */ break; case 10: -#line 693 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 712 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "Select ColViews Tables"; if (!((yyval.querySchema) = buildSelectQuery( (yyvsp[-1].querySchema), nullptr, (yyvsp[0].exprList) ))) YYABORT; } -#line 1568 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1600 "sqlparser.cpp" /* yacc.c:1646 */ break; case 11: -#line 699 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 718 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "Select ColViews Conditions"; if (!((yyval.querySchema) = buildSelectQuery( (yyvsp[-2].querySchema), (yyvsp[-1].exprList), nullptr, (yyvsp[0].selectOptions) ))) YYABORT; } -#line 1578 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1610 "sqlparser.cpp" /* yacc.c:1646 */ break; case 12: -#line 705 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 724 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "Select Tables SelectOptions"; if (!((yyval.querySchema) = buildSelectQuery( (yyvsp[-2].querySchema), nullptr, (yyvsp[-1].exprList), (yyvsp[0].selectOptions) ))) YYABORT; } -#line 1588 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1620 "sqlparser.cpp" /* yacc.c:1646 */ break; case 13: -#line 711 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 730 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "Select ColViews Tables SelectOptions"; if (!((yyval.querySchema) = buildSelectQuery( (yyvsp[-3].querySchema), (yyvsp[-2].exprList), (yyvsp[-1].exprList), (yyvsp[0].selectOptions) ))) YYABORT; } -#line 1598 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1630 "sqlparser.cpp" /* yacc.c:1646 */ break; case 14: -#line 720 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 739 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "SELECT"; (yyval.querySchema) = KDbParserPrivate::get(globalParser)->createQuery(); } -#line 1607 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1639 "sqlparser.cpp" /* yacc.c:1646 */ break; case 15: -#line 728 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 747 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "WhereClause"; (yyval.selectOptions) = new SelectOptionsInternal; (yyval.selectOptions)->whereExpr = *(yyvsp[0].expr); delete (yyvsp[0].expr); } -#line 1618 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1650 "sqlparser.cpp" /* yacc.c:1646 */ break; case 16: -#line 735 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 754 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "OrderByClause"; (yyval.selectOptions) = new SelectOptionsInternal; (yyval.selectOptions)->orderByColumns = (yyvsp[0].orderByColumns); } -#line 1628 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1660 "sqlparser.cpp" /* yacc.c:1646 */ break; case 17: -#line 741 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 760 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "WhereClause ORDER BY OrderByClause"; (yyval.selectOptions) = new SelectOptionsInternal; (yyval.selectOptions)->whereExpr = *(yyvsp[-3].expr); delete (yyvsp[-3].expr); (yyval.selectOptions)->orderByColumns = (yyvsp[0].orderByColumns); } -#line 1640 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1672 "sqlparser.cpp" /* yacc.c:1646 */ break; case 18: -#line 749 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 768 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "OrderByClause WhereClause"; (yyval.selectOptions) = new SelectOptionsInternal; (yyval.selectOptions)->whereExpr = *(yyvsp[0].expr); delete (yyvsp[0].expr); (yyval.selectOptions)->orderByColumns = (yyvsp[-1].orderByColumns); } -#line 1652 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1684 "sqlparser.cpp" /* yacc.c:1646 */ break; case 19: -#line 760 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 779 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[0].expr); } -#line 1660 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1692 "sqlparser.cpp" /* yacc.c:1646 */ break; case 20: -#line 769 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 788 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "ORDER BY IDENTIFIER"; (yyval.orderByColumns) = new QList; OrderByColumnInternal orderByColumn; orderByColumn.setColumnByNameOrNumber( *(yyvsp[0].variantValue) ); (yyval.orderByColumns)->append( orderByColumn ); delete (yyvsp[0].variantValue); } -#line 1673 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1705 "sqlparser.cpp" /* yacc.c:1646 */ break; case 21: -#line 778 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 797 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "ORDER BY IDENTIFIER OrderByOption"; (yyval.orderByColumns) = new QList; @@ -1683,233 +1715,233 @@ (yyval.orderByColumns)->append( orderByColumn ); delete (yyvsp[-1].variantValue); } -#line 1687 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1719 "sqlparser.cpp" /* yacc.c:1646 */ break; case 22: -#line 788 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 807 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.orderByColumns) = (yyvsp[0].orderByColumns); OrderByColumnInternal orderByColumn; orderByColumn.setColumnByNameOrNumber( *(yyvsp[-2].variantValue) ); (yyval.orderByColumns)->append( orderByColumn ); delete (yyvsp[-2].variantValue); } -#line 1699 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1731 "sqlparser.cpp" /* yacc.c:1646 */ break; case 23: -#line 796 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 815 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.orderByColumns) = (yyvsp[0].orderByColumns); OrderByColumnInternal orderByColumn; orderByColumn.setColumnByNameOrNumber( *(yyvsp[-3].variantValue) ); orderByColumn.order = (yyvsp[-2].sortOrderValue); (yyval.orderByColumns)->append( orderByColumn ); delete (yyvsp[-3].variantValue); } -#line 1712 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1744 "sqlparser.cpp" /* yacc.c:1646 */ break; case 24: -#line 808 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 827 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.variantValue) = new QVariant( *(yyvsp[0].stringValue) ); sqlParserDebug() << "OrderByColumnId: " << *(yyval.variantValue); delete (yyvsp[0].stringValue); } -#line 1722 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1754 "sqlparser.cpp" /* yacc.c:1646 */ break; case 25: -#line 814 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 833 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.variantValue) = new QVariant( *(yyvsp[-2].stringValue) + QLatin1Char('.') + *(yyvsp[0].stringValue) ); sqlParserDebug() << "OrderByColumnId: " << *(yyval.variantValue); delete (yyvsp[-2].stringValue); delete (yyvsp[0].stringValue); } -#line 1733 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1765 "sqlparser.cpp" /* yacc.c:1646 */ break; case 26: -#line 821 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 840 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.variantValue) = new QVariant((yyvsp[0].integerValue)); sqlParserDebug() << "OrderByColumnId: " << *(yyval.variantValue); } -#line 1742 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1774 "sqlparser.cpp" /* yacc.c:1646 */ break; case 27: -#line 828 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 847 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.sortOrderValue) = KDbOrderByColumn::SortOrder::Ascending; } -#line 1750 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1782 "sqlparser.cpp" /* yacc.c:1646 */ break; case 28: -#line 832 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 851 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.sortOrderValue) = KDbOrderByColumn::SortOrder::Descending; } -#line 1758 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1790 "sqlparser.cpp" /* yacc.c:1646 */ break; case 30: -#line 844 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 863 "KDbSqlParser.y" /* yacc.c:1646 */ { // sqlParserDebug() << "AND " << $3.debugString(); (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::AND, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1769 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1801 "sqlparser.cpp" /* yacc.c:1646 */ break; case 31: -#line 851 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 870 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::OR, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1779 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1811 "sqlparser.cpp" /* yacc.c:1646 */ break; case 32: -#line 857 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 876 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::XOR, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1789 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1821 "sqlparser.cpp" /* yacc.c:1646 */ break; case 34: -#line 869 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 888 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '>', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1799 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1831 "sqlparser.cpp" /* yacc.c:1646 */ break; case 35: -#line 875 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 894 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::GREATER_OR_EQUAL, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1809 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1841 "sqlparser.cpp" /* yacc.c:1646 */ break; case 36: -#line 881 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 900 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '<', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1819 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1851 "sqlparser.cpp" /* yacc.c:1646 */ break; case 37: -#line 887 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 906 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::LESS_OR_EQUAL, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1829 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1861 "sqlparser.cpp" /* yacc.c:1646 */ break; case 38: -#line 893 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 912 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '=', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1839 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1871 "sqlparser.cpp" /* yacc.c:1646 */ break; case 40: -#line 905 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 924 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::NOT_EQUAL, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1849 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1881 "sqlparser.cpp" /* yacc.c:1646 */ break; case 41: -#line 911 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 930 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::NOT_EQUAL2, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1859 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1891 "sqlparser.cpp" /* yacc.c:1646 */ break; case 42: -#line 917 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 936 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::LIKE, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1869 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1901 "sqlparser.cpp" /* yacc.c:1646 */ break; case 43: -#line 923 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 942 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::NOT_LIKE, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1879 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1911 "sqlparser.cpp" /* yacc.c:1646 */ break; case 44: -#line 929 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 948 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::SQL_IN, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1889 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1921 "sqlparser.cpp" /* yacc.c:1646 */ break; case 45: -#line 935 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 954 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::SIMILAR_TO, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1899 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1931 "sqlparser.cpp" /* yacc.c:1646 */ break; case 46: -#line 941 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 960 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::NOT_SIMILAR_TO, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1909 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1941 "sqlparser.cpp" /* yacc.c:1646 */ break; case 47: -#line 947 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 966 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbNArgExpression(KDb::RelationalExpression, KDbToken::BETWEEN_AND); (yyval.expr)->toNArg().append( *(yyvsp[-4].expr) ); @@ -1919,11 +1951,11 @@ delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1923 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1955 "sqlparser.cpp" /* yacc.c:1646 */ break; case 48: -#line 957 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 976 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbNArgExpression(KDb::RelationalExpression, KDbToken::NOT_BETWEEN_AND); (yyval.expr)->toNArg().append( *(yyvsp[-4].expr) ); @@ -1933,246 +1965,246 @@ delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1937 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1969 "sqlparser.cpp" /* yacc.c:1646 */ break; case 50: -#line 973 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 992 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbUnaryExpression( KDbToken::SQL_IS_NULL, *(yyvsp[-1].expr) ); delete (yyvsp[-1].expr); } -#line 1946 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1978 "sqlparser.cpp" /* yacc.c:1646 */ break; case 51: -#line 978 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 997 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbUnaryExpression( KDbToken::SQL_IS_NOT_NULL, *(yyvsp[-1].expr) ); delete (yyvsp[-1].expr); } -#line 1955 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1987 "sqlparser.cpp" /* yacc.c:1646 */ break; case 53: -#line 989 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1008 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::BITWISE_SHIFT_LEFT, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1965 "sqlparser.cpp" /* yacc.c:1646 */ +#line 1997 "sqlparser.cpp" /* yacc.c:1646 */ break; case 54: -#line 995 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1014 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::BITWISE_SHIFT_RIGHT, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1975 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2007 "sqlparser.cpp" /* yacc.c:1646 */ break; case 56: -#line 1007 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1026 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '+', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1985 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2017 "sqlparser.cpp" /* yacc.c:1646 */ break; case 57: -#line 1013 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1032 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), KDbToken::CONCATENATION, *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 1995 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2027 "sqlparser.cpp" /* yacc.c:1646 */ break; case 58: -#line 1019 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1038 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '-', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 2005 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2037 "sqlparser.cpp" /* yacc.c:1646 */ break; case 59: -#line 1025 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1044 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '&', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 2015 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2047 "sqlparser.cpp" /* yacc.c:1646 */ break; case 60: -#line 1031 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1050 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '|', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 2025 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2057 "sqlparser.cpp" /* yacc.c:1646 */ break; case 62: -#line 1043 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1062 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '/', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 2035 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2067 "sqlparser.cpp" /* yacc.c:1646 */ break; case 63: -#line 1049 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1068 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '*', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 2045 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2077 "sqlparser.cpp" /* yacc.c:1646 */ break; case 64: -#line 1055 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1074 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression(*(yyvsp[-2].expr), '%', *(yyvsp[0].expr)); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 2055 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2087 "sqlparser.cpp" /* yacc.c:1646 */ break; case 66: -#line 1068 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1087 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbUnaryExpression( '-', *(yyvsp[0].expr) ); delete (yyvsp[0].expr); } -#line 2064 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2096 "sqlparser.cpp" /* yacc.c:1646 */ break; case 67: -#line 1073 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1092 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbUnaryExpression( '+', *(yyvsp[0].expr) ); delete (yyvsp[0].expr); } -#line 2073 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2105 "sqlparser.cpp" /* yacc.c:1646 */ break; case 68: -#line 1078 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1097 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbUnaryExpression( '~', *(yyvsp[0].expr) ); delete (yyvsp[0].expr); } -#line 2082 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2114 "sqlparser.cpp" /* yacc.c:1646 */ break; case 69: -#line 1083 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1102 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbUnaryExpression( KDbToken::NOT, *(yyvsp[0].expr) ); delete (yyvsp[0].expr); } -#line 2091 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2123 "sqlparser.cpp" /* yacc.c:1646 */ break; case 70: -#line 1088 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1107 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbVariableExpression( *(yyvsp[0].stringValue) ); //! @todo simplify this later if that's 'only one field name' expression sqlParserDebug() << " + identifier: " << *(yyvsp[0].stringValue); delete (yyvsp[0].stringValue); } -#line 2103 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2135 "sqlparser.cpp" /* yacc.c:1646 */ break; case 71: -#line 1096 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1115 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbQueryParameterExpression( *(yyvsp[0].stringValue) ); sqlParserDebug() << " + query parameter:" << *(yyval.expr); delete (yyvsp[0].stringValue); } -#line 2113 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2145 "sqlparser.cpp" /* yacc.c:1646 */ break; case 72: -#line 1102 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1121 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << " + function:" << *(yyvsp[-1].stringValue) << "(" << *(yyvsp[0].exprList) << ")"; (yyval.expr) = new KDbFunctionExpression(*(yyvsp[-1].stringValue), *(yyvsp[0].exprList)); delete (yyvsp[-1].stringValue); delete (yyvsp[0].exprList); } -#line 2124 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2156 "sqlparser.cpp" /* yacc.c:1646 */ break; case 73: -#line 1110 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1129 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbVariableExpression( *(yyvsp[-2].stringValue) + QLatin1Char('.') + *(yyvsp[0].stringValue) ); sqlParserDebug() << " + identifier.identifier:" << *(yyvsp[-2].stringValue) << "." << *(yyvsp[0].stringValue); delete (yyvsp[-2].stringValue); delete (yyvsp[0].stringValue); } -#line 2135 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2167 "sqlparser.cpp" /* yacc.c:1646 */ break; case 74: -#line 1117 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1136 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbConstExpression( KDbToken::SQL_NULL, QVariant() ); sqlParserDebug() << " + NULL"; // $$ = new KDbField(); //$$->setName(QString::null); } -#line 2146 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2178 "sqlparser.cpp" /* yacc.c:1646 */ break; case 75: -#line 1124 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1143 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbConstExpression( KDbToken::SQL_TRUE, true ); } -#line 2154 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2186 "sqlparser.cpp" /* yacc.c:1646 */ break; case 76: -#line 1128 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1147 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbConstExpression( KDbToken::SQL_FALSE, false ); } -#line 2162 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2194 "sqlparser.cpp" /* yacc.c:1646 */ break; case 77: -#line 1132 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1151 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbConstExpression( KDbToken::CHARACTER_STRING_LITERAL, *(yyvsp[0].stringValue) ); sqlParserDebug() << " + constant " << (yyvsp[0].stringValue); delete (yyvsp[0].stringValue); } -#line 2172 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2204 "sqlparser.cpp" /* yacc.c:1646 */ break; case 78: -#line 1138 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1157 "KDbSqlParser.y" /* yacc.c:1646 */ { QVariant val; if ((yyvsp[0].integerValue) <= INT_MAX && (yyvsp[0].integerValue) >= INT_MIN) @@ -2189,95 +2221,273 @@ (yyval.expr) = new KDbConstExpression( KDbToken::INTEGER_CONST, val ); sqlParserDebug() << " + int constant: " << val.toString(); } -#line 2193 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2225 "sqlparser.cpp" /* yacc.c:1646 */ break; case 79: -#line 1155 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1174 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbConstExpression( KDbToken::REAL_CONST, *(yyvsp[0].binaryValue) ); sqlParserDebug() << " + real constant: " << *(yyvsp[0].binaryValue); delete (yyvsp[0].binaryValue); } -#line 2203 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2235 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 80: +#line 1180 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.expr) = new KDbConstExpression(KDbToken::DATE_CONST, QVariant::fromValue(*(yyvsp[0].dateValue))); + sqlParserDebug() << " + date constant:" << *(yyvsp[0].dateValue); + delete (yyvsp[0].dateValue); +} +#line 2245 "sqlparser.cpp" /* yacc.c:1646 */ break; case 81: -#line 1167 "KDbSqlParser.y" /* yacc.c:1646 */ +#line 1186 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.expr) = new KDbConstExpression(KDbToken::TIME_CONST, QVariant::fromValue(*(yyvsp[0].timeValue))); + sqlParserDebug() << " + time constant:" << *(yyvsp[0].timeValue); + delete (yyvsp[0].timeValue); +} +#line 2255 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 82: +#line 1192 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.expr) = new KDbConstExpression(KDbToken::DATETIME_CONST, QVariant::fromValue(*(yyvsp[0].dateTimeValue))); + sqlParserDebug() << " + datetime constant:" << *(yyvsp[0].dateTimeValue); + delete (yyvsp[0].dateTimeValue); +} +#line 2265 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 84: +#line 1203 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.dateValue) = (yyvsp[-1].dateValue); + sqlParserDebug() << "DateConst:" << *(yyval.dateValue); +} +#line 2274 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 85: +#line 1211 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.dateValue) = new KDbDate(*(yyvsp[-4].yearValue), *(yyvsp[-2].binaryValue), *(yyvsp[0].binaryValue)); + sqlParserDebug() << "DateValue:" << *(yyval.dateValue); + delete (yyvsp[-4].yearValue); + delete (yyvsp[-2].binaryValue); + delete (yyvsp[0].binaryValue); +} +#line 2286 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 86: +#line 1219 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.dateValue) = new KDbDate(*(yyvsp[0].yearValue), *(yyvsp[-4].binaryValue), *(yyvsp[-2].binaryValue)); + sqlParserDebug() << "DateValue:" << *(yyval.dateValue); + delete (yyvsp[-4].binaryValue); + delete (yyvsp[-2].binaryValue); + delete (yyvsp[0].yearValue); +} +#line 2298 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 87: +#line 1230 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.yearValue) = new KDbYear(KDbYear::Sign::None, *(yyvsp[0].binaryValue)); + sqlParserDebug() << "YearConst:" << *(yyval.yearValue); + delete (yyvsp[0].binaryValue); +} +#line 2308 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 88: +#line 1236 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.yearValue) = new KDbYear(KDbYear::Sign::Plus, *(yyvsp[0].binaryValue)); + sqlParserDebug() << "YearConst:" << *(yyval.yearValue); + delete (yyvsp[0].binaryValue); +} +#line 2318 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 89: +#line 1242 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.yearValue) = new KDbYear(KDbYear::Sign::Minus, *(yyvsp[0].binaryValue)); + sqlParserDebug() << "YearConst:" << *(yyval.yearValue); + delete (yyvsp[0].binaryValue); +} +#line 2328 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 90: +#line 1251 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.timeValue) = (yyvsp[-1].timeValue); + sqlParserDebug() << "TimeConst:" << *(yyval.timeValue); +} +#line 2337 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 91: +#line 1259 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.timeValue) = new KDbTime(*(yyvsp[-4].binaryValue), *(yyvsp[-2].binaryValue), {}, *(yyvsp[-1].binaryValue), (yyvsp[0].timePeriodValue)); + sqlParserDebug() << "TimeValue:" << *(yyval.timeValue); + delete (yyvsp[-4].binaryValue); + delete (yyvsp[-2].binaryValue); + delete (yyvsp[-1].binaryValue); +} +#line 2349 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 92: +#line 1267 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.timeValue) = new KDbTime(*(yyvsp[-6].binaryValue), *(yyvsp[-4].binaryValue), *(yyvsp[-2].binaryValue), *(yyvsp[-1].binaryValue), (yyvsp[0].timePeriodValue)); + sqlParserDebug() << "TimeValue:" << *(yyval.timeValue); + delete (yyvsp[-6].binaryValue); + delete (yyvsp[-4].binaryValue); + delete (yyvsp[-2].binaryValue); + delete (yyvsp[-1].binaryValue); +} +#line 2362 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 93: +#line 1279 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.binaryValue) = (yyvsp[0].binaryValue); +} +#line 2370 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 94: +#line 1283 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.binaryValue) = new QByteArray; +} +#line 2378 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 95: +#line 1290 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.timePeriodValue) = KDbTime::Period::Am; +} +#line 2386 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 96: +#line 1294 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.timePeriodValue) = KDbTime::Period::Pm; +} +#line 2394 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 97: +#line 1298 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.timePeriodValue) = KDbTime::Period::None; +} +#line 2402 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 98: +#line 1305 "KDbSqlParser.y" /* yacc.c:1646 */ + { + (yyval.dateTimeValue) = new KDbDateTime(*(yyvsp[-3].dateValue), *(yyvsp[-1].timeValue)); + sqlParserDebug() << "DateTimeConst:" << *(yyval.dateTimeValue); + delete (yyvsp[-3].dateValue); + delete (yyvsp[-1].timeValue); +} +#line 2413 "sqlparser.cpp" /* yacc.c:1646 */ + break; + + case 99: +#line 1315 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "(expr)"; (yyval.expr) = new KDbUnaryExpression('(', *(yyvsp[-1].expr)); delete (yyvsp[-1].expr); } -#line 2213 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2423 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 82: -#line 1176 "KDbSqlParser.y" /* yacc.c:1646 */ + case 100: +#line 1324 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = (yyvsp[-1].exprList); } -#line 2221 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2431 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 83: -#line 1180 "KDbSqlParser.y" /* yacc.c:1646 */ + case 101: +#line 1328 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = new KDbNArgExpression(KDb::ArgumentListExpression, ','); } -#line 2229 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2439 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 84: -#line 1187 "KDbSqlParser.y" /* yacc.c:1646 */ + case 102: +#line 1335 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = (yyvsp[0].exprList); (yyval.exprList)->prepend( *(yyvsp[-2].expr) ); delete (yyvsp[-2].expr); } -#line 2239 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2449 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 85: -#line 1193 "KDbSqlParser.y" /* yacc.c:1646 */ + case 103: +#line 1341 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = new KDbNArgExpression(KDb::ArgumentListExpression, ','); (yyval.exprList)->append( *(yyvsp[0].expr) ); delete (yyvsp[0].expr); } -#line 2249 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2459 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 86: -#line 1202 "KDbSqlParser.y" /* yacc.c:1646 */ + case 104: +#line 1350 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = (yyvsp[0].exprList); } -#line 2257 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2467 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 87: -#line 1247 "KDbSqlParser.y" /* yacc.c:1646 */ + case 105: +#line 1395 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = (yyvsp[-2].exprList); (yyval.exprList)->append(*(yyvsp[0].expr)); delete (yyvsp[0].expr); } -#line 2267 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2477 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 88: -#line 1253 "KDbSqlParser.y" /* yacc.c:1646 */ + case 106: +#line 1401 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = new KDbNArgExpression(KDb::TableListExpression, KDbToken::IDENTIFIER); //ok? (yyval.exprList)->append(*(yyvsp[0].expr)); delete (yyvsp[0].expr); } -#line 2277 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2487 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 89: -#line 1262 "KDbSqlParser.y" /* yacc.c:1646 */ + case 107: +#line 1410 "KDbSqlParser.y" /* yacc.c:1646 */ { sqlParserDebug() << "FROM: '" << *(yyvsp[0].stringValue) << "'"; (yyval.expr) = new KDbVariableExpression(*(yyvsp[0].stringValue)); @@ -2305,11 +2515,11 @@ }*/ delete (yyvsp[0].stringValue); } -#line 2309 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2519 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 90: -#line 1290 "KDbSqlParser.y" /* yacc.c:1646 */ + case 108: +#line 1438 "KDbSqlParser.y" /* yacc.c:1646 */ { //table + alias (yyval.expr) = new KDbBinaryExpression( @@ -2319,11 +2529,11 @@ delete (yyvsp[-1].stringValue); delete (yyvsp[0].stringValue); } -#line 2323 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2533 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 91: -#line 1300 "KDbSqlParser.y" /* yacc.c:1646 */ + case 109: +#line 1448 "KDbSqlParser.y" /* yacc.c:1646 */ { //table + alias (yyval.expr) = new KDbBinaryExpression( @@ -2333,55 +2543,55 @@ delete (yyvsp[-2].stringValue); delete (yyvsp[0].stringValue); } -#line 2337 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2547 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 92: -#line 1315 "KDbSqlParser.y" /* yacc.c:1646 */ + case 110: +#line 1463 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = (yyvsp[-2].exprList); (yyval.exprList)->append(*(yyvsp[0].expr)); delete (yyvsp[0].expr); sqlParserDebug() << "ColViews: ColViews , ColItem"; } -#line 2348 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2558 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 93: -#line 1322 "KDbSqlParser.y" /* yacc.c:1646 */ + case 111: +#line 1470 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.exprList) = new KDbNArgExpression(KDb::FieldListExpression, KDbToken()); (yyval.exprList)->append(*(yyvsp[0].expr)); delete (yyvsp[0].expr); sqlParserDebug() << "ColViews: ColItem"; } -#line 2359 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2569 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 94: -#line 1332 "KDbSqlParser.y" /* yacc.c:1646 */ + case 112: +#line 1480 "KDbSqlParser.y" /* yacc.c:1646 */ { // $$ = new KDbField(); // dummy->addField($$); // $$->setExpression( $1 ); // globalParser->query()->addField($$); (yyval.expr) = (yyvsp[0].expr); sqlParserDebug() << " added column expr:" << *(yyvsp[0].expr); } -#line 2372 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2582 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 95: -#line 1341 "KDbSqlParser.y" /* yacc.c:1646 */ + case 113: +#line 1489 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[0].expr); sqlParserDebug() << " added column wildcard:" << *(yyvsp[0].expr); } -#line 2381 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2591 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 96: -#line 1346 "KDbSqlParser.y" /* yacc.c:1646 */ + case 114: +#line 1494 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression( *(yyvsp[-2].expr), KDbToken::AS, @@ -2391,11 +2601,11 @@ delete (yyvsp[-2].expr); delete (yyvsp[0].stringValue); } -#line 2395 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2605 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 97: -#line 1356 "KDbSqlParser.y" /* yacc.c:1646 */ + case 115: +#line 1504 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbBinaryExpression( *(yyvsp[-1].expr), KDbToken::AS_EMPTY, @@ -2405,54 +2615,54 @@ delete (yyvsp[-1].expr); delete (yyvsp[0].stringValue); } -#line 2409 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2619 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 98: -#line 1369 "KDbSqlParser.y" /* yacc.c:1646 */ + case 116: +#line 1517 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[0].expr); } -#line 2417 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2627 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 99: -#line 1415 "KDbSqlParser.y" /* yacc.c:1646 */ + case 117: +#line 1563 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[-1].expr); //! @todo DISTINCT '(' ColExpression ')' // $$->setName("DISTINCT(" + $3->name() + ")"); } -#line 2427 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2637 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 100: -#line 1424 "KDbSqlParser.y" /* yacc.c:1646 */ + case 118: +#line 1572 "KDbSqlParser.y" /* yacc.c:1646 */ { (yyval.expr) = new KDbVariableExpression(QLatin1String("*")); sqlParserDebug() << "all columns"; // KDbQueryAsterisk *ast = new KDbQueryAsterisk(globalParser->query(), dummy); // globalParser->query()->addAsterisk(ast); // requiresTable = true; } -#line 2440 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2650 "sqlparser.cpp" /* yacc.c:1646 */ break; - case 101: -#line 1433 "KDbSqlParser.y" /* yacc.c:1646 */ + case 119: +#line 1581 "KDbSqlParser.y" /* yacc.c:1646 */ { QString s( *(yyvsp[-2].stringValue) ); s += QLatin1String(".*"); (yyval.expr) = new KDbVariableExpression(s); sqlParserDebug() << " + all columns from " << s; delete (yyvsp[-2].stringValue); } -#line 2452 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2662 "sqlparser.cpp" /* yacc.c:1646 */ break; -#line 2456 "sqlparser.cpp" /* yacc.c:1646 */ +#line 2666 "sqlparser.cpp" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2680,7 +2890,7 @@ #endif return yyresult; } -#line 1448 "KDbSqlParser.y" /* yacc.c:1906 */ +#line 1596 "KDbSqlParser.y" /* yacc.c:1906 */ KDB_TESTING_EXPORT const char* g_tokenName(unsigned int offset) { diff --git a/src/parser/generated/sqlscanner.cpp b/src/parser/generated/sqlscanner.cpp --- a/src/parser/generated/sqlscanner.cpp +++ b/src/parser/generated/sqlscanner.cpp @@ -364,54 +364,57 @@ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 48 -#define YY_END_OF_BUFFER 49 +#define YY_NUM_RULES 55 +#define YY_END_OF_BUFFER 56 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[177] = +static yyconst flex_int16_t yy_accept[192] = { 0, - 0, 0, 49, 48, 46, 47, 48, 47, 47, 48, - 47, 7, 47, 47, 47, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 47, 47, 46, 2, 0, 43, 0, 9, 0, - 43, 0, 8, 8, 7, 44, 32, 4, 1, 3, - 5, 33, 44, 10, 44, 40, 44, 44, 44, 44, - 6, 25, 44, 44, 44, 44, 44, 29, 30, 44, - 44, 44, 44, 44, 44, 44, 0, 31, 43, 43, - 8, 9, 41, 44, 44, 44, 44, 44, 44, 0, - 44, 44, 44, 24, 44, 44, 44, 44, 44, 44, - - 44, 44, 34, 45, 44, 44, 42, 44, 12, 44, - 0, 14, 15, 16, 0, 26, 44, 44, 44, 44, - 44, 27, 44, 44, 44, 28, 44, 0, 0, 0, - 0, 0, 39, 35, 44, 44, 37, 38, 44, 11, - 44, 0, 0, 0, 0, 0, 36, 44, 18, 13, - 0, 23, 0, 0, 0, 44, 0, 0, 17, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, - 19, 0, 0, 0, 20, 0 + 0, 0, 0, 0, 56, 55, 53, 54, 55, 9, + 54, 54, 55, 54, 7, 54, 54, 54, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 54, 54, 12, 15, 10, 11, + 55, 55, 53, 2, 0, 50, 0, 16, 0, 50, + 0, 8, 8, 7, 51, 39, 4, 1, 3, 5, + 40, 51, 17, 51, 47, 51, 51, 51, 51, 6, + 32, 51, 51, 51, 51, 51, 36, 37, 51, 51, + 51, 51, 51, 51, 51, 0, 38, 12, 0, 0, + 11, 13, 14, 50, 50, 8, 16, 48, 51, 51, + + 51, 51, 51, 51, 0, 51, 51, 51, 31, 51, + 51, 51, 51, 51, 51, 51, 51, 41, 52, 51, + 51, 49, 51, 19, 51, 0, 21, 22, 23, 0, + 33, 51, 51, 51, 51, 51, 34, 51, 51, 51, + 35, 51, 0, 0, 0, 0, 0, 46, 42, 51, + 51, 44, 45, 51, 18, 51, 0, 0, 0, 0, + 0, 43, 51, 25, 20, 0, 30, 0, 0, 0, + 51, 0, 0, 24, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 28, 29, 26, 0, 0, 0, 27, + 0 + } ; static yyconst flex_int32_t yy_ec[256] = { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 3, 4, 5, 1, 5, 6, 7, 5, - 5, 5, 5, 5, 5, 8, 5, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 5, 5, 10, - 11, 12, 5, 5, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 28, 29, 30, 31, 32, 28, 33, 34, 35, 28, - 36, 37, 38, 5, 28, 5, 39, 40, 41, 42, - - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 28, 28, 54, 55, 56, 57, 28, 58, 59, - 60, 28, 1, 61, 1, 5, 1, 1, 1, 1, + 1, 2, 4, 5, 6, 1, 7, 8, 9, 7, + 7, 7, 10, 7, 10, 11, 10, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 10, 7, 13, + 14, 15, 7, 7, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 32, 37, 38, 39, 32, + 40, 41, 42, 7, 32, 7, 43, 44, 45, 46, + + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 32, 59, 60, 61, 62, 32, 63, 64, + 65, 32, 1, 66, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -428,181 +431,203 @@ 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[62] = +static yyconst flex_int32_t yy_meta[67] = { 0, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 3, 1, 3, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, + 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1 + 2, 2, 2, 2, 2, 1 } ; -static yyconst flex_int16_t yy_base[181] = +static yyconst flex_int16_t yy_base[197] = { 0, - 0, 0, 431, 441, 428, 418, 58, 441, 422, 56, - 418, 56, 56, 415, 58, 64, 63, 67, 65, 417, - 68, 75, 76, 70, 101, 110, 78, 94, 118, 92, - 116, 0, 363, 421, 441, 73, 418, 116, 441, 67, - 414, 107, 411, 410, 80, 410, 441, 441, 441, 441, - 441, 441, 124, 127, 140, 409, 138, 137, 126, 148, - 143, 77, 144, 141, 155, 152, 153, 408, 171, 165, - 162, 172, 174, 185, 181, 182, 377, 441, 190, 188, - 405, 404, 403, 197, 194, 207, 198, 201, 221, 214, - 192, 212, 224, 229, 211, 237, 226, 239, 241, 249, - - 242, 250, 402, 441, 243, 261, 401, 257, 400, 262, - 244, 397, 396, 393, 281, 391, 255, 267, 279, 269, - 295, 389, 298, 305, 308, 388, 310, 258, 278, 291, - 303, 305, 386, 384, 302, 322, 382, 378, 321, 376, - 331, 381, 313, 301, 317, 317, 283, 335, 270, 231, - 343, 441, 313, 327, 328, 288, 322, 338, 441, 332, - 357, 341, 350, 359, 347, 352, 351, 333, 441, 441, - 441, 219, 376, 353, 441, 441, 432, 435, 90, 438 + 0, 0, 65, 66, 484, 515, 67, 469, 69, 515, + 515, 474, 64, 469, 68, 70, 466, 72, 77, 78, + 79, 80, 467, 83, 84, 90, 108, 118, 120, 110, + 140, 119, 91, 128, 0, 410, 134, 515, 515, 463, + 117, 118, 90, 515, 152, 469, 158, 515, 147, 464, + 157, 460, 459, 92, 459, 515, 515, 515, 515, 515, + 515, 163, 172, 159, 458, 175, 170, 157, 178, 186, + 199, 189, 185, 192, 194, 196, 457, 205, 203, 204, + 208, 215, 217, 223, 216, 425, 515, 240, 184, 209, + 454, 515, 515, 233, 232, 453, 453, 451, 243, 246, + + 249, 235, 233, 257, 263, 261, 265, 267, 282, 270, + 271, 285, 290, 288, 275, 296, 292, 446, 515, 300, + 298, 444, 302, 439, 312, 291, 438, 437, 436, 328, + 435, 317, 325, 345, 327, 321, 427, 346, 347, 353, + 335, 354, 309, 288, 332, 345, 347, 329, 294, 364, + 367, 237, 160, 366, 158, 369, 382, 360, 354, 365, + 364, 156, 393, 111, 104, 403, 515, 360, 383, 383, + 406, 375, 392, 515, 386, 418, 389, 404, 411, 399, + 404, 404, 402, 515, 515, 515, 439, 442, 406, 515, + 515, 503, 506, 509, 105, 512 + } ; -static yyconst flex_int16_t yy_def[181] = +static yyconst flex_int16_t yy_def[197] = { 0, - 176, 1, 176, 176, 176, 176, 177, 176, 176, 178, - 176, 179, 176, 176, 176, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 180, 176, 176, 176, 177, 176, 177, 176, 178, - 176, 178, 176, 176, 179, 179, 176, 176, 176, 176, - 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 180, 176, 177, 178, - 176, 179, 179, 179, 179, 179, 179, 179, 179, 176, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - - 179, 179, 179, 176, 179, 179, 179, 179, 179, 179, - 176, 179, 179, 179, 176, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 176, 176, 176, - 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 176, 176, 176, 176, 176, 179, 179, 179, 179, - 176, 176, 176, 176, 176, 179, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 0, 176, 176, 176, 176 + 191, 1, 192, 192, 191, 191, 191, 191, 193, 191, + 191, 191, 194, 191, 195, 191, 191, 191, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 196, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 193, 191, 193, 191, 194, 191, + 194, 191, 191, 195, 195, 191, 191, 191, 191, 191, + 191, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 196, 191, 191, 191, 191, + 191, 191, 191, 193, 194, 191, 195, 195, 195, 195, + + 195, 195, 195, 195, 191, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 191, 195, + 195, 195, 195, 195, 195, 191, 195, 195, 195, 191, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 191, 191, 191, 191, 191, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 191, 191, 191, 191, + 191, 195, 195, 195, 195, 191, 191, 191, 191, 191, + 195, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 0, 191, 191, 191, 191, 191 + } ; -static yyconst flex_int16_t yy_nxt[503] = +static yyconst flex_int16_t yy_nxt[582] = { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 20, 20, - 22, 23, 20, 24, 20, 25, 26, 20, 27, 28, - 29, 20, 30, 31, 20, 32, 4, 8, 16, 17, - 18, 19, 20, 21, 20, 20, 22, 23, 20, 24, - 20, 25, 26, 27, 28, 29, 20, 30, 31, 20, - 33, 37, 41, 44, 45, 47, 48, 49, 51, 52, - 176, 176, 176, 41, 176, 176, 37, 176, 90, 55, - 59, 58, 176, 176, 176, 176, 64, 44, 45, 53, - 65, 46, 42, 54, 38, 57, 60, 56, 70, 176, - - 61, 176, 63, 42, 62, 55, 59, 58, 176, 38, - 71, 75, 64, 80, 72, 53, 65, 176, 54, 79, - 57, 60, 56, 176, 70, 176, 61, 66, 63, 62, - 73, 176, 67, 176, 176, 68, 71, 75, 69, 82, - 72, 83, 76, 42, 176, 176, 74, 176, 176, 87, - 176, 176, 38, 66, 85, 176, 73, 67, 92, 176, - 176, 68, 176, 69, 91, 82, 86, 83, 76, 176, - 84, 74, 176, 89, 88, 87, 95, 93, 176, 176, - 85, 176, 94, 97, 92, 98, 96, 100, 176, 176, - 91, 86, 176, 79, 80, 84, 99, 102, 89, 176, - - 88, 176, 95, 93, 176, 176, 106, 94, 176, 97, - 103, 98, 96, 100, 176, 90, 101, 112, 176, 176, - 173, 107, 99, 102, 42, 109, 38, 108, 176, 105, - 115, 176, 106, 176, 116, 103, 176, 110, 176, 111, - 114, 101, 113, 112, 176, 118, 176, 107, 176, 176, - 176, 109, 108, 117, 105, 119, 176, 176, 122, 124, - 116, 120, 176, 110, 176, 111, 114, 113, 176, 176, - 128, 118, 121, 126, 176, 129, 176, 176, 123, 117, - 127, 119, 115, 133, 122, 124, 176, 120, 142, 161, - 176, 125, 136, 135, 130, 176, 128, 134, 121, 126, - - 129, 143, 176, 123, 131, 176, 127, 144, 133, 176, - 132, 137, 176, 142, 138, 176, 125, 176, 136, 135, - 130, 139, 134, 145, 140, 146, 141, 143, 176, 176, - 131, 153, 147, 144, 148, 132, 152, 137, 176, 154, - 138, 155, 176, 159, 151, 158, 149, 139, 160, 145, - 140, 146, 141, 162, 163, 164, 153, 147, 161, 150, - 148, 172, 152, 156, 166, 154, 167, 155, 157, 159, - 158, 168, 149, 169, 160, 170, 171, 173, 162, 175, - 163, 164, 151, 176, 150, 176, 172, 165, 156, 176, - 166, 176, 167, 176, 157, 176, 176, 168, 176, 169, - - 176, 170, 171, 176, 176, 175, 174, 176, 176, 176, - 176, 176, 165, 81, 104, 176, 176, 176, 81, 43, - 40, 36, 34, 78, 176, 50, 43, 39, 35, 34, - 176, 174, 36, 36, 36, 40, 40, 40, 77, 77, - 3, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - - 176, 176 + 6, 7, 7, 8, 9, 10, 11, 12, 13, 11, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 23, 23, 25, 26, 23, 27, 23, 28, 29, + 23, 23, 30, 31, 32, 23, 33, 34, 23, 35, + 6, 11, 19, 20, 21, 22, 23, 24, 23, 23, + 25, 26, 23, 27, 23, 28, 29, 23, 30, 31, + 32, 23, 33, 34, 23, 36, 37, 37, 43, 43, + 38, 38, 50, 46, 39, 39, 40, 40, 53, 54, + 41, 41, 56, 57, 58, 60, 61, 191, 191, 191, + 191, 43, 43, 191, 191, 42, 42, 64, 68, 67, + + 191, 191, 53, 54, 51, 62, 55, 41, 41, 47, + 63, 66, 70, 84, 191, 69, 65, 71, 191, 72, + 191, 191, 42, 42, 64, 68, 67, 73, 191, 191, + 191, 74, 62, 79, 82, 88, 63, 66, 191, 70, + 84, 69, 65, 71, 92, 93, 72, 75, 77, 89, + 191, 83, 78, 76, 73, 50, 46, 85, 74, 80, + 79, 82, 94, 81, 90, 95, 191, 191, 191, 191, + 191, 92, 93, 191, 75, 77, 89, 83, 78, 76, + 191, 97, 191, 102, 85, 191, 80, 51, 191, 98, + 81, 90, 47, 99, 100, 191, 191, 51, 47, 191, + + 105, 105, 191, 101, 191, 107, 191, 103, 97, 191, + 102, 92, 106, 191, 191, 191, 98, 108, 191, 99, + 104, 100, 110, 111, 112, 191, 191, 191, 109, 101, + 113, 115, 107, 191, 103, 114, 93, 94, 92, 106, + 95, 88, 117, 191, 108, 191, 104, 191, 118, 110, + 111, 112, 116, 191, 109, 89, 191, 113, 115, 191, + 124, 121, 114, 93, 105, 105, 122, 191, 123, 117, + 90, 191, 51, 47, 118, 191, 125, 191, 116, 120, + 191, 191, 89, 130, 130, 191, 129, 124, 121, 127, + 132, 126, 191, 122, 123, 191, 131, 90, 191, 128, + + 191, 136, 191, 125, 191, 120, 191, 133, 191, 134, + 191, 135, 191, 129, 158, 137, 127, 132, 126, 139, + 143, 141, 191, 131, 138, 128, 144, 191, 136, 130, + 130, 191, 140, 142, 133, 191, 134, 191, 135, 191, + 152, 158, 137, 157, 145, 191, 139, 143, 141, 148, + 138, 159, 144, 151, 146, 191, 191, 191, 140, 149, + 142, 147, 150, 191, 191, 153, 154, 152, 160, 157, + 161, 145, 155, 156, 191, 148, 191, 191, 159, 191, + 151, 146, 163, 166, 166, 149, 167, 147, 168, 150, + 169, 170, 153, 154, 164, 160, 173, 161, 162, 155, + + 156, 165, 174, 191, 166, 166, 175, 176, 176, 163, + 177, 178, 179, 167, 168, 181, 191, 169, 170, 176, + 176, 164, 173, 182, 162, 171, 183, 165, 184, 174, + 185, 172, 186, 175, 187, 190, 177, 191, 178, 179, + 188, 188, 181, 188, 188, 191, 191, 191, 191, 191, + 182, 171, 180, 183, 191, 184, 191, 185, 172, 186, + 187, 191, 190, 191, 96, 91, 119, 191, 191, 191, + 96, 52, 49, 45, 91, 87, 189, 191, 180, 59, + 52, 48, 44, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + + 191, 191, 189, 6, 6, 6, 45, 45, 45, 49, + 49, 49, 86, 86, 5, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191 } ; -static yyconst flex_int16_t yy_chk[503] = +static yyconst flex_int16_t yy_chk[582] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 7, 10, 12, 12, 13, 13, 13, 15, 15, - 17, 16, 19, 40, 18, 21, 36, 24, 62, 17, - 21, 19, 22, 23, 62, 27, 24, 45, 45, 16, - 24, 179, 10, 16, 7, 18, 21, 17, 27, 30, - - 22, 28, 23, 40, 22, 17, 21, 19, 25, 36, - 28, 30, 24, 42, 28, 16, 24, 26, 16, 38, - 18, 21, 17, 31, 27, 29, 22, 25, 23, 22, - 29, 53, 25, 59, 54, 26, 28, 30, 26, 53, - 28, 54, 31, 42, 58, 57, 29, 55, 64, 59, - 61, 63, 38, 25, 57, 60, 29, 25, 64, 66, - 67, 26, 65, 26, 63, 53, 58, 54, 31, 71, - 55, 29, 70, 61, 60, 59, 67, 65, 69, 72, - 57, 73, 66, 70, 64, 71, 69, 73, 75, 76, - 63, 58, 74, 79, 80, 55, 72, 75, 61, 91, - - 60, 85, 67, 65, 84, 87, 85, 66, 88, 70, - 76, 71, 69, 73, 86, 90, 74, 91, 95, 92, - 172, 86, 72, 75, 80, 88, 79, 87, 89, 84, - 94, 93, 85, 97, 95, 76, 94, 89, 150, 90, - 93, 74, 92, 91, 96, 97, 98, 86, 99, 101, - 105, 88, 87, 96, 84, 98, 100, 102, 101, 105, - 95, 99, 117, 89, 108, 90, 93, 92, 106, 110, - 111, 97, 100, 108, 118, 111, 120, 149, 102, 96, - 110, 98, 115, 117, 101, 105, 119, 99, 128, 156, - 147, 106, 120, 119, 115, 156, 111, 118, 100, 108, - - 111, 129, 121, 102, 115, 123, 110, 130, 117, 135, - 115, 121, 124, 128, 123, 125, 106, 127, 120, 119, - 115, 124, 118, 131, 125, 132, 127, 129, 139, 136, - 115, 144, 135, 130, 136, 115, 143, 121, 141, 145, - 123, 146, 148, 154, 151, 153, 139, 124, 155, 131, - 125, 132, 127, 157, 158, 160, 144, 135, 161, 141, - 136, 168, 143, 148, 162, 145, 163, 146, 151, 154, - 153, 164, 139, 165, 155, 166, 167, 173, 157, 174, - 158, 160, 142, 140, 141, 138, 168, 161, 148, 137, - 162, 134, 163, 133, 151, 126, 122, 164, 116, 165, - - 114, 166, 167, 113, 112, 174, 173, 109, 107, 103, - 83, 82, 161, 81, 77, 68, 56, 46, 44, 43, - 41, 37, 34, 33, 20, 14, 11, 9, 6, 5, - 3, 173, 177, 177, 177, 178, 178, 178, 180, 180, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - - 176, 176 + 1, 1, 1, 1, 1, 1, 3, 4, 7, 7, + 3, 4, 13, 9, 3, 4, 3, 4, 15, 15, + 3, 4, 16, 16, 16, 18, 18, 19, 20, 21, + 22, 43, 43, 24, 25, 3, 4, 20, 24, 22, + + 26, 33, 54, 54, 13, 19, 195, 3, 4, 9, + 19, 21, 25, 33, 165, 24, 20, 25, 27, 26, + 30, 164, 3, 4, 20, 24, 22, 27, 28, 32, + 29, 27, 19, 30, 32, 37, 19, 21, 34, 25, + 33, 24, 20, 25, 41, 42, 26, 28, 29, 37, + 31, 32, 29, 28, 27, 49, 45, 34, 27, 31, + 30, 32, 47, 31, 37, 51, 162, 68, 155, 64, + 153, 41, 42, 62, 28, 29, 37, 32, 29, 28, + 67, 62, 63, 68, 34, 66, 31, 49, 69, 63, + 31, 37, 45, 64, 66, 73, 70, 51, 47, 72, + + 71, 71, 74, 67, 75, 73, 76, 69, 62, 71, + 68, 89, 72, 79, 80, 78, 63, 74, 81, 64, + 70, 66, 76, 78, 79, 82, 85, 83, 75, 67, + 80, 82, 73, 84, 69, 81, 90, 94, 89, 72, + 95, 88, 84, 103, 74, 102, 70, 152, 85, 76, + 78, 79, 83, 99, 75, 88, 100, 80, 82, 101, + 103, 100, 81, 90, 105, 105, 101, 104, 102, 84, + 88, 106, 95, 94, 85, 107, 104, 108, 83, 99, + 110, 111, 88, 109, 109, 115, 108, 103, 100, 106, + 111, 105, 109, 101, 102, 112, 110, 88, 114, 107, + + 113, 115, 117, 104, 149, 99, 116, 112, 121, 113, + 120, 114, 123, 108, 144, 116, 106, 111, 105, 120, + 126, 123, 125, 110, 117, 107, 126, 132, 115, 130, + 130, 136, 121, 125, 112, 133, 113, 135, 114, 148, + 136, 144, 116, 143, 130, 141, 120, 126, 123, 132, + 117, 145, 126, 135, 130, 134, 138, 139, 121, 133, + 125, 130, 134, 140, 142, 138, 139, 136, 146, 143, + 147, 130, 140, 142, 150, 132, 154, 151, 145, 156, + 135, 130, 151, 157, 157, 133, 158, 130, 159, 134, + 160, 161, 138, 139, 154, 146, 168, 147, 150, 140, + + 142, 156, 169, 163, 166, 166, 170, 171, 171, 151, + 172, 173, 175, 158, 159, 177, 171, 160, 161, 176, + 176, 154, 168, 178, 150, 163, 179, 156, 180, 169, + 181, 166, 182, 170, 183, 189, 172, 137, 173, 175, + 187, 187, 177, 188, 188, 131, 129, 128, 127, 124, + 178, 163, 176, 179, 122, 180, 118, 181, 166, 182, + 183, 98, 189, 97, 96, 91, 86, 77, 65, 55, + 53, 52, 50, 46, 40, 36, 188, 23, 176, 17, + 14, 12, 8, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 188, 192, 192, 192, 193, 193, 193, 194, + 194, 194, 196, 196, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191 } ; static yy_state_type yy_last_accepting_state; @@ -622,7 +647,7 @@ #line 1 "KDbSqlScanner.l" /* This file is part of the KDE project Copyright (C) 2004 Lucijan Busch - Copyright (C) 2004-2015 Jarosław Staniek + Copyright (C) 2004-2018 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -657,11 +682,13 @@ extern void setError(const QString& errName, const QString& errDesc); /* *** Please reflect changes to this file in ../driver_p.cpp *** */ + /*identifier [a-zA-Z_][a-zA-Z_0-9]* */ /* quoted_identifier (\"[a-zA-Z_0-9]+\") */ -#line 663 "generated/sqlscanner.cpp" +#line 689 "generated/sqlscanner.cpp" #define INITIAL 0 +#define DATE_OR_TIME 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -841,11 +868,12 @@ register char *yy_cp, *yy_bp; register int yy_act; -#line 60 "KDbSqlScanner.l" +#line 63 "KDbSqlScanner.l" + int DATE_OR_TIME_caller = 0; -#line 849 "generated/sqlscanner.cpp" +#line 877 "generated/sqlscanner.cpp" if ( !(yy_init) ) { @@ -898,13 +926,13 @@ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 177 ) + if ( yy_current_state >= 192 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; ++yy_cp; } - while ( yy_current_state != 176 ); + while ( yy_current_state != 191 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); @@ -926,55 +954,55 @@ case 1: YY_RULE_SETUP -#line 63 "KDbSqlScanner.l" +#line 67 "KDbSqlScanner.l" { ECOUNT; return NOT_EQUAL; } YY_BREAK case 2: YY_RULE_SETUP -#line 68 "KDbSqlScanner.l" +#line 72 "KDbSqlScanner.l" { ECOUNT; return NOT_EQUAL2; } YY_BREAK case 3: YY_RULE_SETUP -#line 73 "KDbSqlScanner.l" +#line 77 "KDbSqlScanner.l" { ECOUNT; return '='; } YY_BREAK case 4: YY_RULE_SETUP -#line 78 "KDbSqlScanner.l" +#line 82 "KDbSqlScanner.l" { ECOUNT; return LESS_OR_EQUAL; } YY_BREAK case 5: YY_RULE_SETUP -#line 83 "KDbSqlScanner.l" +#line 87 "KDbSqlScanner.l" { ECOUNT; return GREATER_OR_EQUAL; } YY_BREAK case 6: YY_RULE_SETUP -#line 88 "KDbSqlScanner.l" +#line 92 "KDbSqlScanner.l" { ECOUNT; return SQL_IN; } YY_BREAK case 7: YY_RULE_SETUP -#line 93 "KDbSqlScanner.l" +#line 97 "KDbSqlScanner.l" { //! @todo what about hex or octal values? //we're using QString:toLongLong() here because atoll() is not so portable: @@ -990,295 +1018,361 @@ YY_BREAK case 8: YY_RULE_SETUP -#line 106 "KDbSqlScanner.l" +#line 110 "KDbSqlScanner.l" { ECOUNT; yylval.binaryValue = new QByteArray(yytext, yyleng); return REAL_CONST; } YY_BREAK +/* --- DATE_OR_TIME --- */ case 9: YY_RULE_SETUP -#line 112 "KDbSqlScanner.l" +#line 117 "KDbSqlScanner.l" { ECOUNT; - return AND; + sqlParserDebug() << "### begin DATE_OR_TIME" << yytext << "(" << yyleng << ")"; + DATE_OR_TIME_caller = YYSTATE; + BEGIN(DATE_OR_TIME); + return '#'; } YY_BREAK + case 10: YY_RULE_SETUP -#line 117 "KDbSqlScanner.l" +#line 127 "KDbSqlScanner.l" +{ // year prefix or / or - or : separator + ECOUNT; + return yytext[0]; +} + YY_BREAK +case 11: +YY_RULE_SETUP +#line 132 "KDbSqlScanner.l" +{ // year, month, day, hour, minute or second + ECOUNT; + yylval.binaryValue = new QByteArray(yytext, yyleng); + return DATE_TIME_INTEGER; +} + YY_BREAK +case 12: +YY_RULE_SETUP +#line 138 "KDbSqlScanner.l" +{ + ECOUNT; + return TABS_OR_SPACES; +} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 143 "KDbSqlScanner.l" +{ + ECOUNT; + return TIME_AM; +} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 148 "KDbSqlScanner.l" +{ + ECOUNT; + return TIME_PM; +} + YY_BREAK +case 15: +YY_RULE_SETUP +#line 153 "KDbSqlScanner.l" +{ + ECOUNT; + sqlParserDebug() << "### begin DATE_OR_TIME" << yytext << "(" << yyleng << ")"; + BEGIN(DATE_OR_TIME_caller); + return '#'; +} + YY_BREAK + +/* -- end of DATE_OR_TIME --- */ +case 16: +YY_RULE_SETUP +#line 163 "KDbSqlScanner.l" +{ + ECOUNT; + return AND; +} + YY_BREAK +case 17: +YY_RULE_SETUP +#line 168 "KDbSqlScanner.l" { ECOUNT; return AS; } YY_BREAK -case 11: +case 18: YY_RULE_SETUP -#line 122 "KDbSqlScanner.l" +#line 173 "KDbSqlScanner.l" { ECOUNT; return CREATE; } YY_BREAK -case 12: +case 19: YY_RULE_SETUP -#line 127 "KDbSqlScanner.l" +#line 178 "KDbSqlScanner.l" { ECOUNT; return FROM; } YY_BREAK -case 13: +case 20: YY_RULE_SETUP -#line 132 "KDbSqlScanner.l" +#line 183 "KDbSqlScanner.l" { ECOUNT; return SQL_TYPE; } YY_BREAK -case 14: +case 21: YY_RULE_SETUP -#line 137 "KDbSqlScanner.l" +#line 188 "KDbSqlScanner.l" { ECOUNT; return JOIN; } YY_BREAK -case 15: +case 22: YY_RULE_SETUP -#line 142 "KDbSqlScanner.l" +#line 193 "KDbSqlScanner.l" { ECOUNT; return LEFT; } YY_BREAK -case 16: +case 23: YY_RULE_SETUP -#line 147 "KDbSqlScanner.l" +#line 198 "KDbSqlScanner.l" { ECOUNT; return LIKE; } YY_BREAK -case 17: -/* rule 17 can match eol */ +case 24: +/* rule 24 can match eol */ YY_RULE_SETUP -#line 152 "KDbSqlScanner.l" +#line 203 "KDbSqlScanner.l" { ECOUNT; return NOT_LIKE; } YY_BREAK -case 18: +case 25: YY_RULE_SETUP -#line 157 "KDbSqlScanner.l" +#line 208 "KDbSqlScanner.l" { ECOUNT; return BETWEEN; } YY_BREAK -case 19: -/* rule 19 can match eol */ +case 26: +/* rule 26 can match eol */ YY_RULE_SETUP -#line 162 "KDbSqlScanner.l" +#line 213 "KDbSqlScanner.l" { ECOUNT; return NOT_BETWEEN; } YY_BREAK -case 20: -/* rule 20 can match eol */ +case 27: +/* rule 27 can match eol */ YY_RULE_SETUP -#line 167 "KDbSqlScanner.l" +#line 218 "KDbSqlScanner.l" { ECOUNT; return NOT_SIMILAR_TO; } YY_BREAK -case 21: -/* rule 21 can match eol */ +case 28: +/* rule 28 can match eol */ YY_RULE_SETUP -#line 172 "KDbSqlScanner.l" +#line 223 "KDbSqlScanner.l" { ECOUNT; return SIMILAR_TO; } YY_BREAK -case 22: -/* rule 22 can match eol */ +case 29: +/* rule 29 can match eol */ YY_RULE_SETUP -#line 177 "KDbSqlScanner.l" +#line 228 "KDbSqlScanner.l" { ECOUNT; return SQL_IS_NOT_NULL; } YY_BREAK -case 23: -/* rule 23 can match eol */ +case 30: +/* rule 30 can match eol */ YY_RULE_SETUP -#line 182 "KDbSqlScanner.l" +#line 233 "KDbSqlScanner.l" { ECOUNT; return SQL_IS_NULL; } YY_BREAK -case 24: +case 31: YY_RULE_SETUP -#line 187 "KDbSqlScanner.l" +#line 238 "KDbSqlScanner.l" { ECOUNT; return NOT; } YY_BREAK -case 25: +case 32: YY_RULE_SETUP -#line 192 "KDbSqlScanner.l" +#line 243 "KDbSqlScanner.l" { ECOUNT; return SQL_IS; } YY_BREAK -case 26: +case 33: YY_RULE_SETUP -#line 197 "KDbSqlScanner.l" +#line 248 "KDbSqlScanner.l" { ECOUNT; return SQL_NULL; } YY_BREAK -case 27: +case 34: YY_RULE_SETUP -#line 202 "KDbSqlScanner.l" +#line 253 "KDbSqlScanner.l" { ECOUNT; return SQL_TRUE; } YY_BREAK -case 28: +case 35: YY_RULE_SETUP -#line 207 "KDbSqlScanner.l" +#line 258 "KDbSqlScanner.l" { ECOUNT; return SQL_FALSE; } YY_BREAK -case 29: +case 36: YY_RULE_SETUP -#line 212 "KDbSqlScanner.l" +#line 263 "KDbSqlScanner.l" { ECOUNT; return SQL_ON; } YY_BREAK -case 30: +case 37: YY_RULE_SETUP -#line 217 "KDbSqlScanner.l" +#line 268 "KDbSqlScanner.l" { ECOUNT; return OR; } YY_BREAK -case 31: +case 38: YY_RULE_SETUP -#line 222 "KDbSqlScanner.l" +#line 273 "KDbSqlScanner.l" { /* also means OR for numbers (mysql) */ ECOUNT; return CONCATENATION; } YY_BREAK -case 32: +case 39: YY_RULE_SETUP -#line 227 "KDbSqlScanner.l" +#line 278 "KDbSqlScanner.l" { ECOUNT; return BITWISE_SHIFT_LEFT; } YY_BREAK -case 33: +case 40: YY_RULE_SETUP -#line 232 "KDbSqlScanner.l" +#line 283 "KDbSqlScanner.l" { ECOUNT; return BITWISE_SHIFT_RIGHT; } YY_BREAK -case 34: +case 41: YY_RULE_SETUP -#line 237 "KDbSqlScanner.l" +#line 288 "KDbSqlScanner.l" { ECOUNT; return XOR; } YY_BREAK -case 35: +case 42: YY_RULE_SETUP -#line 242 "KDbSqlScanner.l" +#line 293 "KDbSqlScanner.l" { ECOUNT; return RIGHT; } YY_BREAK -case 36: +case 43: YY_RULE_SETUP -#line 247 "KDbSqlScanner.l" +#line 298 "KDbSqlScanner.l" { ECOUNT; return SELECT; } YY_BREAK -case 37: +case 44: YY_RULE_SETUP -#line 252 "KDbSqlScanner.l" +#line 303 "KDbSqlScanner.l" { ECOUNT; return TABLE; } YY_BREAK -case 38: +case 45: YY_RULE_SETUP -#line 257 "KDbSqlScanner.l" +#line 308 "KDbSqlScanner.l" { ECOUNT; return WHERE; } YY_BREAK -case 39: +case 46: YY_RULE_SETUP -#line 262 "KDbSqlScanner.l" +#line 313 "KDbSqlScanner.l" { ECOUNT; return ORDER; } YY_BREAK -case 40: +case 47: YY_RULE_SETUP -#line 267 "KDbSqlScanner.l" +#line 318 "KDbSqlScanner.l" { ECOUNT; return BY; } YY_BREAK -case 41: +case 48: YY_RULE_SETUP -#line 272 "KDbSqlScanner.l" +#line 323 "KDbSqlScanner.l" { ECOUNT; return ASC; } YY_BREAK -case 42: +case 49: YY_RULE_SETUP -#line 277 "KDbSqlScanner.l" +#line 328 "KDbSqlScanner.l" { ECOUNT; return DESC; } YY_BREAK -case 43: -/* rule 43 can match eol */ +case 50: +/* rule 50 can match eol */ YY_RULE_SETUP -#line 282 "KDbSqlScanner.l" +#line 333 "KDbSqlScanner.l" { ECOUNT; sqlParserDebug() << "{string} yytext: '" << yytext << "' (" << yyleng << ")"; @@ -1296,9 +1390,9 @@ /* "ZZZ" sentinel for script */ } YY_BREAK -case 44: +case 51: YY_RULE_SETUP -#line 299 "KDbSqlScanner.l" +#line 350 "KDbSqlScanner.l" { sqlParserDebug() << "{identifier} yytext: '" << yytext << "' (" << yyleng << ")"; ECOUNT; @@ -1311,41 +1405,42 @@ return IDENTIFIER; } YY_BREAK -case 45: -/* rule 45 can match eol */ +case 52: +/* rule 52 can match eol */ YY_RULE_SETUP -#line 311 "KDbSqlScanner.l" +#line 362 "KDbSqlScanner.l" { sqlParserDebug() << "{query_parameter} yytext: '" << yytext << "' (" << yyleng << ")"; ECOUNT; yylval.stringValue = new QString(QString::fromUtf8(yytext+1, yyleng-2)); return QUERY_PARAMETER; } YY_BREAK -case 46: -/* rule 46 can match eol */ +case 53: +/* rule 53 can match eol */ YY_RULE_SETUP -#line 318 "KDbSqlScanner.l" +#line 369 "KDbSqlScanner.l" { ECOUNT; } YY_BREAK -case 47: +case 54: YY_RULE_SETUP -#line 322 "KDbSqlScanner.l" +#line 373 "KDbSqlScanner.l" { sqlParserDebug() << "char: '" << yytext[0] << "'"; ECOUNT; return yytext[0]; } YY_BREAK -case 48: +case 55: YY_RULE_SETUP -#line 328 "KDbSqlScanner.l" +#line 379 "KDbSqlScanner.l" ECHO; YY_BREAK -#line 1348 "generated/sqlscanner.cpp" +#line 1442 "generated/sqlscanner.cpp" case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(DATE_OR_TIME): yyterminate(); case YY_END_OF_BUFFER: @@ -1637,7 +1732,7 @@ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 177 ) + if ( yy_current_state >= 192 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; @@ -1665,11 +1760,11 @@ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 177 ) + if ( yy_current_state >= 192 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; - yy_is_jam = (yy_current_state == 176); + yy_is_jam = (yy_current_state == 191); return yy_is_jam ? 0 : yy_current_state; } @@ -2339,7 +2434,7 @@ #define YYTABLES_NAME "yytables" -#line 328 "KDbSqlScanner.l" +#line 379 "KDbSqlScanner.l" diff --git a/src/tools/KDbUtils.cpp b/src/tools/KDbUtils.cpp --- a/src/tools/KDbUtils.cpp +++ b/src/tools/KDbUtils.cpp @@ -144,7 +144,7 @@ } // kdbDebug() << QDateTime( QDate(0,1,2), QTime::fromString( s, Qt::ISODate ) // ).toString(Qt::ISODate); - return QDateTime(QDate(0, 1, 2), QTime::fromString(s, Qt::ISODate)); + return QDateTime(QDate(0, 1, 2), QTime::fromString(s, Qt::ISODateWithMs)); } void KDbUtils::serializeMap(const QMap& map, QByteArray *array)