Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions

tgg00_BasisError Join_JoinOperator2::next ( tgg00_Rec **  records  )  [protected, virtual]

Parameters:
recptr [in/out] pointer to memory should be filled with record
Returns:
information code [e_ok, e_no_next_record] / error code

Implements IOperator.

Definition at line 366 of file Join_JoinOperator2.cpp.

References SAPDB_AutoPtr< T >::GetPtr(), SQLMan_Context::IsOk(), IOperator::m_acv, IOperator::m_Startkeys, IOperator::m_Stopkeys, SAPDB_MemCopyNoCheck(), and SQLMan_Context::TransContext().

Referenced by Next().

{
    SAPDBTRACE_METHOD_DEBUG( "Join_JoinOperator2::next(<vector>)", Join_Trace, 1 );
    tgg00_BasisError _left_err  = e_ok;
    tgg00_BasisError _right_err = e_ok;
    tgg00_BasisError _b_err;

    do
    {
        _b_err = e_ok;
        if ( ! m_AppendRightOuterJoinRecords )
        {
            if ( m_GetLeftTupel )
            {
                m_GetLeftTupel    = false;
                m_LeftRecChanged  = false;
                m_LeftRecJoined = false;
                SAPDBTRACE_WRITELN( Join_Trace, 3, "<< get next left record from " << m_RightTableIdx - 1 << ". tab" );
                _left_err = m_LeftOp->next( records );
                if ( e_no_next_record == _left_err )
                {
                    if ( m_JoinInfo.jn_rightoj )
                    {
                        m_AppendRightOuterJoinRecords = true;
                    }
                    else
                    {
                        // don't close left file to ensure repeatable Next() operation
                        //m_LeftOp->Close();

                        // inner join and no left record 
                        SAPDBTRACE_WRITELN( Join_Trace, 5, "end of Next @ " << (void *)this );
                        SAPDBTRACE_WRITELN( Join_Trace, 5, "because of left e_no_next_record" );
                        return e_no_next_record;
                    }
                }
                else if ( e_ok == _left_err )
                {
                    SAPDBTRACE_WRITELN( Join_Trace, 3, "left record (len=" << m_LeftOp->GetRecordLength() << ") @ " << (void *) this );
                    if ( a70glob_join_strats.includes( m_RightAccessStrat ) )
                        // set m_Startkeys, m_Stopkeys
                        _right_err = prepare_right_key( records );
                    else
                        _right_err = e_ok;
                }
                else
                    return _left_err;
            }

            if ( e_ok == _left_err )
            {
                SAPDB_Bool _joining;
                
                // open right operator
                if ( ! m_RightOp->IsOpened() )
                {
                    if ( a70glob_join_strats.includes( m_RightAccessStrat ) )
                    {
                        if ( m_JoinInfo.jn_rightoj && never_scanned == m_TableForRightOuterJoinScanStat )
                        {
                            SAPDBTRACE_WRITELN( Join_Trace, 5, "scan for RIGHT OUTER JOIN" );
                            _right_err = m_RightOp->Open();
                        }
                        else
                            _right_err = m_RightOp->Open( m_Startkeys, m_Stopkeys );
                    }
                    else
                        // use one table strategy
                        _right_err = m_RightOp->Open();
                }

                do 
                {
                    SAPDBTRACE_WRITELN( Join_Trace, 3, ">> get next right record from " << m_RightTableIdx << ". tab (" << m_RightAccessStrat << ")");
                    if ( e_ok == _right_err ) 
                        _right_err = m_RightOp->next( records );
                    if ( e_ok == _right_err )
                    {
                        if ( never_scanned == m_TableForRightOuterJoinScanStat )
                            m_TableForRightOuterJoinScanStat = while_scanning;

                        if ( _joining = this->join( records, _b_err ) ) 
                            m_LeftRecJoined = true;
                            
                        if ( m_JoinInfo.jn_rightoj )
                        {
                            if ( !_joining && while_scanning == m_TableForRightOuterJoinScanStat )
                            {
                                /* !!! RIGHT OUTER JOIN !!! */
                                // add record with no join to auxiliary file
                                SAPDBTRACE_WRITELN( Join_Trace, 3, "add to ROJ aux file" << " m_AuxRightOuterKeyLen: " << m_AuxRightOuterKeyLen );

                                (*(records+(m_RightTableIdx-1)))->recLen_gg00()    = m_RightOp->GetRecordLength();
                                (*(records+(m_RightTableIdx-1)))->recKeyLen_gg00() = m_AuxRightOuterKeyLen;
                                (*(records+(m_RightTableIdx-1)))->recVarcolOffset_gg00() = 0;
                                (*(records+(m_RightTableIdx-1)))->recVarcolCnt_gg00()    = 0;
                                
                                SAPDBTRACE_IF( Join_Trace, 4, 
                                t01buf( td_always, (*(records+(m_RightTableIdx-1))), 1, (*(records+(m_RightTableIdx-1)))->recLen_gg00() <= 300 ? (*(records+(m_RightTableIdx-1)))->recLen_gg00() : 300 ));
                                b07cadd_record( m_acv.TransContext(), m_AuxRightOuterJoinFile, *(*(records+(m_RightTableIdx-1))) );
                                _right_err = m_acv.TransContext().trError_gg00;
                            }

                            if ( _joining && already_scanned == m_TableForRightOuterJoinScanStat )
                            {
                                SAPDBTRACE_WRITELN( Join_Trace, 3, "delete from ROJ aux file" );
                                SAPDBTRACE_IF( Join_Trace, 4, 
                                t01buf( td_always, &((*(records+(m_RightTableIdx-1)))->recBuf_gg00()), 1, m_RightOp->GetRecordLength() <= 300 ? m_RightOp->GetRecordLength() : 300 ));
                                
                                tgg00_Lkey _key;
                                _key.keyLen_gg00() = m_AuxRightOuterKeyLen;
                                SAPDB_MemCopyNoCheck( &_key.keyVal_gg00(), 
                                        &((*(records+(m_RightTableIdx-1)))->recKey_gg00().keyVal_gg00()),
                                        m_AuxRightOuterKeyLen );
                                SAPDBTRACE_IF( Join_Trace, 3, 
                                    t01key( td_always, "key         ", _key ));
                                b07cdel_record( m_acv.TransContext(), m_AuxRightOuterJoinFile, _key );
                                // ignore already joined records
                                if ( e_key_not_found == m_acv.TransContext().trError_gg00 )
                                    m_acv.TransContext().trError_gg00 = e_ok;
                                _right_err = m_acv.TransContext().trError_gg00;
                            }
                        }
                    }

                    // test for command canceling
                    if ( m_acv.TransContext().trRteCommPtr_gg00->to_cancel )
                        _right_err = e_cancelled;
                }
                while ( e_ok == _right_err && !_joining );

                if ( e_no_next_record == _right_err )
                {
                    // no more right records -> switch inner state
                    m_GetLeftTupel = true;
                    if ( while_scanning == m_TableForRightOuterJoinScanStat )
                        m_TableForRightOuterJoinScanStat = already_scanned;
                    if ( !m_LeftRecJoined && m_JoinInfo.jn_leftoj )
                    {
                        SAPDBTRACE_WRITELN( Join_Trace, 5, "append LEFT OUTER record " );
                        /* !!! LEFT OUTER JOIN !!! */
                        _right_err = m_RightOp->get_null_record( records );
                    }
                    m_RightOp->Close();
                }
            }
        }

        if ( m_AppendRightOuterJoinRecords )
        {
            SAPDBTRACE_WRITELN( Join_Trace, 5, "append RIGHT OUTER record " );
            
            // tie NULL record on left side
            _left_err = m_LeftOp->get_null_record( records );
            if  ( e_ok != _left_err ) return _left_err;

            if ( never_scanned == m_TableForRightOuterJoinScanStat )
            {
                SAPDBTRACE_WRITELN( Join_Trace, 5, "right tab never scanned" );
                /* !!! RIGHT OUTER JOIN for empty left table !!! */
                // left table delivers no records, therfore m_AuxRightOuterJoinFile
                // is empty but we have to select whole right table
                
                if ( ! m_RightOp->IsOpened() ) _right_err = m_RightOp->Open();

                if ( e_ok == _right_err )
                    _right_err = m_RightOp->next( records );

                if  ( e_no_next_record == _right_err )
                {
                    m_RightOp->Close();
                    m_GetLeftTupel = true;
                }
            }
            else
            {
                tgg00_BdSetResultRecord _set_result;
                _set_result.bd_key_check_len = 0;
                _set_result.bd_max_rec_cnt   = 1;
                _set_result.bd_max_fill_len  = m_RightOp->GetRecordLength();
                _set_result.bd_next          = true;
                _set_result.bd_drop_page     = false;
                
                // fill m_RightAuxRec with unmatched right record 
                b07cnext_record( m_acv.TransContext(), 
                        m_AuxRightOuterJoinFile, 
                        m_AuxRightOuterJoinKey, _set_result, 
                        m_AuxRightOuterJoinFilePos, 
                        m_RightAuxRec.GetPtr() );
                if ( e_key_not_found == m_acv.TransContext().trError_gg00 )
                    m_acv.TransContext().trError_gg00 = e_ok;
                if ( e_ok == m_acv.TransContext().trError_gg00 )
                {
                    SAPDBTRACE_IF( Join_Trace, 3, 
                    t01buf( td_always, m_RightAuxRec.GetPtr(), 1, 
                        m_RightAuxRec->recLen_gg00() <= 300 ? 
                        m_RightAuxRec->recLen_gg00() : 300 ));

                    *(records+(m_RightTableIdx-1)) = m_RightAuxRec.GetPtr();
                }
                _right_err = m_acv.TransContext().trError_gg00;
            }

            if ( e_no_next_record == _right_err )
            {
                // don't close left file to ensure repeatable Next() operation
                // m_LeftOp->Close();

                // RIGHT OUTER JOIN and no more right records
                SAPDBTRACE_WRITELN( Join_Trace, 5, 
                        "end of Next @ " << (void *)this );
                SAPDBTRACE_WRITELN( Join_Trace, 5, 
                        "because of ROJ e_no_next_record" );
                return e_no_next_record;
            }
        } // m_AppendRightOuterJoinRecords
    }
    while ( e_no_next_record == _right_err && e_ok == _b_err && m_acv.IsOk() );

    // reach this if _right_err == _b_err == e_ok or sudden error situation
    
    SAPDBTRACE_WRITELN( Join_Trace, 5, "end of Next @ " << (void *)this );
#ifdef SAPDB_SLOW
    if ( e_ok != _b_err )
    {
        SAPDBTRACE_WRITELN( Join_Trace, 5, "return "  << SAPDBTrace::BasisError(_b_err) );
    }
    else
    {
        SAPDBTRACE_WRITELN( Join_Trace, 5, "return "  << SAPDBTrace::BasisError(_right_err) );
    }
#endif
    return ( e_ok != _b_err) ? _b_err : _right_err;
}


Generated by  Doxygen 1.6.0   Back to index