1 /* Copyright (C) 2014 InfiniDB, Inc.
2 
3    This program is free software; you can redistribute it and/or
4    modify it under the terms of the GNU General Public License
5    as published by the Free Software Foundation; version 2 of
6    the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16    MA 02110-1301, USA. */
17 
18 /***********************************************************************
19 *   $Id: simplefilter.cpp 9679 2013-07-11 22:32:03Z zzhu $
20 *
21 *
22 ***********************************************************************/
23 #include <exception>
24 #include <stdexcept>
25 #include <string>
26 #include <iostream>
27 #include <sstream>
28 using namespace std;
29 
30 #include "returnedcolumn.h"
31 #include "constantcolumn.h"
32 #include "simplecolumn.h"
33 #include "operator.h"
34 #include "constantfilter.h"
35 #include "bytestream.h"
36 #include "objectreader.h"
37 #include "functioncolumn.h"
38 #include "arithmeticcolumn.h"
39 #include "simplefilter.h"
40 #include "aggregatecolumn.h"
41 #include "windowfunctioncolumn.h"
42 
43 namespace execplan
44 {
45 
46 /**
47  * Constructors/Destructors
48  */
SimpleFilter()49 SimpleFilter::SimpleFilter():
50     fLhs(0),
51     fRhs(0),
52     fIndexFlag(NOINDEX),
53     fJoinFlag (EQUA)
54 {}
55 
56 // TODO: only handled simplecolumn operands for now
SimpleFilter(const string & sql)57 SimpleFilter::SimpleFilter(const string& sql):
58     Filter(sql)
59 {
60     parse(sql);
61 }
62 
SimpleFilter(const SOP & op,ReturnedColumn * lhs,ReturnedColumn * rhs,const string & timeZone)63 SimpleFilter::SimpleFilter(const SOP& op, ReturnedColumn* lhs, ReturnedColumn* rhs, const string& timeZone) :
64     fOp(op), fLhs(lhs), fRhs(rhs), fIndexFlag(NOINDEX), fJoinFlag(EQUA), fTimeZone(timeZone)
65 {
66     convertConstant();
67 }
68 
SimpleFilter(const SimpleFilter & rhs)69 SimpleFilter::SimpleFilter(const SimpleFilter& rhs) :
70     Filter(rhs),
71     fOp(rhs.op()),
72     fIndexFlag(rhs.indexFlag()),
73     fJoinFlag(rhs.joinFlag()),
74     fTimeZone(rhs.timeZone())
75 {
76     fLhs = rhs.lhs()->clone();
77     fRhs = rhs.rhs()->clone();
78 
79     fSimpleColumnList.clear();
80     fAggColumnList.clear();
81     fWindowFunctionColumnList.clear();
82 
83     SimpleColumn* lsc = dynamic_cast<SimpleColumn*>(fLhs);
84     FunctionColumn* lfc = dynamic_cast<FunctionColumn*>(fLhs);
85     ArithmeticColumn* lac = dynamic_cast<ArithmeticColumn*>(fLhs);
86     WindowFunctionColumn* laf = dynamic_cast<WindowFunctionColumn*>(fLhs);
87     AggregateColumn* lagc = dynamic_cast<AggregateColumn*>(fLhs);
88     SimpleColumn* rsc = dynamic_cast<SimpleColumn*>(fRhs);
89     FunctionColumn* rfc = dynamic_cast<FunctionColumn*>(fRhs);
90     ArithmeticColumn* rac = dynamic_cast<ArithmeticColumn*>(fRhs);
91     AggregateColumn* ragc = dynamic_cast<AggregateColumn*>(fRhs);
92     WindowFunctionColumn* raf = dynamic_cast<WindowFunctionColumn*>(fRhs);
93 
94     if (lsc)
95     {
96         fSimpleColumnList.push_back(lsc);
97     }
98     else if (lagc)
99     {
100         fAggColumnList.push_back(lagc);
101     }
102     else if (lfc)
103     {
104         fSimpleColumnList.insert(fSimpleColumnList.end(), lfc->simpleColumnList().begin(), lfc->simpleColumnList().end());
105         fAggColumnList.insert(fAggColumnList.end(), lfc->aggColumnList().begin(), lfc->aggColumnList().end());
106         fWindowFunctionColumnList.insert
107         (fWindowFunctionColumnList.end(), lfc->windowfunctionColumnList().begin(), lfc->windowfunctionColumnList().end());
108     }
109     else if (lac)
110     {
111         fSimpleColumnList.insert(fSimpleColumnList.end(), lac->simpleColumnList().begin(), lac->simpleColumnList().end());
112         fAggColumnList.insert(fAggColumnList.end(), lac->aggColumnList().begin(), lac->aggColumnList().end());
113         fWindowFunctionColumnList.insert
114         (fWindowFunctionColumnList.end(), lac->windowfunctionColumnList().begin(), lac->windowfunctionColumnList().end());
115     }
116     else if (laf)
117     {
118         fWindowFunctionColumnList.push_back(laf);
119     }
120 
121     if (rsc)
122     {
123         fSimpleColumnList.push_back(rsc);
124     }
125     else if (ragc)
126     {
127         fAggColumnList.push_back(ragc);
128     }
129     else if (rfc)
130     {
131         fSimpleColumnList.insert
132         (fSimpleColumnList.end(), rfc->simpleColumnList().begin(), rfc->simpleColumnList().end());
133         fAggColumnList.insert
134         (fAggColumnList.end(), rfc->aggColumnList().begin(), rfc->aggColumnList().end());
135         fWindowFunctionColumnList.insert
136         (fWindowFunctionColumnList.end(), rfc->windowfunctionColumnList().begin(), rfc->windowfunctionColumnList().end());
137     }
138     else if (rac)
139     {
140         fSimpleColumnList.insert(fSimpleColumnList.end(), rac->simpleColumnList().begin(), rac->simpleColumnList().end());
141         fAggColumnList.insert(fAggColumnList.end(), rac->aggColumnList().begin(), rac->aggColumnList().end());
142         fWindowFunctionColumnList.insert
143         (fWindowFunctionColumnList.end(), rac->windowfunctionColumnList().begin(), rac->windowfunctionColumnList().end());
144     }
145     else if (raf)
146     {
147         fWindowFunctionColumnList.push_back(raf);
148     }
149 }
150 
~SimpleFilter()151 SimpleFilter::~SimpleFilter()
152 {
153     //delete fOp;
154     if (fLhs != NULL)
155         delete fLhs;
156 
157     if (fRhs != NULL)
158         delete fRhs;
159 
160     fLhs = NULL;
161     fRhs = NULL;
162 }
163 
164 /**
165  * Methods
166  */
167 
lhs(ReturnedColumn * lhs)168 void SimpleFilter::lhs(ReturnedColumn* lhs)
169 {
170     fLhs = lhs;
171 
172     if (fLhs && fRhs)
173         convertConstant();
174 }
175 
rhs(ReturnedColumn * rhs)176 void SimpleFilter::rhs(ReturnedColumn* rhs)
177 {
178     fRhs = rhs;
179 
180     if (fLhs && fRhs)
181         convertConstant();
182 }
183 
escapeString(const std::string & input)184 std::string SimpleFilter::escapeString(const std::string& input)
185 {
186     std::ostringstream ss;
187 
188     for (std::string::const_iterator iter = input.begin(); iter != input.end(); iter++)
189     {
190         switch (*iter)
191         {
192             case '\\':
193                 ss << "\\\\";
194                 break;
195 
196             case '\'':
197                 ss << "\\'";
198                 break;
199 
200             default:
201                 ss << *iter;
202                 break;
203         }
204     }
205 
206     return ss.str();
207 }
208 
data() const209 const string SimpleFilter::data() const
210 {
211     string rhs, lhs;
212 
213     if (dynamic_cast<ConstantColumn*>(fRhs) &&
214             (fRhs->resultType().colDataType == CalpontSystemCatalog::VARCHAR ||
215              fRhs->resultType().colDataType == CalpontSystemCatalog::CHAR ||
216              fRhs->resultType().colDataType == CalpontSystemCatalog::BLOB ||
217              fRhs->resultType().colDataType == CalpontSystemCatalog::TEXT ||
218              fRhs->resultType().colDataType == CalpontSystemCatalog::VARBINARY ||
219              fRhs->resultType().colDataType == CalpontSystemCatalog::DATE ||
220              fRhs->resultType().colDataType == CalpontSystemCatalog::DATETIME ||
221              fRhs->resultType().colDataType == CalpontSystemCatalog::TIMESTAMP ||
222              fRhs->resultType().colDataType == CalpontSystemCatalog::TIME))
223         rhs = "'" + SimpleFilter::escapeString(fRhs->data()) + "'";
224     else
225         rhs = fRhs->data();
226 
227     if (dynamic_cast<ConstantColumn*>(fLhs) &&
228             (fLhs->resultType().colDataType == CalpontSystemCatalog::VARCHAR ||
229              fLhs->resultType().colDataType == CalpontSystemCatalog::CHAR ||
230              fLhs->resultType().colDataType == CalpontSystemCatalog::BLOB ||
231              fLhs->resultType().colDataType == CalpontSystemCatalog::TEXT ||
232              fLhs->resultType().colDataType == CalpontSystemCatalog::VARBINARY ||
233              fLhs->resultType().colDataType == CalpontSystemCatalog::DATE ||
234              fLhs->resultType().colDataType == CalpontSystemCatalog::TIME ||
235              fLhs->resultType().colDataType == CalpontSystemCatalog::TIMESTAMP ||
236              fLhs->resultType().colDataType == CalpontSystemCatalog::DATETIME))
237         lhs = "'" + SimpleFilter::escapeString(fLhs->data()) + "'";
238     else
239         lhs = fLhs->data();
240 
241     return lhs + " " + fOp->data() + " " + rhs;
242 }
243 
toString() const244 const string SimpleFilter::toString() const
245 {
246     ostringstream output;
247     output << "SimpleFilter(indexflag=" << fIndexFlag;
248     output << " joinFlag= " << fJoinFlag;
249     output << " card= " << fCardinality << ")" << endl;
250     output << "  " << *fLhs;
251     output << "  " << *fOp;
252     output << "  " << *fRhs;
253     return output.str();
254 }
255 
parse(string sql)256 void SimpleFilter::parse(string sql)
257 {
258     fLhs = 0;
259     fRhs = 0;
260     string delimiter[7] = {">=", "<=", "<>", "!=", "=", "<", ">"};
261     string::size_type pos;
262 
263     for (int i = 0; i < 7; i++)
264     {
265         pos = sql.find(delimiter[i], 0);
266 
267         if (pos == string::npos)
268             continue;
269 
270         fOp.reset(new Operator (delimiter[i]));
271         string lhs = sql.substr(0, pos);
272 
273         if (lhs.at(0) == ' ')
274             lhs = lhs.substr(1, pos);
275 
276         if (lhs.at(lhs.length() - 1) == ' ')
277             lhs = lhs.substr(0, pos - 1);
278 
279         fLhs = new SimpleColumn(lhs);
280 
281         pos = pos + delimiter[i].length();
282         string rhs = sql.substr(pos, sql.length());
283 
284         if (rhs.at(0) == ' ')
285             rhs = rhs.substr(1, pos);
286 
287         if (rhs.at(rhs.length() - 1) == ' ')
288             rhs = rhs.substr(0, pos - 1);
289 
290         fRhs = new SimpleColumn (rhs);
291         break;
292     }
293 
294     if (fLhs == NULL || fRhs == NULL)
295         throw runtime_error ("invalid sql for simple filter\n" );
296 }
297 
operator <<(ostream & output,const SimpleFilter & rhs)298 ostream& operator<<(ostream& output, const SimpleFilter& rhs)
299 {
300     output << rhs.toString();
301     return output;
302 }
303 
serialize(messageqcpp::ByteStream & b) const304 void SimpleFilter::serialize(messageqcpp::ByteStream& b) const
305 {
306     b << static_cast<ObjectReader::id_t>(ObjectReader::SIMPLEFILTER);
307     Filter::serialize(b);
308 
309     if (fOp != NULL)
310         fOp->serialize(b);
311     else
312         b << static_cast<ObjectReader::id_t>(ObjectReader::NULL_CLASS);
313 
314     if (fLhs != NULL)
315         fLhs->serialize(b);
316     else
317         b << static_cast<ObjectReader::id_t>(ObjectReader::NULL_CLASS);
318 
319     if (fRhs != NULL)
320         fRhs->serialize(b);
321     else
322         b << static_cast<ObjectReader::id_t>(ObjectReader::NULL_CLASS);
323 
324     b << static_cast<uint32_t>(fIndexFlag);
325     b << static_cast<uint32_t>(fJoinFlag);
326     b << fTimeZone;
327 }
328 
unserialize(messageqcpp::ByteStream & b)329 void SimpleFilter::unserialize(messageqcpp::ByteStream& b)
330 {
331     ObjectReader::checkType(b, ObjectReader::SIMPLEFILTER);
332 
333     //delete fOp;
334     delete fLhs;
335     delete fRhs;
336     Filter::unserialize(b);
337     fOp.reset(dynamic_cast<Operator*>(ObjectReader::createTreeNode(b)));
338     fLhs = dynamic_cast<ReturnedColumn*>(ObjectReader::createTreeNode(b));
339     fRhs = dynamic_cast<ReturnedColumn*>(ObjectReader::createTreeNode(b));
340     b >> reinterpret_cast<uint32_t&>(fIndexFlag);
341     b >> reinterpret_cast<uint32_t&>(fJoinFlag);
342     b >> fTimeZone;
343 
344     fSimpleColumnList.clear();
345     fAggColumnList.clear();
346     fWindowFunctionColumnList.clear();
347 
348     SimpleColumn* lsc = dynamic_cast<SimpleColumn*>(fLhs);
349     FunctionColumn* lfc = dynamic_cast<FunctionColumn*>(fLhs);
350     ArithmeticColumn* lac = dynamic_cast<ArithmeticColumn*>(fLhs);
351     WindowFunctionColumn* laf = dynamic_cast<WindowFunctionColumn*>(fLhs);
352     AggregateColumn* lagc = dynamic_cast<AggregateColumn*>(fLhs);
353     SimpleColumn* rsc = dynamic_cast<SimpleColumn*>(fRhs);
354     FunctionColumn* rfc = dynamic_cast<FunctionColumn*>(fRhs);
355     ArithmeticColumn* rac = dynamic_cast<ArithmeticColumn*>(fRhs);
356     AggregateColumn* ragc = dynamic_cast<AggregateColumn*>(fRhs);
357     WindowFunctionColumn* raf = dynamic_cast<WindowFunctionColumn*>(fRhs);
358 
359     if (lsc)
360     {
361         fSimpleColumnList.push_back(lsc);
362     }
363     else if (lagc)
364     {
365         fAggColumnList.push_back(lagc);
366     }
367     else if (lfc)
368     {
369         lfc->setSimpleColumnList();
370         fSimpleColumnList.insert(fSimpleColumnList.end(), lfc->simpleColumnList().begin(), lfc->simpleColumnList().end());
371         fAggColumnList.insert(fAggColumnList.end(), lfc->aggColumnList().begin(), lfc->aggColumnList().end());
372         fWindowFunctionColumnList.insert
373         (fWindowFunctionColumnList.end(), lfc->windowfunctionColumnList().begin(), lfc->windowfunctionColumnList().end());
374     }
375     else if (lac)
376     {
377         lac->setSimpleColumnList();
378         fSimpleColumnList.insert(fSimpleColumnList.end(), lac->simpleColumnList().begin(), lac->simpleColumnList().end());
379         fAggColumnList.insert(fAggColumnList.end(), lac->aggColumnList().begin(), lac->aggColumnList().end());
380         fWindowFunctionColumnList.insert
381         (fWindowFunctionColumnList.end(), lac->windowfunctionColumnList().begin(), lac->windowfunctionColumnList().end());
382     }
383     else if (laf)
384     {
385         fWindowFunctionColumnList.push_back(laf);
386     }
387 
388     if (rsc)
389     {
390         fSimpleColumnList.push_back(rsc);
391     }
392     else if (ragc)
393     {
394         fAggColumnList.push_back(ragc);
395     }
396     else if (rfc)
397     {
398         rfc->setSimpleColumnList();
399         fSimpleColumnList.insert
400         (fSimpleColumnList.end(), rfc->simpleColumnList().begin(), rfc->simpleColumnList().end());
401         fAggColumnList.insert
402         (fAggColumnList.end(), rfc->aggColumnList().begin(), rfc->aggColumnList().end());
403         fWindowFunctionColumnList.insert
404         (fWindowFunctionColumnList.end(), rfc->windowfunctionColumnList().begin(), rfc->windowfunctionColumnList().end());
405     }
406     else if (rac)
407     {
408         rac->setSimpleColumnList();
409         fSimpleColumnList.insert(fSimpleColumnList.end(), rac->simpleColumnList().begin(), rac->simpleColumnList().end());
410         fAggColumnList.insert(fAggColumnList.end(), rac->aggColumnList().begin(), rac->aggColumnList().end());
411         fWindowFunctionColumnList.insert
412         (fWindowFunctionColumnList.end(), rac->windowfunctionColumnList().begin(), rac->windowfunctionColumnList().end());
413     }
414     else if (raf)
415     {
416         fWindowFunctionColumnList.push_back(raf);
417     }
418 
419 }
420 
operator ==(const SimpleFilter & t) const421 bool SimpleFilter::operator==(const SimpleFilter& t) const
422 {
423     const Filter* f1, *f2;
424 
425     f1 = static_cast<const Filter*>(this);
426     f2 = static_cast<const Filter*>(&t);
427 
428     if (*f1 != *f2)
429         return false;
430 
431     if (fOp != NULL)
432     {
433         if (*fOp != *t.fOp)
434             return false;
435     }
436     else if (t.fOp != NULL)
437         return false;
438 
439     if (fLhs != NULL)
440     {
441         if (*fLhs != t.fLhs)
442             return false;
443     }
444     else if (t.fLhs != NULL)
445         return false;
446 
447     if (fRhs != NULL)
448     {
449         if (*fRhs != t.fRhs)
450             return false;
451     }
452     else if (t.fRhs != NULL)
453         return false;
454 
455     else if (fIndexFlag != t.fIndexFlag)
456         return false;
457 
458     else if (fJoinFlag != t.fJoinFlag)
459         return false;
460 
461     else if (fTimeZone != t.fTimeZone)
462         return false;
463 
464     return true;
465 }
466 
semanticEq(const SimpleFilter & t) const467 bool SimpleFilter::semanticEq(const SimpleFilter& t) const
468 {
469     if (fOp != NULL)
470     {
471         if (*fOp != *t.fOp)
472             return false;
473     }
474     if (fLhs != NULL)
475     {
476         if (*fLhs != t.fLhs && *fLhs != *t.fRhs)
477             return false;
478     }
479     if (fRhs != NULL)
480     {
481         if (*fRhs != t.fRhs && *fRhs != *t.fLhs)
482             return false;
483     }
484 
485     return true;
486 }
487 
operator ==(const TreeNode * t) const488 bool SimpleFilter::operator==(const TreeNode* t) const
489 {
490     const SimpleFilter* o;
491 
492     o = dynamic_cast<const SimpleFilter*>(t);
493 
494     if (o == NULL)
495         return false;
496 
497     return *this == *o;
498 }
499 
operator !=(const SimpleFilter & t) const500 bool SimpleFilter::operator!=(const SimpleFilter& t) const
501 {
502     return (!(*this == t));
503 }
504 
operator !=(const TreeNode * t) const505 bool SimpleFilter::operator!=(const TreeNode* t) const
506 {
507     return (!(*this == t));
508 }
509 
pureFilter()510 bool SimpleFilter::pureFilter()
511 {
512     if (typeid (*fLhs) == typeid(ConstantColumn) &&
513             typeid (*fRhs) != typeid(ConstantColumn))
514     {
515         // make sure constantCol sit on right hand side
516         ReturnedColumn* temp = fLhs;
517         fLhs = fRhs;
518         fRhs = temp;
519 
520         // also switch indexFlag
521         if (fIndexFlag == SimpleFilter::LEFT) fIndexFlag = SimpleFilter::RIGHT;
522         else if (fIndexFlag == SimpleFilter::RIGHT) fIndexFlag = SimpleFilter::LEFT;
523 
524         return true;
525     }
526 
527     if (typeid (*fRhs) == typeid(ConstantColumn) &&
528             typeid (*fLhs) != typeid(ConstantColumn))
529         return true;
530 
531     return false;
532 }
533 
convertConstant()534 void SimpleFilter::convertConstant()
535 {
536     if (fOp->op() == OP_ISNULL || fOp->op() == OP_ISNOTNULL)
537         return;
538 
539     ConstantColumn* lcc = dynamic_cast<ConstantColumn*>(fLhs);
540     ConstantColumn* rcc = dynamic_cast<ConstantColumn*>(fRhs);
541 
542     if (lcc)
543     {
544         Result result = lcc->result();
545 
546         if (fRhs->resultType().colDataType == CalpontSystemCatalog::DATE)
547         {
548             if (lcc->constval().empty())
549             {
550                 lcc->constval("0000-00-00");
551                 result.intVal = 0;
552                 result.strVal = lcc->constval();
553             }
554             else
555             {
556                 result.intVal = dataconvert::DataConvert::dateToInt(result.strVal);
557             }
558         }
559         else if (fRhs->resultType().colDataType == CalpontSystemCatalog::DATETIME)
560         {
561             if (lcc->constval().empty())
562             {
563                 lcc->constval("0000-00-00 00:00:00");
564                 result.intVal = 0;
565                 result.strVal = lcc->constval();
566             }
567             else
568             {
569                 result.intVal = dataconvert::DataConvert::datetimeToInt(result.strVal);
570             }
571         }
572         else if (fRhs->resultType().colDataType == CalpontSystemCatalog::TIMESTAMP)
573         {
574             if (lcc->constval().empty())
575             {
576                 lcc->constval("0000-00-00 00:00:00");
577                 result.intVal = 0;
578                 result.strVal = lcc->constval();
579             }
580             else
581             {
582                 result.intVal = dataconvert::DataConvert::timestampToInt(result.strVal, fTimeZone);
583             }
584         }
585         else if (fRhs->resultType().colDataType == CalpontSystemCatalog::TIME)
586         {
587             if (lcc->constval().empty())
588             {
589                 lcc->constval("00:00:00");
590                 result.intVal = 0;
591                 result.strVal = lcc->constval();
592             }
593             else
594             {
595                 result.intVal = dataconvert::DataConvert::timeToInt(result.strVal);
596             }
597         }
598 
599         lcc->result(result);
600     }
601 
602     if (rcc)
603     {
604         Result result = rcc->result();
605 
606         if (fLhs->resultType().colDataType == CalpontSystemCatalog::DATE)
607         {
608             if (rcc->constval().empty())
609             {
610                 rcc->constval("0000-00-00");
611                 result.intVal = 0;
612                 result.strVal = rcc->constval();
613             }
614             else
615             {
616                 result.intVal = dataconvert::DataConvert::dateToInt(result.strVal);
617             }
618         }
619         else if (fLhs->resultType().colDataType == CalpontSystemCatalog::DATETIME)
620         {
621             if (rcc->constval().empty())
622             {
623                 rcc->constval("0000-00-00 00:00:00");
624                 result.intVal = 0;
625                 result.strVal = rcc->constval();
626             }
627             else
628             {
629                 result.intVal = dataconvert::DataConvert::datetimeToInt(result.strVal);
630             }
631         }
632         else if (fLhs->resultType().colDataType == CalpontSystemCatalog::TIMESTAMP)
633         {
634             if (rcc->constval().empty())
635             {
636                 rcc->constval("0000-00-00 00:00:00");
637                 result.intVal = 0;
638                 result.strVal = rcc->constval();
639             }
640             else
641             {
642                 result.intVal = dataconvert::DataConvert::timestampToInt(result.strVal, fTimeZone);
643             }
644         }
645         else if (fLhs->resultType().colDataType == CalpontSystemCatalog::TIME)
646         {
647             if (rcc->constval().empty())
648             {
649                 rcc->constval("00:00:00");
650                 result.intVal = 0;
651                 result.strVal = rcc->constval();
652             }
653             else
654             {
655                 result.intVal = dataconvert::DataConvert::timeToInt(result.strVal);
656             }
657         }
658 
659         rcc->result(result);
660     }
661 }
662 
setDerivedTable()663 void SimpleFilter::setDerivedTable()
664 {
665     string lDerivedTable = "";
666     string rDerivedTable = "";
667 
668     if (hasAggregate())
669         return;
670 
671     if (fLhs)
672     {
673         fLhs->setDerivedTable();
674         lDerivedTable = fLhs->derivedTable();
675     }
676     else
677     {
678         lDerivedTable = "*";
679     }
680 
681     if (fRhs)
682     {
683         fRhs->setDerivedTable();
684         rDerivedTable = fRhs->derivedTable();
685     }
686     else
687     {
688         rDerivedTable = "*";
689     }
690 
691     if (lDerivedTable == "*")
692     {
693         fDerivedTable = rDerivedTable;
694     }
695     else if (rDerivedTable == "*")
696     {
697         fDerivedTable = lDerivedTable;
698     }
699     else if (lDerivedTable == rDerivedTable)
700     {
701         fDerivedTable = lDerivedTable; // should be the same as rhs
702     }
703     else
704     {
705         fDerivedTable = "";
706     }
707 }
708 
replaceRealCol(CalpontSelectExecutionPlan::ReturnedColumnList & derivedColList)709 void SimpleFilter::replaceRealCol(CalpontSelectExecutionPlan::ReturnedColumnList& derivedColList)
710 {
711     SimpleColumn* sc = NULL;
712 
713     if (fLhs)
714     {
715         sc = dynamic_cast<SimpleColumn*>(fLhs);
716 
717         if (sc)
718         {
719             ReturnedColumn* tmp = derivedColList[sc->colPosition()]->clone();
720             delete fLhs;
721             fLhs = tmp;
722         }
723         else
724         {
725             fLhs->replaceRealCol(derivedColList);
726         }
727     }
728 
729     if (fRhs)
730     {
731         sc = dynamic_cast<SimpleColumn*>(fRhs);
732 
733         if (sc)
734         {
735             ReturnedColumn* tmp = derivedColList[sc->colPosition()]->clone();
736             delete fRhs;
737             fRhs = tmp;
738         }
739         else
740         {
741             fRhs->replaceRealCol(derivedColList);
742         }
743     }
744 }
745 
simpleColumnList()746 const std::vector<SimpleColumn*>& SimpleFilter::simpleColumnList()
747 {
748     return fSimpleColumnList;
749 }
750 
setSimpleColumnList()751 void SimpleFilter::setSimpleColumnList()
752 {
753     SimpleColumn* lsc = dynamic_cast<SimpleColumn*>(fLhs);
754     SimpleColumn* rsc = dynamic_cast<SimpleColumn*>(fRhs);
755     fSimpleColumnList.clear();
756 
757     if (lsc)
758     {
759         fSimpleColumnList.push_back(lsc);
760     }
761     else if (fLhs)
762     {
763         fLhs->setSimpleColumnList();
764         fSimpleColumnList.insert
765         (fSimpleColumnList.end(), fLhs->simpleColumnList().begin(), fLhs->simpleColumnList().end());
766     }
767 
768     if (rsc)
769     {
770         fSimpleColumnList.push_back(rsc);
771     }
772     else if (fRhs)
773     {
774         fRhs->setSimpleColumnList();
775         fSimpleColumnList.insert
776         (fSimpleColumnList.end(), fRhs->simpleColumnList().begin(), fRhs->simpleColumnList().end());
777     }
778 }
779 
hasAggregate()780 bool SimpleFilter::hasAggregate()
781 {
782     if (fAggColumnList.empty())
783     {
784         AggregateColumn* lac = dynamic_cast<AggregateColumn*>(fLhs);
785         AggregateColumn* rac = dynamic_cast<AggregateColumn*>(fRhs);
786         fAggColumnList.clear();
787 
788         if (lac)
789         {
790             fAggColumnList.insert(fAggColumnList.end(), lac);
791         }
792 
793         if (rac)
794         {
795             fAggColumnList.insert(fAggColumnList.end(), rac);
796         }
797 
798         if (fLhs)
799         {
800             if (fLhs->hasAggregate())
801                 fAggColumnList.insert(fAggColumnList.end(),
802                                       fLhs->aggColumnList().begin(),
803                                       fLhs->aggColumnList().end());
804         }
805 
806         if (fRhs)
807         {
808             if (fRhs->hasAggregate())
809                 fAggColumnList.insert(fAggColumnList.end(),
810                                       fRhs->aggColumnList().begin(),
811                                       fRhs->aggColumnList().end());
812         }
813     }
814 
815     if (!fAggColumnList.empty())
816     {
817         return true;
818     }
819 
820     return false;
821 }
822 
823 
824 } // namespace execplan
825