static INT32 getCondAttrMoreFields( qgmConditionNode *condNode, const qgmOPFieldVec &fields, qgmOPFieldVec &more ) { if ( 0 == fields.size() ) { return SDB_OK ; } qgmConditionNodeHelper condTree( condNode ) ; qgmDbAttrPtrVec attrs ; condTree.getAllAttr( attrs ) ; qgmDbAttrPtrVec::iterator it = attrs.begin() ; while ( it != attrs.end() ) { if ( isFromOne( *(*it), more, FALSE ) ) { ++it ; continue ; } if ( !isFromOne( *(*it), fields, TRUE ) ) { more.push_back( qgmOpField( *(*it), SQL_GRAMMAR::DBATTR ) ) ; } ++it ; } return SDB_OK ; }
INT32 _qgmOptiAggregation::_addFields( qgmOprUnit * oprUnit ) { PD_TRACE_ENTRY( SDB__QGMOPTIAGGREGATION__ADDFIELDS ) ; INT32 rc = SDB_OK ; if ( QGM_OPTI_TYPE_FILTER != oprUnit->getType() ) { return SDB_INVALIDARG ; } qgmOPFieldVec notAggrFields ; qgmAggrSelectorVec::iterator it = _selector.begin() ; while ( it != _selector.end() ) { qgmOpField &field = (*it).value ; if ( SQL_GRAMMAR::FUNC != field.type ) { notAggrFields.push_back( field ) ; } ++it ; } oprUnit->getFields()->clear() ; it = _selector.begin() ; while ( it != _selector.end() ) { qgmAggrSelector &select = *it ; if ( select.value.type != SQL_GRAMMAR::FUNC ) { oprUnit->addOpField( select.value, QGM_OPR_FILTER_COPY_FLAG ) ; } else if ( select.value.type != SQL_GRAMMAR::WILDCARD ) { vector<qgmOpField>::iterator itAttr = select.param.begin() ; while ( itAttr != select.param.end() ) { qgmDbAttr &attr = itAttr->value ; if ( !isFromOne( attr, notAggrFields, FALSE ) ) { oprUnit->addOpField( qgmOpField( attr, SQL_GRAMMAR::DBATTR ), TRUE ) ; } ++itAttr ; } } ++it ; } if ( !oprUnit->isWildCardField() && oprUnit->getFields()->size() > 0 ) { oprUnit->addOpField( _groupby, TRUE ) ; } PD_TRACE_EXITRC( SDB__QGMOPTIAGGREGATION__ADDFIELDS, rc ) ; return rc ; }
INT32 _qgmOptiAggregation::_pushOprUnit( qgmOprUnit * oprUnit, PUSH_FROM from ) { PD_TRACE_ENTRY( SDB__QGMOPTIAGGREGATION__PUSHOPRUNIT ) ; INT32 rc = SDB_OK ; if ( QGM_OPTI_TYPE_FILTER == oprUnit->getType() ) { qgmOPFieldVec *fields = oprUnit->getFields() ; if ( fields->size() != 0 && !oprUnit->isWildCardField() ) { qgmAggrSelectorVec tmpSelector = _selector ; _selector.clear() ; UINT32 count = fields->size() ; UINT32 index = 0 ; while ( index < count ) { qgmOpField &field = (*fields)[index] ; qgmAggrSelectorVec::iterator it = tmpSelector.begin() ; while ( it != tmpSelector.end() ) { qgmAggrSelector &selector = *it ; if ( selector.value.alias == field.value.attr() || selector.value.value == field.value || ( field.value.relegation().empty() && field.value.attr() == selector.value.value.attr() ) ) { _selector.push_back( selector ) ; if ( !field.alias.empty() ) { (*(--_selector.end())).value.alias = field.alias ; } break ; } ++it ; } if ( it == tmpSelector.end() ) { _selector.push_back( qgmAggrSelector( field ) ) ; } ++index ; } _update2Unit( AGGR_SELECTOR ) ; } qgmFilterUnit *filterUnit = (qgmFilterUnit*)oprUnit ; _addFields( filterUnit ) ; qgmFilterUnit *otherUnit = (qgmFilterUnit*) getOprUnitByType( QGM_OPTI_TYPE_FILTER ) ; if ( otherUnit ) { if ( otherUnit->hasCondition() ) { qgmConditionNodePtrVec conds = otherUnit->getConditions() ; filterUnit->addCondition( conds ) ; } removeOprUnit( otherUnit, TRUE, FALSE ) ; } filterUnit->setOptional( TRUE ) ; _oprUnits.push_back( filterUnit ) ; } else if ( QGM_OPTI_TYPE_SORT == oprUnit->getType() ) { if ( _groupby.size() > oprUnit->getFields()->size() ) { UINT32 count = _groupby.size() ; UINT32 index = 0 ; while ( index < count ) { if ( !isFromOne( _groupby[index], *(oprUnit->getFields()), FALSE ) ) { oprUnit->getFields()->push_back( _groupby[index] ) ; } ++index ; } } _groupby = *(oprUnit->getFields()) ; _oprUnits.insert( _oprUnits.begin(), oprUnit ) ; _update2Unit( AGGR_GROUPBY ) ; } else { rc = SDB_SYS ; goto error ; } done: PD_TRACE_EXITRC( SDB__QGMOPTIAGGREGATION__PUSHOPRUNIT, rc ) ; return rc ; error: goto done ; }
INT32 _optQgmFilterSortSty::calcResult( qgmOprUnit * oprUnit, qgmOptiTreeNode * curNode, qgmOptiTreeNode * subNode, OPT_QGM_SS_RESULT & result ) { INT32 rc = SDB_OK ; qgmFilterUnit *filterUnit = ( qgmFilterUnit* )oprUnit ; qgmFilterUnit *newUnit = NULL ; qgmOPFieldVec *fields = oprUnit->getFields() ; qgmOptiSort *sortNode = ( qgmOptiSort* )subNode ; qgmOPFieldVec *orderby = sortNode->getOrderby() ; qgmOPFieldVec::iterator itSort ; qgmOPFieldVec sortMore ; if ( fields->size() > 0 ) { itSort = orderby->begin() ; while ( itSort != orderby->end() ) { if ( !isFromOne( *itSort, *fields, TRUE ) ) { sortMore.push_back( *itSort ) ; } ++itSort ; } } if ( 0 == sortMore.size() ) { result = OPT_SS_TAKEOVER ; goto done ; } else { if ( !oprUnit->isOptional() && curNode->getParent() ) { qgmOpStream outputStream ; qgmOptiTreeNode *rootNode = curNode->getParent() ; while ( rootNode->getParent() ) { rootNode = rootNode->getParent() ; } rootNode->outputStream( outputStream ) ; if ( outputStream.stream.size() != 0 && !outputStream.isWildCard() ) { result = OPT_SS_TAKEOVER ; goto done ; } } newUnit = SDB_OSS_NEW qgmFilterUnit( *filterUnit, filterUnit->isFieldsOptional() ? FALSE : QGM_OPR_FILTER_COPY_FLAG ) ; if ( !newUnit ) { rc = SDB_OOM ; goto error ; } newUnit->setNodeID( curNode->getNodeID() ) ; if ( filterUnit->hasCondition() ) { qgmConditionNodePtrVec subConds = filterUnit->getConditions() ; newUnit->addCondition( subConds ) ; filterUnit->emptyCondition() ; } PD_LOG( PDDEBUG, "Create a optional unit[%s], curNode[%s], subNode[%s]", newUnit->toString().c_str(), curNode->toString().c_str(), subNode->toString().c_str() ) ; rc = subNode->pushOprUnit( newUnit, curNode, qgmOptiTreeNode::FROM_UP ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "Push oprUnit[%s] to node[%s] failed, rc: %d", newUnit->toString().c_str(), subNode->toString().c_str(), rc ) ; goto error ; } } result = OPT_SS_REFUSE ; done: return rc ; error: if ( newUnit ) { SDB_OSS_DEL newUnit ; } goto done ; }
INT32 _qgmOptiNLJoin::_pushOprUnit( qgmOprUnit * oprUnit, PUSH_FROM from ) { PD_TRACE_ENTRY( SDB__QGMOPTINLJOIN__PUSHOPRUNIT ) ; INT32 rc = SDB_OK ; qgmFilterUnit *filterUnit = NULL ; qgmFilterUnit *outerUnit = NULL ; qgmFilterUnit *innerUnit = NULL ; if ( needMakeCondition() ) { rc = makeCondition() ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "Node[%s] make condition failed, rc: %d", toString().c_str(), rc ) ; goto error ; } } if ( QGM_OPTI_TYPE_SORT == oprUnit->getType() ) { oprUnit->setDispatchAlias( outer()->getAlias( TRUE ) ) ; oprUnit->resetNodeID() ; _oprUnits.insert( _oprUnits.begin(), oprUnit ) ; _hasPushSort = TRUE ; } else if ( QGM_OPTI_TYPE_FILTER == oprUnit->getType() ) { qgmConditionNodePtrVec conds ; qgmConditionNodePtrVec::iterator itCond ; BOOLEAN outerChange = FALSE ; BOOLEAN innerChange = FALSE ; outerUnit = SDB_OSS_NEW qgmFilterUnit( QGM_OPTI_TYPE_FILTER ) ; innerUnit = SDB_OSS_NEW qgmFilterUnit( QGM_OPTI_TYPE_FILTER ) ; if ( !outerUnit || !innerUnit ) { rc = SDB_OOM ; goto error ; } outerUnit->setOptional( TRUE ) ; innerUnit->setOptional( TRUE ) ; filterUnit = (qgmFilterUnit*)oprUnit ; qgmOPFieldVec *fields = filterUnit->getFields() ; for ( UINT32 index = 0 ; index < fields->size() ; index++ ) { qgmOpField &field = (*fields)[index] ; if ( field.value.relegation() == outer()->getAlias( TRUE ) ) { outerUnit->addOpField( field ) ; outerChange = TRUE ; } else if ( field.value.relegation() == inner()->getAlias( TRUE ) ) { innerUnit->addOpField( field ) ; innerChange = TRUE ; } else { PD_LOG_MSG( PDERROR, "oprUnit[%s] field[%s] is not in outer[%s] or " "inner[%s]", oprUnit->toString().c_str(), field.toString().c_str(), outer()->getAlias( TRUE ).toString().c_str(), inner()->getAlias( TRUE ).toString().c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } } conds = filterUnit->getConditions() ; itCond = conds.begin() ; while ( itCond != conds.end() ) { qgmConditionNode *condNode = *itCond ; while ( condNode->left ) { condNode = condNode->left ; } if ( condNode->type != SQL_GRAMMAR::DBATTR ) { outerUnit->addCondition( *itCond ) ; innerUnit->addCondition( SDB_OSS_NEW qgmConditionNode( *itCond ) ) ; outerChange = TRUE ; innerChange = TRUE ; } else if ( condNode->value.relegation() == outer()->getAlias( TRUE ) ) { outerUnit->addCondition( *itCond ) ; outerChange = TRUE ; } else if ( condNode->value.relegation() == inner()->getAlias( TRUE ) ) { innerUnit->addCondition( *itCond ) ; innerChange = TRUE ; } else { PD_LOG_MSG( PDERROR, "oprUnit[%s] condition attr[%s] is not in " "outer[%s] or inner[%s]", oprUnit->toString().c_str(), condNode->value.toString().c_str(), outer()->getAlias( TRUE ).toString().c_str(), inner()->getAlias( TRUE ).toString().c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } ++itCond ; } if ( !outerChange && _varList.size() == 0 ) { qgmOpField dummyField ; dummyField.value.relegation() = outer()->getAlias( TRUE ) ; _table->getUniqueFieldAlias( dummyField.value.attr() ) ; dummyField.type = SQL_GRAMMAR::DBATTR ; outerUnit->addOpField( dummyField ) ; } QGM_VARLIST::iterator itVar = _varList.begin() ; while ( itVar != _varList.end() ) { if ( !isFromOne( (*itVar)._fieldName, *(outerUnit->getFields()), FALSE ) && ((*itVar)._fieldName.relegation() == outer()->getAlias()) ) { outerUnit->addOpField( qgmOpField( (*itVar)._fieldName, SQL_GRAMMAR::DBATTR) ) ; } ++itVar ; } if ( !_hints.empty() ) { SDB_ASSERT( _varList.empty(), "must be empty" ) ; _qgmConditionNodeHelper ctree( _condition ) ; qgmDbAttrPtrVec attrVec ; rc = ctree.getAllAttr( attrVec ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to get all attrs from condition tree:%d", rc ) ; goto error ; } qgmDbAttrPtrVec::const_iterator itr = attrVec.begin() ; for ( ; itr != attrVec.end(); itr++ ) { if ( !isFromOne( **itr, *(outerUnit->getFields()), FALSE ) && ((*itr)->relegation() == outer()->getAlias()) ) { outerUnit->addOpField( qgmOpField( **itr, SQL_GRAMMAR::DBATTR) ) ; } else if ( !isFromOne( **itr, *(innerUnit->getFields()), FALSE ) && ((*itr)->relegation() == inner()->getAlias())) { innerUnit->addOpField( qgmOpField(**itr, SQL_GRAMMAR::DBATTR) ) ; } } } outerUnit->setDispatchAlias( outer()->getAlias( TRUE ) ) ; _oprUnits.push_back( outerUnit ) ; outerUnit = NULL ; if ( !innerChange ) { qgmOpField dummyField ; dummyField.value.relegation() = inner()->getAlias( TRUE ) ; _table->getUniqueFieldAlias( dummyField.value.attr() ) ; dummyField.type = SQL_GRAMMAR::DBATTR ; innerUnit->addOpField( dummyField ) ; } innerUnit->setDispatchAlias( inner()->getAlias( TRUE ) ) ; _oprUnits.push_back( innerUnit ) ; innerUnit = NULL ; filterUnit->emptyCondition() ; SDB_OSS_DEL filterUnit ; } else { rc = SDB_SYS ; goto error ; } done: PD_TRACE_EXITRC( SDB__QGMOPTINLJOIN__PUSHOPRUNIT, rc ) ; return rc ; error: if ( outerUnit ) { SDB_OSS_DEL outerUnit ; } if ( innerUnit ) { SDB_OSS_DEL innerUnit ; } goto done ; }