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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2