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 {
911class 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+
1254public:
1355 SQLWhereClauseEmitter (raw_ostream &OS) : OS(OS) {}
1456
@@ -17,12 +59,104 @@ class SQLWhereClauseEmitter {
1759} // end anonymous namespace
1860
1961Error 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
0 commit comments