.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2004 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VAK661$
.tt 2 $$$
.TT 3 $ElkeZ$Subquery_handling$2000-04-04$
***********************************************************
.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
.nf
.sp
MODULE  : Subquery_handling
=========
.sp
Purpose : First part of processing mass selects
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              a661_corr_sub (
                    VAR acv                     : tak_all_command_glob;
                    VAR dmli                    : tak_dml_info;
                    s_n                         : integer;
                    filled_part2_bytes          : integer;
                    VAR sr_rec                  : tak70_strat_rec;
                    VAR pseudo_resultset_select : boolean;
                    last_corr_query             : boolean;
                    level                       : integer;
                    no_in_level                 : integer);
 
        PROCEDURE
              a661_update_keys_of_parsrecords
                    (VAR acv    : tak_all_command_glob;
                    old_p_id    : tsp00_C1;
                    VAR lowpars : tsp00_Uint1;
                    old_lowpars : tsp00_Uint1);
 
        PROCEDURE
              a661_build_t_fromsel_tableid (
                    VAR syskey_tableid  : tgg00_Surrogate;
                    VAR fn_tableid      : tgg00_Surrogate;
                    VAR curr_ex_parskey : tak_parskey;
                    site                : tgg00_ServerdbNo;
                    from_select_no      : tsp00_Int2);
 
        FUNCTION
              a661_fromsel_found (
                    VAR acv : tak_all_command_glob;
                    sub_n : integer) : boolean;
 
        PROCEDURE
              a661del_all_fromtabs (
                    VAR acv : tak_all_command_glob;
                    sub_n : integer);
 
        PROCEDURE
              a661_fdelete_fromtab_results (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a661a_subquery (
                    VAR acv                     : tak_all_command_glob;
                    VAR dmli                    : tak_dml_info;
                    VAR sr_rec                  : tak70_strat_rec;
                    curr_n                      : tsp00_Int2;
                    VAR pseudo_resultset_select : boolean);
 
        PROCEDURE
              a661_get_from_select_table (
                    VAR acv     : tak_all_command_glob;
                    VAR tableid : tgg00_Surrogate;
                    VAR pbasep  : tak_sysbufferaddress;
                    dstate      : tak_directory_state;
                    all         : boolean;
                    VAR f_ok    : boolean);
 
        PROCEDURE
              a661get_from_select_table (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    from_select_no : tsp00_Int2;
                    all            : boolean);
 
        PROCEDURE
              a661_sub_build (
                    VAR acv               : tak_all_command_glob;
                    VAR dmli              : tak_dml_info;
                    sub_n                 : integer;
                    filled_part2_bytes    : integer;
                    VAR sr_rec            : tak70_strat_rec);
 
        FUNCTION
              a661_is_fromsel_table (
                    VAR acv     : tak_all_command_glob;
                    VAR ftreeid : tgg00_FileId) : boolean;
 
        PROCEDURE
              a661exec_sub (
                    VAR acv                 : tak_all_command_glob;
                    VAR dmli                : tak_dml_info;
                    VAR parsk               : tak_parskey;
                    curr_n                  : tsp00_Int2;
                    VAR del_cnt             : integer;
                    m_acv_info_output       : boolean;
                    pseudo_resultset_select : boolean);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              Scanner : VAK01;
 
        VAR
              a01sysnullkey        : tgg00_SysInfoKey;
              a01_il_b_identifier   : tsp00_KnlIdentifier;
 
      ------------------------------ 
 
        FROM
              AK_universal_semantic_tools : VAK06;
 
        PROCEDURE
              a06reset_retpart (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a06finish_curr_retpart (
                    VAR acv   : tak_all_command_glob;
                    part_kind : tsp1_part_kind;
                    arg_count : tsp00_Int2);
 
      ------------------------------ 
 
        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
              AK_error_handling : VAK071;
 
        FUNCTION
              a07_return_code (
                    b_err   : tgg00_BasisError;
                    sqlmode : tsp00_SqlMode) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              Systeminfo_cache : VAK10;
 
        PROCEDURE
              a10del_sysinfo (
                    VAR acv     : tak_all_command_glob;
                    VAR syskey  : tgg00_SysInfoKey;
                    VAR b_err   : tgg00_BasisError);
 
        PROCEDURE
              a10_rel_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syskey   : tgg00_SysInfoKey);
 
        PROCEDURE
              a10get_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syskey   : tgg00_SysInfoKey;
                    dstate       : tak_directory_state;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10repl_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10_upd_key (
                    VAR acv   : tak_all_command_glob;
                    VAR p     : tak_parskey;
                    diff      : integer;
                    VAR b_err : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              Executing_dispatcher : VAK501;
 
        PROCEDURE
              a501do_execute (
                    VAR acv                 : tak_all_command_glob;
                    VAR dmli                : tak_dml_info;
                    VAR parsk               : tak_parskey;
                    output_during_execution : boolean);
 
        PROCEDURE
              a501exec_with_change_rec (
                    VAR acv                 : tak_all_command_glob;
                    VAR dmli                : tak_dml_info;
                    VAR parsk               : tak_parskey;
                    VAR change_rec          : tak_changerecord;
                    output_during_execution : boolean);
 
      ------------------------------ 
 
        FROM
              Long-Support-Getval: VAK508;
 
        PROCEDURE
              a508_lget_long_columns (
                    VAR acv             : tak_all_command_glob;
                    VAR change_rec      : tak_changerecord;
                    VAR lcol_lock       : boolean;
                    rec_cnt             : integer;
                    rec_len             : integer;
                    startpos            : integer);
 
        FUNCTION
              a508_lcol_found (
                    VAR acv        : tak_all_command_glob;
                    VAR change_rec : tak_changerecord) : boolean;
 
      ------------------------------ 
 
        FROM
              DML_Help_Procedures : VAK54;
 
        PROCEDURE
              a54_get_pparsp_pinfop (
                    VAR acv   : tak_all_command_glob;
                    VAR sparr : tak_syspointerarr;
                    mtype     : tgg00_MessType);
 
        PROCEDURE
              a54set_complex_entry (
                    VAR acv     : tak_all_command_glob;
                    call_reason : tak_complex_call_reason);
 
        PROCEDURE
              a54_loc_temp_locks (
                    VAR acv   : tak_all_command_glob;
                    globstate : tgg00_HandlingSet;
                    VAR sparr : tak_syspointerarr);
 
        PROCEDURE
              a54_shortinfo_to_varpart (
                    VAR acv   : tak_all_command_glob;
                    store_cmd : boolean;
                    VAR infop : tak_sysbufferaddress);
 
      ------------------------------ 
 
        FROM
              Select_Syntax : VAK60;
 
        PROCEDURE
              a60_change_results (
                    VAR acv        : tak_all_command_glob;
                    VAR data       : tsp00_MoveObj;
                    VAR change_rec : tak_changerecord;
                    startpos       : integer;
                    curr_resreclen : integer);
 
        PROCEDURE
              a60_put_result (
                    VAR acv    : tak_all_command_glob;
                    VAR mblock : tgg00_MessBlock;
                    spos      : integer);
 
        PROCEDURE
              a60rescount (
                    VAR acv  : tak_all_command_glob;
                    rescount : tsp00_Int4);
 
        PROCEDURE
              a60_get_longinfobuffer (
                    VAR acv   : tak_all_command_glob;
                    VAR sparr : tak_syspointerarr;
                    col_cnt   : integer;
                    resultno  : tsp00_Int4);
 
        PROCEDURE
              a60_columnnames_return (
                    VAR acv   : tak_all_command_glob;
                    pcolnamep : tak_sysbufferaddress);
 
      ------------------------------ 
 
        FROM
              Execute_Select_Expression : VAK660;
 
        PROCEDURE
              a660select (
                    VAR acv                     : tak_all_command_glob;
                    startnode                   : tsp00_Int2;
                    VAR dmli                    : tak_dml_info;
                    VAR pseudo_resultset_select : boolean);
 
        PROCEDURE
              a660_query_execute (
                    VAR acv                     : tak_all_command_glob;
                    VAR dmli                    : tak_dml_info;
                    s_n                         : integer;
                    new_parsinfo                : boolean;
                    filled_part2_bytes          : integer;
                    VAR sr_rec                  : tak70_strat_rec;
                    VAR pseudo_resultset_select : boolean;
                    level                       : integer;
                    no_in_level                 : integer;
                    from_sel_found              : boolean);
 
        PROCEDURE
              a660_new_pparsp (
                    VAR acv        : tak_all_command_glob;
                    VAR sparr      : tak_syspointerarr;
                    needs_twuseold : boolean;
                    complicate     : boolean);
 
        PROCEDURE
              a660_prefix_delete (
                    VAR acv       : tak_all_command_glob;
                    VAR parsk     : tak_parskey;
                    VAR del_cnt   : integer;
                    prefix_length : integer);
 
      ------------------------------ 
 
        FROM
              Union_handling : VAK662;
 
        PROCEDURE
              a662_start_union_select (
                    VAR acv                     : tak_all_command_glob;
                    startnode                   : tsp00_Int2;
                    VAR dmli                    : tak_dml_info;
                    VAR pseudo_resultset_select : boolean;
                    VAR parsk                   : tak_parskey);
 
      ------------------------------ 
 
        FROM
              Resultname_handling : VAK663;
 
        PROCEDURE
              a663_del_result (
                    VAR acv          : tak_all_command_glob;
                    VAR resname_rec  : tak_resname_record;
                    do_cdel          : boolean;
                    del_resname_rec  : boolean);
 
        FUNCTION
              a663parse_for_execute (VAR acv : tak_all_command_glob) : boolean;
 
      ------------------------------ 
 
        FROM
              Resulttable : VAK73;
 
        PROCEDURE
              a73_ex_describe (
                    VAR acv           : tak_all_command_glob;
                    VAR dmli          : tak_dml_info;
                    start_fieldno     : integer;
                    count_in_var_part : boolean);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_1 : VBD01;
 
        PROCEDURE
              b01prefix_destroy_files (
                    VAR t         : tgg00_TransContext;
                    VAR prefix_fn : tgg00_Filename;
                    prefix_len    : integer);
 
      ------------------------------ 
 
        FROM
              Select_Help_Procedures : VGG04;
 
        PROCEDURE
              g04build_temp_tree_id (
                    VAR curr : tgg00_FileId;
                    VAR t : tgg00_TransContext);
 
      ------------------------------ 
 
        FROM
              GG_cpp_auxiliary_functions : VGG06;
 
        PROCEDURE
              gg06SetNilSession (VAR SessionNo : tgg91_SessionNo);
 
        FUNCTION
              gg06IsNilSession (VAR SessionNo : tgg91_SessionNo): boolean;
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalForcedMove  (
                    size1    : tsp00_Int4;
                    size2    : tsp00_Int4;
                    val1     : tsp00_MoveObjPtr;
                    p1       : tsp00_Int4;
                    val2     : tsp00_MoveObjPtr;
                    p2       : tsp00_Int4;
                    cnt      : tsp00_Int4);
 
        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
              t01command_kind (
                    debug        : tgg00_Debug;
                    nam          : tsp00_Sname;
                    command_kind : tak_commandkind);
 
        PROCEDURE
              t01basis_error (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname;
                    b_err : tgg00_BasisError);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01buf  (
                    level     : tgg00_Debug;
                    VAR buf   : tak_systembuffer;
                    pos_start : integer;
                    pos_end   : integer);
&       ENDIF
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              t01buf;
 
              tsp00_Buf tak_systembuffer
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : ElkeZ
.sp
.cp 3
Created : 1985-07-05
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-04-04
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
 
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
 
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      c_output_during_execution= true (* a501do_execute *);
      c_first_parsinfo   = true (* a660_new_pparsp *);
      c_complicate       = true (* a660_new_pparsp *);
      c_new_parsinfo     = true (* a660_query_execute *);
      c_from_sel_found   = true (* a660_query_execute *);
      (*                           ak661a_corr_subquery *)
      c_last_corr_query  = true (* a661_corr_sub *);
      c_do_cdel          = true (* a663_del_result *);
      c_del_resname_rec  = true (* a663_del_result *);
      c_subquery         = true (* a73_ex_describe *);
 
 
(*------------------------------*) 
 
PROCEDURE
      ak661_del_one_fromtab (
            VAR acv   : tak_all_command_glob;
            fromsel_n : integer);
 
VAR
      b_err        : tgg00_BasisError;
      ke           : tgg00_SysInfoKey;
      hbuf         : tak_sysbufferaddress;
      aux_return   : tsp00_Int2;
      aux_errorpos : tsp00_Int4;
      fn_tableid   : tgg00_Surrogate;
 
BEGIN
WITH acv DO
    BEGIN
    aux_return   := acv.a_returncode;
    aux_errorpos := acv.a_errorpos;
    a_returncode := 0;
    ke          := a01sysnullkey;
    (* PTS 1111510 E.Z. *)
    a661_build_t_fromsel_tableid (ke.stableid, fn_tableid,
          a_curr_ex_parskey, cak_fromseltab_site,
          a_ap_tree^[ fromsel_n ].n_pos);
    ke.sentrytyp := cak_eresult;
    ke.slinkage  := cak_init_linkage;
    a10get_sysinfo (acv, ke, d_release, hbuf, b_err);
    IF  (b_err <> e_ok) AND
        (b_err <> e_sysinfo_not_found)
    THEN
        a07_b_put_error (acv, b_err, 1);
    (*ENDIF*) 
    a10del_sysinfo (acv, ke, b_err);
    acv.a_returncode := aux_return;
    acv.a_errorpos   := aux_errorpos;
    (* PTS 1118537 E.Z. *)
    (* in case it is a union, from-selects in that union *)
    (* will not be found by a661del_all_fromtabs, it has *)
    (* to be done somehow                                *)
    WITH a_ap_tree^[a_ap_tree^[fromsel_n].n_lo_level] DO
        IF  (n_proc = a63) AND (n_subproc = cak_x_start_union)
        THEN
            ak661del_union_fromtab (acv, n_lo_level)
        (*ENDIF*) 
    (*ENDWITH*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak661del_union_fromtab (
            VAR acv : tak_all_command_glob;
            union_n : integer);
 
BEGIN
IF  acv.a_ap_tree^[union_n].n_proc = a63query_spec
THEN
    a661del_all_fromtabs (acv, acv.a_ap_tree^[union_n].n_sa_level)
ELSE
    IF  acv.a_ap_tree^[union_n].n_proc = a63
    THEN
        BEGIN
        ak661del_union_fromtab (acv, acv.a_ap_tree^[union_n].n_lo_level);
        ak661del_union_fromtab (acv, acv.a_ap_tree^[union_n].n_sa_level);
        END
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(* PTS END 1118537 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      ak661_fromsub_build (
            VAR acv                 : tak_all_command_glob;
            VAR dmli                : tak_dml_info;
            VAR parsk               : tak_parskey;
            fs_n                    : integer;
            pseudo_resultset_select : boolean;
            VAR sr_rec              : tak70_strat_rec;
            VAR new_complex_rec     : boolean);
 
VAR
      m_fromsel_n   : tsp00_Int2;
      m_select_node : tsp00_Int2;
      next_n        : tsp00_Int2;
      m_d_corr      : tak_corr_type;
      messagetype   : tgg00_MessType;
 
BEGIN
WITH acv, dmli,
     a_ap_tree^[ acv.a_ap_tree^[ fs_n ].n_pos ] DO
    BEGIN
&   IFDEF TRACE
    t01int4 (ak_sem, 'fs_n   start', fs_n);
    t01int4 (ak_sem, 'a_select_nod', a_select_node);
&   ENDIF
    a_outer_join  := false;
    m_fromsel_n   := 0;
    m_select_node := 0;
    m_d_corr      := d_corr;
    IF  (a_returncode = 0)
    THEN
        BEGIN
        m_fromsel_n   := a_fromsel_n;
        a_fromsel_n   := acv.a_ap_tree^[ fs_n ].n_pos;
        m_select_node := a_select_node;
        a_select_node := fs_n;
        next_n        := a_ap_tree^[ fs_n ].n_lo_level;
        IF  (next_n > 0)
        THEN
            IF  (a_ap_tree^[ next_n ].n_proc = a92fromsel)
            THEN
                BEGIN
                ak661_fromsub_build (acv, dmli, parsk, next_n,
                      pseudo_resultset_select, sr_rec, new_complex_rec);
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        next_n := a_ap_tree^[ fs_n ].n_sa_level;
        IF  (next_n > 0)
        THEN
            IF  (a_ap_tree^[ next_n ].n_proc = a92fromsel)
            THEN
                BEGIN
                ak661_fromsub_build (acv, dmli, parsk, next_n,
                      pseudo_resultset_select, sr_rec, new_complex_rec);
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        IF  (a_returncode = 0)
        THEN
            BEGIN
            a_from_select := true;
            IF  (NOT dmli.d_only_sem_check)
            THEN
                IF  new_complex_rec
                THEN
                    BEGIN
                    IF  a_intern_explain
                    THEN
                        messagetype := m_show
                    ELSE
                        messagetype := m_select;
                    (*ENDIF*) 
                    a54_get_pparsp_pinfop (acv, d_sparr, messagetype);
                    new_complex_rec := false;
                    END
                ELSE
                    a660_new_pparsp (acv, dmli.d_sparr,
                          NOT c_first_parsinfo, c_complicate);
                (*ENDIF*) 
            (*ENDIF*) 
            IF  (a_returncode = 0)
            THEN
                BEGIN
                IF  (a_ap_tree^[ fs_n ].n_lo_level > 0)
                THEN
                    BEGIN
                    ak661a_corr_subquery (acv, dmli, parsk, sr_rec,
                          n_lo_level, pseudo_resultset_select,
                          a_ex_kind, a_from_select);
                    END
                ELSE
                    BEGIN
                    a_outer_join           := false;
                    d_subquery             := false;
                    d_corr                 := no_correlation;
                    d_use_sub              := false;
                    d_cntpar               := MAX_COL_PER_TAB_GG00;
                    a660select (acv, a_ap_tree^[ a_fromsel_n ].n_lo_level,
                          dmli, pseudo_resultset_select);
                    a_outer_join := false;
                    a54set_complex_entry (acv, c_set_last_pars);
                    END;
                (*ENDIF*) 
                IF  (m_select_node > 0) AND
                    (m_fromsel_n   > 0)
                THEN (* *** not first call *** *)
                    IF  a_ap_tree^[ m_select_node ].n_lo_level = fs_n
                    THEN
                        a_ap_tree^[ m_select_node ].n_lo_level :=
                              a_ap_tree^[ fs_n ].n_sa_level;
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            d_subquery             := false;
            m_d_corr               := d_corr;
            d_corr                 := no_correlation;
            d_use_sub              := false;
            d_cntpar               := MAX_COL_PER_TAB_GG00;
            END;
        (*ENDIF*) 
        d_corr        := m_d_corr;
        a_fromsel_n   := m_fromsel_n;
        a_select_node := m_select_node;
        END;
    (*ENDIF*) 
    a_from_select := a_fromsel_n > 0;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak661a_corr_subquery (
            VAR acv                     : tak_all_command_glob;
            VAR dmli                    : tak_dml_info;
            VAR parsk                   : tak_parskey;
            VAR sr_rec                  : tak70_strat_rec;
            curr_n                      : integer;
            VAR pseudo_resultset_select : boolean;
            VAR m_ex_kind               : tak_execution_kind;
            from_sel_found              : boolean);
 
VAR
      mdm_union              : boolean;
      munion_cnt             : integer;
      m_d_keylen             : integer;
      m_p_id                 : tsp00_C1;
      dummy_resultset_select : boolean;
      ke                     : tgg00_SysInfoKey;
      b_err                  : tgg00_BasisError;
      aux_return             : tsp00_Int2;
      aux_errorpos           : tsp00_Int4;
      m_d_distinct           : tgg04_Distinct;
 
BEGIN
WITH acv, dmli DO
    BEGIN
&   IFDEF TRACE
    t01int4 (ak_sem, 'curr_n      ', curr_n);
    t01int4 (ak_sem, 'a_select_nod', a_select_node);
    t01int4 (ak_sem, 'd_distinct  ', ord (d_distinct));
&   ENDIF
    d_corr        := first_correlation;
    d_use_sub     := false;
    a_outer_join  := false;
    m_d_distinct  := d_distinct;
    mdm_union     := d_union;
    munion_cnt    := a_union_cnt;
    (* PTS 1117747 E.Z. *)
    a_where_corr_info.uci_oldlowpars := 0;
    a_where_corr_info.uci_lowpars    := 0;
    a_where_corr_info.uci_pid[1]     := chr(0);
    IF  from_sel_found
    THEN
        BEGIN
        d_union       := false;
        a_union_cnt   := 0;
        a660select (acv, curr_n, dmli, pseudo_resultset_select)
        END
    ELSE
        BEGIN
        (* PTS 1000785 E.Z. *)
        d_subquery_node := curr_n;
        a660_query_execute (acv, dmli, curr_n, NOT c_new_parsinfo,
              cgg_rec_key_offset, sr_rec, pseudo_resultset_select,
              1, 1, from_sel_found);
        d_union       := false;
        a_union_cnt   := 0;
        END;
    (*ENDIF*) 
    a_outer_join           := false;
    a_from_select          := false;
    a_fromsel_n            := 0;
    m_d_keylen             := d_keylen;
    d_subquery             := true;
    dummy_resultset_select := false;
    d_corr                 := correlation;
    m_p_id                 := a_pars_last_key.p_id;
&   IFDEF TRACE
    t01int4 (ak_sem, 'acv_select_n', a_select_node);
    t01int4 (ak_sem, 'curr_n      ', curr_n);
    t01int4 (ak_sem, 'dm_act_node ', d_act_node);
&   ENDIF
    IF  from_sel_found AND
        (a_ap_tree^[ a_select_node ].n_lo_level > 0)
    THEN
        curr_n := a_ap_tree^[ a_select_node ].n_lo_level
    ELSE
        IF  (a_ap_tree^[ a_select_node ].n_sa_level > 0)
        THEN
            curr_n := a_ap_tree^[ a_select_node ].n_sa_level
        ELSE
            IF  (a_ap_tree^[ a_select_node ].n_lo_level > 0)
            THEN
                curr_n := a_ap_tree^[ a_select_node ].n_lo_level;
&           ifdef TRACE
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    t01int4 (ak_sem, 'curr_n      ', curr_n);
&   ENDIF
    IF  (a_returncode = 0)
    THEN
        BEGIN
        a661_corr_sub (acv, dmli, curr_n, d_filled_bytes,
              sr_rec, dummy_resultset_select, c_last_corr_query, 2, 1);
        IF  d_view
        THEN
            BEGIN
            WITH ke DO
                BEGIN
                ke           := a01sysnullkey;
                sauthid[ 1 ] := cak_tempinfo_byte;
                s10mv (sizeof(a_pars_last_key), sizeof(sauthid),
                      @a_pars_last_key, 1, @sauthid, 2, mxak_parskey);
                sauthid[ mxak_parskey + 1 ] := chr(0);
                sentrytyp                   := cak_ecorrinfo;
                END;
            (*ENDWITH*) 
            aux_return   := acv.a_returncode;
            aux_errorpos := acv.a_errorpos;
            a_returncode := 0;
            b_err              := e_ok;
            a10del_sysinfo (acv, ke, b_err);
            IF  (b_err <> e_ok)                AND
                (b_err <> e_sysinfo_not_found) AND
                (aux_return = 0)
            THEN
                a07_b_put_error (acv, b_err, 1)
            ELSE
                BEGIN
                acv.a_returncode := aux_return;
                acv.a_errorpos   := aux_errorpos;
                END;
            (*ENDIF*) 
&           IFDEF TRACE
            t01basis_error  (ak_sem, 'b_err       ', b_err);
            t01int4  (ak_sem, 'returncode  ', a_returncode);
&           endif
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (a_returncode = 0)       AND
        (d_lowpars   < csp_maxint1) AND
        (NOT d_only_sem_check)
    THEN
        a661_update_keys_of_parsrecords (acv, m_p_id,
              d_lowpars, csp_maxint1);
    (*ENDIF*) 
    d_distinct    := m_d_distinct;
    d_union       := mdm_union;
    a_union_cnt   := munion_cnt;
    d_subcount    := 0;
    d_subquery    := false;
    IF  (a_returncode       = 0)                 AND
        (m_ex_kind         = only_parsing)      AND
        (a_max_intern_select = a_intern_select_cnt) AND
        (a_union_cnt     = 0)                 AND
        (NOT a_insert_select)                 AND
        (NOT from_sel_found)
    THEN
        BEGIN
        (* PTS 1122398 E.Z. *)
        a54_shortinfo_to_varpart (acv, a_initial_segment_header.sp1c_prepare OR
              (acv.a_intern_explain AND a663parse_for_execute (acv)),
              d_sparr.pinfop);
        IF  (
            (acv.a_comp_type = at_xci)
            OR (acv.a_comp_type = at_odbc)
            )                          AND
            (m_ex_kind = only_parsing) AND
            (d_sparr.pcolnamep <> NIL)
        THEN
            a60_columnnames_return (acv, d_sparr.pcolnamep);
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    parsk           := a_pars_last_key;
    a_part_rollback := (a_returncode <> 0) AND
          (a_returncode <> 100);
    d_keylen        := m_d_keylen;
    END;
(*ENDWITH*) 
END;
 
(* PTS 1116715 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      ak661a_norm_sub (
            VAR acv                     : tak_all_command_glob;
            VAR dmli                    : tak_dml_info;
            VAR parsk                   : tak_parskey;
            VAR sr_rec                  : tak70_strat_rec;
            curr_n                      : tsp00_Int2;
            VAR pseudo_resultset_select : boolean;
            VAR m_acv_info_output       : boolean);
 
VAR
      mcommand         : tak_commandkind;
      md_union         : boolean;
      munion_cnt       : integer;
      m_distinct       : tgg04_Distinct;
      m_recurs_state   : tak_recursive_state;
      m_subcount       : tsp00_Int2;
      m_cntpar         : tsp00_Int2;
      m_act_node       : tsp00_Int2;
      m_subquery       : boolean;
      m_use_sub        : boolean;
      messagetype      : tgg00_MessType;
      set_subcntlev    : boolean;
 
BEGIN
WITH acv, dmli DO
    BEGIN
&   IFDEF TRACE
    t01int4 (ak_sem, 'd_cor      1', ord (dmli.d_corr));
    t01int4 (ak_sem, 'dm_union    ', ord(d_union));
    t01int4 (ak_sem, 'command_kind', ord(a_command_kind));
&   ENDIF
    m_use_sub       := d_use_sub;
    d_use_sub       := true;
    m_subquery      := d_subquery;
    d_subquery      := true;
    d_sparr.pbasep  := NIL;
    m_distinct      := d_distinct;
    m_subcount      := d_subcount;
    m_act_node      := d_act_node;
    m_cntpar        := d_cntpar;
    m_recurs_state  := a_recursive_state;
    a_recursive_state := rs_no_recursive_select;
    mcommand        := a_command_kind;
    IF  mcommand in [ complex_view_command,
        sub_in_complex_command ]
    THEN
        a_command_kind := sub_in_complex_command
    ELSE
        IF  mcommand = union_command
        THEN
            a_command_kind := sub_in_union_command
        ELSE
            IF  mcommand = sub_in_union_command
            THEN
                a_command_kind := sub_in_union_command
            ELSE
                IF  d_union AND
                    (mcommand = union_in_sub_command)
                THEN
                    a_command_kind := sub_in_union_command
                ELSE
                    a_command_kind := subquery_command;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    IF  a_intern_explain
    THEN
        messagetype := m_show
    ELSE
        messagetype := m_select;
    (*ENDIF*) 
    IF  NOT (d_only_sem_check)
    THEN
        a54_get_pparsp_pinfop (acv, d_sparr, messagetype);
    (*ENDIF*) 
    a_mblock.mb_data_len         := cgg_rec_key_offset;
    a_mblock.mb_data^.mbp_keylen := 0;
    a_mblock.mb_data^.mbp_reclen := 0;
    md_union                       := d_union;
    d_union                        := false;
    munion_cnt                     := a_union_cnt;
    a_union_cnt                    := 0;
    a661_sub_build (acv, dmli, a_ap_tree^[ curr_n ].n_sa_level,
          cgg_rec_key_offset, sr_rec);
    IF  (a_returncode = 0) AND (a_main_returncode <> 0)
    THEN
        BEGIN
        a_returncode := a_main_returncode;
        a_errorpos   := a_main_errorpos;
        END;
    (*ENDIF*) 
    d_subquery  := false;
    d_union     := md_union;
    a_union_cnt := munion_cnt;
    d_distinct  := m_distinct;
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  NOT (d_view OR dmli.d_only_sem_check)
        THEN
            BEGIN
            a660_new_pparsp (acv, dmli.d_sparr,
                  NOT c_first_parsinfo, c_complicate);
            ak661_subquery_found (acv, a_ap_tree^[ curr_n ].n_sa_level,
                  set_subcntlev);
            WITH a_ap_tree^[ curr_n ] DO
                IF  (a_returncode = 0) AND
                    set_subcntlev
                THEN
                    WITH a_ap_tree^[ a_ap_tree^[ curr_n ].n_sa_level ] DO
                        BEGIN
                        dmli.d_sparr.pparsp^.sparsinfo.p_subcntlevel :=
                              a_ap_tree^[ n_pos ].n_length DIV 100;
&                       IFDEF TRACE
                        t01int4(ak_sem, 'new subcnt  ',
                              dmli.d_sparr.pparsp^.sparsinfo.p_subcntlevel );
&                       ENDIF
                        END;
                    (*ENDWITH*) 
                (*ENDIF*) 
            (*ENDWITH*) 
            IF  (a_max_intern_select = a_intern_select_cnt) AND
                (NOT a_from_select) AND
                (NOT a_insert_select) AND
                (m_subcount = 0)
            THEN
                (* PTS 1114017 E.Z. *)
                a54set_complex_entry (acv, c_set_last_pars);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        d_subcount := m_subcount;
        (*d_use_sub       := m_use_sub;*)
        d_subquery      := m_subquery;
        IF  mcommand <> single_command
        THEN
            a_command_kind  := mcommand;
        (*ENDIF*) 
        d_cntpar := m_cntpar;
        (* restable is needed for longinfos in case of single select  *)
        IF  mcommand = union_in_sub_command
        THEN
            d_act_node := m_act_node
        ELSE
            d_act_node := curr_n;
        (*ENDIF*) 
        a_recursive_state:= m_recurs_state;
&       IFDEF trace
        t01int4 (ak_sem, 'query_exec4 ', 6604);
        t01int4 (ak_sem, 'command_kind', ord(a_command_kind));
&       ENDIF
        a_outer_join  := false;
        (* PTS 1116716 E.Z. *)
        IF  a_init_ex_kind = only_parsing
        THEN
            a_info_output := m_acv_info_output;
        (*ENDIF*) 
        a660_query_execute (acv, dmli, curr_n, NOT c_new_parsinfo,
              cgg_rec_key_offset, sr_rec, pseudo_resultset_select, 1, 1,
              NOT c_from_sel_found);
&       IFDEF trace
        t01int4 (ak_sem, 'query_exec4 ', 66049);
&       ENDIF
        (* PTS 1114017 E.Z. *)
        END
    ELSE
        a_command_kind  := mcommand;
    (*ENDIF*) 
    parsk           := a_pars_last_key;
    parsk.p_id[ 1 ] := a_first_parskey;
    parsk.p_kind    := m_complex;
    parsk.p_no      := 0;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak661change_p_no_in_fetch (
            VAR acv  : tak_all_command_glob;
            hp_no    : tsp00_Uint1;
            old_p_no : tsp00_Uint1);
 
VAR
      b_err   : tgg00_BasisError;
      sysp    : tak_sysbufferaddress;
      sysk    : tgg00_SysInfoKey;
 
BEGIN
sysk              := a01sysnullkey;
sysk.sauthid[ 1 ] := cak_tempinfo_byte;
s10mv (sizeof(acv.a_pars_last_key), sizeof(sysk.sauthid),
      @acv.a_pars_last_key, 1, @sysk.sauthid, 2, mxak_parskey);
sysk.sauthid[ mxak_parskey + 1 ] := chr(hp_no);
sysk.sentrytyp                   := cak_eparsinfo;
a10get_sysinfo (acv, sysk, d_release, sysp, b_err);
IF  b_err = e_ok
THEN
    IF  sysp^.sparsinfo.p_mtyp = m_fetch
    THEN
        BEGIN
        (* PTS 1117747 E.Z. *)
        WITH sysp^.sparsinfo DO
            BEGIN
&           ifdef TRACE
            t01int4 (ak_sem, 'hp_no       ', hp_no);
            t01int4 (ak_sem, 'old_p_no    ', old_p_no);
            t01int4 (ak_sem, 'p_p_no      ', p_p_no);
&           endif
            p_p_no := p_p_no + acv.a_pars_last_key.p_no - old_p_no;
&           ifdef TRACE
            t01int4 (ak_sem, 'p_p_no new  ', p_p_no);
&           endif
            END;
        (*ENDWITH*) 
        a10repl_sysinfo (acv, sysp, b_err);
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  b_err <> e_ok
THEN
    a07_b_put_error (acv, b_err, 2)
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a661exec_sub (
            VAR acv                 : tak_all_command_glob;
            VAR dmli                : tak_dml_info;
            VAR parsk               : tak_parskey;
            curr_n                  : tsp00_Int2;
            VAR del_cnt             : integer;
            m_acv_info_output       : boolean;
            pseudo_resultset_select : boolean);
 
VAR
      _del_result   : boolean;
      _lcol_found   : boolean;
      _lcol_lock    : boolean;
      _aux_return   : tsp00_Int2;
      _aux_errorpos : tsp00_Int4;
      _munion_cnt   : integer;
      _prefix_len   : integer;
 
BEGIN
(* PTS 1121945 E.Z. *)
IF  (csa_subq_datatype_problem in acv.a_sql_cmd_state)
THEN
    acv.a_returncode := cak_e_subq_type_diff;
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    BEGIN
    acv.a_ex_kind   := only_executing;
    _munion_cnt  := acv.a_union_cnt;
    acv.a_union_cnt := 0;
    acv.a_recursive_state := rs_no_recursive_select;
&   ifdef TRACE
    t01command_kind (ak_sem, 'command_kind', acv.a_command_kind);
    WITH parsk DO
        BEGIN
        t01int4 (ak_sem, 'p_count[1]  ', ord(p_count[1]));
        t01int4 (ak_sem, 'p_count[2]  ', ord(p_count[2]));
        t01int4 (ak_sem, 'p_count[3]  ', ord(p_count[3]));
        t01int4 (ak_sem, 'p_id        ', ord (p_id[ 1 ]));
        t01int4 (ak_sem, 'p_kind      ', ord (p_kind));
        t01int4 (ak_sem, 'p_no        ', p_no);
        END;
    (*ENDWITH*) 
    WITH acv.a_pars_last_key DO
        BEGIN
        t01int4 (ak_sem, 'p_count[1]  ', ord(p_count[1]));
        t01int4 (ak_sem, 'p_count[2]  ', ord(p_count[2]));
        t01int4 (ak_sem, 'p_count[3]  ', ord(p_count[3]));
        t01int4 (ak_sem, 'p_id        ', ord (p_id[ 1 ]));
        t01int4 (ak_sem, 'p_kind      ', ord (p_kind));
        t01int4 (ak_sem, 'p_no        ', p_no);
        END;
    (*ENDWITH*) 
&   ENDIF
    acv.a_input_data_pos := 1;
    IF  acv.a_ap_tree^[ curr_n ].n_symb = s_sum
    THEN
        a501exec_with_change_rec (acv, dmli, parsk, dmli.d_change,
              NOT c_output_during_execution)
    ELSE
        a501do_execute (acv, dmli, parsk, NOT c_output_during_execution);
    (*ENDIF*) 
    acv.a_union_cnt := _munion_cnt;
    END;
(*ENDIF*) 
_aux_return   := acv.a_returncode;
_aux_errorpos := acv.a_errorpos;
&IFDEF TRACE
t01int4 (ak_sem, 'old m_info  ', ord(m_acv_info_output));
t01int4 (ak_sem, 'returncode  ', acv.a_returncode);
&ENDIF
IF  (acv.a_returncode = 0)   OR
    (acv.a_returncode = 100)
THEN
    BEGIN
    IF  m_acv_info_output
    THEN
        BEGIN
        IF  NOT pseudo_resultset_select
        THEN
            BEGIN
            acv.a_returncode := 0;
            a73_ex_describe (acv, dmli, 2, c_subquery);
            IF  acv.a_returncode = 0
            THEN
                BEGIN
                (* PTS 1106243 E.Z. *)
                IF  dmli.d_sparr.pinfop <> NIL
                THEN
                    acv.a_resname_addr[ cak_extern_pos ]^.sresname.
                          resinfobuf := 2
                ELSE
                    acv.a_resname_addr[ cak_extern_pos ]^.sresname.
                          resinfobuf := 1;
                (*ENDIF*) 
                acv.a_returncode := _aux_return;
                acv.a_errorpos   := _aux_errorpos;
                END
            (*ENDIF*) 
            END
        ELSE
            IF  acv.a_returncode = 0
            THEN
                BEGIN
                a06reset_retpart (acv);
                a73_ex_describe (acv, dmli, 2, NOT c_subquery)
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (NOT pseudo_resultset_select) AND
        (acv.a_intern_select_cnt = acv.a_max_intern_select)
    THEN
        WITH  acv.a_resname_addr[ cak_extern_pos ]^.sresname DO
            BEGIN
            acv.a_result_name := reskey_name;
            acv.a_modul_name  := reskey_modul_name;
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  (pseudo_resultset_select AND (acv.a_returncode = 0))
THEN
    BEGIN
    _lcol_found := false;
    IF  dmli.d_change.cr_colcount > 0
    THEN
        _lcol_found := a508_lcol_found (acv, dmli.d_change);
    (*ENDIF*) 
    a60rescount (acv, 1);
    a60_change_results (acv, acv.a_mblock.mb_data^.mbp_buf,
          dmli.d_change, 0, acv.a_mblock.mb_data_len);
    a60_put_result (acv, acv.a_mblock,
          cgg_rec_key_offset + acv.a_mblock.mb_data^.mbp_keylen);
    IF  _lcol_found AND (acv.a_returncode = 0)
    THEN
        BEGIN
        _lcol_lock := true;
        a508_lget_long_columns (acv, dmli.d_change,
              _lcol_lock, 1, acv.a_mblock.mb_data^.mbp_reclen,
              - (acv.a_mblock.mb_data^.mbp_keylen +
              cgg_rec_key_offset))
        END;
    (*ENDIF*) 
    IF  acv.a_returncode = 0
    THEN
        a06finish_curr_retpart (acv, sp1pk_data, 1)
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  (acv.a_returncode <> 0) AND
    ((_aux_return = 0  ) OR
    ( _aux_return = 100)   )
THEN
    BEGIN
    _aux_return   := acv.a_returncode;
    _aux_errorpos := acv.a_errorpos;
    END;
(*ENDIF*) 
IF  (acv.a_returncode      = cak_e_corelated_subquery_not_allowed) OR
    (acv.a_main_returncode = cak_e_corelated_subquery_not_allowed)
THEN
    BEGIN
&   IFDEF TRACE
    t01int4 (ak_sem, '661exec_sub ', 661);
    t01int4 (ak_sem, 'd_onlysemchk', ord (dmli.d_only_sem_check));
    t01int4 (ak_sem, 'acv_unioncnt', acv.a_union_cnt);
&   ENDIF
    IF  (acv.a_ex_kind <> only_parsing) AND
        ((NOT dmli.d_view) OR
        (acv.a_union_cnt = 0))
    THEN
        a660_prefix_delete (acv, parsk, del_cnt, cak_intern_prefix);
    (*ENDIF*) 
    acv.a_ap_tree^[ acv.a_select_node ].n_symb := s_sum;
    END
ELSE
    BEGIN
    _del_result := (acv.a_returncode <> 0) AND
          (acv.a_returncode <> 100) AND
          (NOT dmli.d_resname_found);
    acv.a_returncode := 0;
    IF  pseudo_resultset_select
    THEN
        IF  acv.a_resname_addr [ cak_intern_pos ] <> NIL
        THEN
            WITH acv.a_resname_addr [ cak_intern_pos ]^.sresname DO
                BEGIN
                IF  (resmaxlinkage > 0) AND
                    (acv.a_union_cnt <= 1 )
                THEN
                    a663_del_result (acv,
                          acv.a_resname_addr [ cak_intern_pos ]^.sresname,
                          c_do_cdel, NOT c_del_resname_rec);
                (*ENDIF*) 
                resdecresdel := dr_sql_db
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
    (*ENDIF*) 
    IF  acv.a_qualified_jv_upd <> no_jv_upd
    THEN
        _prefix_len := cak_intern_prefix
    ELSE
        _prefix_len := cak_complete_prefix;
    (*ENDIF*) 
    IF  acv.a_max_intern_select = acv.a_intern_select_cnt
    THEN
        a660_prefix_delete (acv, parsk, del_cnt, _prefix_len);
    (*ENDIF*) 
    IF  (acv.a_returncode = 0) OR
        ((_aux_return <> 0  ) AND
        ( _aux_return <> 100)    )
    THEN
        BEGIN
        acv.a_returncode := _aux_return;
        acv.a_errorpos   := _aux_errorpos;
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak661s_corr_start (
            VAR acv                     : tak_all_command_glob;
            VAR dmli                    : tak_dml_info;
            VAR parsk                   : tak_parskey;
            VAR sr_rec                  : tak70_strat_rec;
            curr_n                      : tsp00_Int2;
            VAR pseudo_resultset_select : boolean;
            VAR m_ex_kind               : tak_execution_kind;
            VAR m_acv_info_output       : boolean);
 
VAR
      b_err           : tgg00_BasisError;
      fs_n            : integer;
      mcommand        : tak_commandkind;
      new_complex_rec : boolean;
      m_first_union   : boolean;
      m_union         : boolean;
      new_col_rec     : boolean;
      m_union_cnt     : integer;
      old_next_n      : integer;
      m_curr_n        : integer;
      messagetype     : tgg00_MessType;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    new_col_rec := false;
    m_union_cnt    := a_union_cnt;
    a_union_append := false;
    IF  a_ap_tree^[ curr_n ].n_sa_level > 0
    THEN
        fs_n := a_ap_tree^[ curr_n ].n_sa_level
    ELSE
        fs_n := curr_n;
    (*ENDIF*) 
    (* PTS 1000785 E.Z. *)
    d_subquery_node := curr_n;
    new_complex_rec := true;
&   IFDEF TRACE
    t01int4 (ak_sem, 'fs_n        ', fs_n);
    t01int4 (ak_sem, 'curr_n      ', curr_n);
    t01int4 (ak_sem, 'd_subcount  ', d_subcount);
    t01int4 (ak_sem, 'd_lowpars   ', d_lowpars);
    t01int4 (ak_sem, 'm_acv_info_o', ord (m_acv_info_output));
    t01int4 (ak_sem, 'pseudo_rsets', ord (pseudo_resultset_select));
&   ENDIF
    mcommand := a_command_kind;
    CASE mcommand OF
        union_command:
            a_command_kind := sub_in_union_command;
        complex_view_command,
        sub_in_complex_command,
        union_in_sub_command,
        sub_in_union_command:
            BEGIN
            END;
        OTHERWISE
            a_command_kind := subquery_command;
        END;
    (*ENDCASE*) 
    old_next_n := 0;
    m_curr_n   := curr_n;
    IF  (a_ap_tree^[ fs_n ].n_proc = a92fromsel)
    THEN
        BEGIN
        m_first_union := d_first_union;
        d_first_union := false;
        m_union       := d_union;
        d_union       := false;
        ak661_fromsub_build (acv, dmli, parsk, fs_n,
              pseudo_resultset_select, sr_rec,
              new_complex_rec);
        d_first_union := m_first_union;
        d_union       := m_union;
        (* PTS 1117747 E.Z. *)
        d_where_subquery       := false;
        d_where_corr_subquery  := false;
        d_having_subquery      := false;
        d_having_corr_subquery := false;
        old_next_n    := a_ap_tree^[ curr_n ].n_sa_level;
        WHILE (fs_n > 0) DO
            IF  (a_ap_tree^[ fs_n ].n_proc = a92fromsel)
            THEN
                BEGIN
                a_ap_tree^[ curr_n ].n_sa_level :=
                      a_ap_tree^[ fs_n ].n_sa_level;
                fs_n := a_ap_tree^[ fs_n ].n_sa_level;
                END
            ELSE
                fs_n := 0;
            (*ENDIF*) 
        (*ENDWHILE*) 
        END
    ELSE
        IF  mcommand = union_command
        THEN
            a_command_kind := mcommand;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  (NOT dmli.d_only_sem_check)
    THEN
        IF  new_complex_rec
        THEN
            BEGIN
            IF  a_intern_explain
            THEN
                messagetype := m_show
            ELSE
                messagetype := m_select;
            (*ENDIF*) 
            a54_get_pparsp_pinfop (acv, d_sparr, messagetype);
            new_complex_rec := false;
            (* PTS 1122398 E.Z. *)
            acv.a_info_output := m_acv_info_output;
            IF  acv.a_info_output
            THEN
                BEGIN
                new_col_rec := true;
                a60_get_longinfobuffer( acv, dmli.d_sparr, MAX_COL_PER_TAB_GG00,
                      acv.a_curr_res_id );
                END;
            (*ENDIF*) 
            END
        ELSE
            a660_new_pparsp (acv, dmli.d_sparr,
                  NOT c_first_parsinfo, c_complicate);
        (*ENDIF*) 
    (*ENDIF*) 
    IF  (a_returncode = 0)
    THEN
        IF  (a_ap_tree^[ curr_n ].n_sa_level > 0)
        THEN (* *** process subquery on highest level *** *)
            ak661a_corr_subquery (acv, dmli, parsk, sr_rec, curr_n,
                  pseudo_resultset_select, m_ex_kind,
                  NOT c_from_sel_found)
        ELSE (* *** subqueries only in fromselect, now select it *** *)
            BEGIN
            a_outer_join           := false;
            d_subquery             := false;
            d_corr                 := no_correlation;
            d_use_sub              := false;
            d_cntpar               := MAX_COL_PER_TAB_GG00;
            a660_query_execute (acv, dmli, curr_n, NOT c_new_parsinfo,
                  cgg_rec_key_offset, sr_rec, pseudo_resultset_select, 1, 1,
                  NOT c_from_sel_found);
            a_outer_join := false;
            IF  (mcommand  <> union_command)
            THEN
                a54set_complex_entry (acv, c_set_last_pars);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    a_command_kind := mcommand;
    a_union_cnt    := m_union_cnt;
    IF  old_next_n <> 0
    THEN
        a_ap_tree^[ curr_n ].n_sa_level := old_next_n;
    (*ENDIF*) 
    IF  new_col_rec AND (dmli.d_sparr.pcolnamep <> NIL)
    THEN
        a10del_sysinfo (acv, dmli.d_sparr.pcolnamep^.syskey, b_err);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(* PTS 1111510 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      a661_build_t_fromsel_tableid (
            VAR syskey_tableid  : tgg00_Surrogate;
            VAR fn_tableid      : tgg00_Surrogate;
            VAR curr_ex_parskey : tak_parskey;
            site                : tgg00_ServerdbNo;
            from_select_no      : tsp00_Int2);
 
VAR
      mt  : tak_fromsel_tabid;
 
BEGIN
(* PTS 1111510 E.Z. *)
mt.fromsiteno := site;
mt.ft         := ttfnFromSelect_egg00;
mt.fs_no      := from_select_no;
(* filename-tabid with session *)
gg06SetNilSession (mt.session); (* shared SQL *)
fn_tableid  := mt.tabid;
(* syskey_tabid with cmd_count *)
mt.fparschar[1] := cak_tempinfo_byte;
mt.fcmd_count   := curr_ex_parskey.p_count;
mt.ffill        := 0;
syskey_tableid := mt.tabid;
&IFDEF TRACE
t01int4   (ak_sem, 'ft          ', ord (mt.ft));
t01int4   (ak_sem, 'from_sel_no ', mt.fs_no);
&ENDIF
END;
 
(* PTS 1117747 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      a661_corr_sub (
            VAR acv                     : tak_all_command_glob;
            VAR dmli                    : tak_dml_info;
            s_n                         : integer;
            filled_part2_bytes          : integer;
            VAR sr_rec                  : tak70_strat_rec;
            VAR pseudo_resultset_select : boolean;
            last_corr_query             : boolean;
            level                       : integer;
            no_in_level                 : integer);
 
VAR
      b_err           : tgg00_BasisError;
      hp_no           : tsp00_Uint1;
      fetch_inner_sel : tsp00_Uint1;
      old_d_lowpars   : tsp00_Uint1;
      old_p_no        : tsp00_Uint1;
      old_p_id        : tsp00_C1;
      ke              : tgg00_SysInfoKey;
      m_corr_info     : tak_used_corr_infos;
 
BEGIN
&ifdef TRACE
t01int4 (ak_sem, 'filled_part2', filled_part2_bytes);
&endif
(* PTS 1000785 E.Z. *)
dmli.d_subquery_node := s_n;
(* ??? dem d_subcount-setzen traue ich im Zusammenhang mit
      unions aber auch nicht ueber den Weg ???*)
dmli.d_subcount := acv.a_ap_tree^[ acv.a_ap_tree^[ s_n ].n_pos ].n_length;
old_d_lowpars := dmli.d_lowpars;
m_corr_info := acv.a_where_corr_info;
acv.a_where_corr_info.uci_oldlowpars := 0;
acv.a_where_corr_info.uci_lowpars    := 0;
acv.a_where_corr_info.uci_pid[1]     := chr(0);
dmli.d_where_corr := false;
&ifdef TRACE
t01int4 (ak_sem, 'hci_oldlowpa', m_corr_info.uci_oldlowpars);
t01int4 (ak_sem, 'hci_lowpars ', m_corr_info.uci_lowpars);
t01int4 (ak_sem, 'hci_no      ', ord(m_corr_info.uci_pid[1]));
&endif
hp_no := acv.a_pars_last_key.p_no;
(* pno of fetch *)
old_p_id := acv.a_pars_last_key.p_id;
IF  NOT (dmli.d_only_sem_check)
THEN
    a660_new_pparsp (acv, dmli.d_sparr,
          NOT c_first_parsinfo, NOT c_complicate);
(*ENDIF*) 
IF  no_in_level > csp_maxint1
THEN
    a07_b_put_error (acv, e_too_many_subqueries, 1);
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    BEGIN
    (* .n_lo_level / n_sa_level = -1 ==> pos for next subquery *)
    IF  acv.a_ap_tree^[ s_n ].n_lo_level <= 0
    THEN
        BEGIN
        IF  (last_corr_query AND (acv.a_ap_tree^[ s_n ].n_sa_level <= 0))
        THEN
            BEGIN
            WITH ke DO
                BEGIN
                ke := a01sysnullkey;
                sauthid[ 1 ] := cak_tempinfo_byte;
                s10mv (sizeof(acv.a_pars_last_key), sizeof(sauthid),
                      @acv.a_pars_last_key, 1,
                      @sauthid, 2, mxak_parskey);
                sauthid[ mxak_parskey + 1 ] := chr(0);
                sentrytyp                   := cak_ecorrinfo;
                END;
            (*ENDWITH*) 
            (* *** union with corelation *** *)
            IF  (acv.a_corr_key.p_no <> 0)
            THEN
                BEGIN
                a10del_sysinfo (acv, ke, b_err);
                IF  b_err <> e_ok
                THEN
                    a07_b_put_error (acv, b_err, 1)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        dmli.d_corr := lowest_of_correlation;
        END;
    (*ENDIF*) 
    dmli.d_act_node := acv.a_ap_tree^[ s_n ].n_pos;
    a660_query_execute (acv, dmli, dmli.d_act_node,
          NOT c_new_parsinfo, filled_part2_bytes, sr_rec,
          pseudo_resultset_select, level, no_in_level,
          NOT c_from_sel_found);
    acv.a_outer_join := false;
    dmli.d_corr      := correlation;
    (* fetch_inner_sel = pno of fetch of inner select *)
    fetch_inner_sel  := acv.a_pars_last_key.p_no;
    END;
(* PTS 1117747 E.Z. *)
(*ENDIF*) 
IF  ((acv.a_returncode = 0) AND
    (acv.a_ap_tree^[ s_n ].n_lo_level > 0))
THEN
    BEGIN
    a661_corr_sub (acv, dmli, acv.a_ap_tree^[ s_n ].n_lo_level,
          dmli.d_filled_bytes, sr_rec, pseudo_resultset_select,
          (last_corr_query AND (acv.a_ap_tree^[ s_n ].n_sa_level <= 0)),
          level+1, 1);
    dmli.d_level[ level + 1 ] := 0
    END;
(*ENDIF*) 
IF  (acv.a_returncode = 0)             AND
    (dmli.d_lowpars          < old_d_lowpars) AND
    (NOT dmli.d_only_sem_check)
THEN
    BEGIN
    a661_update_keys_of_parsrecords (acv, old_p_id,
          dmli.d_lowpars, old_d_lowpars);
    dmli.d_lowpars := old_d_lowpars;
    END;
(*ENDIF*) 
IF  (acv.a_ap_tree^[ s_n ].n_sa_level > 0) AND
    (* PTS 1123051 E.Z. *)
    (acv.a_ap_tree^[ s_n ].n_symb in [ s_where, s_select ])
THEN
    IF  (acv.a_ap_tree^[ acv.a_ap_tree^
        [ s_n ].n_sa_level ].n_symb = s_having) AND
        (m_corr_info.uci_lowpars <> m_corr_info.uci_oldlowpars)
    THEN
        BEGIN
        a661_update_keys_of_parsrecords (acv, m_corr_info.uci_pid,
              m_corr_info.uci_lowpars, m_corr_info.uci_oldlowpars);
        dmli.d_lowpars                       := m_corr_info.uci_oldlowpars;
        acv.a_where_corr_info.uci_oldlowpars := 0;
        acv.a_where_corr_info.uci_lowpars    := 0;
        acv.a_where_corr_info.uci_pid[1]     := chr(0);
        END
    ELSE
        acv.a_where_corr_info := m_corr_info;
    (*ENDIF*) 
(*ENDIF*) 
IF  (acv.a_returncode       = 0) AND
    (acv.a_ap_tree^[ s_n ].n_sa_level > 0)
THEN
    BEGIN
    old_p_no := acv.a_pars_last_key.p_no;
    a661_corr_sub (acv, dmli, acv.a_ap_tree^[ s_n ].n_sa_level,
          filled_part2_bytes, sr_rec, pseudo_resultset_select,
          last_corr_query, level, no_in_level+1);
    IF  NOT (dmli.d_only_sem_check) AND NOT acv.a_intern_explain
    THEN
        (* PTS 1123051 E.Z. *)
        IF  (acv.a_ap_tree^[ s_n ].n_symb in [ s_where, s_select ]) AND
            (acv.a_ap_tree^[ acv.a_ap_tree^
            [ s_n ].n_sa_level ].n_symb = s_having)
        THEN
            ak661change_p_no_in_fetch (acv, hp_no, old_p_no)
        ELSE
            ak661change_p_no_in_fetch (acv, fetch_inner_sel, old_p_no)
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a661_fdelete_fromtab_results (VAR acv : tak_all_command_glob);
 
VAR
      del_cnt        : integer;
      i              : integer;
      fs_tree        : tgg00_FileId;
      pars_k         : tak_parskey;
      aux_return    : tsp00_Int2;
      aux_errorpos  : tsp00_Int4;
      syskey_tableid : tgg00_Surrogate;
 
BEGIN
WITH acv DO
    BEGIN
    g04build_temp_tree_id (fs_tree, a_transinf.tri_trans);
    (* PTS 1111510 E.Z. *)
    a661_build_t_fromsel_tableid (syskey_tableid,
          fs_tree.fileTabId_gg00,
          a_curr_ex_parskey, cak_fromseltab_site, 0);
    s10mv (sizeof(syskey_tableid), sizeof(pars_k),
          @syskey_tableid, 2, @pars_k, 1, mxak_parskey);
    del_cnt     := 0;
    aux_return   := acv.a_returncode;
    aux_errorpos := acv.a_errorpos;
    a_returncode := 0;
    a660_prefix_delete (acv, pars_k, del_cnt, mxak_parskey);
    a_returncode := 0;
    FOR i := mxak_parskey + 4 TO FN_MXGG00 DO
        fs_tree.fileName_gg00 [ i ] := chr(0);
    (*ENDFOR*) 
    fs_tree.fileZeroSite_gg00 := 0; (* local_site*)
    b01prefix_destroy_files (a_transinf.tri_trans,
          fs_tree.fileName_gg00, mxak_parskey + 3);
    acv.a_returncode := aux_return;
    acv.a_errorpos   := aux_errorpos;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a661_get_from_select_table (
            VAR acv     : tak_all_command_glob;
            VAR tableid : tgg00_Surrogate;
            VAR pbasep  : tak_sysbufferaddress;
            dstate      : tak_directory_state;
            all         : boolean;
            VAR f_ok    : boolean);
 
VAR
      _site  : tgg00_ServerdbNo;
      _b_err : tgg00_BasisError;
      _sysk  : tgg00_SysInfoKey;
      (* PTS 1111510 E.Z. *)
      _mt    : tak_fromsel_tabid;
 
BEGIN
_mt.tabid        := tableid;
(* PTS 1111510 E.Z. *)
_mt.fparschar[1] := cak_tempinfo_byte;
_mt.fcmd_count   := acv.a_curr_ex_parskey.p_count;
_mt.ffill        := 0;
_sysk            := a01sysnullkey;
_sysk.sentrytyp  := cak_eresult;
_sysk.stableid   := _mt.tabid;
_sysk.slinkage   := cak_init_linkage;
_site            := cgg_zero_c2;
f_ok            := true;
a10get_sysinfo (acv, _sysk, dstate, pbasep, _b_err);
IF  _b_err <> e_ok
THEN
    BEGIN
    IF  (_b_err = e_key_not_found)
    THEN
        _b_err := e_sysinfo_not_found;
    (*ENDIF*) 
    IF  (_b_err <> e_sysinfo_not_found)
    THEN
        a07_b_put_error (acv, _b_err, 1)
    ELSE
        a07_b_put_error (acv, e_from_select_not_allowed, 1);
    (*ENDIF*) 
    f_ok := false;
    END
ELSE
    BEGIN
    IF  NOT all
    THEN
        a10_rel_sysinfo (acv, pbasep^.syskey);
    (*ENDIF*) 
    ;
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      a661_is_fromsel_table (
            VAR acv     : tak_all_command_glob;
            VAR ftreeid : tgg00_FileId) : boolean;
 
VAR
      mt : tak_fromsel_tabid;
 
BEGIN
mt.tabid              := ftreeid.fileTabId_gg00;
&IFDEF TRACE
t01int4   (ak_sem, 'ft          ', ord (mt.ft));
t01int4   (ak_sem, 'from_sel_no ', mt.fs_no);
&ENDIF
(* PTS 1111510 *)
a661_is_fromsel_table :=
      (ftreeid.fileTfn_gg00 = tfnTemp_egg00) AND
      (mt.fromsiteno = cgg_zero_c2) AND
      (mt.ft         = ttfnFromSelect_egg00) AND
      gg06IsNilSession (mt.session);
END;
 
(*------------------------------*) 
 
PROCEDURE
      a661_sub_build (
            VAR acv               : tak_all_command_glob;
            VAR dmli              : tak_dml_info;
            sub_n                 : integer;
            filled_part2_bytes    : integer;
            VAR sr_rec            : tak70_strat_rec);
 
VAR
      dummy           : boolean;
      md_subquery     : boolean;
      count           : integer;
      next_n          : integer;
      pos             : integer;
      subq_n          : integer;
      dummy_parsk     : tak_parskey;
      m_union_key     : tak_parskey;
      m_fromsel_n     : tsp00_Int2;
      m_select_n      : tsp00_Int2;
      m_from_select   : boolean;
      m_first_union   : boolean;
      set_subcntlev   : boolean;
      m_union_order_n : integer;
      m_first_parsid  : char;
      m_command_kind  : tak_commandkind;
 
BEGIN
WITH acv, dmli DO
    IF  a_returncode = 0
    THEN
        BEGIN
        a_outer_join    := false;
        m_first_union   := d_first_union;
        m_union_order_n := d_union_order_n;
        d_first_union   := false;
        subq_n          := a_ap_tree^[ sub_n ].n_pos;
        count   := a_ap_tree^[ subq_n ].n_length;
        next_n  := a_ap_tree^[ sub_n ].n_lo_level;
        m_select_n    := a_select_node;
        a_select_node := subq_n;
&       IFDEF TRACE
        t01int4 (ak_sem, 'sub_n       ', sub_n);
        t01int4 (ak_sem, 'next_n      ', next_n);
&       ENDIF
        IF  next_n > 0
        THEN
            BEGIN
            (* PTS 1114017 E.Z. *)
            m_from_select := a_from_select;
            m_fromsel_n   := a_fromsel_n;
            a_from_select := false;
            a_fromsel_n   := 0;
            dmli.d_act_node := a_ap_tree^[ next_n ].n_pos;
            a661_sub_build (acv, dmli, next_n, filled_part2_bytes,
                  sr_rec);
            a_from_select := m_from_select;
            a_fromsel_n   := m_fromsel_n;
            END;
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            BEGIN
            IF  (a_ap_tree^[ subq_n ].n_proc = a63) AND
                (a_ap_tree^[ subq_n ].n_subproc = cak_x_start_union)
            THEN
                BEGIN
                m_first_parsid := a_first_parsid;
                m_command_kind := a_command_kind;
                a662_start_union_select (acv, sub_n,
                      dmli, dummy, dummy_parsk);
                IF  m_command_kind = sub_in_union_command
                THEN
                    a_first_parsid := m_first_parsid
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                dmli.d_act_node  := subq_n;
                dmli.d_subcount  := count;
                IF  (dmli.d_sparr.pparsp = NIL)  AND
                    (NOT dmli.d_only_sem_check)
                THEN
                    a660_new_pparsp (acv, dmli.d_sparr,
                          NOT c_first_parsinfo, c_complicate);
                (*ENDIF*) 
                ak661_subquery_found (acv, sub_n, set_subcntlev);
                IF  (a_returncode = 0)              AND
                    (NOT dmli.d_only_sem_check)           AND
                    (a_ap_tree^[ sub_n ].n_lo_level >  0)  AND
                    set_subcntlev
                THEN
                    WITH a_ap_tree^[ a_ap_tree^[ sub_n ].n_lo_level ] DO
                        BEGIN
                        dmli.d_sparr.pparsp^.sparsinfo.p_subcntlevel :=
                              a_ap_tree^[ n_pos ].n_length DIV 100;
&                       IFDEF TRACE
                        t01int4(ak_sem, 'subcounter  ',
                              dmli.d_sparr.pparsp^.sparsinfo.p_subcntlevel);
&                       ENDIF
                        END;
                    (*ENDWITH*) 
                (*ENDIF*) 
                dummy                    := false;
                a_rowno_allowed          := true;
                sr_rec.sr_distinct_bytes := true;
                IF  (a_ap_tree^[ sub_n ].n_proc = a92fromsel)
                THEN
                    BEGIN
                    a_outer_join           := false;
                    m_fromsel_n            := a_fromsel_n;
                    a_fromsel_n            := subq_n;
                    m_from_select          := a_from_select;
                    a_from_select          := true;
                    md_subquery            := d_subquery;
                    d_subquery             := false;
                    d_use_sub              := false;
                    d_cntpar               := MAX_COL_PER_TAB_GG00;
                    m_union_key            := a_union_key;
                    a660select (acv, a_ap_tree^[subq_n].n_lo_level,
                          dmli, dummy);
                    a_outer_join    := false;
                    d_use_sub       := true;
                    a_union_key     := m_union_key;
                    a_fromsel_n     := m_fromsel_n;
                    a_from_select   := m_from_select;
                    d_subquery      := md_subquery;
                    END
                ELSE
                    BEGIN
                    a660_query_execute (acv, dmli, subq_n, NOT c_new_parsinfo,
                          filled_part2_bytes, sr_rec, dummy,
                          1, 1, NOT c_from_sel_found);
                    a_outer_join           := false;
                    END;
                (*ENDIF*) 
                IF  a_returncode = 0
                THEN
                    IF  (NOT a_insert_select) OR
                        (* not top of insert select *)
                        (dmli.d_subcount <> 102)
                    THEN
                        BEGIN
                        IF  ( a_mblock.mb_qual^.mstrat_pos > 0 ) AND
                            ( a_mblock.mb_st^[ a_mblock.mb_qual^.mstrat_pos ].
                            etype = st_strat )
                        THEN
                            a_mblock.mb_strat_len :=
                                  a_mblock.mb_st^[ a_mblock.mb_qual^.mstrat_pos ].epos - 1;
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  a_returncode = cak_e_corelated_subquery_not_allowed
            THEN
                BEGIN
                IF  a_main_returncode = 0
                THEN
                    BEGIN
                    a_main_returncode := cak_e_corelated_subquery_not_allowed;
                    a_main_errorpos   := a_errorpos
                    END;
                (*ENDIF*) 
                a_returncode := 0;
                a_errorpos   := 0;
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        next_n := a_ap_tree^[ sub_n ].n_sa_level;
        IF  next_n > 0
        THEN
            BEGIN
            a661_sub_build (acv,
                  dmli, next_n, filled_part2_bytes, sr_rec)
            END;
        (*ENDIF*) 
        d_first_union   := m_first_union;
        d_union_order_n := m_union_order_n;
        a_select_node   := m_select_n;
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a661_update_keys_of_parsrecords (
            VAR acv     : tak_all_command_glob;
            old_p_id    : tsp00_C1;
            VAR lowpars : tsp00_Uint1;
            old_lowpars : tsp00_Uint1);
 
VAR
      b_err  : tgg00_BasisError;
      diff   : integer;
      old_no : integer;
      new_no : tsp00_Uint1;
      p      : tak_parskey;
 
BEGIN
new_no := acv.a_pars_last_key.p_no + 1;
old_no := lowpars+1;
diff   := old_no - new_no;
p      := acv.a_pars_last_key;
p.p_id := old_p_id;
&ifdef trace
t01int4 (ak_sem, 'new_no      ', new_no);
t01int4 (ak_sem, 'old_no      ', old_no);
t01int4 (ak_sem, 'old_lowpars ', old_lowpars);
t01int4 (ak_sem, 'diff        ', diff);
&endif
WHILE ((acv.a_returncode = 0) AND
      (old_no <= old_lowpars)) DO
    BEGIN
    p.p_no := old_no;
    a10_upd_key (acv, p, diff, b_err);
    IF  b_err <> e_ok
    THEN
        a07_b_put_error (acv, b_err, 1)
    ELSE
        old_no := old_no + 1
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
IF  acv.a_pars_last_key.p_id = old_p_id
THEN
    acv.a_pars_last_key := p;
(*ENDIF*) 
lowpars           := old_lowpars;
IF  (acv.a_command_kind  <> single_command) AND
    (acv.a_command_kind  <> show_command)   AND
    (acv.a_command_kind  <> link_command)   AND
    (acv.a_union_cnt = 0)
THEN
    a54set_complex_entry (acv, c_set_p_no);
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a661a_subquery (
            VAR acv                     : tak_all_command_glob;
            VAR dmli                    : tak_dml_info;
            VAR sr_rec                  : tak70_strat_rec;
            curr_n                      : tsp00_Int2;
            VAR pseudo_resultset_select : boolean);
 
VAR
      del_cnt           : integer;
      low_first         : integer;
      m_ex_kind         : tak_execution_kind;
      m_acv_info_output : boolean;
      parsk             : tak_parskey;
      ke                : tgg00_SysInfoKey;
      b_err             : tgg00_BasisError;
      aux_return        : tsp00_Int2;
      aux_errorpos      : tsp00_Int4;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    a_ap_tree^[ curr_n ].n_length := 1;
    low_first                    := 1;
&   ifdef TRACE
    t01int4 (ak_sem, 'curr_n      ', curr_n);
&   ENDIF
    IF  d_view
    THEN
        d_phase_cnt := cak_complex_view_indicator;
    (*ENDIF*) 
    m_acv_info_output := a_info_output;
&   IFDEF TRACE
    t01int4 (ak_sem, 'new m_info  ', ord(m_acv_info_output));
&   ENDIF
    a_info_output := false;
    m_ex_kind     := a_ex_kind;
    IF  NOT (d_view)
    THEN
        a_ex_kind := only_parsing;
    (*ENDIF*) 
    IF  ((hsTempLock_egg00 in dmli.d_globstate) OR
        (hsPermLock_egg00 in dmli.d_globstate))
        AND (a_isolation_info <> temp_lock_rec_get)
    THEN
        a_isolation_info := temp_lock_rec_needed;
    (*ENDIF*) 
    pseudo_resultset_select := m_acv_info_output
          AND (m_ex_kind <> only_parsing);
    IF  a_corr_select
    THEN
        a_ap_tree^[ curr_n ].n_symb := s_sum;
    (*ENDIF*) 
    IF  a_ap_tree^[ curr_n ].n_symb = s_sum
    THEN
        BEGIN
        a_corr_select := true;
        ak661s_corr_start (acv, dmli, parsk, sr_rec, curr_n,
              pseudo_resultset_select, m_ex_kind,
              m_acv_info_output);
        END
    ELSE
        BEGIN
        ak661a_norm_sub (acv, dmli, parsk, sr_rec, curr_n,
              pseudo_resultset_select, m_acv_info_output);
        END;
    (*ENDIF*) 
&   IFDEF TRACE
    t01int4 (ak_sem, 'isolation_in', ord(a_isolation_info));
    t01int4 (ak_sem, 'dm_union    ', ord(d_union));
&   ENDIF
    IF  (a_returncode = 0)                         AND
        (a_corr_select                      OR
        (a_isolation_info = temp_lock_rec_get)) AND
        (NOT d_union)                            AND
        (a_max_intern_select = 0)                   AND
        (NOT d_only_sem_check)                    AND
        (acv.a_qualified_jv_upd = no_jv_upd)
    THEN
        BEGIN
        a54set_complex_entry (acv, c_set_last_pars);
        IF  (a_isolation_info = temp_lock_rec_get) AND
            (NOT a_from_select) AND
            (NOT a_insert_select)
        THEN
            a54_loc_temp_locks (acv,
                  a_transinf.tri_global_state, a_p_arr1);
        (*ENDIF*) 
        parsk           := a_pars_last_key;
        parsk.p_no      := 0;
        parsk.p_id[ 1 ] := a_first_parskey;
        parsk.p_kind    := m_complex;
        END;
    (*ENDIF*) 
    IF  (m_ex_kind <> only_parsing) AND
        (NOT d_only_sem_check)
    THEN
        a661exec_sub (acv, dmli, parsk, curr_n, del_cnt,
              m_acv_info_output, pseudo_resultset_select)
    ELSE
        IF  a_returncode <> 0
        THEN
            BEGIN
            IF  (acv.a_returncode      = cak_e_corelated_subquery_not_allowed) OR
                (acv.a_main_returncode = cak_e_corelated_subquery_not_allowed)
            THEN
                BEGIN
&               IFDEF TRACE
                t01int4 (ak_sem, '661a_subquer', 661);
                t01int4 (ak_sem, 'd_onlysemchk', ord (dmli.d_only_sem_check));
                t01int4 (ak_sem, 'acv_unioncnt', acv.a_union_cnt);
&               ENDIF
                IF  (acv.a_union_cnt > 0) AND d_view
                THEN
                    BEGIN
                    WITH a_unionrec_ptr^.sunionrec DO
                        IF  (a_p_arr1.pbasep <> NIL)
                        THEN
                            ucolpos := a_p_arr1.pbasep^.sresult.bfirstindex;
&                       ifdef trace
                        (*ENDIF*) 
                    (*ENDWITH*) 
                    t01int4 (ak_sem, 'ucolpos 1   ',
                          a_unionrec_ptr^.sunionrec.ucolpos);
&                   endif
                    END;
                (*ENDIF*) 
                IF  (m_ex_kind <> only_parsing)
                THEN
                    BEGIN
                    IF  (acv.a_union_cnt < 2) OR (NOT d_view)
                    THEN
                        a660_prefix_delete (acv, parsk,
                              del_cnt, cak_intern_prefix)
                    ELSE
                        IF  (acv.a_union_cnt  >  0 ) AND
                            (d_esparr.pbasep <> NIL)
                        THEN
                            BEGIN
                            aux_return   := acv.a_returncode;
                            aux_errorpos := acv.a_errorpos;
                            a_returncode := 0;
                            b_err              := e_ok;
                            ke                 := d_esparr.pbasep^.syskey;
&                           IFDEF TRACE
                            t01int4  (ak_sem, 'd_view      ', ord (d_view));
                            t01int4  (ak_sem, 'd_union     ', ord (d_union));
                            t01int4  (ak_sem, 'a_union_cnt ', a_union_cnt);
                            t01int4  (ak_sem, 'd_first_unio', ord (d_first_union));
                            t01int4  (ak_sem, 'd_subquery  ', ord (d_subquery  ));
                            t01int4 (ak_sem, ' first_corr?', ord (d_corr));
                            t01buf (ak_sem, d_esparr.pbasep^, 1,
                                  d_esparr.pbasep^.b_kl + 4 );
                            t01buf (ak_sem, a_p_arr1.pbasep^, 1,
                                  a_p_arr1.pbasep^.b_kl + 4 );
&                           ENDIF
                            a10del_sysinfo (acv, ke, b_err);
                            IF  (b_err <> e_ok)                AND
                                (b_err <> e_sysinfo_not_found) AND
                                (aux_return = 0)
                            THEN
                                a07_b_put_error (acv, b_err, 1)
                            ELSE
                                BEGIN
                                acv.a_returncode := aux_return;
                                acv.a_errorpos   := aux_errorpos;
                                END;
                            (*ENDIF*) 
&                           IFDEF TRACE
                            t01basis_error  (ak_sem, 'b_err       ', b_err);
                            t01int4  (ak_sem, 'returncode  ',
                                  a_returncode);
                            t01int4  (ak_sem, 'd_view      ', ord (d_view));
                            t01int4  (ak_sem, 'd_union     ', ord (d_union));
                            t01int4  (ak_sem, 'a_union_cnt ', a_union_cnt);
                            t01int4  (ak_sem, 'd_first_unio', ord (d_first_union));
                            t01int4  (ak_sem, 'd_subquery  ', ord (d_subquery  ));
                            t01int4 (ak_sem, ' first_corr?', ord (d_corr));
                            t01buf (ak_sem, d_esparr.pbasep^, 1,
                                  d_esparr.pbasep^.b_kl + 4 );
                            t01buf (ak_sem, a_p_arr1.pbasep^, 1,
                                  a_p_arr1.pbasep^.b_kl + 4 );
                            t01int4  (ak_sem, 'a_select_nod', a_select_node);
&                           ENDIF
                            END;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                a_tempinfo_key             := cgg_zero_id;
                a_ap_tree^[ a_select_node ].n_symb := s_sum;
                END
            ELSE
                BEGIN
                a_part_rollback := (a_returncode <> 0) AND
                      (a_returncode <> 100);
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    a_ex_kind := m_ex_kind;
&   IFDEF TRACE
    t01int4 (ak_sem, 'again m_info', ord(m_acv_info_output));
&   ENDIF
    a_info_output := m_acv_info_output;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a661del_all_fromtabs (
            VAR acv : tak_all_command_glob;
            sub_n : integer);
 
VAR
      next_n      : integer;
 
BEGIN
WITH acv DO
    (* PTS 1118537 E.Z. *)
    IF  (a_returncode = 0) AND (sub_n > 0)
    THEN
        BEGIN
        next_n := a_ap_tree^[ sub_n ].n_lo_level;
        IF  next_n > 0
        THEN
            a661del_all_fromtabs (acv, next_n);
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            WITH a_ap_tree^[ sub_n ] DO
                BEGIN
                IF  (n_proc = a92fromsel)
                THEN
                    BEGIN
&                   ifdef trace
                    t01int4 (ak_sem, 'sub_n       ', sub_n);
&                   endif
                    ak661_del_one_fromtab (acv, n_pos);
                    END;
                (*ENDIF*) 
                next_n := n_sa_level;
                IF  (next_n > 0) AND
                    (a_returncode = 0)
                THEN
                    a661del_all_fromtabs (acv, next_n);
                (*ENDIF*) 
                END
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a661get_from_select_table (
            VAR acv        : tak_all_command_glob;
            VAR dmli       : tak_dml_info;
            from_select_no : tsp00_Int2;
            all            : boolean);
 
VAR
      f_ok     : boolean;
      tableid  : tgg00_Surrogate;
      fn_tabid : tgg00_Surrogate;
 
BEGIN
WITH acv, dmli, d_tabarr[ d_acttabindex ] DO
    BEGIN
    (* PTS 1111510 E.Z. *)
    a661_build_t_fromsel_tableid (tableid, fn_tabid,
          a_curr_ex_parskey, cak_fromseltab_site, from_select_no);
    d_sparr.psynfound := false;
    d_sparr.pcount    := 0;
    a661_get_from_select_table (acv, tableid, d_sparr.pbasep, d_fix, all, f_ok);
    IF  f_ok
    THEN
        BEGIN
        d_table := a01_il_b_identifier;
        WITH d_sparr, pbasep^, sbase DO
            BEGIN
            ouser            := a_curr_user_name;
            otable           := a01_il_b_identifier;
            ospecialname     := [  ];
            oprivset         := [  ];
            osetallpriv      := [  ];
            oattributes      := [  ];
            ospecs_needed    := ons_only_tablename;
            oall_priv        := true;
            oview            := false;
            ocomplex_view    := false;
            oviewqual        := false;
            oviewcheck       := false;
            otreeid          := btreeid;
            IF  d_acttabindex = 1
            THEN
                ocounttabs := 0;
            (*ENDIF*) 
            IF  d_acttabindex < d_cntfromtab
            THEN
                d_tabarr[ d_acttabindex + 1 ].ocounttabs := ocounttabs + bv_tabcount
            ELSE
                d_maxcounttabs := ocounttabs + bv_tabcount;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        END
    ELSE
        a07_b_put_error (acv, e_sysinfo_not_found, 1);
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak661_subquery_found (
            VAR acv       : tak_all_command_glob;
            curr_n        : tsp00_Int2;
            VAR found     : boolean);
 
BEGIN
WITH acv DO
    BEGIN
&   IFDEF TRACE
    t01int4 (ak_sem, 'curr_n      ', curr_n);
&   ENDIF
    found := a_ap_tree^[ curr_n ].n_proc <> a92fromsel;
    IF  (NOT found) AND
        (a_ap_tree^[ curr_n ].n_lo_level > 0)
    THEN
        ak661_subquery_found(acv, a_ap_tree^[ curr_n ].n_lo_level, found);
    (*ENDIF*) 
    IF  (NOT found) AND
        (a_ap_tree^[ curr_n ].n_sa_level > 0)
    THEN
        ak661_subquery_found(acv, a_ap_tree^[ curr_n ].n_sa_level, found);
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      a661_fromsel_found (
            VAR acv : tak_all_command_glob;
            sub_n : integer) : boolean;
 
VAR
      next_n      : integer;
      found       : boolean;
 
BEGIN
found := false;
WITH acv DO
    IF  a_returncode = 0
    THEN
        BEGIN
        next_n := a_ap_tree^[ sub_n ].n_lo_level;
        IF  next_n > 0
        THEN
            found := a661_fromsel_found (acv, next_n);
        (*ENDIF*) 
        IF  (a_returncode = 0) AND NOT found
        THEN
            WITH a_ap_tree^[ sub_n ] DO
                BEGIN
                IF  (n_proc = a92fromsel)
                THEN
                    found := true;
                (*ENDIF*) 
                next_n := n_sa_level;
                IF  (next_n > 0) AND
                    (a_returncode = 0) AND NOT found
                THEN
                    found := a661_fromsel_found (acv, next_n);
                (*ENDIF*) 
                END
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDWITH*) 
a661_fromsel_found := found;
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
