示例#1
0
   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 ;
   }
示例#4
0
   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 ;
   }
示例#5
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 ;
}