INT32 _qgmOptiNLJoin::makeCondition() { PD_TRACE_ENTRY( SDB__QGMOPTINLJOIN_MAKECONDITION ) ; INT32 rc = SDB_OK ; qgmFilterUnit *condUnit = NULL ; if ( !needMakeCondition() ) { goto done ; ; } rc = _makeCondVar( _condition ) ; if ( SDB_OK != rc ) { goto error ; } rc = _createJoinUnit() ; if ( SDB_OK != rc ) { goto error ; } if ( _hints.empty() ) { // create a condtion oprUnit condUnit = SDB_OSS_NEW qgmFilterUnit( QGM_OPTI_TYPE_FILTER ) ; if ( !condUnit ) { rc = SDB_OOM ; goto error ; } condUnit->setCondition( _condition ) ; _condition = NULL ; condUnit->setDispatchAlias( inner()->getAlias( TRUE ) ) ; _oprUnits.push_back( condUnit ) ; condUnit = NULL ; } else { _varList.clear() ; } _hasMakeVar = TRUE ; done: PD_TRACE_EXITRC( SDB__QGMOPTINLJOIN_MAKECONDITION, rc ) ; return rc ; error: if ( condUnit ) { SDB_OSS_DEL condUnit ; } goto done ; }
INT32 _qgmOptiAggregation::init() { PD_TRACE_ENTRY(SDB__QGMOPTIAGGREGATION_INIT) ; INT32 rc = SDB_OK ; qgmOprUnit *oprUnit = NULL ; qgmAggrUnit *aggrUnit = NULL ; if ( _selector.size() > 0 ) { oprUnit = SDB_OSS_NEW qgmFilterUnit( QGM_OPTI_TYPE_FILTER ) ; if ( !oprUnit ) { rc = SDB_OOM ; goto error ; } oprUnit->setOptional( TRUE ) ; _addFields( oprUnit ) ; _oprUnits.push_back( oprUnit ) ; oprUnit = NULL ; } aggrUnit = SDB_OSS_NEW qgmAggrUnit( QGM_OPTI_TYPE_AGGR ) ; if ( !aggrUnit ) { rc = SDB_OOM ; goto error ; } aggrUnit->addOpField( _groupby, FALSE ) ; aggrUnit->addAggrSelector( _selector ) ; _oprUnits.push_back( aggrUnit ) ; aggrUnit = NULL ; done: PD_TRACE_EXITRC( SDB__QGMOPTIAGGREGATION_INIT, rc ) ; return rc ; error: if ( oprUnit ) { SDB_OSS_DEL oprUnit ; } if ( aggrUnit ) { SDB_OSS_DEL aggrUnit ; } goto done ; }
INT32 _optQgmFilterJoinSty::calcResult( qgmOprUnit * oprUnit, qgmOptiTreeNode * curNode, qgmOptiTreeNode * subNode, OPT_QGM_SS_RESULT & result ) { INT32 rc = SDB_OK ; qgmFilterUnit *newUnit = NULL ; qgmFilterUnit *filterUnit = (qgmFilterUnit*)oprUnit ; BOOLEAN fieldReleValid = TRUE ; BOOLEAN condReleSame = TRUE ; qgmConditionNodePtrVec pushConds ; qgmOPFieldVec moreField ; if ( oprUnit->isWildCardField() ) { fieldReleValid = FALSE ; } else { qgmOPFieldVec *fields = oprUnit->getFields() ; qgmOPFieldVec::iterator itField = fields->begin() ; while ( itField != fields->end() ) { if ( (*itField).value.relegation().empty() ) { fieldReleValid = FALSE ; break ; } ++itField ; } } qgmConditionNodePtrVec subConds = filterUnit->getConditions() ; qgmConditionNodePtrVec::iterator itSub = subConds.begin() ; while ( itSub != subConds.end() ) { if ( isCondSameRele( *itSub, FALSE ) && !isCondIncludedNull( *itSub ) ) { pushConds.push_back( *itSub ) ; filterUnit->removeCondition( *itSub ) ; } else { condReleSame = FALSE ; getCondAttrMoreFields( *itSub, *(filterUnit->getFields()), moreField ) ; } ++itSub ; } if ( FILTER_CON == filterUnit->filterType() && condReleSame ) { filterUnit->addCondition( pushConds ) ; result = OPT_SS_TAKEOVER ; goto done ; } if ( fieldReleValid ) { qgmOPFieldVec::iterator itField = moreField.begin() ; while ( itField != moreField.end() ) { if ( (*itField).value.relegation().empty() ) { fieldReleValid = FALSE ; break ; } ++itField ; } } if ( !fieldReleValid && 0 == pushConds.size() ) { result = OPT_SS_REFUSE ; goto done ; } newUnit = SDB_OSS_NEW qgmFilterUnit( QGM_OPTI_TYPE_FILTER ) ; if ( !newUnit ) { rc = SDB_OOM ; goto error ; } newUnit->setOptional( TRUE ) ; if ( fieldReleValid ) { newUnit->addOpField( *oprUnit->getFields(), filterUnit->isFieldsOptional() ? FALSE : QGM_OPR_FILTER_COPY_FLAG ) ; newUnit->addOpField( moreField, FALSE ) ; } newUnit->setNodeID( curNode->getNodeID() ) ; if ( pushConds.size() > 0 ) { newUnit->addCondition( pushConds ) ; } 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 _optQgmFilterAggrSty::calcResult( qgmOprUnit * oprUnit, qgmOptiTreeNode * curNode, qgmOptiTreeNode * subNode, OPT_QGM_SS_RESULT & result ) { INT32 rc = SDB_OK ; qgmFilterUnit *filterUnit = ( qgmFilterUnit* )oprUnit ; qgmFilterUnit *newUnit = NULL ; qgmOptiAggregation *aggrNode = ( qgmOptiAggregation* )subNode ; qgmOPFieldVec* fields = filterUnit->getFields() ; BOOLEAN fieldNotInAggrFunc = TRUE ; BOOLEAN attrNotInAggrFunc = TRUE ; qgmOPFieldVec moreField ; BOOLEAN change = FALSE ; qgmConditionNodePtrVec pushConds ; BOOLEAN delDup = QGM_OPR_FILTER_COPY_FLAG ; qgmOPFieldVec::iterator it = fields->begin() ; while ( it != fields->end() ) { qgmOpField &field = *it ; if ( field.type == SQL_GRAMMAR::WILDCARD || aggrNode->isInAggrFieldAlias( field.value ) ) { fieldNotInAggrFunc = FALSE ; break ; } ++it ; } if ( filterUnit->hasCondition() ) { qgmConditionNodePtrVec subConds = filterUnit->getConditions() ; qgmConditionNodePtrVec::iterator itSub = subConds.begin() ; while ( itSub != subConds.end() ) { if ( isCondNotInAggrFunc( *itSub, aggrNode ) ) { pushConds.push_back( *itSub ) ; filterUnit->removeCondition( *itSub ) ; } else { getCondAttrMoreFields( *itSub, *fields, moreField ) ; attrNotInAggrFunc = FALSE ; } ++itSub ; } } if ( fieldNotInAggrFunc && attrNotInAggrFunc ) { filterUnit->addCondition( pushConds ) ; result = OPT_SS_TAKEOVER ; goto done ; } else if ( attrNotInAggrFunc || FILTER_SEC == filterUnit->filterType() ) { filterUnit->addCondition( pushConds ) ; result = OPT_SS_TAKEOVER ; goto done ; } else if ( filterUnit->isWildCardField() && 0 == pushConds.size() ) { result = OPT_SS_REFUSE ; goto done ; } if ( 0 == moreField.size() || filterUnit->isFieldsOptional() ) { delDup = FALSE ; } newUnit = SDB_OSS_NEW qgmFilterUnit( *filterUnit, delDup ) ; if ( !newUnit ) { rc = SDB_OOM ; goto error ; } newUnit->setNodeID( curNode->getNodeID() ) ; if ( moreField.size() == 0 ) { fields->clear() ; change = TRUE ; } else { newUnit->addOpField( moreField, FALSE ) ; } newUnit->addCondition( pushConds ) ; 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 ; } if ( change ) { curNode->updateChange( filterUnit ) ; } result = OPT_SS_REFUSE ; done: return rc ; error: if ( newUnit ) { SDB_OSS_DEL newUnit ; } goto done ; }
INT32 _optQgmFilterFilterSty::calcResult( qgmOprUnit * oprUnit, qgmOptiTreeNode * curNode, qgmOptiTreeNode * subNode, OPT_QGM_SS_RESULT & result ) { qgmOptiSelect *filter = (qgmOptiSelect*)subNode ; qgmFilterUnit *filterUnit = (qgmFilterUnit*)oprUnit ; qgmFilterUnit *newCopy = NULL ; INT32 rc = SDB_OK ; if ( filter->hasConstraint() && FILTER_SEC != filterUnit->filterType() ) { result = OPT_SS_REFUSE ; qgmOPFieldVec *fields = filterUnit->getFields() ; if ( fields->size() > 0 && !oprUnit->isWildCardField() ) { qgmDbAttrPtrVec attrs ; qgmDbAttrPtrVec::iterator itAttr ; newCopy = SDB_OSS_NEW qgmFilterUnit( *filterUnit, filterUnit->isFieldsOptional() ? FALSE : QGM_OPR_FILTER_COPY_FLAG ) ; if ( !newCopy ) { rc = SDB_OOM ; goto error ; } filterUnit->getCondFields( attrs ) ; itAttr = attrs.begin() ; while ( itAttr != attrs.end() ) { newCopy->addOpField( qgmOpField( *(*itAttr), SQL_GRAMMAR::DBATTR ), TRUE ) ; ++itAttr ; } rc = subNode->pushOprUnit( newCopy, curNode, qgmOptiTreeNode::FROM_UP ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "push oprUnit[%s] to subNode[%s] from node[%s] " "failed, rc: %d", newCopy->toString().c_str(), subNode->toString().c_str(), rc ) ; goto error ; } } } else { result = OPT_SS_ACCEPT ; } done: return rc ; error: if ( newCopy ) { SDB_OSS_DEL newCopy ; } 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 ; }