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