1
+ #include " llvm/ADT/SmallSet.h"
1
2
#include " llvm/ADT/StringExtras.h"
2
3
#include " llvm/ADT/StringMap.h"
4
+ #include " llvm/ADT/StringSwitch.h"
3
5
#include " Error.h"
4
6
#include " SQLQueryEmitter.h"
5
7
@@ -9,6 +11,46 @@ namespace {
9
11
class SQLWhereClauseEmitter {
10
12
raw_ostream &OS;
11
13
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
+
12
54
public:
13
55
SQLWhereClauseEmitter (raw_ostream &OS) : OS(OS) {}
14
56
@@ -17,12 +59,104 @@ class SQLWhereClauseEmitter {
17
59
} // end anonymous namespace
18
60
19
61
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
+
21
156
return Error::success ();
22
157
}
23
158
24
- Error SQLQueryEmitter::run (ArrayRef<const Record *> Queries,
25
- ArrayRef<const Record *> Operators) {
159
+ Error SQLQueryEmitter::run (ArrayRef<const Record *> Queries) {
26
160
// Map from the tag name to its corresponding SQL table field name.
27
161
StringMap<StringRef> FieldTagMap;
28
162
0 commit comments