1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // CegoAttrCond.cc
4 // ---------------
5 // Cego database table field implementation
6 //
7 // Design and Implementation by Bjoern Lemke
8 //
9 // (C)opyright 2000-2019 Bjoern Lemke
10 //
11 // IMPLEMENTATION MODULE
12 //
13 // Class: CegoAttrCond
14 //
15 // Description: Attribute condition description used for index cursors
16 //
17 // Status: CLEAN
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20
21 // CEGO INCLUDES
22 #include "CegoAttrCond.h"
23
24 // POSIX INCLUDES
25 #include <stdlib.h>
26 #include <string.h>
27
CegoAttrCond()28 CegoAttrCond::CegoAttrCond()
29 {
30 }
31
~CegoAttrCond()32 CegoAttrCond::~CegoAttrCond()
33 {
34 }
35
getId() const36 Chain CegoAttrCond::getId() const
37 {
38 Chain s;
39
40 CegoAttrComp *pAC = _attrCompSet.First();
41 while ( pAC )
42 {
43 s += pAC->getId();
44 pAC = _attrCompSet.Next();
45 if ( pAC )
46 s += Chain("&");
47 }
48 return s;
49 }
50
add(const CegoAttrComp & attrComp)51 void CegoAttrCond::add(const CegoAttrComp& attrComp)
52 {
53 CegoAttrComp *pAC;
54 if ( (pAC = _attrCompSet.Find(attrComp)) == 0 )
55 {
56 _attrCompSet.Insert(attrComp);
57 }
58 /*
59 else
60 {
61
62 cout << "Adding " << attrComp << " failed, already exists " << *pAC << endl;
63 cout << "T1 = " << attrComp.getTableName() << endl;
64 cout << "T2 = " << pAC->getTableName() << endl;
65
66 }
67 */
68 }
69
numComp() const70 int CegoAttrCond::numComp() const
71 {
72 return _attrCompSet.Size();
73 }
74
getStrength() const75 int CegoAttrCond::getStrength() const
76 {
77 CegoAttrComp *pAC = _attrCompSet.First();
78 if ( pAC )
79 {
80 if ( pAC->getCompMode() == CegoAttrComp::BTWN )
81 return 4;
82 switch ( pAC->getComparison() )
83 {
84 case EQUAL:
85 return 5;
86 case NOT_EQUAL:
87 return 1;
88 case LESS_THAN:
89 return 3;
90 case MORE_THAN:
91 return 3;
92 case LESS_EQUAL_THAN:
93 return 2;
94 case MORE_EQUAL_THAN:
95 return 2;
96 }
97 }
98 return 0;
99 }
100
getAttrCompSet() const101 const TreeT<CegoAttrComp>& CegoAttrCond::getAttrCompSet() const
102 {
103 return _attrCompSet;
104 }
105
getFilterCond(const ListT<CegoField> & fl,bool ignoreNullComp) const106 CegoAttrCond CegoAttrCond::getFilterCond(const ListT<CegoField>& fl, bool ignoreNullComp) const
107 {
108 CegoAttrCond ac;
109
110 CegoField *pF = fl.First();
111 while ( pF)
112 {
113 CegoAttrComp *pAC = _attrCompSet.First();
114 while ( pAC )
115 {
116 if ( pF->getTableAlias() == pAC->getTableName() && pF->getAttrName() == pAC->getAttrName() )
117 {
118 if ( ! ( ignoreNullComp && pAC->isNullComp() ) )
119 ac.add(*pAC);
120 /*
121 else
122 cout << "Ignoring comp " << *pAC << endl;
123 */
124 }
125 pAC = _attrCompSet.Next();
126 }
127
128 pF = fl.Next();
129 }
130 return ac;
131 }
132
getIndexCond(const ListT<CegoField> & fl) const133 CegoAttrCond CegoAttrCond::getIndexCond(const ListT<CegoField>& fl) const
134 {
135 CegoAttrCond ac;
136
137 int pos = 0;
138 CegoField *pF = fl.First();
139
140 while ( pF )
141 {
142 CegoAttrComp *pAC = _attrCompSet.First();
143 while ( pAC )
144 {
145 if ( pF->getAttrName() == pAC->getAttrName()
146 && ( pAC->getCompMode() == CegoAttrComp::VAL
147 || pAC->getCompMode() == CegoAttrComp::ATTR
148 || pAC->getCompMode() == CegoAttrComp::BTWN ) )
149 {
150 pAC->setPos(pos);
151 ac.add(*pAC);
152 }
153 pAC = _attrCompSet.Next();
154 }
155 pF = fl.Next();
156 pos++;
157 }
158
159 return ac;
160 }
161
setup(const ListT<CegoField> & fl)162 bool CegoAttrCond::setup(const ListT<CegoField>& fl)
163 {
164 CegoAttrComp *pAC = _attrCompSet.First();
165 while ( pAC )
166 {
167 if ( pAC->getCompMode() == CegoAttrComp::ATTR )
168 if ( pAC->setup(fl) == false )
169 return false;
170 pAC = _attrCompSet.Next();
171 }
172 return true;
173 }
174
setup(ListT<CegoField> ** pJoinBuf,int offset)175 bool CegoAttrCond::setup(ListT<CegoField>** pJoinBuf, int offset)
176 {
177
178 CegoAttrComp *pAC = _attrCompSet.First();
179 while ( pAC )
180 {
181 pAC->reset();
182 if ( pAC->getCompMode() == CegoAttrComp::ATTR || pAC->getCompMode() == CegoAttrComp::BTWN )
183 {
184 if ( pAC->setup(pJoinBuf, offset) == false )
185 {
186 return false;
187 }
188
189 }
190 pAC = _attrCompSet.Next();
191 }
192 return true;
193 }
194
setup(ListT<CegoField> ** pParentJoinBuf,int parentOffset,ListT<CegoField> ** pJoinBuf,int offset)195 bool CegoAttrCond::setup(ListT<CegoField>** pParentJoinBuf, int parentOffset, ListT<CegoField>** pJoinBuf, int offset)
196 {
197
198 CegoAttrComp *pAC = _attrCompSet.First();
199 while ( pAC )
200 {
201 pAC->reset();
202 if ( pAC->getCompMode() == CegoAttrComp::ATTR || pAC->getCompMode() == CegoAttrComp::BTWN )
203 {
204 if ( pAC->isParentSetup() )
205 {
206 if ( pAC->setup(pParentJoinBuf, parentOffset) == false )
207 {
208 return false;
209 }
210 }
211 else
212 {
213 if ( pAC->setup(pJoinBuf, offset) == false )
214 {
215 if ( pParentJoinBuf )
216 {
217 if ( pAC->setup(pParentJoinBuf, parentOffset) == false )
218 {
219 return false;
220 }
221 else
222 {
223 pAC->setParentSetup();
224 }
225 }
226 else
227 {
228 return false;
229 }
230 }
231 }
232 }
233
234 pAC = _attrCompSet.Next();
235 }
236
237 return true;
238 }
239
asConjunctionList(const ListT<CegoExpr * > & exprList,ListT<CegoPredDesc * > & conjunctionList,ListT<CegoField> ** pFLA) const240 void CegoAttrCond::asConjunctionList(const ListT<CegoExpr*>& exprList, ListT<CegoPredDesc*>& conjunctionList, ListT<CegoField>** pFLA) const
241 {
242 CegoAttrComp *pAC = _attrCompSet.First();
243 while ( pAC )
244 {
245 CegoPredDesc *pP;
246
247 CegoExpr *pExpr = getExpressionForAlias(exprList, pAC->getAttrName() );
248
249 if ( pExpr == 0 )
250 {
251 pExpr = new CegoExpr(new CegoTerm(new CegoFactor( new CegoAttrDesc(pAC->getAttrName()))));
252 pExpr->setExternalFieldListArray(pFLA);
253 }
254
255 if ( pAC->getCompMode() == CegoAttrComp::ATTR && pAC->isSetup() == false )
256 {
257 CegoExpr* pExternExpr = new CegoExpr(new CegoTerm(new CegoFactor( pAC->getAttrDesc().clone())));
258 pExternExpr->setExternalFieldListArray(pFLA);
259 pP = new CegoPredDesc(pExpr,
260 pExternExpr,
261 pAC->getComparison());
262
263 }
264 else if ( pAC->getCompMode() == CegoAttrComp::VAL ||
265 ( pAC->getCompMode() == CegoAttrComp::ATTR && pAC->isSetup() ) )
266 {
267 pP = new CegoPredDesc(pExpr,
268 new CegoExpr(new CegoTerm(new CegoFactor( pAC->getFieldValue()))),
269 pAC->getComparison());
270 }
271 else if ( pAC->getCompMode() == CegoAttrComp::BTWN )
272 {
273 pP = new CegoPredDesc(pExpr,
274 new CegoExpr(new CegoTerm(new CegoFactor( pAC->getFieldValue()))),
275 new CegoExpr(new CegoTerm(new CegoFactor( pAC->getFieldValue2()))));
276 }
277 else if ( pAC->getCompMode() == CegoAttrComp::ISLIKE )
278 {
279 pP = new CegoPredDesc(pExpr,
280 pAC->getPattern(),
281 false);
282 }
283 else if ( pAC->getCompMode() == CegoAttrComp::ISNOTLIKE )
284 {
285 pP = new CegoPredDesc(pExpr,
286 pAC->getPattern(),
287 true);
288 }
289
290 conjunctionList.Insert(pP);
291
292 pAC = _attrCompSet.Next();
293 }
294 }
295
getExpressionForAlias(const ListT<CegoExpr * > & exprList,const Chain & alias) const296 CegoExpr* CegoAttrCond::getExpressionForAlias(const ListT<CegoExpr*>& exprList, const Chain& alias) const
297 {
298 CegoExpr **pExpr = exprList.First();
299 while ( pExpr )
300 {
301 if ( (*pExpr)->getAlias() == alias )
302 return (*pExpr)->clone();
303 pExpr = exprList.Next();
304 }
305 return 0;
306 }
307
checkIndex(const ListT<CegoField> & schema) const308 CegoAttrCond::IndexMatch CegoAttrCond::checkIndex(const ListT<CegoField>& schema) const
309 {
310 int numFound=0;
311
312 bool hasLeak=false;
313 CegoField *pF = schema.First();
314
315 while ( pF && hasLeak == false )
316 {
317 bool isFound=false;
318 CegoAttrComp *pComp = _attrCompSet.First();
319 while ( pComp )
320 {
321 if ( pComp->getAttrName() == pF->getAttrName()
322 && ( pComp->getCompMode() == CegoAttrComp::VAL
323 || pComp->getCompMode() == CegoAttrComp::ATTR
324 || pComp->getCompMode() == CegoAttrComp::BTWN ) )
325 {
326 numFound++;
327 isFound=true;
328 pComp = _attrCompSet.Next();
329 }
330 else
331 {
332 pComp = _attrCompSet.Next();
333 }
334 }
335
336 if ( isFound == true )
337 hasLeak=false;
338 else
339 hasLeak=true;
340
341 pF = schema.Next();
342 }
343
344 if ( numFound == _attrCompSet.Size() )
345 return FULL;
346
347 if ( numFound < _attrCompSet.Size() && numFound > 0 )
348 return PART;
349
350 return INAPP;
351 }
352
setIdxSchema(ListT<CegoField> & schema)353 void CegoAttrCond::setIdxSchema(ListT<CegoField>& schema)
354 {
355 _idxSchema = schema;
356 }
357
setPrimaryComparison(CegoComparison comp)358 void CegoAttrCond::setPrimaryComparison(CegoComparison comp)
359 {
360 CegoAttrComp* pAC = _attrCompSet.First();
361 if ( pAC )
362 {
363 pAC->setComparison(comp);
364 }
365 else
366 {
367 throw Exception(EXLOC, "Cannot set primary comparison");
368 }
369 }
370
getPrimaryCompMode() const371 CegoAttrComp::CompMode CegoAttrCond::getPrimaryCompMode() const
372 {
373 CegoAttrComp* pAC = _attrCompSet.First();
374 if ( pAC )
375 {
376 return pAC->getCompMode();
377 }
378 else
379 {
380 throw Exception(EXLOC, "Cannot get primary comp mode");
381 }
382 }
383
getPrimaryComparison() const384 CegoComparison CegoAttrCond::getPrimaryComparison() const
385 {
386 CegoAttrComp* pAC = _attrCompSet.First();
387 if ( pAC )
388 {
389 return pAC->getComparison();
390 }
391 else
392 {
393 throw Exception(EXLOC, "Cannot get primary comparison");
394 }
395 }
396
diff(const CegoAttrCond & ac) const397 bool CegoAttrCond::diff( const CegoAttrCond& ac) const
398 {
399 if ( ac._attrCompSet.Size() != _attrCompSet.Size() )
400 return false;
401
402 CegoAttrComp* pAC = ac._attrCompSet.First();
403 while ( pAC )
404 {
405 CegoAttrComp* pAC2 = findComp(pAC);
406 if ( pAC2 )
407 {
408 if ( pAC->getFieldValue() != pAC2->getFieldValue() )
409 return false;
410 }
411 else
412 {
413 return false;
414 }
415 pAC = ac._attrCompSet.Next();
416 }
417
418 pAC = _attrCompSet.First();
419 while ( pAC )
420 {
421 CegoAttrComp* pAC2 = ac.findComp(pAC);
422 if ( pAC2 )
423 {
424 if ( pAC->getFieldValue() != pAC2->getFieldValue() )
425 return false;
426 }
427 else
428 {
429 return false;
430 }
431 pAC = _attrCompSet.Next();
432 }
433 return true;
434 }
435
findComp(CegoAttrComp * pAttrComp) const436 CegoAttrComp* CegoAttrCond::findComp(CegoAttrComp* pAttrComp) const
437 {
438 // for searching attribute comparison, we use a dedicated loop, since for TreeT, just < and > operators are used.
439 // for comparison we have to use the = operator
440
441 CegoAttrComp* pAC = _attrCompSet.First();
442 while ( pAC )
443 {
444 if ( *pAC == *pAttrComp )
445 return pAC;
446 pAC = _attrCompSet.Next();
447 }
448 return 0;
449 }
450
update(const CegoAttrCond & ac)451 void CegoAttrCond::update( const CegoAttrCond& ac )
452 {
453 CegoAttrComp* pAC = _attrCompSet.First();
454 while ( pAC )
455 {
456 CegoAttrComp* pAC2 = ac.findComp(pAC);
457 if ( pAC2 )
458 {
459 pAC->setFieldValue(pAC2->getFieldValue());
460 if ( pAC->getCompMode() == CegoAttrComp::BTWN )
461 pAC->setFieldValue2(pAC2->getFieldValue2());
462 }
463 else
464 {
465 throw Exception(EXLOC, Chain("Cannot set up diff for attribute condition"));
466 }
467 pAC = _attrCompSet.Next();
468 }
469 }
470
operator =(const CegoAttrCond & ac)471 CegoAttrCond& CegoAttrCond::operator = ( const CegoAttrCond& ac)
472 {
473 _idxSchema = ac._idxSchema;
474 _attrCompSet = ac._attrCompSet;
475 return (*this);
476 }
477
operator ==(const CegoAttrCond & ac) const478 bool CegoAttrCond::operator == ( const CegoAttrCond& ac) const
479 {
480 if ( ac._attrCompSet.Size() != _attrCompSet.Size() )
481 return false;
482
483 CegoAttrComp* pAC = ac._attrCompSet.First();
484 while ( pAC )
485 {
486 if ( findComp(pAC) == 0 )
487 return false;
488 pAC = ac._attrCompSet.Next();
489 }
490
491 pAC = _attrCompSet.First();
492 while ( pAC )
493 {
494 if ( ac.findComp(pAC) == 0 )
495 return false;
496 pAC = _attrCompSet.Next();
497 }
498 return true;
499 }
500
operator !=(const CegoAttrCond & ac) const501 bool CegoAttrCond::operator != ( const CegoAttrCond& ac) const
502 {
503 if ( *this == ac )
504 return false;
505 return true;
506 }
507
operator +(const CegoAttrCond & ac1,const CegoAttrCond & ac2)508 CegoAttrCond operator + ( const CegoAttrCond& ac1, const CegoAttrCond& ac2 )
509 {
510 CegoAttrCond ac;
511 CegoAttrComp *pComp;
512 pComp = ac1._attrCompSet.First();
513 while ( pComp )
514 {
515 ac.add(*pComp);
516 pComp = ac1._attrCompSet.Next();
517 }
518 pComp = ac2._attrCompSet.First();
519 while ( pComp )
520 {
521 ac.add(*pComp);
522 pComp = ac2._attrCompSet.Next();
523 }
524 return ac;
525 }
526
toChain() const527 Chain CegoAttrCond::toChain() const
528 {
529 Chain s;
530
531 CegoAttrComp *pAC = _attrCompSet.First();
532 while ( pAC )
533 {
534 s += pAC->toChain();
535 pAC = _attrCompSet.Next();
536 if ( pAC )
537 s += Chain(" and ");
538 }
539 return s;
540 }
541
operator <<(ostream & s,const CegoAttrCond & ac)542 ostream& operator << (ostream& s, const CegoAttrCond& ac)
543 {
544 s << ac.toChain();
545 return s;
546 }
547