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

View file

@ -50,6 +50,24 @@ from_item
: Ident Dot Ident from_alias? : Ident Dot Ident from_alias?
| Ident from_alias? | Ident from_alias?
| OpenParen select_stmt CloseParen 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 from_alias

View file

@ -45,11 +45,13 @@ SOURCES += \
catalog/PgConstraintContainer.cpp \ catalog/PgConstraintContainer.cpp \
ParamListJson.cpp \ ParamListJson.cpp \
ParamListModel.cpp \ ParamListModel.cpp \
sqlast/BuildStandardItemTreeModelNodeVisitor.cpp \
sqlast/ColumnDefinition.cpp \ sqlast/ColumnDefinition.cpp \
sqlast/CreateTable.cpp \ sqlast/CreateTable.cpp \
sqlast/Expression.cpp \ sqlast/Expression.cpp \
sqlast/Literal.cpp \ sqlast/Literal.cpp \
sqlast/Node.cpp \ sqlast/Node.cpp \
sqlast/NodeVisitor.cpp \
sqlast/SelectItem.cpp \ sqlast/SelectItem.cpp \
sqlast/SelectList.cpp \ sqlast/SelectList.cpp \
sqlast/SelectStatement.cpp \ sqlast/SelectStatement.cpp \
@ -130,11 +132,13 @@ HEADERS += \
catalog/PgConstraintContainer.h \ catalog/PgConstraintContainer.h \
ParamListJson.h \ ParamListJson.h \
ParamListModel.h \ ParamListModel.h \
sqlast/BuildStandardItemTreeModelNodeVisitor.h \
sqlast/ColumnDefinition.h \ sqlast/ColumnDefinition.h \
sqlast/CreateTable.h \ sqlast/CreateTable.h \
sqlast/Expression.h \ sqlast/Expression.h \
sqlast/Literal.h \ sqlast/Literal.h \
sqlast/Node.h \ sqlast/Node.h \
sqlast/NodeVisitor.h \
sqlast/SelectItem.h \ sqlast/SelectItem.h \
sqlast/SelectList.h \ sqlast/SelectList.h \
sqlast/SelectStatement.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() Node::Node()
{ {
}
QString Node::ToString() const
{
return QString::fromUtf8(typeid(*this).name());
} }

View file

@ -1,12 +1,25 @@
#pragma once #pragma once
#include <QString>
#include <stdexcept>
#include <typeinfo>
namespace sqlast { namespace sqlast {
class NodeVisitor;
class Node { class Node {
public: public:
Node(); Node();
virtual ~Node() = default; 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 "SelectItem.h"
#include "Expression.h" #include "Expression.h"
#include "NodeVisitor.h"
using namespace sqlast; using namespace sqlast;
@ -11,3 +12,8 @@ void SelectItem::SetAlias(const std::string &alias)
{ {
this->alias = 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); void SetAlias(const std::string &alias);
std::string GetAlias() const { return alias; } std::string GetAlias() const { return alias; }
void Accept(NodeVisitor &visitor) override;
private: private:
std::unique_ptr<Expression> expression; std::unique_ptr<Expression> expression;
std::string alias; std::string alias;

View file

@ -1,5 +1,6 @@
#include "SelectList.h" #include "SelectList.h"
#include "SelectItem.h" #include "SelectItem.h"
#include "sqlast/NodeVisitor.h"
using namespace sqlast; using namespace sqlast;
@ -9,10 +10,20 @@ SelectList::SelectList()
void SelectList::Add(std::unique_ptr<SelectItem> select_item) 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 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 { namespace sqlast {
class SelectItem; class SelectItem;
class SelectList : public Node class SelectList : public Node
@ -16,14 +18,13 @@ namespace sqlast {
void Add(std::unique_ptr<SelectItem> select_item); void Add(std::unique_ptr<SelectItem> select_item);
int Count() const; int Count() const;
SelectItem& Get(int index) SelectItem& Get(int index);
{
return *list.at(index); void Accept(NodeVisitor &visitor) override;
}
private: private:
using List = std::vector<std::unique_ptr<SelectItem>>; using List = std::vector<std::unique_ptr<SelectItem>>;
List list; List selectItems;
}; };
} }

View file

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

View file

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

View file

@ -1,6 +1,6 @@
#include "StatementList.h" #include "StatementList.h"
#include "Statement.h" #include "Statement.h"
#include "sqlast/NodeVisitor.h"
using namespace sqlast; using namespace sqlast;
@ -22,3 +22,8 @@ int StatementList::Count() const
return static_cast<int>(statements.size()); 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); Statement &Get(int index);
int Count() const; int Count() const;
void Accept(NodeVisitor &visitor) override;
private: private:
using Statements = std::vector<std::unique_ptr<Statement>>; using Statements = std::vector<std::unique_ptr<Statement>>;

View file

@ -1,7 +1,13 @@
#include "StringLiteral.h" #include "StringLiteral.h"
#include "NodeVisitor.h"
using namespace sqlast; using namespace sqlast;
StringLiteral::StringLiteral(const std::string s) StringLiteral::StringLiteral(const std::string s)
: value(QString::fromStdString(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); explicit StringLiteral(const std::string s);
QString GetValue() const { return value; } QString GetValue() const { return value; }
void Accept(NodeVisitor &visitor) override;
private: private:
QString value; QString value;
}; };

View file

@ -38,6 +38,17 @@ TEST(NewSqlLexer, QuotedIdent)
ASSERT_EQ("Abc", token->getText()); ASSERT_EQ("Abc", token->getText());
} }
TEST(NewSqlLexer, AcceptNewLineInQuotedIdent)
{
std::string source = "\"Ab\nc\"";
antlr4::ANTLRInputStream input(source);
PgsqlLexer lexer(&input);
auto token = lexer.nextToken();
ASSERT_EQ(PgsqlLexer::Ident, token->getType());
ASSERT_EQ("Ab\nc", token->getText());
}
TEST(NewSqlParser, statementList) TEST(NewSqlParser, statementList)
{ {