.nf
 
 
    ========== licence begin  GPL
    Copyright (c) 2000-2004 SAP AG
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
 
.fo
*****************************************************
Copyright (c) 2000-2004 SAP AG
SAP Database Technology
 
Release :      Date : 2000-10-23
*****************************************************
modname : VAK651
changed : 2000-10-23
module  : Const_Expression
 
Author  : ElkeZ
Created : 1985-10-16
*****************************************************
 
Purpose : Processing const expression with and without parameter
 
Define  :
 
        PROCEDURE
              a651const_between_expression (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    st_begin       : integer;
                    op             : tgg00_StackOpType);
 
        PROCEDURE
              a651in_const_expression (
                    VAR acv     : tak_all_command_glob;
                    VAR dmli    : tak_dml_info;
                    st_begin    : tsp00_Int2;
                    st_end      : tsp00_Int2);
 
        PROCEDURE
              a651code_for_const_param_expr
                    (VAR acv : tak_all_command_glob;
                    VAR dmli    : tak_dml_info;
                    st_begin    : tsp00_Int2;
                    expr_st_cnt : tsp00_Int2);
 
        PROCEDURE
              a651value_calculate (
                    VAR acv  : tak_all_command_glob;
                    st_begin : integer;
                    st_end   : integer;
                    byte_str : boolean;
                    like     : boolean;
                    iolen    : tsp00_Int2;
                    err_pos  : tsp00_Int4);
 
.CM *-END-* define --------------------------------------
***********************************************************
 
