.nf
 
 
    ========== licence begin  GPL
    Copyright (c) 1999-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) 1999-2004 SAP AG
SAP Database Technology
 
Release :      Date : 2000-11-23
*****************************************************
modname : VAK67
changed : 2000-11-23
module  : Part2_Select_Expression
 
Author  : ElkeZ
Created : 1985-07-09
*****************************************************
 
Purpose : Second part of processing a mass select
 
Define  :
 
        PROCEDURE
              a67_fetchkeys (
                    VAR acv   : tak_all_command_glob;
                    ppoint    : tak_sysbufferaddress;
                    recmaxlen : integer;
                    invmaxlen : integer);
 
        PROCEDURE
              a67_s_sel_second_part (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    VAR select_rec : tak_select_record;
                    VAR sr_rec     : tak70_strat_rec);
 
        PROCEDURE
              a67_update_atinoutpos (
                    VAR acv          : tak_all_command_glob;
                    VAR dmli         : tak_dml_info;
                    update_changepos : boolean);
 
        PROCEDURE
              a67_sel2_second_part (
                    VAR acv            : tak_all_command_glob;
                    VAR dmli           : tak_dml_info;
                    VAR res_tree       : tgg00_FileId;
                    is_not_corr_search : boolean;
                    last_pars_part     : boolean;
                    view_done          : boolean;
                    VAR sr_rec         : tak70_strat_rec);
 
        PROCEDURE
              a67_sel3_second_part (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    VAR select_rec : tak_select_record;
                    VAR sr_rec     : tak70_strat_rec);
 
        PROCEDURE
              a67_bextcolindex (
                    VAR d_esparr : tak_syspointerarr;
                    outcolno     : integer);
 
        PROCEDURE
              a67_put_all_views_into (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a67_first_corr (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a67_corr_search (
                    VAR acv                 : tak_all_command_glob;
                    VAR dmli                : tak_dml_info;
                    only_having_columns_get : boolean;
                    VAR starttabno          : integer;
                    only_split              : boolean;
                    predefined_pno          : integer;
                    VAR old_infolen         : integer;
                    VAR rtree               : tgg00_FileId);
 
        PROCEDURE
              a67_keyspecs (
                    VAR reskeyrec   : tak_sysbufferaddress;
                    primlen         : integer;
                    invlen          : integer);
 
.CM *-END-* define --------------------------------------
***********************************************************
 
Use     :
 
        FROM
              Scanner : VAK01;
 
        VAR
              a01sysnullkey        : tgg00_SysInfoKey;
              a01defaultkey        : tgg00_SysInfoKey;
              a01_i_domain         : tsp00_KnlIdentifier;
              a01_i_public         : tsp00_KnlIdentifier;
              a01_i_temp           : tsp00_KnlIdentifier;
              a01_il_b_identifier  : tsp00_KnlIdentifier;
              a01diag_analyze_on   : boolean;
 
      ------------------------------ 
 
        FROM
              AK_semantic_scanner_tools : VAK05;
 
        PROCEDURE
              a05identifier_get (
                    VAR acv     : tak_all_command_glob;
                    tree_index  : integer;
                    obj_len     : integer;
                    VAR moveobj : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              AK_universal_semantic_tools : VAK06;
 
        PROCEDURE
              a06a_mblock_init (
                    VAR acv      : tak_all_command_glob;
                    mtype        : tgg00_MessType;
                    m2type       : tgg00_MessType2;
                    VAR tree     : tgg00_FileId);
 
        PROCEDURE
              a06cpy_mblock (
                    VAR acv        : tak_all_command_glob;
                    VAR src_mblock : tgg00_MessBlock;
                    VAR dst_mblock : tgg00_MessBlock;
                    withoutData    : boolean;
                    VAR e          : tgg00_BasisError);
 
        PROCEDURE
              a06extcolno (
                    VAR baserec  : tak_baserecord;
                    extcolno     : integer;
                    VAR col_ptr  : tak00_colinfo_ptr);
 
        PROCEDURE
              a06get_username (
                    VAR acv        : tak_all_command_glob;
                    VAR tree_index : integer;
                    VAR username   : tsp00_KnlIdentifier);
 
        PROCEDURE
              a06_systable_get (
                    VAR acv      : tak_all_command_glob;
                    dstate       : tak_directory_state;
                    VAR tableid  : tgg00_Surrogate;
                    VAR base_ptr : tak_sysbufferaddress;
                    all          : boolean;
                    VAR ok       : boolean);
 
        PROCEDURE
              a06finish_curr_retpart (
                    VAR acv   : tak_all_command_glob;
                    part_kind : tsp1_part_kind;
                    arg_count : tsp00_Int2);
 
      ------------------------------ 
 
        FROM
              AK_Identifier_Handling : VAK061;
 
        PROCEDURE
              a061colinfo_to_var (
                    VAR src : tak00_columninfo;
                    VAR dst : tak00_columninfo);
 
        FUNCTION
              a061exist_columnname (
                    VAR base_rec    : tak_baserecord;
                    VAR column      : tsp00_KnlIdentifier;
                    VAR colinfo_ptr : tak00_colinfo_ptr) : boolean;
 
        PROCEDURE
              a061get_colname (
                    VAR col_info : tak00_columninfo;
                    VAR colname  : tsp00_KnlIdentifier);
&       ifdef trace
 
        PROCEDURE
              a061td_colinfo (
                    VAR colinfo : tak00_columninfo;
                    index : integer);
&       endif
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK07;
 
        PROCEDURE
              a07_b_put_error (
                    VAR acv : tak_all_command_glob;
                    b_err   : tgg00_BasisError;
                    err_code : tsp00_Int4);
 
        PROCEDURE
              a07_nb_put_error (
                    VAR acv  : tak_all_command_glob;
                    b_err    : tgg00_BasisError;
                    err_code : tsp00_Int4;
                    VAR n    : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK071;
 
        FUNCTION
              a07_return_code (
                    b_err   : tgg00_BasisError;
                    sqlmode : tsp00_SqlMode) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              Systeminfo_cache : VAK10;
 
        PROCEDURE
              a10cpy_result (
                    VAR acv         : tak_all_command_glob;
                    VAR pars_syskey : tgg00_SysInfoKey;
                    VAR res_syskey  : tgg00_SysInfoKey;
                    rescnt          : tsp00_Int4;
                    VAR b_err       : tgg00_BasisError);
 
        PROCEDURE
              a10repl_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10add_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10_nil_get_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syskey   : tgg00_SysInfoKey;
                    dstate       : tak_directory_state;
                    syslen       : tsp00_Int2;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10del_sysinfo (
                    VAR acv     : tak_all_command_glob;
                    VAR syskey  : tgg00_SysInfoKey;
                    VAR b_err   : tgg00_BasisError);
 
        PROCEDURE
              a10_key_del  (
                    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
              a10_rel_sysinfo (
                    VAR acv    : tak_all_command_glob;
                    VAR syskey : tgg00_SysInfoKey);
 
        PROCEDURE
              a10intermediate_mblock (
                    VAR acv        : tak_all_command_glob;
                    VAR mblock     : tgg00_MessBlock;
                    VAR mblock_ptr : tgg00_MessBlockPtr);
 
        PROCEDURE
              a10new (
                    VAR acv  : tak_all_command_glob;
                    obj_size : tsp00_Int4;
                    VAR p    : tgg00_StackListPtr);
 
        PROCEDURE
              a10dispose (
                    VAR acv : tak_all_command_glob;
                    VAR p : tgg00_StackListPtr);
 
        PROCEDURE
              a10rel_sysinfo (syspointer : tak_sysbufferaddress);
 
      ------------------------------ 
 
        FROM
              AK_Table : VAK11;
 
        PROCEDURE
              a11sort (VAR base_rec: tak_baserecord);
 
      ------------------------------ 
 
        FROM
              AK_View_semantic : VAK16;
 
        PROCEDURE
              a16col_to_view_description (
                    VAR acv      : tak_all_command_glob;
                    VAR dmli     : tak_dml_info;
                    VAR col_info : tak00_columninfo;
                    use_extcolno : boolean);
 
      ------------------------------ 
 
        FROM
              AK_update_statistics : VAK28;
 
        FUNCTION
              a28prim_pages (
                    VAR acv     : tak_all_command_glob;
                    VAR baserec : tak_baserecord) : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              Executing_complex : VAK502;
 
        PROCEDURE
              a502destroy_file (
                    VAR acv          : tak_all_command_glob;
                    VAR tree         : tgg00_FileId);
 
      ------------------------------ 
 
        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_select_last_part (
                    VAR acv              : tak_all_command_glob;
                    VAR dmli             : tak_dml_info;
                    VAR user_result_tree : tgg00_FileId;
                    last_pars_part       : boolean);
 
        PROCEDURE
              a54_store_parsinfo (
                    VAR acv   : tak_all_command_glob;
                    VAR sparr : tak_syspointerarr);
 
        PROCEDURE
              a54_view_put_into (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a54_joinview_baserecords (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a54_fixedpos (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
      ------------------------------ 
 
        FROM
              diagnose analyze : VAK544;
 
        PROCEDURE
              a544get_cmdid(
                    VAR acv     : tak_all_command_glob;
                    VAR parskey : tak_parskey;
                    VAR cmdid   : tgg00_Surrogate);
 
      ------------------------------ 
 
        FROM
              Select_Syntax : VAK60;
 
        PROCEDURE
              a60_p_info_output (
                    VAR acv   : tak_all_command_glob;
                    VAR sparr : tak_syspointerarr);
 
        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
              a60resnum (
                    VAR acv     : tak_all_command_glob;
                    VAR moveobj : tsp00_Buf;
                    startpos    : integer);
 
      ------------------------------ 
 
        FROM
              Select_List : VAK61;
 
        PROCEDURE
              a61_is_orderfield (
                    VAR acv       : tak_all_command_glob;
                    VAR dmli      : tak_dml_info;
                    VAR colinf    : tak00_columninfo;
                    order_ptr     : tak00_ord_fields_ptr;
                    single_column : boolean;
                    convert_t     : tak_convert_type;
                    curr_n        : tsp00_Int2;
                    VAR col       : tsp00_KnlIdentifier);
 
        PROCEDURE
              a61_rel_old_table (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    i        : integer);
 
        PROCEDURE
              a61_put_last_func (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a61_search_table (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a61_set_jump (
                    VAR mblock : tgg00_MessBlock;
                    stentrynr : integer;
                    operator  : tgg00_StackEntryType);
 
        PROCEDURE
              a61_var_col_stackentry (
                    VAR acv          : tak_all_command_glob;
                    VAR dmli         : tak_dml_info;
                    VAR colinf       : tak00_columninfo;
                    may_be_together  : boolean;
                    VAR put_together : boolean;
                    VAR output_len   : integer;
                    is_corr_column   : boolean;
                    convert_t        : tak_convert_type;
                    convert_type     : tsp00_DataType);
 
        PROCEDURE
              a61_update_column (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    VAR minkeylen  : integer;
                    curr_n         : integer);
 
        PROCEDURE
              a61_is_group_field (
                    VAR acv       : tak_all_command_glob;
                    VAR dmli      : tak_dml_info;
                    VAR fieldname : tsp00_KnlIdentifier;
                    extcolno      : tsp00_Int2;
                    is_expression : boolean;
                    expression_n  : tsp00_Int2;
                    errorpos      : integer);
 
      ------------------------------ 
 
        FROM
              Execute_Where_Part : VAK65;
 
        PROCEDURE
              a65_search_condition (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    VAR first_node : integer);
 
        PROCEDURE
              a65_val_expr (
                    VAR acv    : tak_all_command_glob;
                    VAR dmli   : tak_dml_info;
                    VAR colin  : tak00_scolinf;
                    first_node : integer);
 
      ------------------------------ 
 
        FROM
              Execute_Select_Expression : VAK660;
 
        PROCEDURE
              a660_search_one_table (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    table_node     : integer;
                    all            : boolean;
                    check_teresult : boolean;
                    lock_spec      : tak_lockenum;
                    wanted_priv    : tak00_PrivR);
 
        PROCEDURE
              a660_from_part (
                    VAR acv   : tak_all_command_glob;
                    VAR dmli  : tak_dml_info;
                    from_node : integer);
 
        PROCEDURE
              a660_new_pparsp (
                    VAR acv        : tak_all_command_glob;
                    VAR sparr      : tak_syspointerarr;
                    first_parsinfo : boolean;
                    complicate     : boolean);
 
        PROCEDURE
              a660_lowpars_pparsp (
                    VAR acv        : tak_all_command_glob;
                    VAR pparsp     : tak_sysbufferaddress;
                    needs_twuseold : boolean;
                    to_release     : boolean;
                    lowpars        : tsp00_Uint1);
 
        PROCEDURE
              a660set_subq_info (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
      ------------------------------ 
 
        FROM
              Subquery_handling : VAK661;
 
        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);
 
        FUNCTION
              a661_is_fromsel_table (
                    VAR acv     : tak_all_command_glob;
                    VAR ftreeid : tgg00_FileId) : boolean;
 
      ------------------------------ 
 
        FROM
              Resultname_handling : VAK663;
 
        PROCEDURE
              a663restable_get (
                    VAR acv    : tak_all_command_glob;
                    dstate     : tak_directory_state;
                    VAR tablen : tsp00_KnlIdentifier;
                    VAR sparr  : tak_syspointerarr;
                    VAR ok     : boolean);
 
        FUNCTION
              a663parse_for_execute (VAR acv : tak_all_command_glob) : boolean;
 
      ------------------------------ 
 
        FROM
              Join_Select : VAK680;
 
        PROCEDURE
              a680_join (
                    VAR acv                 : tak_all_command_glob;
                    VAR dmli                : tak_dml_info;
                    VAR res_tree            : tgg00_FileId;
                    VAR ak_strat_interface  : tak70_strat_rec;
                    last_pars_part          : boolean;
                    VAR jvrec               : tak68_joinview_rec);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              join_trace_routines : VAK683;
 
        PROCEDURE
              a683_output (
                    debug    : tgg00_Debug;
                    VAR dmli : tak_dml_info);
&       endif
 
      ------------------------------ 
 
        FROM
              Build_Strategy : VAK70;
 
        VAR
              a70glob_fetch_strats      : tgg07_StratEnumSet;
 
        PROCEDURE
              a70_strategy_search (
                    VAR acv       : tak_all_command_glob;
                    VAR dmli      : tak_dml_info;
                    VAR rtree     : tgg00_FileId;
                    VAR strat_rec : tak70_strat_rec);
 
        PROCEDURE
              a70_keylengths (
                    VAR acv           : tak_all_command_glob;
                    strategy          : tgg07_StratEnum;
                    fetch_primkeylen  : integer;
                    fetch_invkeylen   : tsp00_Int2;
                    build_primkeylen  : integer;
                    VAR primlen       : integer;
                    VAR invlen        : integer);
 
      ------------------------------ 
 
        FROM
              Fetch_Without_Resulttable : VAK74;
 
        PROCEDURE
              a74_copy_twokeys (
                    VAR acv     : tak_all_command_glob;
                    VAR keysbuf : tak_res_keysbuf;
                    VAR source  : tak_two_keyspecs;
                    VAR dest    : tak_two_keyspecs;
                    res_stat    : tak_sresstate);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_1 : VBD01;
 
        VAR
              b01niltree_id : tgg00_FileId;
 
        PROCEDURE
              b01empty_file (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01glob          : tgg00_KernelGlobals;
 
      ------------------------------ 
 
        FROM
              Select_Help_Procedures : VGG04;
 
        PROCEDURE
              g04build_temp_tree_id (
                    VAR curr : tgg00_FileId;
                    VAR t : tgg00_TransContext);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id   : tsp00_C6;
                    mod_num  : tsp00_Int4;
                    obj_upb  : tsp00_Int4;
                    obj      : tsp00_MoveObjPtr;
                    obj_pos  : tsp00_Int4;
                    length   : tsp00_Int4;
                    fillchar : char;
                    VAR e    : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalMove  (
                    mod_id          : tsp00_C6;
                    mod_intern_num  : tsp00_Int4;
                    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;
                    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);
 
      ------------------------------ 
 
        FROM
              GET-Conversions : VSP40;
 
        PROCEDURE
              s40g4int (
                    VAR buf  : tsp00_ResNum;
                    pos      : tsp00_Int4;
                    VAR dest : tsp00_Int4;
                    VAR res  : tsp00_NumError);
&       IFDEF TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01refinfoindex (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname;
                    idx   : tgg00_RefInfoIndex);
 
        PROCEDURE
              t01recursive_state (
                    debug           : tgg00_Debug;
                    nam             : tsp00_Sname;
                    recursive_state : tak_recursive_state);
 
        PROCEDURE
              t01moveobj (
                    debug       : tgg00_Debug;
                    VAR moveobj : tak_res_keysbuf;
                    startpos    : tsp00_Int4;
                    endpos      : tsp00_Int4);
 
        PROCEDURE
              t01sname (
                    debug   : tgg00_Debug;
                    nam     : tsp00_Sname);
 
        PROCEDURE
              t01corr_type (
                    debug     : tgg00_Debug;
                    nam       : tsp00_Sname;
                    corr_type : tak_corr_type);
 
        PROCEDURE
              t01bool (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    curr_bool: boolean);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01p4int4 (
                    level : tgg00_Debug;
                    nam   : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    int_2 : tsp00_Int4;
                    int_3 : tsp00_Int4;
                    int_4 : tsp00_Int4);
 
        PROCEDURE
              t01lidentifier (
                    level      : tgg00_Debug;
                    identifier : tsp00_KnlIdentifier);
 
        PROCEDURE
              t01name (
                    level : tgg00_Debug;
                    nam : tsp00_Name);
 
        PROCEDURE
              t01treeid (
                    level      : tgg00_Debug;
                    nam        : tsp00_Sname;
                    VAR treeid : tgg00_FileId);
 
        PROCEDURE
              t01buf  (
                    level     : tgg00_Debug;
                    VAR buf   : tak_resname_record (*tgg07_StrategyInfo*);
                    pos_start : integer;
                    pos_end   : integer);
 
        PROCEDURE
              t01buf1 (
                    level     : tgg00_Debug;
                    VAR buf   : tgg00_SysInfoKey;
                    pos_start : integer;
                    pos_end   : integer);
 
        PROCEDURE
              t01messblock (
                    level        : tgg00_Debug;
                    nam          : tsp00_Sname;
                    VAR mblock   : tgg00_MessBlock);
 
        PROCEDURE
              t01qual (
                    level     : tgg00_Debug;
                    VAR q_buf : tgg00_QualBuf);
 
        PROCEDURE
              t01warningset (
                    debug : tgg00_Debug;
                    nam  : tsp00_Sname;
                    warn : tsp00_WarningSet);
&       ENDIF
 
.CM *-END-* use -----------------------------------------
***********************************************************
 
Synonym :
 
        PROCEDURE
              a05identifier_get;
 
              tsp00_MoveObj tsp00_KnlIdentifier
 
        PROCEDURE
              a10new;
 
              tak_sysbufferaddress tgg00_StackListPtr
 
        PROCEDURE
              a10dispose;
 
              tak_sysbufferaddress tgg00_StackListPtr
 
        PROCEDURE
              a60resnum;
 
              tsp00_MoveObj tsp00_Buf
 
        PROCEDURE
              s40g4int;
 
              tsp00_MoveObj tsp00_ResNum
 
        PROCEDURE
              t01buf;
 
              tsp00_Buf tak_resname_record (*tgg07_StrategyInfo*)
 
        PROCEDURE
              t01buf1;
 
              tsp00_Buf tgg00_SysInfoKey
 
        PROCEDURE
              t01moveobj;
 
              tsp00_MoveObj tak_res_keysbuf
 
.CM *-END-* synonym -------------------------------------
***********************************************************
 
Description:
 
C O R R E L A T I O N
 
 
CONST
  mxak_one_corcolumn        =          16  (* &tak_one_corcolumn *);
  (* correlation_columns of all tables *)
  cak_maxcorcolumns         =          64;
  cak_maxcorlevel           =           4; (* maxno. of corr-subqueries *)
  cak_maxcortables          =          64; (* correlation_tables *)
  mxak_corfields            =        1024  (* mxak_one_corcolumn *
        cak_maxcorcolumns *);
  mxak_correc               =        1096  (* cak_maxcorcolumns
        * mxak_one_corcolumn + 16*4 + 8 *);
 
  tak_corlevel      =  ARRAY [ 1..cak_maxcorlevel ] OF tsp00_Uint1;
 
  tak_soc_record  =  RECORD
        socoldtabno    : tsp00_Uint1;
        socselecttabno : tsp00_Uint1;
        socfields      : tsp00_Uint1;
        socfill        : tsp00_Uint1
  END;
 
 
  tak_one_corcolumn  =  RECORD (* 16 Bytes, mxak_one_corcolumn *)
        cfieldno  : tsp00_Int2;
        cnode     : tsp00_Int2;
        clevel    : tak_corlevel;
        csetnode  : tsp00_Int2;
        ctabno    : tsp00_Uint1;
        ccntcol   : tsp00_Uint1;
        ccmd_part : tak_cmd_part_type;
        cdatatype : tsp00_DataType;
        cfiller2  : tsp00_Int2;
  END;
 
  tak_all_corcolumns  =  ARRAY [ 1..cak_maxcorcolumns ] OF
        tak_one_corcolumn;
 
  tak_correcord  =  RECORD
        tc_reclen        : tsp00_Int2;
        tc_keylen        : tsp00_Int2;
        tc_surrogate     : tgg00_Surrogate;
        tc_entrytype     : tsp00_C2;
        tc_segno         : tsp00_Int2;
        tc_no_of_tables  : tsp00_Int2;
        tc_no_of_columns : tsp00_Int2;
        tc_starttable    : tsp00_Int2;
        tc_oldstarttable : tsp00_Int2;
        tc_tables        : ARRAY [ 1..16 ] OF tak_soc_record;
        tc_columns       : tak_all_corcolumns
  END;
 
 
  tak_corfields  =  RECORD
        cfields      : tak_all_corcolumns;
        cused_fields : tsp00_Int2;
        ccfill       : tsp00_Int2
  END;
 
      tak_one_table_specialname =  SET OF
            (oresfile,
            oissynonym,
            oisreference,
            oisjoinview,
            oispartjoinview);
 
  tak_corr_type  =  (no_correlation,
        correlation,
        first_correlation,
        lowest_of_correlation)
 
Ein Beispiel
 
Enter command:
CONNECT KERN TEST !
 
Enter command:
CREATE TABLE T ( A CHAR (8)) !
 
Enter command:
INSERT T SET A = 'aaa'!
 
Enter command:
CREATE TABLE T1 ( A1 CHAR (8))!
 
Enter command:
INSERT T1 SET A1 = 'aaa'!
 
Enter command:
SELECT * FROM T WHERE EXISTS (SELECT A1 FROM T1 WHERE T.A = T1.A1)!
 
   Ausgabe des PARSE-Baumes nach dem Parsen
 
Index Proc   Symb    Pos  Len  Lo   Sa
   1   63      1    sum        2   10
   2   60      1               3    5
   3   60      2               4    0
   4  Symb stern      8    1   0    0
   5   63      3               6    8
   6   66      1               7    0
   7  Symb tablen    15    1   0    0
   8   63     10               9    0
   9   64      3    exists    11    0
  10   63     11               0    0
  11   91     -2              12   27
  12   60      1              13   15
  13   60      2              14    0
  14  Symb columnn   38    2   0    0
  15   63      3              16   18
  16   66      1              17    0
  17  Symb tablen    46    2   0    0
  18   63     10              21   24
  19  Symb tablen    55    1   0   20
  20  Symb columnn   57    1   0   22
  21   64      3    equal     19    0
  22  Symb tablen    61    2   0   23
  23  Symb columnn   64    2   0    0
  24   63      5              25    0
  25   63      9              26    0
  26  Symb fixed      1    0   0    0
  27  Symb unknown  768    0   9    0
 1------ 2------ 3------ 4------
  | a63|__| a60|__| a60|__|Symb|
  |   1|  |   1|  |   2|  |ster|
  ------  ------  ------  ------
     |       |
     |   5------ 6------ 7------
     |    | a63|__| a66|__|Symb|
     |    |   3|  |   1|  |tabl|
     |    ------  ------  ------
     |       |
     |   8------ 9------11------12------13------14------
     |    | a63|__| a64|__| a91|__| a60|__| a60|__|Symb|
     |    |  10|  |exis|  |  -2|  |   1|  |   2|  |colu|
     |    ------  ------  ------  ------  ------  ------
     |                       |       |
     |                       |  15------16------17------
     |                       |    | a63|__| a66|__|Symb|
     |                       |    |   3|  |   1|  |tabl|
     |                       |    ------  ------  ------
     |                       |       |
     |                       |  18------21------19------
     |                       |    | a63|__| a64|__|Symb|
     |                       |    |  10|  |equa|  |tabl|
     |                       |    ------  ------  ------
     |                       |       |               |
     |                       |       |          20------
     |                       |       |            |Symb|
     |                       |       |            |colu|
     |                       |       |            ------
     |                       |       |               |
     |                       |       |          22------
     |                       |       |            |Symb|
     |                       |       |            |tabl|
     |                       |       |            ------
     |                       |       |               |
     |                       |       |          23------
     |                       |       |            |Symb|
     |                       |       |            |colu|
     |                       |       |            ------
     |                       |       |
     |                       |  24------25------26------
     |                       |    | a63|__| a63|__|Symb|
     |                       |    |   5|  |   9|  |fixe|
     |                       |    ------  ------  ------
     |                       |
     |
10------
  | a63|
  |  11|
  ------
 
    Ausgabe des PARSE-Baumes am Ende des Befehls
    (man beachte Baumknoten 1 und 19)
 
Index Proc   Symb    Pos  Len  Lo   Sa
   1   63      1    sum        2   10
   2   60      1               3    5
   3   60      2               4    0
   4  Symb stern      8    1   0    0
   5   63      3               6    8
   6   66      1               7    0
   7  Symb tablen    15    1   0    0
   8   63     10               9    0
   9   64      3    exists    11    0
  10   63     11               0    0
  11   91     -2              12   28
  12   60      1              13   15
  13   60      2              14    0
  14  Symb columnn   38    2   0    0
  15   63      3              16   18
  16   66      1              17    0
  17  Symb tablen    46    2   0    0
  18   63     10              21   24
  19   67      5               0    0
  20  Symb columnn   57    1   0   22
  21   64      3    equal     22    0
  22  Symb tablen    61    2   0   23
  23  Symb columnn   64    2   0   19
  24   63      5              25    0
  25   63      9              26    0
  26  Symb fixed      1    0   0    0
  27  Symb unknown  768    0   9    0
  28  Symb unknown 3584    0   0    0
 1------ 2------ 3------ 4------
  | a63|__| a60|__| a60|__|Symb|
  |   1|  |   1|  |   2|  |ster|
  ------  ------  ------  ------
     |       |
     |   5------ 6------ 7------
     |    | a63|__| a66|__|Symb|
     |    |   3|  |   1|  |tabl|
     |    ------  ------  ------
     |       |
     |   8------ 9------11------12------13------14------
     |    | a63|__| a64|__| a91|__| a60|__| a60|__|Symb|
     |    |  10|  |exis|  |  -2|  |   1|  |   2|  |colu|
     |    ------  ------  ------  ------  ------  ------
     |                       |       |
     |                       |  15------16------17------
     |                       |    | a63|__| a66|__|Symb|
     |                       |    |   3|  |   1|  |tabl|
     |                       |    ------  ------  ------
     |                       |       |
     |                       |  18------21------22------
     |                       |    | a63|__| a64|__|Symb|
     |                       |    |  10|  |equa|  |tabl|
     |                       |    ------  ------  ------
     |                       |       |               |
     |                       |       |          23------
     |                       |       |            |Symb|
     |                       |       |            |colu|
     |                       |       |            ------
     |                       |       |               |
     |                       |       |          19------
     |                       |       |            | a67|
     |                       |       |            |ebcd|
     |                       |       |            ------
     |                       |       |
     |                       |  24------25------26------
     |                       |    | a63|__| a63|__|Symb|
     |                       |    |   5|  |   9|  |fixe|
     |                       |    ------  ------  ------
     |                       |
     |                  28------
     |                    |Symb|
     |                    |unkn|
     |                    ------
     |
10------
  | a63|
  |  11|
  ------
 
Die Abarbeitung einer Correlation geschieht wie folgt:
 
Es wird ganz normal geparst. Dabei erkennt man nur syntaktische Strukturen,
also auch die Subqueries.
 
In VAK35 wird dann a660_select aufgerufen, weil der erste Knoten
anzeigt, dass es sich um ein Mengenselect handelt.
Das a660_select ruft, wenn man kein UNION o.ae. findet, das
a660select auf. In diesem wird festgestellt, dass an n_sa_level
des aktuellen Knotens noch ein Knoten haengt.
 
In diesem Knoten (bei uns Nr. 10) steht drin, bei welchem Knoten die
darunterliegende Subquery anfaengt (bei uns hier 11).
Es wird jetzt ueber ak660subquery und weitere Prozeduraufrufe
bis zur untersten Subquery vorgedrungen, die als erste abgearbeitet
werden soll.
 
Bei der Bearbeitung einer correlated Subquery stellt man irgendwann
auf der Strecke im VAK61 fest, dass man eine angesprochene Tabelle
in dem aktuellen SELECT nicht kennt (Correlated Spalten muessen ja
immer mit der Tabelle davor angegeben werden). Daraus folgt der
Fehler corelated_subquery_not_allowed.
 
Bei einem Fehler hangelt das System wieder zurueck, raeumt moeglichst
irgendwelche Hinterlassenschaften auf und findet sich im VAK35 wieder.
In VAK35 a35_asql_statement gibt es ja so eine Abfrage, ob
corelated_subquery_not_allowed kam. Dann wird noch einmal in VAK660
a660select reingegangen.
 
Damit nicht wieder derselbe Kaese mit der untersten Subquery losgeht,
wurde am Ende des ersten Durchlaufes (der mit corelated_subquery_not...
endete) in dem obersten Select-Knoten (bei uns 1) ein 'sum' eingetragen.
(Der Name sum hat keine Bedeutung, bloss sum und count waren/sind
immer Hinweise auf besondere Effekte ]
 
Wenn man also 'sum' findet, weiss man, dass es sich um eine Correlation
handelt.
 
Das oberste Select wird weitestgehend abgearbeitet. Es kommt aber in
a67_sel2_second_part in das a67_first_corr rein, weil
first_correlation sitzt. In a67_first_corr wird durch ALLE
Subqueries durchgegangen und folgendes gemacht:
 
1) Es wird die lokale Variable vom Typ tak_cortables gefuellt
und zwar mit den Tabellen, die in ALLEN FROM-Teilen aller
Subqueries und des obersten Select angegeben wurden.
 
  ocuser      : <auth id> der Tabelle
  octable     : Tabellenname
  ocreference : ggf. angegebener Referenzname
  ocspecialname: Angabe, ob ein Referenzname angegeben wurde,
                 und ob es ein Synonym oder eine Ergebnismenge ist
 
 
Dieses Array wird NICHT gespeichert und wuerde mit seinen
136 * 64 Bytes auch nicht in einen Record passen.
Man koennte aber die notwendigen Teile in ein Ding reinkopieren,
was dann abgespeichert wuerde oder dieses Array teilen und in drei
Records stopfen.
ak67from_part_to_cortabs wird benutzt.
 
2) Es wird dann durch die WHERE-Klausel (und die HAVING-Klausel)
gegangen und fuer jede Spalte geguckt, ob es eine Correlation-Spalte
ist oder eine, deren Tabelle im aktuellen SELECT steckt.
 
Wenn die Tabelle nicht im aktuellen SELECT steckt, dann wird geguckt,
ob die angegebene Tabelle in der aktuellen Hierarchie von FROM-Klauseln
(also Selects) drinsteht. Wenn ja, wird ueberprueft, ob die Spalte
in der Tabelle steht (a06_exist_columnname).
 
Wenn ja, wird diese Correlation_Spalte in das
Array tak_corfields.cfields gesteckt. Darin enthalten ist die Tabellennr
der Correlation-Tabelle, also der Index der Tabelle in dem Array
vom Typ tak_cortables.
 
Es ist die externe Nummer der Spalte in dieser Tabelle enthalten
(= der entsprechenden Zeile beim SHOW TABLEDEF, wenn der Benutzer
einen Schluessel definiert hat, sonst die (n-1)-Zeile). Damit kann
man in der Tabellenbeschreibung ganz leicht wieder auf dieses Feld
zugreifen.
 
Es ist die Knotennummer des Knotens im Parsebaum enthalten, der
die Beschreibung des Tabellennamens (oder der <auth id>) enthaelt
in dem Array enthalten. Damit gibt es den Querverweis zwischen
Parsebaum und Correlation_Spalten-Beschreibung.
 
csetnode und ccntcol sind nur fuer die Abarbeitung von Having-Klauseln
(wo ja auch in der darunterliegenden Subquery <set function>s in der
WHERE-Klausel sein duerfen) notwendig.
 
clevel gibt an, auf welchem hierarchischem Level man sich bewegt
(maximal 4 Level moeglich) und welche von den gegebenenfalls
mehreren Subqueries auf einem Level gerade gemeint ist.
 
Gleichzeitig wird fuer die entsprechende Correlation-Tabelle der
Zaehler ocfields hochgezaehlt, um anzuzeigen, dass aus dieser Tabelle
wirklich Correlation-Spalten entspringen.
 
 
Wenn man sich durch die Rekursion wieder hochgequaelt hat, werden
die Erkenntnisse in tak_correcord uebertragen.
 
Es werden dort nur maximal 16 Tabellen eingetragen. Es sind nur solche,
von denen ermittelt wurde, dass sie Correlation-Spalten enthalten,
also dass sie Correlation-Tables sind.
 
Durch socoldtabno wird die Verbindung zu dem Array in tak_cortables
hergestellt (es wird in socoldtabno der Index eingetragen, unter
dem diese Tabelle in tak_cortables beschrieben war). Damit ist
auch wieder die Verbindung zu ctabno in der Spaltenbeschreibung
hergestellt.
 
socselecttabno gibt die Nummer der angegebenen Tabelle
innerhalb der FROM-Klausel ihres SELECTs an.
 
socfields ist die Anzahl von Correlation-Spalten aus dieser Tabelle.
 
Die Eintraege in cfields (die Spaltenbeschreibungen) werden komplett
in tc_columns kopiert und abgespeichert.
 
Bei jeder einzelnen SELECT-Bearbeitung, die ganz normal und
voellig getrennt voneinander dann ablaeuft, wird jedesmal (also
auch beim obersten SELECT nach Aufruf von a67_first_corr) a67_corr_search
aufgerufen. Das sorgt dann dafuer, dass zu den Informationen
ueber Ausgabespalten und zu der Qualifikation noch als quasi
Ausgabespalten die Correlation-Spalten in den Messagebuffer
dazugepackt werden. Es
werden auch solche Correlation-Spalten-Werte weiter durchgereicht,
die von einem oberen Select kommen und in einem weiter unten
liegenden Select gebraucht werden, da die Correlation beliebig viele
Stufen ueberspringen kann.
 
Wenn dann jeweils in einem SELECT die Correlation-Spalten, die von
diesem Select ausgehen, verarbeitet werden, wird der Parsebaum modifiziert.
In a_ap_tree^[ cnode ] wird durch
 
n_proc = a67 eingetragen, dass es sich um eine Correlation-Spalte
handelt. Es wird in VAK642 ak642corr_column ein solcher
Parse-Baum-Knoten speziell behandelt (die Search-Condition wird ja erst
spaeter abgearbeitet; es ist ja eine Search-Condition auf einem
tieferen Subquery-Level).
 
n_pos gibt die Position des Correlation-Spaltenwertes in der
Ausgabe des aktuellen Selects an,
 
n_length zeigt die maximale Laenge des Correlation-Spaltenwertes,
 
n_symb gibt den Datentyp der Correlation-Spalte an, den man braucht,
um zu ueberpruefen, ob der Vergleich zwischen den beiden
Werten in einem Praedikat ueberhaupt zulaessig ist.
 
.CM *-END-* description ---------------------------------
***********************************************************
.CM -lll-
Code    :
 
 
CONST
      c_all             = true (* a06_systable_get *);
      (*                          a660_search_one_table *)
      (*                          a661_get_from_select_table *)
      c_use_extcolno    = true (* a16col_to_view_description *);
      c_is_expression   = true (* a61_is_group_field *);
      c_single_column   = true (* a61_is_orderfield *);
      c_is_corr_column  = true (* a61_var_col_stackentry *);
      c_to_release      = true (* a660_lowpars_pparsp *);
      c_first_parsinfo  = true (* a660_new_pparsp *);
      c_complicate      = true (* a660_new_pparsp *);
      c_check_teresult  = true (* a660_search_one_table *);
      c_first_part      = true (* ak67sub_check *);
      c_only_having_columns_get = true (* a67_corr_search *);
      c_only_split      = true (* a67_corr_search *);
      c_is_not_corr_search = true (* a67_sel2_second_part *);
      c_last_pars_part   = true (* a67_sel2_second_part *);
      c_view_done        = true (* a67_sel2_second_part *);
      c_no_predefined_pno= 0 (* a67_corr_search *);
      cak67_maxcortables          =          64; (* correlation_tables *)
 
TYPE
 
      tak67_one_cortable  =  RECORD
            ocuser         : tsp00_KnlIdentifier;
            octable        : tsp00_KnlIdentifier;
            ocreference    : tsp00_KnlIdentifier;
            ocfromtableid  : tgg00_Surrogate;
            octreeid       : tgg00_FileId;
            ocprivset      : tak_columnset;
            ocall_priv     : boolean;
            ocuseful_tab   : boolean;   (* if ocreferences are equal *)
            (*  =  false in the first table *)
            ocspecialname  : tak_one_table_specialname;
            ocview         : boolean;
            octabno        : tsp00_Uint1;
            ocfields       : tsp00_Uint1;
            oclast_sup_tab : tsp00_Uint1;
            occmd_part     : tak_cmd_part_type;
      END;
 
      tak67_all_cortables  =  ARRAY [ 1..cak67_maxcortables ] OF
            tak67_one_cortable;
 
      tak_cortables  =  RECORD
            cortabs    : tak67_all_cortables;
            cused_tabs : tsp00_Int2;
            clast_used : tsp00_Int2;
      END;
 
      tak67_cuseful_arr  =  ARRAY [ 1..cak67_maxcortables ] OF boolean;
 
 
(*------------------------------*) 
 
PROCEDURE
      ak67col_stackentry (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR oldst : tgg00_StackEntry);
 
BEGIN
IF  acv.a_returncode = 0
THEN
    IF  (acv.a_mblock.mb_qual^.mfirst_free + 2 > acv.a_mblock.mb_st_max+1)
    THEN
        a07_b_put_error (acv, e_too_many_mb_stackentries, 1)
    ELSE
        BEGIN
        acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mfirst_free ]     := oldst;
        acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mfirst_free ].eop := op_none;
        WITH acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mfirst_free + 1 ] DO
            BEGIN
            etype    := st_output;
            eop      := op_none;
            epos     := dmli.d_inoutpos;
            elen_var := oldst.elen_var;
            ecol_pos := 0;
            END;
        (*ENDWITH*) 
        WITH oldst DO
            BEGIN
            etype      := st_fixcol;
            epos       := dmli.d_inoutpos - dmli.d_keylen - cgg_rec_key_offset;
            elen_var   := oldst.elen_var;
            dmli.d_inoutpos := dmli.d_inoutpos + oldst.elen_var;
            IF  dmli.d_inoutpos > MAX_RECLEN_GG00 + 1
            THEN
                a07_b_put_error (acv,
                      e_output_columns_too_long, 1);
            (*ENDIF*) 
            ecol_tab[ 1 ] := chr(0);
            ecol_tab[ 2 ] := chr(1);
            END;
        (*ENDWITH*) 
        acv.a_mblock.mb_qual^.mfirst_free := acv.a_mblock.mb_qual^.mfirst_free + 2;
        acv.a_mblock.mb_qual^.mqual_cnt   := acv.a_mblock.mb_qual^.mqual_cnt + 2
        END
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      ak67cnt_1_to_1_tabs (
            VAR acv   : tak_all_command_glob;
            VAR tabid : tgg00_Surrogate) : integer;
 
VAR
      _b_err        : tgg00_BasisError;
      _ix           : integer;
      _cnt          : integer;
      _viewqual_buf : tak_sysbufferaddress;
      _sysk         : tgg00_SysInfoKey;
 
BEGIN
_cnt            := 0;
_sysk           := a01defaultkey;
_sysk.stableid  := tabid;
_sysk.sentrytyp := cak_eviewqual_basis;
a10get_sysinfo (acv, _sysk, d_release, _viewqual_buf, _b_err);
IF  _b_err = e_ok
THEN
    WITH _viewqual_buf^.sviewqual_basis DO
        BEGIN
        _ix := 1;
        WHILE _ix <= vbasetabcnt DO
            BEGIN
            IF  vtable[ _ix ].vtone_to_one
            THEN
                _cnt := _cnt + 1;
            (*ENDIF*) 
            _ix := _ix + 1;
            END;
        (*ENDWHILE*) 
        END
    (*ENDWITH*) 
ELSE
    a07_b_put_error (acv, _b_err, 1);
(*ENDIF*) 
ak67cnt_1_to_1_tabs := _cnt;
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67corfiletree (
            VAR acv      : tak_all_command_glob;
            VAR level    : tak_corlevel;
            VAR res_tree : tgg00_FileId;
            for_having   : boolean);
 
VAR
      _i  : integer;
      _no : tsp00_Int4;
 
BEGIN
g04build_temp_tree_id (res_tree, acv.a_transinf.tri_trans);
res_tree.fileTfnTemp_gg00 := ttfnCorrelation_egg00;
_no := 0;
FOR _i := 1 TO cak_maxcorlevel DO
    _no := _no * 16 + level[ _i ];
(*ENDFOR*) 
IF  for_having
THEN
    _no := _no + 32768;
(*ENDIF*) 
res_tree.fileTempCnt_gg00 := _no
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67corr_column (
            VAR acv           : tak_all_command_glob;
            VAR dmli          : tak_dml_info;
            VAR all_cortabs   : tak_cortables;
            VAR all_corfields : tak_corfields;
            tab_n             : integer;
            column_n          : integer);
 
VAR
      _all_ok    : boolean;
      _f_ok      : boolean;
      _found     : boolean;
      _with_tab  : boolean;
      _first_col : boolean;
      _tabno     : integer;
 
BEGIN
_with_tab := acv.a_ap_tree^[tab_n].n_symb <> s_columnname;
_found := false;
_tabno := 0;
&IFDEF TRACE
t01lidentifier (ak_sem, dmli.d_column);
&ENDIF
IF  _with_tab
THEN (* tablename is explicit given by the user *)
    REPEAT
        _tabno := succ(_tabno);
&       ifdef TRACE
        WITH dmli.d_tabarr[ _tabno ] DO
            BEGIN
            t01int4 (ak_sem, 'tabno atarr ', _tabno);
            t01int4 (ak_sem, 'oisref in   ', ord(oisreference in ospecialname));
            t01lidentifier (ak_sem, dmli.d_table);
            t01lidentifier (ak_sem, otable);
            t01lidentifier (ak_sem, oreference);
            t01lidentifier (ak_sem, dmli.d_user);
            t01lidentifier (ak_sem, ouser);
            t01lidentifier (ak_sem, acv.a_curr_user_name);
            END;
        (*ENDWITH*) 
&       ENDIF
        WITH dmli.d_tabarr[ _tabno ] DO
            (* PTS 1116396 E.Z. *)
            IF  ((oisreference in ospecialname) AND
                ( dmli.d_table = oreference) AND
                ( dmli.d_user  = a01_il_b_identifier))
                OR
                ((NOT (oisreference in ospecialname)) AND
                (dmli.d_table = otable) AND
                ((dmli.d_user = ouser) OR
                ((dmli.d_user = a01_il_b_identifier) AND
                ((ouser  = acv.a_curr_user_name) OR
                ( ouser  = a01_i_public )    OR
                ( ouser  = acv.a_acc_dbaname)    OR
                ( ouser  = g01glob.sysuser_name) OR
                (((acv.a_sqlmode = sqlm_internal) OR g01glob.db_is_for_sapr3) AND
                ( ouser  = a01_i_domain))
                ))))
            THEN
                _found := true
            (*ENDIF*) 
        (*ENDWITH*) 
    UNTIL
        (_found OR (_tabno = dmli.d_cntfromtab))
    (*ENDREPEAT*) 
ELSE (* corelated column without tablename prefix. *)
    BEGIN
    dmli.d_acttabindex := 2;               (* different from 1             *)
    a61_rel_old_table (acv, dmli, 1); (* read in first tab            *)
    a61_search_table (acv, dmli);     (* look for column in from-part *)
&   IFDEF TRACE
    t01int4 (ak_sem, 'searchtab rc', acv.a_returncode);
&   ENDIF
    IF  a07_return_code (e_unknown_columnname, acv.a_sqlmode) =
        acv.a_returncode
    THEN
        BEGIN
        acv.a_returncode := 0;
        acv.a_errorpos   := 0;
        END
    ELSE
        _found := true
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  NOT _found
THEN (* it must be a corelated column, so let's have a look *)
    BEGIN
    _tabno     := all_cortabs.cused_tabs;
    _first_col := false;
    REPEAT (* for all tables from the outer selects *)
        WITH all_cortabs.cortabs[ _tabno ] DO
            BEGIN
&           IFDEF TRACE
            t01int4 (ak_sem, 'tabno crtabs', _tabno);
            t01int4 (ak_sem, 'oisref in   ', ord(oisreference in ocspecialname));
            t01int4 (ak_sem, 'ocusefultab ', ord(ocuseful_tab));
            t01int4 (ak_sem, 'acv_fromsele', ord(acv.a_from_select));
            t01int4 (ak_sem, 'acv_fromseln', acv.a_fromsel_n);
            t01lidentifier (ak_sem, dmli.d_table);
            t01lidentifier (ak_sem, ocreference);
            t01lidentifier (ak_sem, dmli.d_user);
            t01lidentifier (ak_sem, ocuser);
            t01lidentifier (ak_sem, acv.a_curr_user_name);
            t01treeid (ak_sem, 'octreeid    ', octreeid);
&           ENDIF
            (* PTS 1116396 E.Z. *)
            IF  (ocuseful_tab
                AND
                ((oisreference in ocspecialname)   AND
                (dmli.d_table  = ocreference)           AND
                ((dmli.d_user  = a01_il_b_identifier) OR
                ( dmli.d_user  = acv.a_curr_user_name)))
                OR
                ((NOT (oisreference in ocspecialname)) AND
                (dmli.d_table = octable) AND
                ((dmli.d_user = ocuser) OR
                ((dmli.d_user = a01_il_b_identifier) AND
                ((ocuser  = acv.a_curr_user_name) OR
                ( ocuser  = a01_i_public )    OR
                ( ocuser  = acv.a_acc_dbaname)    OR
                ( ocuser  = g01glob.sysuser_name) OR
                (((acv.a_sqlmode = sqlm_internal) OR g01glob.db_is_for_sapr3) AND
                ( ocuser  = a01_i_domain))
                )))))
                OR           (* without tablename all tables must be *)
                NOT _with_tab (* inspected for the given column       *)
            THEN
                BEGIN
                IF  _with_tab
                THEN (* the given table is found in an outer from-part *)
                    _found := true;
&               ifdef TRACE
                (*ENDIF*) 
                t01int4 (ak_sem, 'syskey pa(1)', 1);
                t01buf1 (ak_sem, dmli.d_sparr.pbasep^.syskey, 1, 16);
                IF  oresfile in ocspecialname
                THEN
                    BEGIN
                    t01int4 (ak_sem, 'octable     ', 0);
                    t01lidentifier (ak_sem, octable);
                    END
                ELSE
                    t01int4 (ak_sem, 'ocview      ', ord (ocview));
                (*ENDIF*) 
&               ENDIF
                (* Now load the found table from whereever into d_sparr *)
                a10rel_sysinfo (dmli.d_sparr.pbasep);
                IF  a661_is_fromsel_table (acv, octreeid)
                THEN
                    BEGIN
                    dmli.d_sparr.psynfound := false;
                    dmli.d_sparr.pcount    := 0;
                    a661_get_from_select_table (acv,
                          octreeid.fileTabId_gg00, dmli.d_sparr.pbasep,
                          d_fix, c_all, _f_ok);
                    END
                ELSE
                    IF  oresfile in ocspecialname
                    THEN
                        BEGIN
                        a663restable_get (acv, d_fix, octable,
                              dmli.d_sparr, _f_ok);
                        END
                    ELSE
                        IF  ocview
                        THEN
                            a06_systable_get (acv, d_fix, ocfromtableid,
                                  dmli.d_sparr.pbasep, c_all, _f_ok)
                        ELSE
                            IF  ocuser = a01_i_temp
                            THEN
                                a06_systable_get (acv, d_fix, ocfromtableid,
                                      dmli.d_sparr.pbasep, c_all, _f_ok)
                            ELSE
                                a06_systable_get (acv, d_fix, octreeid.fileTabId_gg00,
                                      dmli.d_sparr.pbasep, c_all, _f_ok);
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  NOT _f_ok
                THEN
                    a07_nb_put_error (acv, e_unknown_tablename, 1, octable)
                ELSE
                    BEGIN
                    _all_ok := true;
                    dmli.d_acttabindex  := 0;
                    IF  a061exist_columnname (dmli.d_sparr.pbasep^.sbase,
                        dmli.d_column, dmli.d_colbuf)
                    THEN
                        IF  _first_col
                        THEN (* not the first column in this from part *)
                            a07_nb_put_error (acv, e_missing_column_definite,
                                  acv.a_ap_tree^[ tab_n ].n_pos, dmli.d_column)
                        ELSE
                            BEGIN
                            _first_col := true;
                            _found     := true;
                            IF  dmli.d_view
                            THEN
                                a16col_to_view_description (acv, dmli,
                                      dmli.d_colbuf^, NOT c_use_extcolno);
                            (*ENDIF*) 
                            WITH dmli.d_colbuf^ DO
                                IF  ((ctinvisible in ccolpropset) OR
                                    (NOT ocall_priv AND
                                    NOT (cextcolno in ocprivset)))
                                THEN
                                    _all_ok := false
                                ELSE
                                    IF  cdatatyp in [ dstra, dstrb, dstruni,
                                        dlonga, dlonguni, dlongb]
                                    THEN
                                        _found := false
                                    ELSE
                                        IF  ctabno > cak00_maxsources
                                        THEN
                                            a07_nb_put_error (acv, e_only_one_recordtype_allowed,
                                                  dmli.d_vppos, dmli.d_column)
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                (*ENDIF*) 
                            (*ENDWITH*) 
                            END
                        (*ENDIF*) 
                    ELSE
                        IF  _with_tab
                        THEN (* column doesn't exist in the given table *)
                            _all_ok := false;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    IF  _found AND (acv.a_returncode = 0)
                    THEN (* we found the table... *)
                        IF  NOT _all_ok
                        THEN (* ... but it doesn't contain the column *)
                            a07_nb_put_error (acv, e_unknown_columnname,
                                  dmli.d_vppos, dmli.d_column)
                        ELSE (* ... and we also found the column *)
                            WITH all_corfields DO
                                IF  cused_fields < cak_maxcorcolumns
                                THEN (* there's room left for one more *)
                                    BEGIN
                                    cused_fields := succ(cused_fields);
                                    WITH cfields[ cused_fields ] DO
                                        BEGIN
                                        cfieldno :=
                                              dmli.d_colbuf^.cextcolno;
                                        ctabno := _tabno;
                                        cnode  := tab_n;
                                        ccmd_part := all_cortabs.cortabs[ _tabno ].occmd_part;
                                        IF  ((csetnode > 0) AND
                                            (ccmd_part = cpt_in_where_clause))
                                        THEN
                                            a07_b_put_error (acv, e_invalid_mix_functions_columns,
                                                  acv.a_ap_tree^[ column_n ].n_pos);
&                                       ifdef TRACE
                                        (*ENDIF*) 
                                        t01int4 (ak_sem, 'cused_fields', cused_fields);
                                        t01int4 (ak_sem, 'ccmd_part   ', ord(ccmd_part));
&                                       endif
                                        END;
                                    (*ENDWITH*) 
                                    WITH all_cortabs.cortabs[ _tabno ] DO
                                        ocfields := succ(ocfields);
                                    (*ENDWITH*) 
&                                   ifdef TRACE
                                    WITH all_cortabs.cortabs[ _tabno ] DO
                                        t01int4 (ak_sem, 'ocfields    ', ocfields);
                                    (*ENDWITH*) 
                                    t01int4 (ak_sem, 'tabno       ', _tabno);
&                                   ENDIF
&                                   IFDEF TRACE
                                    t01lidentifier (test_ak, ocreference);
&                                   ENDIF
                                    END
                                ELSE
                                    a07_b_put_error (acv, e_too_many_correlation_columns,
                                          acv.a_ap_tree^[ tab_n ].n_pos)
                                (*ENDIF*) 
                            (*ENDWITH*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  NOT _with_tab
            THEN (* here we have to search for duplicate columns *)
                _found := false;
            (*ENDIF*) 
            IF  (oclast_sup_tab > 0) OR (_tabno = 1)
            THEN (* left edge of one from-part reached *)
                BEGIN
                IF  _first_col AND NOT _with_tab
                THEN (* the found column is the only one *)
                    _found := true;
                (*ENDIF*) 
                _tabno := oclast_sup_tab
                END
            ELSE (* continue with next table from same from-part *)
                _tabno := pred (_tabno)
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    UNTIL
        (_found OR (_tabno <= 0) OR (acv.a_returncode <> 0));
    (*ENDREPEAT*) 
    IF  NOT _found
    THEN
        IF  _with_tab
        THEN
            a07_b_put_error (acv, e_table_not_in_from_list,
                  acv.a_ap_tree^[ tab_n ].n_pos)
        ELSE
            a07_nb_put_error (acv, e_unknown_columnname,
                  acv.a_ap_tree^[ tab_n ].n_pos, dmli.d_column)
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67corr_dml_init (VAR dmli : tak_dml_info );
 
BEGIN
dmli.d_vppos  := 1;
dmli.d_keylen := RESCNT_MXGG04;
IF  (dmli.d_distinct <> no_distinct) OR dmli.d_union
THEN
    dmli.d_keylen := dmli.d_keylen + cgg04_cdistinct_bytes;
(*ENDIF*) 
dmli.d_inoutpos      := cgg_rec_key_offset + 1 + dmli.d_keylen;
dmli.d_subquery      := true;
dmli.d_use_sub       := false;
dmli.d_subcount      := 2;
dmli.d_outcolno      := 1;
dmli.d_act_node      := 0;
dmli.d_pos_result    := succ(cak_maxresulttables);
dmli.d_reuse         := true;
dmli.d_single        := false;
dmli.d_rowno         :=  cgg04_no_rowno_predicate;
dmli.d_change.cr_colcount := 0;
dmli.d_exprno        := 1;
dmli.d_refname       := a01_il_b_identifier;
dmli.d_view          := false;
dmli.d_having        := false;
dmli.d_group         := false;
dmli.d_like          := false;
dmli.d_movebefore    := 0;
dmli.d_pargeslen     := 0;
dmli.d_range         := false;
dmli.d_maxlen        := 0;
dmli.d_use_order     := false;
dmli.d_order_cols.ocntord  := 1;
WITH dmli.d_order_cols.ofield[ 1 ] DO
    BEGIN
    (* PTS 1116888 E.Z. *)
    ofname  := a01_il_b_identifier;
    ofno    := 1;
    ofstno  := 0;
    ofasc   := [ is_order_asc ];
    oftabno := cak00_maxsources + 1;
    offno   := 0;
    ofapos  := 0;
    ofnode  := 0;
    offill  := 0;
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67corr_search_condition (
            VAR acv           : tak_all_command_glob;
            VAR dmli          : tak_dml_info;
            VAR all_cortabs   : tak_cortables;
            VAR all_corfields : tak_corfields;
            startnode         : integer);
 
VAR
      _curr_n      : integer;
      _tab_n       : integer;
      _old_corrcnt : integer;
 
BEGIN
&IFDEF TRACE
t01int4 (ak_sem, 'startnode   ', startnode);
&ENDIF
_curr_n      := startnode;
_old_corrcnt := cak_is_undefined;
WITH acv.a_ap_tree^[ _curr_n ] DO
    IF  ((n_proc = no_proc) AND
        ((n_symb = s_avg) OR (n_symb = s_dis_avg) OR
        ( n_symb = s_sum) OR (n_symb = s_dis_sum) OR
        ( n_symb = s_min) OR
        ( n_symb = s_max) OR
        ( n_symb = s_variance) OR (n_symb = s_dis_variance) OR
        ( n_symb = s_stddev)   OR (n_symb = s_dis_stddev) OR
        ( n_symb = s_count)    OR (n_symb = s_dis_count)))
    THEN
        WITH all_corfields DO
            IF  cused_fields < cak_maxcorcolumns
            THEN
                WITH cfields[ cused_fields + 1 ] DO
                    BEGIN
                    _old_corrcnt := cused_fields;
                    csetnode    := _curr_n;
                    ccntcol     := 0
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
        (*ENDWITH*) 
    (*ENDIF*) 
(*ENDWITH*) 
IF  acv.a_ap_tree^[ _curr_n ].n_symb in [ s_authid, s_tablename, s_columnname ]
THEN
    BEGIN
    dmli.d_n_pos := acv.a_ap_tree^[ _curr_n ].n_pos;
    dmli.d_user  := a01_il_b_identifier;
    _tab_n   := _curr_n;
    a06get_username (acv, _curr_n, dmli.d_user);
    WITH acv.a_ap_tree^[ _curr_n ] DO
        IF  n_symb = s_tablename
        THEN
            BEGIN
            a05identifier_get (acv, _curr_n,
                  sizeof (dmli.d_table), dmli.d_table);
            _curr_n := n_sa_level
            END
        ELSE
            dmli.d_table  := a01_il_b_identifier;
        (*ENDIF*) 
    (*ENDWITH*) 
    WITH acv.a_ap_tree^[ _curr_n ] DO
        BEGIN
        a05identifier_get (acv, _curr_n, sizeof (dmli.d_column), dmli.d_column);
        dmli.d_vppos := n_pos;
        ak67corr_column (acv, dmli, all_cortabs, all_corfields, _tab_n, _curr_n)
        END;
    (*ENDWITH*) 
    END;
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    WITH acv.a_ap_tree^[ _curr_n ] DO
        BEGIN
        IF  (n_lo_level  > 0) AND
            (n_proc     <> a63query_spec) (* subquery *)
            AND
            NOT ((n_proc = a63) AND (n_subproc = cak_x_start_union))
        THEN
            ak67corr_search_condition (acv, dmli, all_cortabs,
                  all_corfields, n_lo_level);
        (*ENDIF*) 
        IF  _old_corrcnt <> cak_is_undefined
        THEN
            IF  _old_corrcnt < all_corfields.cused_fields
            THEN
                all_corfields.cfields[ _old_corrcnt + 1 ].ccntcol :=
                      all_corfields.cused_fields - _old_corrcnt
            ELSE
                all_corfields.cfields[ _old_corrcnt + 1 ].csetnode := 0;
            (*ENDIF*) 
        (*ENDIF*) 
        IF  (n_sa_level  > 0) AND
            (n_proc     <> a63query_spec) (* subquery *)
            AND
            NOT ((n_proc = a63) AND (n_subproc = cak_x_start_union))
        THEN
            ak67corr_search_condition (acv, dmli, all_cortabs,
                  all_corfields, n_sa_level)
        (*ENDIF*) 
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67distinct_len (
            VAR mblock    : tgg00_MessBlock;
            VAR maxdislen : integer);
 
VAR
      _act       : integer;
      _first     : integer;
 
BEGIN
_first := mblock.mb_qual^.mqual_pos-1;
_act   := _first + mblock.mb_st^[ _first+1 ].epos-1;
_first := succ(_first);
&IFDEF TRACE
t01int4 (kb, 'act         ', _act);
t01int4 (kb, 'first       ', _first);
&ENDIF
maxdislen := 0;
(* PTS 1122141 E.Z. *)
WHILE (_act - mblock.mb_st^[ _act ].epos > _first) AND
      (mblock.mb_st^[ _act ].epos > 0) DO
    BEGIN
    _act := _act - mblock.mb_st^[ _act ].epos;
&   IFDEF TRACE
    t01int4 (kb, 'act         ', _act);
&   ENDIF
    IF  ((mblock.mb_st^[ _act ].eop_func = op_f_dis_avg)      OR
        ( mblock.mb_st^[ _act ].eop_func = op_f_dis_sum)      OR
        ( mblock.mb_st^[ _act ].eop_func = op_f_dis_count)    OR
        ( mblock.mb_st^[ _act ].eop_func = op_f_dis_stddev)   OR
        ( mblock.mb_st^[ _act ].eop_func = op_f_dis_variance) OR
        ( mblock.mb_st^[ _act ].eop_func = op_f_stddev)       OR
        ( mblock.mb_st^[ _act ].eop_func = op_f_variance))
    THEN
        BEGIN
        IF  (mblock.mb_st^[ _act+1 ].etype = st_output)
        THEN
            IF  (mblock.mb_st^[ _act+1 ].elen_var > maxdislen)
            THEN
                maxdislen := mblock.mb_st^[ _act+1 ].elen_var
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67fill_cortabs (
            VAR acv           : tak_all_command_glob;
            VAR dmli          : tak_dml_info;
            VAR all_cortabs   : tak_cortables;
            VAR all_corfields : tak_corfields;
            VAR useful_arr    : tak67_cuseful_arr;
            subquery_node     : tsp00_Int2; (* on node, which *)
            (*                         points to Select *)
            level             : integer;
            no_in_level       : integer;
            last_sup_tab      : tsp00_Uint1);
 
VAR
      do_optimize    : boolean;
      new_useful_arr : tak67_cuseful_arr;
      h_cpt          : tak_cmd_part_type;
      i              : integer;
      tabno          : integer;
      curr_col_start : integer;
      curr_n         : tsp00_Int2;
      select_list_n  : tsp00_Int2;
      corrcols_before_this_node : integer;
 
BEGIN
WITH all_corfields DO
    IF  acv.a_returncode = 0
    THEN
        IF  level > cak_maxcorlevel
        THEN
            a07_b_put_error (acv, e_too_many_subqueries,
                  acv.a_ap_tree^[ acv.a_ap_tree^[ subquery_node ].n_pos ].n_pos)
        ELSE
            BEGIN
            h_cpt := acv.a_cpart_type;
            CASE acv.a_ap_tree^[ subquery_node ].n_symb OF
                (* PTS 1123051 E.Z. *)
                s_where, s_select :
                    acv.a_cpart_type := cpt_in_where_clause;
                s_having :
                    acv.a_cpart_type := cpt_in_having_clause;
                OTHERWISE
                    acv.a_cpart_type := cpt_unknown;
                END;
            (*ENDCASE*) 
&           ifdef TRACE
            t01int4 (ak_sem, 'clast_used  ', all_cortabs.clast_used);
            t01int4 (ak_sem, 'cused_tabs  ', all_cortabs.cused_tabs);
&           endif
            (* PTS 1117747 E.Z. *)
            corrcols_before_this_node := cused_fields;
            WITH all_cortabs DO
                FOR i := clast_used+1 TO cused_tabs DO
                    cortabs[ i ].occmd_part := acv.a_cpart_type;
                (*ENDFOR*) 
            (*ENDWITH*) 
            a10rel_sysinfo (dmli.d_sparr.pbasep);
            curr_n := acv.a_ap_tree^[ subquery_node ].n_pos;
            IF  (acv.a_ap_tree^[ curr_n ].n_proc = a63) AND
                (acv.a_ap_tree^[ curr_n ].n_subproc  = cak_x_start_union)
            THEN
                a07_b_put_error (acv, e_corelated_subquery_not_allowe,
                      acv.a_ap_tree^[ acv.a_ap_tree^[ curr_n ].n_lo_level].n_pos)
            ELSE
                BEGIN
                IF  (acv.a_ap_tree^[ curr_n ].n_proc = a66) AND
                    (acv.a_ap_tree^[ curr_n ].n_subproc  = cak_x_select_in_from_part)
                THEN
                    curr_n := acv.a_ap_tree^[ curr_n ].n_lo_level;
                (*ENDIF*) 
                curr_n := acv.a_ap_tree^[ curr_n ].n_lo_level;
                IF  (acv.a_ap_tree^[ curr_n ].n_proc = a63) AND
                    (acv.a_ap_tree^[ curr_n ].n_subproc  = cak_x_distinct)
                THEN
                    curr_n := acv.a_ap_tree^[ curr_n ].n_lo_level;
                (*ENDIF*) 
                select_list_n := curr_n;
                curr_n := acv.a_ap_tree^[ curr_n ].n_sa_level; (* from-part *)
                IF  (acv.a_ap_tree^[ curr_n ].n_proc = a66) AND
                    (acv.a_ap_tree^[ curr_n ].n_subproc  = cak_x_given_sequence)
                THEN
                    curr_n := acv.a_ap_tree^[ curr_n ].n_sa_level;
                (* complex view optimizer must not collect any *)
                (* information at this step                    *)
                (*ENDIF*) 
                do_optimize := acv.a_optimize_info.o_do_optimize;
                acv.a_optimize_info.o_do_optimize := false;
                a660_from_part (acv, dmli, curr_n);
                (* restore optimization state *)
                acv.a_optimize_info.o_do_optimize := do_optimize;
                curr_n := acv.a_ap_tree^[ curr_n ].n_sa_level;
                (* correlation column in select list *)
                select_list_n := acv.a_ap_tree^[select_list_n].n_lo_level;
                WHILE (select_list_n > 0) AND (acv.a_returncode = 0) DO
                    BEGIN
                    FOR i := cused_fields + 1 TO cak_maxcorcolumns DO
                        cfields[ i ].clevel[ level ] := no_in_level;
                    (*ENDFOR*) 
                    ak67corr_search_condition (acv, dmli, all_cortabs,
                          all_corfields, acv.a_ap_tree^[ select_list_n ].n_lo_level);
                    select_list_n := acv.a_ap_tree^[select_list_n].n_sa_level;
                    END;
                (*ENDWHILE*) 
&               IFDEF TRACE
                t01name (ak_sem, bsp_name);
                t01int4 (ak_sem, 'NO OF COLS  ', cused_fields);
                FOR i := 1 TO cused_fields DO
                    WITH cfields[ i ] DO
                        BEGIN
                        t01name (ak_sem, bsp_name);
                        t01int4 (ak_sem, 'COLNO       ', i);
                        t01int4 (ak_sem, 'cfieldno    ', cfieldno);
                        t01int4 (ak_sem, 'ctabno      ', ctabno);
                        t01int4 (ak_sem, 'cnode       ', cnode);
                        t01p4int4 (ak_sem, 'clevel      ', clevel[ 1 ], clevel[ 2 ],
                              clevel[ 3 ], clevel[ 4 ]);
                        END;
                    (*ENDWITH*) 
                (*ENDFOR*) 
&               ENDIF
                IF  (curr_n <> 0) AND (acv.a_returncode = 0)
                THEN
                    BEGIN
                    IF  (acv.a_ap_tree^[ curr_n ].n_proc = a63) AND
                        (acv.a_ap_tree^[ curr_n ].n_subproc  = cak_x_search_condition)
                    THEN
                        BEGIN
                        FOR i := cused_fields + 1 TO cak_maxcorcolumns DO
                            cfields[ i ].clevel[ level ] := no_in_level;
                        (*ENDFOR*) 
                        ak67corr_search_condition (acv, dmli, all_cortabs,
                              all_corfields, acv.a_ap_tree^[ curr_n ].n_lo_level);
                        curr_n := acv.a_ap_tree^[ curr_n ].n_sa_level;
&                       IFDEF TRACE
                        t01name (ak_sem, bsp_name);
                        t01int4 (ak_sem, 'NO OF COLS  ', cused_fields);
                        FOR i := 1 TO cused_fields DO
                            WITH cfields[ i ] DO
                                BEGIN
                                t01name (ak_sem, bsp_name);
                                t01int4 (ak_sem, 'COLNO       ', i);
                                t01int4 (ak_sem, 'cfieldno    ', cfieldno);
                                t01int4 (ak_sem, 'ctabno      ', ctabno);
                                t01int4 (ak_sem, 'cnode       ', cnode);
                                t01p4int4 (ak_sem, 'clevel      ', clevel[ 1 ], clevel[ 2 ],
                                      clevel[ 3 ], clevel[ 4 ]);
                                END
                            (*ENDWITH*) 
                        (*ENDFOR*) 
&                       ENDIF
                        END;
                    (*ENDIF*) 
                    IF  curr_n > 0
                    THEN
                        IF  (acv.a_ap_tree^[ curr_n ].n_proc = a63) AND
                            (acv.a_ap_tree^[ curr_n ].n_subproc  = cak_x_group_by)
                        THEN
                            curr_n := acv.a_ap_tree^[ curr_n ].n_sa_level;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    IF  curr_n > 0
                    THEN
                        IF  (acv.a_ap_tree^[ curr_n ].n_proc = a63) AND
                            (acv.a_ap_tree^[ curr_n ].n_subproc  = cak_x_having)
                        THEN
                            BEGIN
                            FOR i := cused_fields + 1 TO cak_maxcorcolumns DO
                                cfields[ i ].clevel[ level ] := no_in_level;
                            (*ENDFOR*) 
                            ak67corr_search_condition (acv, dmli, all_cortabs,
                                  all_corfields, acv.a_ap_tree^[ curr_n ].n_lo_level);
&                           IFDEF TRACE
                            t01name (ak_sem, bsp_name);
                            t01int4 (ak_sem, 'NO OF COLS  ', cused_fields);
                            FOR i := 1 TO cused_fields DO
                                WITH cfields[ i ] DO
                                    BEGIN
                                    t01name (ak_sem, bsp_name);
                                    t01int4 (ak_sem, 'COLNO       ', i);
                                    t01int4 (ak_sem, 'cfieldno    ', cfieldno);
                                    t01int4 (ak_sem, 'ctabno      ', ctabno);
                                    t01int4 (ak_sem, 'cnode       ', cnode);
                                    t01p4int4 (ak_sem, 'clevel      ', clevel[ 1 ], clevel[ 2 ],
                                          clevel[ 3 ], clevel[ 4 ]);
                                    END
                                (*ENDWITH*) 
                            (*ENDFOR*) 
&                           ENDIF
                            END
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                new_useful_arr := useful_arr;
                tabno          := 1;
                IF  acv.a_mblock.mb_type in [ m_update, m_delete ]
                THEN
                    WHILE ((tabno <= dmli.d_cntfromtab) AND
                          (acv.a_returncode = 0)) DO
                        BEGIN
                        WITH dmli.d_tabarr[ tabno ],
                             all_cortabs.cortabs[ 1 ] DO
                            IF  ((ocuser   = ouser)  AND
                                ( octable  = otable))
                            THEN
                                a07_b_put_error (acv, e_update_not_allowed, 1);
                            (*ENDIF*) 
                        (*ENDWITH*) 
                        tabno := succ(tabno)
                        END;
                    (*ENDWHILE*) 
                (*ENDIF*) 
                IF  (acv.a_ap_tree^[ subquery_node ].n_lo_level > 0)
                THEN
                    WITH acv.a_ap_tree^[ subquery_node ] DO
                        IF  (n_proc <> a92fromsel)
                        THEN
                            BEGIN
                            curr_col_start := cused_fields;
                            ak67from_part_to_cortabs (acv, dmli, all_cortabs,
                                  new_useful_arr, last_sup_tab);
                            ak67fill_cortabs (acv, dmli, all_cortabs, all_corfields,
                                  new_useful_arr, n_lo_level, level + 1, 1,
                                  all_cortabs.cused_tabs);
                            END;
                        (*ENDIF*) 
                    (*ENDWITH*) 
                (*ENDIF*) 
                FOR i := cused_fields + 1 TO cak_maxcorcolumns DO
                    cfields[ i ].clevel[ level ] := 0;
                (*ENDFOR*) 
                FOR i := 1 TO all_cortabs.cused_tabs DO
                    all_cortabs.cortabs[ i ].ocuseful_tab := useful_arr[ i ];
                (*ENDFOR*) 
                (* PTS 1117747 E.Z. *)
                IF  cused_fields > corrcols_before_this_node
                THEN
                    IF  acv.a_ap_tree^[ subquery_node ].n_subproc = cak_x_subquery
                    THEN
                        acv.a_ap_tree^[ subquery_node ].n_subproc := cak_x_corr_subquery
                    ELSE
                        IF  acv.a_ap_tree^[ subquery_node ].n_subproc = cak_x_one_val_subquery
                        THEN
                            acv.a_ap_tree^[ subquery_node ].n_subproc := cak_x_one_val_corr_sub;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  (acv.a_ap_tree^[ subquery_node ].n_sa_level > 0)
                THEN
                    WITH acv.a_ap_tree^[ subquery_node ] DO
                        IF  (n_proc <> a92fromsel)
                        THEN
                            ak67fill_cortabs (acv, dmli, all_cortabs, all_corfields,
                                  useful_arr, n_sa_level, level, no_in_level + 1,
                                  last_sup_tab);
                        (*ENDIF*) 
                    (*ENDWITH*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            acv.a_cpart_type := h_cpt;
            END
        (*ENDIF*) 
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67from_part_to_cortabs (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR all_cortabs    : tak_cortables;
            VAR new_useful_arr : tak67_cuseful_arr;
            last_sup_tab       : tsp00_Uint1);
 
VAR
      ok    : boolean;
      i     : integer;
      tabno : integer;
 
BEGIN
WITH acv, dmli, all_cortabs DO
    BEGIN
    tabno := 1;
    clast_used := cused_tabs;
    IF  cused_tabs + d_cntfromtab > cak67_maxcortables
    THEN
        a07_b_put_error (acv, e_too_many_corr_tables, 1)
    ELSE
        WHILE ((tabno <= d_cntfromtab) AND
              (a_returncode = 0)) DO
            WITH d_tabarr[ tabno ] DO
                BEGIN
                WITH cortabs[ cused_tabs + 1 ] DO
                    BEGIN
                    ocuser        := ouser;
                    octable       := otable;
                    ocspecialname := ospecialname;
                    ocview        := oview;
                    octreeid      := otreeid;
                    ocfromtableid := ofromtableid;
                    ocreference   := oreference;
                    ocall_priv    := oall_priv;
                    ocprivset     := oprivset;
                    ocuseful_tab  := true;
                    octabno       := tabno;
                    ocfields      := 0;
                    IF  tabno = 1
                    THEN
                        oclast_sup_tab := last_sup_tab
                    ELSE
                        oclast_sup_tab := 0;
                    (*ENDIF*) 
&                   IFDEF TRACE
                    t01lidentifier (ak_sem, octable);
                    t01int4 (ak_sem, 'last_sup_tab', oclast_sup_tab);
                    t01int4  (ak_sem, 'cused_tabs  ', cused_tabs);
                    t01int4  (ak_sem, 'tabno       ', tabno);
                    t01int4  (ak_sem, 'ocref in osp', ord (oisreference in ospecialname));
                    t01treeid (ak_sem, 'octreeid    ', octreeid);
&                   ENDIF
                    END;
                (*ENDWITH*) 
                new_useful_arr[ cused_tabs + 1 ] := true;
                FOR i := 1 TO cused_tabs DO
                    WITH cortabs[ i ] DO
                        BEGIN
                        ok := true;
                        IF  oisreference in ospecialname
                        THEN
                            BEGIN
                            IF  ((ocreference = oreference)
                                OR
                                ((ocuser  = a_curr_user_name)   AND
                                (octable  = oreference)))
                            THEN
                                ok := false
                            (*ENDIF*) 
                            END
                        ELSE
                            IF  oisreference in ocspecialname
                            THEN
                                BEGIN
                                IF  ((ouser  = a_curr_user_name)   AND
                                    (otable  = ocreference))
                                THEN
                                    ok := false
                                (*ENDIF*) 
                                END
                            ELSE
                                IF  ((ocuser  = ouser)   AND
                                    (octable  = otable))
                                THEN
                                    ok := false;
                                (*ENDIF*) 
                            (*ENDIF*) 
                        (*ENDIF*) 
                        IF  NOT ok
                        THEN
                            BEGIN
                            ocuseful_tab := false;
                            new_useful_arr[ i ] := false
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDWITH*) 
                (*ENDFOR*) 
                cused_tabs := succ(cused_tabs);
                tabno := succ(tabno)
                END;
            (*ENDWITH*) 
        (*ENDWHILE*) 
    (*ENDIF*) 
&   IFDEF TRACE
    t01int4 (ak_sem, 'NO of TABLES', cused_tabs);
    FOR tabno := 1 TO cused_tabs DO
        WITH cortabs[ tabno ] DO
            BEGIN
            t01name (ak_sem, bsp_name);
            t01int4 (ak_sem, '   TABLENO  ', tabno);
            t01lidentifier (ak_sem, ocuser);
            t01lidentifier (ak_sem, octable);
            t01lidentifier (ak_sem, ocreference);
            t01int4  (ak_sem, 'ocref in osp', ord (oisreference in ocspecialname));
            IF  ocuseful_tab
            THEN
                t01name (ak_sem, 'USEFUL            ')
            ELSE
                t01name (ak_sem, 'NOT USEFUL        ');
            (*ENDIF*) 
            t01int4 (ak_sem, 'octabno     ', octabno);
            t01int4 (ak_sem, 'ocfields    ', ocfields);
            END
        (*ENDWITH*) 
    (*ENDFOR*) 
&   ENDIF
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67output_corr_columns (
            VAR acv             : tak_all_command_glob;
            VAR dmli            : tak_dml_info;
            VAR sparr           : tak_syspointerarr;
            VAR tabno           : integer;
            VAR orderlen        : integer;
            VAR distpos         : integer;
            corrtab_buf         : tak_sysbufferaddress);
 
VAR
      all              : boolean;
      m_d_join         : boolean;
      put_together     : boolean;
      together_allowed : boolean;
      add              : integer;
      dummy_len        : integer;
      fno              : integer;
      ftabno           : integer;
      helpfno          : integer;
      next_n           : integer;
      col_name         : tsp00_KnlIdentifier;
      colin            : tak00_scolinf;
      colinf           : tak00_columninfo;
 
BEGIN
orderlen := 0;
all      := false;
(* PTS 1115725 E.Z. *)
dmli.d_prep_corr_cols := true;
WITH acv, dmli, corrtab_buf^.scorr DO
    WHILE ((a_returncode = 0 ) AND NOT all) DO
        BEGIN
&       IFDEF TRACE
        t01int4 (ak_sem, 'tabno       ', tabno);
        t01int4 (ak_sem, 'tc_no_of_tab', tc_no_of_tables);
        t01int4 (ak_sem, 'tc_oldstartt', tc_oldstarttable);
        t01int4 (ak_sem, 'd_maxcountab', d_maxcounttabs);
        IF  tabno <= tc_no_of_tables
        THEN
            BEGIN
            t01int4 (ak_sem, 'socoldtab   ', tc_tables[ tabno ].socoldtabno);
            t01int4 (ak_sem, 'socselecttab', tc_tables[ tabno ].socselecttabno);
            END;
&       ENDIF
        (*ENDIF*) 
        IF  tabno <= tc_no_of_tables
        THEN
            IF  tc_tables[ tabno ].socoldtabno <
                tc_oldstarttable + d_maxcounttabs
                (* belongs to this select *)
            THEN
                WITH tc_tables[ tabno ] DO
                    BEGIN
                    a61_rel_old_table (acv, dmli, socselecttabno);
                    IF  a_returncode = 0
                    THEN
                        BEGIN
                        fno    := 1;
                        ftabno := 0;
                        WHILE ((fno   <= tc_no_of_columns) AND
                              (ftabno <= socfields) AND
                              (a_returncode = 0)) DO
                            WITH corrtab_buf^.scorr,
                                 sparr.pbasep^.sbase DO
                                BEGIN
&                               ifdef TRACE
                                t01int4 (ak_sem, 'FNO         ', fno);
                                t01int4 (ak_sem, 'tc_no_of_col', tc_no_of_columns);
                                t01int4 (ak_sem, 'ftabno      ', ftabno);
                                t01int4 (ak_sem, 'socfields   ', socfields);
                                t01int4 (ak_sem, 'ctabno      ', tc_columns[ fno ].ctabno);
                                t01int4 (ak_sem, 'socoldtabno ', socoldtabno);
                                t01int4 (ak_sem, 'a_cpart_type', ord(a_cpart_type));
                                t01int4 (ak_sem, 'ccmd_part   ', ord(tc_columns[ fno ].ccmd_part));
&                               endif
                                (* PTS 1117747 E.Z. *)
                                IF  tc_columns[ fno ].ctabno = socoldtabno
                                THEN
                                    IF  a_cpart_type = tc_columns[ fno ].ccmd_part
                                    THEN
                                        BEGIN
                                        WITH tc_columns[ fno ] DO
                                            IF  ((csetnode > 0) AND (ccntcol > 0)
                                                AND d_having)
                                            THEN
                                                BEGIN
                                                colin.sci_len := 0;
                                                m_d_join      := d_join;
                                                d_join        := false;
                                                a65_val_expr (acv, dmli, colin,
                                                      csetnode);
                                                d_join := m_d_join;
                                                WITH a_ap_tree^[ csetnode ], colin DO
                                                    BEGIN
                                                    n_proc := a67;
                                                    n_pos  :=
                                                       d_inoutpos -
                                                       d_keylen-distpos;
&                                                   ifdef TRACE
                                                    t01int4 (ak_sem, 'd_inoutpos  ', d_inoutpos);
                                                    t01int4 (ak_sem, 'd_keylen    ', d_keylen);
                                                    t01int4 (ak_sem, 'distpos     ', distpos);
&                                                   endif
                                                    n_length   := colin.sci_iolen;
                                                    IF  a_union_cnt <> 0
                                                    THEN
                                                     n_symb := s_true
                                                    ELSE
                                                     (* true : in Union *)
                                                     n_symb := s_unknown;
                                                    (*ENDIF*) 
                                                    n_datatype := sci_typ;
                                                    n_lo_level := 0
                                                    END;
                                                (*ENDWITH*) 
                                                ftabno := ftabno + ccntcol;
                                                fno    := fno    + ccntcol - 1;
                                                WITH a_mblock, mb_qual^ DO
                                                    IF  mfirst_free > mb_st_max
                                                    THEN
                                                     a07_b_put_error (acv, e_too_many_mb_stackentries, 1)
                                                    ELSE
                                                     WITH mb_st^[ mfirst_free ] DO
                                                      BEGIN
                                                      add := 0;
                                                      etype := st_output;
                                                      eop   := op_none;
                                                      epos  := d_inoutpos;
                                                      IF  ((mb_st^[ mfirst_free-1 ].etype = st_func) AND
                                                       ((mb_st^[ mfirst_free-1 ].eop_func = op_f_count) OR
                                                       (mb_st^[ mfirst_free-1 ].eop_func = op_f_dis_count)))
                                                      THEN
                                                       elen_var := mb_st^[ mfirst_free-1 ].elen_var
                                                      ELSE
                                                       elen_var := colin.sci_iolen;
                                                      (*ENDIF*) 
                                                      ecol_pos := 0;
                                                      IF  mb_st^[ mfirst_free-1 ].etype = st_func
                                                      THEN
                                                       IF  ((mb_st^[ mfirst_free-1 ].eop_func = op_f_count) OR
                                                        ( mb_st^[ mfirst_free-1 ].eop_func = op_f_dis_count))
                                                       THEN
                                                        add := - mxsp_resnum +
                                                           mb_st^[ mfirst_free-1 ].elen_var
                                                       ELSE
                                                        IF  mb_st^[ mfirst_free-1 ].eop_func in
                                                         [ op_f_avg, op_f_dis_avg,
                                                         op_f_stddev, op_f_dis_stddev,
                                                         op_f_variance, op_f_dis_variance ]
                                                        THEN
                                                         BEGIN
                                                         add := mxsp_resnum;
                                                         distpos := distpos + add
                                                         END;
                                                        (*ENDIF*) 
                                                       (*ENDIF*) 
                                                      (*ENDIF*) 
                                                      d_inoutpos := d_inoutpos +
                                                         colin.sci_iolen + add;
                                                      IF  (d_inoutpos > MAX_RECLEN_GG00+1)
                                                      THEN
                                                       a07_b_put_error (acv,
                                                          e_output_columns_too_long, d_vppos);
                                                      (*ENDIF*) 
                                                      IF  a_returncode = 0
                                                      THEN
                                                       BEGIN
                                                       mqual_cnt   := succ(mqual_cnt);
                                                       mfirst_free := succ(mfirst_free);
                                                       END;
                                                      (*ENDIF*) 
                                                      END
                                                     (*ENDWITH*) 
                                                    (*ENDIF*) 
                                                (*ENDWITH*) 
                                                END
                                            ELSE
                                                BEGIN
                                                ftabno := succ(ftabno);
                                                WITH a_ap_tree^[ cnode ] DO
                                                    BEGIN
                                                    IF  (n_symb = s_authid) OR (n_symb = s_tablename)
                                                    THEN
                                                     BEGIN
                                                     next_n := n_sa_level;
                                                     IF  a_ap_tree^[ next_n ].n_symb = s_tablename
                                                      (* with authid *)
                                                     THEN
                                                      next_n := a_ap_tree^[ next_n ].n_sa_level;
                                                     (*ENDIF*) 
                                                     n_sa_level := a_ap_tree^[ next_n ].n_sa_level;
                                                     n_lo_level := a_ap_tree^[ next_n ].n_lo_level
                                                     END;
                                                    (*ENDIF*) 
                                                    END;
                                                (*ENDWITH*) 
                                                helpfno := 0;
                                                REPEAT
                                                    helpfno := succ(helpfno)
                                                UNTIL
                                                    ((tc_columns[ helpfno ].ctabno =
                                                    tc_columns[ fno ].ctabno) AND
                                                    (tc_columns[ helpfno ].cfieldno =
                                                    tc_columns[ fno ].cfieldno));
                                                (*ENDREPEAT*) 
                                                IF  helpfno <> fno
                                                THEN
                                                    BEGIN
                                                    (* the same ak67corr_column ist used twice *)
&                                                   IFDEF TRACE
                                                    t01int4 (ak_sem, 'fno         ', fno);
                                                    t01int4 (ak_sem, 'helpfno     ', helpfno);
&                                                   ENDIF
                                                    a_ap_tree^[ cnode ].n_proc  := a67;
                                                    a_ap_tree^[ cnode ].n_symb  :=
                                                       a_ap_tree^[ tc_columns[ helpfno ].cnode ].n_symb;
                                                    a_ap_tree^[ cnode ].n_datatype  :=
                                                       a_ap_tree^[ tc_columns[ helpfno ].cnode ].n_datatype;
                                                    a_ap_tree^[ cnode ].n_pos   :=
                                                       a_ap_tree^[ tc_columns[ helpfno ].cnode ].n_pos;
                                                    a_ap_tree^[ cnode ].n_length :=
                                                       a_ap_tree^[ tc_columns[ helpfno ].cnode ].n_length
                                                    END
                                                ELSE
                                                    BEGIN
                                                    a06extcolno (sparr.pbasep^.sbase,
                                                       cfieldno,
                                                       d_colbuf);
                                                    WITH d_colbuf^ DO
                                                     BEGIN
                                                     a061get_colname (d_colbuf^,
                                                        d_column);
                                                     IF  d_having
                                                     THEN
                                                      a61_is_group_field (acv, dmli,
                                                         d_column,
                                                         d_colbuf^.cextcolno,
                                                         NOT c_is_expression, 0, 1);
                                                     (*ENDIF*) 
                                                     IF  a_returncode = 0
                                                     THEN
                                                      BEGIN
&                                                     IFDEF TRACE
                                                      t01int4 (ak_sem, 'cnode       ', cnode);
                                                      t01int4 (ak_sem, 'd_inoutpos  ', d_inoutpos);
                                                      t01int4 (ak_sem, 'd_keylen    ', d_keylen);
                                                      t01lidentifier (ak_sem, d_column);
                                                      t01name (ak_sem, 'btablen           ');
                                                      t01lidentifier (ak_sem, btablen^);
&                                                     ENDIF
                                                      WITH a_ap_tree^[ cnode ] DO
                                                       BEGIN
                                                       n_proc := a67;
                                                       IF  a_union_cnt <> 0
                                                       THEN
                                                        n_symb := s_true
                                                       ELSE
                                                        (* true : in Union *)
                                                        n_symb := s_unknown;
                                                       (*ENDIF*) 
                                                       n_pos  := d_inoutpos -
                                                          d_keylen-distpos;
                                                       n_length   := cinoutlen;
                                                       n_datatype := cdatatyp;
                                                       END;
                                                      (*ENDWITH*) 
                                                      together_allowed := false;
                                                      a061colinfo_to_var (
                                                         d_colbuf^, colinf);
                                                      a61_var_col_stackentry (acv, dmli,
                                                         colinf, together_allowed,
                                                         put_together, dummy_len,
                                                         c_is_corr_column,
                                                         conv_none, dunknown);
                                                      a_ap_tree^[ cnode ].n_length := colinf.cinoutlen;
                                                      (* may have been changed for ddate, dtime *)
                                                      IF  ((orderlen + cinoutlen<=
                                                       cak_maxorderlength) AND
                                                       NOT d_having)
                                                      THEN
                                                       BEGIN
                                                       d_order_cols.ofield[ 1 ].ofstno := 0;
                                                       d_order_cols.ofield[ 1 ].ofasc :=
                                                          [ is_order_asc ];
                                                       a061get_colname (
                                                          d_colbuf^,
                                                          col_name);
                                                       a61_is_orderfield (acv, dmli,
                                                          colinf,
                                                          @d_order_cols,
                                                          put_together,
                                                          conv_none, 0,
                                                          col_name);
                                                       WITH colinf DO
                                                        orderlen := orderlen +
                                                           cinoutlen;
                                                       (*ENDWITH*) 
                                                       END
                                                      (*ENDIF*) 
                                                      END
                                                     (*ENDIF*) 
                                                     END
                                                    (*ENDWITH*) 
                                                    END
                                                (*ENDIF*) 
                                                END;
                                            (*ENDIF*) 
                                        (*ENDWITH*) 
                                        END;
                                    (*ENDIF*) 
                                (*ENDIF*) 
                                fno := succ(fno)
                                END
                            (*ENDWITH*) 
                        (*ENDWHILE*) 
                        END;
                    (*ENDIF*) 
                    tabno := succ(tabno)
                    END
                (*ENDWITH*) 
            ELSE
                all := true
            (*ENDIF*) 
        ELSE
            all := true
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
(*ENDWITH*) 
(* PTS 1115725 E.Z. *)
dmli.d_prep_corr_cols := false;
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67pass_through_corr_columns (
            VAR acv         : tak_all_command_glob;
            VAR dmli        : tak_dml_info;
            add             : integer;
            VAR corrtab_buf : tak_sysbufferaddress);
 
VAR
      equal      : boolean;
      last_found : boolean;
      fno        : integer;
      ilevel     : integer;
      act_node   : integer;
 
BEGIN
WITH acv, dmli, corrtab_buf^.scorr DO
    BEGIN
    fno := 1;
    WHILE ((a_returncode = 0) AND
          (fno <= tc_no_of_columns)) DO
        BEGIN
&       ifdef TRACE
        t01int4 (ak_sem, 'fno         ', fno);
        WITH tc_columns[ fno ] DO
            BEGIN
            t01int4 (ak_sem, 'n_pos       ', a_ap_tree^[ cnode ].n_pos);
            t01int4 (ak_sem, 'cset.n_pos  ', a_ap_tree^[ csetnode ].n_pos);
            t01int4 (ak_sem, 'ctabno      ', ctabno);
            t01int4 (ak_sem, 'tc_oldstartt', tc_oldstarttable);
            END;
        (*ENDWITH*) 
&       endif
        WITH tc_columns[ fno ] DO
            BEGIN
            equal    := false;
            act_node := 0;
            IF  cnode > 0
            THEN
                IF  ((a_ap_tree^[ cnode ].n_pos > 0) AND
                    (ctabno > 0) AND
                    (ctabno < tc_oldstarttable))
                THEN
                    BEGIN
                    equal    := true;
                    act_node := cnode
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  csetnode > 0
            THEN
                IF  ((a_ap_tree^[ csetnode ].n_pos > 0) AND
                    (ctabno > 0) AND
                    (ctabno < tc_oldstarttable))
                THEN
                    BEGIN
                    equal    := true;
                    act_node := csetnode
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  equal
            THEN
                BEGIN
                last_found := false;
                ilevel     := 0;
                REPEAT
                    ilevel := succ(ilevel);
&                   ifdef TRACE
                    t01int4 (ak_sem, 'ilevel      ', ilevel);
                    t01int4 (ak_sem, 'dl[ ilevel ]', d_level[ ilevel ]);
                    t01int4 (ak_sem, 'cl[ ilevel ]', clevel[ ilevel ]);
&                   endif
                    IF  d_level[ ilevel ] = 0
                    THEN
                        BEGIN
                        last_found := true;
                        IF  clevel[ ilevel ] = 0
                        THEN
                            equal := false
                        (*ENDIF*) 
                        END
                    ELSE
                        IF  d_level[ ilevel ] <> clevel[ ilevel ]
                        THEN
                            equal := false
                        (*ENDIF*) 
                    (*ENDIF*) 
                UNTIL
                    last_found OR NOT equal;
                (*ENDREPEAT*) 
                (* we are on the direct way *)
                (* to a used column *)
&               ifdef TRACE
                t01int4 (ak_sem, 'equal       ', ord(equal));
&               endif
                IF  equal
                THEN
                    IF  (a_mblock.mb_qual^.mfirst_free + 2 >
                        a_mblock.mb_st_max+1)
                    THEN
                        a07_b_put_error (acv, e_too_many_mb_stackentries, 1)
                    ELSE
                        (* PTS 1117747 E.Z. *)
                        IF  (d_where_corr_subquery ) AND
                            (d_having_subquery OR d_having_corr_subquery)
                        THEN
                            BEGIN
                            (* passing through of corr columns not possible     *)
                            (* through a query with where AND having-subqueries *)
                            (* because the resulting n_pos had to be different  *)
                            (* depending if the passing through passes the where*)
                            (* or the having-part (and we do not know which one)*)
                            (* see this example out of fokus.vdnts              *)
                            (*===========================================================================*)
                            (* select name, beschreibung, wert                                           *)
                            (* from personal, praemie                                                    *)
                            (* where wert =                                                              *)
                            (*        (select max(wert)                                                  *)
                            (*          from praemie                                                     *)
                            (*         where pr_id in                                                    *)
                            (*              (select pr_id                                                *)
                            (*                 from notwendiges_ziel nz                                  *)
                            (*                where nz.ziel_id in (select ziel_id                        *)
                            (*                                       from erreichtes_ziel ez             *)
                            (*                                      where ez.pers_no = personal.pers_no  *)
                            (*                                    )                                      *)
                            (*                group by pr_id                                             *)
                            (*                having count ( * ) = (select count( * )                    *)
                            (*                                      from notwendiges_ziel                *)
                            (*                                     where pr_id = nz.pr_id                *)
                            (*                                   )                                       *)
                            (*              )                                                            *)
                            (*        )                                                                  *)
                            (* order by 3                                                                *)
                            (*===========================================================================*)
                            a07_b_put_error (acv, e_too_many_subqueries, 2)
                            END
                        ELSE
                            BEGIN
                            WITH a_mblock.mb_st^[ a_mblock.mb_qual^.mfirst_free ] DO
                                BEGIN
                                etype    := st_value;
                                eop      := op_order_asc;
                                epos     := a_ap_tree^[ act_node ].n_pos;
                                elen_var := a_ap_tree^[ act_node ].n_length;
                                ecol_tab[ 1 ] := cgg04_value_to_be_truncated;
                                ecol_tab[ 2 ] := chr(0)
                                END;
                            (*ENDWITH*) 
                            WITH a_mblock.mb_st^
                                 [ a_mblock.mb_qual^.mfirst_free + 1 ] DO
                                BEGIN
                                etype    := st_output;
                                eop      := op_none;
                                epos     := d_inoutpos-add;
                                elen_var := a_ap_tree^[ act_node ].n_length;
                                a_ap_tree^[ act_node ].n_pos := d_inoutpos -
                                      d_keylen - add;
                                d_inoutpos := d_inoutpos + elen_var;
                                IF  d_inoutpos > MAX_RECLEN_GG00 + 1
                                THEN
                                    a07_b_put_error (acv,
                                          e_too_long_corelated_row, 1);
                                (*ENDIF*) 
                                ecol_tab[ 1 ] := chr(0);
                                ecol_tab[ 2 ] := chr(0)
                                END;
                            (*ENDWITH*) 
                            WITH a_mblock.mb_qual^ DO
                                mfirst_free := mfirst_free + 2
                            (*ENDWITH*) 
                            END
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        fno := succ(fno)
        END
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67reskey_build (
            VAR acv      : tak_all_command_glob;
            VAR dmli     : tak_dml_info;
            VAR res_n    : tsp00_KnlIdentifier;
            VAR res_tree : tgg00_FileId;
            VAR upd_stat : boolean;
            VAR sr_rec   : tak70_strat_rec;
            output_len   : integer);
 
VAR
      _e                : tgg00_BasisError;
      _fetch_primkeylen : integer;
      _primlen          : integer;
      _invlen           : integer;
      _updkeylen        : integer;
      _recordlen        : integer;
      _re               : tsp00_NumError;
      _ke               : tgg00_SysInfoKey;
 
BEGIN
upd_stat := false;
a61_rel_old_table (acv, dmli, 1);
_fetch_primkeylen := 0;
IF  dmli.d_maxcounttabs = 1
THEN
    IF  acv.a_returncode = 0
    THEN
        (* PTS 1112311 E.Z. *)
        IF  (dmli.d_sparr.pbasep^.sbase.btablekind <> tdb2view)     AND
            (dmli.d_sparr.pbasep^.sbase.btablekind <> tcomplexview) AND
            (* PTS 1128361 E.Z. *)
            (dmli.d_sparr.pbasep^.sbase.blastkeyind > 0)
        THEN
            WITH dmli.d_sparr.pbasep^.sbase, bcolumn[ blastkeyind ]^ DO
                _fetch_primkeylen := ccolstack.epos + cinoutlen - 1;
            (*ENDWITH*) 
        (*ENDIF*) 
    (*ENDIF*) 
(*ENDIF*) 
a70_keylengths (acv, sr_rec.sr_strategy, _fetch_primkeylen, sr_rec.sr_invkeylen,
      dmli.d_keylen, _primlen, _invlen);
_updkeylen := dmli.d_inoutpos - ( dmli.d_reclen + 1 );
_recordlen := sizeof(tak_resultkeyrecord) - mxak_res_keysbuf +
      4 + dmli.d_change.cr_colcount*mxak_change_colinfo +
      4*_primlen + 4*_invlen + _updkeylen;
_e  := e_ok;
_ke := a01sysnullkey;
IF  acv.a_ex_kind = only_parsing
THEN
    BEGIN
    IF  dmli.d_union
    THEN
        acv.a_union_key := acv.a_pars_last_key;
    (*ENDIF*) 
    _ke.sauthid[ 1 ] := cak_tempinfo_byte;
    g10mv ('VAK67 ',   1,    
          sizeof(acv.a_pars_last_key), sizeof(_ke.sauthid),
          @acv.a_pars_last_key, 1, @_ke.sauthid, 2, mxak_parskey, _e);
    _ke.sauthid[ mxak_parskey + 1 ] := chr(0);
    END
ELSE
    _ke.stempid  := acv.a_curr_res_id;
(*ENDIF*) 
_ke.sentrytyp := cak_ereskey;
a10_nil_get_sysinfo (acv, _ke, d_release, _recordlen, dmli.d_esparr.pparsp, _e);
IF  _e <> e_ok
THEN
    a07_b_put_error (acv, _e, 1)
ELSE
    BEGIN
    WITH dmli.d_esparr.pparsp^.sreskey DO
        BEGIN
        res_resstate :=
              acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resstate;
        res_nextpos     := 0;
        res_prevpos     := 0;
        res_keylen      := dmli.d_keylen;
        res_reclen      := dmli.d_inoutpos - 1;
        res_length      := dmli.d_reclen;
        res_first_fetch := true;
        res_eof         := false;
        res_dist_optim    := dmli.d_dist_optim;
        res_qual_kind   := dmli.d_qual_kind;
        res_strat_info  := dmli.d_strat_info;
        res_reverse_access := sr_rec.sr_reverse_access;
        (* h.b. PTS 1001366 *)
        res_rowno       := dmli.d_rowno;
&       IFDEF TRACE
        t01int4 (ak_sem, 'res_keylen  ', res_keylen);
        t01int4 (ak_sem, 'res_reclen  ', res_reclen);
        t01int4 (ak_sem, 'res_length  ', res_length);
        t01int4 (ak_sem, 'res_dist_opt', res_dist_optim);
        t01refinfoindex (ak_sem, 'res_strat_in', res_strat_info);
&       ENDIF
        (* PTS 1122398 E.Z. *)
        IF  ((hsTempLock_egg00 in dmli.d_globstate) AND
            ( acv.a_isolation_info = temp_lock_rec_not_needed))
        THEN
            res_unlocktab := dmli.d_sparr.pbasep^.sbase.btreeid.fileTabId_gg00
        ELSE
            res_unlocktab := cgg_zero_id;
        (*ENDIF*) 
        res_parsinfob := acv.a_precomp_info_byte;
        IF  acv.a_date_time_used
        THEN
            res_pars_dt_format := acv.a_dt_format
        ELSE
            res_pars_dt_format := dtf_none;
        (*ENDIF*) 
        (* PTS 1106955 E.Z. *)
        res_pars_sqlmode  := acv.a_sqlmode;
        res_analyze_cmdid := cgg_zero_id;
        res_updkey.ks_len := res_reclen - res_length;
        res_primkeylen    := res_reclen - res_length;
&       ifdef TRACE
        t01int4 (ak_sem, 'res_reclen  ', res_reclen);
        t01int4 (ak_sem, 'res_length  ', res_length);
        t01warningset (ak_sem, 'warn2check  ',
              acv.a_transinf.tri_trans.trWarning_gg00);
&       endif
        IF  res_reclen = res_length
        THEN
            BEGIN
            res_for_update := false;
            res_updchar[ 1 ] := bsp_c1;
            res_length := cgg_rec_key_offset + res_keylen + output_len;
            IF  res_reclen = res_length+1
                (* for warn2-Byte *)
            THEN
                IF  ((acv.a_ex_kind <> only_parsing) AND
                    NOT (warn2_null_in_builtin_func
                    in acv.a_transinf.tri_trans.trWarning_gg00))
                THEN
                    res_updkey.ks_len := 0
                ELSE
                    res_updkey.ks_len := 1
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            res_for_update := true;
            res_updtabid   := dmli.d_tabarr[ 1 ].ofromtableid;
            res_useupdk    := 0;
            IF  dmli.d_maxcounttabs = 1
            THEN
                res_upd_tabcnt := 1
            ELSE
                res_upd_tabcnt := ak67cnt_1_to_1_tabs (acv, res_updtabid);
            (*ENDIF*) 
&           ifdef trace
            t01int4 (ak_sem, 'res_useupd_c', res_upd_tabcnt);
&           endif
            IF  acv.a_returncode = 0
            THEN
                BEGIN
                res_treeids.file_id := dmli.d_tabarr[ dmli.d_acttabindex ].otreeid;
                WITH dmli.d_sparr.pbasep^.sbase DO
                    IF  btablekind in [tdb2view]
                    THEN
                        res_updchar[1] := bsp_c1
                    ELSE
                        BEGIN
                        WITH dmli.d_sparr.pbasep^.sbase.
                             bcolumn[ blastkeyind ]^ DO
                            BEGIN
                            CASE cdatatyp OF
                                dcha, dtime, ddate, dtimestamp :
                                    res_updchar[ 1 ] := csp_ascii_blank;
                                dunicode :
                                    res_updchar[ 1 ] := csp_unicode_def_byte;
                                OTHERWISE
                                    res_updchar[ 1 ] := csp_defined_byte
                                END;
                            (*ENDCASE*) 
                            res_minkeylen := ccolstack.epos;
                            END;
                        (*ENDWITH*) 
                        END;
                    (*ENDIF*) 
                (*ENDWITH*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        res_decresdel :=
              acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resdecresdel;
        IF  acv.a_ex_kind <> only_parsing
        THEN
            s40g4int (acv.a_mblock.mb_qual^.mr_resnum, 2,
                  res_actres, _re)
        ELSE
            res_actres := csp_maxint4;
        (*ENDIF*) 
        res_searched_pages := 1;
        IF  dmli.d_maxcounttabs = 1
        THEN
            IF  acv.a_returncode = 0
            THEN
                BEGIN
                res_known_pages :=
                      a28prim_pages (acv, dmli.d_sparr.pbasep^.sbase);
                res_primkeylen := _fetch_primkeylen
                END
            ELSE
                res_known_pages := cak_is_undefined
            (*ENDIF*) 
        ELSE
            res_known_pages := cak_is_undefined;
        (*ENDIF*) 
        g10mv ('VAK67 ',   2,    
              sizeof(dmli.d_change), sizeof(res_change),
              @dmli.d_change, 1, @res_change, 1,
              4 + dmli.d_change.cr_colcount*mxak_change_colinfo,
              acv.a_returncode);
        a67_keyspecs (dmli.d_esparr.pparsp, _primlen, _invlen);
        ;
        IF  NOT (sr_rec.sr_strategy in a70glob_fetch_strats)
        THEN
            (* build strategies *)
            BEGIN
            SAPDB_PascalFill ('VAK67 ',   3,    
                  sizeof(res_keysbuf), @res_keysbuf,
                  res_stopkeys.reckeyspec.ks_pos,
                  res_stopkeys.reckeyspec.ks_len, chr(255),
                  acv.a_returncode);
            res_treeids.inv_id := b01niltree_id;
            res_build := true;
&           IFDEF TRACE
            t01int4 (ak_sem, 'res_keylen  ', res_keylen);
            t01int4 (ak_sem, 'ex_kind     ', ord(acv.a_ex_kind));
&           ENDIF
            IF  acv.a_ex_kind <> only_parsing
            THEN
                BEGIN
                res_restree := res_tree;
                END
            ELSE
                res_restree := b01niltree_id
            (*ENDIF*) 
            END
        ELSE
            (* fetch strategies *)
            BEGIN
            res_restree := b01niltree_id;
            IF  (acv.a_ex_kind <> only_parsing)
            THEN
                BEGIN
                a67_fetchkeys (acv, dmli.d_esparr.pparsp, _primlen, _invlen);
                upd_stat :=
                      ((res_searched_pages > cak68_updstat_minpages) AND
                      (res_searched_pages > res_known_pages * cak68_updstat_factor));
                END;
            (*ENDIF*) 
            res_build   := false;
            res_prevpos :=  - 1;
            END;
        (*ENDIF*) 
        res_resultname := res_n;
        res_order      := dmli.d_use_order OR (dmli.d_distinct <> no_distinct)
              OR (dmli.d_group_cols.ocntord > 0) OR (acv.a_union_cnt > 0);
        res_outcolno   := dmli.d_outcolno - 1;
        dmli.d_esparr.pparsp^.b_sl := _recordlen;
        res_fullen                 := _recordlen;
&       IFDEF TRACE
        t01int4 (ak_sem, 'res_build   ', ord(res_build));
        t01int4 (ak_sem, 'start rec p ', res_startkeys.reckeyspec.ks_pos);
        t01int4 (ak_sem, 'start rec l ', res_startkeys.reckeyspec.ks_len);
        t01int4 (ak_sem, 'start inv p ', res_startkeys.listkeyspec.ks_pos);
        t01int4 (ak_sem, 'start inv l ', res_startkeys.listkeyspec.ks_len);
        t01int4 (ak_sem, 'stop  rec p ', res_stopkeys.reckeyspec.ks_pos);
        t01int4 (ak_sem, 'stop  rec l ', res_stopkeys.reckeyspec.ks_len);
        t01int4 (ak_sem, 'stop  inv p ', res_stopkeys.listkeyspec.ks_pos);
        t01int4 (ak_sem, 'stop  inv l ', res_stopkeys.listkeyspec.ks_len);
        t01int4 (ak_sem, 'next  rec p ', res_nextkeys.reckeyspec.ks_pos);
        t01int4 (ak_sem, 'next  rec l ', res_nextkeys.reckeyspec.ks_len);
        t01int4 (ak_sem, 'next  inv p ', res_nextkeys.listkeyspec.ks_pos);
        t01int4 (ak_sem, 'next  inv l ', res_nextkeys.listkeyspec.ks_len);
        t01int4 (ak_sem, 'prev  rec p ', res_prevkeys.reckeyspec.ks_pos);
        t01int4 (ak_sem, 'prev  rec l ', res_prevkeys.reckeyspec.ks_len);
        t01int4 (ak_sem, 'prev  inv p ', res_prevkeys.listkeyspec.ks_pos);
        t01int4 (ak_sem, 'prev  inv l ', res_prevkeys.listkeyspec.ks_len);
&       ENDIF
        END;
    (*ENDWITH*) 
    a10add_sysinfo (acv, dmli.d_esparr.pparsp, _e);
    IF  _e <> e_ok
    THEN
        a07_b_put_error (acv, _e, 1)
    (*ENDIF*) 
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67second_qual_columns (
            VAR acv              : tak_all_command_glob;
            VAR dmli             : tak_dml_info;
            VAR aux_mblock       : tgg00_MessBlock;
            VAR h_d_jcnt         : integer;
            VAR fetch_keypos     : integer;
            VAR fetch_keylen     : integer;
            VAR new_keypos       : integer;
            VAR minkeylen        : integer;
            VAR varkeyvaluestack : integer;
            VAR qualpos          : integer;
            VAR qualend          : integer);
 
VAR
      and_count : integer;
      j         : integer;
      joinpos   : integer;
      diff      : integer;
 
      and_arr   : RECORD
            CASE boolean OF
                true :
                    (eops : tak_eop_arr_ptr);
                false :
                    (sl : tgg00_StackListPtr)
                END;
            (*ENDCASE*) 
 
 
BEGIN
WITH acv, dmli, aux_mblock, mb_qual^ DO
    BEGIN
    minkeylen := 1;
    IF  mb_type in [ m_update, m_delete ]
    THEN
        BEGIN
        d_single     := true;
        d_group      := false;
        d_corr       := no_correlation;
        fetch_keypos := d_inoutpos - 1;
        a61_update_column (acv, dmli, minkeylen, 1);
        fetch_keylen := d_inoutpos - 1 - fetch_keypos;
        d_corr       := first_correlation;
        d_single     := false;
        END
    ELSE
        ak67sub_check (acv, dmli, aux_mblock, 0, c_first_part);
    (*ENDIF*) 
    a61_set_jump (a_mblock, 1, st_jump_output);
    WITH a_mblock.mb_st^[ 1 ] DO
        epos := succ(epos);
    (*ENDWITH*) 
&   IFDEF TRACE
    t01messblock (ak_sem, 'sec_qual amb', a_mblock);
&   ENDIF
    IF  a_returncode = 0
    THEN
        BEGIN
        qualpos := qualend;
        qualend := mqual_pos + mqual_cnt - 1;
        IF  a_mblock.mb_qual^.mfirst_free + qualend - qualpos >
            a_mblock.mb_st_max+1
        THEN
            a07_b_put_error (acv, e_too_many_mb_stackentries, 1)
        ELSE
            BEGIN
            g10mv ('VAK67 ',   4,    
                  mb_st_size, a_mblock.mb_st_size,
                  @mb_st^, qualpos * STACK_ENTRY_MXGG00 + 1,
                  @a_mblock.mb_st^,
                  (a_mblock.mb_qual^.mfirst_free - 1) *
                  STACK_ENTRY_MXGG00 + 1,
                  (qualend - qualpos) * STACK_ENTRY_MXGG00,
                  a_returncode);
&           IFDEF TRACE
            t01int4 (ak_sem, 'qualpos     ', qualpos);
            t01int4 (ak_sem, 'qualend     ', qualend);
            t01messblock (ak_sem, 'sec_qual am2', a_mblock);
&           ENDIF
            WITH dmli.d_joins DO
                FOR joinpos := 0 TO jrc_cnt - 1 DO
                    WITH jrc_joinarr[ joinpos ] DO
                        BEGIN
                        jo_recs[ 1 ].jop_startstack := jo_recs[ 1 ]
                              .jop_startstack - qualpos +
                              a_mblock.mb_qual^.mfirst_free - 1;
                        jo_recs[ 2 ].jop_startstack := jo_recs[ 2 ]
                              .jop_startstack - qualpos +
                              a_mblock.mb_qual^.mfirst_free - 1;
                        END;
                    (*ENDWITH*) 
                (*ENDFOR*) 
            (*ENDWITH*) 
            h_d_jcnt := 0;
            a_mblock.mb_qual^.mfirst_free :=
                  a_mblock.mb_qual^.mfirst_free + qualend - qualpos;
            a_mblock.mb_qual^.mqual_cnt   :=
                  a_mblock.mb_qual^.mqual_cnt + qualend - qualpos;
&           IFDEF TRACE
            t01messblock (ak_sem, 'aux mblock: ', aux_mblock);
            t01messblock   (ak_sem, 'sec_qual am3', a_mblock);
&           ENDIF
            ak67sub_check (acv, dmli, aux_mblock,
                  a_mblock.mb_qual^.mfirst_free -
                  mb_qual^.mfirst_free, NOT c_first_part);
&           IFDEF TRACE
            t01messblock (ak_sem, 'aux mblock: ', aux_mblock);
&           ENDIF
            IF  mb_st^[ mqual_pos ].etype = st_jump_output
            THEN
                IF  mfirst_free = mqual_pos - 1 + mb_st^[ mqual_pos ].epos
                THEN
                    diff := 2
                ELSE
                    diff := 4
                (*ENDIF*) 
            ELSE
                IF  ((mqual_pos > 0) AND (mfirst_free > mqual_pos))
                THEN
                    diff := 4
                ELSE
                    diff := 2;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  mfirst_free + diff > mb_st_max+1
            THEN
                a07_b_put_error (acv, e_too_many_mb_stackentries, 1)
            ELSE
                IF  mb_data_len + fetch_keylen > mb_data_size
                THEN
                    a07_b_put_error (acv, e_too_many_mb_data, 1);
                (*ENDIF*) 
            (*ENDIF*) 
            IF  a_returncode = 0
            THEN
                BEGIN
                j := mfirst_free - 1;
                WHILE mb_st^[ j ].eop in [ op_and, op_upd_view_and ] DO
                    j := pred(j);
                (*ENDWHILE*) 
                and_count := 0;
                IF  mfirst_free - 1 - j > 0
                THEN
                    BEGIN
                    a10new (acv, (mfirst_free - 1 - j) * sizeof(tgg00_StackOpType),
                          and_arr.sl);
                    IF  and_arr.sl = NIL
                    THEN
                        a07_b_put_error (acv, e_no_more_memory, 1)
                    ELSE
                        WHILE mfirst_free - 1 > j DO
                            BEGIN
                            mfirst_free := mfirst_free - 1;
                            and_count   := and_count + 1;
                            and_arr.eops^[ and_count ] :=
                                  mb_st^[ mfirst_free ].eop;
&                           IFDEF TRACE
                            t01int4 (ak_sem, 'and_count   ', and_count);
                            t01int4 (ak_sem, 'and_array   ', ord(and_arr.eops^[ and_count ]));
&                           ENDIF
                            END
                        (*ENDWHILE*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  diff = 4
                THEN
                    BEGIN
                    WITH mb_st^[ mfirst_free ] DO
                        BEGIN
                        etype    := st_jump_false;
                        eop      := op_none;
                        epos     := 4;
                        elen_var := 0;
                        ecol_pos := 0
                        END;
                    (*ENDWITH*) 
                    mfirst_free := succ(mfirst_free)
                    END;
                (*ENDIF*) 
                WITH mb_st^[ mfirst_free ] DO
                    BEGIN
                    etype         := st_varkey;
                    eop           := op_none;
                    epos          := 1;
                    elen_var      := fetch_keylen;
                    ecol_tab[ 1 ] := chr(0);
                    ecol_tab[ 2 ] := chr(1)
                    END;
                (*ENDWITH*) 
                WITH mb_st^[ mfirst_free + 1 ] DO
                    BEGIN
                    varkeyvaluestack := mfirst_free + 1;
                    etype            := st_value;
                    eop              := op_eq_all;
                    epos             := mb_data_len + 1;
                    new_keypos       := epos;
                    mb_data_len      := mb_data_len + fetch_keylen;
                    elen_var         := fetch_keylen;
                    ecol_tab[ 1 ]    := chr(0);
                    ecol_tab[ 2 ]    := chr(0)
                    END;
                (*ENDWITH*) 
                mfirst_free := mfirst_free + 2;
                IF  diff = 4
                THEN
                    BEGIN
                    WITH mb_st^[ mfirst_free ] DO
                        BEGIN
                        etype := st_op;
                        IF  mb_type = m_update
                        THEN
                            eop := op_upd_view_and
                        ELSE
                            eop := op_and;
                        (*ENDIF*) 
                        epos     := 0;
                        elen_var := 0;
                        ecol_pos := 0;
                        END;
                    (*ENDWITH*) 
                    mfirst_free := succ(mfirst_free)
                    END;
                (*ENDIF*) 
                mqual_cnt := mqual_cnt + diff;
                IF  and_count > 0
                THEN
                    BEGIN
                    FOR j := and_count DOWNTO 1 DO
                        BEGIN
                        WITH mb_st^[ mfirst_free ] DO
                            BEGIN
                            etype    := st_op;
                            eop      := and_arr.eops^[ j ];
                            epos     := 0;
                            elen_var := 0;
                            ecol_pos := 0;
                            END;
                        (*ENDWITH*) 
                        mfirst_free := succ(mfirst_free)
                        END;
                    (*ENDFOR*) 
                    a10dispose (acv, and_arr.sl);
                    FOR j := 1 TO mfirst_free - and_count - 4 - 1 DO
                        IF  mb_st^[ j ].etype = st_jump_false
                        THEN
                            IF  ((j + mb_st^[ j ].epos) >
                                mfirst_free - and_count - 4)
                            THEN
                                WITH mb_st^[ j ] DO
                                    epos := epos + 4;
                                (*ENDWITH*) 
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDFOR*) 
                    END;
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67sel1_second_part (
            VAR acv    : tak_all_command_glob;
            VAR dmli   : tak_dml_info;
            where_done : boolean;
            curr_n     : integer);
 
VAR
      _next_n : integer;
 
BEGIN
dmli.d_join := ( dmli.d_maxcounttabs > 1 );
IF  ((acv.a_returncode = 0)
    AND
    NOT (dmli.d_only_sem_check)
    AND
    (dmli.d_use_order OR dmli.d_group AND (dmli.d_group_cols.ocntord > 0)))
THEN
    a67_update_atinoutpos( acv, dmli, NOT dmli.d_subquery );
(*ENDIF*) 
dmli.d_group := false;
IF  ( NOT where_done )
THEN
    BEGIN
    IF  ((acv.a_returncode = 0) AND (curr_n <> 0))
    THEN
        WITH acv.a_ap_tree^[ curr_n ] DO
            BEGIN
            (* PTS 1103081 E.Z. *)
            IF  ((n_proc = a63) AND (n_subproc = cak_x_search_condition))
            THEN
                BEGIN
                _next_n := n_lo_level;
                IF  acv.a_ex_kind = only_parsing
                THEN
                    a54_fixedpos (acv, dmli);
                (*ENDIF*) 
                a65_search_condition (acv, dmli, _next_n);
                dmli.d_join := false;
                END
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67sub_check (
            VAR acv        : tak_all_command_glob;
            VAR dmli       : tak_dml_info;
            VAR aux_mblock : tgg00_MessBlock;
            diff           : integer;
            first_part     : boolean);
 
VAR
      corrsub_found : boolean;
      ready         : boolean;
      i             : integer;
      qualend       : integer;
      qualpos       : integer;
      qualstart     : integer;
      spos          : integer;
 
BEGIN
WITH aux_mblock, mb_qual^ DO
    BEGIN
    IF  mb_st^[ mqual_pos ].etype = st_jump_output
    THEN
        qualstart := mqual_pos + mb_st^[ mqual_pos ].epos - 1
    ELSE
        qualstart := mqual_pos;
    (*ENDIF*) 
    qualend := mqual_pos + mqual_cnt - 1;
    WHILE ((acv.a_returncode = 0) AND
          (qualstart <= qualend)) DO
        BEGIN
        ready         := false;
        corrsub_found := false;
        qualpos       := qualstart;
        WHILE NOT ready DO
            BEGIN
            WHILE ((qualpos <= qualend) AND
                  (mb_st^[ qualpos ].etype <> st_jump_false)) DO
                BEGIN
                IF  mb_st^[ qualpos ].etype = st_subquery
                THEN
                    corrsub_found := true;
                (*ENDIF*) 
                qualpos := succ(qualpos)
                END;
            (*ENDWHILE*) 
            IF  (qualpos > qualend)
            THEN
                BEGIN
                ready   := true;
                qualpos := qualend
                END
            ELSE
                BEGIN
                spos := qualpos;
                WHILE ((spos <= qualend) AND
                      ((mb_st^[ spos ].etype = st_jump_false) OR
                      (mb_st^[ spos ].eop in [ op_and, op_upd_view_and ]))) DO
                    IF  (mb_st^[ spos ].etype = st_jump_false)
                    THEN
                        spos := spos + mb_st^[ spos ].epos
                    ELSE
                        spos := succ(spos);
                    (*ENDIF*) 
                (*ENDWHILE*) 
                IF  spos > qualend
                THEN
                    ready   := true
                ELSE
                    qualpos := succ(qualpos)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        IF  (mb_st^[ qualpos ].etype = st_jump_false)
        THEN
            spos := pred(qualpos)
        ELSE
            spos := qualpos;
        (*ENDIF*) 
        WHILE mb_st^[ spos ].eop in [ op_and, op_upd_view_and ] DO
            spos := pred(spos);
        (*ENDWHILE*) 
        IF  (corrsub_found AND first_part)
        THEN
            BEGIN
            i := qualstart;
            WHILE ((i <= spos) AND
                  (acv.a_returncode = 0)) DO
                BEGIN
                IF  (mb_st^[ i ].etype in [ st_fixkey, st_varkey,
                    st_fixcol, st_varcol,
                    st_varlongchar ])
                THEN
                    ak67col_stackentry (acv, dmli, mb_st^[ i ]);
                (*ENDIF*) 
                i := succ(i)
                END
            (*ENDWHILE*) 
            END
        ELSE
            IF  NOT first_part
            THEN
                IF  NOT corrsub_found
                THEN
                    BEGIN
                    FOR i := qualstart TO spos - 1 DO
                        WITH mb_st^[ i ] DO
                            BEGIN
                            etype := st_dummy;
                            eop   := op_none
                            END;
                        (*ENDWITH*) 
                    (*ENDFOR*) 
                    WITH mb_st^[ spos ] DO
                        BEGIN
                        etype    := st_bool;
                        eop      := op_none;
                        epos     := cgg04_is_true;
                        elen_var := 0;
                        ecol_pos := 0
                        END
                    (*ENDWITH*) 
                    END
                ELSE
                    BEGIN
                    FOR i := qualstart + diff TO spos + diff - 1 DO
                        WITH acv.a_mblock.mb_st^[ i ] DO
                            BEGIN
                            etype := st_dummy;
                            eop   := op_none
                            END;
                        (*ENDWITH*) 
                    (*ENDFOR*) 
                    WITH acv.a_mblock.mb_st^[ spos + diff ] DO
                        BEGIN
                        etype    := st_bool;
                        eop      := op_none;
                        epos     := cgg04_is_true;
                        elen_var := 0;
                        ecol_pos := 0
                        END
                    (*ENDWITH*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        qualstart := succ(qualpos)
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_bextcolindex (
            VAR d_esparr : tak_syspointerarr;
            outcolno : integer);
 
VAR
      _count : integer;
      _i     : integer;
      _j     : integer;
 
BEGIN
WITH d_esparr.pbasep^.sresult DO
    BEGIN
&   IFDEF TRACE
    t01int4 (ak_sem, 'bmaxcol     ', bmaxcol);
    FOR _i := 1 TO bmaxcol DO
        bextcolindex [ _i ] := cak_cdropped;
    (*ENDFOR*) 
&   ENDIF
    boutcolno := outcolno;
    _count     := 0;
    WITH d_esparr.pbasep^, syskey, sbase DO
        BEGIN
        FOR _j := bfirstindex TO blastindex DO
            WITH bcolumn[ _j ]^ DO
                BEGIN
&               ifdef trace
                a061td_colinfo (bcolumn[_j]^, _j);
&               endif
                d_esparr.pbasep^.sbase.bextcolindex[ cextcolno ] := _count;
                _count := succ(_count);
                END;
            (*ENDWITH*) 
        (*ENDFOR*) 
        END;
    (*ENDWITH*) 
    d_esparr.pbasep^.sbase.bmaxcol := _count;
    a11sort (d_esparr.pbasep^.sbase)
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak67update_a67_nodes (
            VAR acv     : tak_all_command_glob;
            VAR dmli    : tak_dml_info;
            VAR tabno   : integer;
            distpos     : integer;
            corrtab_buf : tak_sysbufferaddress);
 
VAR
      all          : boolean;
      fno          : integer;
      ftabno       : integer;
 
BEGIN
all      := false;
IF  distpos <> 0
THEN
    WITH corrtab_buf^.scorr DO
        WHILE ((acv.a_returncode = 0 ) AND NOT all) DO
            BEGIN
&           IFDEF TRACE
            t01int4 (ak_sem, 'tabno       ', tabno);
            t01int4 (ak_sem, 'tc_no_of_tab', tc_no_of_tables);
            t01int4 (ak_sem, 'tc_oldstartt', tc_oldstarttable);
            t01int4 (ak_sem, 'd_maxcountab', dmli.d_maxcounttabs);
&           ENDIF
            IF  tabno <= tc_no_of_tables
            THEN
                IF  tc_tables[ tabno ].socoldtabno < tc_oldstarttable
                    (* belongs to this select *)
                    (* pay attention, tc_oldstarttable was *)
                    (* increased by d_maxcounttabs after   *)
                    (* ak67output.... Therefore no addition*)
                    (* here.                               *)
                THEN
                    BEGIN
                    WITH tc_tables[ tabno ] DO
                        BEGIN
                        fno    := 1;
                        ftabno := 0;
                        WITH corrtab_buf^.scorr DO
                            WHILE ((fno   <= tc_no_of_columns) AND
                                  (ftabno <= socfields) AND
                                  (acv.a_returncode = 0)) DO
                                BEGIN
&                               ifdef TRACE
                                t01int4 (ak_sem, 'FNO         ', fno);
                                t01int4 (ak_sem, 'tc_no_of_col', tc_no_of_columns);
                                t01int4 (ak_sem, 'ftabno      ', ftabno);
                                t01int4 (ak_sem, 'socfields   ', socfields);
                                t01int4 (ak_sem, 'ctabno      ', tc_columns[ fno ].ctabno);
                                t01int4 (ak_sem, 'socoldtabno ', socoldtabno);
                                t01int4 (ak_sem, 'ccmd_part   ', ord(tc_columns[ fno ].ccmd_part));
                                t01int4 (ak_sem, 'csetnode    ', tc_columns[ fno ].csetnode);
                                t01int4 (ak_sem, 'ccntcol     ', tc_columns[ fno ].ccntcol);
                                t01int4 (ak_sem, 'cfieldno    ', tc_columns[ fno ].cfieldno);
                                t01int4 (ak_sem, 'cnode       ', tc_columns[ fno ].cnode);
                                t01int4 (ak_sem, 'ccntcol     ', tc_columns[ fno ].ccntcol);
                                t01int4 (ak_sem, 'd_having    ', ord(dmli.d_having));
                                t01int4 (ak_sem, 'd_inoutpos  ', dmli.d_inoutpos);
                                t01int4 (ak_sem, 'd_keylen    ', dmli.d_keylen);
                                t01int4 (ak_sem, 'distpos     ', distpos);
&                               endif
                                IF  tc_columns[ fno ].ctabno = socoldtabno
                                THEN
                                    IF  cpt_in_having_clause = tc_columns[ fno ].ccmd_part
                                    THEN
                                        WITH tc_columns[ fno ] DO
                                            IF  ((csetnode > 0) AND (ccntcol > 0))
                                            THEN
                                                BEGIN
                                                WITH acv.a_ap_tree^[ csetnode ] DO
                                                    BEGIN
                                                    n_pos  := n_pos + distpos;
&                                                   ifdef TRACE
                                                    t01int4 (ak_sem, 'csetnode    ', csetnode);
                                                    t01int4 (ak_sem, 'new n_pos   ', n_pos);
                                                    t01int4 (ak_sem, 'distpos used', distpos);
&                                                   endif
                                                    END;
                                                (*ENDWITH*) 
                                                ftabno := ftabno + ccntcol;
                                                fno    := fno    + ccntcol - 1;
                                                END
                                            ELSE
                                                BEGIN
                                                WITH acv.a_ap_tree^[ cnode ] DO
                                                    BEGIN
                                                    n_pos  := n_pos + distpos;
&                                                   ifdef TRACE
                                                    t01int4 (ak_sem, 'cnode       ', cnode);
                                                    t01int4 (ak_sem, 'new n_pos   ', n_pos);
                                                    t01int4 (ak_sem, 'distpos used', distpos);
&                                                   endif
                                                    END;
                                                (*ENDWITH*) 
                                                END;
                                            (*ENDIF*) 
                                        (*ENDWITH*) 
                                    (*ENDIF*) 
                                (*ENDIF*) 
                                fno := succ(fno)
                                END
                            (*ENDWHILE*) 
                        (*ENDWITH*) 
                        END;
                    (*ENDWITH*) 
                    tabno := succ(tabno)
                    END
                ELSE
                    all := true
                (*ENDIF*) 
            ELSE
                all := true
            (*ENDIF*) 
            END
        (*ENDWHILE*) 
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(* PTS 1117747 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      a67_corr_search (
            VAR acv                 : tak_all_command_glob;
            VAR dmli                : tak_dml_info;
            only_having_columns_get : boolean;
            VAR starttabno          : integer;
            only_split              : boolean;
            predefined_pno          : integer;
            VAR old_infolen         : integer;
            VAR rtree               : tgg00_FileId);
 
CONST
      c_without_data = true;
 
VAR
      b_err            : tgg00_BasisError;
      to_split         : boolean;
      use_subquery     : boolean;
      add              : integer;
      fetch_keylen     : integer;
      fetch_keypos     : integer;
      i                : integer;
      j                : integer;
      minkeylen        : integer;
      new_keypos       : integer;
      orderlen         : integer;
      qualend          : integer;
      qualpos          : integer;
      tabno            : integer;
      varkeyvaluestack : integer;
      init_first_free  : integer;
      init_data_len    : integer;
      stackentry_cnt   : integer;
      mtype            : tgg00_MessType;
      m2type           : tgg00_MessType2;
      sr_rec           : tak70_strat_rec;
      part_res_tree    : tgg00_FileId;
      corrtab_buf      : tak_sysbufferaddress;
      last_parsbuf     : tak_sysbufferaddress;
      mblock_ptr       : tgg00_MessBlockPtr;
      ke               : tgg00_SysInfoKey;
      p_h_dmli         : tak_part_dml_info;
      p_dmli_ptr       : ^tak_part_dml_info;
      h_d_tabarr       : tak_all_from_tables;
      h_d_sparr        : tak_syspointerarr;
      h_d_rowno        : tsp00_Int2;
      h_d_filled_bytes : tsp00_Int2;
      h_d_jcnt         : integer;
      h_d_changecnt    : integer;
      h_d_keylen       : tsp00_Int2;
      h_d_reclen       : tsp00_Int2;
 
      aux_ptr         : RECORD
            CASE boolean OF
                true :
                    (x_data_ptr : tgg00_DataPartPtr);
                false  :
                    (x_qual_ptr : tgg00_QualBufPtr)
                END;
            (*ENDCASE*) 
 
      aux_mblock       : tgg00_MessBlock;
      old_st_addr      : tgg00_StackListPtr;
 
      pseudo_stack_list_ptr : RECORD
            CASE boolean OF
                true :
                    (mblock : tgg00_MessBlockPtr);
                false :
                    (stack : tgg00_StackListPtr)
                END;
            (*ENDCASE*) 
 
 
BEGIN
&ifdef TRACE
t01int4 (ak_sem, 'only_having ', ord(only_having_columns_get));
t01int4 (ak_sem, 'only_split  ', ord(only_split));
&endif
use_subquery := false;
(* PTS 1117747 E.Z. *)
to_split     := NOT only_having_columns_get;
WITH acv.a_mblock DO
    BEGIN
    IF  mb_type = m_show
    THEN
        mb_type := m_select;
    (*ENDIF*) 
    old_st_addr                     := mb_st;
    aux_mblock.mb_header            := mb_header;
    aux_mblock.mb_trailer           := mb_trailer;
&   ifdef trace
    t01messblock (ak_sem, 'aux_mblock  ', aux_mblock);
&   endif
    (* save a_mblock and stack entries into AK cache *)
    init_first_free                 := mb_qual^.mfirst_free;
    init_data_len                   := mb_data_len;
    (* room for fetch_keylen is needed whose value is unknown by now *)
    aux_mblock.mb_data_len :=
          aux_mblock.mb_data_len + mxsp_key;
    aux_mblock.mb_qual^.mfirst_free := 1;
    a10intermediate_mblock (acv, aux_mblock, mblock_ptr);
    aux_mblock.mb_qual^.mfirst_free := init_first_free;
    aux_mblock.mb_data_len          := init_data_len;
    IF  mblock_ptr <> NIL
    THEN
        BEGIN
        mblock_ptr^.mb_data_len     := init_data_len;
        mblock_ptr^.mb_st := NIL;
        stackentry_cnt    := init_first_free - 1 + 4;
        (* see diff := .. in second_qual_columns (now 4 ) *)
        a10new (acv, stackentry_cnt * STACK_ENTRY_MXGG00,
              mblock_ptr^.mb_st);
        IF  mblock_ptr^.mb_st = NIL
        THEN
            a07_b_put_error (acv, e_no_more_memory, 1)
        ELSE
            BEGIN
            mblock_ptr^.mb_st_size := stackentry_cnt * STACK_ENTRY_MXGG00;
            mblock_ptr^.mb_st_max  := stackentry_cnt;
            mblock_ptr^.mb_qual^.mfirst_free := init_first_free;
            g10mv ('VAK67 ',   5,    
                  mb_st_size, mblock_ptr^.mb_st_size,
                  @mb_st^, 1, @mblock_ptr^.mb_st^, 1,
                  (init_first_free - 1) * STACK_ENTRY_MXGG00,
                  acv.a_returncode);
            mblock_ptr^.mb_qual^.msubquery := true;
            mblock_ptr^.mb_qual^.mst_addr := mblock_ptr^.mb_st;
            mblock_ptr^.mb_qual^.mst_max  := mblock_ptr^.mb_st_max;
&           ifdef trace
            t01messblock (ak_sem, 'mblock_ptr^ ', mblock_ptr^)
&                 endif
            END
        (*ENDIF*) 
        END
    ELSE
        a07_b_put_error (acv, e_no_more_memory, 1)
    (*ENDIF*) 
    END;
(*ENDWITH*) 
p_dmli_ptr := @dmli;
p_h_dmli   := p_dmli_ptr^;
h_d_tabarr       := dmli.d_tabarr;
h_d_sparr        := dmli.d_sparr;
h_d_rowno        := dmli.d_rowno;
h_d_filled_bytes := dmli.d_filled_bytes;
h_d_jcnt         := dmli.d_joins.jrc_cnt;
h_d_changecnt    := dmli.d_change.cr_colcount;
h_d_keylen       := dmli.d_keylen;
h_d_reclen       := dmli.d_reclen;
IF  acv.a_returncode = 0
THEN
    BEGIN
    WITH ke DO
        BEGIN
        ke           := a01sysnullkey;
        sauthid[ 1 ] := cak_tempinfo_byte;
        g10mv ('VAK67 ',   6,    
              sizeof(acv.a_corr_key), sizeof(sauthid), @acv.a_corr_key, 1,
              @sauthid, 2, mxak_parskey,
              acv.a_returncode);
        sauthid[ mxak_parskey + 1 ] := chr(0);
        sentrytyp                   := cak_ecorrinfo;
        END;
    (*ENDWITH*) 
    a10get_sysinfo (acv, ke, d_fix, corrtab_buf, b_err);
    IF  b_err <> e_ok
    THEN
        a07_b_put_error (acv, b_err, 1)
    ELSE
        BEGIN
        IF  NOT only_having_columns_get
        THEN
            BEGIN
            ak67corr_dml_init (dmli);
            sr_rec.sr_distinct_bytes := true;
            sr_rec.sr_must_result    := true;
            sr_rec.sr_use_rowno      := false;
            sr_rec.sr_reverse_access := false;
            IF  dmli.d_maxcounttabs = 1
            THEN
                m2type := mm_nil
            ELSE
                m2type := mm_with_join;
            (*ENDIF*) 
            WITH dmli.d_tabarr[ 1 ] DO
                BEGIN
                IF  oisshowview in ospecialname
                THEN
                    mtype := m_show
                ELSE
                    mtype := m_select;
                (*ENDIF*) 
                a06a_mblock_init (acv, mtype, m2type, otreeid);
                END;
            (*ENDWITH*) 
            WITH acv.a_mblock.mb_qual^ DO
                BEGIN
                mqual_pos   := 1;
                mqual_cnt   := 1;
                mfirst_free := 2
                END;
            (*ENDWITH*) 
            WITH acv.a_mblock, mb_data^ DO
                BEGIN
                mb_data_len  := mblock_ptr^.mb_data_len;
                mbp_reclen   := mblock_ptr^.mb_data^.mbp_reclen;
                mbp_keylen   := mblock_ptr^.mb_data^.mbp_keylen;
                END;
            (*ENDWITH*) 
&           IFDEF TRACE
            IF  acv.a_ex_kind = only_parsing
            THEN
                g10mv ('VAK67 ',   7,    
                      mblock_ptr^.mb_data_size,
                      acv.a_mblock.mb_data_size,
                      @mblock_ptr^.mb_data^.mbp_buf, 1,
                      @acv.a_mblock.mb_data^.mbp_buf, 1,
                      mblock_ptr^.mb_data_len,
                      acv.a_returncode);
            (* see vak54_get_pparsp *)
&           ENDIF
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        tabno := corrtab_buf^.scorr.tc_starttable;
        IF  NOT only_split
        THEN
            starttabno := tabno;
&       IFDEF TRACE
        (* PTS 1117747 E.Z. *)
        (*ENDIF*) 
        t01messblock (ak_sem, 'aux mblock: ', mblock_ptr^);
        t01name      (ak_sem, '====> a_mblock:   ');
        t01messblock   (ak_sem, 'corr_s a_mbl', acv.a_mblock);
        t01int4      (ak_sem, 'tabno       ', tabno);
        t01int4      (ak_sem, 'tc_no_of_ta ',
              corrtab_buf^.scorr.tc_no_of_tables);
        t01int4      (ak_sem, 'd_maxcount  ', dmli.d_maxcounttabs);
        t01int4      (ak_sem, 'tc_oldstart ',
              corrtab_buf^.scorr.tc_oldstarttable);
&       ENDIF
        END;
    (*ENDIF*) 
    (* PTS 1117747 E.Z. *)
    IF  only_having_columns_get
    THEN
        orderlen := cak_maxorderlength
    ELSE
        orderlen := 0;
    (*ENDIF*) 
    add := 0;
    IF  acv.a_returncode = 0
    THEN
        WITH mblock_ptr^, mb_qual^ DO
            FOR i := mqual_pos TO mqual_pos + mqual_cnt - 1 DO
                IF  ((mb_st^[ i ].etype = st_func) AND
                    ( mb_st^[ i ].eop_func in
                    [ op_f_avg, op_f_dis_avg,
                    op_f_stddev, op_f_dis_stddev,
                    op_f_variance, op_f_dis_variance ]))
                THEN
                    IF  ((mb_st^[ i+1 ].etype = st_output) OR
                        ( mb_st^[ i+1 ].etype = st_result))
                    THEN
                        add := add + mxsp_resnum;
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDFOR*) 
        (*ENDWITH*) 
    (*ENDIF*) 
    IF  ((NOT only_split) AND (acv.a_returncode = 0))
    THEN
        BEGIN
        (* PTS 1117747 E.Z. *)
        ak67output_corr_columns (acv, dmli, dmli.d_sparr, tabno,
              orderlen, add, corrtab_buf);
        (* correlation columns as output in new mess_buf *)
        IF  acv.a_returncode = 0
        THEN
            BEGIN
            IF  NOT only_having_columns_get
            THEN
                BEGIN
                j := cgg_rec_key_offset+1;
                WITH acv.a_mblock, mb_qual^ DO
                    BEGIN
&                   IFDEF TRACE
                    t01int4 (ak_sem, 'mqual_cnt   ', mqual_cnt);
&                   ENDIF
                    FOR i := 1 TO mqual_cnt DO
                        WITH mb_st^[ i ] DO
                            IF  etype = st_output
                            THEN
                                IF  ( eop_out in [ op_o_none,
                                    op_o_output_hold ] ) OR
                                    ( ( eop_out = op_o_output_oflw ) AND
                                    ( mb_st^[ i - 1 ].etype <> st_output ) )
                                THEN
                                    epos := epos + orderlen
                                ELSE
                                    IF  eop_out in [ op_o_output,
                                        op_o_output_oflw, op_o_output_no_oflw,
                                        op_o_output_order ]
                                    THEN
                                        BEGIN
                                        epos := j;
                                        j    := epos + elen_var
                                        END;
&                                   IFDEF TRACE
                                    (*ENDIF*) 
                                (*ENDIF*) 
                            (*ENDIF*) 
                        (*ENDWITH*) 
                    (*ENDFOR*) 
                    t01int4 (ak_sem, 'cntord      ', dmli.d_order_cols.ocntord);
&                   ENDIF
                    WITH dmli.d_order_cols DO
                        FOR i := 1 TO ocntord DO
                            WITH ofield[ i ] DO
                                IF  ofstno > 0
                                THEN
                                    WITH mb_st^[ ofstno ] DO
                                        IF  is_possible_oflw_field in ofasc
                                        THEN
                                            IF  is_order_asc in ofasc
                                            THEN
                                                eop_out := op_o_output_oflw
                                            (*ENDIF*) 
                                        (*ENDIF*) 
                                    (*ENDWITH*) 
                                (*ENDIF*) 
                            (*ENDWITH*) 
                        (*ENDFOR*) 
                    (*ENDWITH*) 
                    END;
                (*ENDWITH*) 
                dmli.d_keylen   := dmli.d_keylen + orderlen;
                dmli.d_inoutpos := dmli.d_inoutpos + orderlen;
                END;
&           IFDEF TRACE
            (*ENDIF*) 
            t01int4      (ak_sem, 'd_keylen    ', dmli.d_keylen);
            t01int4      (ak_sem, 'd_inoutpos  ', dmli.d_inoutpos);
            t01messblock (ak_sem, 'aux mblock: ', mblock_ptr^);
            t01name      (ak_sem, '====> a_mblock:   ');
            t01messblock   (ak_sem, 'corr_s amb 2', acv.a_mblock);
&           ENDIF
            IF  (dmli.d_inoutpos > MAX_RECLEN_GG00 + 1)
            THEN
                a07_b_put_error (acv, e_too_long_corelated_row, 1);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  acv.a_returncode = 0
        THEN
            WITH corrtab_buf^.scorr DO
                BEGIN
                IF  ((NOT (mblock_ptr^.mb_type in [ m_update, m_delete ]))
                    AND
                    (dmli.d_corr <> lowest_of_correlation) AND
                    (dmli.d_corr <> first_correlation))
                THEN
                    BEGIN
                    ak67pass_through_corr_columns (acv, dmli,
                          add, corrtab_buf);
                    (* pass through columns, which come from upper levels *)
                    (* and are needed in lower levels *)
                    WITH acv.a_mblock.mb_qual^ DO
                        mqual_cnt := mfirst_free - mqual_pos;
                    (*ENDWITH*) 
                    END;
                (*ENDIF*) 
                IF  acv.a_returncode = 0
                THEN
                    WITH corrtab_buf^.scorr DO
                        BEGIN
                        (* PTS 1117747 E.Z. *)
                        IF  (NOT only_having_columns_get) OR
                            NOT dmli.d_where_corr
                        THEN
                            BEGIN
                            tc_oldstarttable := tc_oldstarttable + dmli.d_maxcounttabs;
                            tc_starttable    := tabno;
                            END;
                        (*ENDIF*) 
                        a10repl_sysinfo (acv, corrtab_buf, b_err);
                        IF  b_err <> e_ok
                        THEN
                            a07_b_put_error (acv, b_err, 1)
                        (*ENDIF*) 
                        END;
                    (*ENDWITH*) 
                (*ENDIF*) 
                a10_rel_sysinfo (acv, ke);
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        old_infolen := -add
        END;
    (*ENDIF*) 
    fetch_keypos := cgg_rec_key_offset;
    fetch_keylen := dmli.d_keylen;
&   IFDEF TRACE
    t01messblock (ak_sem, 'aux mblock: ', mblock_ptr^);
    t01name      (ak_sem, '====> a_mblock:   ');
    t01messblock   (ak_sem, 'corr_s amb 3', acv.a_mblock);
&   ENDIF
    (* PTS 1117747 E.Z. *)
    WITH mblock_ptr^, mb_qual^ DO
        FOR i := mqual_pos TO mqual_pos + mqual_cnt - 1 DO
            IF  (mb_st^[ i ].etype = st_subquery)
            THEN
                use_subquery := true;
            (*ENDIF*) 
        (*ENDFOR*) 
    (*ENDWITH*) 
    IF  ((acv.a_mblock.mb_qual^.mfirst_free <= 2) AND NOT only_split
        AND NOT use_subquery)
    THEN
        to_split := false;
&   ifdef TRACE
    (*ENDIF*) 
    t01int4 (ak_sem, 'use_subquery', ord(use_subquery));
    t01int4 (ak_sem, 'to_split    ', ord(to_split));
    t01int4 (ak_sem, 'only_split  ', ord(only_split));
    t01int4 (ak_sem, 'h_d_filled_b', h_d_filled_bytes);
    t01int4 (ak_sem, 'd_inoutpos  ', dmli.d_inoutpos);
    t01int4 (ak_sem, 'd_keylen    ', dmli.d_keylen);
&   endif
    IF  only_split
    THEN
        dmli.d_filled_bytes := h_d_filled_bytes
    ELSE
        BEGIN
        dmli.d_filled_bytes   := dmli.d_inoutpos - dmli.d_keylen - 1;
        h_d_filled_bytes := dmli.d_filled_bytes;
        END;
    (*ENDIF*) 
    IF  only_having_columns_get
    THEN
        BEGIN
        IF  (mblock_ptr^.mb_qual^.mfirst_free <
            acv.a_mblock.mb_qual^.mfirst_free)
        THEN
            BEGIN
            a61_put_last_func (acv);
            a61_set_jump (acv.a_mblock, 1, st_jump_output);
            WITH acv.a_mblock.mb_st^[ 1 ] DO
                epos := succ(epos);
            (*ENDWITH*) 
            END
        (*ENDIF*) 
        END
    ELSE
        IF  to_split
        THEN
            BEGIN
&           IFDEF TRACE
            t01int4      (ak_sem, 'd_keylen    ', dmli.d_keylen);
            t01int4      (ak_sem, 'd_inoutpos  ', dmli.d_inoutpos);
            t01int4      (ak_sem, 'd_filled_byt', dmli.d_filled_bytes);
            t01messblock (ak_sem, 'aux mblock: ', mblock_ptr^);
            t01name      (ak_sem, '====> a_mblock:   ');
            t01messblock (ak_sem, 'corr_s amb 4', acv.a_mblock);
&           ENDIF
            IF  (dmli.d_cntfromtab < dmli.d_maxcounttabs)
            THEN
                (* there was at least one join view in the FROM-part *)
                a54_joinview_baserecords (acv, dmli);
            (*ENDIF*) 
            WITH mblock_ptr^, mb_qual^ DO
                BEGIN
                qualpos := mqual_pos + 1;
                IF  (mb_st^[ mqual_pos ].etype = st_jump_output)
                THEN
                    qualend := mqual_pos + mb_st^[ mqual_pos ].epos - 2
                ELSE
                    qualend := pred(mqual_pos);
                (*ENDIF*) 
                IF  ((acv.a_returncode = 0) AND
                    NOT (mblock_ptr^.mb_type in [ m_update, m_delete ]))
                THEN
                    BEGIN
                    (* output columns of this select as output in new mess_buf *)
                    (* during second half of correlation-select we do not *)
                    (* search in primary tables (think of joins) but in the *)
                    (* result of the first half *)
                    WHILE ((qualpos <= qualend) AND (acv.a_returncode = 0)) DO
                        BEGIN
                        IF  (mb_st^[ qualpos ].etype in [ st_fixkey,
                            st_varkey, st_fixcol, st_varcol,
                            st_varlongchar ])
                        THEN
                            ak67col_stackentry (acv, dmli,
                                  mb_st^[ qualpos ]);
                        (*ENDIF*) 
                        qualpos := succ(qualpos)
                        END;
                    (*ENDWHILE*) 
&                   IFDEF TRACE
                    t01int4 (ak_sem, 'd_keylen   a', dmli.d_keylen);
                    t01int4 (ak_sem, 'd_inoutpos a', dmli.d_inoutpos);
&                   endif
                    tabno := starttabno;
                    (* PTS 1117747 E.Z. *)
                    IF  acv.a_cpart_type <> cpt_in_where_clause
                    THEN
                        ak67update_a67_nodes (acv, dmli, tabno,
                              (dmli.d_inoutpos - 1 - cgg_rec_key_offset - dmli.d_keylen)
                              - old_infolen, corrtab_buf);
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
&           IFDEF TRACE
            t01messblock (ak_sem, 'aux mblock: ', mblock_ptr^);
            t01name      (ak_sem, '====> a_mblock:   ');
            t01messblock   (ak_sem, 'corr_s amb 5', acv.a_mblock);
&           ENDIF
            IF  acv.a_returncode = 0
            THEN
                ak67second_qual_columns (acv, dmli, mblock_ptr^,
                      h_d_jcnt, fetch_keypos, fetch_keylen,
                      new_keypos, minkeylen, varkeyvaluestack,
                      qualpos, qualend);
            (* columns needed for qualification during second half *)
            (* of select as output in new mess_buf *)
&           IFDEF TRACE
            (*ENDIF*) 
            t01messblock (ak_sem, 'aux mblock: ', mblock_ptr^);
            t01name      (ak_sem, '====> a_mblock:   ');
            t01messblock   (ak_sem, 'corr_s amb 6', acv.a_mblock);
&           ENDIF
            IF  acv.a_returncode = 0
            THEN
                BEGIN
                IF  NOT(dmli.d_only_sem_check)
                THEN
                    BEGIN
&                   ifdef TRACE
                    t01int4 (ak_sem, 'corr_se lowp', 1);
&                   endif
                    IF  only_split
                    THEN
                        (* PTS 1117747 E.Z. *)
                        IF  predefined_pno > 0
                        THEN
                            (* having corr, when where has subquery, too *)
                            a660_lowpars_pparsp (acv, dmli.d_sparr.pparsp,
                                  c_first_parsinfo,
                                  NOT c_to_release, predefined_pno)
                        ELSE
                            a660_new_pparsp (acv, dmli.d_sparr,
                                  c_first_parsinfo, NOT c_complicate)
                        (*ENDIF*) 
                    ELSE
                        a660_lowpars_pparsp (acv, last_parsbuf,
                              c_first_parsinfo,
                              NOT c_to_release, dmli.d_lowpars);
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  acv.a_returncode = 0
                THEN
                    BEGIN
                    IF  ((NOT dmli.d_only_sem_check) AND (NOT only_split))
                    THEN
                        BEGIN
&                       ifdef TRACE
                        t01int4 (ak_sem, 'vor g10mv15 ', 1);
                        t01buf1 (ak_sem, dmli.d_sparr.pparsp^.syskey, 1,
                              dmli.d_sparr.pparsp^.syskey.sreclen);
                        t01buf1 (ak_sem, last_parsbuf^.syskey, 1, 16);
&                       endif
                        (* PTS 1109742 E.Z. *)
                        last_parsbuf^.sparsinfo.p_pars_header :=
                              dmli.d_sparr.pparsp^.sparsinfo.p_pars_header;
                        g10mv ('VAK67 ',   8,    
                              sizeof(dmli.d_sparr.pparsp^.sparsinfo.p_pars_infos),
                              sizeof(last_parsbuf^.sparsinfo.p_pars_infos),
                              @dmli.d_sparr.pparsp^.sparsinfo.p_pars_infos, 1,
                              @last_parsbuf^.sparsinfo.p_pars_infos, 1,
                              dmli.d_sparr.pparsp^.sparsinfo.p_cnt_infos *
                              sizeof(tak_field_pars),
                              acv.a_returncode);
                        dmli.d_sparr.pparsp^.sparsinfo.p_subcntlevel :=  - 1
                        END;
                    (*ENDIF*) 
                    ak67corfiletree (acv, dmli.d_level, part_res_tree,
                          only_having_columns_get OR only_split);
                    dmli.d_corr := no_correlation;
                    dmli.d_change.cr_colcount := 0; (* no dchange for first part *)
                    a67_sel2_second_part (acv, dmli, part_res_tree,
                          NOT c_is_not_corr_search,
                          NOT c_last_pars_part, NOT c_view_done,
                          sr_rec);
                    dmli.d_corr := correlation;
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  (acv.a_returncode = 0) AND NOT (dmli.d_only_sem_check)
            THEN
                BEGIN
&               ifdef TRACE
                t01int4 (ak_sem, 'fetch lowpar', 1);
&               endif
                (* PTS 1117747 E.Z. *)
                IF  predefined_pno > 0
                THEN
                    a660_lowpars_pparsp (acv, dmli.d_sparr.pparsp,
                          c_first_parsinfo,
                          NOT c_to_release, succ(predefined_pno))
                ELSE
                    a660_new_pparsp (acv, dmli.d_sparr,
                          NOT c_first_parsinfo, NOT c_complicate);
                (*ENDIF*) 
                IF  (acv.a_returncode = 0)
                THEN
                    BEGIN
                    a06a_mblock_init (acv,
                          m_fetch, mm_nil, b01niltree_id);
                    (* compare vak50 *)
                    (* correlated subquery result at coordinator always *)
                    g10mv ('VAK67 ',   9,    
                          sizeof(rtree), acv.a_mblock.mb_data_size, @rtree, 1,
                          @acv.a_mblock.mb_data^.mbp_buf, cgg_rec_key_offset + 1,
                          sizeof (rtree),
                          acv.a_returncode);
                    acv.a_mblock.mb_struct          := mbs_buf;
                    acv.a_mblock.mb_qual^.mcol_pos  := dmli.d_inoutpos - 1;
                    acv.a_mblock.mb_qual^.mcol_cnt  := dmli.d_filled_bytes-cgg_rec_key_offset;
                    acv.a_mblock.mb_qual^.mqual_pos := new_keypos;
                    acv.a_mblock.mb_qual^.mqual_cnt := dmli.d_keylen;
                    (* PTS 1117747 E.Z. *)
                    IF  predefined_pno > 0
                    THEN
                        acv.a_mblock.mb_qual^.mmult_pos := dmli.d_oldlowpars -
                              succ(predefined_pno)
                    ELSE
                        IF  only_split
                        THEN
                            acv.a_mblock.mb_qual^.mmult_pos := dmli.d_oldlowpars - dmli.d_lowpars
                        ELSE
                            IF  (dmli.d_where_subquery OR dmli.d_where_corr_subquery) AND
                                (dmli.d_having_corr_subquery)
                            THEN
                                acv.a_mblock.mb_qual^.mmult_pos :=
                                      (* compare ak660three_phase *)
                                      dmli.d_oldlowpars - 2 - dmli.d_lowpars + 1
                            ELSE
                                acv.a_mblock.mb_qual^.mmult_pos := dmli.d_oldlowpars - dmli.d_lowpars + 1;
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    acv.a_mblock.mb_qual^.mmult_cnt := h_d_rowno;
                    acv.a_mblock.mb_qual^.mview_pos := fetch_keypos;
                    acv.a_mblock.mb_qual^.mview_cnt := fetch_keylen;
                    acv.a_mblock.mb_qual^.mupd_pos  := varkeyvaluestack;
                    acv.a_mblock.mb_qual^.mupd_cnt  := minkeylen;
                    acv.a_mblock.mb_qual^.mlink_cnt := mblock_ptr^.mb_qual^.mlink_cnt;
                    acv.a_mblock.mb_qual^.mstrat_pos:= h_d_reclen;
                    acv.a_mblock.mb_qual^.mstrat_cnt:= h_d_reclen -
                          cgg_rec_key_offset - h_d_keylen;
                    acv.a_mblock.mb_data_len        := sizeof(rtree) +
                          cgg_rec_key_offset;
                    dmli.d_sparr.pparsp^.sparsinfo.p_mtyp := m_fetch;
                    (* PTS 1117747 E.Z. *)
                    IF  predefined_pno > 0
                    THEN
                        dmli.d_sparr.pparsp^.sparsinfo.p_p_no := dmli.d_oldlowpars -
                              succ(predefined_pno)
                    ELSE
                        IF  only_split
                        THEN
                            dmli.d_sparr.pparsp^.sparsinfo.p_p_no := dmli.d_oldlowpars -
                                  dmli.d_lowpars
                        ELSE
                            dmli.d_sparr.pparsp^.sparsinfo.p_p_no := dmli.d_oldlowpars -
                                  dmli.d_lowpars + 1;
                        (*ENDIF*) 
                    (*ENDIF*) 
&                   ifdef TRACE
                    t01int4 (ak_sem, 'oldlowpars  ', dmli.d_oldlowpars);
                    t01int4 (ak_sem, 'd_lowpars   ', dmli.d_lowpars);
                    t01int4 (ak_sem, 'p_p_no      ',
                          dmli.d_sparr.pparsp^.sparsinfo.p_p_no);
&                   endif
                    a54_store_parsinfo (acv, dmli.d_sparr);
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    h_d_sparr := dmli.d_sparr;
    END;
(*ENDIF*) 
IF  (NOT only_having_columns_get) AND (aux_mblock.mb_qual <> NIL) AND
    (aux_mblock.mb_data <> NIL) AND (aux_mblock.mb_st <> NIL) AND
    (mblock_ptr <> NIL)
THEN
    WITH acv.a_mblock DO
        BEGIN
        aux_mblock.mb_st       := old_st_addr;
        aux_mblock.mb_data_len := 0;
        a06cpy_mblock (acv, mblock_ptr^, aux_mblock, NOT c_without_data, b_err);
        IF  b_err <> e_ok
        THEN
            a07_b_put_error (acv, b_err, 1)
        ELSE
            BEGIN
            mb_header := aux_mblock.mb_header;
            p_dmli_ptr  := @dmli;
            p_dmli_ptr^ := p_h_dmli;
            dmli.d_tabarr             := h_d_tabarr;
            dmli.d_sparr              := h_d_sparr;
            dmli.d_rowno              := h_d_rowno;
            dmli.d_filled_bytes       := h_d_filled_bytes;
            dmli.d_joins.jrc_cnt         := h_d_jcnt;
            dmli.d_change.cr_colcount := h_d_changecnt
            END;
        (*ENDIF*) 
        IF  ((acv.a_returncode = 0) AND to_split)
        THEN
            WITH dmli DO
                BEGIN
                IF  NOT only_having_columns_get AND
                    (NOT only_split)
                THEN
                    BEGIN
                    d_lowpars      := d_lowpars - 1;
                    d_sparr.pparsp := last_parsbuf
                    END
                ELSE
                    d_sparr.pparsp := NIL;
                (*ENDIF*) 
                d_maxcounttabs := 1;
                d_cntfromtab   := 1;
                d_acttabindex  := 1;
                IF  mb_type in [ m_update, m_delete ]
                THEN
                    BEGIN
                    mb_type2 := mm_qual;
                    WITH d_tabarr[ d_acttabindex ] DO
                        IF  (oview AND oviewqual AND oviewcheck AND
                            (mb_type = m_update))
                        THEN
                            BEGIN
                            mb_qual^.mview_pos := 0;
                            mb_qual^.mview_cnt := 0;
                            IF  acv.a_ex_kind = only_parsing
                            THEN
                                a54_fixedpos (acv, dmli);
                            (*ENDIF*) 
                            a54_view_put_into (acv, dmli);
                            END;
                        (*ENDIF*) 
                    (*ENDWITH*) 
                    END
                ELSE
                    BEGIN
                    WITH mb_qual^.mtree DO
                        BEGIN
                        fileTfn_gg00     := tfnTemp_egg00;
                        fileTfnTemp_gg00 := ttfnCorrelation_egg00
                        END;
                    (*ENDWITH*) 
                    WITH d_tabarr[ 1 ] DO
                        BEGIN
                        otreeid      := part_res_tree;
                        ospecialname := ospecialname + [ oresfile ]
                        END
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
                END
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  mblock_ptr <> NIL
THEN
    BEGIN
    IF  mblock_ptr^.mb_st <> NIL
    THEN
        a10dispose (acv, mblock_ptr^.mb_st);
    (*ENDIF*) 
    mblock_ptr^.mb_st := NIL;
    pseudo_stack_list_ptr.mblock := mblock_ptr;
    a10dispose (acv, pseudo_stack_list_ptr.stack)
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_fetchkeys (
            VAR acv   : tak_all_command_glob;
            ppoint    : tak_sysbufferaddress;
            recmaxlen : integer;
            invmaxlen : integer);
 
VAR
      _lc2 : tsp_int_map_c2;
      _i   : integer;
 
BEGIN
&ifdef TRACE
t01int4 (ak_sem, 'recmaxlen   ', recmaxlen);
t01int4 (ak_sem, 'invmaxlen   ', invmaxlen);
&endif
ppoint^.sreskey.res_searched_pages := acv.a_mblock.mb_qual^.mr_pagecnt;
WITH ppoint^.sreskey.res_startkeys.reckeyspec DO
    BEGIN
    _i := 1;
    _lc2.map_c2[ 1 ] := acv.a_mblock.mb_data^.mbp_buf [_i];
    _lc2.map_c2[ 2 ] := acv.a_mblock.mb_data^.mbp_buf [_i + 1];
    ks_len := _lc2.map_int;
    IF  ks_len > recmaxlen
    THEN
        ks_len := recmaxlen;
    (*ENDIF*) 
    g10mv ('VAK67 ',  10,    
          acv.a_mblock.mb_data_size, sizeof(ppoint^.sreskey.res_keysbuf),
          @acv.a_mblock.mb_data^.mbp_buf, _i + 2,
          @ppoint^.sreskey.res_keysbuf, ks_pos, ks_len,
          acv.a_returncode);
    _i := _i + 2 + _lc2.map_int;
&   ifdef trace
    t01sname(ak_sem, 'res_startk r');
    t01moveobj(ak_sem, ppoint^.sreskey.res_keysbuf, ks_pos, ks_len);
&   endif
    END;
(*ENDWITH*) 
IF  acv.a_returncode = 0
THEN
    WITH ppoint^.sreskey.res_nextkeys.reckeyspec DO
        BEGIN
        _lc2.map_c2[ 1 ] := acv.a_mblock.mb_data^.mbp_buf[ _i ];
        _lc2.map_c2[ 2 ] := acv.a_mblock.mb_data^.mbp_buf[ _i + 1 ];
        ks_len := _lc2.map_int;
        IF  ks_len > recmaxlen
        THEN
            ks_len := recmaxlen;
        (*ENDIF*) 
        g10mv ('VAK67 ',  11,    
              acv.a_mblock.mb_data_size, sizeof(ppoint^.sreskey.res_keysbuf),
              @acv.a_mblock.mb_data^.mbp_buf, _i + 2,
              @ppoint^.sreskey.res_keysbuf, ks_pos, ks_len,
              acv.a_returncode);
        _i := _i + 2 + _lc2.map_int;
&       ifdef trace
        t01sname(ak_sem, 'res_nextk  r');
        t01moveobj(ak_sem, ppoint^.sreskey.res_keysbuf, ks_pos, ks_len);
&       endif
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    WITH ppoint^.sreskey.res_stopkeys.reckeyspec DO
        BEGIN
        _lc2.map_c2[ 1 ] := acv.a_mblock.mb_data^.mbp_buf[ _i ];
        _lc2.map_c2[ 2 ] := acv.a_mblock.mb_data^.mbp_buf[ _i + 1 ];
        ks_len := _lc2.map_int;
        IF  ks_len > recmaxlen
        THEN
            ks_len := recmaxlen;
        (*ENDIF*) 
        g10mv ('VAK67 ',  12,    
              acv.a_mblock.mb_data_size, sizeof(ppoint^.sreskey.res_keysbuf),
              @acv.a_mblock.mb_data^.mbp_buf, _i + 2,
              @ppoint^.sreskey.res_keysbuf, ks_pos, ks_len,
              acv.a_returncode);
        _i := _i + 2 + _lc2.map_int;
&       ifdef trace
        t01sname(ak_sem, 'res_stopk  r');
        t01moveobj(ak_sem, ppoint^.sreskey.res_keysbuf, ks_pos, ks_len);
&       endif
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    WITH ppoint^.sreskey.res_startkeys.listkeyspec DO
        BEGIN
        _lc2.map_c2[ 1 ] := acv.a_mblock.mb_data^.mbp_buf[ _i ];
        _lc2.map_c2[ 2 ] := acv.a_mblock.mb_data^.mbp_buf[ _i + 1 ];
        ks_len := _lc2.map_int;
        IF  ks_len > invmaxlen
        THEN
            ks_len := invmaxlen;
        (*ENDIF*) 
        g10mv ('VAK67 ',  13,    
              acv.a_mblock.mb_data_size, sizeof(ppoint^.sreskey.res_keysbuf),
              @acv.a_mblock.mb_data^.mbp_buf, _i + 2,
              @ppoint^.sreskey.res_keysbuf, ks_pos, ks_len,
              acv.a_returncode);
        _i := _i + 2 + _lc2.map_int;
&       ifdef trace
        t01sname(ak_sem, 'res_startk l');
        t01moveobj(ak_sem, ppoint^.sreskey.res_keysbuf, ks_pos, ks_len);
&       endif
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    WITH ppoint^.sreskey.res_nextkeys.listkeyspec DO
        BEGIN
        _lc2.map_c2[ 1 ] := acv.a_mblock.mb_data^.mbp_buf[ _i ];
        _lc2.map_c2[ 2 ] := acv.a_mblock.mb_data^.mbp_buf[ _i + 1 ];
        ks_len := _lc2.map_int;
        IF  ks_len > invmaxlen
        THEN
            ks_len := invmaxlen;
        (*ENDIF*) 
        g10mv ('VAK67 ',  14,    
              acv.a_mblock.mb_data_size, sizeof(ppoint^.sreskey.res_keysbuf),
              @acv.a_mblock.mb_data^.mbp_buf, _i + 2,
              @ppoint^.sreskey.res_keysbuf, ks_pos, ks_len,
              acv.a_returncode);
        _i := _i + 2 + _lc2.map_int;
&       ifdef trace
        t01sname(ak_sem, 'res_nextk  l');
        t01moveobj(ak_sem, ppoint^.sreskey.res_keysbuf, ks_pos, ks_len);
&       endif
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    WITH ppoint^.sreskey.res_stopkeys.listkeyspec DO
        BEGIN
        _lc2.map_c2[ 1 ] := acv.a_mblock.mb_data^.mbp_buf[ _i ];
        _lc2.map_c2[ 2 ] := acv.a_mblock.mb_data^.mbp_buf[ _i + 1 ];
        ks_len := _lc2.map_int;
        IF  ks_len > invmaxlen
        THEN
            ks_len := invmaxlen;
        (*ENDIF*) 
        g10mv ('VAK67 ',  15,    
              acv.a_mblock.mb_data_size, sizeof(ppoint^.sreskey.res_keysbuf),
              @acv.a_mblock.mb_data^.mbp_buf, _i + 2,
              @ppoint^.sreskey.res_keysbuf, ks_pos, ks_len,
              acv.a_returncode);
        _i := _i + 2 + _lc2.map_int;
&       ifdef trace
        t01sname(ak_sem, 'res_stopk  l');
        t01moveobj(ak_sem, ppoint^.sreskey.res_keysbuf, ks_pos, ks_len);
&       endif
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    g10mv ('VAK67 ',  16,    
          acv.a_mblock.mb_data_size, sizeof(ppoint^.sreskey.res_treeids.file_id),
          @acv.a_mblock.mb_data^.mbp_buf, _i,
          @ppoint^.sreskey.res_treeids.file_id, 1, sizeof(ppoint^.sreskey.res_treeids.file_id),
          acv.a_returncode);
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    g10mv ('VAK67 ',  17,    
          acv.a_mblock.mb_data_size, sizeof(ppoint^.sreskey.res_treeids.inv_id),
          @acv.a_mblock.mb_data^.mbp_buf, _i + sizeof(ppoint^.sreskey.res_treeids.file_id),
          @ppoint^.sreskey.res_treeids.inv_id, 1, sizeof(ppoint^.sreskey.res_treeids.inv_id),
          acv.a_returncode);
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    BEGIN
&   ifdef trace
    t01name(ak_sem, 'res_next -> res_pr');
&   endif
    a74_copy_twokeys (acv,
          ppoint^.sreskey.res_keysbuf,
          ppoint^.sreskey.res_nextkeys,
          ppoint^.sreskey.res_prevkeys,
          ppoint^.sreskey.res_resstate);
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_first_corr (
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info);
 
VAR
      b_err          : tgg00_BasisError;
      m_distinct     : tgg04_Distinct;
      all_corfields  : tak_corfields;
      new_useful_arr : tak67_cuseful_arr;
      i              : integer;
      j              : integer;
      start_sub_node : integer;
      subquery_node  : integer;
      curr_tab_cnt   : integer;
      corrtab_buf    : tak_sysbufferaddress;
      ke             : tgg00_SysInfoKey;
      all_cortabs    : tak_cortables;
 
BEGIN
m_distinct := dmli.d_distinct;
FOR i := 1 TO cak67_maxcortables DO
    new_useful_arr[ i ] := false;
(*ENDFOR*) 
all_cortabs.cused_tabs     := 0;
all_cortabs.clast_used     := 0;
all_corfields.cused_fields := 0;
FOR i := 1 TO cak_maxcorcolumns DO
    BEGIN
    all_corfields.cfields[ i ].clevel[ 1 ] := 1;
    all_corfields.cfields[ i ].csetnode    := 0;
    all_corfields.cfields[ i ].cnode       := 0;
    all_corfields.cfields[ i ].ccntcol     := 0;
    FOR j := 2 TO cak_maxcorlevel DO
        all_corfields.cfields[ i ].clevel[ j ] := 0;
    (*ENDFOR*) 
    all_corfields.cfields[ i ].ccmd_part   := cpt_in_where_clause;
    END;
(*ENDFOR*) 
dmli.d_wherepart := true;
ak67from_part_to_cortabs (acv, dmli, all_cortabs, new_useful_arr, 0);
subquery_node := acv.a_select_node;
IF  (acv.a_ap_tree^[ subquery_node ].n_proc     = a92fromsel) AND
    (acv.a_ap_tree^[ subquery_node ].n_lo_level > 0)
THEN
    start_sub_node := acv.a_ap_tree^[ subquery_node ].n_lo_level
ELSE
    IF  (acv.a_ap_tree^[ subquery_node ].n_sa_level > 0)
    THEN
        start_sub_node := acv.a_ap_tree^[ subquery_node ].n_sa_level
    ELSE
        start_sub_node := acv.a_ap_tree^[ subquery_node ].n_lo_level;
    (*ENDIF*) 
(*ENDIF*) 
curr_tab_cnt   := dmli.d_cntfromtab;
ak67fill_cortabs (acv, dmli, all_cortabs, all_corfields,
      new_useful_arr, start_sub_node, 2, 1, all_cortabs.cused_tabs);
IF  acv.a_returncode = 0
THEN
    a10rel_sysinfo (dmli.d_sparr.pbasep);
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    IF  acv.a_ap_tree^[ acv.a_ap_tree^[ 0 ].n_lo_level ].n_proc in [ a57, a58 ]
        (* update, delete *)
    THEN
        WITH dmli DO
            BEGIN
            d_acttabindex                 := 1;
            d_cntfromtab                 := 1;
            d_tabarr[ 1 ].ocounttabs := 0;
            d_maxcounttabs        := 0;
            subquery_node     := acv.a_ap_tree^[ subquery_node ].n_lo_level;
            a660_search_one_table (acv, dmli,
                  acv.a_ap_tree^[ subquery_node ].n_lo_level,
                  c_all, c_check_teresult, no_lock, r_sel);
            END
        (*ENDWITH*) 
    ELSE
        BEGIN
        IF  (acv.a_ap_tree^[ subquery_node ].n_proc = a92fromsel)
        THEN
            BEGIN
            subquery_node := acv.a_ap_tree^[ subquery_node ].n_pos;
            subquery_node := acv.a_ap_tree^[ subquery_node ].n_lo_level;
            END;
        (*ENDIF*) 
        subquery_node := acv.a_ap_tree^[ subquery_node ].n_lo_level;
        IF  (acv.a_ap_tree^[ subquery_node ].n_proc = a63) AND
            (acv.a_ap_tree^[ subquery_node ].n_subproc  = cak_x_distinct)
        THEN
            subquery_node := acv.a_ap_tree^[ subquery_node ].n_lo_level;
        (*ENDIF*) 
        IF  (acv.a_ap_tree^[ subquery_node ].n_proc <> a60) OR
            (acv.a_ap_tree^[ subquery_node ].n_subproc  <> cak_x_select_list)
        THEN
            (* resulttablename found *)
            subquery_node := acv.a_ap_tree^[ subquery_node ].n_sa_level;
        (*ENDIF*) 
        subquery_node := acv.a_ap_tree^[ subquery_node ].n_sa_level;
        IF  (acv.a_ap_tree^[ subquery_node ].n_proc = a60) AND
            (acv.a_ap_tree^[ subquery_node ].n_subproc  = cak_x_single_select)
        THEN
            subquery_node := acv.a_ap_tree^[ subquery_node ].n_sa_level;
        (*ENDIF*) 
        IF  (acv.a_ap_tree^[ subquery_node ].n_proc = a66) AND
            (acv.a_ap_tree^[ subquery_node ].n_subproc  = cak_x_given_sequence)
        THEN
            subquery_node := acv.a_ap_tree^[ subquery_node ].n_sa_level;
        (*ENDIF*) 
        a660_from_part (acv, dmli, subquery_node)
        END;
    (*ENDIF*) 
(*ENDIF*) 
dmli.d_distinct := m_distinct;
IF  acv.a_returncode = 0
THEN
    BEGIN
    WITH ke DO
        BEGIN
        ke           := a01sysnullkey;
        sauthid[ 1 ] := cak_tempinfo_byte;
        g10mv ('VAK67 ',  18,    
              sizeof(acv.a_pars_last_key), sizeof(sauthid),
              @acv.a_pars_last_key, 1, @sauthid, 2, mxak_parskey,
              acv.a_returncode);
        acv.a_corr_key   := acv.a_pars_last_key;
        sauthid[ mxak_parskey + 1 ] := chr(0);
        sentrytyp                  := cak_ecorrinfo;
        END;
    (*ENDWITH*) 
    a10_nil_get_sysinfo (acv, ke, d_release,
          mxak_correc + cak_sysbufferoffset, corrtab_buf, b_err);
    IF  b_err <> e_ok
    THEN
        a07_b_put_error (acv, b_err, 1)
    ELSE
        WITH corrtab_buf^, scorr, all_cortabs, all_corfields DO
            BEGIN
            tc_no_of_tables := 0;
            FOR i := 1 TO cused_tabs DO
                WITH corrtab_buf^, scorr, all_cortabs, all_corfields DO
                    IF  cortabs[ i ].ocfields > 0
                    THEN
                        IF  tc_no_of_tables = cak00_maxsources
                        THEN
                            a07_b_put_error (acv, e_too_many_corr_tables, 1)
                        ELSE
                            BEGIN
                            tc_no_of_tables := succ(tc_no_of_tables);
&                           ifdef TRACE
                            t01int4 (ak_sem, 'tc_no_of_tab', tc_no_of_tables);
&                           ENDIF
                            WITH tc_tables[ tc_no_of_tables ],
                                 cortabs[ i ] DO
                                BEGIN
                                socoldtabno    := i;
                                socselecttabno := octabno;
                                socfields      := ocfields
                                END
                            (*ENDWITH*) 
                            END;
                        (*ENDIF*) 
&                   ifdef TRACE
                    (*ENDIF*) 
                (*ENDWITH*) 
            (*ENDFOR*) 
            t01int4 (ak_sem, 'ocfields    ', cortabs[ i ].ocfields);
&           ENDIF
            tc_starttable    := 1;
            tc_oldstarttable := 1;
            IF  acv.a_returncode = 0
            THEN
                BEGIN
                tc_no_of_columns := cused_fields;
                g10mv ('VAK67 ',  19,    
                      sizeof(cfields), sizeof(tc_columns),
                      @cfields, 1, @tc_columns, 1,
                      mxak_one_corcolumn*cused_fields,
                      acv.a_returncode);
                b_sl := mxak_correc + cak_sysbufferoffset -
                      (cak_maxcorcolumns - cused_fields) * 4;
                a10add_sysinfo (acv, corrtab_buf, b_err);
                IF  b_err = e_ok
                THEN
                    a10_rel_sysinfo (acv, corrtab_buf^.syskey)
                ELSE
                    a07_b_put_error (acv, b_err, 1)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDWITH*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_keyspecs (
            VAR reskeyrec : tak_sysbufferaddress;
            primlen     : integer;
            invlen      : integer);
 
BEGIN
reskeyrec^.sreskey.res_startkeys.reckeyspec.ks_len := 0;
reskeyrec^.sreskey.res_startkeys.listkeyspec.ks_len:= 0;
reskeyrec^.sreskey.res_stopkeys.reckeyspec.ks_len  := primlen;
reskeyrec^.sreskey.res_stopkeys.listkeyspec.ks_len := 0;
reskeyrec^.sreskey.res_nextkeys.listkeyspec.ks_len := 0;
reskeyrec^.sreskey.res_nextkeys.reckeyspec.ks_len  := 0;
reskeyrec^.sreskey.res_prevkeys.listkeyspec.ks_len := 0;
reskeyrec^.sreskey.res_prevkeys.reckeyspec.ks_len  := 0;
reskeyrec^.sreskey.res_startkeys.reckeyspec.ks_pos :=
      4 + reskeyrec^.sreskey.res_change.cr_colcount * mxak_change_colinfo + 1;
reskeyrec^.sreskey.res_startkeys.listkeyspec.ks_pos:=
      reskeyrec^.sreskey.res_startkeys.reckeyspec.ks_pos + primlen;
reskeyrec^.sreskey.res_stopkeys.reckeyspec.ks_pos  :=
      reskeyrec^.sreskey.res_startkeys.listkeyspec.ks_pos + invlen;
reskeyrec^.sreskey.res_stopkeys.listkeyspec.ks_pos :=
      reskeyrec^.sreskey.res_stopkeys.reckeyspec.ks_pos + primlen;
reskeyrec^.sreskey.res_nextkeys.reckeyspec.ks_pos :=
      reskeyrec^.sreskey.res_stopkeys.listkeyspec.ks_pos + invlen;
reskeyrec^.sreskey.res_nextkeys.listkeyspec.ks_pos :=
      reskeyrec^.sreskey.res_nextkeys.reckeyspec.ks_pos + primlen;
reskeyrec^.sreskey.res_prevkeys.reckeyspec.ks_pos :=
      reskeyrec^.sreskey.res_nextkeys.listkeyspec.ks_pos + invlen;
reskeyrec^.sreskey.res_prevkeys.listkeyspec.ks_pos :=
      reskeyrec^.sreskey.res_prevkeys.reckeyspec.ks_pos + primlen;
reskeyrec^.sreskey.res_updkey.ks_pos :=
      reskeyrec^.sreskey.res_prevkeys.listkeyspec.ks_pos + invlen;
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_put_all_views_into (
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info);
 
VAR
      first     : boolean;
      htabindex : integer;
      i         : integer;
      j         : integer;
 
BEGIN
first     := true;
htabindex := dmli.d_acttabindex;
i         := 1;
WHILE (i <= dmli.d_cntfromtab) AND (acv.a_returncode = 0) DO
    BEGIN
    WITH dmli.d_tabarr[ i ] DO
        IF  oview AND oviewqual
        THEN
            BEGIN
            IF  first
            THEN
                BEGIN
                first := false;
                IF  ( acv.a_ex_kind = only_parsing )
                THEN
                    a54_fixedpos( acv, dmli );
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            dmli.d_acttabindex := i;
            IF  i = dmli.d_cntfromtab
            THEN
                j := dmli.d_maxcounttabs - ocounttabs
            ELSE
                j := dmli.d_tabarr[ i+1 ].ocounttabs - ocounttabs;
            (*ENDIF*) 
            (* j = bv_tabcount of current table *)
            IF  ((j > 1) AND (acv.a_ex_kind <> only_executing))
            THEN
                (* error no 241 *)
                htabindex := dmli.d_acttabindex;
            (*ENDIF*) 
            a54_view_put_into( acv, dmli );
            END;
        (*ENDIF*) 
    (*ENDWITH*) 
    i := succ( i );
    END;
(*ENDWHILE*) 
a61_rel_old_table( acv, dmli, htabindex );
dmli.d_acttabindex := htabindex;
IF  ( acv.a_returncode = 0 )
THEN
    BEGIN
    IF  (dmli.d_maxcounttabs > 1) AND
        (acv.a_mblock.mb_data_len < acv.a_mblock.mb_data_size)
    THEN
        IF  ( acv.a_mblock.mb_data^.mbp_buf[ acv.a_mblock.mb_data_len ] <>
            csp_undef_byte )
        THEN
            BEGIN
            (* join usually needs NULL-value for *)
            (* its is-not-null qualifications    *)
            acv.a_mblock.mb_data_len := succ( acv.a_mblock.mb_data_len );
            acv.a_mblock.mb_data^.mbp_buf[ acv.a_mblock.mb_data_len ] :=
                  csp_undef_byte;
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_s_sel_second_part (
            VAR acv        : tak_all_command_glob;
            VAR dmli       : tak_dml_info;
            VAR select_rec : tak_select_record;
            VAR sr_rec     : tak70_strat_rec);
 
VAR
      old_d_distinct  : tgg04_Distinct;
      old_d_use_order : boolean;
      b_err           : tgg00_BasisError;
 
BEGIN
&ifdef TRACE
t01bool (ak_sem, 'sel_where_do', select_rec.sel_where_done);
t01bool (ak_sem, 'd_use_order ', dmli.d_use_order );
t01bool (ak_sem, 'd_subquery  ', dmli.d_subquery  );
t01bool (ak_sem, 'sel_is_not_c', select_rec.sel_is_not_corr_search);
t01bool (ak_sem, 'sel_view_don', select_rec.sel_view_done);
t01bool (ak_sem, 'd_onlysemchk', dmli.d_only_sem_check);
&endif
ak67sel1_second_part( acv, dmli, select_rec.sel_where_done,
      acv.a_ap_tree^[ select_rec.sel_from_n ].n_sa_level );
old_d_distinct := dmli.d_distinct;
IF  (select_rec.sel_new_atdistinct <> no_distinct) AND
    (old_d_distinct = no_distinct)
THEN
    BEGIN
    old_d_use_order          := dmli.d_use_order;
    dmli.d_distinct          := select_rec.sel_new_atdistinct;
    dmli.d_use_order         := true;
    sr_rec.sr_distinct_bytes := false;
    END;
(*ENDIF*) 
IF  ( dmli.d_subquery )
THEN
    a67_sel2_second_part( acv, dmli, select_rec.sel_res_tree,
          select_rec.sel_is_not_corr_search,
          NOT c_last_pars_part, select_rec.sel_view_done, sr_rec )
ELSE
    a67_sel2_second_part( acv, dmli, select_rec.sel_res_tree,
          select_rec.sel_is_not_corr_search,
          select_rec.sel_last_pars_part, select_rec.sel_view_done, sr_rec );
(*ENDIF*) 
IF  (select_rec.sel_new_atdistinct <> no_distinct) AND
    (old_d_distinct = no_distinct)
THEN
    BEGIN
    dmli.d_distinct          := old_d_distinct;
    dmli.d_use_order         := old_d_use_order;
    sr_rec.sr_distinct_bytes := true;
    END;
&IFDEF TRACE
(*ENDIF*) 
t01int4 (ak_sem, 'acvfromsel_n', acv.a_fromsel_n);
t01int4 (ak_sem, 'acv_unioncnt', acv.a_union_cnt);
t01bool (ak_sem, 'd_view      ', dmli.d_view);
&ENDIF
IF  (NOT dmli.d_only_sem_check) AND
    ((acv.a_union_cnt <= 1) OR
    ((acv.a_union_cnt > 1) AND
    ((acv.a_returncode      = cak_e_corelated_subquery_not_allowed) OR
    ( acv.a_main_returncode = cak_e_corelated_subquery_not_allowed))))
THEN
    a67_sel3_second_part( acv, dmli, select_rec, sr_rec )
ELSE
    IF  (dmli.d_only_sem_check                   AND
        (acv.a_from_select                    OR
        ((acv.a_fromsel_n > 0)            AND
        ( dmli.d_corr = first_correlation)   )  )   ) OR
        (acv.a_recursive_state = rs_first_select)     OR
        a661_is_fromsel_table (acv, select_rec.sel_res_tree)
    THEN
        BEGIN
        a67_bextcolindex( dmli.d_esparr, dmli.d_outcolno );
        a10add_sysinfo ( acv, dmli.d_esparr.pbasep, b_err );
        IF  ( b_err <> e_ok )
        THEN
            a07_b_put_error( acv, b_err, 1 );
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_sel2_second_part (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR res_tree       : tgg00_FileId;
            is_not_corr_search : boolean;
            last_pars_part     : boolean;
            view_done          : boolean;
            VAR sr_rec         : tak70_strat_rec);
 
VAR
      must_result     : boolean;
      store_parsinfos : boolean;
      h_cpt           : tak_cmd_part_type;
      dummy_tabno     : integer;
      dummy_infolen   : integer;
      gg_strategy_ptr : ^tgg07_StrategyInfo;
      jvrec           : tak68_joinview_rec;
 
BEGIN
IF  ((acv.a_returncode = 0) AND NOT view_done)
THEN
    a67_put_all_views_into( acv, dmli );
(*ENDIF*) 
IF  ((acv.a_returncode = 0) AND NOT dmli.d_view) AND
    ((dmli.d_pos_result = cak_extern_pos) OR
    ( dmli.d_pos_result = cak_intern_pos))
THEN
    acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resstate :=
          acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resstate +
          [ rs_result ];
&IFDEF TRACE
(*ENDIF*) 
t01messblock( ak_sem, 'sel2_second1', acv.a_mblock );
t01bool( ak_sem, 'acv_from_sel', acv.a_from_select );
t01corr_type( ak_sem, ' first_corr?', dmli.d_corr );
&ENDIF
IF  (dmli.d_corr = first_correlation) AND
    (NOT acv.a_from_select)
THEN
    a67_first_corr (acv, dmli);
(*ENDIF*) 
IF  ((dmli.d_corr in [ first_correlation, correlation ]) AND
    (acv.a_returncode = 0)) AND
    (NOT acv.a_from_select)
THEN
    BEGIN
    h_cpt      := acv.a_cpart_type;
    acv.a_cpart_type := cpt_in_where_clause;
    (* PTS 1117747 E.Z. *)
    a660set_subq_info (acv, dmli);
    IF  acv.a_mblock.mb_type2 = mm_with_functions
    THEN
        a07_b_put_error( acv, e_not_implemented, 1 );
    (*ENDIF*) 
    IF  ( acv.a_returncode = 0 )
    THEN
        a67_corr_search( acv, dmli, NOT c_only_having_columns_get,
              dummy_tabno, NOT c_only_split, c_no_predefined_pno, dummy_infolen, res_tree );
    (*ENDIF*) 
    acv.a_cpart_type := h_cpt;
    END;
(*ENDIF*) 
IF  ( acv.a_returncode = 0 ) AND
    ( NOT( dmli.d_only_sem_check ))
THEN
    IF  ( dmli.d_maxcounttabs > 1 )
    THEN
        BEGIN
        sr_rec.sr_strategy := strat_key_range;
        jvrec.jv_tabid      := b01niltree_id.fileTabId_gg00;
        jvrec.jv_maxkeyl    := 0;
        a680_join( acv, dmli, res_tree, sr_rec, last_pars_part, jvrec );
        END
    ELSE
        BEGIN
        IF  oresfile in dmli.d_tabarr[ dmli.d_acttabindex ].ospecialname
        THEN
            IF  (dmli.d_tabarr[ dmli.d_acttabindex ].otreeid.fileTfnTemp_gg00 =
                ttfnCorrelation_egg00) AND
                (dmli.d_tabarr[ dmli.d_acttabindex ].otreeid.fileTfn_gg00     =
                tfnTemp_egg00)
            THEN
                BEGIN
                IF  acv.a_mblock.mb_type2 = mm_with_join
                THEN
                    acv.a_mblock.mb_type2 := mm_nil;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        must_result := false;
        IF  dmli.d_reuse                                      OR
            NOT is_not_corr_search                            OR
            dmli.d_subquery                                   OR
            dmli.d_union                                      OR
            acv.a_insert_select                               OR
            (acv.a_recursive_state <> rs_no_recursive_select) OR
            (dmli.d_corr <> no_correlation)                   OR
            (acv.a_mblock.mb_type2 = mm_with_functions)       OR
            (acv.a_max_intern_select > 0)                     OR
            (acv.a_mblock.mb_type = m_show)
        THEN
            must_result := true
        ELSE
            IF  ((dmli.d_pos_result = cak_extern_pos) OR
                ( dmli.d_pos_result = cak_intern_pos))
            THEN
                IF  rs_nobase in
                    acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resstate
                THEN
                    must_result := true;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        IF  ( NOT dmli.d_pseudo_ins_select ) OR dmli.d_subquery
        THEN
            BEGIN
            sr_rec.sr_must_result := must_result;
            a70_strategy_search( acv, dmli, res_tree, sr_rec );
            IF  NOT ( sr_rec.sr_strategy in a70glob_fetch_strats )
            THEN
                dmli.d_reuse := true;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        ;
&       IFDEF TRACE
        t01messblock( ak_sem, 'sel2_second2', acv.a_mblock );
&       ENDIF
        IF  ( acv.a_returncode = 0 )
        THEN
            BEGIN
&           ifdef TRACE
            t01int4 (ak_sem, 'pseudoinssel', ord(dmli.d_pseudo_ins_select));
            t01int4 (ak_sem, 'd_subquery  ', ord(dmli.d_subquery));
&           endif
            store_parsinfos := ( NOT dmli.d_pseudo_ins_select )
                  OR dmli.d_subquery;
            IF  ( acv.a_insert_select )
                AND
                ( acv.a_intern_select_cnt = acv.a_max_intern_select )
                AND
                ( acv.a_union_cnt = 0 )
                AND
                ( dmli.d_corr = no_correlation )
                AND
                ( NOT dmli.d_subquery )
                AND
                ( NOT acv.a_from_select )
                AND
                ( NOT dmli.d_pseudo_ins_select)
            THEN
                IF  ( acv.a_mblock.mb_type2 <> mm_with_functions )
                THEN
                    BEGIN
                    gg_strategy_ptr := @acv.a_mblock.mb_strat^[
                          acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mstrat_pos ].epos ];
                    IF  (( gg_strategy_ptr^.str_distinc = no_distinct )
                        AND
                        ( NOT gg_strategy_ptr^.str_use_rowno )
                        AND
                        ( gg_strategy_ptr^.str_qual_kind <> inv_only )
                        AND
                        (( gg_strategy_ptr^.str_result_id.fileTfn_gg00 <>
                        tfnTemp_egg00) OR
                        ( gg_strategy_ptr^.str_result_id.fileTfnTemp_gg00 <>
                        ttfnComplexSelect_egg00)))
                    THEN
                        BEGIN
                        WITH acv.a_mblock.mb_qual^.mtree DO
                            IF  NOT (( ftsTemp_egg00 in fileType_gg00 ) AND
                                ( fileTfn_gg00     = tfnTemp_egg00 ) AND
                                ( fileTfnTemp_gg00 <> ttfnTempTable_egg00 ) AND
                                ( fileTfnTemp_gg00 <> ttfnUserResult_egg00 ) AND
                                ( fileTfnTemp_gg00 <> ttfnGatewayResult_egg00 ))
                            THEN
                                store_parsinfos := false;
                            (*ENDIF*) 
                        (*ENDWITH*) 
                        END
                    ELSE
                        WITH acv.a_resname_addr[ cak_intern_pos ]^.sresname DO
                            IF  ( gg_strategy_ptr^.str_result_id.fileTfnTemp_gg00 =
                                ttfnInternResult_egg00 )
                            THEN
                                BEGIN
&                               IFDEF TRACE
                                t01treeid (ak_sem, 'restreeid =?', restreeid);
&                               ENDIF
                                restreeid.fileTfnTemp_gg00 := ttfnInternResult_egg00;
&                               IFDEF TRACE
                                t01treeid (ak_sem, 'restreeid =?', restreeid);
&                               ENDIF
                                gg_strategy_ptr^.str_result_id := restreeid;
                                END
                            (*ENDIF*) 
                        (*ENDWITH*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  ( store_parsinfos )
            THEN
                a54_select_last_part( acv, dmli, res_tree, last_pars_part );
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_sel3_second_part (
            VAR acv        : tak_all_command_glob;
            VAR dmli       : tak_dml_info;
            VAR select_rec : tak_select_record;
            VAR sr_rec     : tak70_strat_rec);
 
VAR
      _b_err            : tgg00_BasisError;
      _i                : integer;
      _aux_return       : tsp00_Int2;
      _aux_errorpos     : tsp00_Int4;
      _kb_return        : integer;
      _output_len       : integer;
      _res              : tsp00_NumError;
      _del_tree         : tgg00_FileId;
      _use_del_tree     : boolean;
      _lcol_found       : boolean;
      _lcol_lock        : boolean;
      _ke               : tgg00_SysInfoKey;
 
BEGIN
_kb_return     := acv.a_returncode;
_use_del_tree  := false;
&IFDEF TRACE
t01int4 (ak_sem, 'returncode1 ', acv.a_returncode);
t01recursive_state (ak_sem, 'recurs state', acv.a_recursive_state);
&ENDIF
IF  ((_kb_return = 0)
    AND
    ((dmli.d_pos_result <= cak_maxresulttables) OR
    ((dmli.d_pos_result = cak_intern_pos) AND
    (acv.a_qualified_jv_upd <> no_jv_upd)))
    AND
    (acv.a_ex_kind <> only_parsing)
    AND
    NOT dmli.d_only_sem_check)
THEN
    BEGIN
    IF  rs_result in acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resstate
    THEN
        BEGIN
        select_rec.sel_res_tree := acv.a_mblock.mb_qual^.mr_restree;
        acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.restreeid :=
              select_rec.sel_res_tree;
        END;
    (*ENDIF*) 
    IF  (NOT dmli.d_single AND select_rec.sel_is_not_corr_search)
    THEN
        IF  ((rs_intinvnoresult in
            acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resstate) AND
            ((acv.a_mblock.mb_trns^.trError_gg00 = e_ok) OR
            ( acv.a_mblock.mb_trns^.trError_gg00 = e_no_next_record)))
            AND (acv.a_mblock.mb_data_len  >= sizeof (_del_tree))
        THEN
            BEGIN
            g10mv ('VAK67 ',  20,    
                  acv.a_mblock.mb_data_size, sizeof(_del_tree),
                  @acv.a_mblock.mb_data^.mbp_buf,
                  acv.a_mblock.mb_data_len  + 1 - sizeof (_del_tree),
                  @_del_tree, 1, sizeof(_del_tree),
                  acv.a_returncode);
            _use_del_tree := true;
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    END;
&IFDEF TRACE
(*ENDIF*) 
t01int4 (ak_sem, 'returncode2 ', acv.a_returncode);
&ENDIF
IF  ((acv.a_returncode = 0)
    AND
    NOT dmli.d_single
    AND
    select_rec.sel_is_not_corr_search
    AND
    NOT (dmli.d_subquery)
    AND
    ((acv.a_intern_select_cnt = acv.a_max_intern_select) OR
    (acv.a_recursive_state = rs_first_select)    OR
    (acv.a_fromsel_n > 0)))
THEN
    BEGIN
&   ifdef trace
    t01sname( ak_sem, '------------' );
    FOR _i := dmli.d_esparr.pbasep^.sbase.bfirstindex TO
          dmli.d_esparr.pbasep^.sbase.blastindex DO
        a061td_colinfo (dmli.d_esparr.pbasep^.sbase.bcolumn[_i]^, _i);
    (*ENDFOR*) 
    t01sname( ak_sem, '------------' );
&   endif
    a67_bextcolindex( dmli.d_esparr, dmli.d_outcolno );
    dmli.d_esparr.pbasep^.sresult.bmaxreclen   := dmli.d_inoutpos - 1;
    dmli.d_esparr.pbasep^.sresult.blenfixedcol :=
          dmli.d_esparr.pbasep^.sresult.bmaxreclen - dmli.d_keylen -
          cgg_rec_key_offset;
    dmli.d_esparr.pbasep^.sresult.bavgrowlen   :=
          dmli.d_esparr.pbasep^.sresult.bmaxreclen;
    IF  ( acv.a_ex_kind <> only_parsing )
    THEN
        BEGIN
        s40g4int( acv.a_mblock.mb_qual^.mr_resnum, 2,
              dmli.d_esparr.pbasep^.sresult.brows, _res );
        IF  dmli.d_esparr.pbasep^.sresult.brows =  - 1 (* unknown *)
        THEN
            dmli.d_esparr.pbasep^.sresult.brows := cak_initrows
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  dmli.d_esparr.pbasep^.sresult.bmaxreclen > cak_page80percent
    THEN
        IF  dmli.d_esparr.pbasep^.sresult.brows = 0
        THEN
            dmli.d_esparr.pbasep^.sresult.bpages := 1
        ELSE
            dmli.d_esparr.pbasep^.sresult.bpages :=
                  dmli.d_esparr.pbasep^.sresult.brows
        (*ENDIF*) 
    ELSE
        dmli.d_esparr.pbasep^.sresult.bpages :=
              dmli.d_esparr.pbasep^.sresult.brows DIV
              (cak_page80percent DIV dmli.d_esparr.pbasep^.sresult.bmaxreclen) + 1;
    (*ENDIF*) 
&   ifdef trace
    t01sname( ak_sem, '------------' );
    FOR _i := dmli.d_esparr.pbasep^.sbase.bfirstindex TO
          dmli.d_esparr.pbasep^.sbase.blastindex DO
        a061td_colinfo (dmli.d_esparr.pbasep^.sbase.bcolumn[_i]^, _i);
    (*ENDFOR*) 
    t01sname( ak_sem, '------------' );
&   endif
    a06extcolno (dmli.d_esparr.pbasep^.sbase,
          dmli.d_esparr.pbasep^.sresult.bmaxcol, dmli.d_colbuf);
    _output_len := dmli.d_colbuf^.ccolstack.epos + dmli.d_colbuf^.cinoutlen - 1;
    _b_err := e_ok;
    _i     := 1;
    IF  (NOT acv.a_insert_select) OR (acv.a_fromsel_n > 0)
    THEN
        BEGIN
        IF  acv.a_intern_explain AND (acv.a_fromsel_n = 0)
            AND
            (acv.a_recursive_state in [ rs_last_select, rs_no_recursive_select])
        THEN
            BEGIN
            a10_key_del (acv, dmli.d_esparr.pbasep^.syskey);
&           ifdef trace
            dmli.d_esparr.pbasep := NIL;
&           endif
            END
        ELSE
            BEGIN
            a10add_sysinfo (acv, dmli.d_esparr.pbasep, _b_err);
            IF  ( acv.a_ex_kind = only_parsing )
            THEN
                BEGIN
                _ke              := a01sysnullkey;
                _ke.sauthid[ 1 ] := cak_tempinfo_byte;
                g10mv ('VAK67 ',  21,    
                      sizeof(acv.a_pars_last_key), sizeof(_ke.sauthid),
                      @acv.a_pars_last_key,
                      1, @_ke.sauthid, 2, mxak_parskey, _b_err);
                _ke.sauthid[ mxak_parskey + 1 ]:= chr(0);
                _ke.sentrytyp                  := cak_eresult;
                _ke.slinkage[ 2 ]              := chr( _i );
                IF  acv.a_pars_last_key.p_kind = m_union
                THEN
                    a10del_sysinfo (acv, _ke, _b_err);
                (*ENDIF*) 
                IF  (acv.a_fromsel_n = 0) AND (_b_err = e_ok)
                THEN
                    BEGIN
                    (* PTS 1106123 E.Z. *)
                    IF  acv.a_recursive_state <> rs_first_select
                    THEN
                        a10cpy_result (acv, dmli.d_esparr.pbasep^.syskey,
                              _ke, -1, _b_err);
                    (*ENDIF*) 
                    IF  (a663parse_for_execute( acv ) OR
                        (acv.a_cmd_segment_header.sp1c_mess_type <> sp1m_parse)) AND
                        (acv.a_union_cnt = 0) AND
                        (dmli.d_pos_result <> cak_intern_pos)
                    THEN
                        BEGIN
                        a10del_sysinfo (acv,
                              dmli.d_esparr.pbasep^.syskey, _b_err);
                        dmli.d_esparr.pbasep := NIL;
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  _b_err <> e_ok
    THEN
        a07_b_put_error (acv, _b_err, 1);
    (*ENDIF*) 
    END;
&IFDEF TRACE
(*ENDIF*) 
t01int4 (ak_sem, 'returncode3 ', acv.a_returncode);
&ENDIF
IF  ((acv.a_returncode = 0)
    AND
    select_rec.sel_is_not_corr_search
    AND
    NOT (dmli.d_subquery)
    AND
    ((acv.a_intern_select_cnt = acv.a_max_intern_select)
    AND
    (NOT (acv.a_fromsel_n > 0))))
THEN
    BEGIN
    (* PTS 1115646 E.Z. *)
    IF  (acv.a_info_output AND
        NOT acv.a_insert_select)
        AND
        (dmli.d_corr = no_correlation)
    THEN
        BEGIN
        a60_p_info_output (acv, dmli.d_sparr);
        IF  (dmli.d_single OR
            (acv.a_ex_kind = only_parsing))
        THEN
            BEGIN
            a10_key_del (acv, dmli.d_sparr.pcolnamep^.syskey);
            dmli.d_sparr.pcolnamep := NIL
            END
        ELSE
            BEGIN
            a10add_sysinfo (acv, dmli.d_sparr.pcolnamep, _b_err);
            IF  _b_err <> e_ok
            THEN
                a07_b_put_error (acv, _b_err, 1)
            ELSE
                acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resinfobuf := 1;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  (acv.a_returncode = 0)
            (* PTS 1108761 E.Z. *)
            AND (dmli.d_sparr.pinfop <> NIL)
        THEN
            IF  (dmli.d_single OR
                (acv.a_ex_kind = only_parsing))
            THEN
                BEGIN
                a10_key_del (acv, dmli.d_sparr.pinfop^.syskey);
                dmli.d_sparr.pinfop := NIL;
                acv.a_shortinfo_key := cgg_zero_id;
                END
            ELSE
                BEGIN
                dmli.d_sparr.pinfop^.b_sl :=
                      sizeof(dmli.d_sparr.pinfop^.sshortinfo) -
                      sizeof(dmli.d_sparr.pinfop^.sshortinfo.siinfo) +
                      dmli.d_sparr.pinfop^.sshortinfo.sicount *
                      sizeof(tsp1_param_info);
                a10add_sysinfo (acv, dmli.d_sparr.pinfop, _b_err);
                IF  _b_err <> e_ok
                THEN
                    a07_b_put_error (acv, _b_err, 1)
                ELSE
                    acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resinfobuf :=
                          succ (acv.a_resname_addr[ dmli.d_pos_result ]^.
                          sresname.resinfobuf);
                (*ENDIF*) 
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  ( acv.a_ex_kind <> only_parsing )
    THEN
        IF  NOT dmli.d_single
        THEN
            a60resnum (acv, acv.a_mblock.mb_qual^.buf,
                  MB_PART1_HEAD_MXGG00 + 1)
        ELSE
            IF  acv.a_mblock.mb_qual^.mr_resnum = csp_rescnt_zero
            THEN
                BEGIN
                a07_b_put_error (acv, e_row_not_found, 1)
                END
            ELSE
                IF  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, dmli.d_keylen + cgg_rec_key_offset);
                    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*) 
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    ;
&   IFDEF TRACE
    t01int4 (ak_sem, 'returncode4 ', acv.a_returncode);
&   ENDIF
    IF  ((NOT dmli.d_single) AND (acv.a_returncode = 0))
    THEN
        BEGIN
        IF  (NOT acv.a_intern_explain) AND
            (NOT acv.a_insert_select)
        THEN
            ak67reskey_build( acv, dmli, select_rec.sel_res_name,
                  select_rec.sel_res_tree,
                  acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                  resimpl_upd_stat,
                  sr_rec, _output_len );
        (*ENDIF*) 
        IF  acv.a_returncode = 0
        THEN
            BEGIN
            acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resmaxlinkage := 1;
            IF  NOT acv.a_info_output
            THEN
                acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                      resinfobuf := 0
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  ((hsTempLock_egg00 in dmli.d_globstate) AND
            (acv.a_isolation_info = temp_lock_rec_not_needed))
        THEN
            acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                  resunlocktabid :=
                  dmli.d_sparr.pbasep^.sbase.btreeid.fileTabId_gg00
        ELSE
            acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                  resunlocktabid := cgg_zero_id;
        (*ENDIF*) 
        IF  acv.a_ex_kind = only_parsing
        THEN
            acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                  reseparsk := acv.a_pars_last_key
        ELSE
            acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                  reseparsk.p_kind := m_nil;
        (*ENDIF*) 
        acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
              resparsinfobyte := acv.a_precomp_info_byte;
        IF  acv.a_date_time_used
        THEN
            acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                  resdatetimeformat := acv.a_dt_format
        ELSE
            acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                  resdatetimeformat := dtf_none;
        (*ENDIF*) 
&       ifdef trace
        t01buf (ak_sem, acv.a_resname_addr[ dmli.d_pos_result ]^.sresname,
              1, sizeof(tak_resname_record));
&       endif
        IF  a01diag_analyze_on AND (acv.a_ex_kind = only_parsing)
        THEN
            a544get_cmdid (acv, acv.a_pars_last_key,
                  acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.
                  resanalyze_cmdid);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
&IFDEF TRACE
(*ENDIF*) 
t01int4 (ak_sem, 'returncode5 ', acv.a_returncode);
&ENDIF
IF  acv.a_returncode = 0
THEN
    BEGIN
    IF  (NOT dmli.d_single AND (acv.a_ex_kind <> only_parsing) AND
        NOT dmli.d_subquery AND NOT acv.a_insert_select)
    THEN
        IF  acv.a_resultnum [ 2 ] = cgg04_zero_exponent
        THEN
            BEGIN
            a07_b_put_error (acv, e_row_not_found, 1)
            END
        ELSE
            IF  acv.a_sqlmode = sqlm_oracle
            THEN
                a60rescount (acv, 0);
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END
ELSE
    BEGIN
&   IFDEF TRACE
    t01int4 (ak_sem, 'returncode6 ', acv.a_returncode);
&   ENDIF
    _aux_return   := acv.a_returncode;
    _aux_errorpos := acv.a_errorpos;
    acv.a_returncode := 0;
    IF  ((_aux_return <> -6003) AND NOT dmli.d_single AND select_rec.sel_is_not_corr_search AND
        (dmli.d_pos_result <= cak_maxresulttables))
        (* atsingle may be false here in case of two_phase-select, *)
        (* though it may have been true                            *)
    THEN
        BEGIN
        _ke := a01sysnullkey;
        IF  acv.a_ex_kind = only_parsing
        THEN
            BEGIN
            _ke.sauthid[ 1 ] := cak_tempinfo_byte;
            g10mv ('VAK67 ',  22,    
                  sizeof(acv.a_pars_last_key), sizeof(_ke.sauthid),
                  @acv.a_pars_last_key, 1,
                  @_ke.sauthid, 2, mxak_parskey,
                  acv.a_returncode);
            _ke.sauthid[ mxak_parskey + 1 ] := chr(0);
            END
        ELSE
            _ke.stempid := acv.a_curr_res_id;
        (*ENDIF*) 
        _ke.sentrytyp   := cak_ereskey;
        IF  select_rec.sel_res_b = 0
        THEN
            BEGIN
            _ke.slinkage := cak_zero_linkage;
            IF  ((_kb_return = 0) AND
                (rs_intinvnoresult in
                acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resstate) AND
                (acv.a_ex_kind <> only_parsing) AND
                ((acv.a_mblock.mb_trns^.trError_gg00 = e_ok) OR
                ( acv.a_mblock.mb_trns^.trError_gg00 = e_no_next_record)))
                AND _use_del_tree
            THEN
                BEGIN
                a502destroy_file (acv, _del_tree);
                _b_err := e_ok
                END;
            (*ENDIF*) 
            a10del_sysinfo (acv, _ke, _b_err);
            _b_err := e_ok;
            IF  (dmli.d_pos_result = cak_intern_pos) OR
                (dmli.d_pos_result = cak_extern_pos)
            THEN
                IF  NOT (rs_result in
                    acv.a_resname_addr[ dmli.d_pos_result ]^.sresname.resstate)
                THEN
                    BEGIN
                    _ke.sentrytyp := cak_emessblock;
                    a10del_sysinfo (acv, _ke, _b_err);
                    END
                ELSE
                    IF  ((_kb_return = 0) AND
                        (select_rec.sel_res_tree.fileTfn_gg00 = tfnTemp_egg00))
                    THEN
                        IF  (select_rec.sel_res_tree.fileTfnTemp_gg00 = ttfnInto_egg00)
                        THEN
                            b01empty_file (acv.a_transinf.tri_trans, select_rec.sel_res_tree)
                        ELSE
                            a502destroy_file (acv, select_rec.sel_res_tree);
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
            _b_err := e_ok;
            IF  (NOT dmli.d_subquery) OR acv.a_insert_select
            THEN
                IF  dmli.d_esparr.pbasep <> NIL
                THEN
                    BEGIN
                    a10del_sysinfo (acv, dmli.d_esparr.pbasep^.syskey, _b_err);
                    dmli.d_esparr.pbasep := NIL;
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
&   IFDEF TRACE
    (*ENDIF*) 
    t01int4 (ak_sem, 'returncode7 ', acv.a_returncode);
    t01int4 (ak_sem, '_aux_return ', _aux_return);
    t01int4 (ak_sem, 'parinf_b    ', select_rec.sel_parinf_b   );
&   ENDIF
    IF  select_rec.sel_parinf_b = 0
    THEN
        IF  acv.a_ex_kind = only_parsing
        THEN
            BEGIN
            IF  dmli.d_sparr.pparsp <> NIL
            THEN
                BEGIN
                a10del_sysinfo (acv, dmli.d_sparr.pparsp^.syskey, _b_err);
                dmli.d_sparr.pparsp := NIL;
                END;
            (*ENDIF*) 
            IF  dmli.d_sparr.pinfop <> NIL
            THEN
                IF  ((ord(dmli.d_sparr.pinfop^.syskey.sauthid[ 6 ]) <> ord(m_union)) AND
                    NOT acv.a_from_select AND
                    (acv.a_command_kind <> sub_in_union_command) AND
                    (acv.a_union_cnt = 0) )
                    OR
                    (_aux_return <> cak_e_corelated_subquery_not_allowed)
                THEN
                    BEGIN
                    a10_key_del (acv, dmli.d_sparr.pinfop^.syskey);
                    dmli.d_sparr.pinfop := NIL;
                    acv.a_shortinfo_key := cgg_zero_id;
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE
            IF  (acv.a_info_output AND select_rec.sel_is_not_corr_search)
            THEN
                BEGIN
                IF  dmli.d_sparr.pcolnamep <> NIL
                THEN
                    BEGIN
                    a10del_sysinfo (acv, dmli.d_sparr.pcolnamep^.syskey, _b_err);
                    dmli.d_sparr.pcolnamep := NIL;
                    END;
                (*ENDIF*) 
                IF  dmli.d_sparr.pinfop <> NIL
                THEN
                    BEGIN
                    a10del_sysinfo (acv, dmli.d_sparr.pinfop^.syskey, _b_err);
                    dmli.d_sparr.pinfop := NIL;
                    acv.a_shortinfo_key := cgg_zero_id;
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    IF  (_aux_return = cak_e_corelated_subquery_not_allowed) AND
        (acv.a_command_kind = union_in_sub_command)
    THEN
        acv.a_returncode := cak_e_union_in_corr
    ELSE
        BEGIN
        acv.a_returncode := _aux_return;
        acv.a_errorpos   := _aux_errorpos;
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a67_update_atinoutpos (
            VAR acv          : tak_all_command_glob;
            VAR dmli         : tak_dml_info;
            update_changepos : boolean);
 
VAR
      i                  : integer;
      j                  : integer;
      leng               : integer;
      maxdistinctlen     : integer;
      moved_stackentries : integer;
      oldfirst_free      : integer;
      oldpos             : integer;
      col_ptr            : tak00_colinfo_ptr;
      dummy_colinfo      : tak00_columninfo;
      all_stacks         : tgg00_StackListPtr;
 
BEGIN
WITH acv.a_mblock, mb_qual^, dmli.d_change, dmli.d_order_or_group_cols^ DO
    BEGIN
    oldfirst_free := 0;
    all_stacks := NIL;
&   IFDEF TRACE
    t01qual (ak_sem, acv.a_mblock.mb_qual^);
    t01int4 (ak_sem, 'd_keylen    ', dmli.d_keylen);
&   ENDIF
    moved_stackentries := 0;
    j                  := 0;
    FOR i := 1 TO ocntord DO
        IF  ofield[ i ].ofstno = 0
        THEN
            j := succ(j);
        (*ENDIF*) 
    (*ENDFOR*) 
    IF  j > 0
    THEN
        BEGIN
        j := mb_st^[ mqual_pos ].epos - 1; (* output stackentries *)
        moved_stackentries := mqual_cnt - j;
        IF  moved_stackentries > 0
        THEN
            BEGIN
            a10new (acv, moved_stackentries * STACK_ENTRY_MXGG00,
                  all_stacks);
            IF  all_stacks = NIL
            THEN
                a07_b_put_error (acv, e_no_more_memory, 1)
            ELSE
                BEGIN
                oldpos := mqual_pos + j;
                g10mv ('VAK67 ',  23,    
                      mb_st_size,
                      moved_stackentries * STACK_ENTRY_MXGG00,
                      @mb_st^, (mqual_pos + j - 1) * STACK_ENTRY_MXGG00 + 1,
                      @all_stacks^, 1,
                      moved_stackentries * STACK_ENTRY_MXGG00,
                      acv.a_returncode);
                mqual_cnt   := mqual_cnt - moved_stackentries;
                mfirst_free := mqual_pos + mqual_cnt;
                END;
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    oldfirst_free := mfirst_free;
    FOR i := 1 TO ocntord DO
        WITH ofield[ i ] DO
            IF  ofstno = 0
            THEN
                IF  is_not_definite in ofasc
                THEN
                    a07_b_put_error (acv, e_missing_column_definite, ofapos)
                ELSE
                    IF  ((ofname = a01_il_b_identifier) OR
                        ((ofname <> a01_il_b_identifier) AND
                        ((dmli.d_distinct <> no_distinct) OR
                        (acv.a_mblock.mb_type2 = mm_with_functions))
                        AND NOT dmli.d_group)) AND
                        NOT ((is_val_expression IN ofasc) AND
                        (dmli.d_distinct = no_distinct))       AND
                        NOT (is_nls_column IN ofasc)
                    THEN
                        BEGIN
&                       IFDEF TRACE
                        t01int4 (ak_sem, 'i           ', i);
                        t01int4 (ak_sem, 'd_group =   ', ord (dmli.d_group));
&                       ENDIF
                        IF  dmli.d_subquery
                        THEN
                            a07_b_put_error (acv, e_too_few_columns, -ofapos)
                        ELSE
                            (* PTS 1113255 E.Z. *)
                            IF  (dmli.d_union AND (ofname <> a01_il_b_identifier))
                            THEN
                                a07_b_put_error (acv, e_order_col_must_be_number, ofapos)
                            ELSE
                                a07_b_put_error (acv, e_unknown_ordercolumn, ofapos)
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        IF  oftabno = 0
                        THEN
                            a07_nb_put_error (acv, e_unknown_columnname,
                                  ofapos, ofname)
                        ELSE
                            BEGIN
                            IF  acv.a_returncode = 0
                            THEN
                                IF  oftabno <> dmli.d_acttabindex
                                THEN
                                    a61_rel_old_table (acv, dmli, oftabno);
                                (*ENDIF*) 
                            (*ENDIF*) 
                            IF  acv.a_returncode = 0
                            THEN
                                BEGIN
                                dmli.d_column := ofname;
                                IF  is_val_expression in ofasc
                                THEN
                                    BEGIN
                                    WITH dummy_colinfo DO
                                        BEGIN
                                        ccolumnn    := a01_il_b_identifier;
                                        ccolumnn_len:= chr(1);
                                        ccolpropset := [];
                                        cinoutlen   := 0;
                                        cdatalen    := 0;
                                        cdatatyp    := dunknown;
                                        cbinary     := false;
                                        ccolstack.etype := st_fixcol;
                                        END;
                                    (*ENDWITH*) 
                                    a61_is_orderfield (acv, dmli,
                                          dummy_colinfo, dmli.d_order_or_group_cols,
                                          NOT c_single_column, conv_none,
                                          0, dmli.d_column);
                                    END
                                ELSE
                                    BEGIN
                                    IF  offill <> 0
                                    THEN
                                        a06extcolno (dmli.d_sparr.pbasep^.sbase,
                                              offill, dmli.d_colbuf)
                                    ELSE
                                        IF  NOT a061exist_columnname (
                                            dmli.d_sparr.pbasep^.sbase,
                                            dmli.d_column, dmli.d_colbuf)
                                        THEN
                                            BEGIN
                                            acv.a_error_tableid :=
                                                  dmli.d_sparr.pbasep^.syskey.stableid;
                                            a07_nb_put_error (acv,
                                                  e_unknown_columnname,
                                                  ofapos, dmli.d_column)
                                            END;
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    IF  acv.a_returncode = 0
                                    THEN
                                        BEGIN
                                        IF  ((ctinvisible in dmli.d_colbuf^.ccolpropset) OR
                                            ((NOT dmli.d_tabarr[ dmli.d_acttabindex ].oall_priv) AND
                                            NOT (dmli.d_colbuf^.cextcolno
                                            in dmli.d_tabarr[ dmli.d_acttabindex ].osetallpriv)))
                                        THEN
                                            BEGIN
                                            acv.a_error_tableid := dmli.d_sparr.pbasep^.syskey.stableid;
                                            a07_nb_put_error (acv, e_unknown_columnname,
                                                  ofapos, dmli.d_column)
                                            END
                                        ELSE
                                            BEGIN
                                            a061colinfo_to_var (
                                                  dmli.d_colbuf^, dummy_colinfo);
                                            a61_is_orderfield (acv, dmli,
                                                  dummy_colinfo, dmli.d_order_or_group_cols,
                                                  NOT c_single_column,
                                                  conv_none, 0, dmli.d_column);
                                            END
                                        (*ENDIF*) 
                                        END
                                    (*ENDIF*) 
                                    END
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
            (* PTS 1122141 E.Z. *)
            (*ENDIF*) 
        (*ENDWITH*) 
    (*ENDFOR*) 
    IF  mfirst_free > oldfirst_free
    THEN
        WITH mb_st^[ mqual_pos ] DO
            epos := epos + mfirst_free - oldfirst_free;
        (*ENDWITH*) 
    (*ENDIF*) 
    IF  acv.a_returncode = cak_e_parameter
    THEN
        BEGIN
        acv.a_returncode := 0;
        a07_b_put_error (acv, e_without_datatypes, 1);
        END
    ELSE
        IF  acv.a_mblock.mb_type2 = mm_with_functions
        THEN
            BEGIN
            IF  ((mb_st^[ mfirst_free - 1 ].etype <> st_func) OR
                ( mb_st^[ mfirst_free - 1 ].eop <> op_none))
            THEN
                (* PTS 1122141 E.Z. *)
                BEGIN
                a61_put_last_func (acv);
                WITH mb_st^[ mqual_pos ] DO
                    epos := succ(epos)
                (*ENDWITH*) 
                END;
            (*ENDIF*) 
            ak67distinct_len (acv.a_mblock, maxdistinctlen)
            END
        ELSE
            maxdistinctlen := 0;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  acv.a_returncode = 0
    THEN
        BEGIN
        (* PTS 1122141 E.Z. *)
        (* if d_distinct wasn't in the beginning, when d_keylen *)
        (* was calculated, but is now, then 4 bytes are needed  *)
        (* for the distinct_bytes (SAGSIS 125647)               *)
        (* PTS 1107400 E.Z. *)
        leng := 0;
        FOR i := 1 TO ocntord DO
            WITH ofield[ i ], mb_st^[ ofstno ] DO
                BEGIN
                epos := leng + cgg_rec_key_offset+1;
                leng := leng + elen_var
                END;
            (*ENDWITH*) 
        (*ENDFOR*) 
        (* PTS 1107400 E.Z. *)
        IF  ((dmli.d_keylen = RESCNT_MXGG04) AND (dmli.d_distinct <> no_distinct))
        THEN
            leng := leng + cgg04_cdistinct_bytes;
        (*ENDIF*) 
        IF  ((leng + dmli.d_keylen       > cak_maxorderlength + RESCNT_MXGG04) OR
            ( leng + maxdistinctlen > cak_maxorderlength + RESCNT_MXGG04))
        THEN
            (* - leng is ok, see vak07 isunipos *)
            a07_b_put_error (acv, e_too_many_order_columns, -leng)
        ELSE
            BEGIN
            FOR j := mqual_pos TO mqual_pos + mqual_cnt - 1 DO
                WITH mb_st^[ j ] DO
                    IF  ((etype = st_output) AND
                        ((eop_out in [ op_o_none, op_o_output_hold ]) OR
                        (( eop_out = op_o_output_oflw) AND
                        (mb_st^[ j - 1 ].etype <> st_output))))
                    THEN
                        epos := epos + leng;
                    (*ENDIF*) 
                (*ENDWITH*) 
            (*ENDFOR*) 
            IF  (update_changepos AND NOT dmli.d_subquery AND
                ((acv.a_intern_select_cnt = acv.a_max_intern_select) OR
                (acv.a_fromsel_n > 0)))
            THEN
                BEGIN
                FOR j := 1 TO cr_colcount DO
                    WITH cr_columns[ j ] DO
                        ch_startpos := ch_startpos + leng;
                    (*ENDWITH*) 
                (*ENDFOR*) 
                IF  NOT dmli.d_single
                THEN
                    BEGIN
                    a67_bextcolindex (dmli.d_esparr, dmli.d_outcolno);
                    (* don't use search_column. In case *)
                    (* we selected SYSKEY there are two *)
                    (* columns named SYSKEY in the result*)
                    (* the increasing of len and iolen   *)
                    (* has to be done in the correct one *)
                    a06extcolno (dmli.d_esparr.pbasep^.sbase, 1, col_ptr);
                    WITH col_ptr^, ccolstack DO
                        BEGIN
                        cdatalen  := cdatalen + leng;
                        cinoutlen := cinoutlen + leng;
                        elen_var  := elen_var + leng;
                        END
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            dmli.d_keylen   := dmli.d_keylen + leng;
            dmli.d_reclen   := dmli.d_reclen + leng;
            dmli.d_inoutpos := dmli.d_inoutpos + leng;
            IF  dmli.d_inoutpos > MAX_RECLEN_GG00 + 1
            THEN
                a07_b_put_error (acv, e_output_columns_too_long,
                      dmli.d_inoutpos);
            (*ENDIF*) 
            IF  moved_stackentries > 0
            THEN
                IF  mfirst_free + moved_stackentries > mb_st_max + 1
                THEN
                    a07_b_put_error (acv, e_too_many_mb_stackentries, 1)
                ELSE
                    BEGIN
                    g10mv ('VAK67 ',  24,    
                          moved_stackentries * STACK_ENTRY_MXGG00,
                          mb_st_size, @all_stacks^, 1, @mb_st^,
                          (mfirst_free - 1) * STACK_ENTRY_MXGG00 + 1,
                          moved_stackentries * STACK_ENTRY_MXGG00,
                          acv.a_returncode);
                    IF  dmli.d_join
                    THEN
                        FOR i := 0 TO dmli.d_joins.jrc_cnt - 1 DO
                            WITH dmli.d_joins.jrc_joinarr[ i ] DO
                                BEGIN
                                jo_recs[ 1 ].jop_startstack :=
                                      jo_recs[ 1 ].jop_startstack + mfirst_free - oldpos;
                                jo_recs[ 2 ].jop_startstack :=
                                      jo_recs[ 2 ].jop_startstack + mfirst_free - oldpos;
                                END;
                            (*ENDWITH*) 
                        (*ENDFOR*) 
&                   IFDEF TRACE
                    (*ENDIF*) 
                    a683_output (ak_sem, dmli);
&                   ENDIF
                    mqual_cnt   := mqual_cnt + moved_stackentries;
                    mfirst_free := mfirst_free + moved_stackentries
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  all_stacks <> NIL
    THEN
        a10dispose (acv, all_stacks);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
