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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2