(file) Return to Cql2Dnf.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / CQL

  1 karl  1.8 //%2005////////////////////////////////////////////////////////////////////////
  2 chuck 1.2 //
  3 karl  1.8 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 chuck 1.2 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.8 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9           // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 chuck 1.2 //
 12           // Permission is hereby granted, free of charge, to any person obtaining a copy
 13           // of this software and associated documentation files (the "Software"), to
 14           // deal in the Software without restriction, including without limitation the
 15           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 16           // sell copies of the Software, and to permit persons to whom the Software is
 17           // furnished to do so, subject to the following conditions:
 18 karl  1.8 // 
 19 chuck 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 20           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 21           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 22           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 23           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 24           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 25           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 26           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27           //
 28           //==============================================================================
 29           //
 30           // Author:      Markus Mueller (sedgewick_de@yahoo.de)
 31           //
 32 humberto 1.3 // Modified By: Humberto Rivero (hurivero@us.ibm.com)
 33 chuck    1.2 //
 34              //%/////////////////////////////////////////////////////////////////////////////
 35              
 36              
 37              #include "Cql2Dnf.h"
 38              #include <Pegasus/Common/Stack.h>
 39 humberto 1.5 #include <Pegasus/Common/Tracer.h>
 40 chuck    1.2 
 41              PEGASUS_USING_STD;
 42              PEGASUS_NAMESPACE_BEGIN
 43              
 44              #define PEGASUS_ARRAY_T term_el
 45              # include <Pegasus/Common/ArrayImpl.h>
 46              #undef PEGASUS_ARRAY_T
 47              
 48              #define PEGASUS_ARRAY_T eval_el
 49              # include <Pegasus/Common/ArrayImpl.h>
 50              #undef PEGASUS_ARRAY_T
 51              
 52              #define PEGASUS_ARRAY_T stack_el
 53              # include <Pegasus/Common/ArrayImpl.h>
 54              #undef PEGASUS_ARRAY_T
 55              
 56              //
 57              // Terminal element methods 
 58              //
 59 humberto 1.6 
 60 chuck    1.2 void term_el::negate()
 61              {
 62 humberto 1.6    NOT = true;
 63 chuck    1.2 };
 64 humberto 1.3 
 65 chuck    1.2 //
 66              // Evaluation heap element methods
 67              //
 68              stack_el eval_el::getFirst() 
 69              { 
 70                 return stack_el(opn1, is_terminal1);
 71              }
 72              
 73              stack_el eval_el::getSecond()
 74              {
 75                 return stack_el(opn2, is_terminal2);
 76              }
 77              
 78              void eval_el::setFirst(const stack_el s)
 79              {
 80                   opn1 = s.opn;
 81                   is_terminal1 = s.is_terminal;
 82              }
 83              
 84              void eval_el::setSecond(const stack_el s)
 85              {
 86 chuck    1.2     opn2 = s.opn;
 87                  is_terminal2 = s.is_terminal;
 88              }
 89              
 90              void eval_el::assign_unary_to_first(const eval_el & assignee)
 91              {
 92                  opn1 = assignee.opn1;
 93                  is_terminal1 = assignee.is_terminal1;
 94              }
 95              
 96              void eval_el::assign_unary_to_second(const eval_el & assignee)
 97              {
 98                  opn2 = assignee.opn1;
 99                  is_terminal2 = assignee.is_terminal1;
100              }
101              
102              // Ordering operators, so that op1 > op2 for all non-terminals
103              // and terminals appear in the second operand first
104              void eval_el::order(void)
105              {
106                  int k;
107 chuck    1.2     if ((!is_terminal1) && (!is_terminal2))
108                      if ((k = opn2) > opn1)
109                      {
110                          opn2 = opn1;
111                          opn1 =  k;
112                      }
113                  else if ((is_terminal1) && (!is_terminal2))
114                      if ((k = opn2) > opn1)
115                      {
116                          opn2 = opn1;
117                          opn1 =  k;
118                          is_terminal1 = false;
119                          is_terminal2 = true;
120                      }
121              }
122 humberto 1.6 /*
123 chuck    1.2 static bool operator==(const term_el& x, const term_el& y)
124              {
125              	return x._simplePredicate == y._simplePredicate; 
126              }
127 humberto 1.6 */
128 chuck    1.2 //
129              // CQL Compiler methods
130              //
131 humberto 1.5 /*    
132 chuck    1.2 Cql2Dnf::Cql2Dnf() 
133              {
134                  eval_heap.reserveCapacity(16);
135                  terminal_heap.reserveCapacity(16);
136              }
137              
138              Cql2Dnf::Cql2Dnf(CQLSelectStatement & cqs)
139              {
140                  eval_heap.reserveCapacity(16);
141                  terminal_heap.reserveCapacity(16);
142                  compile(&cqs);
143              }
144              
145              Cql2Dnf::Cql2Dnf(CQLSelectStatement * cqs)
146              {
147                  eval_heap.reserveCapacity(16);
148                  terminal_heap.reserveCapacity(16);
149                  compile(cqs);
150              }
151 humberto 1.5 */
152 chuck    1.2 Cql2Dnf::Cql2Dnf(CQLPredicate& topLevel){
153                  eval_heap.reserveCapacity(16);
154                  terminal_heap.reserveCapacity(16);
155                  compile(topLevel);
156              }
157              
158              Cql2Dnf::~Cql2Dnf() {}
159 humberto 1.5 /*
160 chuck    1.2 void Cql2Dnf::compile(CQLSelectStatement * cqs){
161              	CQLPredicate topLevel = cqs->getPredicate();
162              	compile(topLevel);
163              }
164 humberto 1.5 */
165 chuck    1.2 void Cql2Dnf::compile(CQLPredicate& topLevel)
166              {
167 humberto 1.5 	PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::compile");
168              
169 chuck    1.2     _strip_ops_operands(topLevel);
170                  _buildEvalHeap();
171                  _pushNOTDown();
172                  _factoring();
173 humberto 1.3     _construct();
174 chuck    1.2     eval_heap.clear();
175 humberto 1.5 
176              	PEG_METHOD_EXIT();
177 chuck    1.2 }
178              
179              void Cql2Dnf::_buildEvalHeap()
180              {
181 humberto 1.5 	PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_buildEvalHeap");
182              
183 chuck    1.2     Stack<stack_el> stack;
184              
185                  // Counter for Operands
186                  Uint32 j = 0;
187              
188                  for (Uint32 i = 0, n = _operations.size(); i < n; i++)
189                  {
190                      OperationType op = _operations[i];
191              
192                      switch (op)
193                      {
194                          case CQL_OR:
195                          case CQL_AND:
196                          {
197                              PEGASUS_ASSERT(stack.size() >= 2);
198              
199                              stack_el op1 = stack.top();
200                              stack.pop();
201              
202                              stack_el op2 = stack.top();
203              
204 chuck    1.2                 // generate Eval expression
205                              eval_heap.append(eval_el(0, op , op1.opn, op1.is_terminal,
206                                               op2.opn , op2.is_terminal));
207              
208                              stack.top() = stack_el(eval_heap.size()-1, false);
209              
210                              break;
211                          }
212              
213                          case CQL_NOT:
214                          {
215                              PEGASUS_ASSERT(stack.size() >= 1);
216              
217                              stack_el op1 = stack.top();
218              
219                              // generate Eval expression
220                              eval_heap.append(eval_el(0, op , op1.opn, op1.is_terminal,
221                                               -1, true));
222              
223                              stack.top() = stack_el(eval_heap.size()-1, false);
224              
225 chuck    1.2                 break;
226                          }
227              
228                          case CQL_EQ: 
229                          case CQL_NE:
230                          case CQL_LT:
231                          case CQL_LE:
232                          case CQL_GT:
233                          case CQL_GE:
234 humberto 1.6 				case CQL_ISA:
235              				case CQL_LIKE:
236 chuck    1.2             {
237                              PEGASUS_ASSERT(_operands.size() >= 2);
238              
239                              CQLExpression lhs = _operands[j++];
240              
241                              CQLExpression rhs = _operands[j++];
242              
243              		CQLSimplePredicate sp(lhs,rhs,_convertOpType(op));
244                              terminal_heap.push(term_el(false, sp));
245              
246                              stack.push(stack_el(terminal_heap.size()-1, true));
247              
248                              break;
249                          }
250 humberto 1.3 
251 chuck    1.2             case CQL_IS_NULL:
252                          {
253                              PEGASUS_ASSERT(_operands.size() >= 1);
254                              CQLExpression expression = _operands[j++];
255 humberto 1.6 		CQLSimplePredicate dummy(expression,IS_NULL);
256 chuck    1.2                 terminal_heap.push(term_el(false, dummy));
257              
258                              stack.push(stack_el(terminal_heap.size()-1, true));
259              
260                              break;
261                          }
262              
263                          case CQL_IS_NOT_NULL:
264                          {
265                              PEGASUS_ASSERT(_operands.size() >= 1);
266                              CQLExpression expression = _operands[j++];
267 humberto 1.6                 CQLSimplePredicate dummy(expression,IS_NOT_NULL);
268 chuck    1.2                 terminal_heap.push(term_el(false, dummy));
269              
270                              stack.push(stack_el(terminal_heap.size()-1, true));
271              
272                              break;
273                          }
274              	    case CQL_NOOP:
275              	    default: break;
276                      }
277                  }
278              
279                  PEGASUS_ASSERT(stack.size() == 1);
280 humberto 1.5 
281                  PEG_METHOD_EXIT();
282 chuck    1.2 }
283              
284              void Cql2Dnf::_pushNOTDown()
285              {
286 humberto 1.5     PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_pushNOTDown");
287              
288 chuck    1.2     for (int i=eval_heap.size()-1; i >= 0; i--)
289                  {
290                      Boolean _found = false;
291              
292                      // Order all operators, so that op1 > op2 for non-terminals
293                      // and terminals appear as second operand
294              
295                      eval_heap[i].order();
296              
297                      // First solve the unary NOT operator
298              
299                      if (eval_heap[i].op == CQL_NOT)
300                     {
301                          // This serves as the equivalent of an empty operator
302                          eval_heap[i].op = CQL_NOOP;
303              
304                          // Substitute this expression in all higher order eval statements
305                          // so that this node becomes disconnected from the tree
306              
307                          for (int j=eval_heap.size()-1; j > i;j--)
308                          {
309 chuck    1.2                // Test first operand
310                             if ((!eval_heap[j].is_terminal1) && (eval_heap[j].opn1 == i))
311              
312                                 eval_heap[j].assign_unary_to_first(eval_heap[i]);
313              
314                             // Test second operand
315                             if ((!eval_heap[j].is_terminal2) && (eval_heap[j].opn2 == i))
316              
317                                 eval_heap[j].assign_unary_to_second(eval_heap[i]);
318                          }
319              
320                          // Test: Double NOT created by moving down
321              
322                          if (eval_heap[i].mark)
323                             eval_heap[i].mark = false;
324                          else
325                             _found = true;
326                          // else indicate a pending NOT to be pushed down further
327                      }
328              
329                      // Simple NOT created by moving down
330 chuck    1.2 
331                      if (eval_heap[i].mark)
332                      {
333                          // Remove the mark, indicate a pending NOT to be pushed down
334                          // further and switch operators (AND / OR)
335              
336                          eval_heap[i].mark=false;
337                          if (eval_heap[i].op == CQL_OR) eval_heap[i].op = CQL_AND;
338                          else if (eval_heap[i].op == CQL_AND) eval_heap[i].op = CQL_OR;
339              
340                          // NOT operator is already ruled out
341                          _found = true;
342                      }
343              
344                      // Push a pending NOT further down
345                      if (_found)
346                      {
347                           // First operand
348              
349                           int j = eval_heap[i].opn1;
350                           if (eval_heap[i].is_terminal1)
351 chuck    1.2                  // Flip NOT mark
352                               terminal_heap[j].negate();
353                           else
354                               eval_heap[j].mark = !(eval_heap[j].mark);
355              
356                           //Second operand (if it exists)
357              
358                           if ((j = eval_heap[i].opn2) >= 0)
359                           {
360                               if (eval_heap[i].is_terminal2)
361                                   // Flip NOT mark
362                                   terminal_heap[j].negate();
363                               else
364                                   eval_heap[j].mark = !(eval_heap[j].mark);
365                           }
366                      }
367                  }
368 humberto 1.5 	PEG_METHOD_EXIT();
369 chuck    1.2 }
370              
371              void Cql2Dnf::_factoring(void)
372              {
373 humberto 1.5 	PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_factoring");
374              
375 chuck    1.2     int i = 0,n = eval_heap.size();
376                  //for (int i=eval_heap.size()-1; i >= 0; i--)
377                  while (i < n)
378                  {
379                      int _found = 0;
380                      int index = 0;
381              
382                      // look for expressions (A | B) & C  ---> A & C | A & B
383                      if (eval_heap[i].op == CQL_AND)
384                      {
385                          if (!eval_heap[i].is_terminal1)
386                          {
387                              index = eval_heap[i].opn1; // remember the index
388                              if (eval_heap[index].op == CQL_OR) _found = 1;
389                          }
390              
391                          if ((_found == 0) && (!eval_heap[i].is_terminal2))
392                          {
393                              index = eval_heap[i].opn2; // remember the index
394                              if (eval_heap[index].op == CQL_OR) _found = 2;
395                          }
396 chuck    1.2 
397                          if (_found != 0)
398                          {
399                               //int u1,u1_t,u2,u2_t,u3,u3_t;
400                               stack_el s;
401              
402                               if (_found == 1)
403                                   s = eval_heap[i].getSecond();
404                               else
405                                   s = eval_heap[i].getFirst();
406              
407                               // insert two new expression before entry i
408                               eval_el evl;
409              
410                               evl = eval_el(false, CQL_OR, i+1, false, i, false);
411                               if ((Uint32 )i < eval_heap.size()-1)
412                                   eval_heap.insert(i+1, evl);
413                               else
414                                   eval_heap.append(evl);
415                               eval_heap.insert(i+1, evl);
416              
417 chuck    1.2                  for (int j=eval_heap.size()-1; j > i + 2; j--)
418                               {
419                                   //eval_heap[j] = eval_heap[j-2];
420              
421                                   // adjust pointers
422              
423                                   if ((!eval_heap[j].is_terminal1)&&
424                                       (eval_heap[j].opn1 >= i))
425                                       eval_heap[j].opn1 += 2;
426                                   if ((!eval_heap[j].is_terminal2)&&
427                                       (eval_heap[j].opn2 >= i))
428                                       eval_heap[j].opn2 += 2;
429                               }
430              
431                               n+=2; // increase size of array
432              
433                               // generate the new expressions : new OR expression
434              
435              
436                               // first new AND expression
437                               eval_heap[i+1].mark = false;
438 chuck    1.2                  eval_heap[i+1].op = CQL_AND;
439                               eval_heap[i+1].setFirst(s);
440                               eval_heap[i+1].setSecond( eval_heap[index].getFirst());
441                               eval_heap[i+1].order();
442              
443              
444                               // second new AND expression
445                               eval_heap[i].mark = false;
446                               eval_heap[i].op = CQL_AND;
447                               eval_heap[i].setFirst(s);
448                               eval_heap[i].setSecond( eval_heap[index].getSecond());
449                               eval_heap[i].order();
450              
451                               // mark the indexed expression as inactive
452                               //eval_heap[index].op = WQL_IS_TRUE; possible disconnects
453                               i--;
454              
455                          } /* endif _found > 0 */
456              
457                      } /* endif found AND operator */
458              
459 chuck    1.2         i++; // increase pointer
460                  }
461 humberto 1.5 
462              	PEG_METHOD_EXIT();
463 chuck    1.2 }
464              
465              void Cql2Dnf::_strip_ops_operands(CQLPredicate& topLevel)
466              {
467 humberto 1.5 	PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_strip_ops_operands");
468 chuck    1.2 	//
469              	// depth first search for all operations and operands
470              	// extract operations and operands and store in respective arrays for later processing
471              	//
472              	_destruct(topLevel);
473 humberto 1.3 	if(topLevel.getInverted()){
474                      	_operations.append(CQL_NOT);
475                      }
476 humberto 1.5 	PEG_METHOD_EXIT();
477 chuck    1.2 }
478              
479              OperationType Cql2Dnf::_convertOpType(ExpressionOpType op){
480              	switch(op){
481              		case EQ: return CQL_EQ;
482              		case NE: return CQL_NE;
483              		case GT: return CQL_GT;
484              		case LT: return CQL_LT;
485              		case GE: return CQL_GE;
486              		case LE: return CQL_LE;
487              		case IS_NULL: return CQL_IS_NULL;
488              		case IS_NOT_NULL: return CQL_IS_NOT_NULL;
489 humberto 1.6 		case ISA: return CQL_ISA;
490              		case LIKE: return CQL_LIKE;
491 chuck    1.2 		default: return CQL_NOOP;
492              	}
493              }
494              
495              ExpressionOpType Cql2Dnf::_convertOpType(OperationType op){
496                      switch(op){
497                              case CQL_EQ: return EQ;
498                              case CQL_NE: return NE;
499                              case CQL_GT: return GT;
500                              case CQL_LT: return LT;
501                              case CQL_GE: return GE;
502                              case CQL_LE: return LE;
503 humberto 1.6                 case CQL_IS_NULL: return IS_NULL; 
504                              case CQL_IS_NOT_NULL: return IS_NOT_NULL;
505              					 case CQL_ISA: return ISA;
506              					 case CQL_LIKE: return LIKE;
507 humberto 1.3                 default: return EQ; // should never get here
508 chuck    1.2         }
509 humberto 1.3 	return EQ; // should never get here
510 chuck    1.2 }
511              
512              void Cql2Dnf::_destruct(CQLPredicate& _p){
513              	if(_p.isSimple()){
514              		CQLSimplePredicate _sp = _p.getSimplePredicate();
515              		_operations.append(_convertOpType(_sp.getOperation()));
516              		_operands.append(_sp.getLeftExpression());
517 humberto 1.6 		if((_operations[_operations.size()-1] != CQL_IS_NULL) && (_operations[_operations.size()-1] != CQL_IS_NOT_NULL))
518              			_operands.append(_sp.getRightExpression());
519 chuck    1.2 	}
520              	else{
521              		Array<CQLPredicate> _preds = _p.getPredicates();
522              		Array<BooleanOpType> _boolops = _p.getOperators();
523              		for(Uint32 i=0;i<_preds.size();i++){
524              			_destruct(_preds[i]);
525              			if(_preds[i].getInverted()){
526              				_operations.append(CQL_NOT);
527              			}
528              			if(i > 0){
529              				if(_boolops[i-1] == AND){
530              					_operations.append(CQL_AND);
531              				}
532              				if(_boolops[i-1] == OR){
533                                                      _operations.append(CQL_OR);
534                                              }
535              			}
536              		}
537              	}
538              }
539              
540 chuck    1.2 void Cql2Dnf::_construct(){
541 humberto 1.5 
542              	PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_construct");
543 chuck    1.2 	//
544              	// Each eval_el on the eval heap contains all the information needed to make a CQLPredicate.  
545              	// We will build a CQLPredicate for every element in the eval heap. So there is a 1 to 1 correspondence
546              	// between elements in the eval heap and elements in the CQLPredicate array used below.  
547              	// The first eval_el on the eval heap will always contain at least one terminal if the operation is a NOT
548              	// or two terminals if the operation is AND or OR.  We are guaranteed to build a CQLPredicate from the first
549              	// position in the eval_heap array. 
550              	//
551              	// The key to the algorithm is the isterminalX flag.  When set to true, we go to the 
552              	// term_heap and get the CQLSimplePredicate.  When set to false, we go to the _preds array below
553              	// and get the CQLPredicate.  Since there is a 1 - 1 correspondence, as explained above, the index
554              	// referred to by eval.opn1 or eval.opn2 is valid into the _preds array.
555              	//
556              	// For ANDs and ORs, we need two operands, as explained above, we get those operands
557              	// from either the term_heap or the _preds array.  For NOTs, we need only 1 operand, and that
558              	// comes from either the term_heap or the _preds array.
559              	//
560              	// When finished, the last element in the _preds array contains the top level CQLPredicate (the rebuilt tree)
561              	//
562              	// Example:  a=b^(!c=d v e=f)
563              	// If the current eval_heap looks like: 
564 chuck    1.2 	//	0,NOT,1,True,-1,True [index = 0]
565              	// 	0,OR,2,True,0,False  [index = 1]
566              	// 	0,AND,1,False,0,True [index = 2]
567              	//
568              	// And the current term_heap looks like:
569              	//	CQLSimplePredicate(a=b) [index = 0]
570              	// 	CQLSimplePredicate(c=d) [index = 1]
571              	//      CQLSimplePredicate(e=f) [index = 0]
572              	//
573              	// The _preds array at the end would look like:
574              	//	CQLPredicate(!c==d)        [index = 0]
575              	//	CQLPredicate(e==f v !c==d) [index = 1]
576              	// 	CQLPredicate((e==f v !c==d) ^ a==b) [index = 2]  (the rebuilt tree)
577              	//
578              
579              	if(eval_heap.size() > 0){
580              	   Array<CQLPredicate> _preds;
581 humberto 1.3 	   CQLPredicate pred;
582 chuck    1.2 	   for(Uint32 i=0;i<eval_heap.size();i++){
583              		eval_el eval = eval_heap[i];
584              		if(eval.is_terminal1 && eval.is_terminal2){
585              			switch(eval.op){
586              				case CQL_NOT:
587 humberto 1.7            	{
588                            	_preds.append(CQLPredicate(terminal_heap[eval.opn1]._simplePredicate,true));
589 chuck    1.2 					break;
590 humberto 1.7             }
591 chuck    1.2 				case CQL_NOOP:
592              				{
593 humberto 1.7 					CQLPredicate p(terminal_heap[eval.opn1]._simplePredicate,false);
594              					if(terminal_heap[eval.opn1].NOT == true)
595              					   p.setInverted(true);
596              					_preds.append(p);
597 chuck    1.2 					break;
598              				}
599 humberto 1.7             case CQL_AND:
600                          {
601 chuck    1.2 					CQLPredicate p;
602              					CQLPredicate p1(terminal_heap[eval.opn2]._simplePredicate,false);
603 humberto 1.6 					if(terminal_heap[eval.opn2].NOT == true)
604 humberto 1.7 					   p1.setInverted(true);
605 chuck    1.2 					p.appendPredicate(p1);
606              					CQLPredicate p2(terminal_heap[eval.opn1]._simplePredicate,false);
607 humberto 1.6 					if(terminal_heap[eval.opn1].NOT == true)
608 humberto 1.7 					   p2.setInverted(true);
609 chuck    1.2 					p.appendPredicate(p2,AND);
610              					_preds.append(p);
611              					break;
612 humberto 1.7             }
613                          case CQL_OR:
614                          {
615              				   CQLPredicate p;
616                             CQLPredicate p1(terminal_heap[eval.opn2]._simplePredicate,false);
617              					if(terminal_heap[eval.opn2].NOT == true)
618              					   p1.setInverted(true);
619                             p.appendPredicate(p1);
620                             CQLPredicate p2(terminal_heap[eval.opn1]._simplePredicate,false);
621              					if(terminal_heap[eval.opn1].NOT == true)
622                                p2.setInverted(true);
623                             p.appendPredicate(p2,OR);
624                             _preds.append(p);
625                             break;
626                          }
627 chuck    1.2 				case CQL_EQ:
628                              		case CQL_NE:
629                              		case CQL_GT:
630                              		case CQL_LT:
631                              		case CQL_GE: 
632                              		case CQL_LE:
633 humberto 1.6 							case CQL_ISA:
634              							case CQL_LIKE:
635 chuck    1.2                 		case CQL_IS_NULL:
636                              		case CQL_IS_NOT_NULL: break;
637              				
638              			}
639              		}else if(eval.is_terminal1 && !eval.is_terminal2){
640              			switch(eval.op){
641              				case CQL_NOT:
642 humberto 1.7             {
643                             _preds.append(CQLPredicate(terminal_heap[eval.opn1]._simplePredicate,true));
644 chuck    1.2 					break;
645 humberto 1.7             }
646 chuck    1.2 				case CQL_NOOP:
647 humberto 1.7             {
648                             CQLPredicate p(terminal_heap[eval.opn1]._simplePredicate,false);
649                             if(terminal_heap[eval.opn1].NOT == true)
650                                p.setInverted(true);
651                             _preds.append(p);
652                             break;
653                          }
654                          case CQL_AND:
655                          {
656                             CQLPredicate p;
657                             CQLPredicate p1(terminal_heap[eval.opn1]._simplePredicate,false);
658              			      if(terminal_heap[eval.opn1].NOT == true)
659                                p1.setInverted(true);
660                             p = _preds[eval.opn2];
661                             p.appendPredicate(p1,AND);
662                             _preds.append(p);
663                             break;
664                          }
665                          case CQL_OR:
666                          {
667                            CQLPredicate p;
668 humberto 1.7               CQLPredicate p1(terminal_heap[eval.opn1]._simplePredicate,false);
669              				  if(terminal_heap[eval.opn1].NOT == true)
670                               p1.setInverted(true);
671                            p = _preds[eval.opn2];
672                            p.appendPredicate(p1,OR);
673                            _preds.append(p);
674                            break;
675                          }
676 chuck    1.2 				case CQL_EQ:
677                                              case CQL_NE:
678                                              case CQL_GT:
679                                              case CQL_LT:
680                                              case CQL_GE:
681                                              case CQL_LE:
682 humberto 1.6 										  case CQL_ISA:
683              							           case CQL_LIKE:
684 chuck    1.2                                 case CQL_IS_NULL:
685                                              case CQL_IS_NOT_NULL: break;
686                                             
687              			}
688              		}else if(!eval.is_terminal1 && eval.is_terminal2){
689 humberto 1.7          switch(eval.op){
690                          case CQL_NOT:
691                          {
692              				   CQLPredicate p = _preds[eval.opn1];
693                             p.setInverted(true);
694                              _preds.append(p);
695 chuck    1.2 					break;
696 humberto 1.7             }
697 chuck    1.2 				case CQL_NOOP:
698 humberto 1.7             {
699                             _preds.append(_preds[eval.opn1]);
700 chuck    1.2 					break;
701 humberto 1.7             }
702                          case CQL_AND:
703                          {
704                             CQLPredicate p;
705                             CQLPredicate p1(terminal_heap[eval.opn2]._simplePredicate,false);
706              				   if(terminal_heap[eval.opn2].NOT == true)
707                                p1.setInverted(true);
708                             p = _preds[eval.opn1];
709                             p.appendPredicate(p1,AND);
710                             _preds.append(p);
711                             break;
712                          }
713                          case CQL_OR:
714                          {
715                             CQLPredicate p;
716                             CQLPredicate p1(terminal_heap[eval.opn2]._simplePredicate,false);
717              				   if(terminal_heap[eval.opn2].NOT == true)
718                                p1.setInverted(true);
719                             p = _preds[eval.opn1];
720                             p.appendPredicate(p1,OR);
721                             _preds.append(p);
722 humberto 1.7                break;
723                          }
724 chuck    1.2 				case CQL_EQ:
725                                              case CQL_NE:
726                                              case CQL_GT:
727                                              case CQL_LT:
728                                              case CQL_GE:
729                                              case CQL_LE:
730 humberto 1.6 										  case CQL_ISA:
731              										  case CQL_LIKE:
732 chuck    1.2                                 case CQL_IS_NULL:
733                                              case CQL_IS_NOT_NULL: break;
734                                             
735                                      }                                                                                                                                    
736                              }else{ // !eval.is_terminal1 && !eval.is_terminal2
737              			switch(eval.op){
738 humberto 1.7             case CQL_NOT:
739                          {
740 chuck    1.2 					CQLPredicate p = _preds[eval.opn1];
741 humberto 1.7 					p.setInverted(true);
742                             _preds.append(p);
743 chuck    1.2 					break;
744 humberto 1.7             }
745              			   case CQL_NOOP:
746                          {
747                             _preds.append(_preds[eval.opn1]);
748              					break;
749                          }
750                          case CQL_AND:
751                          {
752 chuck    1.2 					CQLPredicate p = _preds[eval.opn2];
753 humberto 1.7                _flattenANDappend(p,AND,_preds[eval.opn1]);
754                             _preds.append(p);
755                             break;
756                          }
757                          case CQL_OR:
758                          {
759 chuck    1.2 					CQLPredicate p = _preds[eval.opn2];
760 humberto 1.7                _flattenANDappend(p,OR,_preds[eval.opn1]);
761                             _preds.append(p);
762                             break;
763                          }
764 chuck    1.2 				case CQL_EQ:
765                                              case CQL_NE:
766                                              case CQL_GT:
767                                              case CQL_LT:
768                                              case CQL_GE:
769                                              case CQL_LE:
770 humberto 1.6 										  case CQL_ISA:
771              										  case CQL_LIKE:
772 chuck    1.2                                 case CQL_IS_NULL:
773                                              case CQL_IS_NOT_NULL: break;
774                                              
775                                      }
776              
777              		}
778              	   } // end for(...)
779              
780              	   _dnfPredicate = _preds[_preds.size()-1];
781              
782              	} // end if
783              	else{ // we just have a CQLSimplePredicate on the terminal_heap
784              		PEGASUS_ASSERT(terminal_heap.size() == 1);
785              		_dnfPredicate = CQLPredicate(terminal_heap[0]._simplePredicate,false);
786              	}
787 humberto 1.5 
788              	PEG_METHOD_EXIT();
789 chuck    1.2 }
790              
791              CQLPredicate Cql2Dnf::getDnfPredicate(){
792              	return _dnfPredicate;
793              }
794              
795 humberto 1.3 CQLPredicate Cql2Dnf::_flattenANDappend(CQLPredicate& topLevel, BooleanOpType op, CQLPredicate& p){
796 humberto 1.5 
797              	PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_flattenANDappend");
798 humberto 1.3 	//
799              	// this is to prevent appending complex predicates to the top level predicate
800              	// the final DNFed predicate must only have simple predicates inside its predicate array
801              	//
802              	// example:
803              	// say P(top level) = A AND B
804              	// say P1 = C AND D
805              	// say we need to OR them together
806              	// we cant call P.appendPredicate(P1,OR) because this creates one more complex predicate layer
807              	// instead we would:
808              	// -> get P1s predicates (which should all be simple)
809              	// -> append its first predicate to P along with the operator passed into us
810              	// -> at this point we have P = A AND B OR C
811              	// -> then go through P1s remaining predicates and append them and P1s operators to P
812              	// -> when finished, we have P = A AND B OR C AND D INSTEAD of having P = A AND B OR P1 where P1 is a complex predicate
813              	//
814              
815              	if(!p.isSimple()){
816              		Array<CQLPredicate> preds = p.getPredicates();
817              		Array<BooleanOpType> ops = p.getOperators();
818              		for(Uint32 i=0;i<preds.size();i++){
819 humberto 1.3 			if(i==0) topLevel.appendPredicate(preds[i],op);
820              			else topLevel.appendPredicate(preds[i],ops[i-1]);
821              		}
822              	}else{
823              		topLevel.appendPredicate(p,op);
824              	}
825 humberto 1.5 
826              	PEG_METHOD_EXIT();
827 humberto 1.3 	return topLevel;
828              }
829              
830 chuck    1.2 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2