aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/parser/ast
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@unit193.net>2021-12-17 07:07:47 -0500
committerLibravatarUnit 193 <unit193@unit193.net>2021-12-17 07:07:47 -0500
commit558b1e35fd0777ac97763c1b28056ac984e583e7 (patch)
tree1eb2557119a117ea76535c89cd14a49e510b96bf /SQLiteStudio3/coreSQLiteStudio/parser/ast
parentc22eb635c11fd45f9c30f911d70e1d79111a49ce (diff)
parent1fdc150116cad39aae5c5da407c3312b47a59e3a (diff)
Update upstream source from tag 'upstream/3.3.3+dfsg1'
Update to upstream version '3.3.3+dfsg1' with Debian dir 9a301fff4922aed2fec0c04c7d011947168c42f1
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/parser/ast')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp9
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.h3
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.cpp5
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteconflictalgo.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h10
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp80
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h7
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp101
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h36
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp49
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h7
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp32
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.h6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedeferrable.cpp4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp8
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp105
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h31
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitefilterover.cpp138
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitefilterover.h65
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.cpp4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp10
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitenulls.cpp26
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitenulls.h17
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp65
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h8
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp8
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp40
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.h1
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp89
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h30
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesortorder.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.cpp17
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h11
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp20
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h10
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupsert.cpp4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp29
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.h6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp308
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.h129
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp22
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h2
76 files changed, 1256 insertions, 412 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp
index 49763a5..5ca593f 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp
@@ -106,7 +106,7 @@ TokenList SqliteAlterTable::rebuildTokensFromContents()
builder.withKeyword("ALTER").withSpace().withKeyword("TABLE").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
builder.withOther(table).withSpace();
@@ -120,7 +120,7 @@ TokenList SqliteAlterTable::rebuildTokensFromContents()
}
else if (!newName.isNull())
{
- builder.withKeyword("RENAME").withSpace().withKeyword("TO").withSpace().withOther(newName, dialect);
+ builder.withKeyword("RENAME").withSpace().withKeyword("TO").withSpace().withOther(newName);
}
builder.withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h
index 360db45..fbac3fe 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h
@@ -34,9 +34,9 @@ class API_EXPORT SqliteAlterTable : public SqliteQuery
public:
Command command = Command::null;
- QString newName = QString::null;
- QString database = QString::null;
- QString table = QString::null;
+ QString newName = QString();
+ QString database = QString();
+ QString table = QString();
bool columnKw = false;
SqliteCreateTable::Column* newColumn = nullptr;
};
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp
index 30396c1..4e79f3d 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp
@@ -73,7 +73,7 @@ TokenList SqliteAnalyze::rebuildTokensFromContents()
builder.withKeyword("ANALYZE").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
builder.withOther(table).withOperator(";");
return builder.build();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.h
index 194e4c9..a786621 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.h
@@ -12,8 +12,8 @@ class API_EXPORT SqliteAnalyze : public SqliteQuery
SqliteAnalyze(const QString& name1, const QString& name2);
SqliteStatement* clone();
- QString database = QString::null;
- QString table = QString::null;
+ QString database = QString();
+ QString table = QString();
protected:
QStringList getTablesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp
index 00ec9ac..899f8bb 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp
@@ -9,7 +9,7 @@ SqliteBeginTrans::SqliteBeginTrans()
}
SqliteBeginTrans::SqliteBeginTrans(const SqliteBeginTrans& other) :
- SqliteQuery(other), onConflict(other.onConflict), name(other.name), transactionKw(other.transactionKw), type(other.type)
+ SqliteQuery(other), name(other.name), transactionKw(other.transactionKw), type(other.type)
{
}
@@ -21,9 +21,8 @@ SqliteBeginTrans::SqliteBeginTrans(SqliteBeginTrans::Type type, bool transaction
this->name = name;
}
-SqliteBeginTrans::SqliteBeginTrans(bool transactionKw, const QString &name, SqliteConflictAlgo onConflict)
+SqliteBeginTrans::SqliteBeginTrans(bool transactionKw, const QString &name)
{
- this->onConflict = onConflict;
this->transactionKw = transactionKw;
this->name = name;
}
@@ -62,10 +61,10 @@ TokenList SqliteBeginTrans::rebuildTokensFromContents()
{
builder.withSpace().withKeyword("TRANSACTION");
if (!name.isNull())
- builder.withSpace().withOther(name, dialect);
+ builder.withSpace().withOther(name);
}
- builder.withConflict(onConflict).withOperator(";");
+ builder.withOperator(";");
return builder.build();
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.h
index 48f5b37..b16b6c0 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.h
@@ -19,10 +19,9 @@ class API_EXPORT SqliteBeginTrans : public SqliteQuery
SqliteBeginTrans();
SqliteBeginTrans(const SqliteBeginTrans& other);
SqliteBeginTrans(Type type, bool transactionKw, const QString& name);
- SqliteBeginTrans(bool transactionKw, const QString& name, SqliteConflictAlgo onConflict);
+ SqliteBeginTrans(bool transactionKw, const QString& name);
SqliteStatement* clone();
- SqliteConflictAlgo onConflict = SqliteConflictAlgo::null; // sqlite2 only
QString name; // in docs sqlite2 only, but in gramma it's also sqlite3
bool transactionKw = false;
Type type = Type::null; // sqlite3 only
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.cpp
index 2c48119..5872ab1 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.cpp
@@ -1,6 +1,7 @@
#include "sqlitecolumntype.h"
#include "parser/statementtokenbuilder.h"
#include "common/utils_sql.h"
+#include "parser/lexer.h"
SqliteColumnType::SqliteColumnType()
{
@@ -50,7 +51,7 @@ TokenList SqliteColumnType::rebuildTokensFromContents()
if (name.isEmpty())
return TokenList();
- builder.withOther(name);
+ TokenList resultTokens = Lexer::tokenize(name);
if (!scale.isNull())
{
@@ -79,7 +80,7 @@ TokenList SqliteColumnType::rebuildTokensFromContents()
builder.withParRight();
}
- return builder.build();
+ return resultTokens + builder.build();
}
DataType SqliteColumnType::toDataType() const
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.h
index fc87b6b..f003f9f 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecolumntype.h
@@ -20,7 +20,7 @@ class API_EXPORT SqliteColumnType : public SqliteStatement
TokenList rebuildTokensFromContents();
DataType toDataType() const;
- QString name = QString::null;
+ QString name = QString();
QVariant scale = QVariant(); // first size number
QVariant precision = QVariant(); // second size number
};
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp
index 2b1b707..4f8de49 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp
@@ -39,7 +39,7 @@ TokenList SqliteCommitTrans::rebuildTokensFromContents()
{
builder.withSpace().withKeyword("TRANSACTION");
if (!name.isNull())
- builder.withSpace().withOther(name, dialect);
+ builder.withSpace().withOther(name);
}
builder.withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.h
index ec418a6..b5557a7 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.h
@@ -13,7 +13,7 @@ class API_EXPORT SqliteCommitTrans : public SqliteQuery
SqliteStatement* clone();
bool endKw = false;
- QString name = QString::null;
+ QString name = QString();
bool transactionKw = false;
protected:
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteconflictalgo.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteconflictalgo.cpp
index 56fb42d..2246979 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteconflictalgo.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteconflictalgo.cpp
@@ -32,6 +32,6 @@ QString sqliteConflictAlgo(SqliteConflictAlgo value)
case SqliteConflictAlgo::REPLACE:
return "REPLACE";
default:
- return QString::null;
+ return QString();
}
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp
index 0d9ed9f..c3ff500 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp
@@ -79,9 +79,9 @@ TokenList SqliteCopy::rebuildTokensFromContents()
builder.withKeyword("OR").withSpace().withKeyword(sqliteConflictAlgo(onConflict)).withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withSpace();
+ builder.withOther(database).withSpace();
- builder.withOther(table, dialect).withSpace().withKeyword("FROM").withSpace().withString(file);
+ builder.withOther(table).withSpace().withKeyword("FROM").withSpace().withString(file);
if (!delimiter.isNull())
builder.withSpace().withKeyword("USING").withSpace().withKeyword("DELIMITERS").withSpace().withString(delimiter);
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h
index ff586df..1e4b5b7 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h
@@ -9,14 +9,14 @@ class API_EXPORT SqliteCopy : public SqliteQuery
public:
SqliteCopy();
SqliteCopy(const SqliteCopy& other);
- SqliteCopy(SqliteConflictAlgo onConflict, const QString& name1, const QString& name2, const QString& name3, const QString& delim = QString::null);
+ SqliteCopy(SqliteConflictAlgo onConflict, const QString& name1, const QString& name2, const QString& name3, const QString& delim = QString());
SqliteStatement* clone();
SqliteConflictAlgo onConflict = SqliteConflictAlgo::null;
- QString database = QString::null;
- QString table = QString::null;
- QString file = QString::null;
- QString delimiter = QString::null;
+ QString database = QString();
+ QString table = QString();
+ QString file = QString();
+ QString delimiter = QString();
protected:
QStringList getTablesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp
index 5c11ff5..b747c33 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp
@@ -17,32 +17,10 @@ SqliteCreateIndex::SqliteCreateIndex(const SqliteCreateIndex& other) :
DEEP_COPY_COLLECTION(SqliteOrderBy, indexedColumns);
}
-SqliteCreateIndex::SqliteCreateIndex(bool unique, bool ifNotExists, const QString& name1, const QString& name2, const QString& name3, const QList<SqliteIndexedColumn*>& columns, SqliteConflictAlgo onConflict)
- : SqliteCreateIndex()
-{
- // Constructor for SQLite 2
- uniqueKw = unique;
- ifNotExistsKw = ifNotExists;
-
- index = name1;
-
- if (!name3.isNull())
- {
- database = name2;
- table = name3;
- }
- else
- table = name2;
-
- this->onConflict = onConflict;
- this->indexedColumns = toOrderColumns(columns);
-}
-
SqliteCreateIndex::SqliteCreateIndex(bool unique, bool ifNotExists, const QString& name1, const QString& name2, const QString& name3,
const QList<SqliteOrderBy*>& columns, SqliteExpr* where)
: SqliteCreateIndex()
{
- // Constructor for SQLite 3
uniqueKw = unique;
ifNotExistsKw = ifNotExists;
@@ -89,18 +67,12 @@ QStringList SqliteCreateIndex::getDatabasesInStatement()
TokenList SqliteCreateIndex::getTableTokensInStatement()
{
- if (dialect == Dialect::Sqlite2)
- return getObjectTokenListFromNmDbnm("nm2", "dbnm");
- else
- return getTokenListFromNamedKey("nm2");
+ return getTokenListFromNamedKey("nm2");
}
TokenList SqliteCreateIndex::getDatabaseTokensInStatement()
{
- if (dialect == Dialect::Sqlite2)
- return getDbTokenListFromNmDbnm("nm2", "dbnm");
- else
- return getDbTokenListFromNmDbnm();
+ return getDbTokenListFromNmDbnm();
}
QList<SqliteStatement::FullObject> SqliteCreateIndex::getFullObjectsInStatement()
@@ -109,14 +81,9 @@ QList<SqliteStatement::FullObject> SqliteCreateIndex::getFullObjectsInStatement(
// Table object
FullObject fullObj;
- if (dialect == Dialect::Sqlite2)
- fullObj = getFullObjectFromNmDbnm(FullObject::TABLE, "nm2", "dbnm");
- else
- {
- TokenList tableTokens = getTokenListFromNamedKey("nm2");
- if (tableTokens.size() > 0)
- fullObj = getFullObject(FullObject::TABLE, TokenPtr(), tableTokens[0]);
- }
+ TokenList tableTokens = getTokenListFromNamedKey("nm2");
+ if (tableTokens.size() > 0)
+ fullObj = getFullObject(FullObject::TABLE, TokenPtr(), tableTokens[0]);
if (fullObj.isValid())
result << fullObj;
@@ -130,14 +97,10 @@ QList<SqliteStatement::FullObject> SqliteCreateIndex::getFullObjectsInStatement(
}
// Index object
- if (dialect == Dialect::Sqlite2)
- {
- TokenList tableTokens = getTokenListFromNamedKey("nm");
- if (tableTokens.size() > 0)
- fullObj = getFullObject(FullObject::INDEX, TokenPtr(), tableTokens[0]);
- }
- else
- fullObj = getFullObjectFromNmDbnm(FullObject::INDEX, "nm", "dbnm");
+ fullObj = getFullObjectFromNmDbnm(FullObject::INDEX, "nm", "dbnm");
+
+ if (fullObj.isValid())
+ result << fullObj;
return result;
}
@@ -155,28 +118,11 @@ TokenList SqliteCreateIndex::rebuildTokensFromContents()
if (ifNotExistsKw)
builder.withKeyword("IF").withSpace().withKeyword("NOT").withSpace().withKeyword("EXISTS").withSpace();
- if (dialect == Dialect::Sqlite2)
- {
- builder.withOther(index, dialect).withSpace().withKeyword("ON").withSpace();
-
- if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
-
- builder.withOther(table, dialect).withSpace();
- builder.withParLeft().withStatementList(indexedColumns).withParRight();
-
-
- if (onConflict != SqliteConflictAlgo::null)
- builder.withSpace().withKeyword(sqliteConflictAlgo(onConflict));
- }
- else
- {
- if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ if (!database.isNull())
+ builder.withOther(database).withOperator(".");
- builder.withOther(index, dialect).withSpace().withKeyword("ON").withSpace().withOther(table, dialect).withSpace().withParLeft()
- .withStatementList(indexedColumns).withParRight();
- }
+ builder.withOther(index).withSpace().withKeyword("ON").withSpace().withOther(table).withSpace().withParLeft()
+ .withStatementList(indexedColumns).withParRight();
if (where)
builder.withSpace().withKeyword("WHERE").withStatement(where);
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h
index 033a663..870ed17 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h
@@ -33,10 +33,9 @@ class API_EXPORT SqliteCreateIndex : public SqliteQuery, public SqliteTableRelat
bool uniqueKw = false;
bool ifNotExistsKw = false;
QList<SqliteOrderBy*> indexedColumns;
- // The database refers to index name in Sqlite3, but in Sqlite2 it refers to the table.
- QString database = QString::null;
- QString index = QString::null;
- QString table = QString::null;
+ QString database = QString();
+ QString index = QString();
+ QString table = QString();
SqliteConflictAlgo onConflict = SqliteConflictAlgo::null;
SqliteExpr* where = nullptr;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp
index eb4ae85..d82270e 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp
@@ -3,6 +3,8 @@
#include "common/utils_sql.h"
#include "common/global.h"
+const QRegExp SqliteCreateTable::Column::GENERATED_ALWAYS_REGEXP = QRegExp("GENERATED\\s+ALWAYS");
+
SqliteCreateTable::SqliteCreateTable()
{
queryType = SqliteQueryType::CreateTable;
@@ -219,10 +221,10 @@ TokenList SqliteCreateTable::rebuildTokensFromContents()
builder.withSpace().withKeyword("IF").withSpace().withKeyword("NOT").withSpace().withKeyword("EXISTS");
builder.withSpace();
- if (dialect == Dialect::Sqlite3 && !database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ if (!database.isNull())
+ builder.withOther(database).withOperator(".");
- builder.withOther(table, dialect);
+ builder.withOther(table);
if (select)
builder.withSpace().withKeyword("AS").withSpace().withStatement(select);
@@ -267,8 +269,9 @@ SqliteCreateTable::Column::Constraint::Constraint()
SqliteCreateTable::Column::Constraint::Constraint(const SqliteCreateTable::Column::Constraint& other) :
SqliteStatement(other), type(other.type), name(other.name), sortOrder(other.sortOrder), onConflict(other.onConflict),
- autoincrKw(other.autoincrKw), literalValue(other.literalValue), literalNull(other.literalNull), ctime(other.ctime), id(other.id),
- collationName(other.collationName), deferrable(other.deferrable), initially(other.initially)
+ autoincrKw(other.autoincrKw), generatedKw(other.generatedKw), literalValue(other.literalValue), literalNull(other.literalNull),
+ ctime(other.ctime), id(other.id), collationName(other.collationName), generatedType(other.generatedType),
+ deferrable(other.deferrable), initially(other.initially)
{
DEEP_COPY_FIELD(SqliteExpr, expr);
DEEP_COPY_FIELD(SqliteForeignKey, foreignKey);
@@ -283,6 +286,30 @@ SqliteStatement* SqliteCreateTable::Column::Constraint::clone()
return new SqliteCreateTable::Column::Constraint(*this);
}
+QString SqliteCreateTable::Column::Constraint::toString(SqliteCreateTable::Column::Constraint::GeneratedType type)
+{
+ switch (type) {
+ case SqliteCreateTable::Column::Constraint::GeneratedType::STORED:
+ return "STORED";
+ case SqliteCreateTable::Column::Constraint::GeneratedType::VIRTUAL:
+ return "VIRTUAL";
+ case SqliteCreateTable::Column::Constraint::GeneratedType::null:
+ break;
+ }
+ return QString();
+}
+
+SqliteCreateTable::Column::Constraint::GeneratedType SqliteCreateTable::Column::Constraint::generatedTypeFrom(const QString& type)
+{
+ QString upType = type.toUpper();
+ if (upType == "STORED")
+ return GeneratedType::STORED;
+ else if (upType == "VIRTUAL")
+ return GeneratedType::VIRTUAL;
+ else
+ return GeneratedType::null;
+}
+
void SqliteCreateTable::Column::Constraint::initDefNameOnly(const QString &name)
{
this->type = SqliteCreateTable::Column::Constraint::NAME_ONLY;
@@ -404,6 +431,14 @@ void SqliteCreateTable::Column::Constraint::initColl(const QString &name)
this->collationName = name;
}
+void SqliteCreateTable::Column::Constraint::initGeneratedAs(SqliteExpr* expr, bool genKw, const QString& type)
+{
+ this->type = SqliteCreateTable::Column::Constraint::GENERATED;
+ this->expr = expr;
+ this->generatedKw = genKw;
+ this->generatedType = generatedTypeFrom(type);
+}
+
QString SqliteCreateTable::Column::Constraint::typeString() const
{
switch (type)
@@ -418,6 +453,8 @@ QString SqliteCreateTable::Column::Constraint::typeString() const
return "CHECK";
case SqliteCreateTable::Column::Constraint::DEFAULT:
return "DEFAULT";
+ case SqliteCreateTable::Column::Constraint::GENERATED:
+ return "GENERATED";
case SqliteCreateTable::Column::Constraint::COLLATE:
return "COLLATE";
case SqliteCreateTable::Column::Constraint::FOREIGN_KEY:
@@ -427,7 +464,7 @@ QString SqliteCreateTable::Column::Constraint::typeString() const
case SqliteCreateTable::Column::Constraint::DEFERRABLE_ONLY:
break;
}
- return QString::null;
+ return QString();
}
SqliteCreateTable::Constraint::Constraint()
@@ -551,9 +588,9 @@ QString SqliteCreateTable::Constraint::typeString() const
case SqliteCreateTable::Constraint::FOREIGN_KEY:
return "FOREIGN KEY";
case SqliteCreateTable::Constraint::NAME_ONLY:
- return QString::null;
+ return QString();
}
- return QString::null;
+ return QString();
}
TokenList SqliteCreateTable::Constraint::rebuildTokensFromContents()
@@ -561,7 +598,7 @@ TokenList SqliteCreateTable::Constraint::rebuildTokensFromContents()
StatementTokenBuilder builder;
if (!name.isNull())
- builder.withKeyword("CONSTRAINT").withSpace().withOther(name, dialect).withSpace();
+ builder.withKeyword("CONSTRAINT").withSpace().withOther(name).withSpace();
switch (type)
{
@@ -694,6 +731,33 @@ QList<SqliteCreateTable::Column::Constraint*> SqliteCreateTable::Column::getFore
return results;
}
+void SqliteCreateTable::Column::fixTypeVsGeneratedAs()
+{
+ // This is a workaround for lemon parser taking "GENERATED ALWAYS" as part of the typename,
+ // despite 2 days effort of forcing proper precedense to parse it as part of a constraint.
+ // Lemon keeps reducing these 2 keywords into the typename by using fallback of GENERATED & ALWAYS to ID,
+ // regardless of rule order and explicit precedence. By throwing the GENERATED keyword out of the fallback list,
+ // we would make the syntax incompatible with official SQLite syntax, which allows usage of GENERATED as ID.
+ // I've tried to use more recent Lemon parser, but it's different a lot from current one and it is no longer possible
+ // to collect tokens parsed per rule (needed tor SqliteStatement's tokens & tokenMap). At least not in the way
+ // that it used to be so far.
+ // This is the last resort to make it right.
+ // This method is called from parser rule that reduces column definition (rule "column(X)").
+ Constraint* generatedConstr = getConstraint(Constraint::GENERATED);
+ if (generatedConstr && !generatedConstr->generatedKw && type && type->name.toUpper().contains(GENERATED_ALWAYS_REGEXP))
+ {
+ type->name.replace(GENERATED_ALWAYS_REGEXP, "");
+ type->tokens = type->rebuildTokensFromContents();
+ type->tokensMap["typename"] = type->tokens;
+ generatedConstr->generatedKw = true;
+ }
+}
+
+void SqliteCreateTable::Column::evaluatePostParsing()
+{
+ fixTypeVsGeneratedAs();
+}
+
QStringList SqliteCreateTable::Column::getColumnsInStatement()
{
return getStrListFromValue(name);
@@ -707,7 +771,7 @@ TokenList SqliteCreateTable::Column::getColumnTokensInStatement()
TokenList SqliteCreateTable::Column::rebuildTokensFromContents()
{
StatementTokenBuilder builder;
- builder.withOther(name, dialect).withStatement(type).withStatementList(constraints, "");
+ builder.withOther(name).withStatement(type).withStatementList(constraints, "");
return builder.build();
}
@@ -715,7 +779,7 @@ TokenList SqliteCreateTable::Column::Constraint::rebuildTokensFromContents()
{
StatementTokenBuilder builder;
if (!name.isNull())
- builder.withKeyword("CONSTRAINT").withSpace().withOther(name, dialect).withSpace();
+ builder.withKeyword("CONSTRAINT").withSpace().withOther(name).withSpace();
switch (type)
{
@@ -746,7 +810,7 @@ TokenList SqliteCreateTable::Column::Constraint::rebuildTokensFromContents()
{
builder.withKeyword("DEFAULT").withSpace();
if (!id.isNull())
- builder.withOther(id, dialect);
+ builder.withOther(id);
else if (!ctime.isNull())
builder.withKeyword(ctime.toUpper());
else if (expr)
@@ -760,7 +824,7 @@ TokenList SqliteCreateTable::Column::Constraint::rebuildTokensFromContents()
}
case SqliteCreateTable::Column::Constraint::COLLATE:
{
- builder.withKeyword("COLLATE").withSpace().withOther(collationName, dialect);
+ builder.withKeyword("COLLATE").withSpace().withOther(collationName);
break;
}
case SqliteCreateTable::Column::Constraint::FOREIGN_KEY:
@@ -768,6 +832,17 @@ TokenList SqliteCreateTable::Column::Constraint::rebuildTokensFromContents()
builder.withStatement(foreignKey);
break;
}
+ case SqliteCreateTable::Column::Constraint::GENERATED:
+ {
+ if (generatedKw)
+ builder.withKeyword("GENERATED").withSpace().withKeyword("ALWAYS").withSpace();
+
+ builder.withKeyword("AS").withSpace().withParLeft().withStatement(expr).withParRight();
+ if (generatedType != GeneratedType::null)
+ builder.withSpace().withOther(toString(generatedType), false);
+
+ break;
+ }
case SqliteCreateTable::Column::Constraint::NULL_:
case SqliteCreateTable::Column::Constraint::NAME_ONLY:
case SqliteCreateTable::Column::Constraint::DEFERRABLE_ONLY:
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h
index 74f4fce..d34688c 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h
@@ -13,6 +13,7 @@
#include "sqliteddlwithdbcontext.h"
#include <QVariant>
#include <QList>
+#include <QRegExp>
class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbContext
{
@@ -34,16 +35,27 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
DEFAULT,
COLLATE,
FOREIGN_KEY,
+ GENERATED,
NULL_, // not officially supported
NAME_ONLY, // unofficial, because of bizarre sqlite grammar
DEFERRABLE_ONLY // unofficial, because of bizarre sqlite grammar
};
+ enum class GeneratedType
+ {
+ STORED,
+ VIRTUAL,
+ null
+ };
+
Constraint();
Constraint(const Constraint& other);
~Constraint();
SqliteStatement* clone();
+ static QString toString(GeneratedType type);
+ static GeneratedType generatedTypeFrom(const QString& type);
+
void initDefNameOnly(const QString& name);
void initDefId(const QString& id);
void initDefTerm(const QVariant& value, bool minus = false);
@@ -59,19 +71,22 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
void initFk(const QString& table, const QList<SqliteIndexedColumn*>& indexedColumns, const QList<SqliteForeignKey::Condition*>& conditions);
void initDefer(SqliteInitially initially, SqliteDeferrable deferrable);
void initColl(const QString& name);
+ void initGeneratedAs(SqliteExpr* expr, bool genKw, const QString& type);
QString typeString() const;
Type type;
- QString name = QString::null;
+ QString name = QString();
SqliteSortOrder sortOrder = SqliteSortOrder::null;
SqliteConflictAlgo onConflict = SqliteConflictAlgo::null;
bool autoincrKw = false;
+ bool generatedKw = false;
SqliteExpr* expr = nullptr;
QVariant literalValue;
bool literalNull = false;
QString ctime;
QString id;
- QString collationName = QString::null;
+ QString collationName = QString();
+ GeneratedType generatedType = GeneratedType::null;
SqliteForeignKey* foreignKey = nullptr;
protected:
@@ -96,8 +111,10 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
Constraint* getConstraint(Constraint::Type type) const;
QList<Constraint*> getConstraints(Constraint::Type type) const;
QList<Constraint*> getForeignKeysByTable(const QString& foreignTable) const;
+ void fixTypeVsGeneratedAs();
+ void evaluatePostParsing();
- QString name = QString::null;
+ QString name = QString();
SqliteColumnType* type = nullptr;
QList<Constraint*> constraints;
@@ -106,12 +123,15 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
* Used to remember original name when column was edited and the name was changed.
* It's defined in the constructor to the same value as the name member.
*/
- QString originalName = QString::null;
+ QString originalName = QString();
protected:
QStringList getColumnsInStatement();
TokenList getColumnTokensInStatement();
TokenList rebuildTokensFromContents();
+
+ private:
+ static const QRegExp GENERATED_ALWAYS_REGEXP;
};
typedef QSharedPointer<Column> ColumnPtr;
@@ -149,7 +169,7 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
QString typeString() const;
Type type;
- QString name = QString::null;
+ QString name = QString();
bool autoincrKw = false; // not in docs, but needs to be supported
SqliteConflictAlgo onConflict = SqliteConflictAlgo::null;
SqliteForeignKey* foreignKey = nullptr;
@@ -189,12 +209,12 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
bool ifNotExistsKw = false;
bool tempKw = false;
bool temporaryKw = false;
- QString database = QString::null;
- QString table = QString::null;
+ QString database = QString();
+ QString table = QString();
QList<Column*> columns;
QList<Constraint*> constraints;
SqliteSelect* select = nullptr;
- QString withOutRowId = QString::null;
+ QString withOutRowId = QString();
protected:
QStringList getTablesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp
index 001dd2d..3f2c4e3 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp
@@ -126,7 +126,7 @@ QString SqliteCreateTrigger::time(SqliteCreateTrigger::Time eventTime)
case SqliteCreateTrigger::Time::null:
break;
}
- return QString::null;
+ return QString();
}
SqliteCreateTrigger::Time SqliteCreateTrigger::time(const QString& eventTime)
@@ -154,7 +154,7 @@ QString SqliteCreateTrigger::scopeToString(SqliteCreateTrigger::Scope scope)
case SqliteCreateTrigger::Scope::null:
break;
}
- return QString::null;
+ return QString();
}
SqliteCreateTrigger::Scope SqliteCreateTrigger::stringToScope(const QString& scope)
@@ -180,18 +180,12 @@ QStringList SqliteCreateTrigger::getDatabasesInStatement()
TokenList SqliteCreateTrigger::getTableTokensInStatement()
{
- if (dialect == Dialect::Sqlite2)
- return getObjectTokenListFromNmDbnm("nm2", "dbnm");
- else
- return getTokenListFromNamedKey("nm2");
+ return getTokenListFromNamedKey("nm2");
}
TokenList SqliteCreateTrigger::getDatabaseTokensInStatement()
{
- if (dialect == Dialect::Sqlite2)
- return getDbTokenListFromNmDbnm("nm2", "dbnm");
- else
- return getDbTokenListFromNmDbnm();
+ return getDbTokenListFromNmDbnm();
}
QList<SqliteStatement::FullObject> SqliteCreateTrigger::getFullObjectsInStatement()
@@ -200,14 +194,9 @@ QList<SqliteStatement::FullObject> SqliteCreateTrigger::getFullObjectsInStatemen
// Table object
FullObject fullObj;
- if (dialect == Dialect::Sqlite2)
- fullObj = getFullObjectFromNmDbnm(FullObject::TABLE, "nm2", "dbnm");
- else
- {
- TokenList tableTokens = getTokenListFromNamedKey("nm2");
- if (tableTokens.size() > 0)
- fullObj = getFullObject(FullObject::TABLE, TokenPtr(), tableTokens[0]);
- }
+ TokenList tableTokens = getTokenListFromNamedKey("nm2");
+ if (tableTokens.size() > 0)
+ fullObj = getFullObject(FullObject::TABLE, TokenPtr(), tableTokens[0]);
if (fullObj.isValid())
result << fullObj;
@@ -221,14 +210,9 @@ QList<SqliteStatement::FullObject> SqliteCreateTrigger::getFullObjectsInStatemen
}
// Trigger object
- if (dialect == Dialect::Sqlite2)
- {
- TokenList tableTokens = getTokenListFromNamedKey("nm");
- if (tableTokens.size() > 0)
- fullObj = getFullObject(FullObject::TRIGGER, TokenPtr(), tableTokens[0]);
- }
- else
- fullObj = getFullObjectFromNmDbnm(FullObject::TRIGGER, "nm", "dbnm");
+ fullObj = getFullObjectFromNmDbnm(FullObject::TRIGGER, "nm", "dbnm");
+ if (fullObj.isValid())
+ result << fullObj;
return result;
}
@@ -299,7 +283,7 @@ QString SqliteCreateTrigger::Event::typeToString(SqliteCreateTrigger::Event::Typ
case SqliteCreateTrigger::Event::null:
break;
}
- return QString::null;
+ return QString();
}
SqliteCreateTrigger::Event::Type SqliteCreateTrigger::Event::stringToType(const QString& type)
@@ -333,10 +317,10 @@ TokenList SqliteCreateTrigger::rebuildTokensFromContents()
if (ifNotExistsKw)
builder.withKeyword("IF").withSpace().withKeyword("NOT").withSpace().withKeyword("EXISTS").withSpace();
- if (dialect == Dialect::Sqlite3 && !database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ if (!database.isNull())
+ builder.withOther(database).withOperator(".");
- builder.withOther(trigger, dialect).withSpace();
+ builder.withOther(trigger).withSpace();
switch (eventTime)
{
case Time::BEFORE:
@@ -353,10 +337,7 @@ TokenList SqliteCreateTrigger::rebuildTokensFromContents()
}
builder.withStatement(event).withSpace().withKeyword("ON").withSpace();
- if (dialect == Dialect::Sqlite2 && !database.isNull())
- builder.withOther(database, dialect).withOperator(".");
-
- builder.withOther(table, dialect).withSpace();
+ builder.withOther(table).withSpace();
switch (scope)
{
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h
index 2ccf876..ac7b81f 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h
@@ -70,10 +70,9 @@ class API_EXPORT SqliteCreateTrigger : public SqliteQuery, public SqliteTableRel
bool tempKw = false;
bool temporaryKw = false;
bool ifNotExistsKw = false;
- // The database refers to the trigger name in Sqlite3, but in Sqlite2 it refers to the table.
- QString database = QString::null;
- QString trigger = QString::null;
- QString table = QString::null; // can also be a view name
+ QString database = QString();
+ QString trigger = QString();
+ QString table = QString(); // can also be a view name
Event* event = nullptr;
Time eventTime = Time::null;
Scope scope = Scope::null;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp
index fe638db..f5b54e7 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp
@@ -67,10 +67,7 @@ QStringList SqliteCreateView::getDatabasesInStatement()
TokenList SqliteCreateView::getDatabaseTokensInStatement()
{
- if (dialect == Dialect::Sqlite3)
- return getDbTokenListFromFullname();
- else
- return TokenList();
+ return getDbTokenListFromFullname();
}
QList<SqliteStatement::FullObject> SqliteCreateView::getFullObjectsInStatement()
@@ -78,28 +75,17 @@ QList<SqliteStatement::FullObject> SqliteCreateView::getFullObjectsInStatement()
QList<FullObject> result;
// View object
- FullObject fullObj;
- if (dialect == Dialect::Sqlite3)
- fullObj = getFullObjectFromFullname(FullObject::VIEW);
- else
- {
- TokenList tokens = getTokenListFromNamedKey("nm");
- if (tokens.size() > 0)
- fullObj = getFullObject(FullObject::VIEW, TokenPtr(), tokens[0]);
- }
+ FullObject fullObj = getFullObjectFromFullname(FullObject::VIEW);
if (fullObj.isValid())
result << fullObj;
// Db object
- if (dialect == Dialect::Sqlite3)
+ fullObj = getFirstDbFullObject();
+ if (fullObj.isValid())
{
- fullObj = getFirstDbFullObject();
- if (fullObj.isValid())
- {
- result << fullObj;
- dbTokenForFullObjects = fullObj.database;
- }
+ result << fullObj;
+ dbTokenForFullObjects = fullObj.database;
}
return result;
@@ -119,10 +105,10 @@ TokenList SqliteCreateView::rebuildTokensFromContents()
if (ifNotExists)
builder.withKeyword("IF").withSpace().withKeyword("NOT").withSpace().withKeyword("EXISTS").withSpace();
- if (dialect == Dialect::Sqlite3 && !database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ if (!database.isNull())
+ builder.withOther(database).withOperator(".");
- builder.withOther(view, dialect).withSpace();
+ builder.withOther(view).withSpace();
if (columns.size() > 0)
builder.withParLeft().withStatementList<SqliteIndexedColumn>(columns).withParRight().withSpace();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h
index 1f46d5e..74f6b91 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h
@@ -25,8 +25,8 @@ class API_EXPORT SqliteCreateView : public SqliteQuery, public SqliteDdlWithDbCo
bool tempKw = false;
bool temporaryKw = false;
bool ifNotExists = false;
- QString database = QString::null;
- QString view = QString::null;
+ QString database = QString();
+ QString view = QString();
SqliteSelect* select = nullptr;
QList<SqliteIndexedColumn*> columns;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp
index 1d98c8d..3f1639a 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp
@@ -97,9 +97,9 @@ TokenList SqliteCreateVirtualTable::rebuildTokensFromContents()
builder.withKeyword("IF").withSpace().withKeyword("NOT").withSpace().withKeyword("EXISTS").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
- builder.withKeyword("USING").withSpace().withOther(module, dialect);
+ builder.withKeyword("USING").withSpace().withOther(module);
if (!args.isEmpty())
{
builder.withSpace();
@@ -109,7 +109,7 @@ TokenList SqliteCreateVirtualTable::rebuildTokensFromContents()
if (i > 0)
builder.withOperator(",").withSpace();
- builder.withTokens(Lexer::tokenize(arg, Dialect::Sqlite3));
+ builder.withTokens(Lexer::tokenize(arg));
i++;
}
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.h
index cb2d231..28f91ce 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.h
@@ -31,9 +31,9 @@ class API_EXPORT SqliteCreateVirtualTable : public SqliteQuery
public:
bool ifNotExistsKw = false;
- QString database = QString::null;
- QString table = QString::null;
- QString module = QString::null;
+ QString database = QString();
+ QString table = QString();
+ QString module = QString();
QList<QString> args;
};
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedeferrable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedeferrable.cpp
index 4ef4d51..50b7de2 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedeferrable.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedeferrable.cpp
@@ -11,7 +11,7 @@ QString sqliteDeferrable(SqliteDeferrable deferrable)
case SqliteDeferrable::null:
break;
}
- return QString::null;
+ return QString();
}
SqliteDeferrable sqliteDeferrable(const QString& deferrable)
@@ -38,7 +38,7 @@ QString sqliteInitially(SqliteInitially initially)
case SqliteInitially::null:
break;
}
- return QString::null;
+ return QString();
}
SqliteInitially sqliteInitially(const QString& initially)
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp
index 6026de3..dd4d7cb 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp
@@ -119,12 +119,12 @@ TokenList SqliteDelete::rebuildTokensFromContents()
builder.withKeyword("DELETE").withSpace().withKeyword("FROM").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
- builder.withOther(table, dialect);
+ builder.withOther(table);
if (indexedByKw)
- builder.withSpace().withKeyword("INDEXED").withSpace().withKeyword("BY").withSpace().withOther(indexedBy, dialect);
+ builder.withSpace().withKeyword("INDEXED").withSpace().withKeyword("BY").withSpace().withOther(indexedBy);
else if (notIndexedKw)
builder.withSpace().withKeyword("NOT").withSpace().withKeyword("INDEXED");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h
index 90e1385..5d24619 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h
@@ -31,11 +31,11 @@ class API_EXPORT SqliteDelete : public SqliteQuery
void init(const QString& name1, const QString& name2, SqliteExpr* where, SqliteWith* with);
public:
- QString database = QString::null;
- QString table = QString::null;
+ QString database = QString();
+ QString table = QString();
bool indexedByKw = false;
bool notIndexedKw = false;
- QString indexedBy = QString::null;
+ QString indexedBy = QString();
SqliteExpr* where = nullptr;
SqliteWith* with = nullptr;
};
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp
index 2e39312..8d5f878 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp
@@ -70,7 +70,7 @@ TokenList SqliteDropIndex::rebuildTokensFromContents()
builder.withKeyword("IF").withSpace().withKeyword("EXISTS").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
builder.withOther(index).withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.h
index 9ce7065..4f4364a 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.h
@@ -14,8 +14,8 @@ class API_EXPORT SqliteDropIndex : public SqliteQuery
SqliteStatement* clone();
bool ifExistsKw = false;
- QString database = QString::null;
- QString index = QString::null;
+ QString database = QString();
+ QString index = QString();
protected:
QStringList getDatabasesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp
index c4fc02d..f567cc0 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp
@@ -78,7 +78,7 @@ TokenList SqliteDropTable::rebuildTokensFromContents()
builder.withKeyword("IF").withSpace().withKeyword("EXISTS").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
builder.withOther(table).withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.h
index edc4da4..58706b2 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.h
@@ -14,8 +14,8 @@ class API_EXPORT SqliteDropTable : public SqliteQuery
SqliteStatement* clone();
bool ifExistsKw = false;
- QString database = QString::null;
- QString table = QString::null;
+ QString database = QString();
+ QString table = QString();
protected:
QStringList getTablesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp
index 8921af3..9794ed4 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp
@@ -71,7 +71,7 @@ TokenList SqliteDropTrigger::rebuildTokensFromContents()
builder.withKeyword("IF").withSpace().withKeyword("EXISTS").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
builder.withOther(trigger).withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.h
index 5221959..316af98 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.h
@@ -14,8 +14,8 @@ class API_EXPORT SqliteDropTrigger : public SqliteQuery
SqliteStatement* clone();
bool ifExistsKw = false;
- QString database = QString::null;
- QString trigger = QString::null;
+ QString database = QString();
+ QString trigger = QString();
protected:
QStringList getDatabasesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp
index b992e98..423b1da 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp
@@ -34,17 +34,11 @@ SqliteStatement*SqliteDropView::clone()
QStringList SqliteDropView::getDatabasesInStatement()
{
- if (dialect == Dialect::Sqlite2)
- return QStringList();
-
return getStrListFromValue(database);
}
TokenList SqliteDropView::getDatabaseTokensInStatement()
{
- if (dialect == Dialect::Sqlite2)
- return TokenList();
-
return getDbTokenListFromFullname();
}
@@ -77,7 +71,7 @@ TokenList SqliteDropView::rebuildTokensFromContents()
builder.withKeyword("IF").withSpace().withKeyword("EXISTS").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
builder.withOther(view).withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.h
index 853ccef..2f0882c 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.h
@@ -14,8 +14,8 @@ class API_EXPORT SqliteDropView : public SqliteQuery
SqliteStatement* clone();
bool ifExistsKw = false;
- QString database = QString::null;
- QString view = QString::null;
+ QString database = QString();
+ QString view = QString();
protected:
QStringList getDatabasesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp
index d17205a..e2c79ea 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp
@@ -2,6 +2,7 @@
#include "sqliteraise.h"
#include "sqliteselect.h"
#include "sqlitecolumntype.h"
+#include "sqlitefilterover.h"
#include "parser/statementtokenbuilder.h"
#include "common/utils_sql.h"
#include "common/global.h"
@@ -25,6 +26,7 @@ SqliteExpr::SqliteExpr(const SqliteExpr& other) :
DEEP_COPY_COLLECTION(SqliteExpr, exprList);
DEEP_COPY_FIELD(SqliteSelect, select);
DEEP_COPY_FIELD(SqliteRaise, raiseFunction);
+ DEEP_COPY_FIELD(SqliteFilterOver, filterOver);
}
SqliteExpr::~SqliteExpr()
@@ -59,7 +61,7 @@ QString SqliteExpr::likeOp(SqliteExpr::LikeOp value)
case SqliteExpr::LikeOp::MATCH:
return "MATCH";
default:
- return QString::null;
+ return QString();
}
}
@@ -87,7 +89,7 @@ QString SqliteExpr::notNullOp(SqliteExpr::NotNull value)
case SqliteExpr::NotNull::NOTNULL:
return "NOTNULL";
default:
- return QString::null;
+ return QString();
}
}
@@ -168,10 +170,7 @@ void SqliteExpr::initFunction(const QString& fnName, int distinct, const QList<S
mode = SqliteExpr::Mode::FUNCTION;
function = fnName;
this->exprList = exprList;
- if (distinct == 1)
- distinctKw = true;
- else if (distinct == 2)
- allKw = true;
+ initDistinct(distinct);
for (SqliteExpr* expr : exprList)
expr->setParent(this);
@@ -184,6 +183,32 @@ void SqliteExpr::initFunction(const QString& fnName, bool star)
this->star = star;
}
+void SqliteExpr::initWindowFunction(const QString& fnName, int distinct, const QList<SqliteExpr*>& exprList, SqliteFilterOver* filterOver)
+{
+ mode = SqliteExpr::Mode::WINDOW_FUNCTION;
+ this->function = fnName;
+ this->exprList = exprList;
+ initDistinct(distinct);
+ this->filterOver = filterOver;
+
+ for (SqliteExpr* expr : exprList)
+ expr->setParent(this);
+
+ if (filterOver)
+ filterOver->setParent(this);
+}
+
+void SqliteExpr::initWindowFunction(const QString& fnName, SqliteFilterOver* filterOver)
+{
+ mode = SqliteExpr::Mode::WINDOW_FUNCTION;
+ this->function = fnName;
+ this->star = true;
+ this->filterOver = filterOver;
+
+ if (filterOver)
+ filterOver->setParent(this);
+}
+
void SqliteExpr::initBinOp(SqliteExpr *expr1, const QString& op, SqliteExpr *expr2)
{
mode = SqliteExpr::Mode::BINARY_OP;
@@ -363,6 +388,36 @@ void SqliteExpr::detectDoubleQuotes(bool recursively)
}
}
+bool SqliteExpr::replace(SqliteExpr* toBeReplaced, SqliteExpr* replaceWith)
+{
+ if (expr1 == toBeReplaced)
+ {
+ expr1 = replaceWith;
+ return true;
+ }
+
+ if (expr2 == toBeReplaced)
+ {
+ expr2 = replaceWith;
+ return true;
+ }
+
+ if (expr3 == toBeReplaced)
+ {
+ expr3 = replaceWith;
+ return true;
+ }
+
+ int idx = exprList.indexOf(toBeReplaced);
+ if (idx > -1)
+ {
+ exprList.replace(idx, replaceWith);
+ return true;
+ }
+
+ return false;
+}
+
QStringList SqliteExpr::getColumnsInStatement()
{
return getStrListFromValue(column);
@@ -498,6 +553,8 @@ TokenList SqliteExpr::rebuildTokensFromContents()
builder.withOther(function).withParLeft();
if (distinctKw)
builder.withKeyword("DISTINCT");
+ else if (allKw)
+ builder.withKeyword("DISTINCT");
if (star)
builder.withOperator("*").withParRight();
@@ -505,6 +562,20 @@ TokenList SqliteExpr::rebuildTokensFromContents()
builder.withStatementList(exprList).withParRight();
break;
+ case SqliteExpr::Mode::WINDOW_FUNCTION:
+ builder.withOther(function).withParLeft();
+ if (distinctKw)
+ builder.withKeyword("DISTINCT");
+ else if (allKw)
+ builder.withKeyword("DISTINCT");
+
+ if (star)
+ builder.withOperator("*").withParRight();
+ else
+ builder.withStatementList(exprList).withParRight();
+
+ builder.withSpace().withStatement(filterOver);
+ break;
case SqliteExpr::Mode::SUB_EXPR:
builder.withParLeft().withStatement(expr1).withParRight();
break;
@@ -513,7 +584,7 @@ TokenList SqliteExpr::rebuildTokensFromContents()
.withStatement(columnType).withParRight();
break;
case SqliteExpr::Mode::COLLATE:
- builder.withStatement(expr1).withSpace().withKeyword("COLLATE").withSpace().withOther(collation, dialect);
+ builder.withStatement(expr1).withSpace().withKeyword("COLLATE").withSpace().withOther(collation);
break;
case SqliteExpr::Mode::LIKE:
builder.withTokens(rebuildLike());
@@ -562,15 +633,15 @@ TokenList SqliteExpr::rebuildId()
{
StatementTokenBuilder builder;
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
if (!table.isNull())
- builder.withOther(table, dialect).withOperator(".");
+ builder.withOther(table).withOperator(".");
if (table.isNull() && possibleDoubleQuotedString)
- builder.withStringPossiblyOther(column, dialect);
+ builder.withStringPossiblyOther(column);
else
- builder.withOther(column, dialect);
+ builder.withOther(column);
return builder.build();
}
@@ -652,9 +723,9 @@ TokenList SqliteExpr::rebuildIn()
else
{
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
- builder.withOther(table, dialect);
+ builder.withOther(table);
}
return builder.build();
}
@@ -686,3 +757,11 @@ TokenList SqliteExpr::rebuildCase()
builder.withKeyword("END");
return builder.build();
}
+
+void SqliteExpr::initDistinct(int distinct)
+{
+ if (distinct == 1)
+ distinctKw = true;
+ else if (distinct == 2)
+ allKw = true;
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h
index c65a8e2..ef4c7da 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h
@@ -6,6 +6,7 @@
#include <QVariant>
#include <QList>
+class SqliteFilterOver;
class SqliteSelect;
class SqliteColumnType;
class SqliteRaise;
@@ -26,7 +27,7 @@ class API_EXPORT SqliteExpr : public SqliteStatement
SUB_EXPR,
ROW_VALUE,
CAST,
- COLLATE, // in Sqlite2 exists only in expr of sortlist
+ COLLATE,
LIKE,
NULL_,
NOTNULL,
@@ -36,7 +37,8 @@ class API_EXPORT SqliteExpr : public SqliteStatement
EXISTS,
CASE,
SUB_SELECT,
- RAISE
+ RAISE,
+ WINDOW_FUNCTION
};
enum class NotNull
@@ -79,6 +81,8 @@ class API_EXPORT SqliteExpr : public SqliteStatement
void initCast(SqliteExpr* expr, SqliteColumnType* type);
void initFunction(const QString& fnName, int distinct, const QList<SqliteExpr*>& exprList);
void initFunction(const QString& fnName, bool star = false);
+ void initWindowFunction(const QString& fnName, int distinct, const QList<SqliteExpr*>& exprList, SqliteFilterOver* filterOver);
+ void initWindowFunction(const QString& fnName, SqliteFilterOver* filterOver);
void initBinOp(SqliteExpr* expr1, const QString& op, SqliteExpr* expr2);
void initUnaryOp(SqliteExpr* expr, const QString& op);
void initLike(SqliteExpr* expr1, bool notKw, SqliteExpr::LikeOp likeOp, SqliteExpr* expr2, SqliteExpr* expr3 = nullptr);
@@ -91,27 +95,29 @@ class API_EXPORT SqliteExpr : public SqliteStatement
void initExists(SqliteSelect* select);
void initSubSelect(SqliteSelect* select);
void initCase(SqliteExpr* expr1, const QList<SqliteExpr*>& exprList, SqliteExpr* expr2);
- void initRaise(const QString& type, const QString& text = QString::null);
+ void initRaise(const QString& type, const QString& text = QString());
void detectDoubleQuotes(bool recursively = true);
+ bool replace(SqliteExpr* toBeReplaced, SqliteExpr* replaceWith);
Mode mode = Mode::null;
QVariant literalValue = QVariant();
bool literalNull = false;
- QString bindParam = QString::null;
- QString database = QString::null;
- QString table = QString::null;
- QString column = QString::null;
- QString unaryOp = QString::null;
- QString binaryOp = QString::null;
- QString function = QString::null;
- QString collation = QString::null;
- QString ctime = QString::null;
+ QString bindParam = QString();
+ QString database = QString();
+ QString table = QString();
+ QString column = QString();
+ QString unaryOp = QString();
+ QString binaryOp = QString();
+ QString function = QString();
+ QString collation = QString();
+ QString ctime = QString();
SqliteColumnType* columnType = nullptr;
SqliteExpr* expr1 = nullptr;
SqliteExpr* expr2 = nullptr;
SqliteExpr* expr3 = nullptr;
QList<SqliteExpr*> exprList;
SqliteSelect* select = nullptr;
+ SqliteFilterOver* filterOver = nullptr;
bool distinctKw = false;
bool allKw = false; // alias for DISTINCT as for sqlite3 grammar
bool star = false;
@@ -141,6 +147,7 @@ class API_EXPORT SqliteExpr : public SqliteStatement
TokenList rebuildBetween();
TokenList rebuildIn();
TokenList rebuildCase();
+ void initDistinct(int distinct);
};
typedef QSharedPointer<SqliteExpr> SqliteExprPtr;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitefilterover.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitefilterover.cpp
new file mode 100644
index 0000000..08b4f88
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitefilterover.cpp
@@ -0,0 +1,138 @@
+#include "sqlitefilterover.h"
+#include "sqliteexpr.h"
+#include "parser/statementtokenbuilder.h"
+#include "common/global.h"
+
+SqliteFilterOver::SqliteFilterOver()
+{
+
+}
+
+SqliteFilterOver::~SqliteFilterOver()
+{
+}
+
+SqliteFilterOver::SqliteFilterOver(const SqliteFilterOver& other) :
+ SqliteStatement(other)
+{
+ DEEP_COPY_FIELD(Filter, filter);
+ DEEP_COPY_FIELD(Over, over);
+}
+
+SqliteFilterOver::SqliteFilterOver(SqliteFilterOver::Filter* filter, SqliteFilterOver::Over* over)
+{
+ this->filter = filter;
+ this->over = over;
+
+ if (filter)
+ filter->setParent(this);
+
+ if (over)
+ over->setParent(this);
+}
+
+SqliteStatement* SqliteFilterOver::clone()
+{
+ return new SqliteFilterOver(*this);
+}
+
+TokenList SqliteFilterOver::rebuildTokensFromContents()
+{
+ StatementTokenBuilder builder;
+
+ if (filter)
+ builder.withStatement(filter);
+
+ if (filter || over)
+ builder.withSpace();
+
+ if (over)
+ builder.withStatement(over);
+
+ return builder.build();
+}
+
+SqliteFilterOver::Over::Over()
+{
+}
+
+SqliteFilterOver::Over::Over(const SqliteFilterOver::Over& other) :
+ SqliteStatement(other), name(other.name), mode(other.mode)
+{
+ DEEP_COPY_FIELD(SqliteWindowDefinition::Window, window);
+}
+
+SqliteFilterOver::Over::~Over()
+{
+}
+
+SqliteFilterOver::Over::Over(SqliteWindowDefinition::Window* window)
+{
+ this->mode = Mode::WINDOW;
+ this->window = window;
+ if (window)
+ window->setParent(this);
+}
+
+SqliteFilterOver::Over::Over(const QString& name)
+{
+ this->mode = Mode::NAME;
+ this->name = name;
+}
+
+SqliteStatement* SqliteFilterOver::Over::clone()
+{
+ return new SqliteFilterOver::Over(*this);
+}
+
+TokenList SqliteFilterOver::Over::rebuildTokensFromContents()
+{
+ StatementTokenBuilder builder;
+
+ builder.withKeyword("OVER").withSpace();
+
+ switch (mode)
+ {
+ case SqliteFilterOver::Over::Mode::WINDOW:
+ builder.withParLeft().withStatement(window).withParRight();
+ break;
+ case SqliteFilterOver::Over::Mode::NAME:
+ builder.withOther(name);
+ break;
+ }
+
+ return builder.build();
+}
+
+
+SqliteFilterOver::Filter::Filter(SqliteExpr* expr)
+{
+ this->expr = expr;
+ if (expr)
+ expr->setParent(this);
+}
+
+SqliteFilterOver::Filter::Filter(const SqliteFilterOver::Filter& other) :
+ SqliteStatement(other)
+{
+ DEEP_COPY_FIELD(SqliteExpr, expr);
+}
+
+SqliteStatement* SqliteFilterOver::Filter::clone()
+{
+ return new SqliteFilterOver::Filter(*this);
+}
+
+TokenList SqliteFilterOver::Filter::rebuildTokensFromContents()
+{
+ StatementTokenBuilder builder;
+
+ builder.withKeyword("FILTER").withSpace().withParLeft().withKeyword("WHERE").withSpace().withStatement(expr).withParRight();
+
+ return builder.build();
+}
+
+
+SqliteFilterOver::Filter::~Filter()
+{
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitefilterover.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitefilterover.h
new file mode 100644
index 0000000..3f023d9
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitefilterover.h
@@ -0,0 +1,65 @@
+#ifndef SQLITEFILTEROVER_H
+#define SQLITEFILTEROVER_H
+
+#include "sqlitestatement.h"
+#include "sqlitewindowdefinition.h"
+
+class SqliteFilterOver : public SqliteStatement
+{
+ public:
+ class Over : public SqliteStatement
+ {
+ public:
+ enum class Mode
+ {
+ WINDOW,
+ NAME
+ };
+
+ Over();
+ Over(const Over& other);
+ ~Over();
+ Over(SqliteWindowDefinition::Window* window);
+ Over(const QString& name);
+
+ SqliteStatement* clone();
+
+ SqliteWindowDefinition::Window* window = nullptr;
+ QString name = QString();
+ Mode mode = Mode::WINDOW;
+
+ protected:
+ TokenList rebuildTokensFromContents();
+ };
+
+ class Filter : public SqliteStatement
+ {
+ public:
+ Filter();
+ Filter(const Filter& other);
+ ~Filter();
+ Filter(SqliteExpr* expr);
+
+ SqliteStatement* clone();
+
+ SqliteExpr* expr;
+
+ protected:
+ TokenList rebuildTokensFromContents();
+ };
+
+ SqliteFilterOver();
+ ~SqliteFilterOver();
+ SqliteFilterOver(const SqliteFilterOver& other);
+ SqliteFilterOver(Filter* filter, Over* over);
+
+ SqliteStatement* clone();
+
+ Filter* filter = nullptr;
+ Over* over = nullptr;
+
+ protected:
+ TokenList rebuildTokensFromContents();
+};
+
+#endif // SQLITEFILTEROVER_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.cpp
index 9a29db2..9bfd56c 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.cpp
@@ -35,7 +35,7 @@ QString SqliteForeignKey::Condition::toString(SqliteForeignKey::Condition::React
case SqliteForeignKey::Condition::NO_ACTION:
return "NO ACTION";
}
- return QString::null;
+ return QString();
}
SqliteForeignKey::Condition::Reaction SqliteForeignKey::Condition::toEnum(const QString& reaction)
@@ -115,7 +115,7 @@ TokenList SqliteForeignKey::rebuildTokensFromContents()
{
StatementTokenBuilder builder;
- builder.withKeyword("REFERENCES").withSpace().withOther(foreignTable, dialect);
+ builder.withKeyword("REFERENCES").withSpace().withOther(foreignTable);
if (indexedColumns.size() > 0)
builder.withSpace().withParLeft().withStatementList(indexedColumns).withParRight();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.h
index 18e0bcb..62dd84d 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteforeignkey.h
@@ -41,7 +41,7 @@ class API_EXPORT SqliteForeignKey : public SqliteStatement
SqliteStatement* clone();
Action action;
- QString name = QString::null;
+ QString name = QString();
Reaction reaction = NO_ACTION;
protected:
@@ -57,7 +57,7 @@ class API_EXPORT SqliteForeignKey : public SqliteStatement
SqliteStatement* clone();
- QString foreignTable = QString::null;
+ QString foreignTable = QString();
QList<SqliteIndexedColumn*> indexedColumns;
QList<Condition*> conditions;
SqliteDeferrable deferrable = SqliteDeferrable::null; // Those two are for table constraint only,
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp
index 142af06..54ebc89 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp
@@ -58,9 +58,9 @@ TokenList SqliteIndexedColumn::getColumnTokensInStatement()
TokenList SqliteIndexedColumn::rebuildTokensFromContents()
{
StatementTokenBuilder builder;
- builder.withOther(name, dialect);
+ builder.withOther(name);
if (!collate.isNull())
- builder.withSpace().withKeyword("COLLATE").withSpace().withOther(collate, dialect);
+ builder.withSpace().withKeyword("COLLATE").withSpace().withOther(collate);
builder.withSortOrder(sortOrder);
return builder.build();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h
index c0fe680..34cf4a4 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h
@@ -21,9 +21,9 @@ class API_EXPORT SqliteIndexedColumn : public SqliteStatement, public SqliteExte
QString getCollation() const;
void clearCollation();
- QString name = QString::null;
+ QString name = QString();
SqliteSortOrder sortOrder = SqliteSortOrder::null;
- QString collate = QString::null;
+ QString collate = QString();
protected:
QStringList getColumnsInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp
index e48cffb..906b385 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp
@@ -191,9 +191,9 @@ TokenList SqliteInsert::rebuildTokensFromContents()
builder.withKeyword("INTO").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
- builder.withOther(table, dialect).withSpace();
+ builder.withOther(table).withSpace();
if (defaultValuesKw)
{
@@ -202,7 +202,7 @@ TokenList SqliteInsert::rebuildTokensFromContents()
else
{
if (columnNames.size() > 0)
- builder.withParLeft().withOtherList(columnNames, dialect).withParRight().withSpace();
+ builder.withParLeft().withOtherList(columnNames).withParRight().withSpace();
if (select)
{
@@ -210,10 +210,6 @@ TokenList SqliteInsert::rebuildTokensFromContents()
if (upsert)
builder.withSpace().withStatement(upsert);
}
- else if (dialect == Dialect::Sqlite2) // Sqlite2 uses classic single row values
- {
- builder.withKeyword("VALUES").withSpace().withParLeft().withStatementList(values).withParRight();
- }
}
builder.withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h
index 2ee4965..40581cd 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h
@@ -45,8 +45,8 @@ class API_EXPORT SqliteInsert : public SqliteQuery
bool replaceKw = false;
bool defaultValuesKw = false;
SqliteConflictAlgo onConflict = SqliteConflictAlgo::null;
- QString database = QString::null;
- QString table = QString::null;
+ QString database = QString();
+ QString table = QString();
QStringList columnNames;
QList<SqliteExpr*> values;
SqliteSelect* select = nullptr;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitenulls.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitenulls.cpp
new file mode 100644
index 0000000..46102a9
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitenulls.cpp
@@ -0,0 +1,26 @@
+#include "sqlitenulls.h"
+
+
+SqliteNulls sqliteNulls(const QString& value)
+{
+ if (value == "NULLS FIRST")
+ return SqliteNulls::FIRST;
+ else if (value == "NULLS LAST")
+ return SqliteNulls::LAST;
+ else
+ return SqliteNulls::null;
+}
+
+QString sqliteNulls(SqliteNulls value)
+{
+ switch (value)
+ {
+ case SqliteNulls::FIRST:
+ return "FIRST";
+ case SqliteNulls::LAST:
+ return "LAST";
+ case SqliteNulls::null:
+ break;
+ }
+ return QString();
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitenulls.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitenulls.h
new file mode 100644
index 0000000..3553eae
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitenulls.h
@@ -0,0 +1,17 @@
+#ifndef SQLITENULLS_H
+#define SQLITENULLS_H
+
+#include "coreSQLiteStudio_global.h"
+#include <QString>
+
+enum class SqliteNulls
+{
+ FIRST,
+ LAST,
+ null
+};
+
+API_EXPORT SqliteNulls sqliteNulls(const QString& value);
+API_EXPORT QString sqliteNulls(SqliteNulls value);
+
+#endif // SQLITENULLS_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp
index 8eb7b46..732c0a2 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp
@@ -2,21 +2,23 @@
#include "sqliteexpr.h"
#include "parser/statementtokenbuilder.h"
#include "common/global.h"
+#include <QDebug>
SqliteOrderBy::SqliteOrderBy()
{
}
SqliteOrderBy::SqliteOrderBy(const SqliteOrderBy& other) :
- SqliteStatement(other), order(other.order)
+ SqliteStatement(other), order(other.order), nulls(other.nulls)
{
DEEP_COPY_FIELD(SqliteExpr, expr);
}
-SqliteOrderBy::SqliteOrderBy(SqliteExpr *expr, SqliteSortOrder order)
+SqliteOrderBy::SqliteOrderBy(SqliteExpr *expr, SqliteSortOrder order, SqliteNulls nulls)
{
this->expr = expr;
this->order = order;
+ this->nulls = nulls;
if (expr)
expr->setParent(this);
}
@@ -44,7 +46,7 @@ QString SqliteOrderBy::getColumnName() const
return expr->column;
if (expr->mode == SqliteExpr::Mode::COLLATE && expr->expr1 && expr->expr1->mode == SqliteExpr::Mode::ID)
- return expr->expr1->literalValue.toString();
+ return expr->expr1->column;
return QString();
}
@@ -107,9 +109,66 @@ TokenList SqliteOrderBy::rebuildTokensFromContents()
if (order != SqliteSortOrder::null)
builder.withSpace().withKeyword(sqliteSortOrder(order));
+ if (nulls != SqliteNulls::null)
+ builder.withSpace().withKeyword("NULLS").withSpace().withKeyword(sqliteNulls(nulls));
+
return builder.build();
}
+void SqliteOrderBy::evaluatePostParsing()
+{
+ pullLastCollationAsOuterExpr();
+}
+
+void SqliteOrderBy::pullLastCollationAsOuterExpr()
+{
+ /*
+ * If the order statement is like: columnName + 2 COLLATE BINARY ASC
+ * then the COLLATE is associated with the "2" subexpr, instead of the most outer expr.
+ * Looks like SQLite's parser does the same, but they don't care about the depth as we do here.
+ * Therefore if we idenfity this case, we need to pull the inner expr to outside.
+ */
+ TokenPtr collateToken = expr->tokens.findLast(Token::KEYWORD, "COLLATE", Qt::CaseInsensitive);
+ if (collateToken.isNull())
+ return;
+
+ int lastCollateIdx = expr->tokens.indexOf(collateToken);
+ if (expr->tokens.mid(lastCollateIdx).filterWhiteSpaces().size() != 2)
+ return;
+
+ // This is the case. We need to pull the expr to the top level.
+ SqliteStatement* stmt = expr->findStatementWithToken(collateToken);
+ SqliteExpr* collateExpr = dynamic_cast<SqliteExpr*>(stmt);
+ if (!collateExpr)
+ {
+ qCritical() << "Could not cast statement to SqliteExpr, even though it's identified as COLLATE expr. The actual contents:"
+ << collateExpr->detokenize();
+ return;
+ }
+
+ if (collateExpr == expr)
+ return; // it's already the top-level expr, we're fine.
+
+ SqliteExpr* parentExpr = dynamic_cast<SqliteExpr*>(collateExpr->parentStatement());
+ if (!parentExpr)
+ {
+ qCritical() << "Could not cast parent statement to SqliteExpr, even though parent of COLLATE should be another expr at this stage."
+ << "The qobject type of parent:" << collateExpr->parentStatement()->metaObject()->className();
+ return;
+ }
+
+ // Take out COLLATE from its current place
+ collateExpr->expr1->setParent(parentExpr); // New parent of COLLATE's expr is now parent of COLLATE
+ parentExpr->replace(collateExpr, collateExpr->expr1); // New child expr of COLLATE's parent is now child of COLLATE
+
+ // Put it at top level
+ collateExpr->expr1 = expr; // COLLATE's child is set to the old top level expr
+ expr->setParent(collateExpr); // Old top level expr gets COLLATE as parent
+ expr = collateExpr; // New top level is now COLLATE
+ collateExpr->setParent(this); // COLLATE's new parent is this
+
+ rebuildTokens();
+}
void SqliteOrderBy::clearCollation()
{
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h
index 4f75c78..4f05d50 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h
@@ -3,6 +3,7 @@
#include "sqlitestatement.h"
#include "sqlitesortorder.h"
+#include "sqlitenulls.h"
#include "sqliteextendedindexedcolumn.h"
class SqliteExpr;
@@ -12,7 +13,7 @@ class API_EXPORT SqliteOrderBy : public SqliteStatement, public SqliteExtendedIn
public:
SqliteOrderBy();
SqliteOrderBy(const SqliteOrderBy& other);
- SqliteOrderBy(SqliteExpr* expr, SqliteSortOrder order);
+ SqliteOrderBy(SqliteExpr* expr, SqliteSortOrder order, SqliteNulls nulls);
~SqliteOrderBy();
SqliteStatement* clone();
@@ -26,9 +27,14 @@ class API_EXPORT SqliteOrderBy : public SqliteStatement, public SqliteExtendedIn
SqliteExpr* expr = nullptr;
SqliteSortOrder order = SqliteSortOrder::null;
+ SqliteNulls nulls = SqliteNulls::null;
protected:
TokenList rebuildTokensFromContents();
+ void evaluatePostParsing();
+
+ private:
+ void pullLastCollationAsOuterExpr();
};
typedef QSharedPointer<SqliteOrderBy> SqliteOrderByPtr;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp
index 4660e4f..4d13d36 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp
@@ -53,7 +53,7 @@ QStringList SqlitePragma::getDatabasesInStatement()
TokenList SqlitePragma::getDatabaseTokensInStatement()
{
- if (dialect == Dialect::Sqlite2 || database.isNull())
+ if (database.isNull())
return TokenList();
return getTokenListFromNamedKey("nm");
@@ -62,7 +62,7 @@ TokenList SqlitePragma::getDatabaseTokensInStatement()
QList<SqliteStatement::FullObject> SqlitePragma::getFullObjectsInStatement()
{
QList<FullObject> result;
- if (dialect == Dialect::Sqlite2 || database.isNull())
+ if (database.isNull())
return result;
// Db object
@@ -94,9 +94,9 @@ TokenList SqlitePragma::rebuildTokensFromContents()
builder.withKeyword("PRAGMA").withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
- builder.withOther(pragmaName, dialect);
+ builder.withOther(pragmaName);
if (equalsOp)
builder.withSpace().withOperator("=").withSpace().withLiteralValue(value);
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.h
index 364a16f..8d75ae4 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.h
@@ -29,8 +29,8 @@ class API_EXPORT SqlitePragma : public SqliteQuery
void initName(const QString& name1, const QString& name2);
public:
- QString database = QString::null;
- QString pragmaName = QString::null;
+ QString database = QString();
+ QString pragmaName = QString();
QVariant value = QVariant();
bool equalsOp = false;
bool parenthesis = false;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp
index c369e0e..1c04ca6 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp
@@ -61,6 +61,44 @@ QString sqliteQueryTypeToString(const SqliteQueryType& type)
case SqliteQueryType::Vacuum:
return "Vacuum";
default:
- return QString::null;
+ return QString();
+ }
+}
+
+bool isDataReturningQuery(const SqliteQueryType& type)
+{
+ switch (type)
+ {
+ case SqliteQueryType::Select:
+ case SqliteQueryType::Pragma:
+ return true;
+ case SqliteQueryType::UNDEFINED:
+ case SqliteQueryType::EMPTY:
+ case SqliteQueryType::AlterTable:
+ case SqliteQueryType::Analyze:
+ case SqliteQueryType::Attach:
+ case SqliteQueryType::BeginTrans:
+ case SqliteQueryType::CommitTrans:
+ case SqliteQueryType::Copy:
+ case SqliteQueryType::CreateIndex:
+ case SqliteQueryType::CreateTable:
+ case SqliteQueryType::CreateTrigger:
+ case SqliteQueryType::CreateView:
+ case SqliteQueryType::CreateVirtualTable:
+ case SqliteQueryType::Delete:
+ case SqliteQueryType::Detach:
+ case SqliteQueryType::DropIndex:
+ case SqliteQueryType::DropTable:
+ case SqliteQueryType::DropTrigger:
+ case SqliteQueryType::DropView:
+ case SqliteQueryType::Insert:
+ case SqliteQueryType::Reindex:
+ case SqliteQueryType::Release:
+ case SqliteQueryType::Rollback:
+ case SqliteQueryType::Savepoint:
+ case SqliteQueryType::Update:
+ case SqliteQueryType::Vacuum:
+ default:
+ return false;
}
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.h
index 763fcfa..9326bf4 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.h
@@ -37,5 +37,6 @@ enum class SqliteQueryType
};
QString API_EXPORT sqliteQueryTypeToString(const SqliteQueryType& type);
+bool API_EXPORT isDataReturningQuery(const SqliteQueryType& type);
#endif // SQLITEQUERYTYPE_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.cpp
index b606baa..1e385b9 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.cpp
@@ -54,7 +54,7 @@ QString SqliteRaise::raiseType(SqliteRaise::Type value)
case SqliteRaise::Type::FAIL:
return "FAIL";
default:
- return QString::null;
+ return QString();
}
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.h
index 1b844f8..2330867 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteraise.h
@@ -27,7 +27,7 @@ class API_EXPORT SqliteRaise : public SqliteStatement
static QString raiseType(Type value);
Type type = Type::null;
- QString message = QString::null;
+ QString message = QString();
protected:
TokenList rebuildTokensFromContents();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp
index 6f863f9..daf8893 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp
@@ -74,7 +74,7 @@ TokenList SqliteReindex::rebuildTokensFromContents()
builder.withTokens(SqliteQuery::rebuildTokensFromContents());
builder.withKeyword("REINDEX");
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
builder.withOther(table).withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.h
index 642b5bf..2fe05d5 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.h
@@ -14,8 +14,8 @@ class API_EXPORT SqliteReindex : public SqliteQuery
SqliteStatement* clone();
- QString database = QString::null;
- QString table = QString::null;
+ QString database = QString();
+ QString table = QString();
protected:
QStringList getTablesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp
index f71d61c..8eb53c0 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp
@@ -33,7 +33,7 @@ TokenList SqliteRelease::rebuildTokensFromContents()
if (savepointKw)
builder.withKeyword("SAVEPOINT").withSpace();
- builder.withOther(name, dialect).withOperator(";");
+ builder.withOther(name).withOperator(";");
return builder.build();
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.h
index d115669..64008f3 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.h
@@ -14,7 +14,7 @@ class API_EXPORT SqliteRelease : public SqliteQuery
SqliteStatement* clone();
- QString name = QString::null;
+ QString name = QString();
bool savepointKw = false;
protected:
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp
index b21b6ae..3af6b8c 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp
@@ -50,7 +50,7 @@ TokenList SqliteRollback::rebuildTokensFromContents()
if (savepointKw)
builder.withKeyword("SAVEPOINT").withSpace();
- builder.withOther(name, dialect);
+ builder.withOther(name);
}
builder.withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.h
index 1dc1574..6adc4c0 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.h
@@ -17,7 +17,7 @@ class API_EXPORT SqliteRollback : public SqliteQuery
bool transactionKw = false;
bool toKw = false;
bool savepointKw = false;
- QString name = QString::null;
+ QString name = QString();
protected:
TokenList rebuildTokensFromContents();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp
index 1ac50cd..e7bd451 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp
@@ -28,6 +28,6 @@ TokenList SqliteSavepoint::rebuildTokensFromContents()
{
StatementTokenBuilder builder;
builder.withTokens(SqliteQuery::rebuildTokensFromContents());
- builder.withKeyword("SAVEPOINT").withSpace().withOther(name, dialect).withOperator(";");
+ builder.withKeyword("SAVEPOINT").withSpace().withOther(name).withOperator(";");
return builder.build();
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.h
index bd75c76..f1ec356 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.h
@@ -14,7 +14,7 @@ class API_EXPORT SqliteSavepoint : public SqliteQuery
SqliteStatement* clone();
- QString name = QString::null;
+ QString name = QString();
protected:
TokenList rebuildTokensFromContents();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp
index 8038cb6..e0439d2 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp
@@ -3,6 +3,7 @@
#include "parser/statementtokenbuilder.h"
#include "common/global.h"
#include "sqlitewith.h"
+#include "sqlitewindowdefinition.h"
#include <QSet>
SqliteSelect::SqliteSelect()
@@ -66,7 +67,7 @@ SqliteSelect* SqliteSelect::append(SqliteSelect* select, SqliteSelect::CompoundO
resColList.clear();
for (SqliteExpr* value : singleValues)
{
- resCol = new Core::ResultColumn(value, false, QString::null);
+ resCol = new Core::ResultColumn(value, false, QString());
value->detectDoubleQuotes(); // invoke explicitly before rebuilding tokens not to lose this information
resCol->rebuildTokens();
resCol->setParent(core);
@@ -97,7 +98,7 @@ QString SqliteSelect::compoundOperator(SqliteSelect::CompoundOperator op)
case SqliteSelect::CompoundOperator::null:
break;
}
- return QString::null;
+ return QString();
}
SqliteSelect::CompoundOperator SqliteSelect::compoundOperator(const QString& op)
@@ -142,11 +143,21 @@ SqliteSelect::Core::Core(const SqliteSelect::Core& other) :
DEEP_COPY_FIELD(SqliteExpr, where);
DEEP_COPY_FIELD(SqliteExpr, having);
DEEP_COPY_COLLECTION(SqliteExpr, groupBy);
+ DEEP_COPY_COLLECTION(SqliteWindowDefinition, windows);
DEEP_COPY_COLLECTION(SqliteOrderBy, orderBy);
DEEP_COPY_FIELD(SqliteLimit, limit);
}
-SqliteSelect::Core::Core(int distinct, const QList<ResultColumn *> &resCols, SqliteSelect::Core::JoinSource *src, SqliteExpr *where, const QList<SqliteExpr *> &groupBy, SqliteExpr *having, const QList<SqliteOrderBy*>& orderBy, SqliteLimit* limit)
+SqliteSelect::Core::Core(int distinct, const QList<ResultColumn*>& resCols, JoinSource* src,
+ SqliteExpr* where, const QList<SqliteExpr*>& groupBy, SqliteExpr* having,
+ const QList<SqliteOrderBy*>& orderBy, SqliteLimit* limit) :
+ Core(distinct, resCols, src, where, groupBy, having, QList<SqliteWindowDefinition*>(), orderBy, limit)
+{
+}
+
+SqliteSelect::Core::Core(int distinct, const QList<ResultColumn *> &resCols, JoinSource *src,
+ SqliteExpr *where, const QList<SqliteExpr *> &groupBy, SqliteExpr *having, const QList<SqliteWindowDefinition*> windows,
+ const QList<SqliteOrderBy*>& orderBy, SqliteLimit* limit)
{
if (distinct == 1)
distinctKw = true;
@@ -156,6 +167,7 @@ SqliteSelect::Core::Core(int distinct, const QList<ResultColumn *> &resCols, Sql
from = src;
this->where = where;
this->having = having;
+ this->windows = windows;
this->groupBy = groupBy;
resultColumns = resCols;
this->limit = limit;
@@ -173,6 +185,9 @@ SqliteSelect::Core::Core(int distinct, const QList<ResultColumn *> &resCols, Sql
if (limit)
limit->setParent(this);
+ for (SqliteWindowDefinition* win : windows)
+ win->setParent(this);
+
for (SqliteOrderBy* order : orderBy)
order->setParent(this);
@@ -246,7 +261,7 @@ TokenList SqliteSelect::Core::ResultColumn::getTableTokensInStatement()
return TokenList();
// Now, we know table was specified
- return getTokenListFromNamedKey("nm");
+ return getTokenListFromNamedKey("tnm");
}
QList<SqliteStatement::FullObject> SqliteSelect::Core::ResultColumn::getFullObjectsInStatement()
@@ -574,7 +589,7 @@ TokenList SqliteSelect::Core::ResultColumn::rebuildTokensFromContents()
if (star)
{
if (!table.isNull())
- builder.withOther(table, dialect).withOperator(".");
+ builder.withOther(table).withOperator(".");
builder.withOperator("*");
}
@@ -586,7 +601,7 @@ TokenList SqliteSelect::Core::ResultColumn::rebuildTokensFromContents()
if (asKw)
builder.withSpace().withKeyword("AS");
- builder.withSpace().withOther(alias, dialect);
+ builder.withSpace().withOther(alias);
}
}
@@ -599,35 +614,35 @@ TokenList SqliteSelect::Core::SingleSource::rebuildTokensFromContents()
if (!table.isNull())
{
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
- builder.withOther(table, dialect);
+ builder.withOther(table);
if (!alias.isNull())
{
if (asKw)
builder.withSpace().withKeyword("AS");
- builder.withSpace().withOther(alias, dialect);
+ builder.withSpace().withOther(alias);
}
}
else if (!funcName.isNull())
{
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
- builder.withOther(funcName, dialect).withParLeft().withStatementList(funcParams).withParRight();
+ builder.withOther(funcName).withParLeft().withStatementList(funcParams).withParRight();
if (!alias.isNull())
{
if (asKw)
builder.withSpace().withKeyword("AS");
- builder.withSpace().withOther(alias, dialect);
+ builder.withSpace().withOther(alias);
}
if (indexedByKw)
- builder.withSpace().withKeyword("INDEXED").withSpace().withKeyword("BY").withSpace().withOther(indexedBy, dialect);
+ builder.withSpace().withKeyword("INDEXED").withSpace().withKeyword("BY").withSpace().withOther(indexedBy);
else if (notIndexedKw)
builder.withSpace().withKeyword("NOT").withSpace().withKeyword("INDEXED");
}
@@ -639,7 +654,7 @@ TokenList SqliteSelect::Core::SingleSource::rebuildTokensFromContents()
if (asKw)
builder.withSpace().withKeyword("AS");
- builder.withSpace().withOther(alias, dialect);
+ builder.withSpace().withOther(alias);
}
}
else
@@ -652,46 +667,7 @@ TokenList SqliteSelect::Core::SingleSource::rebuildTokensFromContents()
TokenList SqliteSelect::Core::JoinOp::rebuildTokensFromContents()
{
- switch (dialect)
- {
- case Dialect::Sqlite3:
- return rebuildTokensForSqlite2();
- case Dialect::Sqlite2:
- return rebuildTokensForSqlite3();
- }
- return TokenList();
-}
-
-TokenList SqliteSelect::Core::JoinOp::rebuildTokensForSqlite2()
-{
- StatementTokenBuilder builder;
- if (comma)
- {
- builder.withOperator(",");
- }
- else
- {
- if (naturalKw)
- builder.withKeyword("NATURAL").withSpace();
-
- if (leftKw)
- builder.withKeyword("LEFT").withSpace();
- else if (rightKw)
- builder.withKeyword("RIGHT").withSpace();
- else if (fullKw)
- builder.withKeyword("FULL").withSpace();
-
- if (innerKw)
- builder.withKeyword("INNER").withSpace();
- else if (crossKw)
- builder.withKeyword("CROSS").withSpace();
- else if (outerKw)
- builder.withKeyword("OUTER").withSpace();
-
- builder.withKeyword("JOIN");
- }
-
- return builder.build();
+ return rebuildTokensForSqlite3();
}
TokenList SqliteSelect::Core::JoinOp::rebuildTokensForSqlite3()
@@ -730,7 +706,7 @@ TokenList SqliteSelect::Core::JoinConstraint::rebuildTokensFromContents()
if (expr)
builder.withKeyword("ON").withStatement(expr);
else
- builder.withKeyword("USING").withSpace().withParLeft().withOtherList(columnNames, dialect).withParRight();
+ builder.withKeyword("USING").withSpace().withParLeft().withOtherList(columnNames).withParRight();
return builder.build();
}
@@ -785,6 +761,9 @@ TokenList SqliteSelect::Core::rebuildTokensFromContents()
builder.withSpace().withKeyword("HAVING").withStatement(having);
}
+ if (windows.size() > 0)
+ builder.withSpace().withKeyword("WINDOW").withStatementList(windows);
+
if (orderBy.size() > 0)
builder.withSpace().withKeyword("ORDER").withSpace().withKeyword("BY").withStatementList(orderBy);
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h
index b6f537d..58babfe 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h
@@ -9,6 +9,7 @@
#include <QList>
class SqliteWith;
+class SqliteWindowDefinition;
/**
* @addtogroup sqlite_statement
@@ -44,8 +45,8 @@ class API_EXPORT SqliteSelect : public SqliteQuery
SqliteExpr* expr = nullptr;
bool star = false;
bool asKw = false;
- QString alias = QString::null;
- QString table = QString::null;
+ QString alias = QString();
+ QString table = QString();
protected:
QStringList getTablesInStatement();
@@ -70,15 +71,15 @@ class API_EXPORT SqliteSelect : public SqliteQuery
SqliteStatement* clone();
- QString database = QString::null;
- QString table = QString::null;
- QString alias = QString::null;
- QString funcName = QString::null;
+ QString database = QString();
+ QString table = QString();
+ QString alias = QString();
+ QString funcName = QString();
QList<SqliteExpr*> funcParams;
bool asKw = false;
bool indexedByKw = false;
bool notIndexedKw = false;
- QString indexedBy = QString::null;
+ QString indexedBy = QString();
SqliteSelect* select = nullptr;
JoinSource* joinSource = nullptr;
@@ -116,15 +117,14 @@ class API_EXPORT SqliteSelect : public SqliteQuery
bool crossKw = false;
bool rightKw = false;
bool fullKw = false;
- QString customKw1 = QString::null;
- QString customKw2 = QString::null;
- QString customKw3 = QString::null;
+ QString customKw1 = QString();
+ QString customKw2 = QString();
+ QString customKw3 = QString();
protected:
TokenList rebuildTokensFromContents();
private:
- TokenList rebuildTokensForSqlite2();
TokenList rebuildTokensForSqlite3();
};
@@ -185,8 +185,11 @@ class API_EXPORT SqliteSelect : public SqliteQuery
Core();
Core(const Core& other);
Core(int distinct, const QList<ResultColumn*>& resCols, JoinSource* src, SqliteExpr* where,
- const QList<SqliteExpr*>& groupBy, SqliteExpr* having, const QList<SqliteOrderBy*>& orderBy,
- SqliteLimit* limit);
+ const QList<SqliteExpr*>& groupBy, SqliteExpr* having,
+ const QList<SqliteOrderBy*>& orderBy, SqliteLimit* limit);
+ Core(int distinct, const QList<ResultColumn*>& resCols, JoinSource* src, SqliteExpr* where,
+ const QList<SqliteExpr*>& groupBy, SqliteExpr* having, const QList<SqliteWindowDefinition*> windows,
+ const QList<SqliteOrderBy*>& orderBy, SqliteLimit* limit);
SqliteStatement* clone();
@@ -199,6 +202,7 @@ class API_EXPORT SqliteSelect : public SqliteQuery
SqliteExpr* having = nullptr;
QList<SqliteExpr*> groupBy;
QList<SqliteOrderBy*> orderBy;
+ QList<SqliteWindowDefinition*> windows;
SqliteLimit* limit = nullptr;
bool valuesMode = false;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesortorder.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesortorder.cpp
index 13f3951..eb0ca5c 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesortorder.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesortorder.cpp
@@ -19,7 +19,7 @@ QString sqliteSortOrder(SqliteSortOrder value)
case SqliteSortOrder::DESC:
return "DESC";
default:
- return QString::null;
+ return QString();
}
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.cpp
index 119461a..d349a86 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.cpp
@@ -9,7 +9,7 @@ SqliteStatement::SqliteStatement()
}
SqliteStatement::SqliteStatement(const SqliteStatement& other) :
- QObject(), tokens(other.tokens), tokensMap(other.tokensMap), dialect(other.dialect)
+ QObject(), tokens(other.tokens), tokensMap(other.tokensMap)
{
}
@@ -87,13 +87,6 @@ QList<SqliteStatement::FullObject> SqliteStatement::getContextFullObjects(bool c
return fullObjects;
}
-void SqliteStatement::setSqliteDialect(Dialect dialect)
-{
- this->dialect = dialect;
- for (SqliteStatement* stmt : childStatements())
- stmt->setSqliteDialect(dialect);
-}
-
SqliteStatementPtr SqliteStatement::detach()
{
if (!parent())
@@ -537,14 +530,6 @@ void SqliteStatement::rebuildTokens()
// and then compare new tokens map with previous one. This way we should be able to get all maps correctly.
}
-void SqliteStatement::setParent(QObject* parent)
-{
- QObject::setParent(parent);
- SqliteStatement* stmt = qobject_cast<SqliteStatement*>(parent);
- if (stmt)
- dialect = stmt->dialect;
-}
-
void SqliteStatement::attach(SqliteStatement*& memberForChild, SqliteStatement* childStatementToAttach)
{
memberForChild = childStatementToAttach;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h
index 779bea3..43a60ba 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h
@@ -3,7 +3,6 @@
#include "common/utils.h"
#include "parser/token.h"
-#include "dialect.h"
#include <QList>
#include <QHash>
#include <QObject>
@@ -50,7 +49,7 @@ typedef QSharedPointer<SqliteStatement> SqliteStatementPtr;
*
* There is also SqliteStatement::tokensMap, which is a table mapping grammar rule name
* into tokens used to fulfill that rule. To learn possible keys for each SqliteStatement,
- * you have to look into sqlite2.y and sqlite3.y files and see definition of the statement,
+ * you have to look into sqlite3.y file and see definition of the statement,
* that you're examining SqliteStatement::tokensMap for.
*
* @note SqliteStatement::tokensMap is a low level API and it's not very predictible,
@@ -89,7 +88,7 @@ typedef QSharedPointer<SqliteStatement> SqliteStatementPtr;
* This is how it's usually done:
* @code
* // STEP 1
- * Parser parser(db->getDialect());
+ * Parser parser;
* if (!parser.parse("SELECT column FROM test WHERE value = 5") || parser.getQueries().size() == 0)
* {
* // handle parsing error, or no queries parsed (which is also some kind of error)
@@ -152,7 +151,7 @@ typedef QSharedPointer<SqliteStatement> SqliteStatementPtr;
*
* Example:
* @code
- * Parser parser(db->getDialect());
+ * Parser parser;
* if (!parser.parse("SELECT column FROM test WHERE value = 5") || parser.getQueries().size() == 0)
* {
* // handle parsing error, or no queries parsed (which is also some kind of error)
@@ -222,9 +221,7 @@ class API_EXPORT SqliteStatement : public QObject
TokenList getContextTableTokens(bool checkParent = true, bool checkChilds = true);
TokenList getContextDatabaseTokens(bool checkParent = true, bool checkChilds = true);
QList<FullObject> getContextFullObjects(bool checkParent = true, bool checkChilds = true);
- void setSqliteDialect(Dialect dialect);
void rebuildTokens();
- void setParent(QObject* parent);
void attach(SqliteStatement*& memberForChild, SqliteStatement* childStatementToAttach);
SqliteStatementPtr detach();
void processPostParsing();
@@ -284,8 +281,6 @@ class API_EXPORT SqliteStatement : public QObject
*/
QHash<QString,TokenList> tokensMap;
- Dialect dialect = Dialect::Sqlite3;
-
protected:
QStringList getContextColumns(SqliteStatement* caller, bool checkParent, bool checkChilds);
QStringList getContextTables(SqliteStatement* caller, bool checkParent, bool checkChilds);
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp
index 2063e0e..89c8195 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp
@@ -26,6 +26,7 @@ SqliteUpdate::SqliteUpdate(const SqliteUpdate& other) :
DEEP_COPY_FIELD(SqliteExpr, where);
DEEP_COPY_FIELD(SqliteWith, with);
+ DEEP_COPY_FIELD(SqliteSelect::Core::JoinSource, from);
}
SqliteUpdate::~SqliteUpdate()
@@ -33,7 +34,7 @@ SqliteUpdate::~SqliteUpdate()
}
SqliteUpdate::SqliteUpdate(SqliteConflictAlgo onConflict, const QString &name1, const QString &name2, bool notIndexedKw, const QString &indexedBy,
- const QList<ColumnAndValue>& values, SqliteExpr *where, SqliteWith* with)
+ const QList<ColumnAndValue>& values, SqliteSelect::Core::JoinSource* from, SqliteExpr *where, SqliteWith* with)
: SqliteUpdate()
{
this->onConflict = onConflict;
@@ -51,6 +52,10 @@ SqliteUpdate::SqliteUpdate(SqliteConflictAlgo onConflict, const QString &name1,
this->notIndexedKw = notIndexedKw;
keyValueMap = values;
+ this->from = from;
+ if (from)
+ from->setParent(this);
+
this->where = where;
if (where)
where->setParent(this);
@@ -188,12 +193,12 @@ TokenList SqliteUpdate::rebuildTokensFromContents()
builder.withKeyword("OR").withSpace().withKeyword(sqliteConflictAlgo(onConflict)).withSpace();
if (!database.isNull())
- builder.withOther(database, dialect).withOperator(".");
+ builder.withOther(database).withOperator(".");
- builder.withOther(table, dialect).withSpace();
+ builder.withOther(table).withSpace();
if (indexedByKw)
- builder.withKeyword("INDEXED").withSpace().withKeyword("BY").withSpace().withOther(indexedBy, dialect).withSpace();
+ builder.withKeyword("INDEXED").withSpace().withKeyword("BY").withSpace().withOther(indexedBy).withSpace();
else if (notIndexedKw)
builder.withKeyword("NOT").withSpace().withKeyword("INDEXED").withSpace();
@@ -206,14 +211,17 @@ TokenList SqliteUpdate::rebuildTokensFromContents()
builder.withOperator(",").withSpace();
if (keyVal.first.type() == QVariant::StringList)
- builder.withParLeft().withOtherList(keyVal.first.toStringList(), dialect).withParRight();
+ builder.withParLeft().withOtherList(keyVal.first.toStringList()).withParRight();
else
- builder.withOther(keyVal.first.toString(), dialect);
+ builder.withOther(keyVal.first.toString());
builder.withSpace().withOperator("=").withStatement(keyVal.second);
first = false;
}
+ if (from)
+ builder.withSpace().withKeyword("FROM").withStatement(from);
+
if (where)
builder.withSpace().withKeyword("WHERE").withStatement(where);
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h
index 642473c..e843bcd 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h
@@ -3,6 +3,7 @@
#include "sqlitequery.h"
#include "sqliteconflictalgo.h"
+#include "sqliteselect.h"
#include <QStringList>
#include <QMap>
@@ -20,18 +21,19 @@ class API_EXPORT SqliteUpdate : public SqliteQuery
~SqliteUpdate();
SqliteUpdate(SqliteConflictAlgo onConflict, const QString& name1, const QString& name2,
bool notIndexedKw, const QString& indexedBy, const QList<ColumnAndValue>& values,
- SqliteExpr* where, SqliteWith* with);
+ SqliteSelect::Core::JoinSource* from, SqliteExpr* where, SqliteWith* with);
SqliteStatement* clone();
SqliteExpr* getValueForColumnSet(const QString& column);
SqliteConflictAlgo onConflict = SqliteConflictAlgo::null;
- QString database = QString::null;
- QString table = QString::null;
+ QString database = QString();
+ QString table = QString();
bool indexedByKw = false;
bool notIndexedKw = false;
- QString indexedBy = QString::null;
+ QString indexedBy = QString();
QList<ColumnAndValue> keyValueMap;
+ SqliteSelect::Core::JoinSource* from = nullptr;
SqliteExpr* where = nullptr;
SqliteWith* with = nullptr;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupsert.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupsert.cpp
index ced9c2d..441cd6d 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupsert.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupsert.cpp
@@ -94,9 +94,9 @@ TokenList SqliteUpsert::rebuildTokensFromContents()
builder.withOperator(",").withSpace();
if (keyVal.first.type() == QVariant::StringList)
- builder.withParLeft().withOtherList(keyVal.first.toStringList(), dialect).withParRight();
+ builder.withParLeft().withOtherList(keyVal.first.toStringList()).withParRight();
else
- builder.withOther(keyVal.first.toString(), dialect);
+ builder.withOther(keyVal.first.toString());
builder.withSpace().withOperator("=").withStatement(keyVal.second);
first = false;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp
index 9d595ed..e65530a 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp
@@ -1,7 +1,8 @@
#include "sqlitevacuum.h"
#include "sqlitequerytype.h"
-
-#include <parser/statementtokenbuilder.h>
+#include "common/global.h"
+#include "parser/statementtokenbuilder.h"
+#include "sqliteexpr.h"
SqliteVacuum::SqliteVacuum()
{
@@ -11,13 +12,26 @@ SqliteVacuum::SqliteVacuum()
SqliteVacuum::SqliteVacuum(const SqliteVacuum& other) :
SqliteQuery(other), database(other.database)
{
+ DEEP_COPY_FIELD(SqliteExpr, expr);
+}
+
+SqliteVacuum::SqliteVacuum(SqliteExpr* expr)
+ : SqliteVacuum()
+{
+ this->expr = expr;
+ if (expr)
+ expr->setParent(this);
}
-SqliteVacuum::SqliteVacuum(const QString& name)
+SqliteVacuum::SqliteVacuum(const QString& name, SqliteExpr* expr)
: SqliteVacuum()
{
if (!name.isNull())
database = name;
+
+ this->expr = expr;
+ if (expr)
+ expr->setParent(this);
}
SqliteStatement*SqliteVacuum::clone()
@@ -55,6 +69,13 @@ TokenList SqliteVacuum::rebuildTokensFromContents()
{
StatementTokenBuilder builder;
builder.withTokens(SqliteQuery::rebuildTokensFromContents());
- builder.withKeyword("VACUUM").withOperator(";");
+ builder.withKeyword("VACUUM");
+ if (!database.isNull())
+ builder.withSpace().withOther(database);
+
+ if (expr)
+ builder.withSpace().withKeyword("INTO").withSpace().withStatement(expr);
+
+ builder.withOperator(";");
return builder.build();
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.h
index 871b8f4..db9af95 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.h
@@ -5,16 +5,20 @@
#include <QString>
+class SqliteExpr;
+
class API_EXPORT SqliteVacuum : public SqliteQuery
{
public:
SqliteVacuum();
SqliteVacuum(const SqliteVacuum& other);
- explicit SqliteVacuum(const QString &name);
+ SqliteVacuum(SqliteExpr* expr);
+ SqliteVacuum(const QString &name, SqliteExpr* expr);
SqliteStatement* clone();
QString database;
+ SqliteExpr* expr = nullptr;
protected:
QStringList getDatabasesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp
new file mode 100644
index 0000000..adf135f
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp
@@ -0,0 +1,308 @@
+#include "sqlitewindowdefinition.h"
+#include "sqliteexpr.h"
+#include "sqliteorderby.h"
+#include "parser/statementtokenbuilder.h"
+#include "common/global.h"
+#include <QDebug>
+
+SqliteWindowDefinition::SqliteWindowDefinition()
+{
+
+}
+
+SqliteWindowDefinition::SqliteWindowDefinition(const SqliteWindowDefinition& other) :
+ SqliteStatement(other), name(other.name)
+{
+ DEEP_COPY_FIELD(Window, window);
+}
+
+SqliteWindowDefinition::SqliteWindowDefinition(const QString& name, SqliteWindowDefinition::Window* window)
+{
+ this->name = name;
+ this->window = window;
+ if (window)
+ window->setParent(this);
+}
+
+SqliteStatement* SqliteWindowDefinition::clone()
+{
+ return new SqliteWindowDefinition(*this);
+}
+
+TokenList SqliteWindowDefinition::rebuildTokensFromContents()
+{
+ StatementTokenBuilder builder;
+
+ builder.withOther(name).withSpace().withKeyword("AS").withParLeft().withStatement(window).withParRight();
+
+ return builder.build();
+}
+
+SqliteWindowDefinition::Window::Window()
+{
+}
+
+SqliteWindowDefinition::Window::Window(const SqliteWindowDefinition::Window& other) :
+ SqliteStatement(other), name(other.name), mode(other.mode)
+{
+ DEEP_COPY_COLLECTION(SqliteExpr, exprList);
+ DEEP_COPY_COLLECTION(SqliteOrderBy, orderBy);
+ DEEP_COPY_FIELD(Frame, frame);
+}
+
+SqliteStatement* SqliteWindowDefinition::Window::clone()
+{
+ return new Window(*this);
+}
+
+void SqliteWindowDefinition::Window::initPartitionBy(const QString& name, const QList<SqliteExpr*>& exprList, const QList<SqliteOrderBy*>& orderBy, SqliteWindowDefinition::Window::Frame* frame)
+{
+ this->mode = Mode::PARTITION_BY;
+ this->name = name;
+ initExprList(exprList);
+ initOrderBy(orderBy);
+ initFrame(frame);
+}
+
+void SqliteWindowDefinition::Window::initOrderBy(const QString& name, const QList<SqliteOrderBy*>& orderBy, SqliteWindowDefinition::Window::Frame* frame)
+{
+ this->mode = Mode::ORDER_BY;
+ this->name = name;
+ initOrderBy(orderBy);
+ initFrame(frame);
+}
+
+void SqliteWindowDefinition::Window::init(const QString& name, SqliteWindowDefinition::Window::Frame* frame)
+{
+ this->mode = Mode::null;
+ this->name = name;
+ initFrame(frame);
+}
+
+TokenList SqliteWindowDefinition::Window::rebuildTokensFromContents()
+{
+ StatementTokenBuilder builder;
+
+ if (!name.isNull())
+ builder.withOther(name).withSpace();
+
+ switch (mode)
+ {
+ case SqliteWindowDefinition::Window::Mode::PARTITION_BY:
+ builder.withKeyword("PARTITION").withSpace().withKeyword("BY").withSpace().withStatementList(exprList).withSpace();
+ break;
+ case SqliteWindowDefinition::Window::Mode::ORDER_BY:
+ break;
+ case SqliteWindowDefinition::Window::Mode::null:
+ break;
+ }
+
+ if (orderBy.size() > 0)
+ builder.withKeyword("ORDER").withSpace().withKeyword("BY").withSpace().withStatementList(orderBy);
+
+ if (frame)
+ builder.withStatement(frame);
+
+ return builder.build();
+}
+
+void SqliteWindowDefinition::Window::initExprList(const QList<SqliteExpr*>& exprList)
+{
+ this->exprList = exprList;
+ for (SqliteExpr* expr : exprList)
+ expr->setParent(this);
+}
+
+void SqliteWindowDefinition::Window::initOrderBy(const QList<SqliteOrderBy*>& orderBy)
+{
+ this->orderBy = orderBy;
+ for (SqliteOrderBy* order : orderBy)
+ order->setParent(this);
+}
+
+void SqliteWindowDefinition::Window::initFrame(SqliteWindowDefinition::Window::Frame* frame)
+{
+ this->frame = frame;
+ if (frame)
+ frame->setParent(this);
+}
+
+SqliteWindowDefinition::Window::Frame::RangeOrRows SqliteWindowDefinition::Window::Frame::toRangeOrRows(const QString& value)
+{
+ QString upper = value.toUpper();
+ if (upper == "RANGE")
+ return RangeOrRows::RANGE;
+ else if (upper == "ROWS")
+ return RangeOrRows::ROWS;
+ else if (upper == "GROUPS")
+ return RangeOrRows::GROUPS;
+ else
+ return RangeOrRows::null;
+}
+
+QString SqliteWindowDefinition::Window::Frame::fromRangeOrRows(SqliteWindowDefinition::Window::Frame::RangeOrRows value)
+{
+ switch (value)
+ {
+ case SqliteWindowDefinition::Window::Frame::RangeOrRows::RANGE:
+ return "RANGE";
+ case SqliteWindowDefinition::Window::Frame::RangeOrRows::ROWS:
+ return "ROWS";
+ case SqliteWindowDefinition::Window::Frame::RangeOrRows::GROUPS:
+ return "GROUPS";
+ case SqliteWindowDefinition::Window::Frame::RangeOrRows::null:
+ break;
+ }
+ return QString();
+}
+
+SqliteWindowDefinition::Window::Frame::Exclude SqliteWindowDefinition::Window::Frame::toExclude(const QString& value)
+{
+ QString upper = value.toUpper();
+ if (upper == "NO OTHERS")
+ return Exclude::NO_OTHERS;
+ else if (upper == "CURRENT ROW")
+ return Exclude::CURRENT_ROW;
+ else if (upper == "GROUP")
+ return Exclude::GROUP;
+ else if (upper == "TIES")
+ return Exclude::TIES;
+ else
+ return Exclude::null;
+}
+
+QString SqliteWindowDefinition::Window::Frame::fromExclude(SqliteWindowDefinition::Window::Frame::Exclude value)
+{
+ switch (value)
+ {
+ case SqliteWindowDefinition::Window::Frame::Exclude::TIES:
+ return "TIES";
+ case SqliteWindowDefinition::Window::Frame::Exclude::NO_OTHERS:
+ return "NO OTHERS";
+ case SqliteWindowDefinition::Window::Frame::Exclude::CURRENT_ROW:
+ return "CURRENT ROW";
+ case SqliteWindowDefinition::Window::Frame::Exclude::GROUP:
+ return "GROUP";
+ case SqliteWindowDefinition::Window::Frame::Exclude::null:
+ break;
+ }
+ return QString();
+}
+
+SqliteWindowDefinition::Window::Frame::Frame()
+{
+}
+
+SqliteWindowDefinition::Window::Frame::Frame(const SqliteWindowDefinition::Window::Frame& other) :
+ SqliteStatement(other), rangeOrRows(other.rangeOrRows), exclude(other.exclude)
+{
+ DEEP_COPY_FIELD(Bound, startBound);
+ DEEP_COPY_FIELD(Bound, endBound);
+}
+
+SqliteWindowDefinition::Window::Frame::Frame(SqliteWindowDefinition::Window::Frame::RangeOrRows rangeOrRows,
+ SqliteWindowDefinition::Window::Frame::Bound* startBound,
+ SqliteWindowDefinition::Window::Frame::Bound* endBound,
+ SqliteWindowDefinition::Window::Frame::Exclude exclude)
+{
+ this->rangeOrRows = rangeOrRows;
+ this->startBound = startBound;
+ this->endBound = endBound;
+ this->exclude = exclude;
+
+ if (startBound)
+ startBound->setParent(this);
+
+ if (endBound)
+ endBound->setParent(this);
+}
+
+SqliteStatement* SqliteWindowDefinition::Window::Frame::clone()
+{
+ return new Frame(*this);
+}
+
+TokenList SqliteWindowDefinition::Window::Frame::rebuildTokensFromContents()
+{
+ StatementTokenBuilder builder;
+
+ if (rangeOrRows != RangeOrRows::null)
+ builder.withKeyword(fromRangeOrRows(rangeOrRows)).withSpace();
+
+ if (endBound)
+ builder.withKeyword("BETWEEN").withSpace().withStatement(startBound).withSpace()
+ .withKeyword("AND").withSpace().withStatement(endBound);
+ else
+ builder.withStatement(startBound);
+
+ if (exclude != Exclude::null)
+ {
+ builder.withSpace().withKeyword("EXCLUDE");
+ for (const QString& kw : fromExclude(exclude).split(" "))
+ builder.withSpace().withKeyword(kw);
+ }
+
+ return builder.build();
+}
+
+SqliteWindowDefinition::Window::Frame::Bound::Bound()
+{
+}
+
+SqliteWindowDefinition::Window::Frame::Bound::Bound(const SqliteWindowDefinition::Window::Frame::Bound& other) :
+ SqliteStatement(other), type(other.type)
+{
+ DEEP_COPY_FIELD(SqliteExpr, expr);
+}
+
+SqliteWindowDefinition::Window::Frame::Bound::Bound(SqliteExpr* expr, const QString& value)
+{
+ this->expr = expr;
+ if (expr)
+ expr->setParent(this);
+
+ QString upper = value.toUpper();
+ if (upper == "UNBOUNDED PRECEDING")
+ type = Type::UNBOUNDED_PRECEDING;
+ else if (expr && upper == "PRECEDING")
+ type = Type::EXPR_FOLLOWING;
+ else if (upper == "UNBOUNDED FOLLOWING")
+ type = Type::UNBOUNDED_FOLLOWING;
+ else if (expr && upper == "FOLLOWING")
+ type = Type::EXPR_FOLLOWING;
+ else if (upper == "CURRENT ROW")
+ type = Type::CURRENT_ROW;
+ else
+ qCritical() << "Unexpected Window Frame Bound:" << value;
+}
+
+SqliteStatement* SqliteWindowDefinition::Window::Frame::Bound::clone()
+{
+ return new Bound(*this);
+}
+
+TokenList SqliteWindowDefinition::Window::Frame::Bound::rebuildTokensFromContents()
+{
+ StatementTokenBuilder builder;
+
+ switch (type)
+ {
+ case SqliteWindowDefinition::Window::Frame::Bound::Type::UNBOUNDED_PRECEDING:
+ builder.withKeyword("UNBOUNDED").withSpace().withKeyword("PRECEDING");
+ break;
+ case SqliteWindowDefinition::Window::Frame::Bound::Type::UNBOUNDED_FOLLOWING:
+ builder.withKeyword("UNBOUNDED").withSpace().withKeyword("FOLLOWING");
+ break;
+ case SqliteWindowDefinition::Window::Frame::Bound::Type::EXPR_PRECEDING:
+ builder.withStatement(expr).withSpace().withKeyword("PRECEDING");
+ break;
+ case SqliteWindowDefinition::Window::Frame::Bound::Type::EXPR_FOLLOWING:
+ builder.withStatement(expr).withSpace().withKeyword("FOLLOWING");
+ break;
+ case SqliteWindowDefinition::Window::Frame::Bound::Type::CURRENT_ROW:
+ builder.withKeyword("CURRENT").withSpace().withKeyword("ROW");
+ break;
+ }
+
+ return builder.build();
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.h
new file mode 100644
index 0000000..fb5cb8e
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.h
@@ -0,0 +1,129 @@
+#ifndef SQLITEWINDOWDEFINITION_H
+#define SQLITEWINDOWDEFINITION_H
+
+//#include "sqliteexpr.h"
+//#include "sqliteorderby.h"
+#include "sqlitestatement.h"
+
+class SqliteExpr;
+class SqliteOrderBy;
+
+/**
+ * @addtogroup sqlite_statement
+ * @brief The SqliteWindowDefinition class
+ */
+class API_EXPORT SqliteWindowDefinition : public SqliteStatement
+{
+ public:
+ class API_EXPORT Window : public SqliteStatement
+ {
+ public:
+ class API_EXPORT Frame : public SqliteStatement
+ {
+ public:
+ class API_EXPORT Bound : public SqliteStatement
+ {
+ public:
+ enum class Type
+ {
+ UNBOUNDED_PRECEDING,
+ UNBOUNDED_FOLLOWING,
+ EXPR_PRECEDING,
+ EXPR_FOLLOWING,
+ CURRENT_ROW
+ };
+
+ Bound();
+ Bound(const Bound& other);
+ Bound(SqliteExpr* expr, const QString& value);
+
+ SqliteStatement* clone();
+
+ Type type = Type::CURRENT_ROW;
+ SqliteExpr* expr = nullptr;
+
+ protected:
+ TokenList rebuildTokensFromContents();
+ };
+
+ enum class RangeOrRows
+ {
+ RANGE,
+ ROWS,
+ GROUPS,
+ null
+ };
+
+ enum class Exclude
+ {
+ NO_OTHERS,
+ CURRENT_ROW,
+ GROUP,
+ TIES,
+ null
+ };
+
+ static RangeOrRows toRangeOrRows(const QString& value);
+ static QString fromRangeOrRows(RangeOrRows value);
+ static Exclude toExclude(const QString& value);
+ static QString fromExclude(Exclude value);
+
+ Frame();
+ Frame(const Frame& other);
+ Frame(RangeOrRows rangeOrRows, Bound* startBound, Bound* endBound, Exclude exclude);
+
+ SqliteStatement* clone();
+
+ RangeOrRows rangeOrRows = RangeOrRows::null;
+ Exclude exclude = Exclude::null;
+ Bound* startBound = nullptr;
+ Bound* endBound = nullptr;
+
+ protected:
+ TokenList rebuildTokensFromContents();
+ };
+
+ enum class Mode
+ {
+ PARTITION_BY,
+ ORDER_BY,
+ null
+ };
+
+ Window();
+ Window(const Window& other);
+
+ SqliteStatement* clone();
+ void initPartitionBy(const QString& name, const QList<SqliteExpr*>& exprList, const QList<SqliteOrderBy*>& orderBy, Frame* frame);
+ void initOrderBy(const QString& name, const QList<SqliteOrderBy*>& orderBy, Frame* frame);
+ void init(const QString& name, Frame* frame);
+
+ QString name;
+ QList<SqliteExpr*> exprList;
+ QList<SqliteOrderBy*> orderBy;
+ Frame* frame = nullptr;
+ Mode mode = Mode::null;
+
+ protected:
+ TokenList rebuildTokensFromContents();
+
+ private:
+ void initExprList(const QList<SqliteExpr*>& exprList);
+ void initOrderBy(const QList<SqliteOrderBy*>& orderBy);
+ void initFrame(Frame* frame);
+ };
+
+ SqliteWindowDefinition();
+ SqliteWindowDefinition(const SqliteWindowDefinition& other);
+ SqliteWindowDefinition(const QString& name, Window* window);
+
+ SqliteStatement* clone();
+
+ QString name = QString();
+ Window* window = nullptr;
+
+ protected:
+ TokenList rebuildTokensFromContents();
+};
+
+#endif // SQLITEWINDOWDEFINITION_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp
index 2b9c99f..901ac56 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp
@@ -13,26 +13,6 @@ SqliteWith::SqliteWith(const SqliteWith& other) :
DEEP_COPY_COLLECTION(CommonTableExpression, cteList);
}
-SqliteWith* SqliteWith::append(const QString& tableName, const QList<SqliteIndexedColumn*>& indexedColumns, SqliteSelect* select)
-{
- SqliteWith* with = new SqliteWith();
- CommonTableExpression* cte = new CommonTableExpression(tableName, indexedColumns, select);
- cte->setParent(with);
- with->cteList << cte;
- return with;
-}
-
-SqliteWith* SqliteWith::append(SqliteWith* with, const QString& tableName, const QList<SqliteIndexedColumn*>& indexedColumns, SqliteSelect* select)
-{
- if (!with)
- with = new SqliteWith();
-
- CommonTableExpression* cte = new CommonTableExpression(tableName, indexedColumns, select);
- cte->setParent(with);
- with->cteList << cte;
- return with;
-}
-
SqliteStatement*SqliteWith::clone()
{
return new SqliteWith(*this);
@@ -76,7 +56,7 @@ SqliteStatement*SqliteWith::CommonTableExpression::clone()
TokenList SqliteWith::CommonTableExpression::rebuildTokensFromContents()
{
StatementTokenBuilder builder;
- builder.withOther(table, dialect);
+ builder.withOther(table);
if (indexedColumns.size() > 0)
builder.withSpace().withParLeft().withStatementList(indexedColumns).withParRight();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h
index fe64c9c..30f8181 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h
@@ -28,8 +28,6 @@ class SqliteWith : public SqliteStatement
SqliteWith();
SqliteWith(const SqliteWith& other);
- static SqliteWith* append(const QString& tableName, const QList<SqliteIndexedColumn*>& indexedColumns, SqliteSelect* select);
- static SqliteWith* append(SqliteWith* with, const QString& tableName, const QList<SqliteIndexedColumn*>& indexedColumns, SqliteSelect* select);
SqliteStatement* clone();