aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/parser/ast
diff options
context:
space:
mode:
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/parser/ast')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp68
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h5
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp92
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h32
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp10
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp56
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h10
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp10
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp10
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h3
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp24
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h13
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp43
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp34
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h16
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp20
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp5
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp24
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp24
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h3
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp22
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h10
29 files changed, 338 insertions, 220 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp
index 5ca593f..42cb59b 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp
@@ -8,7 +8,8 @@ SqliteAlterTable::SqliteAlterTable()
}
SqliteAlterTable::SqliteAlterTable(const SqliteAlterTable& other)
- : SqliteQuery(other), command(other.command), newName(other.newName), database(other.database), table(other.table), columnKw(other.columnKw)
+ : SqliteQuery(other), command(other.command), newName(other.newName), database(other.database), table(other.table),
+ dropColumnName(other.dropColumnName), columnKw(other.columnKw)
{
DEEP_COPY_FIELD(SqliteCreateTable::Column, newColumn);
}
@@ -32,10 +33,17 @@ SqliteAlterTable::SqliteAlterTable(const QString& name1, const QString& name2, b
column->setParent(this);
}
+SqliteAlterTable::SqliteAlterTable(const QString& name1, const QString& name2, bool columnKw, const QString& dropColumn)
+ : SqliteAlterTable()
+{
+ command = Command::DROP_COLUMN;
+ initName(name1, name2);
+ this->columnKw = columnKw;
+ this->dropColumnName = dropColumn;
+}
+
SqliteAlterTable::~SqliteAlterTable()
{
-// if (newColumn)
- // delete newColumn;
}
SqliteStatement* SqliteAlterTable::clone()
@@ -43,6 +51,15 @@ SqliteStatement* SqliteAlterTable::clone()
return new SqliteAlterTable(*this);
}
+QStringList SqliteAlterTable::getColumnsInStatement()
+{
+ QStringList list;
+ if (!dropColumnName.isNull())
+ list << dropColumnName;
+
+ return list;
+}
+
QStringList SqliteAlterTable::getTablesInStatement()
{
QStringList list;
@@ -60,6 +77,14 @@ QStringList SqliteAlterTable::getDatabasesInStatement()
return getStrListFromValue(database);
}
+TokenList SqliteAlterTable::getColumnTokensInStatement()
+{
+ if (command == Command::DROP_COLUMN && tokensMap.contains("nm"))
+ return extractPrintableTokens(tokensMap["nm"]);
+
+ return TokenList();
+}
+
TokenList SqliteAlterTable::getTableTokensInStatement()
{
return getObjectTokenListFromFullname();
@@ -110,17 +135,32 @@ TokenList SqliteAlterTable::rebuildTokensFromContents()
builder.withOther(table).withSpace();
- if (newColumn)
- {
- builder.withKeyword("ADD").withSpace();
- if (columnKw)
- builder.withKeyword("COLUMN").withSpace();
-
- builder.withStatement(newColumn);
- }
- else if (!newName.isNull())
- {
- builder.withKeyword("RENAME").withSpace().withKeyword("TO").withSpace().withOther(newName);
+ switch (command) {
+ case Command::RENAME:
+ {
+ builder.withKeyword("RENAME").withSpace().withKeyword("TO").withSpace().withOther(newName);
+ break;
+ }
+ case Command::ADD_COLUMN:
+ {
+ builder.withKeyword("ADD").withSpace();
+ if (columnKw)
+ builder.withKeyword("COLUMN").withSpace();
+
+ builder.withStatement(newColumn);
+ break;
+ }
+ case Command::DROP_COLUMN:
+ {
+ builder.withKeyword("DROP").withSpace();
+ if (columnKw)
+ builder.withKeyword("COLUMN").withSpace();
+
+ builder.withOther(dropColumnName);
+ break;
+ }
+ case Command::null:
+ break;
}
builder.withOperator(";");
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h
index fbac3fe..1733dfc 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.h
@@ -11,6 +11,7 @@ class API_EXPORT SqliteAlterTable : public SqliteQuery
{
RENAME,
ADD_COLUMN,
+ DROP_COLUMN,
null
};
@@ -18,12 +19,15 @@ class API_EXPORT SqliteAlterTable : public SqliteQuery
SqliteAlterTable(const SqliteAlterTable& other);
SqliteAlterTable(const QString& name1, const QString& name2, const QString& newName);
SqliteAlterTable(const QString& name1, const QString& name2, bool columnKw, SqliteCreateTable::Column* column);
+ SqliteAlterTable(const QString& name1, const QString& name2, bool columnKw, const QString& dropColumn);
~SqliteAlterTable();
SqliteStatement* clone();
protected:
+ QStringList getColumnsInStatement();
QStringList getTablesInStatement();
QStringList getDatabasesInStatement();
+ TokenList getColumnTokensInStatement();
TokenList getTableTokensInStatement();
TokenList getDatabaseTokensInStatement();
QList<FullObject> getFullObjectsInStatement();
@@ -37,6 +41,7 @@ class API_EXPORT SqliteAlterTable : public SqliteQuery
QString newName = QString();
QString database = QString();
QString table = QString();
+ QString dropColumnName = QString();
bool columnKw = false;
SqliteCreateTable::Column* newColumn = nullptr;
};
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp
deleted file mode 100644
index c3ff500..0000000
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "sqlitecopy.h"
-#include "sqlitequerytype.h"
-
-#include <parser/statementtokenbuilder.h>
-
-SqliteCopy::SqliteCopy()
-{
- queryType = SqliteQueryType::Copy;
-}
-
-SqliteCopy::SqliteCopy(const SqliteCopy& other) :
- SqliteQuery(other), onConflict(other.onConflict), database(other.database), table(other.table), file(other.file), delimiter(other.delimiter)
-{
-}
-
-SqliteCopy::SqliteCopy(SqliteConflictAlgo onConflict, const QString &name1, const QString &name2, const QString &name3, const QString &delim)
- : SqliteCopy()
-{
- this->onConflict = onConflict;
-
- if (!name2.isNull())
- {
- database = name1;
- table = name2;
- }
- else
- table = name1;
-
- file = name3;
- delimiter = delim;
-}
-
-SqliteStatement* SqliteCopy::clone()
-{
- return new SqliteCopy(*this);
-}
-
-QStringList SqliteCopy::getTablesInStatement()
-{
- return getStrListFromValue(table);
-}
-
-QStringList SqliteCopy::getDatabasesInStatement()
-{
- return getStrListFromValue(database);
-}
-
-TokenList SqliteCopy::getTableTokensInStatement()
-{
- return getObjectTokenListFromNmDbnm();
-}
-
-TokenList SqliteCopy::getDatabaseTokensInStatement()
-{
- return getDbTokenListFromNmDbnm();
-}
-
-QList<SqliteStatement::FullObject> SqliteCopy::getFullObjectsInStatement()
-{
- QList<FullObject> result;
-
- FullObject fullObj = getFullObjectFromNmDbnm(FullObject::TABLE);
- if (fullObj.isValid())
- result << fullObj;
-
- fullObj = getFirstDbFullObject();
- if (fullObj.isValid())
- result << fullObj;
-
- return result;
-}
-
-TokenList SqliteCopy::rebuildTokensFromContents()
-{
- StatementTokenBuilder builder;
- builder.withTokens(SqliteQuery::rebuildTokensFromContents());
- builder.withKeyword("COPY").withSpace();
- if (onConflict != SqliteConflictAlgo::null)
- builder.withKeyword("OR").withSpace().withKeyword(sqliteConflictAlgo(onConflict)).withSpace();
-
- if (!database.isNull())
- builder.withOther(database).withSpace();
-
- builder.withOther(table).withSpace().withKeyword("FROM").withSpace().withString(file);
-
- if (!delimiter.isNull())
- builder.withSpace().withKeyword("USING").withSpace().withKeyword("DELIMITERS").withSpace().withString(delimiter);
-
- builder.withOperator(";");
-
- return builder.build();
-}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h
deleted file mode 100644
index 1e4b5b7..0000000
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef SQLITECOPY_H
-#define SQLITECOPY_H
-
-#include "sqlitequery.h"
-#include "sqliteconflictalgo.h"
-
-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());
- SqliteStatement* clone();
-
- SqliteConflictAlgo onConflict = SqliteConflictAlgo::null;
- QString database = QString();
- QString table = QString();
- QString file = QString();
- QString delimiter = QString();
-
- protected:
- QStringList getTablesInStatement();
- QStringList getDatabasesInStatement();
- TokenList getTableTokensInStatement();
- TokenList getDatabaseTokensInStatement();
- QList<FullObject> getFullObjectsInStatement();
- TokenList rebuildTokensFromContents();
-};
-
-typedef QSharedPointer<SqliteCopy> SqliteCopyPtr;
-
-#endif // SQLITECOPY_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp
index b747c33..1749e9a 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp
@@ -172,3 +172,13 @@ void SqliteCreateIndex::setTargetDatabase(const QString& database)
{
this->database = database;
}
+
+QString SqliteCreateIndex::getObjectName() const
+{
+ return index;
+}
+
+void SqliteCreateIndex::setObjectName(const QString& name)
+{
+ index = name;
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h
index 870ed17..b8876a2 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h
@@ -29,6 +29,8 @@ class API_EXPORT SqliteCreateIndex : public SqliteQuery, public SqliteTableRelat
QString getTargetTable() const;
QString getTargetDatabase() const;
void setTargetDatabase(const QString& database);
+ QString getObjectName() const;
+ void setObjectName(const QString& name);
bool uniqueKw = false;
bool ifNotExistsKw = false;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp
index d82270e..fff4036 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp
@@ -1,6 +1,6 @@
#include "sqlitecreatetable.h"
+#include "parser/parser_helper_stubs.h"
#include "parser/statementtokenbuilder.h"
-#include "common/utils_sql.h"
#include "common/global.h"
const QRegExp SqliteCreateTable::Column::GENERATED_ALWAYS_REGEXP = QRegExp("GENERATED\\s+ALWAYS");
@@ -12,7 +12,7 @@ SqliteCreateTable::SqliteCreateTable()
SqliteCreateTable::SqliteCreateTable(const SqliteCreateTable& other) :
SqliteQuery(other), ifNotExistsKw(other.ifNotExistsKw), tempKw(other.tempKw), temporaryKw(other.temporaryKw),
- database(other.database), table(other.table), withOutRowId(other.withOutRowId)
+ database(other.database), table(other.table), withOutRowId(other.withOutRowId), strict(other.strict)
{
DEEP_COPY_COLLECTION(Column, columns);
DEEP_COPY_COLLECTION(Constraint, constraints);
@@ -40,10 +40,11 @@ SqliteCreateTable::SqliteCreateTable(bool ifNotExistsKw, int temp, const QString
}
}
-SqliteCreateTable::SqliteCreateTable(bool ifNotExistsKw, int temp, const QString& name1, const QString& name2, const QList<SqliteCreateTable::Column*>& columns, const QList<SqliteCreateTable::Constraint*>& constraints, const QString& withOutRowId) :
+SqliteCreateTable::SqliteCreateTable(bool ifNotExistsKw, int temp, const QString& name1, const QString& name2, const QList<SqliteCreateTable::Column*>& columns, const QList<SqliteCreateTable::Constraint*>& constraints, const QList<ParserStubCreateTableOption*>& options) :
SqliteCreateTable(ifNotExistsKw, temp, name1, name2, columns, constraints)
{
- this->withOutRowId = withOutRowId;
+ this->withOutRowId = parserStubFindCreateTableOption(options, ParserStubCreateTableOption::WITHOUT_ROWID) != nullptr;
+ this->strict = parserStubFindCreateTableOption(options, ParserStubCreateTableOption::STRICT) != nullptr;
}
SqliteCreateTable::SqliteCreateTable(bool ifNotExistsKw, int temp, const QString &name1, const QString &name2, SqliteSelect *select)
@@ -76,7 +77,7 @@ QList<SqliteCreateTable::Constraint*> SqliteCreateTable::getConstraints(SqliteCr
SqliteStatement* SqliteCreateTable::getPrimaryKey() const
{
- for (Constraint* constr : getConstraints(Constraint::PRIMARY_KEY))
+ for (Constraint*& constr : getConstraints(Constraint::PRIMARY_KEY))
return constr;
Column::Constraint* colConstr = nullptr;
@@ -115,7 +116,7 @@ QStringList SqliteCreateTable::getPrimaryKeyColumns() const
SqliteCreateTable::Column* SqliteCreateTable::getColumn(const QString& colName)
{
- for (Column* col : columns)
+ for (Column*& col : columns)
{
if (col->name.compare(colName, Qt::CaseInsensitive) == 0)
return col;
@@ -142,6 +143,18 @@ QList<SqliteCreateTable::Column::Constraint*> SqliteCreateTable::getColumnForeig
return results;
}
+void SqliteCreateTable::removeColumnConstraint(Column::Constraint* constr)
+{
+ for (Column* col : columns)
+ {
+ if (col->constraints.contains(constr))
+ {
+ col->constraints.removeOne(constr);
+ return;
+ }
+ }
+}
+
QStringList SqliteCreateTable::getColumnNames() const
{
QStringList names;
@@ -236,8 +249,21 @@ TokenList SqliteCreateTable::rebuildTokensFromContents()
builder.withParRight();
- if (!withOutRowId.isNull())
+ bool atLeastOneOption = false;
+ if (withOutRowId)
+ {
builder.withSpace().withKeyword("WITHOUT").withSpace().withOther("ROWID");
+ atLeastOneOption = true;
+ }
+
+ if (strict)
+ {
+ if (atLeastOneOption)
+ builder.withOperator(",");
+
+ builder.withSpace().withOther("STRICT");
+ //atLeastOneOption = true; // to uncomment if there are further options down below
+ }
}
builder.withOperator(";");
@@ -564,7 +590,7 @@ bool SqliteCreateTable::Constraint::doesAffectColumn(const QString& columnName)
int SqliteCreateTable::Constraint::getAffectedColumnIdx(const QString& columnName)
{
int i = 0;
- for (SqliteIndexedColumn* idxCol : indexedColumns)
+ for (SqliteIndexedColumn*& idxCol : indexedColumns)
{
if (idxCol->name.compare(columnName, Qt::CaseInsensitive) == 0)
return i;
@@ -604,12 +630,12 @@ TokenList SqliteCreateTable::Constraint::rebuildTokensFromContents()
{
case SqliteCreateTable::Constraint::PRIMARY_KEY:
{
- builder.withKeyword("PRIMARY").withSpace().withKeyword("KEY").withSpace().withParLeft().withStatementList(indexedColumns).withParRight();
+ builder.withKeyword("PRIMARY").withSpace().withKeyword("KEY").withSpace().withParLeft().withStatementList(indexedColumns);
if (autoincrKw)
builder.withSpace().withKeyword("AUTOINCREMENT");
- builder.withConflict(onConflict);
+ builder.withParRight().withConflict(onConflict);
break;
}
case SqliteCreateTable::Constraint::UNIQUE:
@@ -861,3 +887,13 @@ void SqliteCreateTable::setTargetDatabase(const QString& database)
{
this->database = database;
}
+
+QString SqliteCreateTable::getObjectName() const
+{
+ return table;
+}
+
+void SqliteCreateTable::setObjectName(const QString& name)
+{
+ table = name;
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h
index d34688c..5d797c1 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h
@@ -15,6 +15,8 @@
#include <QList>
#include <QRegExp>
+struct ParserStubCreateTableOption;
+
class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbContext
{
public:
@@ -189,7 +191,7 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
const QList<Column*>& columns, const QList<Constraint*>& constraints);
SqliteCreateTable(bool ifNotExistsKw, int temp, const QString& name1, const QString& name2,
const QList<Column*>& columns, const QList<Constraint*>& constraints,
- const QString& withOutRowId);
+ const QList<ParserStubCreateTableOption*>& options);
SqliteCreateTable(bool ifNotExistsKw, int temp, const QString& name1, const QString& name2,
SqliteSelect* select);
~SqliteCreateTable();
@@ -201,10 +203,13 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
Column* getColumn(const QString& colName);
QList<Constraint*> getForeignKeysByTable(const QString& foreignTable) const;
QList<Column::Constraint*> getColumnForeignKeysByTable(const QString& foreignTable) const;
+ void removeColumnConstraint(Column::Constraint* constr);
QStringList getColumnNames() const;
QHash<QString,QString> getModifiedColumnsMap(bool lowercaseKeys = false, Qt::CaseSensitivity cs = Qt::CaseInsensitive) const;
QString getTargetDatabase() const;
void setTargetDatabase(const QString& database);
+ QString getObjectName() const;
+ void setObjectName(const QString& name);
bool ifNotExistsKw = false;
bool tempKw = false;
@@ -213,8 +218,9 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbC
QString table = QString();
QList<Column*> columns;
QList<Constraint*> constraints;
+ bool withOutRowId = false;
+ bool strict = false;
SqliteSelect* select = nullptr;
- QString withOutRowId = QString();
protected:
QStringList getTablesInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp
index 3f2c4e3..597395f 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp
@@ -370,3 +370,13 @@ void SqliteCreateTrigger::setTargetDatabase(const QString& database)
{
this->database = database;
}
+
+QString SqliteCreateTrigger::getObjectName() const
+{
+ return trigger;
+}
+
+void SqliteCreateTrigger::setObjectName(const QString& name)
+{
+ trigger = name;
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h
index ac7b81f..44b953a 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h
@@ -66,6 +66,8 @@ class API_EXPORT SqliteCreateTrigger : public SqliteQuery, public SqliteTableRel
QString getTargetTable() const;
QString getTargetDatabase() const;
void setTargetDatabase(const QString& database);
+ QString getObjectName() const;
+ void setObjectName(const QString& name);
bool tempKw = false;
bool temporaryKw = false;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp
index f5b54e7..0e11619 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp
@@ -129,3 +129,13 @@ void SqliteCreateView::setTargetDatabase(const QString& database)
{
this->database = database;
}
+
+QString SqliteCreateView::getObjectName() const
+{
+ return view;
+}
+
+void SqliteCreateView::setObjectName(const QString& name)
+{
+ view = name;
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h
index 74f6b91..645532c 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h
@@ -21,6 +21,8 @@ class API_EXPORT SqliteCreateView : public SqliteQuery, public SqliteDdlWithDbCo
SqliteStatement* clone();
QString getTargetDatabase() const;
void setTargetDatabase(const QString& database);
+ QString getObjectName() const;
+ void setObjectName(const QString& name);
bool tempKw = false;
bool temporaryKw = false;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h
index cb64986..0daf378 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h
@@ -9,6 +9,9 @@ class API_EXPORT SqliteDdlWithDbContext
public:
virtual QString getTargetDatabase() const = 0;
virtual void setTargetDatabase(const QString& database) = 0;
+
+ virtual QString getObjectName() const = 0;
+ virtual void setObjectName(const QString& name) = 0;
};
typedef QSharedPointer<SqliteDdlWithDbContext> SqliteDdlWithDbContextPtr;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp
index dd4d7cb..faf92a4 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp
@@ -16,20 +16,21 @@ SqliteDelete::SqliteDelete(const SqliteDelete& other) :
{
DEEP_COPY_FIELD(SqliteExpr, where);
DEEP_COPY_FIELD(SqliteWith, with);
+ DEEP_COPY_COLLECTION(SqliteResultColumn, returning);
}
-SqliteDelete::SqliteDelete(const QString &name1, const QString &name2, const QString& indexedByName, SqliteExpr *where, SqliteWith* with)
+SqliteDelete::SqliteDelete(const QString &name1, const QString &name2, const QString& indexedByName, SqliteExpr *where, SqliteWith* with, const QList<SqliteResultColumn*>& returning)
: SqliteDelete()
{
- init(name1, name2, where, with);
+ init(name1, name2, where, with, returning);
this->indexedBy = indexedByName;
this->indexedByKw = true;
}
-SqliteDelete::SqliteDelete(const QString &name1, const QString &name2, bool notIndexedKw, SqliteExpr *where, SqliteWith* with)
+SqliteDelete::SqliteDelete(const QString &name1, const QString &name2, bool notIndexedKw, SqliteExpr *where, SqliteWith* with, const QList<SqliteResultColumn*>& returning)
: SqliteDelete()
{
- init(name1, name2, where, with);
+ init(name1, name2, where, with, returning);
this->notIndexedKw = notIndexedKw;
}
@@ -37,7 +38,7 @@ SqliteDelete::~SqliteDelete()
{
}
-SqliteStatement*SqliteDelete::clone()
+SqliteStatement* SqliteDelete::clone()
{
return new SqliteDelete(*this);
}
@@ -91,7 +92,7 @@ QList<SqliteStatement::FullObject> SqliteDelete::getFullObjectsInStatement()
return result;
}
-void SqliteDelete::init(const QString &name1, const QString &name2, SqliteExpr *where, SqliteWith* with)
+void SqliteDelete::init(const QString &name1, const QString &name2, SqliteExpr *where, SqliteWith* with, const QList<SqliteResultColumn*>& returning)
{
this->where = where;
if (where)
@@ -108,6 +109,10 @@ void SqliteDelete::init(const QString &name1, const QString &name2, SqliteExpr *
}
else
table = name1;
+
+ this->returning = returning;
+ for (SqliteResultColumn*& retCol : this->returning)
+ retCol->setParent(this);
}
TokenList SqliteDelete::rebuildTokensFromContents()
@@ -131,6 +136,13 @@ TokenList SqliteDelete::rebuildTokensFromContents()
if (where)
builder.withSpace().withKeyword("WHERE").withStatement(where);
+ if (!returning.isEmpty())
+ {
+ builder.withKeyword("RETURNING");
+ for (SqliteResultColumn*& retCol : returning)
+ builder.withSpace().withStatement(retCol);
+ }
+
builder.withOperator(";");
return builder.build();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h
index 5d24619..faa38fe 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.h
@@ -2,8 +2,9 @@
#define SQLITEDELETE_H
#include "sqlitequery.h"
-
+#include "sqliteselect.h"
#include <QString>
+#include <QList>
class SqliteExpr;
class SqliteWith;
@@ -13,8 +14,10 @@ class API_EXPORT SqliteDelete : public SqliteQuery
public:
SqliteDelete();
SqliteDelete(const SqliteDelete& other);
- SqliteDelete(const QString& name1, const QString& name2, const QString& indexedByName, SqliteExpr* where, SqliteWith* with);
- SqliteDelete(const QString& name1, const QString& name2, bool notIndexedKw, SqliteExpr* where, SqliteWith* with);
+ SqliteDelete(const QString& name1, const QString& name2, const QString& indexedByName, SqliteExpr* where, SqliteWith* with,
+ const QList<SqliteResultColumn*>& returning);
+ SqliteDelete(const QString& name1, const QString& name2, bool notIndexedKw, SqliteExpr* where, SqliteWith* with,
+ const QList<SqliteResultColumn*>& returning);
~SqliteDelete();
SqliteStatement* clone();
@@ -28,7 +31,8 @@ class API_EXPORT SqliteDelete : public SqliteQuery
TokenList rebuildTokensFromContents();
private:
- void init(const QString& name1, const QString& name2, SqliteExpr* where, SqliteWith* with);
+ void init(const QString& name1, const QString& name2, SqliteExpr* where, SqliteWith* with,
+ const QList<SqliteResultColumn*>& returning);
public:
QString database = QString();
@@ -38,6 +42,7 @@ class API_EXPORT SqliteDelete : public SqliteQuery
QString indexedBy = QString();
SqliteExpr* where = nullptr;
SqliteWith* with = nullptr;
+ QList<SqliteResultColumn*> returning;
};
typedef QSharedPointer<SqliteDelete> SqliteDeletePtr;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp
index e2c79ea..89c6b9b 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp
@@ -231,6 +231,19 @@ void SqliteExpr::initUnaryOp(SqliteExpr *expr, const QString& op)
expr->setParent(this);
}
+void SqliteExpr::initPtrOp(SqliteExpr* expr1, const QString& op, SqliteExpr* expr2)
+{
+ mode = SqliteExpr::Mode::PTR_OP;
+ this->expr1 = expr1;
+ this->expr2 = expr2;
+ ptrOp = op;
+ if (expr1)
+ expr1->setParent(this);
+
+ if (expr2)
+ expr2->setParent(this);
+}
+
void SqliteExpr::initLike(SqliteExpr *expr1, bool notKw, LikeOp likeOp, SqliteExpr *expr2, SqliteExpr *expr3)
{
mode = SqliteExpr::Mode::LIKE;
@@ -271,6 +284,19 @@ void SqliteExpr::initIs(SqliteExpr *expr1, bool notKw, SqliteExpr *expr2)
expr2->setParent(this);
}
+void SqliteExpr::initDistinct(SqliteExpr* expr1, bool notKw, SqliteExpr* expr2)
+{
+ mode = SqliteExpr::Mode::DISTINCT;
+ this->expr1 = expr1;
+ this->notKw = notKw;
+ this->expr2 = expr2;
+ if (expr1)
+ expr1->setParent(this);
+
+ if (expr2)
+ expr2->setParent(this);
+}
+
void SqliteExpr::initBetween(SqliteExpr *expr1, bool notKw, SqliteExpr *expr2, SqliteExpr *expr3)
{
mode = SqliteExpr::Mode::BETWEEN;
@@ -549,6 +575,9 @@ TokenList SqliteExpr::rebuildTokensFromContents()
case SqliteExpr::Mode::BINARY_OP:
builder.withStatement(expr1).withSpace().withOperator(binaryOp).withSpace().withStatement(expr2);
break;
+ case SqliteExpr::Mode::PTR_OP:
+ builder.withStatement(expr1).withSpace().withOperator(ptrOp).withSpace().withStatement(expr2);
+ break;
case SqliteExpr::Mode::FUNCTION:
builder.withOther(function).withParLeft();
if (distinctKw)
@@ -598,6 +627,9 @@ TokenList SqliteExpr::rebuildTokensFromContents()
case SqliteExpr::Mode::IS:
builder.withTokens(rebuildIs());
break;
+ case SqliteExpr::Mode::DISTINCT:
+ builder.withTokens(rebuildDistinct());
+ break;
case SqliteExpr::Mode::BETWEEN:
builder.withTokens(rebuildBetween());
break;
@@ -691,6 +723,17 @@ TokenList SqliteExpr::rebuildIs()
return builder.build();
}
+TokenList SqliteExpr::rebuildDistinct()
+{
+ StatementTokenBuilder builder;
+ builder.withStatement(expr1).withSpace().withKeyword("IS");
+ if (notKw)
+ builder.withSpace().withKeyword("NOT");
+
+ builder.withSpace().withKeyword("DISTINCT").withSpace().withKeyword("FROM").withSpace().withStatement(expr2);
+ return builder.build();
+}
+
TokenList SqliteExpr::rebuildBetween()
{
StatementTokenBuilder builder;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h
index ef4c7da..f5fc6c2 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.h
@@ -23,6 +23,7 @@ class API_EXPORT SqliteExpr : public SqliteStatement
ID,
UNARY_OP,
BINARY_OP,
+ PTR_OP,
FUNCTION,
SUB_EXPR,
ROW_VALUE,
@@ -32,6 +33,7 @@ class API_EXPORT SqliteExpr : public SqliteStatement
NULL_,
NOTNULL,
IS,
+ DISTINCT,
BETWEEN,
IN,
EXISTS,
@@ -85,9 +87,11 @@ class API_EXPORT SqliteExpr : public SqliteStatement
void initWindowFunction(const QString& fnName, SqliteFilterOver* filterOver);
void initBinOp(SqliteExpr* expr1, const QString& op, SqliteExpr* expr2);
void initUnaryOp(SqliteExpr* expr, const QString& op);
+ void initPtrOp(SqliteExpr* expr1, const QString& op, SqliteExpr* expr2);
void initLike(SqliteExpr* expr1, bool notKw, SqliteExpr::LikeOp likeOp, SqliteExpr* expr2, SqliteExpr* expr3 = nullptr);
void initNull(SqliteExpr* expr, const QString& value);
void initIs(SqliteExpr* expr1, bool notKw, SqliteExpr* expr2);
+ void initDistinct(SqliteExpr* expr1, bool notKw, SqliteExpr* expr2);
void initBetween(SqliteExpr* expr1, bool notKw, SqliteExpr* expr2, SqliteExpr* expr3);
void initIn(SqliteExpr* expr, bool notKw, const QList<SqliteExpr*>& exprList);
void initIn(SqliteExpr* expr, bool notKw, SqliteSelect* select);
@@ -108,6 +112,7 @@ class API_EXPORT SqliteExpr : public SqliteStatement
QString column = QString();
QString unaryOp = QString();
QString binaryOp = QString();
+ QString ptrOp = QString();
QString function = QString();
QString collation = QString();
QString ctime = QString();
@@ -144,6 +149,7 @@ class API_EXPORT SqliteExpr : public SqliteStatement
TokenList rebuildLike();
TokenList rebuildNotNull();
TokenList rebuildIs();
+ TokenList rebuildDistinct();
TokenList rebuildBetween();
TokenList rebuildIn();
TokenList rebuildCase();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp
index 906b385..5242fa6 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp
@@ -20,14 +20,14 @@ SqliteInsert::SqliteInsert(const SqliteInsert& other) :
DEEP_COPY_FIELD(SqliteSelect, select);
DEEP_COPY_FIELD(SqliteWith, with);
DEEP_COPY_FIELD(SqliteUpsert, upsert);
+ DEEP_COPY_COLLECTION(SqliteResultColumn, returning);
}
SqliteInsert::SqliteInsert(bool replace, SqliteConflictAlgo onConflict, const QString &name1, const QString &name2, const QList<QString> &columns,
- const QList<SqliteExpr *> &row, SqliteWith* with) :
+ const QList<SqliteExpr *> &row, SqliteWith* with, const QList<SqliteResultColumn*>& returning) :
SqliteInsert()
{
- initName(name1, name2);
- initMode(replace, onConflict);
+ init(name1, name2, replace, onConflict, returning);
columnNames = columns;
values = row;
@@ -40,11 +40,10 @@ SqliteInsert::SqliteInsert(bool replace, SqliteConflictAlgo onConflict, const QS
}
SqliteInsert::SqliteInsert(bool replace, SqliteConflictAlgo onConflict, const QString &name1, const QString &name2, const QList<QString> &columns,
- SqliteSelect *select, SqliteWith* with, SqliteUpsert* upsert) :
+ SqliteSelect *select, SqliteWith* with, SqliteUpsert* upsert, const QList<SqliteResultColumn*>& returning) :
SqliteInsert()
{
- initName(name1, name2);
- initMode(replace, onConflict);
+ init(name1, name2, replace, onConflict, returning);
this->with = with;
if (with)
@@ -61,11 +60,10 @@ SqliteInsert::SqliteInsert(bool replace, SqliteConflictAlgo onConflict, const QS
}
SqliteInsert::SqliteInsert(bool replace, SqliteConflictAlgo onConflict, const QString &name1, const QString &name2, const QList<QString> &columns,
- SqliteWith* with) :
+ SqliteWith* with, const QList<SqliteResultColumn*>& returning) :
SqliteInsert()
{
- initName(name1, name2);
- initMode(replace, onConflict);
+ init(name1, name2, replace, onConflict, returning);
this->with = with;
if (with)
@@ -104,7 +102,7 @@ QStringList SqliteInsert::getDatabasesInStatement()
TokenList SqliteInsert::getColumnTokensInStatement()
{
TokenList list;
- for (TokenPtr token : getTokenListFromNamedKey("idlist_opt", -1))
+ for (TokenPtr& token : getTokenListFromNamedKey("idlist_opt", -1))
{
if (token->type != Token::OTHER && token->type != Token::KEYWORD)
continue;
@@ -153,7 +151,7 @@ QList<SqliteStatement::FullObject> SqliteInsert::getFullObjectsInStatement()
return result;
}
-void SqliteInsert::initName(const QString& name1, const QString& name2)
+void SqliteInsert::init(const QString& name1, const QString& name2, bool replace, SqliteConflictAlgo onConflict, const QList<SqliteResultColumn*>& returning)
{
if (!name2.isNull())
{
@@ -162,12 +160,13 @@ void SqliteInsert::initName(const QString& name1, const QString& name2)
}
else
table = name1;
-}
-void SqliteInsert::initMode(bool replace, SqliteConflictAlgo onConflict)
-{
replaceKw = replace;
this->onConflict = onConflict;
+
+ this->returning = returning;
+ for (SqliteResultColumn*& retCol : this->returning)
+ retCol->setParent(this);
}
TokenList SqliteInsert::rebuildTokensFromContents()
@@ -212,6 +211,13 @@ TokenList SqliteInsert::rebuildTokensFromContents()
}
}
+ if (!returning.isEmpty())
+ {
+ builder.withKeyword("RETURNING");
+ for (SqliteResultColumn*& retCol : returning)
+ builder.withSpace().withStatement(retCol);
+ }
+
builder.withOperator(";");
return builder.build();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h
index 40581cd..b409abc 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.h
@@ -3,10 +3,10 @@
#include "sqlitequery.h"
#include "sqliteconflictalgo.h"
+#include "sqliteselect.h"
#include <QString>
#include <QList>
-class SqliteSelect;
class SqliteExpr;
class SqliteWith;
class SqliteUpsert;
@@ -18,11 +18,14 @@ class API_EXPORT SqliteInsert : public SqliteQuery
SqliteInsert(const SqliteInsert& other);
SqliteInsert(bool replace, SqliteConflictAlgo onConflict, const QString& name1,
const QString& name2, const QList<QString>& columns,
- const QList<SqliteExpr*>& row, SqliteWith* with);
+ const QList<SqliteExpr*>& row, SqliteWith* with,
+ const QList<SqliteResultColumn*>& returning);
SqliteInsert(bool replace, SqliteConflictAlgo onConflict, const QString& name1,
- const QString& name2, const QList<QString>& columns, SqliteSelect* select, SqliteWith* with, SqliteUpsert* upsert = nullptr);
+ const QString& name2, const QList<QString>& columns, SqliteSelect* select, SqliteWith* with,
+ SqliteUpsert* upsert, const QList<SqliteResultColumn*>& returning);
SqliteInsert(bool replace, SqliteConflictAlgo onConflict, const QString& name1,
- const QString& name2, const QList<QString>& columns, SqliteWith* with);
+ const QString& name2, const QList<QString>& columns, SqliteWith* with,
+ const QList<SqliteResultColumn*>& returning);
~SqliteInsert();
SqliteStatement* clone();
@@ -38,8 +41,8 @@ class API_EXPORT SqliteInsert : public SqliteQuery
TokenList rebuildTokensFromContents();
private:
- void initName(const QString& name1, const QString& name2);
- void initMode(bool replace, SqliteConflictAlgo onConflict);
+ void init(const QString& name1, const QString& name2, bool replace, SqliteConflictAlgo onConflict,
+ const QList<SqliteResultColumn*>& returning);
public:
bool replaceKw = false;
@@ -52,6 +55,7 @@ class API_EXPORT SqliteInsert : public SqliteQuery
SqliteSelect* select = nullptr;
SqliteWith* with = nullptr;
SqliteUpsert* upsert = nullptr;
+ QList<SqliteResultColumn*> returning;
};
typedef QSharedPointer<SqliteInsert> SqliteInsertPtr;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp
index 732c0a2..4db4b5d 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp
@@ -88,18 +88,20 @@ void SqliteOrderBy::setColumnName(const QString& name)
void SqliteOrderBy::setCollation(const QString& name)
{
- if (expr && expr->mode == SqliteExpr::Mode::COLLATE)
+ if (!expr)
+ return;
+
+ if (expr->mode == SqliteExpr::Mode::COLLATE)
{
expr->collation = name;
+ return;
}
- else
- {
- SqliteExpr* theExpr = expr;
- SqliteExpr* collationExpr = new SqliteExpr();
- collationExpr->initCollate(theExpr, name);
- theExpr->setParent(collationExpr);
- collationExpr->setParent(this);
- }
+
+ SqliteExpr* collationExpr = new SqliteExpr();
+ collationExpr->initCollate(expr, name);
+ expr->setParent(collationExpr);
+ collationExpr->setParent(this);
+ expr = collationExpr;
}
TokenList SqliteOrderBy::rebuildTokensFromContents()
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp
index 1c04ca6..b70778e 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequerytype.cpp
@@ -60,9 +60,8 @@ QString sqliteQueryTypeToString(const SqliteQueryType& type)
return "Update";
case SqliteQueryType::Vacuum:
return "Vacuum";
- default:
- return QString();
}
+ return QString();
}
bool isDataReturningQuery(const SqliteQueryType& type)
@@ -98,7 +97,7 @@ bool isDataReturningQuery(const SqliteQueryType& type)
case SqliteQueryType::Savepoint:
case SqliteQueryType::Update:
case SqliteQueryType::Vacuum:
- default:
return false;
}
+ return false;
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp
index e0439d2..501f7f3 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp
@@ -118,7 +118,7 @@ SqliteSelect::CompoundOperator SqliteSelect::compoundOperator(const QString& op)
void SqliteSelect::reset()
{
- for (Core* core : coreSelects)
+ for (Core*& core : coreSelects)
delete core;
coreSelects.clear();
@@ -443,7 +443,7 @@ QStringList SqliteSelect::Core::JoinConstraint::getColumnsInStatement()
TokenList SqliteSelect::Core::JoinConstraint::getColumnTokensInStatement()
{
TokenList list;
- for (TokenPtr token : getTokenListFromNamedKey("idlist", -1))
+ for (TokenPtr& token : getTokenListFromNamedKey("idlist", -1))
{
if (token->type == Token::OPERATOR) // a COMMA
continue;
@@ -573,7 +573,7 @@ SqliteSelect::Core::JoinSource::JoinSource(SqliteSelect::Core::SingleSource *sin
if (singleSource)
singleSource->setParent(this);
- for (JoinSourceOther* other : otherSources)
+ for (JoinSourceOther*& other : otherSources)
other->setParent(this);
}
@@ -667,11 +667,6 @@ TokenList SqliteSelect::Core::SingleSource::rebuildTokensFromContents()
TokenList SqliteSelect::Core::JoinOp::rebuildTokensFromContents()
{
- return rebuildTokensForSqlite3();
-}
-
-TokenList SqliteSelect::Core::JoinOp::rebuildTokensForSqlite3()
-{
StatementTokenBuilder builder;
if (comma)
{
@@ -682,9 +677,16 @@ TokenList SqliteSelect::Core::JoinOp::rebuildTokensForSqlite3()
if (naturalKw)
builder.withKeyword("NATURAL").withSpace();
- if (leftKw)
+ if (leftKw || fullKw || rightKw)
{
- builder.withKeyword("LEFT").withSpace();
+ if (leftKw)
+ builder.withKeyword("LEFT");
+ else if (fullKw)
+ builder.withKeyword("FULL");
+ else if (rightKw)
+ builder.withKeyword("RIGHT");
+
+ builder.withSpace();
if (outerKw)
builder.withKeyword("OUTER").withSpace();
}
@@ -780,7 +782,7 @@ TokenList SqliteSelect::rebuildTokensFromContents()
if (with)
builder.withStatement(with);
- for (SqliteSelect::Core* core : coreSelects)
+ for (SqliteSelect::Core*& core : coreSelects)
{
if (core->compoundOp == CompoundOperator::UNION_ALL)
{
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h
index 58babfe..dfed9c2 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.h
@@ -123,9 +123,6 @@ class API_EXPORT SqliteSelect : public SqliteQuery
protected:
TokenList rebuildTokensFromContents();
-
- private:
- TokenList rebuildTokensForSqlite3();
};
class API_EXPORT JoinConstraint : public SqliteStatement
@@ -232,5 +229,6 @@ class API_EXPORT SqliteSelect : public SqliteQuery
};
typedef QSharedPointer<SqliteSelect> SqliteSelectPtr;
+typedef SqliteSelect::Core::ResultColumn SqliteResultColumn;
#endif // SQLITESELECT_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h
index 43a60ba..167321f 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitestatement.h
@@ -228,6 +228,12 @@ class API_EXPORT SqliteStatement : public QObject
virtual SqliteStatement* clone() = 0;
template <class T>
+ T* typeClone()
+ {
+ return dynamic_cast<T*>(clone());
+ }
+
+ template <class T>
void attach(QList<T*>& listMemberForChild, T* childStatementToAttach)
{
listMemberForChild << childStatementToAttach;
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp
index 89c8195..55d8b34 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp
@@ -27,6 +27,7 @@ SqliteUpdate::SqliteUpdate(const SqliteUpdate& other) :
DEEP_COPY_FIELD(SqliteExpr, where);
DEEP_COPY_FIELD(SqliteWith, with);
DEEP_COPY_FIELD(SqliteSelect::Core::JoinSource, from);
+ DEEP_COPY_COLLECTION(SqliteResultColumn, returning);
}
SqliteUpdate::~SqliteUpdate()
@@ -34,7 +35,7 @@ SqliteUpdate::~SqliteUpdate()
}
SqliteUpdate::SqliteUpdate(SqliteConflictAlgo onConflict, const QString &name1, const QString &name2, bool notIndexedKw, const QString &indexedBy,
- const QList<ColumnAndValue>& values, SqliteSelect::Core::JoinSource* from, SqliteExpr *where, SqliteWith* with)
+ const QList<ColumnAndValue>& values, SqliteSelect::Core::JoinSource* from, SqliteExpr *where, SqliteWith* with, const QList<SqliteResultColumn*>& returning)
: SqliteUpdate()
{
this->onConflict = onConflict;
@@ -64,8 +65,12 @@ SqliteUpdate::SqliteUpdate(SqliteConflictAlgo onConflict, const QString &name1,
if (with)
with->setParent(this);
- for (const ColumnAndValue& keyValue : keyValueMap)
+ for (ColumnAndValue& keyValue : keyValueMap)
keyValue.second->setParent(this);
+
+ this->returning = returning;
+ for (SqliteResultColumn*& retCol : this->returning)
+ retCol->setParent(this);
}
SqliteStatement*SqliteUpdate::clone()
@@ -75,7 +80,7 @@ SqliteStatement*SqliteUpdate::clone()
SqliteExpr* SqliteUpdate::getValueForColumnSet(const QString& column)
{
- for (const ColumnAndValue& keyValue : keyValueMap)
+ for (ColumnAndValue& keyValue : keyValueMap)
{
if (keyValue.first == column)
return keyValue.second;
@@ -86,7 +91,7 @@ SqliteExpr* SqliteUpdate::getValueForColumnSet(const QString& column)
QStringList SqliteUpdate::getColumnsInStatement()
{
QStringList columns;
- for (const ColumnAndValue& keyValue : keyValueMap)
+ for (ColumnAndValue& keyValue : keyValueMap)
{
if (keyValue.first.type() == QVariant::StringList)
columns += keyValue.first.toStringList();
@@ -120,7 +125,7 @@ TokenList SqliteUpdate::getColumnTokensInStatement()
int end;
int start = 0;
SqliteExpr* expr = nullptr;
- for (const ColumnAndValue& keyValue : keyValueMap)
+ for (ColumnAndValue& keyValue : keyValueMap)
{
expr = keyValue.second;
end = setListTokens.indexOf(expr->tokens[0]);
@@ -205,7 +210,7 @@ TokenList SqliteUpdate::rebuildTokensFromContents()
builder.withKeyword("SET").withSpace();
bool first = true;
- for (const ColumnAndValue& keyVal : keyValueMap)
+ for (ColumnAndValue& keyVal : keyValueMap)
{
if (!first)
builder.withOperator(",").withSpace();
@@ -225,6 +230,13 @@ TokenList SqliteUpdate::rebuildTokensFromContents()
if (where)
builder.withSpace().withKeyword("WHERE").withStatement(where);
+ if (!returning.isEmpty())
+ {
+ builder.withKeyword("RETURNING");
+ for (SqliteResultColumn*& retCol : returning)
+ builder.withSpace().withStatement(retCol);
+ }
+
builder.withOperator(";");
return builder.build();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h
index e843bcd..be121b2 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.h
@@ -21,7 +21,7 @@ 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,
- SqliteSelect::Core::JoinSource* from, SqliteExpr* where, SqliteWith* with);
+ SqliteSelect::Core::JoinSource* from, SqliteExpr* where, SqliteWith* with, const QList<SqliteResultColumn*>& returning);
SqliteStatement* clone();
SqliteExpr* getValueForColumnSet(const QString& column);
@@ -36,6 +36,7 @@ class API_EXPORT SqliteUpdate : public SqliteQuery
SqliteSelect::Core::JoinSource* from = nullptr;
SqliteExpr* where = nullptr;
SqliteWith* with = nullptr;
+ QList<SqliteResultColumn*> returning;
protected:
QStringList getColumnsInStatement();
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp
index adf135f..69138b6 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewindowdefinition.cpp
@@ -265,7 +265,7 @@ SqliteWindowDefinition::Window::Frame::Bound::Bound(SqliteExpr* expr, const QStr
if (upper == "UNBOUNDED PRECEDING")
type = Type::UNBOUNDED_PRECEDING;
else if (expr && upper == "PRECEDING")
- type = Type::EXPR_FOLLOWING;
+ type = Type::EXPR_PRECEDING;
else if (upper == "UNBOUNDED FOLLOWING")
type = Type::UNBOUNDED_FOLLOWING;
else if (expr && upper == "FOLLOWING")
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp
index 901ac56..c15b447 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.cpp
@@ -36,19 +36,19 @@ SqliteWith::CommonTableExpression::CommonTableExpression()
}
SqliteWith::CommonTableExpression::CommonTableExpression(const SqliteWith::CommonTableExpression& other) :
- SqliteStatement(other), table(other.table)
+ SqliteStatement(other), table(other.table), asMode(other.asMode)
{
DEEP_COPY_COLLECTION(SqliteIndexedColumn, indexedColumns);
DEEP_COPY_FIELD(SqliteSelect, select);
}
-SqliteWith::CommonTableExpression::CommonTableExpression(const QString& tableName, const QList<SqliteIndexedColumn*>& indexedColumns, SqliteSelect* select) :
- table(tableName), indexedColumns(indexedColumns), select(select)
+SqliteWith::CommonTableExpression::CommonTableExpression(const QString& tableName, const QList<SqliteIndexedColumn*>& indexedColumns, SqliteSelect* select, AsMode asMode) :
+ table(tableName), indexedColumns(indexedColumns), select(select), asMode(asMode)
{
select->setParent(this);
}
-SqliteStatement*SqliteWith::CommonTableExpression::clone()
+SqliteStatement* SqliteWith::CommonTableExpression::clone()
{
return new SqliteWith::CommonTableExpression(*this);
}
@@ -61,7 +61,19 @@ TokenList SqliteWith::CommonTableExpression::rebuildTokensFromContents()
if (indexedColumns.size() > 0)
builder.withSpace().withParLeft().withStatementList(indexedColumns).withParRight();
- builder.withSpace().withKeyword("AS").withSpace().withParLeft().withStatement(select).withParRight();
+ builder.withSpace().withKeyword("AS");
+ switch (asMode) {
+ case ANY:
+ break;
+ case MATERIALIZED:
+ builder.withKeyword("MATERIALIZED");
+ break;
+ case NOT_MATERIALIZED:
+ builder.withKeyword("NOT").withSpace().withKeyword("MATERIALIZED");
+ break;
+ }
+
+ builder.withSpace().withParLeft().withStatement(select).withParRight();
return builder.build();
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h
index 30f8181..8429e53 100644
--- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h
+++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitewith.h
@@ -12,15 +12,23 @@ class SqliteWith : public SqliteStatement
class CommonTableExpression : public SqliteStatement
{
public:
+ enum AsMode {
+ ANY,
+ MATERIALIZED,
+ NOT_MATERIALIZED
+ };
+
CommonTableExpression();
CommonTableExpression(const CommonTableExpression& other);
- CommonTableExpression(const QString& tableName, const QList<SqliteIndexedColumn*>& indexedColumns, SqliteSelect* select);
+ CommonTableExpression(const QString& tableName, const QList<SqliteIndexedColumn*>& indexedColumns, SqliteSelect* select,
+ AsMode asMode);
SqliteStatement* clone();
QString table;
QList<SqliteIndexedColumn*> indexedColumns;
SqliteSelect* select = nullptr;
+ AsMode asMode = ANY;
protected:
TokenList rebuildTokensFromContents();