void WQLCompile::_gather(Array<stack_el>& stk, stack_el sel, bool or_flag) { UInt32 i = 0; stk.empty(); if ((i = eval_heap.size()) == 0) { return; } while (eval_heap[i-1].op == WQL_DO_NOTHING) { eval_heap.remove(i-1); i--; if (i == 0) { return; } } if (or_flag) { stk.append(stack_el(i-1, EVAL_HEAP)); } else { if (sel.type != EVAL_HEAP) { return; } stk.append(sel); } i = 0; while (i<stk.size()) { int k = stk[i].opn; if ((k < 0) || (stk[i].type != EVAL_HEAP)) { i++; } else { if ( ((eval_heap[k].op != WQL_OR) && (or_flag)) || ((eval_heap[k].op != WQL_AND) && (!or_flag)) ) { i++; } else { // replace the element with disjunction stk[i] = eval_heap[k].getSecond(); stk.insert(i, eval_heap[k].getFirst()); if (or_flag) { eval_heap[k].op = WQL_DO_NOTHING; } } } } }
void WQLCompile::compile(const WQLSelectStatement * wqs) { if (!wqs->hasWhereClause()) { return; } _tableau.clear(); _buildEvalHeap(wqs); _pushNOTDown(); _factoring(); Array<stack_el> disj; _gatherDisj(disj); if (disj.size() == 0) { if (terminal_heap.size() > 0) { // point to the remaining terminal element disj.append(stack_el(0, TERMINAL_HEAP)); } } for (UInt32 i=0, n =disj.size(); i< n; i++) { TableauRow tr; Array<stack_el> conj; if (disj[i].type == EVAL_HEAP) { _gatherConj(conj, disj[i]); for ( UInt32 j=0, m = conj.size(); j < m; j++) { tr.append(terminal_heap[conj[j].opn]); } } else { tr.append(terminal_heap[disj[i].opn]); } _tableau.append(tr); } eval_heap.clear(); //printTableau(); _sortTableau(); }
stack_el eval_el::getSecond() { return stack_el(opn2, is_terminal2); }
// // Evaluation heap element methods // stack_el eval_el::getFirst() { return stack_el(opn1, is_terminal1); }
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(); }
WQLCompile::stack_el WQLCompile::eval_el::getSecond() { return stack_el(opn2, is_terminal2); }
// // Evaluation heap element methods // WQLCompile::stack_el WQLCompile::eval_el::getFirst() { return stack_el(opn1, is_terminal1); }
void WQLCompile::_gatherDisj(Array<stack_el>& stk) { _gather(stk, stack_el(0, TERMINAL_HEAP), true); }
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); }