Skip to content

Commit 8dd3af5

Browse files
committed
Finish implementing all the SELECT features
1 parent a860d43 commit 8dd3af5

File tree

3 files changed

+140
-8
lines changed

3 files changed

+140
-8
lines changed

SQLEmitter.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ Error emitSQL(raw_ostream &OS, RecordKeeper &Records) {
3636
return std::move(E);
3737
}
3838

39-
if (Records.getClass("Operator") && Records.getClass("Query")) {
40-
auto SQLOperators = Records.getAllDerivedDefinitions("Operator");
39+
if (Records.getClass("Query")) {
4140
auto SQLQueries = Records.getAllDerivedDefinitions("Query");
42-
if (auto E = SQLQueryEmitter(OS).run(SQLQueries, SQLOperators))
41+
if (auto E = SQLQueryEmitter(OS).run(SQLQueries))
4342
return std::move(E);
4443
}
4544

SQLQueryEmitter.cpp

+137-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
#include "llvm/ADT/SmallSet.h"
12
#include "llvm/ADT/StringExtras.h"
23
#include "llvm/ADT/StringMap.h"
4+
#include "llvm/ADT/StringSwitch.h"
35
#include "Error.h"
46
#include "SQLQueryEmitter.h"
57

@@ -9,6 +11,46 @@ namespace {
911
class SQLWhereClauseEmitter {
1012
raw_ostream &OS;
1113

14+
enum OperatorKind {
15+
Unknown = 0,
16+
OPK_EQ,
17+
OPK_NE,
18+
OPK_GT,
19+
OPK_GE,
20+
OPK_LT,
21+
OPK_LE,
22+
OPK_AND,
23+
OPK_OR
24+
};
25+
26+
OperatorKind getOperator(const Init *DagOperator) {
27+
auto OpString = DagOperator->getAsString();
28+
return StringSwitch<OperatorKind>(OpString)
29+
.Case("eq", OPK_EQ)
30+
.Case("ne", OPK_NE)
31+
.Case("gt", OPK_GT)
32+
.Case("ge", OPK_GE)
33+
.Case("lt", OPK_LT)
34+
.Case("le", OPK_LE)
35+
.Case("and", OPK_AND)
36+
.Case("or", OPK_OR)
37+
.Default(Unknown);
38+
}
39+
40+
SmallVector<const Init *, 8> Nodes;
41+
void insertNode(unsigned Idx, const Init *Node) {
42+
if (Idx < Nodes.size())
43+
Nodes[Idx] = Node;
44+
else {
45+
Nodes.append(Idx - Nodes.size(), nullptr);
46+
Nodes.push_back(Node);
47+
}
48+
}
49+
50+
// Elements in this set are index of Nodes whose `Init`
51+
// instance needs to be printed as quoted string.
52+
SmallSet<unsigned, 2> AsQuotedString;
53+
1254
public:
1355
SQLWhereClauseEmitter(raw_ostream &OS) : OS(OS) {}
1456

@@ -17,12 +59,104 @@ class SQLWhereClauseEmitter {
1759
} // end anonymous namespace
1860

1961
Error SQLWhereClauseEmitter::run(const DagInit *WhereClause) {
20-
// TODO: Build an operator tree and visit it in an infix fashion.
62+
63+
// {The operand / operator Init, prospective index}
64+
SmallVector<std::pair<const Init *, unsigned>, 4> Worklist;
65+
66+
Worklist.push_back({WhereClause, 0U});
67+
68+
// First step, build the expression tree.
69+
const Init *Term;
70+
unsigned Idx;
71+
while (!Worklist.empty()) {
72+
std::tie(Term, Idx) = Worklist.pop_back_val();
73+
if (const auto *DagTerm = dyn_cast<DagInit>(Term)) {
74+
if (!getOperator(DagTerm->getOperator()))
75+
return createTGStringError(SMLoc(), "Unknown where clause operator");
76+
if (DagTerm->arg_size() != 2)
77+
return createTGStringError(SMLoc(), "Only binary operators are "
78+
"supported now");
79+
Term = DagTerm->getOperator();
80+
for (int i : {1, 0}) {
81+
// Also push the operands into the work list.
82+
Worklist.push_back({DagTerm->getArg(i), 2 * Idx + (i + 1)});
83+
if (const auto *Tag = DagTerm->getArgName(i)) {
84+
if (Tag->getValue() == "str")
85+
AsQuotedString.insert(2 * Idx + (i + 1));
86+
}
87+
}
88+
}
89+
insertNode(Idx, Term);
90+
}
91+
92+
assert(Nodes.size());
93+
94+
OS << "WHERE ";
95+
96+
// Then, visit the tree in an infix fashion.
97+
SmallVector<unsigned, 4> VisitStack;
98+
VisitStack.push_back(0U);
99+
100+
unsigned NumNodes = Nodes.size();
101+
while (!VisitStack.empty()) {
102+
unsigned Idx = VisitStack.back();
103+
unsigned LeftIdx = 2 * Idx + 1,
104+
RightIdx = 2 * Idx + 2;
105+
// Visit the left tree.
106+
if (LeftIdx < NumNodes && Nodes[LeftIdx]) {
107+
VisitStack.push_back(LeftIdx);
108+
continue;
109+
}
110+
111+
// Print the root.
112+
assert(Nodes[Idx]);
113+
if (auto OpK = getOperator(Nodes[Idx])) {
114+
switch (OpK) {
115+
case OPK_NE:
116+
OS << " <> ";
117+
break;
118+
case OPK_EQ:
119+
OS << " = ";
120+
break;
121+
case OPK_LE:
122+
OS << " <= ";
123+
break;
124+
case OPK_LT:
125+
OS << " < ";
126+
break;
127+
case OPK_GE:
128+
OS << " >= ";
129+
break;
130+
case OPK_GT:
131+
OS << " > ";
132+
break;
133+
case OPK_OR:
134+
OS << " OR ";
135+
break;
136+
case OPK_AND:
137+
OS << " AND ";
138+
break;
139+
default:
140+
llvm_unreachable("Unrecognized operator kind");
141+
}
142+
} else {
143+
if (AsQuotedString.count(Idx))
144+
OS << Nodes[Idx]->getAsString();
145+
else
146+
OS << Nodes[Idx]->getAsUnquotedString();
147+
}
148+
VisitStack.pop_back();
149+
Nodes[Idx] = nullptr;
150+
151+
// Visit the right tree.
152+
if (RightIdx < NumNodes && Nodes[RightIdx])
153+
VisitStack.push_back(RightIdx);
154+
}
155+
21156
return Error::success();
22157
}
23158

24-
Error SQLQueryEmitter::run(ArrayRef<const Record *> Queries,
25-
ArrayRef<const Record *> Operators) {
159+
Error SQLQueryEmitter::run(ArrayRef<const Record *> Queries) {
26160
// Map from the tag name to its corresponding SQL table field name.
27161
StringMap<StringRef> FieldTagMap;
28162

SQLQueryEmitter.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ class SQLQueryEmitter {
1313
explicit
1414
SQLQueryEmitter(raw_ostream &OS) : OS(OS) {}
1515

16-
Error run(ArrayRef<const Record *> Queries,
17-
ArrayRef<const Record *> Operators);
16+
Error run(ArrayRef<const Record *> Queries);
1817
};
1918
} // end namespace llvm
2019
#endif

0 commit comments

Comments
 (0)