void Cql2Dnf::_buildEvalHeap() { PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_buildEvalHeap"); Stack<stack_el> stack; // Counter for Operands Uint32 j = 0; for (Uint32 i = 0, n = _operations.size(); i < n; i++) { OperationType op = _operations[i]; switch (op) { case CQL_OR: case CQL_AND: { PEGASUS_ASSERT(stack.size() >= 2); stack_el op1 = stack.top(); stack.pop(); stack_el op2 = stack.top(); // generate Eval expression eval_heap.append(eval_el(0, op , op1.opn, op1.is_terminal, op2.opn , op2.is_terminal)); stack.top() = stack_el(eval_heap.size()-1, false); break; } case CQL_NOT: { PEGASUS_ASSERT(stack.size() >= 1); stack_el op1 = stack.top(); // generate Eval expression eval_heap.append(eval_el(0, op , op1.opn, op1.is_terminal, -1, true)); stack.top() = stack_el(eval_heap.size()-1, false); break; } case CQL_EQ: case CQL_NE: case CQL_LT: case CQL_LE: case CQL_GT: case CQL_GE: case CQL_ISA: case CQL_LIKE: { PEGASUS_ASSERT(_operands.size() >= 2); CQLExpression lhs = _operands[j++]; CQLExpression rhs = _operands[j++]; CQLSimplePredicate sp(lhs,rhs,_convertOpType(op)); terminal_heap.push(term_el(false, sp)); stack.push(stack_el(terminal_heap.size()-1, true)); break; } case CQL_IS_NULL: { PEGASUS_ASSERT(_operands.size() >= 1); CQLExpression expression = _operands[j++]; CQLSimplePredicate dummy(expression,IS_NULL); terminal_heap.push(term_el(false, dummy)); stack.push(stack_el(terminal_heap.size()-1, true)); break; } case CQL_IS_NOT_NULL: { PEGASUS_ASSERT(_operands.size() >= 1); CQLExpression expression = _operands[j++]; CQLSimplePredicate dummy(expression,IS_NOT_NULL); terminal_heap.push(term_el(false, dummy)); stack.push(stack_el(terminal_heap.size()-1, true)); break; } case CQL_NOOP: default: break; } } PEGASUS_ASSERT(stack.size() == 1); PEG_METHOD_EXIT(); }
void Cql2Dnf::_factoring(void) { PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_factoring"); int i = 0,n = eval_heap.size(); //for (int i=eval_heap.size()-1; i >= 0; i--) while (i < n) { int _found = 0; int index = 0; // look for expressions (A | B) & C ---> A & C | A & B if (eval_heap[i].op == CQL_AND) { if (!eval_heap[i].is_terminal1) { index = eval_heap[i].opn1; // remember the index if (eval_heap[index].op == CQL_OR) _found = 1; } if ((_found == 0) && (!eval_heap[i].is_terminal2)) { index = eval_heap[i].opn2; // remember the index if (eval_heap[index].op == CQL_OR) _found = 2; } if (_found != 0) { //int u1,u1_t,u2,u2_t,u3,u3_t; stack_el s; if (_found == 1) s = eval_heap[i].getSecond(); else s = eval_heap[i].getFirst(); // insert two new expression before entry i eval_el evl; evl = eval_el(false, CQL_OR, i+1, false, i, false); if ((Uint32 )i < eval_heap.size()-1) eval_heap.insert(i+1, evl); else eval_heap.append(evl); eval_heap.insert(i+1, evl); for (int j=eval_heap.size()-1; j > i + 2; j--) { //eval_heap[j] = eval_heap[j-2]; // adjust pointers if ((!eval_heap[j].is_terminal1)&& (eval_heap[j].opn1 >= i)) eval_heap[j].opn1 += 2; if ((!eval_heap[j].is_terminal2)&& (eval_heap[j].opn2 >= i)) eval_heap[j].opn2 += 2; } n+=2; // increase size of array // generate the new expressions : new OR expression // first new AND expression eval_heap[i+1].mark = false; eval_heap[i+1].op = CQL_AND; eval_heap[i+1].setFirst(s); eval_heap[i+1].setSecond( eval_heap[index].getFirst()); eval_heap[i+1].order(); // second new AND expression eval_heap[i].mark = false; eval_heap[i].op = CQL_AND; eval_heap[i].setFirst(s); eval_heap[i].setSecond( eval_heap[index].getSecond()); eval_heap[i].order(); // mark the indexed expression as inactive //eval_heap[index].op = WQL_IS_TRUE; possible disconnects i--; } /* endif _found > 0 */ } /* endif found AND operator */ i++; // increase pointer } PEG_METHOD_EXIT(); }
void WQLCompile::_buildEvalHeap(const WQLSelectStatement * wqs) { Stack<stack_el> stack; for (UInt32 i = 0, n = wqs->_operStack.size(); i < n; i++) { const WQLSelectStatement::OperandOrOperation& curItem = wqs->_operStack[i]; if (curItem.m_type == WQLSelectStatement::OperandOrOperation::OPERAND) { // put pointer to it onto the stack stack.push(stack_el(i, OPERAND)); } else { WQLOperation op = curItem.m_operation; switch (op) { // unary case WQL_NOT: { OW_ASSERT(stack.size() >= 1); stack_el op1 = stack.top(); // generate Eval expression eval_heap.append(eval_el(false, op, op1.opn, op1.type, -1, TERMINAL_HEAP)); stack.top() = stack_el(eval_heap.size()-1, EVAL_HEAP); break; } // binary case WQL_OR: case WQL_AND: case WQL_EQ: case WQL_NE: case WQL_LT: case WQL_LE: case WQL_GT: case WQL_GE: case WQL_ISA: { OW_ASSERT(stack.size() >= 2); stack_el op2 = stack.top(); stack.pop(); stack_el op1 = stack.top(); if (op1.type == OPERAND && op2.type == OPERAND) { OW_ASSERT(op1.type == OPERAND); OW_ASSERT(wqs->_operStack[op1.opn].m_type == WQLSelectStatement::OperandOrOperation::OPERAND); WQLOperand lhs = wqs->_operStack[op1.opn].m_operand; OW_ASSERT(op2.type == OPERAND); OW_ASSERT(wqs->_operStack[op2.opn].m_type == WQLSelectStatement::OperandOrOperation::OPERAND); WQLOperand rhs = wqs->_operStack[op2.opn].m_operand; terminal_heap.push_back(term_el(false, op, lhs, rhs)); stack.top() = stack_el(terminal_heap.size()-1, TERMINAL_HEAP); } else { // generate Eval expression eval_heap.append(eval_el(false, op, op1.opn, op1.type, op2.opn , op2.type)); stack.top() = stack_el(eval_heap.size()-1, EVAL_HEAP); } break; } case WQL_DO_NOTHING: { OW_ASSERT(0); // this should never happen break; } } } } OW_ASSERT(stack.size() == 1); }