This commit is contained in:
eelke 2022-04-07 19:35:29 +02:00
parent 0da32b916c
commit 698ccab6ab
20 changed files with 265 additions and 37 deletions

View file

@ -11,45 +11,51 @@ Dot: '.';
OpenParen: '(';
CloseParen: ')';
fragment A : 'a' | 'A';
fragment B : 'B' | 'b';
fragment C : 'C' | 'c';
fragment D : 'D' | 'd';
fragment E : 'E' | 'e';
fragment F : 'F' | 'f';
fragment G : 'G' | 'g';
fragment H : 'H' | 'h';
fragment I : 'I' | 'i';
fragment J : 'J' | 'j';
fragment K : 'K' | 'k';
fragment L : 'L' | 'l';
fragment M : 'M' | 'm';
fragment N : 'N' | 'n';
fragment O : 'O' | 'o';
fragment P : 'P' | 'p';
fragment Q : 'Q' | 'q';
fragment R : 'R' | 'r';
fragment S : 'S' | 's';
fragment T : 'T' | 't';
fragment U : 'U' | 'u';
fragment V : 'V' | 'v';
fragment W : 'W' | 'w';
fragment X : 'X' | 'x';
fragment Y : 'Y' | 'y';
fragment Z : 'Z' | 'z';
fragment A : [aA];
fragment B : [bB];
fragment C : [cC];
fragment D : [dD];
fragment E : [eE];
fragment F : [fF];
fragment G : [gG];
fragment H : [hH];
fragment I : [iI];
fragment J : [jJ];
fragment K : [kK];
fragment L : [lL];
fragment M : [mM];
fragment N : [nN];
fragment O : [oO];
fragment P : [pP];
fragment Q : [qQ];
fragment R : [rR];
fragment S : [sS];
fragment T : [tT];
fragment U : [uU];
fragment V : [vV];
fragment W : [wW];
fragment X : [xX];
fragment Y : [yY];
fragment Z : [zZ];
As: A S;
By: B Y;
Cross: C R O S S;
From: F R O M;
Full: F U L L;
Group: G R O U P;
Having: H A V I N G;
Inner: I N N E R;
Join: J O I N;
Left : L E F T;
Natural : N A T U R A L;
On : O N;
Order : O R D E R;
Outer : O U T E R;
Right : R I G H T;
Select: S E L E C T;
Where: W H E R E;
Select : S E L E C T;
Using : U S I N G;
Where : W H E R E;
Ident: [\p{Alpha}]~[\p{White_Space}]*
{

View file

@ -50,6 +50,24 @@ from_item
: Ident Dot Ident from_alias?
| Ident from_alias?
| OpenParen select_stmt CloseParen from_alias
| from_item (Left|Right|Full) Outer? Join from_item (join_on_condition|join_using_condition)
| from_item Natural (Left|Right|Full) Outer? Join from_item
;
join_on_condition
: On
;
join_using_condition
: Using OpenParen ident_list CloseParen (As join_using_alias)
;
join_using_alias
:
;
ident_list
: Ident (Comma Ident)*
;
from_alias

View file

@ -45,11 +45,13 @@ SOURCES += \
catalog/PgConstraintContainer.cpp \
ParamListJson.cpp \
ParamListModel.cpp \
sqlast/BuildStandardItemTreeModelNodeVisitor.cpp \
sqlast/ColumnDefinition.cpp \
sqlast/CreateTable.cpp \
sqlast/Expression.cpp \
sqlast/Literal.cpp \
sqlast/Node.cpp \
sqlast/NodeVisitor.cpp \
sqlast/SelectItem.cpp \
sqlast/SelectList.cpp \
sqlast/SelectStatement.cpp \
@ -130,11 +132,13 @@ HEADERS += \
catalog/PgConstraintContainer.h \
ParamListJson.h \
ParamListModel.h \
sqlast/BuildStandardItemTreeModelNodeVisitor.h \
sqlast/ColumnDefinition.h \
sqlast/CreateTable.h \
sqlast/Expression.h \
sqlast/Literal.h \
sqlast/Node.h \
sqlast/NodeVisitor.h \
sqlast/SelectItem.h \
sqlast/SelectList.h \
sqlast/SelectStatement.h \

View file

@ -0,0 +1,69 @@
#include "BuildStandardItemTreeModelNodeVisitor.h"
using namespace sqlast;
namespace {
template <class T>
class AutoRevert {
public:
AutoRevert(T& var, const T newValue)
: variable(var)
, previousValue(var)
{
variable = std::move(newValue);
}
AutoRevert(T& var, const T&& newValue)
: variable(var)
, previousValue(var)
{
variable = std::move(newValue);
}
~AutoRevert()
{
variable = std::move(previousValue);
}
AutoRevert(const AutoRevert&) = delete;
AutoRevert operator=(const AutoRevert&) = delete;
private:
T& variable;
T previousValue;
};
template<class T>
AutoRevert<T> MakeAutoRevert(T& var, const T newValue)
{
return AutoRevert<T>(var, newValue);
}
}
BuildStandardItemTreeModelNodeVisitor::BuildStandardItemTreeModelNodeVisitor()
: model(std::make_unique<QStandardItemModel>())
, currentParent(model->invisibleRootItem())
{
}
void BuildStandardItemTreeModelNodeVisitor::Visit(SelectItem &selectItem)
{
}
void BuildStandardItemTreeModelNodeVisitor::Visit(SelectList &selectList)
{
}
void BuildStandardItemTreeModelNodeVisitor::Visit(SelectStatement &selectStatement)
{
auto item = new QStandardItem("SELECT");
currentParent->appendRow(item);
auto guard = MakeAutoRevert(currentParent, item);
}
void sqlast::BuildStandardItemTreeModelNodeVisitor::Visit(StatementList &statementList)
{
}

View file

@ -0,0 +1,28 @@
#pragma once
#include "NodeVisitor.h"
#include <QStandardItemModel>
#include <memory>
namespace sqlast {
class BuildStandardItemTreeModelNodeVisitor : public NodeVisitor
{
public:
BuildStandardItemTreeModelNodeVisitor();
// NodeVisitor interface
public:
virtual void Visit(SelectItem &selectItem) override;
virtual void Visit(SelectList &selectList) override;
virtual void Visit(SelectStatement &selectStatement) override;
virtual void Visit(StatementList &statementList) override;
virtual void Visit(StringLiteral &stringLiteral) override;
private:
std::unique_ptr<QStandardItemModel> model;
QStandardItem *currentParent;
};
}

View file

@ -4,5 +4,9 @@ using namespace sqlast;
Node::Node()
{
}
QString Node::ToString() const
{
return QString::fromUtf8(typeid(*this).name());
}

View file

@ -1,12 +1,25 @@
#pragma once
#include <QString>
#include <stdexcept>
#include <typeinfo>
namespace sqlast {
class NodeVisitor;
class Node {
public:
Node();
virtual ~Node() = default;
virtual void Accept(NodeVisitor &visitor) = 0;
/// Every derived class that has child nodes should override these
/// to facilitate
// virtual int ChildCount() const { return 0; }
// virtual const Node* GetChild(int index) const { throw std::out_of_range("GetChild"); }
virtual QString ToString() const;
};
}

View file

@ -0,0 +1,8 @@
#include "NodeVisitor.h"
#include "sqlast/SelectList.h"
void sqlast::NodeVisitor::VisitSelectListItems(SelectList &selectList)
{
for (int idx = 0; idx < selectList.Count(); ++idx)
Visit(selectList.Get(idx));
}

View file

@ -0,0 +1,27 @@
#pragma once
namespace sqlast {
class SelectItem;
class SelectList;
class SelectStatement;
class StatementList;
class StringLiteral;
class NodeVisitor
{
public:
virtual ~NodeVisitor() = default;
virtual void Visit(SelectItem &selectItem) = 0;
virtual void Visit(SelectList &selectList) = 0;
virtual void Visit(SelectStatement &selectStatement) = 0;
virtual void Visit(StatementList &statementList) = 0;
virtual void Visit(StringLiteral &stringLiteral) = 0;
protected:
void VisitSelectListItems(SelectList &selectList);
};
}

View file

@ -1,5 +1,6 @@
#include "SelectItem.h"
#include "Expression.h"
#include "NodeVisitor.h"
using namespace sqlast;
@ -11,3 +12,8 @@ void SelectItem::SetAlias(const std::string &alias)
{
this->alias = alias;
}
void SelectItem::Accept(NodeVisitor &visitor)
{
visitor.Visit(*this);
}

View file

@ -17,6 +17,8 @@ public:
void SetAlias(const std::string &alias);
std::string GetAlias() const { return alias; }
void Accept(NodeVisitor &visitor) override;
private:
std::unique_ptr<Expression> expression;
std::string alias;

View file

@ -1,5 +1,6 @@
#include "SelectList.h"
#include "SelectItem.h"
#include "sqlast/NodeVisitor.h"
using namespace sqlast;
@ -9,10 +10,20 @@ SelectList::SelectList()
void SelectList::Add(std::unique_ptr<SelectItem> select_item)
{
list.push_back(std::move(select_item));
selectItems.push_back(std::move(select_item));
}
int SelectList::Count() const
{
return static_cast<int>(list.size());
return static_cast<int>(selectItems.size());
}
SelectItem &SelectList::Get(int index)
{
return *selectItems.at(index);
}
void SelectList::Accept(NodeVisitor &visitor)
{
visitor.Visit(*this);
}

View file

@ -6,6 +6,8 @@
namespace sqlast {
class SelectItem;
class SelectList : public Node
@ -16,14 +18,13 @@ namespace sqlast {
void Add(std::unique_ptr<SelectItem> select_item);
int Count() const;
SelectItem& Get(int index)
{
return *list.at(index);
}
SelectItem& Get(int index);
void Accept(NodeVisitor &visitor) override;
private:
using List = std::vector<std::unique_ptr<SelectItem>>;
List list;
List selectItems;
};
}

View file

@ -1,5 +1,6 @@
#include "SelectStatement.h"
#include "SelectList.h"
#include "NodeVisitor.h"
using namespace sqlast;
@ -17,3 +18,8 @@ void SelectStatement::SetSelectList(std::unique_ptr<SelectList> value)
{
selectList = std::move(value);
}
void SelectStatement::Accept(NodeVisitor &visitor)
{
visitor.Visit(*this);
}

View file

@ -15,6 +15,7 @@ namespace sqlast {
SelectList* GetSelectList();
void SetSelectList(std::unique_ptr<SelectList> value);
void Accept(NodeVisitor &visitor) override;
private:
std::unique_ptr<SelectList> selectList;
};

View file

@ -1,6 +1,6 @@
#include "StatementList.h"
#include "Statement.h"
#include "sqlast/NodeVisitor.h"
using namespace sqlast;
@ -22,3 +22,8 @@ int StatementList::Count() const
return static_cast<int>(statements.size());
}
void StatementList::Accept(NodeVisitor &visitor)
{
visitor.Visit(*this);
}

View file

@ -18,6 +18,7 @@ namespace sqlast {
Statement &Get(int index);
int Count() const;
void Accept(NodeVisitor &visitor) override;
private:
using Statements = std::vector<std::unique_ptr<Statement>>;

View file

@ -1,7 +1,13 @@
#include "StringLiteral.h"
#include "NodeVisitor.h"
using namespace sqlast;
StringLiteral::StringLiteral(const std::string s)
: value(QString::fromStdString(s))
{}
void StringLiteral::Accept(NodeVisitor &visitor)
{
visitor.Visit(*this);
}

View file

@ -12,6 +12,7 @@ namespace sqlast {
explicit StringLiteral(const std::string s);
QString GetValue() const { return value; }
void Accept(NodeVisitor &visitor) override;
private:
QString value;
};