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 _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 ; }