Use     :
 
        FROM
              AK_semantic_scanner_tools : VAK05;
 
        PROCEDURE
              a05qualification_test (
                    VAR acv        : tak_all_command_glob;
                    VAR m          : tgg00_MessBlock;
                    result_wanted  : boolean;
                    check_new_rec  : boolean;
                    error_pos      : integer;
                    VAR rec        : tsp00_MoveObj;
                    VAR result     : tsp00_MoveObj;
                    resultBufSize  : tsp00_Int4;
                    VAR result_len : integer);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK07;
 
        PROCEDURE
              a07_b_put_error (
                    VAR acv : tak_all_command_glob;
                    b_err   : tgg00_BasisError;
                    err_code : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalMove   (
                    mod_id         : tsp00_C6;
                    mod_intern_num : tsp00_Int4;
                    size1          : tsp00_Int4;
                    size2          : tsp00_Int4;
                    val1           : tsp00_MoveObjPtr;
                    p1             : tsp00_Int4;
                    val2           : tsp00_MoveObjPtr;
                    p2             : tsp00_Int4;
                    cnt            : tsp00_Int4;
                    VAR e          : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalOverlappingMove  (
                    mod_id         : tsp00_C6;
                    mod_intern_num : tsp00_Int4;
                    size1          : tsp00_Int4;
                    size2          : tsp00_Int4;
                    val1           : tsp00_MoveObjPtr;
                    p1             : tsp00_Int4;
                    val2           : tsp00_MoveObjPtr;
                    p2             : tsp00_Int4;
                    cnt            : tsp00_Int4;
                    VAR e          : tgg00_BasisError);
 
        PROCEDURE
              g10mv (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              s10mv (
                    source_upb  : tsp00_Int4;
                    destin_upb  : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    source_pos  : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    destin_pos  : tsp00_Int4;
                    length      : tsp00_Int4);
&       ifdef trace
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01qual (debug : tgg00_Debug; VAR part1 : tgg00_QualBuf);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01messblock (
                    debug         : tgg00_Debug;
                    nam           : tsp00_Sname;
                    VAR m         : tgg00_MessBlock);
 
        PROCEDURE
              t01moveobj (
                    debug       : tgg00_Debug;
                    VAR moveobj : tsp00_MoveObj;
                    startpos    : tsp00_Int4;
                    endpos      : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
***********************************************************
 
Synonym :
 
        PROCEDURE
              a05qualification_test;
 
              tgg00_Rec tsp00_MoveObj
              tsp00_Buf     tsp00_MoveObj
 
.CM *-END-* synonym -------------------------------------
***********************************************************
.CM -lll-
Code    :
 
 
CONST
      c_result_wanted = true (* a05qualification_test *);
      c_check_new_rec = true (* a05qualification_test *);
 
 
(*------------------------------*) 
 
PROCEDURE
      a651const_between_expression (
            VAR acv        : tak_all_command_glob;
            VAR dmli       : tak_dml_info;
            st_begin       : integer;
            op             : tgg00_StackOpType);
 
VAR
      expr_st_cnt : tsp00_Int2;
 
BEGIN
WITH acv, a_mblock, mb_qual^, dmli DO
    IF  mfirst_free + 1 > mb_st_max
    THEN
        a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
    ELSE
        BEGIN
&       ifdef TRACE
        t01messblock (ak_sem, 'MBLOCK 651co', a_mblock);
&       endif
        expr_st_cnt := mfirst_free - st_begin +1;
        SAPDB_PascalOverlappingMove ('VAK651',   1,    
              mb_st_size, mb_st_size,
              @mb_st^, (st_begin - 1) * STACK_ENTRY_MXGG00 + 1,
              @mb_st^, (st_begin + 1) * STACK_ENTRY_MXGG00 + 1,
              expr_st_cnt * STACK_ENTRY_MXGG00,
              a_returncode);
        mfirst_free := mfirst_free + 2;
        mqual_cnt   := mqual_cnt + 2;
        WITH mb_st^[st_begin] DO
            BEGIN
            etype := st_value;
            eop   := op_none;
            epos  := mb_st^ [st_begin + 2].epos;
            elen_var := mb_st^ [st_begin + 2].elen_var;
            ecol_tab[1] := cgg04_param_in_between_expr;
            ecol_tab[2] := chr(0);
            END;
        (*ENDWITH*) 
        WITH mb_st^[st_begin+1] DO
            BEGIN
            etype := st_value;
            eop   := op;
            IF  mb_st^ [st_begin + 2].ecol_tab[2] = chr(0)
            THEN
                BEGIN
                epos  := mb_st^ [st_begin + 3].epos;
                elen_var := mb_st^ [st_begin + 3].elen_var;
                END
            ELSE
                BEGIN
                epos  := mb_st^ [st_begin + 3 +
                      ord(mb_st^[st_begin + 2].ecol_tab[2])].epos;
                elen_var := mb_st^ [st_begin + 3 +
                      ord(mb_st^[st_begin + 2].ecol_tab[2])].elen_var;
                END;
            (*ENDIF*) 
            ecol_tab[1] := cgg04_param_in_between_expr;
            ecol_tab[2] := chr(mfirst_free - st_begin - 2);
            END;
        (*ENDWITH*) 
&       ifdef TRACE
        t01messblock (ak_sem, 'MBLOCK 651co', a_mblock);
&       endif
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a651in_const_expression (
            VAR acv     : tak_all_command_glob;
            VAR dmli    : tak_dml_info;
            st_begin    : tsp00_Int2;
            st_end      : tsp00_Int2);
 
VAR
      index            : integer;
      expr_cnt         : integer;
      last_entry       : integer;
      free             : integer;
      mv_entry_cnt     : integer;
      next_expr_st_ptr : integer;
      no_optimize      : boolean;
 
BEGIN
WITH acv.a_mblock.mb_qual^ DO
    BEGIN
&   ifdef TRACE
    t01qual( ak_sem, acv.a_mblock.mb_qual^ );
    t01int4(ak_sem,'st_begin    ',st_begin);
    t01int4(ak_sem,'st_end      ',st_end);
&   endif
    no_optimize  := false;
    index        := st_begin;
    free         := mfirst_free;
    mv_entry_cnt := 0;
    WHILE ( index < st_end ) AND NOT no_optimize DO
        BEGIN
        IF  ( acv.a_mblock.mb_st^[ index ].etype = st_value ) AND
            ( acv.a_mblock.mb_st^[ index ].ecol_tab[ 2 ] <> chr( 0 ))
        THEN
            BEGIN
            mv_entry_cnt := succ( mv_entry_cnt );
            no_optimize  := ( free +
                  ord( acv.a_mblock.mb_st^[ index ].ecol_tab[ 2 ] ) + 1 >
                  acv.a_mblock.mb_st_max ) OR
                  ( st_end - st_begin + mv_entry_cnt > 255 );
            free := succ( free );
            END;
        (*ENDIF*) 
        index := succ( index );
        END;
    (*ENDWHILE*) 
    IF  ( NOT no_optimize )
    THEN
        BEGIN
        index      := st_begin;
        last_entry := st_end;
        WHILE ( index < last_entry ) DO
            BEGIN
            WHILE ( index < last_entry ) AND
                  ( acv.a_mblock.mb_st^[ index ].etype = st_value ) AND
                  ( acv.a_mblock.mb_st^[ index ].ecol_tab[ 2 ] = chr( 0 )) DO
                index := succ( index );
            (*ENDWHILE*) 
            IF  ( index < last_entry )
            THEN
                BEGIN
                expr_cnt := ord( acv.a_mblock.mb_st^ [index].ecol_tab[ 2 ] );
                g10mv ('VAK651',   2,    
                      acv.a_mblock.mb_st_size, acv.a_mblock.mb_st_size,
                      @acv.a_mblock.mb_st^, ( index - 1 ) * STACK_ENTRY_MXGG00 + 1,
                      @acv.a_mblock.mb_st^, ( mfirst_free - 1 ) * STACK_ENTRY_MXGG00 + 1,
                      ( expr_cnt + 1 ) * STACK_ENTRY_MXGG00,
                      acv.a_returncode);
                SAPDB_PascalOverlappingMove ('VAK651',   3,    
                      acv.a_mblock.mb_st_size, acv.a_mblock.mb_st_size,
                      @acv.a_mblock.mb_st^, ( index + expr_cnt ) * STACK_ENTRY_MXGG00+1,
                      @acv.a_mblock.mb_st^, index * STACK_ENTRY_MXGG00 + 1,
                      ( mfirst_free - index ) * STACK_ENTRY_MXGG00,
                      acv.a_returncode);
                mfirst_free := succ( mfirst_free );
                mqual_cnt   := succ( mqual_cnt );
                last_entry  := last_entry - expr_cnt;
                acv.a_mblock.mb_st^[ index ].ecol_tab[ 1 ] := cgg04_param_in_in_expr;
                END;
            (*ENDIF*) 
            index := succ( index );
            END;
        (*ENDWHILE*) 
        index            := st_begin;
        next_expr_st_ptr := last_entry + 1;
        WHILE ( index < last_entry ) DO
            BEGIN
            IF  ( acv.a_mblock.mb_st^[ index ].etype = st_value ) AND
                ( acv.a_mblock.mb_st^[ index ].ecol_tab[ 1 ] =
                cgg04_param_in_in_expr )
            THEN
                BEGIN
                acv.a_mblock.mb_st^ [index].ecol_tab[ 2 ] :=
                      chr( next_expr_st_ptr - index );
                next_expr_st_ptr := next_expr_st_ptr +
                      ord( acv.a_mblock.mb_st^[ next_expr_st_ptr ].ecol_tab[ 2 ]) + 1;
                END;
            (*ENDIF*) 
            index := succ( index );
            END;
        (*ENDWHILE*) 
        acv.a_mblock.mb_st^[ last_entry ].ecol_tab[ 2 ] :=
              chr( mfirst_free - last_entry - 1 );
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
&ifdef TRACE
t01qual( ak_sem, acv.a_mblock.mb_qual^ );
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      a651code_for_const_param_expr (
            VAR acv     : tak_all_command_glob;
            VAR dmli    : tak_dml_info;
            st_begin    : tsp00_Int2;
            expr_st_cnt : tsp00_Int2);
 
VAR
      delta       : tsp00_Int2;
      first_entry : tsp00_Int2;
      expr_cnt    : tsp00_Int2;
      st_param    : tsp00_Int2;
      index       : tsp00_Int2;
 
BEGIN
&ifdef trace
t01int4 (ak_sem, 'st_begin    ',st_begin);
t01int4 (ak_sem, 'd_param_st_b',dmli.d_param_st_begin);
t01int4 (ak_sem, 'expr_st_cnt ',expr_st_cnt);
t01int4 (ak_sem, 'd_where_part',ord(dmli.d_wherepart));
&endif
WITH acv, dmli, a_mblock, mb_qual^ DO
    IF  NOT d_like                                                  AND
        NOT d_pseudo_ins_select                                     AND
        (* PTS 1112767 E.Z. *)
        (st_begin > 0)                                              AND
        ((st_begin <> mfirst_free - 1)       OR
        ((expr_st_cnt = 1) AND (mb_st^ [st_begin].eop <> op_none))) AND
        ((d_wherepart AND NOT d_single_expr) OR
        ( st_begin <> d_param_st_begin)      OR
        ( NOT d_wherepart AND NOT d_having))
    THEN
        BEGIN
        IF  d_param_st_begin = 0
        THEN
            IF  mfirst_free > mb_st_max
            THEN
                a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
            ELSE
                BEGIN
&               ifdef TRACE
                t01messblock (ak_sem, 'MBLOCK 651co', a_mblock);
&               endif
                SAPDB_PascalOverlappingMove ('VAK651',   4,    
                      mb_st_size, mb_st_size,
                      @mb_st^, (st_begin - 1) * STACK_ENTRY_MXGG00 + 1,
                      @mb_st^, (st_begin) * STACK_ENTRY_MXGG00 + 1,
                      expr_st_cnt * STACK_ENTRY_MXGG00,
                      a_returncode);
                WITH mb_st^ [st_begin] DO
                    BEGIN
                    etype    := st_value;
                    eop      := op_none;
                    epos     := mb_st^ [st_begin + 1].epos;
                    elen_var := mb_data_len -
                          mb_st^ [st_begin + 1].epos + 1;
                    ecol_tab[ 1 ] := chr(0);
                    ecol_tab[ 2 ] := chr (expr_st_cnt);
                    END;
                (*ENDWITH*) 
                first_entry := st_begin;
                expr_cnt := expr_st_cnt;
                d_param_st_index := d_param_st_index + 1;
                mfirst_free := succ(mfirst_free);
                mqual_cnt   := succ(mqual_cnt);
                IF  d_sparr.pparsp <> NIL
                THEN
                    d_sparr.pparsp^.sparsinfo.p_bool_states :=
                          d_sparr.pparsp^.sparsinfo.p_bool_states +
                          [ pi_const_param_expr ];
                (*ENDIF*) 
                d_param_st_begin := st_begin;
&               ifdef TRACE
                t01messblock (ak_sem, 'MBLOCK 651co', a_mblock);
&               endif
                END
            (*ENDIF*) 
        ELSE
            BEGIN
&           ifdef TRACE
            t01messblock (ak_sem, 'MBLOCK 651co', a_mblock);
&           endif
            IF  d_param_st_begin > st_begin
            THEN (* operation *)
                BEGIN
                (* this procedure was called earlier. 3 + :p1 - :p2  *)
                (* There is an special value-stackentry, which       *)
                (* describes a result-value on                       *)
                (* mb_st^[ d_param_st_begin ]                        *)
                (* This is destroyed by moving everything beforehand *)
                (* one stackentry to the right                       *)
                (* d_param_st_index (parameter-stackentry) >         *)
                (* d_param_st_begin ==> the param-stackentry will NOT*)
                (* be moved                                          *)
                first_entry := st_begin;
                delta       := d_param_st_begin - st_begin;
                expr_cnt    := expr_st_cnt - 1;
                st_param    := d_param_st_index;
                SAPDB_PascalOverlappingMove ('VAK651',   5,    
                      mb_st_size, mb_st_size,
                      @mb_st^, (st_begin - 1) * STACK_ENTRY_MXGG00 + 1,
                      @mb_st^, (st_begin) * STACK_ENTRY_MXGG00 + 1,
                      delta * STACK_ENTRY_MXGG00,
                      a_returncode);
                END
            ELSE (* build_in_function *)
                BEGIN
                first_entry := d_param_st_begin;
                delta       := st_begin - d_param_st_begin;
                expr_cnt    := mfirst_free - first_entry - 1;
                st_param    := st_begin + 1;
                END;
            (*ENDIF*) 
&           ifdef trace
            t01int4 ( ak_sem, 'delta       ', delta);
            t01int4 ( ak_sem, 'first_entry ',first_entry);
            t01int4 ( ak_sem, 'expr_cnt    ',expr_cnt);
&           endif
            WITH mb_st^ [first_entry] DO
                BEGIN
                etype    := st_value;
                eop      := op_none;
                epos     := mb_st^ [st_param].epos;
                elen_var := mb_st^ [st_param].elen_var;
                ecol_tab[ 1 ] := chr(0);
                ecol_tab[ 2 ] := chr (expr_cnt);
                END;
            (*ENDWITH*) 
            d_param_st_begin := first_entry;
&           ifdef TRACE
            t01messblock (ak_sem, 'MBLOCK 651co', a_mblock);
&           endif
            END;
        (*ENDIF*) 
        index := first_entry+1;
        WHILE (index < first_entry+expr_cnt) DO
            BEGIN
            IF  (mb_st^[ index ].etype = st_value) AND
                ((mb_st^[ index ].ecol_tab[ 1 ] in
                [ cgg04_param_in_between_expr, cgg04_param_in_in_expr]) OR
                ((mb_st^[ index ].ecol_tab[ 1 ] = chr(0)) AND
                (mb_st^[ index ].ecol_tab[ 2 ] <> chr(0))))
            THEN
                BEGIN
                mb_st^[ index ].etype := st_dummy;
                index := index +
                      ord(mb_st^[ index ].ecol_tab[ 2 ] <> chr(0))
                END
            ELSE
                index := succ(index)
            (*ENDIF*) 
            END
        (*ENDWHILE*) 
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a651value_calculate (
            VAR acv  : tak_all_command_glob;
            st_begin : integer;
            st_end   : integer;
            byte_str : boolean;
            like     : boolean;
            iolen    : tsp00_Int2;
            err_pos  : tsp00_Int4);
 
VAR
      m_pos      : integer;
      m_cnt      : integer;
      result_len : integer;
 
BEGIN
WITH acv, a_mblock, mb_qual^ DO
    IF  ((st_end > st_begin) OR
        ( mb_st^ [st_end].eop <> op_none )) AND
        NOT like
    THEN
        BEGIN
        m_pos  := mqual_pos;
        m_cnt  := mqual_cnt;
        mqual_pos := st_begin;
        mqual_cnt := st_end - st_begin + 2;
        WITH mb_st^ [st_end + 1] DO
            BEGIN
            etype         := st_output;
            eop_out       := op_o_output_not_fill;
            epos          := mb_st^ [st_begin].epos;
            elen_var      := iolen;
            IF  byte_str
            THEN
                ecol_tab[ 1 ] := chr(1)
            ELSE
                ecol_tab[ 1 ] := chr(0);
            (*ENDIF*) 
            ecol_tab[ 2 ] := chr(0);
            END;
        (*ENDWITH*) 
        mfirst_free              := mqual_pos + mqual_cnt;
        a_mblock.mb_work_st      := a_work_st_addr;
        a_mblock.mb_work_st_max  := a_work_st_max;
        a_mblock.mb_workbuf      := a_work_buf_addr;
        a_mblock.mb_workbuf_size := a_work_buf_size;
&       ifdef trace
        t01messblock (ak_sem, 'MBLOCK a05qu', a_mblock);
        t01int4 (ak_sem, 'st_begin    ',st_begin);
        t01int4 (ak_sem, 'st_end      ',st_end);
&       endif
        a05qualification_test (acv, a_mblock,
              c_result_wanted, c_check_new_rec, err_pos,
              mb_data^.mbp_buf,
              mb_data^.mbp_buf, mb_data_size, result_len);
&       ifdef trace
        t01int4 (ak_sem,'laenge      ', result_len);
        t01moveobj (ak_sem, mb_data^.mbp_buf, mb_st^[st_begin].epos,
              mb_st^[st_begin].epos + result_len - 1 );
&       endif
        WITH mb_st^ [st_begin] DO
            BEGIN
            etype         := st_value;
            eop           := op_none;
            epos          := epos;
            elen_var      := result_len;
            ecol_tab[ 1 ] := chr(0);
            ecol_tab[ 2 ] := chr(0);
            END;
        (*ENDWITH*) 
        mb_data_len := mb_st^ [st_begin].epos + result_len;
        mfirst_free := st_begin + 1;
        mqual_cnt   := m_cnt - st_end + st_begin;
        mqual_pos   := m_pos;
        IF  a_returncode <> 0
        THEN
            a_transinf.tri_trans.trState_gg00 :=
                  a_mblock.mb_trns^.trState_gg00
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
