Beispiel #1
0
   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 ;
   }
Beispiel #2
0
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 ;
}