1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // CegoQueryHelper.cc
4 // ------------------
5 // Cego query helper implementation
6 //
7 // Design and Implementation by Bjoern Lemke
8 //
9 // (C)opyright 2000-2019 Bjoern Lemke
10 //
11 // IMPLEMENTATION MODULE
12 //
13 // Class: CegoQueryHelper
14 //
15 // Description: The CegoQueryHelper class provides several utility methods with are used for tuple retrieval and evalution
16 //
17 // Status: CLEAN
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20
21 // base includes
22 #include <lfcbase/BigDecimal.h>
23 #include <lfcbase/Datetime.h>
24
25 // cego includes
26 #include "CegoQueryHelper.h"
27 #include "CegoXMLdef.h"
28 #include "CegoSelect.h"
29 #include "CegoTypeConverter.h"
30
31 #include <string.h>
32 #include <stdlib.h>
33
CegoQueryHelper()34 CegoQueryHelper::CegoQueryHelper()
35 {
36 }
37
~CegoQueryHelper()38 CegoQueryHelper::~CegoQueryHelper()
39 {
40 }
41
evalPredicate(ListT<CegoField> ** pParentJoinBuf,int parentJoinBufPos,ListT<CegoField> ** pJoinBuf,int pos,CegoPredDesc * pP,CegoProcBlock * pBlock)42 bool CegoQueryHelper::evalPredicate(ListT<CegoField>** pParentJoinBuf,
43 int parentJoinBufPos,
44 ListT<CegoField>** pJoinBuf,
45 int pos,
46 CegoPredDesc* pP,
47 CegoProcBlock *pBlock)
48 {
49 if (pP == 0)
50 return true;
51
52 // cout << "Eval prediacte " << pP->toChain("") << endl;
53
54 CegoCondDesc* pC = pP->getCondition();
55 if (pC)
56 {
57 switch ( pC->getCondType() )
58 {
59 case CegoCondDesc::AND:
60 return ( evalPredicate(pParentJoinBuf,
61 parentJoinBufPos,
62 pJoinBuf,
63 pos,
64 pC->Left(),
65 pBlock)
66 && evalPredicate(pParentJoinBuf,
67 parentJoinBufPos,
68 pJoinBuf,
69 pos,
70 pC->Right(),
71 pBlock));
72 case CegoCondDesc::OR:
73 return ( evalPredicate(pParentJoinBuf,
74 parentJoinBufPos,
75 pJoinBuf,
76 pos,
77 pC->Left(),
78 pBlock)
79 || evalPredicate(pParentJoinBuf,
80 parentJoinBufPos,
81 pJoinBuf,
82 pos,
83 pC->Right(),
84 pBlock));
85 case CegoCondDesc::PRED:
86 break;
87 }
88 }
89 else
90 {
91 if ( pP->getMode() == CegoPredDesc::NOTPRED )
92 {
93 bool np = evalPredicate(pParentJoinBuf,
94 parentJoinBufPos,
95 pJoinBuf,
96 pos,
97 pP->getNotPred(),
98 pBlock);
99 if ( np )
100 {
101 return false;
102 }
103 return true;
104 }
105 else
106 {
107 ListT<CegoField>** flArray = 0;
108 ListT<CegoField>* flStaticArray[TABMNG_MAXJOINLEVEL];
109
110 if ( pParentJoinBuf )
111 {
112 flArray = flStaticArray;
113
114 int flpos=0;
115 int i=parentJoinBufPos;
116 while ( pParentJoinBuf[i] )
117 {
118 if ( flpos > TABMNG_MAXJOINLEVEL )
119 {
120 Chain msg = Chain("Join buffer exceeded");
121 throw Exception(EXLOC, msg);
122 }
123
124 flArray[flpos] = pParentJoinBuf[i];
125 i++;
126 flpos++;
127 }
128 i=pos;
129 while ( pJoinBuf[i] )
130 {
131 if ( flpos > TABMNG_MAXJOINLEVEL )
132 {
133 Chain msg = Chain("Join buffer exceeded");
134 throw Exception(EXLOC, msg);
135 }
136
137 flArray[flpos] = pJoinBuf[i];
138 i++;
139 flpos++;
140 }
141 // terminate array
142 flArray[flpos]=0;
143 }
144 else if ( pJoinBuf )
145 {
146 flArray = pJoinBuf + pos;
147 }
148
149 bool retVal = false;
150
151 switch ( pP->getMode() )
152 {
153 case CegoPredDesc::EXPRCOMP:
154 {
155 if ( flArray )
156 {
157 pP->getExpr1()->setFieldListArray(flArray);
158 pP->getExpr2()->setFieldListArray(flArray);
159 }
160 pP->getExpr1()->setBlock(pBlock);
161 pP->getExpr2()->setBlock(pBlock);
162
163 // cout << "Eval : " << pP->getExpr1()->evalFieldValue() << " comp " << pP->getExpr2()->evalFieldValue() << endl;
164
165 retVal = evalFields(pP->getComparison(), pP->getExpr1()->evalFieldValue(), pP->getExpr2()->evalFieldValue());
166
167 // we have to reset field list array, other wise we can have invalid references which might lead to seg faults
168 if ( flArray )
169 {
170 flArray = 0;
171 pP->getExpr1()->setFieldListArray(flArray);
172 pP->getExpr2()->setFieldListArray(flArray);
173 }
174 pP->getExpr1()->setBlock(0);
175 pP->getExpr2()->setBlock(0);
176 break;
177 }
178 case CegoPredDesc::BETWEEN:
179 {
180 if ( flArray )
181 {
182 pP->getExpr1()->setFieldListArray(flArray);
183 pP->getExpr2()->setFieldListArray(flArray);
184 pP->getExpr3()->setFieldListArray(flArray);
185 }
186
187 pP->getExpr1()->setBlock(pBlock);
188 pP->getExpr2()->setBlock(pBlock);
189 pP->getExpr3()->setBlock(pBlock);
190
191 // cout << " Eval " << pP->getExpr1()->evalFieldValue() << " is btwn " << pP->getExpr2()->evalFieldValue() << " and " << pP->getExpr3()->evalFieldValue() << endl;
192
193 retVal = evalBetween(pP->getExpr1()->evalFieldValue(), pP->getExpr2()->evalFieldValue(), pP->getExpr3()->evalFieldValue());
194
195 // we have to reset field list array, other wise we can have invalid references which might lead to seg faults
196 if ( flArray )
197 {
198 flArray = 0;
199 pP->getExpr1()->setFieldListArray(flArray);
200 pP->getExpr2()->setFieldListArray(flArray);
201 pP->getExpr3()->setFieldListArray(flArray);
202 }
203
204 pP->getExpr1()->setBlock(0);
205 pP->getExpr2()->setBlock(0);
206 pP->getExpr3()->setBlock(0);
207
208 break;
209 }
210 case CegoPredDesc::NULLCOMP:
211 {
212 if ( flArray )
213 {
214 pP->getExpr1()->setFieldListArray(flArray);
215 }
216
217 pP->getExpr1()->setBlock(pBlock);
218
219 if ( pP->getExpr1()->evalFieldValue().isNull() )
220 {
221 retVal = true;
222 }
223 else
224 {
225 retVal = false;
226 }
227
228 if ( flArray )
229 {
230 flArray=0;
231 pP->getExpr1()->setFieldListArray(flArray);
232 }
233 pP->getExpr1()->setBlock(0);
234 break;
235 }
236 case CegoPredDesc::NOTNULLCOMP:
237 {
238 if ( flArray )
239 {
240 pP->getExpr1()->setFieldListArray(flArray);
241 }
242 pP->getExpr1()->setBlock(pBlock);
243
244 if ( pP->getExpr1()->evalFieldValue().isNull() )
245 {
246 retVal = false;
247 }
248 else
249 {
250 retVal = true;
251 }
252
253 if ( flArray )
254 {
255 flArray=0;
256 pP->getExpr1()->setFieldListArray(flArray);
257 }
258 pP->getExpr1()->setBlock(0);
259
260 break;
261 }
262 case CegoPredDesc::EXISTSCOMP:
263 {
264 CegoSelect* pSelect = pP->getSelectQuery();
265
266 pSelect->reset(false);
267 if ( flArray )
268 {
269 pSelect->setParentJoinBuf(flArray);
270 }
271 pSelect->setProcBlock(pBlock);
272
273 ListT<CegoField> fl;
274
275 if ( pSelect->nextTuple(fl) )
276 {
277 retVal= true;
278 }
279 else
280 {
281 retVal = false;
282 }
283
284 if ( flArray )
285 {
286 flArray=0;
287 }
288 pSelect->setProcBlock(0);
289 pSelect->setParentJoinBuf();
290 pSelect->reset(false);
291 break;
292 }
293 case CegoPredDesc::ISLIKE:
294 case CegoPredDesc::ISNOTLIKE:
295 {
296 if ( flArray )
297 {
298 pP->getExpr1()->setFieldListArray(flArray);
299 }
300 pP->getExpr1()->setBlock(pBlock);
301
302 if ( pP->getMode() == CegoPredDesc::ISLIKE )
303 retVal = pP->match(pP->getExpr1()->evalFieldValue());
304 else
305 retVal = ! pP->match(pP->getExpr1()->evalFieldValue());
306
307 if ( flArray )
308 {
309 flArray=0;
310 pP->getExpr1()->setFieldListArray(flArray);
311 }
312 pP->getExpr1()->setBlock(0);
313
314 break;
315 }
316 case CegoPredDesc::IN:
317 case CegoPredDesc::NOTIN:
318 {
319 if ( flArray )
320 {
321 pP->getExpr1()->setFieldListArray(flArray);
322 }
323 pP->getExpr1()->setBlock(pBlock);
324
325 ListT<CegoExpr*> exprList = pP->getExprList();
326 CegoExpr **pExpr = exprList.First();
327
328 bool matchFound = false;
329 while ( pExpr && matchFound == false )
330 {
331 if ( flArray )
332 {
333 (*pExpr)->setFieldListArray(flArray);
334 }
335 (*pExpr)->setBlock(pBlock);
336
337 if ( pP->getExpr1()->evalFieldValue() == (*pExpr)->evalFieldValue() )
338 {
339 matchFound = true;
340 }
341
342 pExpr = exprList.Next();
343 }
344
345 if ( pP->getMode() == CegoPredDesc::IN )
346 retVal = matchFound;
347 else
348 retVal = ! matchFound;
349
350 // reset
351 if ( flArray )
352 {
353 flArray=0;
354 pP->getExpr1()->setFieldListArray(flArray);
355 }
356 pP->getExpr1()->setBlock(0);
357
358 pExpr = exprList.First();
359 while ( pExpr )
360 {
361 (*pExpr)->setFieldListArray(flArray);
362 (*pExpr)->setBlock(0);
363 pExpr = exprList.Next();
364 }
365
366 break;
367 }
368 case CegoPredDesc::INSUB:
369 case CegoPredDesc::NOTINSUB:
370 {
371 if ( flArray )
372 {
373 pP->getExpr1()->setFieldListArray(flArray);
374 }
375 pP->getExpr1()->setBlock(pBlock);
376
377 CegoSelect* pSelect = pP->getSelectQuery();
378
379 pSelect->reset(false);
380
381 if ( flArray )
382 {
383 pSelect->setParentJoinBuf(flArray);
384 }
385 pSelect->setProcBlock(pBlock);
386
387 ListT<CegoField> fl;
388
389 if ( pP->getMode() == CegoPredDesc::INSUB )
390 {
391 retVal = false;
392 while ( pSelect->nextTuple(fl) && retVal == false )
393 {
394 CegoField *pSF = fl.First();
395
396 if ( (CegoFieldValue)pSF->getValue() == (CegoFieldValue)pP->getExpr1()->evalFieldValue() )
397 retVal = true;
398 }
399 }
400 else
401 {
402 retVal = true;
403 while ( pSelect->nextTuple(fl) && retVal == true )
404 {
405 CegoField *pSF = fl.First();
406 if ( (CegoFieldValue)pSF->getValue() == (CegoFieldValue)pP->getExpr1()->evalFieldValue() )
407 retVal = false;
408 }
409 }
410
411 // in case of caching, we have to read to the end to fill up cache
412 if ( pSelect->isCacheEnabled() == true && pSelect->isCached() == false )
413 {
414 while ( pSelect->nextTuple(fl));
415 }
416
417 if ( flArray )
418 {
419 flArray=0;
420 pP->getExpr1()->setFieldListArray(flArray);
421 }
422 pP->getExpr1()->setBlock(0);
423
424 pSelect->setProcBlock(0);
425 pSelect->setParentJoinBuf();
426 pSelect->reset(false);
427
428 break;
429 }
430 case CegoPredDesc::NOTPRED:
431 case CegoPredDesc::CONDITION:
432 break;
433 }
434 return retVal;
435 }
436 }
437 return false;
438 }
439
checkAttrCond(CegoAttrCond & ac,CegoPredDesc * pP,const ListT<CegoField> & schema,ListT<CegoField> * flArray,int flSize,CegoProcBlock * pBlock)440 CegoQueryHelper::AttrCondMatch CegoQueryHelper::checkAttrCond(CegoAttrCond& ac,
441 CegoPredDesc* pP,
442 const ListT<CegoField>& schema,
443 ListT<CegoField>* flArray,
444 int flSize,
445 CegoProcBlock *pBlock)
446 {
447 AttrCondMatch m = evalAttrCond(ac, pP, schema, flArray, flSize, pBlock);
448 if ( ac.numComp() == 0 )
449 m = INAPP;
450
451 return m;
452 }
453
evalAttrCond(CegoAttrCond & ac,CegoPredDesc * pP,const ListT<CegoField> & schema,ListT<CegoField> * flArray,int flSize,CegoProcBlock * pBlock)454 CegoQueryHelper::AttrCondMatch CegoQueryHelper::evalAttrCond(CegoAttrCond& ac,
455 CegoPredDesc* pP,
456 const ListT<CegoField>& schema,
457 ListT<CegoField>* flArray,
458 int flSize,
459 CegoProcBlock *pBlock)
460 {
461 if (pP->getCondition())
462 {
463 return evalAttrCondbyCondition(ac, pP->getCondition(), schema, flArray, flSize, pBlock);
464 }
465 else if (pP->getMode() == CegoPredDesc::EXPRCOMP)
466 {
467 CegoAttrDesc* pAttrDesc1;
468 CegoAttrDesc* pAttrDesc2;
469
470 pAttrDesc1 = pP->getExpr1()->checkAttr();
471 pAttrDesc2 = pP->getExpr2()->checkAttr();
472 ListT<CegoAttrDesc*> attrRefList1 = pP->getExpr1()->getAttrRefList();
473 ListT<CegoAttrDesc*> attrRefList2 = pP->getExpr2()->getAttrRefList();
474
475 if ( pAttrDesc1 && pAttrDesc2 )
476 {
477 CegoField* pF = schema.First();
478
479 while (pF)
480 {
481 if ( ((Chain)pAttrDesc1->getTableName() == (Chain)pF->getTableName() ||
482 (Chain)pAttrDesc1->getTableName() == (Chain)pF->getTableAlias() ||
483 pAttrDesc1->getTableName() == Chain())
484 && (Chain)pAttrDesc1->getAttrName() == (Chain)pF->getAttrName() )
485 {
486 for ( int i=0; i<flSize; i++)
487 {
488 CegoField* pFB = flArray[i].First();
489 while (pFB)
490 {
491 if (((Chain)pAttrDesc2->getTableName() == (Chain)pFB->getTableName() ||
492 (Chain)pAttrDesc2->getTableName() == (Chain)pFB->getTableAlias() ||
493 pAttrDesc2->getTableName() == Chain())
494 && (Chain)pAttrDesc2->getAttrName() == (Chain)pFB->getAttrName())
495 {
496 ac.add(CegoAttrComp(pF->getTableAlias(),
497 pF->getAttrName(),
498 pP->getComparison(),
499 *pAttrDesc2));
500 }
501 pFB = flArray[i].Next();
502 }
503 }
504 }
505
506 if ( ((Chain)pAttrDesc2->getTableName() == (Chain)pF->getTableName() ||
507 (Chain)pAttrDesc2->getTableName() == (Chain)pF->getTableAlias() ||
508 pAttrDesc2->getTableName() == Chain())
509 && (Chain)pAttrDesc2->getAttrName() == (Chain)pF->getAttrName() )
510 {
511 for ( int i=0; i<flSize; i++)
512 {
513 CegoField* pFB = flArray[i].First();
514 while (pFB)
515 {
516 if (((Chain)pAttrDesc1->getTableName() == (Chain)pFB->getTableName() ||
517 (Chain)pAttrDesc1->getTableName() == (Chain)pFB->getTableAlias() ||
518 pAttrDesc1->getTableName() == Chain())
519 && (Chain)pAttrDesc1->getAttrName() == (Chain)pFB->getAttrName())
520 {
521
522 // we have to map comparison
523 CegoComparison comp = pP->getComparison();
524 if ( comp == LESS_THAN )
525 comp = MORE_THAN;
526 else if ( comp == MORE_THAN )
527 comp = LESS_THAN;
528 else if ( comp == LESS_EQUAL_THAN )
529 comp = MORE_EQUAL_THAN;
530 else if ( comp == MORE_EQUAL_THAN )
531 comp = LESS_EQUAL_THAN;
532
533 ac.add(CegoAttrComp(pF->getTableAlias(),
534 pF->getAttrName(),
535 comp,
536 *pAttrDesc1));
537 }
538 pFB = flArray[i].Next();
539 }
540 }
541 }
542 pF = schema.Next();
543 }
544 }
545 else if ( pAttrDesc1 && attrRefList2.Size() == 0 )
546 {
547 CegoField* pF = schema.First();
548 while (pF)
549 {
550 if ((pAttrDesc1->getTableName() == (Chain)pF->getTableName() ||
551 pAttrDesc1->getTableName() == (Chain)pF->getTableAlias() ||
552 pAttrDesc1->getTableName() == Chain())
553 && pAttrDesc1->getAttrName() == (Chain)pF->getAttrName())
554 {
555 pP->getExpr2()->setBlock(pBlock);
556 ac.add(CegoAttrComp(pF->getTableAlias(),
557 pF->getAttrName(),
558 pP->getComparison(),
559 pP->getExpr2()->evalFieldValue()));
560 return COMPLETE;
561 }
562 pF = schema.Next();
563 }
564 return PARTIAL;
565 }
566 else if ( pAttrDesc2 && attrRefList1.Size() == 0 )
567 {
568 CegoField* pF = schema.First();
569 while (pF)
570 {
571
572 if ((pAttrDesc2->getTableName() == (Chain)pF->getTableName() ||
573 pAttrDesc2->getTableName() == (Chain)pF->getTableAlias() ||
574 pAttrDesc2->getTableName() == Chain())
575 && pAttrDesc2->getAttrName() == (Chain)pF->getAttrName())
576 {
577 pP->getExpr1()->setBlock(pBlock);
578
579 // we have to map comparison
580 CegoComparison comp = pP->getComparison();
581 if ( comp == LESS_THAN )
582 comp = MORE_THAN;
583 else if ( comp == MORE_THAN )
584 comp = LESS_THAN;
585 else if ( comp == LESS_EQUAL_THAN )
586 comp = MORE_EQUAL_THAN;
587 else if ( comp == MORE_EQUAL_THAN )
588 comp = LESS_EQUAL_THAN;
589
590 ac.add(CegoAttrComp(pF->getTableAlias(),
591 pF->getAttrName(),
592 comp,
593 pP->getExpr1()->evalFieldValue()));
594 return COMPLETE;
595 }
596 pF = schema.Next();
597 }
598 return PARTIAL;
599 }
600 else
601 {
602 return PARTIAL;
603 }
604 }
605 else if (pP->getMode() == CegoPredDesc::BETWEEN)
606 {
607 CegoAttrDesc* pAttrDesc1 = pP->getExpr1()->checkAttr();
608 CegoAttrDesc* pAttrDesc2 = pP->getExpr2()->checkAttr();
609 CegoAttrDesc* pAttrDesc3 = pP->getExpr3()->checkAttr();
610
611 ListT<CegoAttrDesc*> attrRefList1 = pP->getExpr1()->getAttrRefList();
612 ListT<CegoAttrDesc*> attrRefList2 = pP->getExpr2()->getAttrRefList();
613 ListT<CegoAttrDesc*> attrRefList3 = pP->getExpr3()->getAttrRefList();
614
615 if ( pAttrDesc1 )
616 {
617 CegoField* pF = schema.First();
618 while (pF)
619 {
620 if ((pAttrDesc1->getTableName() == (Chain)pF->getTableName() ||
621 pAttrDesc1->getTableName() == (Chain)pF->getTableAlias() ||
622 pAttrDesc1->getTableName() == Chain())
623 && pAttrDesc1->getAttrName() == (Chain)pF->getAttrName())
624 {
625 if ( attrRefList2.Size() == 0 && attrRefList3.Size() == 0 )
626 {
627 pP->getExpr2()->setBlock(pBlock);
628 pP->getExpr3()->setBlock(pBlock);
629
630 ac.add(CegoAttrComp(pF->getTableAlias(),
631 pF->getAttrName(),
632 pP->getExpr2()->evalFieldValue(),
633 pP->getExpr3()->evalFieldValue()));
634 }
635 else if ( pAttrDesc2 && attrRefList3.Size() == 0 )
636 {
637 pP->getExpr3()->setBlock(pBlock);
638
639 ac.add(CegoAttrComp(pF->getTableAlias(),
640 pF->getAttrName(),
641 *pAttrDesc2,
642 pP->getExpr3()->evalFieldValue()));
643 }
644 else if ( attrRefList2.Size() == 0 && pAttrDesc3 )
645 {
646 pP->getExpr2()->setBlock(pBlock);
647
648 ac.add(CegoAttrComp(pF->getTableAlias(),
649 pF->getAttrName(),
650 pP->getExpr2()->evalFieldValue(),
651 *pAttrDesc3));
652 }
653 else if ( pAttrDesc2 && pAttrDesc3 )
654 {
655 ac.add(CegoAttrComp(pF->getTableAlias(),
656 pF->getAttrName(),
657 *pAttrDesc2,
658 *pAttrDesc3));
659 }
660 else
661 {
662 return PARTIAL;
663 }
664
665 return COMPLETE;
666 }
667 pF = schema.Next();
668 }
669 return PARTIAL;
670 }
671 else
672 {
673 return PARTIAL;
674 }
675 }
676 else if (pP->getMode() == CegoPredDesc::ISLIKE)
677 {
678 CegoAttrDesc* pAttrDesc;
679 pAttrDesc = pP->getExpr1()->checkAttr();
680 if ( pAttrDesc )
681 {
682 CegoField* pF = schema.First();
683 while (pF)
684 {
685 if ((pAttrDesc->getTableName() == (Chain)pF->getTableName() ||
686 pAttrDesc->getTableName() == (Chain)pF->getTableAlias() ||
687 pAttrDesc->getTableName() == Chain())
688 && pAttrDesc->getAttrName() == (Chain)pF->getAttrName())
689 {
690 ac.add(CegoAttrComp(pAttrDesc->getTableName(), pAttrDesc->getAttrName(), pP->getPattern(), false));
691 return COMPLETE;
692 }
693 pF = schema.Next();
694 }
695 return PARTIAL;
696 }
697 else
698 {
699 return PARTIAL;
700 }
701 }
702 else if (pP->getMode() == CegoPredDesc::ISNOTLIKE)
703 {
704 CegoAttrDesc* pAttrDesc;
705 pAttrDesc = pP->getExpr1()->checkAttr();
706 if ( pAttrDesc )
707 {
708 CegoField* pF = schema.First();
709 while (pF)
710 {
711 if ((pAttrDesc->getTableName() == (Chain)pF->getTableName() ||
712 pAttrDesc->getTableName() == (Chain)pF->getTableAlias() ||
713 pAttrDesc->getTableName() == Chain())
714 && pAttrDesc->getAttrName() == (Chain)pF->getAttrName())
715 {
716 ac.add(CegoAttrComp(pAttrDesc->getTableName(), pAttrDesc->getAttrName(), pP->getPattern(), true));
717 return COMPLETE;
718 }
719 pF = schema.Next();
720 }
721 return PARTIAL;
722 }
723 else
724 {
725 return PARTIAL;
726 }
727 }
728 else if (pP->getMode() == CegoPredDesc::NULLCOMP)
729 {
730 CegoAttrDesc* pAttrDesc;
731 pAttrDesc = pP->getExpr1()->checkAttr();
732 if ( pAttrDesc )
733 {
734 CegoField* pF = schema.First();
735 while (pF)
736 {
737 if ((pAttrDesc->getTableName() == (Chain)pF->getTableName() ||
738 pAttrDesc->getTableName() == (Chain)pF->getTableAlias() ||
739 pAttrDesc->getTableName() == Chain())
740 && pAttrDesc->getAttrName() == (Chain)pF->getAttrName())
741 {
742 CegoFieldValue nullValue;
743 ac.add(CegoAttrComp(pAttrDesc->getTableName(), pAttrDesc->getAttrName(), EQUAL, nullValue));
744 return COMPLETE;
745 }
746 pF = schema.Next();
747 }
748 return PARTIAL;
749 }
750 else
751 {
752 return PARTIAL;
753 }
754 }
755 else if (pP->getMode() == CegoPredDesc::NOTNULLCOMP)
756 {
757 CegoAttrDesc* pAttrDesc;
758 pAttrDesc = pP->getExpr1()->checkAttr();
759 if ( pAttrDesc )
760 {
761 CegoField* pF = schema.First();
762 while (pF)
763 {
764 if ((pAttrDesc->getTableName() == (Chain)pF->getTableName() ||
765 pAttrDesc->getTableName() == (Chain)pF->getTableAlias() ||
766 pAttrDesc->getTableName() == Chain())
767 && pAttrDesc->getAttrName() == (Chain)pF->getAttrName())
768 {
769 CegoFieldValue nullValue;
770 ac.add(CegoAttrComp(pAttrDesc->getTableName(), pAttrDesc->getAttrName(), NOT_EQUAL, nullValue));
771 return COMPLETE;
772 }
773 pF = schema.Next();
774 }
775 return PARTIAL;
776 }
777 else
778 {
779 return PARTIAL;
780 }
781 }
782 else if (pP->getMode() == CegoPredDesc::EXISTSCOMP)
783 {
784 return PARTIAL;
785 }
786 else if (pP->getMode() == CegoPredDesc::IN)
787 {
788 return PARTIAL;
789 }
790 else if (pP->getMode() == CegoPredDesc::NOTIN)
791 {
792 return PARTIAL;
793 }
794 else if (pP->getMode() == CegoPredDesc::INSUB)
795 {
796 return PARTIAL;
797 }
798 else if (pP->getMode() == CegoPredDesc::NOTINSUB)
799 {
800 return PARTIAL;
801 }
802 else if (pP->getMode() == CegoPredDesc::NOTPRED)
803 {
804 return PARTIAL;
805 }
806 else
807 {
808 return PARTIAL;
809 }
810
811 return COMPLETE;
812 }
813
evalAttrCondbyCondition(CegoAttrCond & ac,CegoCondDesc * pC,const ListT<CegoField> & schema,ListT<CegoField> * flArray,int flSize,CegoProcBlock * pBlock)814 CegoQueryHelper::AttrCondMatch CegoQueryHelper::evalAttrCondbyCondition(CegoAttrCond& ac,
815 CegoCondDesc* pC,
816 const ListT<CegoField>& schema,
817 ListT<CegoField>* flArray,
818 int flSize,
819 CegoProcBlock* pBlock)
820 {
821 if ( pC->getCondType() == CegoCondDesc::OR)
822 {
823 return INAPP;
824 }
825
826 AttrCondMatch m1, m2;
827 m1 = COMPLETE;
828 m2 = COMPLETE;
829 if ( pC->Left() )
830 {
831 m1 = evalAttrCond(ac, pC->Left(), schema, flArray, flSize, pBlock);
832 }
833 if ( pC->Right() )
834 {
835 m2 = evalAttrCond(ac, pC->Right(), schema, flArray, flSize, pBlock);
836 }
837
838 if ( m1 == INAPP || m2 == INAPP )
839 return INAPP;
840 if ( m1 == PARTIAL || m2 == PARTIAL )
841 return PARTIAL;
842
843 return COMPLETE;
844 }
845
makeCNF(CegoCondDesc * pC)846 void CegoQueryHelper::makeCNF(CegoCondDesc* pC)
847 {
848 if ( pC )
849 {
850 if (pC->Left()->getCondition())
851 {
852 makeCNF(pC->Left()->getCondition());
853 }
854 if (pC->Right()->getCondition())
855 {
856 makeCNF(pC->Right()->getCondition());
857 }
858 if ( pC->getCondType() == CegoCondDesc::AND )
859 {
860 // nothing to do
861 }
862 else if ( pC->getCondType() == CegoCondDesc::OR )
863 {
864 if ( pC->Left()->getCondition() )
865 {
866 CegoCondDesc *pLC = pC->Left()->getCondition();
867 if (pLC->getCondType() == CegoCondDesc::AND)
868 {
869 pC->setCondType(CegoCondDesc::AND);
870 CegoCondDesc* pNC = new CegoCondDesc(CegoCondDesc::OR);
871 pNC->setLeft(pLC->Right());
872 pNC->setRight(pC->Right());
873 CegoPredDesc* pNP = new CegoPredDesc(pNC);
874 pC->setRight(pNP);
875 pLC->setCondType(CegoCondDesc::OR);
876
877 pLC->setRight(pNC->Right()->clone());
878
879 makeCNF(pC->Left()->getCondition());
880 makeCNF(pC->Right()->getCondition());
881 }
882 else
883 {
884 makeCNF(pC->Left()->getCondition());
885 }
886 }
887 else if ( pC->Right()->getCondition() )
888 {
889 CegoCondDesc *pRC = pC->Right()->getCondition();
890 if (pRC->getCondType() == CegoCondDesc::AND)
891 {
892 pC->setCondType(CegoCondDesc::AND);
893 CegoCondDesc* pNC = new CegoCondDesc(CegoCondDesc::OR);
894 pNC->setLeft(pC->Left());
895 pNC->setRight(pRC->Left());
896 CegoPredDesc* pNP = new CegoPredDesc(pNC);
897 pC->setLeft(pNP);
898 pRC->setCondType(CegoCondDesc::OR);
899 pRC->setLeft(pNC->Left()->clone());
900
901 makeCNF(pC->Left()->getCondition());
902 makeCNF(pC->Right()->getCondition());
903 }
904 else
905 {
906 makeCNF(pC->Right()->getCondition());
907 }
908
909 }
910 }
911 }
912 }
913
createConjunctionList(CegoPredDesc * pPred,ListT<CegoPredDesc * > * pConjunctionList)914 void CegoQueryHelper::createConjunctionList(CegoPredDesc* pPred, ListT<CegoPredDesc*>* pConjunctionList)
915 {
916 if (pPred)
917 {
918 CegoCondDesc* pC = pPred->getCondition();
919 if (pC)
920 {
921 if (pC->getCondType() == CegoCondDesc::AND)
922 {
923 createConjunctionList(pC->Left(), pConjunctionList);
924 createConjunctionList(pC->Right(), pConjunctionList);
925 }
926 else
927 {
928 pConjunctionList->Insert(pPred);
929 }
930 }
931 else
932 {
933 pConjunctionList->Insert(pPred);
934 }
935 }
936 }
937
condToChain(CegoCondDesc * pC,int depth)938 Chain CegoQueryHelper::condToChain(CegoCondDesc* pC, int depth)
939 {
940 Chain s;
941 if (pC->Left())
942 {
943 s = predToChain(pC->Left(), depth+1);
944 for (int i=0;i<depth;i++)
945 s += Chain(" ");
946 switch(pC->getCondType())
947 {
948 case CegoCondDesc::AND:
949 s += Chain(" AND ");
950 break;
951 case CegoCondDesc::OR:
952 s += Chain(" OR ");
953 break;
954 case CegoCondDesc::PRED:
955 break;
956 }
957 s += predToChain(pC->Right(), depth+1);
958 }
959 return s;
960 }
961
predToChain(CegoPredDesc * pP,int depth)962 Chain CegoQueryHelper::predToChain(CegoPredDesc* pP, int depth)
963 {
964 Chain s;
965
966 s += pP->toChain();
967
968 if (pP->getCondition())
969 {
970 s = condToChain(pP->getCondition(), depth+1);
971 }
972 else
973 {
974 for (int i=0;i<depth;i++)
975 s+= Chain(" ");
976 }
977 return s;
978 }
979
evalFields(CegoComparison comp,const CegoFieldValue & f1,const CegoFieldValue & f2)980 bool CegoQueryHelper::evalFields(CegoComparison comp, const CegoFieldValue& f1, const CegoFieldValue& f2)
981 {
982 switch (comp)
983 {
984 case EQUAL:
985 return ( f1 == f2 );
986 case NOT_EQUAL:
987 return ( f1 != f2 );
988 case LESS_THAN:
989 return ( f1 < f2 );
990 case MORE_THAN:
991 return ( f1 > f2 );
992 case LESS_EQUAL_THAN:
993 return ( f1 <= f2 );
994 case MORE_EQUAL_THAN:
995 return ( f1 >= f2 );
996 }
997 }
998
evalBetween(const CegoFieldValue & f1,const CegoFieldValue & f2,const CegoFieldValue & f3)999 bool CegoQueryHelper::evalBetween(const CegoFieldValue& f1, const CegoFieldValue& f2, const CegoFieldValue& f3)
1000 {
1001 if ( f2 <= f1 && f1 <= f3 )
1002 return true;
1003 return false;
1004 }
1005
aggregateTuple(ListT<CegoField> & aggTuple,CegoExpr * pExpr)1006 void CegoQueryHelper::aggregateTuple(ListT<CegoField>& aggTuple, CegoExpr* pExpr)
1007 {
1008 CegoAggregation **pAgg = pExpr->getAggregationList().First();
1009
1010 while ( pAgg )
1011 {
1012 aggregateTuple(aggTuple, *pAgg);
1013 pAgg = pExpr->getAggregationList().Next();
1014 }
1015 }
1016
aggregateTuple(ListT<CegoField> & aggTuple,CegoAggregation * pAgg)1017 void CegoQueryHelper::aggregateTuple(ListT<CegoField>& aggTuple, CegoAggregation* pAgg)
1018 {
1019 switch ( pAgg->getType() )
1020 {
1021 case CegoAggregation::COUNT:
1022 {
1023 if ( pAgg->getFieldValue().getValue() == 0 )
1024 {
1025 pAgg->setFieldValue( CegoFieldValue(LONG_TYPE, Chain("1")) );
1026 }
1027 else
1028 {
1029 (*(((long long*)(pAgg->getFieldValue().getValue()))))++;
1030 }
1031 break;
1032 }
1033 case CegoAggregation::SUM:
1034 case CegoAggregation::AVG:
1035 {
1036
1037 CegoFieldValue fv;
1038
1039 CegoExpr *pAE = pAgg->getExpr();
1040
1041 if ( pAE )
1042 {
1043 pAE->setFieldListArray( &aggTuple );
1044 fv = pAE->evalFieldValue();
1045 }
1046
1047 if ( fv.getType() == VARCHAR_TYPE )
1048 {
1049 Chain msg = Chain("Aggregation not supported on datatype <") + CEGO_TYPE_MAP[ (int) fv.getType()] + Chain(">");
1050 throw Exception(EXLOC, msg);
1051 }
1052
1053 if ( pAgg->getFieldValue().getValue() == 0 )
1054 {
1055 pAgg->setFieldValue( fv.getLocalCopy() );
1056 }
1057 else
1058 {
1059 // local copy via add
1060 pAgg->setFieldValue( pAgg->getFieldValue() + fv );
1061 }
1062 break;
1063 }
1064 case CegoAggregation::MIN:
1065 {
1066 CegoFieldValue fv;
1067 CegoExpr *pAE = pAgg->getExpr();
1068
1069 if ( pAE )
1070 {
1071 pAE->setFieldListArray( &aggTuple );
1072 fv = pAE->evalFieldValue();
1073 }
1074
1075 if ( pAgg->getFieldValue().getValue() == 0 )
1076 // if ( pAgg->isInit() )
1077 {
1078 pAgg->setFieldValue( fv.getLocalCopy() );
1079 // pAgg->setInit(false);
1080 }
1081 else
1082 {
1083 if ( (CegoFieldValue)pAgg->getFieldValue() > fv )
1084 {
1085 pAgg->setFieldValue( fv.getLocalCopy() );
1086 }
1087 }
1088 break;
1089 }
1090 case CegoAggregation::MAX:
1091 {
1092 CegoFieldValue fv;
1093 CegoExpr *pAE = pAgg->getExpr();
1094
1095 if ( pAE )
1096 {
1097 pAE->setFieldListArray( &aggTuple );
1098 fv = pAE->evalFieldValue();
1099 }
1100
1101 if ( pAgg->getFieldValue().getValue() == 0 )
1102 {
1103 pAgg->setFieldValue( fv.getLocalCopy() );
1104 }
1105 else
1106 {
1107 if ( (CegoFieldValue)pAgg->getFieldValue() < fv )
1108 {
1109 pAgg->setFieldValue( fv.getLocalCopy() );
1110 }
1111 }
1112
1113 break;
1114 }
1115 }
1116 }
1117
prepareFieldValue(CegoField * pFV,CegoFieldValue & fv,CegoTableManager * pTM,int tabSetId)1118 void CegoQueryHelper::prepareFieldValue(CegoField* pFV, CegoFieldValue& fv, CegoTableManager* pTM, int tabSetId)
1119 {
1120 // first we check if the field is nullable and a value is given
1121 if ( pFV->isNullable() == false && fv.isNull() )
1122 {
1123 throw Exception(EXLOC, Chain("Invalid null value for attribute <")
1124 + pFV->getAttrName()
1125 + Chain("> in value list"));
1126
1127 // if not nullable and no value given, we check for field default value
1128
1129 /*
1130 if ( pFV->getValue().isNull() )
1131 {
1132 }
1133 else
1134 {
1135 // set field default value
1136 fv = pFV->getValue();
1137 }
1138 */
1139 }
1140
1141 if ( fv.getType() != NULL_TYPE && pFV->getType() != fv.getType() )
1142 {
1143
1144 if ( pFV->getType() == CLOB_TYPE && fv.getType() == VARCHAR_TYPE && pTM )
1145 if ( string2Clob(fv, pTM, tabSetId) )
1146 return;
1147
1148 if ( fv.castTo(pFV->getType(), pFV->getDim()) == false )
1149 {
1150 throw Exception(EXLOC, Chain("Mismatched datatype <")
1151 + CEGO_TYPE_MAP[(int)fv.getType()]
1152 + Chain("> for attribute ") + pFV->getAttrName()
1153 + ", expected <"
1154 + CEGO_TYPE_MAP[(int)pFV->getType()] + ">");
1155 }
1156 }
1157
1158 if ( fv.getValue() != 0 )
1159 {
1160 if ( pFV->getLength() < fv.getLength() -1 )
1161 {
1162 throw Exception(EXLOC, Chain("Value length for ") + pFV->getAttrName() + Chain(" exceeded ( max len is ") + Chain(pFV->getLength()) + Chain(")"));
1163 }
1164
1165 if ( pFV->getType() == VARCHAR_TYPE
1166 && pFV->getLength() < fv.getLength() )
1167 {
1168 Chain shrinkVal ( (char*) fv.getValue() );
1169 fv = CegoFieldValue(VARCHAR_TYPE, shrinkVal.subChain(1, pFV->getLength()));
1170 }
1171 else if ( pFV->getType() == DATETIME_TYPE )
1172 {
1173 unsigned long long dateVal;
1174 memcpy(&dateVal, fv.getValue(), sizeof(unsigned long long));
1175 if (dateVal == 0 )
1176 {
1177 Datetime n;
1178 unsigned long long dtval = n.asLong();
1179 memcpy(fv.getValue(), &dtval, sizeof(unsigned long long));
1180 }
1181 }
1182 else if ( pFV->getType() == BLOB_TYPE || pFV->getType() == CLOB_TYPE )
1183 {
1184 PageIdType pageId;
1185 memcpy(&pageId, fv.getValue(), sizeof(PageIdType));
1186
1187 if ( pTM->getDBMng()->isClaimed(pageId, pTM->getLockHandler()))
1188 {
1189 CegoBufferPage bp;
1190 pTM->getDBMng()->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, pTM->getLockHandler());
1191 pTM->getDBMng()->bufferUnfix(bp, true, pTM->getLockHandler());
1192
1193 if ( pFV->getType() == BLOB_TYPE && bp.getType() == CegoBufferPage::BLOB )
1194 {
1195 // ok !
1196 }
1197 else if ( pFV->getType() == CLOB_TYPE && bp.getType() == CegoBufferPage::CLOB )
1198 {
1199 // ok !
1200 }
1201 else
1202 {
1203 throw Exception(EXLOC, Chain("Invalid lob type"));
1204 }
1205 }
1206 }
1207 else if ( pFV->getType() == FIXED_TYPE )
1208 {
1209 // for fixed values, we have to check the correct dimension
1210
1211 Chain fixedVal = fv.valAsChain();
1212
1213 int pos;
1214 if ( fixedVal.posStr(Chain("."), pos) == false )
1215 throw Exception(EXLOC, Chain("Invalid fixed value <") + fixedVal + Chain(">"));
1216
1217 int dim = fixedVal.length() - pos - 1;
1218
1219 if ( dim < pFV->getDim() )
1220 {
1221 int diff = pFV->getDim() - dim;
1222 while ( diff > 0 )
1223 {
1224 fixedVal = fixedVal + Chain("0");
1225 diff --;
1226 }
1227 }
1228 else if ( dim > pFV->getDim() )
1229 {
1230 int diff = dim - pFV->getDim();
1231 fixedVal = fixedVal.subChain(1, fixedVal.length() - ( diff + 1) );
1232 }
1233
1234 fv = CegoFieldValue(FIXED_TYPE, fixedVal);
1235 }
1236 }
1237 }
1238
checkIndexForPredicate(int tabSetId,CegoDistManager * pGTM,CegoPredDesc * pPred,ListT<CegoContentObject * > & coList)1239 bool CegoQueryHelper::checkIndexForPredicate(int tabSetId, CegoDistManager* pGTM, CegoPredDesc *pPred, ListT<CegoContentObject*>& coList)
1240 {
1241 CegoCondDesc* pC = pPred->getCondition();
1242 if (pC)
1243 {
1244 if (pC->getCondType() == CegoCondDesc::AND)
1245 {
1246 return checkIndexForPredicate(tabSetId, pGTM, pC->Left(), coList) || checkIndexForPredicate(tabSetId, pGTM, pC->Right(), coList);
1247 }
1248 else
1249 {
1250 return false;
1251 }
1252 }
1253 else if (pPred->getMode() == CegoPredDesc::EXPRCOMP)
1254 {
1255
1256 SetT<Chain> tableRefSet = pPred->getTableRefSet();
1257 ListT<CegoAttrDesc*> attrRefList = pPred->getAttrRefList();
1258
1259 if ( tableRefSet.Size() == 1 )
1260 {
1261 Chain *pTableName = tableRefSet.First();
1262
1263 ListT<CegoTableObject> idxList;
1264 ListT<CegoBTreeObject> btreeList;
1265 ListT<CegoKeyObject> keyList;
1266 ListT<CegoCheckObject> checkList;
1267 ListT<CegoTriggerObject> triggerList;
1268 ListT<CegoAliasObject> aliasList;
1269 int numInvalid;
1270
1271 int tsId;
1272 Chain tabName;
1273 CegoContentObject **pCO = coList.First();
1274 bool found=false;
1275 while ( pCO && ! found )
1276 {
1277
1278 // cout << "Checking co " << (*pCO)->getName() << " table = " << (*pCO)->getTabName() << endl;
1279
1280 if ( (*pCO)->getName() == *pTableName || (*pCO)->getTabName() == *pTableName )
1281 {
1282 // the table might be in a different tableset
1283 tsId = (*pCO)->getTabSetId();
1284 tabName = (*pCO)->getTabName();
1285 found=true;
1286 }
1287 else
1288 {
1289 pCO = coList.Next();
1290 }
1291 }
1292
1293 // we just check index objects for appropriate physical objects ( e.g. join objects are not appropriate )
1294 if ( found )
1295 {
1296
1297 pGTM->getObjectListByTable(tsId, tabName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
1298
1299 ListT<CegoAttrAlias> aliasList;
1300 if ( (*pCO)->getType() == CegoObject::ALIAS )
1301 {
1302 aliasList = ((CegoAliasObject*)*pCO)->getAliasList();
1303 }
1304
1305 CegoBTreeObject *pBTO = btreeList.First();
1306
1307 while ( pBTO )
1308 {
1309 if ( pBTO->isValid() )
1310 {
1311 CegoField *pIF = pBTO->getSchema().First();
1312 if ( pIF )
1313 {
1314 CegoAttrDesc **pAttrDesc = attrRefList.First();
1315 while ( pAttrDesc )
1316 {
1317
1318 Chain attrName = (*pAttrDesc)->getAttrName();
1319 CegoAttrAlias *pA = aliasList.First();
1320 bool found=false;
1321 while ( pA && ! found )
1322 {
1323 if ( (*pAttrDesc)->getAttrName() == pA->getAliasName() )
1324 {
1325 attrName = pA->getAttrName();
1326 found = true;
1327 }
1328 else
1329 {
1330 pA = aliasList.Next();
1331 }
1332 }
1333
1334 if ( attrName == pIF->getAttrName() )
1335 {
1336 return true;
1337 }
1338 pAttrDesc = attrRefList.Next();
1339 }
1340
1341 pIF = pBTO->getSchema().Next();
1342 }
1343 }
1344 pBTO = btreeList.Next();
1345 }
1346 }
1347 }
1348 }
1349 return false;
1350 }
1351
encodeFL(const ListT<CegoField> & fvl,char * & pBufBase,int & buflen)1352 void CegoQueryHelper::encodeFL(const ListT<CegoField>& fvl, char* &pBufBase, int &buflen)
1353 {
1354 CegoField* pF = fvl.First();
1355 while (pF)
1356 {
1357 buflen += sizeof(CegoDataType); // datatype
1358 buflen += sizeof(int); // datatype len
1359
1360 buflen += sizeof(int); // defaultvalue len
1361
1362 if ( pF->getValue().getLength() > 0 )
1363 buflen += pF->getValue().getLength();
1364
1365 buflen += sizeof(char); // isNullable
1366 buflen += sizeof(int); // attr length
1367 buflen += pF->getAttrName().length(); // attr
1368
1369 pF = fvl.Next();
1370 }
1371
1372 pBufBase = (char*) malloc(buflen);
1373
1374 if (pBufBase == 0)
1375 {
1376 throw Exception(EXLOC, "malloc system error");
1377 }
1378
1379 char *pBuf = pBufBase;
1380
1381 pF = fvl.First();
1382 while (pF)
1383 {
1384 int attrLength = pF->getAttrName().length();
1385 CegoDataType dt = pF->getType();
1386
1387 memcpy( pBuf, &dt, sizeof(CegoDataType));
1388 pBuf += sizeof(CegoDataType);
1389
1390 int dtlen = pF->getLength();
1391
1392 memcpy( pBuf, &dtlen, sizeof(int));
1393 pBuf += sizeof(int);
1394
1395 int deflen = pF->getValue().getLength();
1396
1397 memcpy( pBuf, &deflen, sizeof(int));
1398 pBuf += sizeof(int);
1399
1400 if ( deflen > 0 )
1401 {
1402 memcpy( pBuf, pF->getValue().getValue(), deflen);
1403 pBuf += deflen;
1404 }
1405
1406 char isNullable = 0;
1407 if ( pF->isNullable() )
1408 isNullable = 1;
1409
1410 memcpy( pBuf, &isNullable, sizeof(char));
1411 pBuf += sizeof(char);
1412
1413 memcpy( pBuf, &attrLength, sizeof(int));
1414 pBuf += sizeof(int);
1415
1416 memcpy( pBuf, (char*)pF->getAttrName(), attrLength);
1417 pBuf += attrLength;
1418
1419 pF = fvl.Next();
1420 }
1421 }
1422
decodeFL(ListT<CegoField> & fvl,char * pc,int len)1423 void CegoQueryHelper::decodeFL(ListT<CegoField>& fvl, char* pc, int len)
1424 {
1425 char *pBase = pc;
1426
1427 while (pc - pBase < len)
1428 {
1429 CegoDataType dt;
1430 memcpy(&dt, pc, sizeof(CegoDataType));
1431 pc += sizeof(CegoDataType);
1432
1433 int dtlen;
1434 memcpy( &dtlen, pc, sizeof(int));
1435 pc += sizeof(int);
1436
1437 CegoFieldValue defVal;
1438
1439 int deflen;
1440 memcpy( &deflen, pc, sizeof(int));
1441 pc += sizeof(int);
1442 if ( deflen > 0 )
1443 {
1444 defVal = CegoFieldValue(dt, pc, deflen, false);
1445 pc += deflen;
1446 }
1447
1448 char isNullable;
1449 memcpy(&isNullable, pc, sizeof(char));
1450 pc += sizeof(char);
1451
1452 int attrLength;
1453 memcpy( &attrLength, pc, sizeof(int));
1454 pc += sizeof(int);
1455
1456 Chain attrName(pc, attrLength-1);
1457 pc += attrLength;
1458
1459 Chain n;
1460
1461 fvl.Insert(CegoField(n,n, attrName, dt, dtlen, 0, defVal, isNullable));
1462 }
1463 }
1464
encodeFVL(unsigned long long tid,unsigned long long tastep,CegoTupleState ts,const ListT<CegoField> & fvl,char * & pBufBase,int & buflen)1465 int CegoQueryHelper::encodeFVL(unsigned long long tid, unsigned long long tastep, CegoTupleState ts, const ListT<CegoField>& fvl, char* &pBufBase, int& buflen)
1466 {
1467 ListT<CegoBlob> blobList;
1468 ListT<CegoClob> clobList;
1469 return encodeFVL(tid, tastep, ts, fvl, blobList, clobList, pBufBase, buflen);
1470 }
1471
encodeFVL(unsigned long long tid,unsigned long long tastep,CegoTupleState ts,const ListT<CegoField> & fvl,const ListT<CegoBlob> & blobList,const ListT<CegoClob> & clobList,char * & pBufBase,int & buflen)1472 int CegoQueryHelper::encodeFVL(unsigned long long tid, unsigned long long tastep, CegoTupleState ts, const ListT<CegoField>& fvl, const ListT<CegoBlob>& blobList, const ListT<CegoClob>& clobList, char* &pBufBase, int& buflen)
1473 {
1474 int enclen = skipTupleHeader();
1475
1476 int blobIdx = 0;
1477 int clobIdx = 0;
1478
1479 CegoField* pF = fvl.First();
1480 while (pF)
1481 {
1482
1483 int l = pF->getValue().getLength();
1484 CegoDataType dt = pF->getValue().getType();
1485
1486 // force null type in case of fv length and value constraints
1487 if ( l == 0 || pF->getValue().getValue() == 0 )
1488 dt = NULL_TYPE;
1489
1490 if ( dt != NULL_TYPE )
1491 {
1492 enclen += sizeof(int); // id
1493 enclen += sizeof(CegoDataType);
1494
1495 if ( dt == BLOB_TYPE && blobList.Size() > 0)
1496 {
1497 enclen += sizeof(unsigned long long); // blobsize
1498 enclen += blobList[blobIdx].getSize();
1499 blobIdx++;
1500 }
1501 else if ( dt == CLOB_TYPE && clobList.Size() > 0)
1502 {
1503 enclen += sizeof(unsigned long long); // clobsize
1504 enclen += clobList[clobIdx].getSize();
1505 clobIdx++;
1506 }
1507 else
1508 {
1509 if ( dt == VARCHAR_TYPE
1510 || dt == BIGINT_TYPE
1511 || dt == DECIMAL_TYPE
1512 || dt == FIXED_TYPE )
1513 {
1514 enclen += sizeof(int);
1515 }
1516
1517 enclen += pF->getValue().getLength();
1518 }
1519 }
1520 pF = fvl.Next();
1521 }
1522
1523 enclen += sizeof(int); // terminating id
1524
1525 if ( enclen > buflen )
1526 {
1527 if ( pBufBase != 0 )
1528 free(pBufBase);
1529 pBufBase = (char*) malloc(enclen);
1530 buflen = enclen;
1531 }
1532
1533 if (pBufBase == 0)
1534 {
1535 throw Exception(EXLOC, "malloc system error");
1536 }
1537
1538 char *pBuf = pBufBase;
1539
1540 int toff = encodeTupleHeader(tid, tastep, ts, pBuf);
1541 pBuf += toff;
1542
1543 blobIdx = 0;
1544 clobIdx = 0;
1545
1546 pF = fvl.First();
1547 while (pF)
1548 {
1549 int id = pF->getId();
1550 int l = pF->getValue().getLength();
1551 CegoDataType dt = pF->getValue().getType();
1552
1553 // cout << "Encoding id " << id << endl;
1554 // force null type in case of fv length and value constraints
1555 if ( l == 0 || pF->getValue().getValue() == 0 )
1556 dt = NULL_TYPE;
1557
1558 if ( dt != NULL_TYPE )
1559 {
1560 // cout << "ID = " << id << " Encoding value " << pF->getValue().valAsChain() << endl;
1561
1562 memcpy( pBuf, &id, sizeof(int));
1563 pBuf += sizeof(int);
1564
1565 memcpy( pBuf, &dt, sizeof(CegoDataType));
1566 pBuf += sizeof(CegoDataType);
1567
1568 if ( dt == BLOB_TYPE && blobList.Size() > 0)
1569 {
1570 unsigned long long blobSize = blobList[blobIdx].getSize();
1571 memcpy( pBuf, &blobSize, sizeof(unsigned long long));
1572 pBuf += sizeof(unsigned long long);
1573 memcpy( pBuf, blobList[blobIdx].getBufPtr(), blobList[blobIdx].getSize());
1574 pBuf += blobList[blobIdx].getSize();
1575 blobIdx++;
1576 }
1577 else if ( dt == CLOB_TYPE && clobList.Size() > 0)
1578 {
1579 unsigned long long clobSize = clobList[clobIdx].getSize();
1580 memcpy( pBuf, &clobSize, sizeof(unsigned long long));
1581 pBuf += sizeof(unsigned long long);
1582 memcpy( pBuf, clobList[clobIdx].getBufPtr(), clobList[clobIdx].getSize());
1583 pBuf += clobList[clobIdx].getSize();
1584 clobIdx++;
1585 }
1586 else
1587 {
1588 if ( dt == VARCHAR_TYPE
1589 || dt == BIGINT_TYPE
1590 || dt == DECIMAL_TYPE
1591 || dt == FIXED_TYPE)
1592 {
1593 memcpy( pBuf, &l, sizeof(int));
1594 pBuf += sizeof(int);
1595 }
1596
1597 memcpy( pBuf, pF->getValue().getValue(), l);
1598
1599 pBuf += l;
1600 }
1601 }
1602
1603 pF = fvl.Next();
1604 }
1605
1606 int termId=0;
1607 memcpy( pBuf, &termId, sizeof(int));
1608
1609 return enclen;
1610 }
1611
1612 // for performance reasons, we also provide a method to just return the
1613 // tuple header len
skipTupleHeader()1614 int CegoQueryHelper::skipTupleHeader()
1615 {
1616 return sizeof(unsigned long long) + sizeof(unsigned long long) + sizeof(CegoTupleState);
1617 }
1618
encodeTupleHeader(unsigned long long tid,unsigned long long tastep,CegoTupleState ts,char * p)1619 int CegoQueryHelper::encodeTupleHeader(unsigned long long tid, unsigned long long tastep, CegoTupleState ts, char* p)
1620 {
1621 memcpy(p, &tid, sizeof(unsigned long long));
1622 p += sizeof(unsigned long long);
1623 memcpy(p, &tastep, sizeof(unsigned long long));
1624 p += sizeof(unsigned long long);
1625 memcpy(p, &ts, sizeof(CegoTupleState));
1626
1627 return sizeof(unsigned long long) + sizeof(unsigned long long) + sizeof(CegoTupleState);
1628 }
1629
decodeTupleHeader(unsigned long long & tid,unsigned long long & tastep,CegoTupleState & ts,char * p)1630 int CegoQueryHelper::decodeTupleHeader(unsigned long long& tid, unsigned long long& tastep, CegoTupleState& ts, char* p)
1631 {
1632 memcpy(&tid, p, sizeof(unsigned long long));
1633
1634 char* ptastep = p + sizeof(unsigned long long);
1635 memcpy(&tastep, ptastep, sizeof(unsigned long long));
1636
1637 char* pts = p + sizeof(unsigned long long) + sizeof(unsigned long long);
1638 memcpy(&ts, pts, sizeof(CegoTupleState));
1639
1640 return sizeof(unsigned long long) + sizeof(unsigned long long) + sizeof(CegoTupleState);
1641 }
1642
1643 // old implementation ( 2.41.6 )
1644
1645 /*
1646 void CegoQueryHelper::decodeFVL(ListT<CegoField>& fvl, char* pc, int len)
1647 {
1648 // make sure no field values are set
1649 if ( true )
1650 {
1651 CegoField* pF = fvl.First();
1652 while ( pF )
1653 {
1654 CegoFieldValue nullValue;
1655 pF->setValue(nullValue);
1656 pF = fvl.Next();
1657 }
1658 }
1659
1660 char* pBase = pc;
1661
1662 bool eot = false;
1663
1664 CegoField* pF = fvl.First();
1665
1666 while (pF && pc - pBase < len && eot == false)
1667 {
1668 int id;
1669 memcpy(&id, pc, sizeof(int));
1670
1671 if ( id > 0 )
1672 {
1673 pc += sizeof(int);
1674
1675 CegoDataType dt;
1676 memcpy(&dt, pc, sizeof(CegoDataType));
1677
1678 pc += sizeof(CegoDataType);
1679
1680 int flen;
1681
1682 if (dt == VARCHAR_TYPE
1683 || dt == BIGINT_TYPE
1684 || dt == DECIMAL_TYPE
1685 || dt == FIXED_TYPE )
1686 {
1687 memcpy(&flen, pc, sizeof(int));
1688 pc += sizeof(int);
1689 }
1690 else
1691 {
1692 flen = CegoTypeConverter::getTypeLen(dt);
1693 }
1694
1695 if ( id >= pF->getId() )
1696 {
1697 while ( pF && id > pF->getId() )
1698 pF=fvl.Next();
1699
1700 if ( pF && id == pF->getId() )
1701 {
1702 CegoFieldValue fv;
1703 fv.setType(dt);
1704 fv.setLength(flen);
1705
1706 if ( flen > 0)
1707 fv.setValue(pc);
1708 else
1709 fv.setValue(0);
1710 fv.setLocalCopy(false);
1711
1712 pF->setValue(fv);
1713
1714 pF = fvl.Next();
1715 }
1716 }
1717
1718 if ( flen > 0 )
1719 {
1720 pc += flen;
1721 }
1722 }
1723 else
1724 {
1725 eot = true;
1726 }
1727 }
1728 }
1729 */
1730
1731 // new implementation ( 2.41.7 )
1732
decodeFVL(ListT<CegoField> & fvl,char * pc,int len)1733 void CegoQueryHelper::decodeFVL(ListT<CegoField>& fvl, char* pc, int len)
1734 {
1735
1736 char* pBase = pc;
1737
1738 bool eot = false;
1739
1740 CegoField* pF = fvl.First();
1741
1742 while (pF && pc - pBase < len && eot == false)
1743 {
1744 int id;
1745 memcpy(&id, pc, sizeof(int));
1746
1747 if ( id > 0 )
1748 {
1749 pc += sizeof(int);
1750
1751 CegoDataType dt;
1752 memcpy(&dt, pc, sizeof(CegoDataType));
1753
1754 pc += sizeof(CegoDataType);
1755
1756 int flen;
1757
1758 if (dt == VARCHAR_TYPE
1759 || dt == BIGINT_TYPE
1760 || dt == DECIMAL_TYPE
1761 || dt == FIXED_TYPE )
1762 {
1763 memcpy(&flen, pc, sizeof(int));
1764 pc += sizeof(int);
1765 }
1766 else
1767 {
1768 flen = CegoTypeConverter::getTypeLen(dt);
1769 }
1770
1771 if ( id >= pF->getId() )
1772 {
1773 while ( pF && id > pF->getId() )
1774 {
1775 pF->setupNull();
1776 pF=fvl.Next();
1777 }
1778 if ( pF && id == pF->getId() )
1779 {
1780 // CegoFieldValue fv;
1781
1782 pF->setupValue(dt, flen > 0 ? pc : 0, flen);
1783
1784 pF = fvl.Next();
1785 }
1786 }
1787
1788 if ( flen > 0 )
1789 {
1790 pc += flen;
1791 }
1792 }
1793 else
1794 {
1795 eot = true;
1796 }
1797 }
1798
1799 while ( pF )
1800 {
1801 pF->setupNull();
1802 pF=fvl.Next();
1803 }
1804 }
1805
1806 /* field list decoding with included blob decoding. This is used by the recovery manager for redo log recovery */
1807
1808
decodeFVL(ListT<CegoField> & fvl,ListT<CegoBlob> & blobList,ListT<CegoClob> & clobList,char * pc,int len)1809 void CegoQueryHelper::decodeFVL(ListT<CegoField>& fvl, ListT<CegoBlob>& blobList, ListT<CegoClob>& clobList, char* pc, int len)
1810 {
1811 // make sure no field values are set
1812 CegoField* pF = fvl.First();
1813 while ( pF )
1814 {
1815 CegoFieldValue nullValue;
1816 pF->setValue(nullValue);
1817 pF = fvl.Next();
1818 }
1819
1820 char* pBase = pc;
1821
1822 bool eot = false;
1823 while (pc - pBase < len && eot == false )
1824 {
1825 int id;
1826 memcpy(&id, pc, sizeof(int));
1827
1828 if ( id > 0 )
1829 {
1830 pc += sizeof(int);
1831
1832 CegoDataType dt;
1833 memcpy(&dt, pc, sizeof(CegoDataType));
1834 pc += sizeof(CegoDataType);
1835
1836 int flen=0;
1837 unsigned long long blobSize=0;
1838 unsigned long long clobSize=0;
1839
1840 if (dt == VARCHAR_TYPE
1841 || dt == BIGINT_TYPE
1842 || dt == DECIMAL_TYPE
1843 || dt == FIXED_TYPE )
1844 {
1845 memcpy(&flen, pc, sizeof(int));
1846 pc += sizeof(int);
1847 }
1848 else if (dt == BLOB_TYPE )
1849 {
1850 memcpy(&blobSize, pc, sizeof(unsigned long long));
1851 pc += sizeof(unsigned long long);
1852 }
1853 else if (dt == CLOB_TYPE )
1854 {
1855 memcpy(&clobSize, pc, sizeof(unsigned long long));
1856 pc += sizeof(unsigned long long);
1857 }
1858 else
1859 {
1860 flen = CegoTypeConverter::getTypeLen(dt);
1861 }
1862
1863 bool found = false;
1864 CegoField* pF = fvl.First();
1865 while (pF && ! found )
1866 {
1867 if (pF->getId() == id )
1868 {
1869 if ( dt == BLOB_TYPE )
1870 {
1871 // pF->getValue().setType(dt);
1872 // since CegoField::getValue() has changed to const, this must be done vie setValue()
1873 CegoFieldValue fv = pF->getValue();
1874 fv.setType(dt);
1875 pF->setValue(fv);
1876
1877 unsigned char *blobBuf = (unsigned char*)malloc(blobSize);
1878 memcpy(blobBuf, pc, blobSize);
1879 blobList.Insert( CegoBlob(0, blobBuf, blobSize) );
1880 }
1881 else if ( dt == CLOB_TYPE )
1882 {
1883 // pF->getValue().setType(dt);
1884 // since CegoField::getValue() has changed to const, this must be done vie setValue()
1885 CegoFieldValue fv = pF->getValue();
1886 fv.setType(dt);
1887 pF->setValue(fv);
1888
1889 char *clobBuf = (char*)malloc(clobSize);
1890 memcpy(clobBuf, pc, clobSize);
1891 clobList.Insert( CegoClob(0, clobBuf, clobSize) );
1892 }
1893 else
1894 {
1895 CegoFieldValue fv = pF->getValue();
1896 fv.setType(dt);
1897 fv.setLength(flen);
1898 if ( flen > 0)
1899 fv.setValue(pc);
1900 else
1901 fv.setValue(0);
1902 fv.setLocalCopy(false);
1903
1904 pF->setValue(fv);
1905 pF->setId(id);
1906 }
1907 found = true;
1908 }
1909 pF = fvl.Next();
1910 }
1911
1912 if ( blobSize > 0 )
1913 {
1914 pc += blobSize;
1915 }
1916
1917 if ( clobSize > 0 )
1918 {
1919 pc += clobSize;
1920 }
1921
1922 if ( flen > 0 )
1923 {
1924 pc += flen;
1925 }
1926 }
1927 else
1928 {
1929 eot = true;
1930 }
1931 }
1932 }
1933
1934
1935
decodeNativeFVL(ListT<CegoFieldValue> & fvl,ListT<CegoBlob> & blobList,ListT<CegoClob> & clobList,char * pc,int len)1936 void CegoQueryHelper::decodeNativeFVL(ListT<CegoFieldValue>& fvl, ListT<CegoBlob>& blobList, ListT<CegoClob>& clobList, char* pc, int len)
1937 {
1938 char* pBase = pc;
1939
1940 bool eot = false;
1941 while (pc - pBase < len && eot == false)
1942 {
1943 int id;
1944 memcpy(&id, pc, sizeof(int));
1945
1946 if ( id > 0 )
1947 {
1948 pc += sizeof(int);
1949
1950 CegoDataType dt;
1951 memcpy(&dt, pc, sizeof(CegoDataType));
1952
1953 pc += sizeof(CegoDataType);
1954
1955 int flen=0;
1956 unsigned long long blobSize=0;
1957 unsigned long long clobSize=0;
1958
1959 if (dt == VARCHAR_TYPE
1960 || dt == BIGINT_TYPE
1961 || dt == DECIMAL_TYPE
1962 || dt == FIXED_TYPE )
1963 {
1964 memcpy(&flen, pc, sizeof(int));
1965 pc += sizeof(int);
1966 }
1967 else if (dt == BLOB_TYPE )
1968 {
1969 memcpy(&blobSize, pc, sizeof(unsigned long long));
1970 pc += sizeof(unsigned long long);
1971 }
1972 else if (dt == CLOB_TYPE )
1973 {
1974 memcpy(&clobSize, pc, sizeof(unsigned long long));
1975 pc += sizeof(unsigned long long);
1976 }
1977 else
1978 {
1979 flen = CegoTypeConverter::getTypeLen(dt);
1980 }
1981
1982 if ( dt == BLOB_TYPE )
1983 {
1984 CegoFieldValue fv(dt, Chain("[0]"));
1985 unsigned char *blobBuf = (unsigned char*)malloc(blobSize);
1986 memcpy(blobBuf, pc, blobSize);
1987 blobList.Insert( CegoBlob(0, blobBuf, blobSize) );
1988 fvl.Insert(fv);
1989 }
1990 else if ( dt == CLOB_TYPE )
1991 {
1992 CegoFieldValue fv(dt, Chain("[0]"));
1993 char *clobBuf = (char*)malloc(clobSize);
1994 memcpy(clobBuf, pc, clobSize);
1995 clobList.Insert( CegoClob(0, clobBuf, clobSize) );
1996 fvl.Insert(fv);
1997 }
1998 else
1999 {
2000 CegoFieldValue fv(dt, pc, flen);
2001 fvl.Insert(fv);
2002 }
2003
2004 if ( blobSize > 0 )
2005 {
2006 pc += blobSize;
2007 }
2008
2009 if ( clobSize > 0 )
2010 {
2011 pc += clobSize;
2012 }
2013
2014 if ( flen > 0 )
2015 {
2016 pc += flen;
2017 }
2018 }
2019 else
2020 {
2021 eot = true;
2022 }
2023 }
2024 }
2025
encodeUpdRec(const Chain & tableAlias,CegoPredDesc * pPred,const ListT<CegoField> & updList,const ListT<CegoExpr * > & exprList,const ListT<CegoBlob> & blobList,const ListT<CegoClob> & clobList,bool returnOnFirst,CegoProcBlock * pBlock,char * & pBuf,int & buflen)2026 void CegoQueryHelper::encodeUpdRec(const Chain& tableAlias,
2027 CegoPredDesc* pPred,
2028 const ListT<CegoField>& updList,
2029 const ListT<CegoExpr*>& exprList,
2030 const ListT<CegoBlob>& blobList,
2031 const ListT<CegoClob>& clobList,
2032 bool returnOnFirst,
2033 CegoProcBlock* pBlock,
2034 char* &pBuf, int &buflen)
2035 {
2036 char* updBuf;
2037 int updBufLen = 0;
2038 char* predBuf;
2039 int predBufLen = 0;
2040 char* expBuf;
2041 int expBufLen = 0;
2042
2043 if ( pPred )
2044 {
2045 if ( pBlock )
2046 pPred->setBlock(pBlock);
2047 predBufLen = pPred->getEncodingLength() + sizeof(char);
2048 predBuf = (char*)malloc( predBufLen );
2049 char* pP = predBuf;
2050 char c = 1;
2051 memcpy(pP, &c, sizeof(char));
2052 pP = pP + sizeof(char);
2053 pPred->encode(pP);
2054 }
2055 else
2056 {
2057 char c = 0;
2058 predBufLen = sizeof(char);
2059 predBuf = (char*)malloc( predBufLen);
2060 memcpy(predBuf, &c, sizeof(char));
2061 }
2062
2063 encodeFL(updList, updBuf, updBufLen);
2064
2065 expBufLen = 0;
2066 int blobIdx=0;
2067 int clobIdx=0;
2068
2069 CegoExpr **pExpr = exprList.First();
2070 while ( pExpr )
2071 {
2072 (*pExpr)->setBlock(pBlock);
2073
2074 CegoFieldValue fv;
2075 if ( (*pExpr)->checkLob(fv) )
2076 {
2077 if ( fv.getType() == BLOB_TYPE )
2078 {
2079 expBufLen += sizeof(char); // lob indicator
2080 expBufLen += sizeof(unsigned long long); // blobsize
2081 expBufLen += blobList[blobIdx].getSize();
2082 blobIdx++;
2083 }
2084 else if ( fv.getType() == CLOB_TYPE )
2085 {
2086 expBufLen += sizeof(char); // lob indicator
2087 expBufLen += sizeof(unsigned long long); // clobsize
2088 expBufLen += clobList[clobIdx].getSize();
2089 clobIdx++;
2090 }
2091 }
2092 else
2093 {
2094 expBufLen += sizeof(char); // lob indicator
2095 expBufLen += (*pExpr)->getEncodingLength();
2096 }
2097 pExpr = exprList.Next();
2098 }
2099
2100 expBuf = (char*)malloc( expBufLen );
2101 char *pExpBuf = expBuf;
2102
2103 blobIdx=0;
2104 clobIdx=0;
2105
2106 pExpr = exprList.First();
2107 while ( pExpr )
2108 {
2109
2110 (*pExpr)->setBlock(pBlock);
2111
2112 CegoFieldValue fv;
2113 if ( (*pExpr)->checkLob(fv) )
2114 {
2115 if ( fv.getType() == BLOB_TYPE )
2116 {
2117 char isLob=1;
2118 memcpy( pExpBuf, &isLob, sizeof(char));
2119 pExpBuf += sizeof(char);
2120 unsigned long long blobSize = blobList[blobIdx].getSize();
2121 memcpy( pExpBuf, &blobSize, sizeof(unsigned long long));
2122 pExpBuf += sizeof(unsigned long long);
2123 memcpy( pExpBuf, blobList[blobIdx].getBufPtr(), blobList[blobIdx].getSize());
2124 pExpBuf += blobList[blobIdx].getSize();
2125 blobIdx++;
2126 }
2127 else if ( fv.getType() == CLOB_TYPE )
2128 {
2129 char isLob=2;
2130 memcpy( pExpBuf, &isLob, sizeof(char));
2131 pExpBuf += sizeof(char);
2132
2133 unsigned long long clobSize = clobList[clobIdx].getSize();
2134 memcpy( pExpBuf, &clobSize, sizeof(unsigned long long));
2135 pExpBuf += sizeof(unsigned long long);
2136 memcpy( pExpBuf, clobList[clobIdx].getBufPtr(), clobList[clobIdx].getSize());
2137 pExpBuf += clobList[clobIdx].getSize();
2138 clobIdx++;
2139 }
2140 }
2141 else
2142 {
2143 char isLob=0;
2144 memcpy( pExpBuf, &isLob, sizeof(char));
2145 pExpBuf += sizeof(char);
2146
2147 int len = (*pExpr)->getEncodingLength();
2148 (*pExpr)->encode(pExpBuf);
2149 pExpBuf += len;
2150 }
2151
2152 pExpr = exprList.Next();
2153 }
2154
2155 int aliasLen = tableAlias.length();
2156
2157 buflen = predBufLen
2158 + sizeof(int) + aliasLen
2159 + sizeof(int) + updBufLen
2160 + sizeof(int) + expBufLen
2161 + sizeof(bool); // returnOnFirst
2162
2163 pBuf = (char*)malloc(buflen);
2164
2165 char* pBP = pBuf;
2166
2167 memcpy(pBP, &aliasLen, sizeof(int));
2168 pBP = pBP + sizeof(int);
2169
2170 memcpy( pBP, (char*)tableAlias, aliasLen);
2171 pBP = pBP + aliasLen;
2172
2173 memcpy(pBP, predBuf, predBufLen);
2174 pBP = pBP + predBufLen;
2175
2176 memcpy(pBP, &updBufLen, sizeof(int));
2177 pBP = pBP + sizeof(int);
2178
2179 memcpy(pBP, updBuf, updBufLen);
2180 pBP = pBP + updBufLen;
2181
2182 memcpy(pBP, &expBufLen, sizeof(int));
2183 pBP = pBP + sizeof(int);
2184
2185 memcpy(pBP, expBuf, expBufLen);
2186 pBP = pBP + expBufLen;
2187
2188 memcpy(pBP, &returnOnFirst, sizeof(bool));
2189 pBP = pBP + sizeof(bool);
2190
2191 free ( predBuf );
2192 free ( updBuf );
2193 free ( expBuf );
2194 }
2195
decodeUpdRec(Chain & tableAlias,CegoPredDesc * & pPred,ListT<CegoField> & updList,ListT<CegoExpr * > & exprList,bool & returnOnFirst,char * pBuf,int buflen,CegoDistManager * pGTM,int tabSetId)2196 void CegoQueryHelper::decodeUpdRec(Chain& tableAlias,
2197 CegoPredDesc* &pPred,
2198 ListT<CegoField>& updList,
2199 ListT<CegoExpr*>& exprList,
2200 bool& returnOnFirst,
2201 char* pBuf, int buflen,
2202 CegoDistManager *pGTM, int tabSetId)
2203 {
2204
2205 int aliasLen;
2206 memcpy(&aliasLen, pBuf, sizeof(int));
2207 pBuf += sizeof(int);
2208
2209 tableAlias = Chain(pBuf, aliasLen-1);
2210 pBuf += aliasLen;
2211
2212 char c = 0;
2213 memcpy(&c, pBuf, sizeof(char));
2214 pBuf += sizeof(char);
2215
2216 if ( c == 1 )
2217 {
2218 pPred = new CegoPredDesc(pBuf, pGTM, tabSetId);
2219 pBuf += pPred->getEncodingLength();
2220 }
2221 else
2222 {
2223 pPred = 0;
2224 }
2225
2226 int updBufLen;
2227 memcpy(&updBufLen, pBuf, sizeof(int));
2228 pBuf += sizeof(int);
2229
2230 decodeFL(updList, pBuf, updBufLen);
2231
2232 pBuf += updBufLen;
2233
2234 int expBufLen;
2235 memcpy(&expBufLen, pBuf, sizeof(int));
2236 pBuf += sizeof(int);
2237
2238 int pos = 0;
2239 while ( pos < expBufLen )
2240 {
2241 char isLob = 0;
2242 memcpy(&isLob, pBuf, sizeof(char));
2243 pBuf += sizeof(char);
2244 pos += sizeof(char);
2245
2246 if ( isLob == 1 )
2247 {
2248 unsigned long long blobSize;
2249 memcpy(&blobSize, pBuf, sizeof(unsigned long long));
2250
2251 CegoFieldValue fv;
2252
2253 if ( pGTM )
2254 {
2255 pBuf += sizeof(unsigned long long);
2256 PageIdType pageId;
2257 pGTM->putBlobData(tabSetId, (unsigned char*)pBuf, blobSize, pageId);
2258
2259 fv = CegoFieldValue(BLOB_TYPE, Chain("[") + Chain(pageId) + Chain("]"));
2260 }
2261
2262 CegoExpr *pExpr = new CegoExpr(new CegoTerm(new CegoFactor(fv)));
2263
2264 exprList.Insert(pExpr);
2265
2266 int len = sizeof(unsigned long long) + blobSize;
2267 pos += len;
2268 pBuf += len;
2269
2270 }
2271 else if ( isLob == 2 )
2272 {
2273 unsigned long long clobSize;
2274 memcpy(&clobSize, pBuf, sizeof(unsigned long long));
2275
2276 CegoFieldValue fv;
2277
2278 if ( pGTM )
2279 {
2280 pBuf += sizeof(unsigned long long);
2281 PageIdType pageId;
2282 pGTM->putClobData(tabSetId, pBuf, clobSize, pageId);
2283
2284 fv = CegoFieldValue(CLOB_TYPE, Chain("[") + Chain(pageId) + Chain("]"));
2285
2286 }
2287
2288 CegoExpr *pExpr = new CegoExpr(new CegoTerm(new CegoFactor(fv)));
2289
2290 exprList.Insert(pExpr);
2291
2292 int len = sizeof(unsigned long long) + clobSize;
2293 pos += len;
2294 pBuf += len;
2295
2296 }
2297 else
2298 {
2299 CegoExpr *pExpr = new CegoExpr(pBuf, pGTM, tabSetId);
2300
2301 int len = pExpr->getEncodingLength();
2302 pos += len;
2303 pBuf += len;
2304
2305 exprList.Insert(pExpr);
2306 }
2307 }
2308
2309 memcpy(&returnOnFirst, pBuf, sizeof(bool));
2310 }
2311
encodeDelRec(const Chain & tableAlias,CegoPredDesc * pPred,CegoProcBlock * pBlock,char * & pBuf,int & buflen)2312 void CegoQueryHelper::encodeDelRec(const Chain& tableAlias,
2313 CegoPredDesc* pPred,
2314 CegoProcBlock* pBlock,
2315 char* &pBuf, int &buflen)
2316
2317 {
2318 char* predBuf;
2319 int predBufLen = 0;
2320
2321 if ( pPred )
2322 {
2323 if ( pBlock )
2324 {
2325 pPred->setBlock(pBlock);
2326 }
2327 predBufLen = pPred->getEncodingLength() + sizeof(char);
2328 predBuf = (char*)malloc( predBufLen );
2329 char* pP = predBuf;
2330 char c = 1;
2331 memcpy(pP, &c, sizeof(char));
2332 pP = pP + sizeof(char);
2333
2334 pPred->encode(pP);
2335 }
2336 else
2337 {
2338 char c = 0;
2339 predBufLen = sizeof(char);
2340 predBuf = (char*)malloc( predBufLen);
2341 memcpy(predBuf, &c, sizeof(char));
2342 }
2343
2344 int aliasLen = tableAlias.length();
2345
2346 buflen = predBufLen
2347 + sizeof(int) + aliasLen;
2348
2349 pBuf = (char*)malloc(buflen);
2350
2351 char* pBP = pBuf;
2352
2353 memcpy(pBP, &aliasLen, sizeof(int));
2354 pBP = pBP + sizeof(int);
2355
2356 memcpy( pBP, (char*)tableAlias, aliasLen);
2357 pBP = pBP + aliasLen;
2358
2359 memcpy(pBP, predBuf, predBufLen);
2360 pBP = pBP + predBufLen;
2361
2362 free ( predBuf );
2363 }
2364
decodeDelRec(Chain & tableAlias,CegoPredDesc * & pPred,char * pBuf,int buflen,CegoDistManager * pGTM,int tabSetId)2365 void CegoQueryHelper::decodeDelRec(Chain& tableAlias,
2366 CegoPredDesc* &pPred,
2367 char* pBuf, int buflen,
2368 CegoDistManager *pGTM, int tabSetId)
2369 {
2370 int aliasLen;
2371 memcpy(&aliasLen, pBuf, sizeof(int));
2372 pBuf += sizeof(int);
2373
2374 tableAlias = Chain(pBuf, aliasLen-1);
2375 pBuf += aliasLen;
2376
2377 char c = 0;
2378 memcpy(&c, pBuf, sizeof(char));
2379 pBuf += sizeof(char);
2380
2381 if ( c == 1 )
2382 {
2383 pPred = new CegoPredDesc(pBuf, pGTM, tabSetId);
2384 pBuf += pPred->getEncodingLength();
2385 }
2386 else
2387 {
2388 pPred = 0;
2389 }
2390 }
2391
createConjunctionList(CegoPredDesc * pPred,ListT<CegoPredDesc * > & conjunctionList)2392 void CegoQueryHelper::createConjunctionList(CegoPredDesc* pPred, ListT<CegoPredDesc*>& conjunctionList)
2393 {
2394 if (pPred)
2395 {
2396 CegoCondDesc* pC = pPred->getCondition();
2397 if (pC)
2398 {
2399 if (pC->getCondType() == CegoCondDesc::AND)
2400 {
2401 createConjunctionList(pC->Left(), conjunctionList);
2402 createConjunctionList(pC->Right(), conjunctionList);
2403 }
2404 else
2405 {
2406 conjunctionList.Insert(pPred);
2407 }
2408 }
2409 else
2410 {
2411 conjunctionList.Insert(pPred);
2412 }
2413 }
2414 }
2415
string2Clob(CegoFieldValue & fv,CegoTableManager * pTM,int tabSetId)2416 bool CegoQueryHelper::string2Clob(CegoFieldValue& fv, CegoTableManager* pTM, int tabSetId)
2417 {
2418 // cout << "Converting to clob .." << endl;
2419 if ( fv.getType() == VARCHAR_TYPE && pTM )
2420 {
2421 char* clobData = (char*)fv.getValue();
2422 unsigned long long clobSize = fv.getLength() - 1; // we don't take terminating zero byte
2423
2424 PageIdType pageId;
2425 pTM->putClobData(tabSetId, clobData, clobSize, pageId);
2426
2427 fv = CegoFieldValue(CLOB_TYPE, Chain("[") + Chain(pageId) + Chain("]"));
2428
2429 // cout << "Clob is " << fv << endl;
2430 return true;
2431 }
2432 return false;
2433 }
2434
skipComment(Chain & line)2435 Chain CegoQueryHelper::skipComment(Chain& line)
2436 {
2437 Chain result;
2438
2439 int pos=0;
2440
2441 bool stringMode=false;
2442 bool commentFound=false;
2443 while ( pos < line.length() && commentFound == false)
2444 {
2445 if ( line[pos] == '\'' && stringMode == false )
2446 {
2447 stringMode=true;
2448 }
2449 else if ( line[pos] == '\'' && stringMode == true )
2450 {
2451 stringMode=false;
2452 }
2453
2454 if ( pos < line.length() -2 )
2455 {
2456 if ( line[pos] == '-' && line[pos+1] == '-' && stringMode == false)
2457 {
2458 if ( pos > 1 )
2459 {
2460 result = line.subChain(1, pos-1);
2461 }
2462 else
2463 {
2464 result = Chain("");
2465 }
2466 commentFound=true;
2467 }
2468 }
2469 pos++;
2470 }
2471
2472 if ( commentFound )
2473 return result.cutTrailing(" \t");
2474 else
2475 return line.cutTrailing(" \t");
2476
2477 }
2478
2479
mapAliasSchema(ListT<CegoField> & schema,const ListT<CegoAttrAlias> & aliasList)2480 void CegoQueryHelper::mapAliasSchema(ListT<CegoField>& schema, const ListT<CegoAttrAlias>& aliasList)
2481 {
2482 CegoField *pF = schema.First();
2483 while ( pF )
2484 {
2485 CegoAttrAlias *pA = aliasList.Find( CegoAttrAlias(pF->getAttrName()));
2486 if ( pA )
2487 {
2488 // cout << "Found alias " << pA->getAliasName() << endl;
2489 pF->setAttrName( pA->getAttrName());
2490 }
2491 pF = schema.Next();
2492 }
2493 // cout << "Mapping schema size " << schema.Size() << endl;
2494 // cout << " with alias size " << aliasList.Size() << endl;
2495 }
2496
mapAliasPredicate(CegoPredDesc * pPred,const Chain & tableAlias,const ListT<CegoAttrAlias> & aliasList)2497 void CegoQueryHelper::mapAliasPredicate(CegoPredDesc* pPred, const Chain& tableAlias, const ListT<CegoAttrAlias>& aliasList)
2498 {
2499 ListT<CegoAttrDesc*> attrList = pPred->getAttrRefList();
2500 CegoAttrDesc **pAD = attrList.First();
2501 while ( pAD )
2502 {
2503 if ( (*pAD)->getTableName() == tableAlias || (*pAD)->getTableName() == Chain() )
2504 {
2505 CegoAttrAlias *pA = aliasList.Find( CegoAttrAlias( (*pAD)->getAttrName() ) );
2506 if ( pA )
2507 {
2508 (*pAD)->setAttrName( pA->getAttrName() );
2509 }
2510 }
2511 pAD = attrList.Next();
2512 }
2513
2514 // cout << "PredDesc=" << pPred->toChain() << endl;
2515 }
2516
mapAttrCond(const CegoAttrCond & attrCond,CegoAliasObject * pAO)2517 CegoAttrCond CegoQueryHelper::mapAttrCond(const CegoAttrCond& attrCond, CegoAliasObject* pAO)
2518 {
2519 CegoAttrCond mapCond;
2520
2521 CegoAttrComp *pAC = attrCond.getAttrCompSet().First();
2522 while ( pAC )
2523 {
2524 CegoAttrComp mapComp = *pAC;
2525
2526 CegoAttrAlias* pAL = pAO->getAliasList().Find(CegoAttrAlias(pAC->getAttrName()));
2527
2528 if ( pAL )
2529 {
2530 if ( pAC->getTableName() == pAO->getTabAlias()
2531 && pAC->getAttrName() == pAL->getAliasName() )
2532 {
2533 mapComp.setTableName(pAO->getTabName());
2534 mapComp.setAttrName(pAL->getAttrName());
2535 }
2536
2537 // map attribute description 1
2538 if ( pAC->getAttrDesc().getTableName() == pAO->getTabAlias()
2539 && pAC->getAttrDesc().getAttrName() == pAL->getAliasName())
2540 mapComp.setAttrDesc( CegoAttrDesc(pAO->getTabName(), pAC->getAttrName()));
2541
2542 // map attribute description 2
2543 if ( pAC->getAttrDesc2().getTableName() == pAO->getTabAlias()
2544 && pAC->getAttrDesc2().getAttrName() == pAL->getAliasName())
2545 mapComp.setAttrDesc2( CegoAttrDesc(pAO->getTabName(), pAC->getAttrName()));
2546
2547
2548 mapCond.add(mapComp);
2549 }
2550 else
2551 {
2552 throw Exception(EXLOC, Chain("Cannot map from alias attribute ") + pAC->getAttrName());
2553 }
2554 pAC = attrCond.getAttrCompSet().Next();
2555 }
2556 return mapCond;
2557 }
2558
mapFLA(ListT<CegoField> * pFLAmap,ListT<CegoField> ** pFLA,int offset,int size,CegoAliasObject * pAO)2559 void CegoQueryHelper::mapFLA(ListT<CegoField>* pFLAmap, ListT<CegoField>** pFLA, int offset, int size, CegoAliasObject* pAO)
2560 {
2561
2562 pFLAmap->Empty();
2563
2564 CegoField *pF = pFLA[offset]->First();
2565
2566 while ( pF )
2567 {
2568 CegoAttrAlias *pAF = pAO->getAliasList().Find( pF->getAttrName() );
2569
2570 if ( pAF )
2571 {
2572 // cout << "Mapping attribute " << pF->getAttrName() << " to " << pAO->getTabName() << " / " << pAF->getAttrName() << endl;
2573 CegoField f(pAO->getTabName(), pAF->getAttrName());
2574 f.setId(pF->getId());
2575 pFLAmap->Insert(f);
2576 }
2577 else
2578 {
2579 // alias defintion might be a subset of the target table
2580 // throw Exception(EXLOC, Chain("Cannot map to alias attribute ") + pF->getAttrName());
2581 }
2582 pF = pFLA[offset]->Next();
2583 }
2584
2585 }
2586
propFLA(ListT<CegoField> * pFLAmap,ListT<CegoField> ** pFLA,int offset,int size,CegoAliasObject * pAO)2587 void CegoQueryHelper::propFLA(ListT<CegoField>* pFLAmap, ListT<CegoField>** pFLA, int offset, int size, CegoAliasObject* pAO)
2588 {
2589 pFLA[offset]->Empty();
2590
2591 CegoAttrAlias *pAF = pAO->getAliasList().First();
2592
2593 while ( pAF )
2594 {
2595 // cout << "Checking attribute " << pAO->getTabName() << " / " << pAF->getAttrName() << endl;
2596 // cout << "FLA Size = " << pFLA[offset]->Size() << endl;
2597
2598 CegoField *pF = pFLAmap->Find( CegoField(pAO->getTabName(), pAF->getAttrName() ) );
2599
2600 if ( pF )
2601 {
2602 // cout << "Propagating attribute " << pAF->getAttrName() << " to " << pAF->getAliasName() << endl;
2603 CegoField f(pAO->getTabAlias(), pAF->getAliasName());
2604 // cout << "Setting value " << pF->getValue() << endl;
2605 f.setValue( pF->getValue() );
2606 pFLA[offset]->Insert(f);
2607 }
2608 pAF = pAO->getAliasList().Next();
2609 }
2610 }
2611
maxFieldSize(CegoField * pF)2612 int CegoQueryHelper::maxFieldSize(CegoField *pF)
2613 {
2614 int maxLen = 0;
2615
2616 switch ( pF->getType() )
2617 {
2618 case INT_TYPE:
2619 {
2620 maxLen = max(pF->getAttrName().length(),
2621 pF->getTableAlias().length(),
2622 pF->getTableName().length(),
2623 MAX_INT_LEN);
2624 break;
2625 }
2626 case LONG_TYPE:
2627 {
2628 maxLen = max(pF->getAttrName().length(),
2629 pF->getTableAlias().length(),
2630 pF->getTableName().length(),
2631 MAX_LONG_LEN);
2632 break;
2633 }
2634 case VARCHAR_TYPE:
2635 {
2636 maxLen = max(pF->getAttrName().length(),
2637 pF->getTableAlias().length(),
2638 pF->getTableName().length(),
2639 pF->getLength());
2640 break;
2641 }
2642 case BOOL_TYPE:
2643 {
2644 maxLen = max(pF->getAttrName().length(),
2645 pF->getTableAlias().length(),
2646 pF->getTableName().length(),
2647 MAX_BOOL_LEN);
2648 break;
2649 }
2650 case DATETIME_TYPE:
2651 {
2652 maxLen = max(pF->getAttrName().length(),
2653 pF->getTableAlias().length(),
2654 pF->getTableName().length(),
2655 MAX_DATETIME_LEN);
2656 break;
2657 }
2658 case FLOAT_TYPE:
2659 {
2660 maxLen = max(pF->getAttrName().length(),
2661 pF->getTableAlias().length(),
2662 pF->getTableName().length(),
2663 MAX_FLOAT_LEN);
2664 break;
2665 }
2666 case DOUBLE_TYPE:
2667 {
2668 maxLen = max(pF->getAttrName().length(),
2669 pF->getTableAlias().length(),
2670 pF->getTableName().length(),
2671 MAX_DOUBLE_LEN);
2672 break;
2673 }
2674 case BIGINT_TYPE:
2675 {
2676 maxLen = max(pF->getAttrName().length(),
2677 pF->getTableAlias().length(),
2678 pF->getTableName().length(),
2679 pF->getLength());
2680 break;
2681 }
2682 case DECIMAL_TYPE:
2683 {
2684 maxLen = max(pF->getAttrName().length(),
2685 pF->getTableAlias().length(),
2686 pF->getTableName().length(),
2687 pF->getLength());
2688 break;
2689 }
2690 case SMALLINT_TYPE:
2691 {
2692 maxLen = max(pF->getAttrName().length(),
2693 pF->getTableAlias().length(),
2694 pF->getTableName().length(),
2695 MAX_SMALLINT_LEN);
2696 break;
2697 }
2698 case TINYINT_TYPE:
2699 {
2700 maxLen = max(pF->getAttrName().length(),
2701 pF->getTableAlias().length(),
2702 pF->getTableName().length(),
2703 MAX_TINYINT_LEN);
2704 break;
2705 }
2706 case FIXED_TYPE:
2707 {
2708 maxLen = max(pF->getAttrName().length(),
2709 pF->getTableAlias().length(),
2710 pF->getTableName().length(),
2711 pF->getLength());
2712 break;
2713 }
2714 case BLOB_TYPE:
2715 case CLOB_TYPE:
2716 {
2717 maxLen = max(pF->getAttrName().length(),
2718 pF->getTableAlias().length(),
2719 pF->getTableName().length(),
2720 MAX_BLOB_LEN);
2721 break;
2722 }
2723 case NULL_TYPE:
2724 {
2725 maxLen = max(pF->getAttrName().length(),
2726 pF->getTableAlias().length(),
2727 pF->getTableName().length(),
2728 MAX_NULL_LEN);
2729 break;
2730
2731 }
2732 case PAGEID_TYPE:
2733 {
2734 throw Exception(EXLOC, Chain("Cannot handle pageid type"));
2735 }
2736 default:
2737 {
2738 throw Exception(EXLOC, Chain("Unknown datatype ") + Chain(pF->getType()));
2739 }
2740 }
2741 return maxLen;
2742 }
2743
max(int i1,int i2,int i3,int i4)2744 int CegoQueryHelper::max(int i1, int i2, int i3, int i4)
2745 {
2746 int c1 = i1 < i2 ? i2 : i1 ;
2747 int c2 = i3 < i4 ? i4 : i3 ;
2748 return c1 < c2 ? c2 : c1 ;
2749 }
2750
2751