.nf
 
 .nf
 
    ========== licence begin  GPL
    Copyright (c) 1999-2005 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
 
 
.fo
*****************************************************
Copyright (c) 1999-2005 SAP AG
SAP Database Technology
 
Release :      Date : 2000-11-16
*****************************************************
modname : VAK16
changed : 2000-11-16
module  : AK_View_semantic
 
Author  : ThomasA
Created : 1985-10-16
*****************************************************
 
Purpose :
 
Define  :
 
        PROCEDURE
              a16_call_semantic (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a16col_to_view_description (
                    VAR acv      : tak_all_command_glob;
                    VAR dmli     : tak_dml_info;
                    VAR col_info : tak00_columninfo;
                    use_extcolno : boolean);
 
        PROCEDURE
              a16constraint_check (
                    VAR acv      : tak_all_command_glob;
                    VAR view_rec : tak_baserecord;
                    qualbuf      : tak_sysbufferaddress);
 
        PROCEDURE
              a16inc_vdesc_cnt (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    VAR p    : tak_sysbufferaddress);
 
        PROCEDURE
              a16new_bextcolindex (VAR base_rec : tak_baserecord);
 
        PROCEDURE
              a16put_usage_def  (
                    VAR acv            : tak_all_command_glob;
                    VAR put_tableid    : tgg00_Surrogate;
                    VAR using_tableid  : tgg00_Surrogate;
                    using_tablekind    : tgg00_TableKind);
 
        PROCEDURE
              a16privrec_build (
                    VAR acv      : tak_all_command_glob;
                    view_ptr     : tak_sysbufferaddress;
                    VAR base_ptr : tak_sysbufferaddress;
                    viewtextbuf  : tak_sysbufferaddress;
                    vqual_basis  : tak_sysbufferaddress;
                    VAR viewpriv : tak_privilege;
                    release      : boolean);
 
.CM *-END-* define --------------------------------------
***********************************************************
 
Use     :
 
&       ifdef TRACE
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01moveobj (
                    debug       : tgg00_Debug;
                    VAR moveobj : tsp00_MoveObj;
                    startpos    : tsp00_Int4;
                    endpos      : tsp00_Int4);
 
        PROCEDURE
              t01sname (debug : tgg00_Debug;
                    nam : tsp00_Sname);
 
        PROCEDURE
              t01str30 (
                    layer : tgg00_Debug;
                    str30 : tsp00_C30);
 
        PROCEDURE
              t01buf (
                    layer   : tgg00_Debug;
                    VAR buf : tsp00_KnlIdentifier;
                    startpos: integer;
                    endpos  : integer);
 
        PROCEDURE
              t01buf1 (
                    layer   : tgg00_Debug;
                    VAR buf : tak00_columninfo;
                    startpos: integer;
                    endpos  : integer);
 
        PROCEDURE
              t01stackentry (
                    layer       : tgg00_Debug;
                    VAR st      : tgg00_StackEntry;
                    entry_index : integer);
 
        PROCEDURE
              t01p2int4 (
                    layer : tgg00_Debug;
                    nam_1 : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    nam_2 : tsp00_Sname;
                    int_2 : tsp00_Int4);
 
        PROCEDURE
              t01p4int4 (
                    layer : tgg00_Debug;
                    nam   : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    int_2 : tsp00_Int4;
                    int_3 : tsp00_Int4;
                    int_4 : tsp00_Int4);
 
        PROCEDURE
              t01int4 (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname;
                    int   : tsp00_Int4);
 
        PROCEDURE
              t01op (
                    layer : tgg00_Debug;
                    nam   : tsp00_Sname;
                    op    : tgg00_StackOpType);
 
        PROCEDURE
              t01messblock (
                    debug   : tgg00_Debug;
                    nam     : tsp00_Sname;
                    VAR m   : tgg00_MessBlock);
 
        PROCEDURE
              t01qual (
                    layer    : tgg00_Debug;
                    VAR qual : tgg00_QualBuf);
 
        PROCEDURE
              t01name (
                    layer   : tgg00_Debug;
                    nam     : tsp00_Name);
 
        PROCEDURE
              t01lidentifier  (
                    layer       : tgg00_Debug;
                    identifier  : tsp00_KnlIdentifier);
 
        PROCEDURE
              t01stackdesc (
                    debug          : tgg00_Debug;
                    nam            : tsp00_Sname;
                    stack_addr     : tgg00_StackListPtr;
                    VAR stack_desc : tgg00_StackDesc);
 
        PROCEDURE
              t01bool (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    curr_bool: boolean);
 
        PROCEDURE
              t01basis_error (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname;
                    b_err : tgg00_BasisError);
&       endif
 
      ------------------------------ 
 
        FROM
              AK_Data_Type_Options : VAK14;
 
        FUNCTION
              a14LengthOfDefaultValue (
                    VAR DefaultRec : tak_defaultrecord) : integer;
 
      ------------------------------ 
 
        FROM
              AK_Grant_Revoke : VAK22;
 
        PROCEDURE
              a22add_priv_rec (
                    VAR acv         : tak_all_command_glob;
                    base_ptr        : tak_sysbufferaddress;
                    VAR new_priv    : tak_privilege;
                    priv_buf        : tak_sysbufferaddress;
                    add_sysinfo     : boolean;
                    VAR revoke_casc : boolean);
 
        PROCEDURE
              a22pack_priv (
                    privbuf         : tak_sysbufferaddress;
                    VAR new_priv    : tak_privilege;
                    VAR packed_priv : tak_privilege);
 
      ------------------------------ 
 
        FROM
              AK_Link : VAK25;
 
        PROCEDURE
              a25get_linkname (
                    VAR acv        : tak_all_command_glob;
                    linkbuf        : tak_sysbufferaddress;
                    index          : integer;
                    VAR link_name  : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              AK_Comment : VAK26;
 
        PROCEDURE
              a26drop_comment (VAR acv : tak_all_command_glob;
                    comment_type : tak_comment_type;
                    VAR id1      : tgg00_Surrogate;
                    VAR id2      : tgg00_Surrogate;
                    colno        : integer);
 
      ------------------------------ 
 
        FROM
              AK_VIEW_SCAN : VAK27;
 
        PROCEDURE
              a27init_viewscanpar (
                    VAR acv         : tak_all_command_glob;
                    VAR viewscanpar : tak_save_viewscan_par;
                    v_type          : tak_viewscantype);
 
        PROCEDURE
              a27ModifyAppendSchemas (
                    VAR acv     : tak_all_command_glob;
                    viewtextbuf : tak_sysbufferaddress;
                    viewdescbuf : tak_sysbufferaddress);
 
        PROCEDURE
              a27substitute_synonyms (
                    VAR acv     : tak_all_command_glob;
                    viewtextbuf : tak_sysbufferaddress;
                    viewdescbuf : tak_sysbufferaddress);
 
      ------------------------------ 
 
        FROM
              AK_Table   : VAK11;
 
        PROCEDURE
              a11del_usage_entry (
                    VAR acv       : tak_all_command_glob;
                    VAR usa_tabid : tgg00_Surrogate;
                    VAR del_tabid : tgg00_Surrogate);
 
        PROCEDURE
              a11get_check_table (
                    VAR acv          : tak_all_command_glob;
                    new_table        : boolean;
                    basetable        : boolean;
                    unload_allowed   : boolean;
                    required_priv    : tak00_PrivilegeSet;
                    any_priv         : boolean;
                    all_base_rec     : boolean;
                    d_state          : tak_directory_state;
                    VAR act_tree_ind : tsp00_Int4;
                    VAR authid       : tsp00_KnlIdentifier;
                    VAR tablen       : tsp00_KnlIdentifier;
                    VAR d_sparr      : tak_syspointerarr);
 
        PROCEDURE
              a11getconstraintname (
                    VAR constraint_rec  : tak_constraintrecord;
                    VAR constraint_name : tsp00_KnlIdentifier);
 
        PROCEDURE
              a11table_reference (
                    VAR acv     : tak_all_command_glob;
                    VAR auth    : tgg00_Surrogate;
                    VAR tablen  : tsp00_KnlIdentifier;
                    tablekind   : tgg00_TableKind;
                    is_global   : boolean;
                    is_systable : boolean;
                    VAR tableid : tgg00_Surrogate);
 
        PROCEDURE
              a11sort (VAR base_rec : tak_baserecord);
 
      ------------------------------ 
 
        FROM
              AK_save_scheme : VAK15;
 
        PROCEDURE
              a15restore_catalog (
                    VAR acv         : tak_all_command_glob;
                    VAR treeid      : tgg00_FileId;
                    VAR viewscanpar : tak_save_viewscan_par);
 
        PROCEDURE
              a15catalog_save (
                    VAR acv         : tak_all_command_glob;
                    VAR viewscanpar : tak_save_viewscan_par);
 
      ------------------------------ 
 
        FROM
              AK_usertab_tools : VAK19;
 
        PROCEDURE
              a19add_usertab  (VAR acv : tak_all_command_glob;
                    VAR user       : tgg00_Surrogate;
                    VAR surrogate  : tgg00_Surrogate;
                    surrogate_desc : tak_usertab_descriptor);
 
      ------------------------------ 
 
        FROM
              DML-Join-View-Procedures : VAK59;
 
        PROCEDURE
              a59_prepare_join_check (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    maxkeyl        : integer);
 
      ------------------------------ 
 
        FROM
              Execute_Select_Expression : VAK660;
 
        PROCEDURE
              a660_prefix_delete (
                    VAR acv         : tak_all_command_glob;
                    VAR parsk       : tak_parskey;
                    VAR del_cnt     : integer;
                    prefix_length   : integer);
 
        PROCEDURE
              a660select (
                    VAR acv                     : tak_all_command_glob;
                    startnode                   : tsp00_Int2;
                    VAR dmli                    : tak_dml_info;
                    VAR pseudo_resultset_select : boolean);
 
      ------------------------------ 
 
        FROM
              Complex_View_Optimization : VAK664;
 
        PROCEDURE
              a664col_info (
                    VAR acv  : tak_all_command_glob;
                    extcolno : integer;
                    colno    : integer;
                    colpos   : integer;
                    startnode: integer);
 
      ------------------------------ 
 
        FROM
              Join_Select_execution : VAK682;
 
        PROCEDURE
              a682join_MBlock_key (
                    VAR acv         : tak_all_command_glob;
                    VAR dmli        : tak_dml_info;
                    VAR parsk       : tak_parskey;
                    VAR jv_tabid    : tgg00_Surrogate;
                    seqno           : tsp00_Int2;
                    VAR syskey      : tgg00_SysInfoKey;
                    use_stmt_parsk  : boolean);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              join_trace_routines : VAK683;
 
        PROCEDURE
              a683_output (
                    debug    : tgg00_Debug;
                    VAR joins : tak_joinrec);
 
        PROCEDURE
              t01basis_error (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname;
                    b_err : tgg00_BasisError);
&       endif
 
      ------------------------------ 
 
        FROM
              DML_Help_Procedures : VAK54;
 
        PROCEDURE
              a54_dml_init (
                    VAR acv   : tak_all_command_glob;
                    VAR dmli  : tak_dml_info;
                    in_union  : boolean);
 
        PROCEDURE
              a54_dml_finalize (
                    VAR dmli         : tak_dml_info;
                    VAR TransContext : tgg00_TransContext);
 
        PROCEDURE
              a54_joinview_baserecords (
                    VAR acv     : tak_all_command_glob;
                    VAR dmli    : tak_dml_info);
 
      ------------------------------ 
 
        FROM
              SQLManager : VAK101;
 
        FUNCTION
              a101_AnySchemaMapped (
                    VAR acv : tak_all_command_glob) : boolean;
 
        PROCEDURE
              a101_RenameSchemaNames (
                    VAR acv  : tak_all_command_glob);
 
        PROCEDURE
              a101_InvalidateListAppend (
                    VAR acv       : tak_all_command_glob;
                    VAR SchemaId  : tgg00_Surrogate;
                    VAR Tablename : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              CatalogWrapper : VAK103;
 
        PROCEDURE
              a103CheckCreateInPrivilege (
                    VAR acv        : tak_all_command_glob;
                    VAR schemaName : tsp00_KnlIdentifier (* ptocConst *);
                    errorPos       : integer);
 
        PROCEDURE
              a103GetSchemaId (
                    VAR acv        : tak_all_command_glob;
                    VAR schemaName : tsp00_KnlIdentifier (* ptocConst *);
                    errorPos       : integer;
                    VAR schemaId   : tgg00_Surrogate);
 
      ------------------------------ 
 
        FROM
              Systeminfo_cache  : VAK10;
 
        PROCEDURE
              a10key_del  (
                    VAR acv         : tak_all_command_glob;
                    VAR  syspointer : tak_sysbufferaddress);
 
        PROCEDURE
              a10repl_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10_copy_catalog_rec (
                    VAR acv         : tak_all_command_glob;
                    VAR old_key     : tgg00_SysInfoKey;
                    del_old_rec     : boolean;
                    VAR new_key     : tgg00_SysInfoKey;
                    new_segment_id  : tsp00_C2;
                    add_new_rec     : boolean;
                    VAR b_err       : tgg00_BasisError);
 
        PROCEDURE
              a10_del_tab_sysinfo  (
                    VAR acv     : tak_all_command_glob;
                    VAR tableid : tgg00_Surrogate;
                    VAR qual    : tak_del_tab_qual;
                    temp_table  : boolean;
                    VAR b_err   : tgg00_BasisError);
 
        PROCEDURE
              a10_add_repl_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    add_sysinfo  : boolean;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10_fix_len_get_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syskey   : tgg00_SysInfoKey;
                    dstate       : tak_directory_state;
                    required_len : integer;
                    plus         : integer;
                    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
              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_lock_sysinfo (VAR acv : tak_all_command_glob;
                    VAR syskey : tgg00_SysInfoKey;
                    lockm      : tgg00_LockReqMode);
 
        PROCEDURE
              a10next_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syskey   : tgg00_SysInfoKey;
                    stop_prefix  : integer;
                    dstate       : tak_directory_state;
                    rec_kind     : tsp00_C2;
                    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_Int4;
                    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_rel_sysinfo (
                    VAR acv     : tak_all_command_glob;
                    VAR syskey  : tgg00_SysInfoKey);
 
        PROCEDURE
              a10_cache_delete  (
                    VAR acv     : tak_all_command_glob;
                    is_rollback : boolean);
 
        PROCEDURE
              a10table_cache_delete (
                    VAR acv     : tak_all_command_glob;
                    VAR tableid : tgg00_Surrogate);
 
        PROCEDURE
              a10rel_sysinfo (syspointer : tak_sysbufferaddress);
 
        PROCEDURE
              a10_all_release (VAR acv : tak_all_command_glob);
 
      ------------------------------ 
 
        FROM
              AK_universal_semantic_tools : VAK06;
 
        PROCEDURE
              a06extcolno (
                    VAR baserec : tak_baserecord;
                    extcolno    : integer;
                    VAR col_ptr : tak00_colinfo_ptr);
 
        PROCEDURE
              a06inc_linkage (VAR linkage : tsp00_C2);
 
        PROCEDURE
              a06pred_linkage (VAR linkage : tsp00_C2);
 
        PROCEDURE
              a06_systable_get (
                    VAR acv       : tak_all_command_glob;
                    dstate        : tak_directory_state;
                    VAR tableid   : tgg00_Surrogate;
                    VAR base_ptr  : tak_sysbufferaddress;
                    get_all       : boolean;
                    VAR ok        : boolean);
 
        PROCEDURE
              a06user_get_priv  (
                    VAR acv  : tak_all_command_glob;
                    VAR brec : tak_sysbufferaddress;
                    VAR user : tgg00_Surrogate;
                    VAR priv : tak_privilege);
 
        PROCEDURE
              a06unpack_priv (
                    VAR packed_priv   : tak_privilege;
                    VAR unpacked_priv : tak_privilege);
 
        PROCEDURE
              a06a_mblock_init (
                    VAR acv  : tak_all_command_glob;
                    mtype    : tgg00_MessType;
                    m2type   : tgg00_MessType2;
                    VAR tree : tgg00_FileId);
&       ifdef trace
 
        PROCEDURE
              a06td_priv (
                    p        : tak_privilege;
                    id       : tsp00_C18;
                    unpacked : boolean);
&       endif
 
      ------------------------------ 
 
        FROM
              AK_Identifier_Handling : VAK061;
 
        PROCEDURE
              a061app_columnname (
                    VAR acv               : tak_all_command_glob;
                    VAR base_rec          : tak_baserecord;
                    VAR column            : tsp00_KnlIdentifier;
                    VAR index             : integer);
 
        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);
 
        PROCEDURE
              a061copy_colinfo (
                    VAR src_col : tak00_columninfo;
                    VAR dst_col : tak00_columninfo);
 
        PROCEDURE
              a061sort (
                    VAR acv               : tak_all_command_glob;
                    VAR base_rec          : tak_baserecord;
                    last_used_expr_no     : integer;
                    VAR duplicate_column  : boolean;
                    VAR duplicate_colname : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalForcedFill (
                    size        : tsp00_Int4;
                    m           : tsp00_MoveObjPtr;
                    pos         : tsp00_Int4;
                    len         : tsp00_Int4;
                    fillchar    : char);
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id   : tsp00_C6;
                    mod_num  : tsp00_Int4;
                    src_upb  : tsp00_Int4;
                    dest_upb : tsp00_Int4;
                    src      : tsp00_MoveObjPtr;
                    src_pos  : tsp00_Int4;
                    dest     : tsp00_MoveObjPtr;
                    dest_pos : tsp00_Int4;
                    length   : tsp00_Int4;
                    VAR err  : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalForcedMove (
                    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);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        PROCEDURE
              g01abort (
                    msg_no     : tsp00_Int4;
                    msg_label  : tsp00_C8;
                    msg_text   : tsp00_C24;
                    bad_value  : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Integer_SET : VGG12;
 
        FUNCTION
              gg12InitBitArray(
                    VAR TransContext : tgg00_TransContext;
                    bits             : tsp00_Int4) : tsp00_Addr;
 
        FUNCTION
              gg12GetBit (
                    IntegerSet  : tsp00_Addr;
                    number      : tsp00_Int4) : boolean;
 
        PROCEDURE
              gg12SetBit (
                    IntegerSet  : tsp00_Addr;
                    number      : tsp00_Int4;
                    value       : boolean);
 
        PROCEDURE
              gg12FinalizeBitArray(
                    VAR TransContext : tgg00_TransContext;
                    VAR IntegerSet   : tsp00_Addr);
 
      ------------------------------ 
 
        FROM
              GG_allocator_interface : VGG941;
 
        FUNCTION
              gg941Allocate(
                    VAR TransContext : tgg00_TransContext;
                    wantedBytes      : integer) : tsp00_Addr;
 
        PROCEDURE
              gg941Deallocate(
                    VAR TransContext : tgg00_TransContext;
                    VAR p            : tsp00_Addr);
 
      ------------------------------ 
 
        FROM
              Scanner : VAK01;
 
        VAR
              a01char_size        : integer;
              a01defaultkey       : tgg00_SysInfoKey;
              a01emptypriv        : tak_privilege;
              a01fullset          : tak_columnset;
              a01_il_b_identifier : tsp00_KnlIdentifier;
              a01_i_sys           : tsp00_KnlIdentifier;
 
        FUNCTION
              a01equal_char (
                    VAR m    : tsp00_MoveObj;
                    pos      : tsp00_Int4;
                    cmp_char : char) : boolean;
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
        PROCEDURE
              s30cmp (
                    VAR buf1     : tak_default_value;
                    fieldpos1    : tsp00_Int4;
                    fieldlength1 : tsp00_Int4;
                    VAR buf2     : tak_default_value;
                    fieldpos2    : tsp00_Int4;
                    fieldlength2 : tsp00_Int4;
                    VAR l_result : tsp00_LcompResult);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK07;
 
        PROCEDURE
              a07ak_system_error (
                    VAR acv  : tak_all_command_glob;
                    modul_no : integer;
                    id       : integer);
 
        PROCEDURE
              a07_const_b_put_error (
                    VAR acv    : tak_all_command_glob;
                    b_err      : tgg00_BasisError;
                    err_code   : tsp00_Int4;
                    param_addr : tsp00_MoveObjPtr;
                    const_len  : integer);
 
        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
              a071_return_code (
                    b_err   : tgg00_BasisError;
                    sqlmode : tsp00_SqlMode) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              Pointer-Arithmetik : VSP35;
 
        FUNCTION
              s35add_moveobj_ptr_ptocm (
                    moveobj_ptr : tsp00_MoveObjPtr;
                    pos         : tsp00_Int4) : tsp00_MoveObjPtr;
 
      ------------------------------ 
 
        FROM
              filesysteminterface_1 : VBD01;
 
        VAR
              b01niltree_id : tgg00_FileId;
 
        PROCEDURE
              b01destroy_file (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId);
 
        PROCEDURE
              b01empty_file (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId);
 
        PROCEDURE
              b01tcreate_file (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_7 : VBD07;
 
        PROCEDURE
              b07cadd_record (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId;
                    VAR b       : tgg00_Rec);
 
.CM *-END-* use -----------------------------------------
 
Synonym :
 
        PROCEDURE
              a27init_viewscanpar;
 
              tak_viewscan_par tak_save_viewscan_par
 
        FUNCTION
              s35add_moveobj_ptr_ptocm;
 
              tsp00_Int4 tsp00_MoveObjPtr;
 
        PROCEDURE
              s30cmp;
 
              tsp00_MoveObj   tak_default_value
&             ifdef trace
 
        PROCEDURE
              t01buf;
 
              tsp00_Buf tsp00_KnlIdentifier
 
        PROCEDURE
              t01buf1;
 
              tsp00_Buf tak00_columninfo
&             endif
 
.CM *-END-* synonym -------------------------------------
***********************************************************
Specification:
 
PROCEDURE  A16_CALL_SEMANTIC
-----------------------------------------------------------
 
The procedure converts a Viewdefinition in part 1 of the SQL-PACKET
into the corresponding catalog information.
 
The procedure can be called by
 
i)a create view command issued by a user or
 
ii)a restore schema issued by a user or
 
iii)an alter table command issued by a user.
 
The initiating command is known to the procedure by acv.a_internal_sql =
(no_internal_sql, sql_restore_scheme, sql_alter_table).
 
The following catalog records describe a view:
 
i)at least one tbaserecord with global view characteristics
and the column descriptions.
 
ii)at least one tviewtextrecord with descriptions of
the tables in the from part as well as the viewdefinition string.
 
iii)a tviewdescrecord with information about the
referenced columns as well as their positions in
the viewdefinition string.
 
iv)a tprivrecord which describes the privileges of the
owner of the view.
 
v)If the view is not a complex view, a tviewqualrecord exists with
descriptions of the referenced base tables,
the join conditions, the expression columns as well as the qualification.
 
vi)In the case of updatable join views, catalog information
of type tmessbuf exists, which contains the qualification
that is to be checked before (after) an update.
 
 
.CM *-END-* specification -------------------------------
***********************************************************
 
Description:
 
 
PROCEDURE  A16_CALL_SEMANTIC :
-----------------------------------------------------------
 
In the syntax analysis in VAK20, the following syntax tree is built:
 
    (a16,with_check_option)
       |
       V
    viewname
       |
       V
    (a16,4) --> Columnname - List
       |
       V
    (a63,4)
       |
       V
    (a63,2)
    distinct
       |
       V
    a60,1 ------->  a63,3 --------->  a63,10
    selectlist     frompart          where_clause
    a60,2 ...      a66,1 --> a66,1..
    stern coln     tablentablen
    refe  coln
    a64,6 function
 
Call hierarchy:
 
+-------------------------------------------------------+
| A16_CALL_SEMANTIC                                     |
|      +------------------------------------------------|
|      | A11GET_CHECK_TABLE                             |
|      +------------------------------------------------|
|      | AK16GET_VIEWTEXT_BUF                           |
|      +------------------------------------------------|
|      | A66_SELECT                                     |
|      +------------------------------------------------|
|      | AK16VIEWTEXT_DEFINITION                        |
|      |      +-----------------------------------------|
|      |      | A16PUT_USAGE_DEF                        |
|      +------------------------------------------------|
|      | A16_RENAME_COLUMN                              |
|      +------------------------------------------------|
|      | AK16ADD_VIEW_QUALIFICATION                     |
|      |      +-----------------------------------------|
|      |      | AK16BASETABS_TO_QUALREC                 |
|      |      +-----------------------------------------|
|      |      | AK16JOIN_INFORMATION                    |
|      |      +-----------------------------------------|
|      |      | AK16EXPRESSION_COLS                     |
|      +------+-----------------------------------------|
|      | AK16END_VIEW                                   |
|      |      +-----------------------------------------|
|      |      | AK16INIT_VIEWBASE_REC                   |
|      |      +-----------------------------------------|
|      |      | A16NEW_BEXTCOLINDEX                     |
|      |      +-----------------------------------------|
|      |      | AK16CREATE_PRIVRECORD                   |
|      |      |      +----------------------------------|
|      |      |      | A16KEY_EQ_JOIN_PREDICATE         |
|      |      |      |    +-----------------------------|
|      |      |      |    | A16_CHECK_KEY_EQ_QUAL       |
|      |      |      |    +-----------------------------|
|      |      |      |    | A16GET_EQ_JOIN_RELATIONS    |
|      |      |      |    +-----------------------------|
|      |      |      |    | A16_ONE_INVISIBLE_COLUMN_ADD|
|      |      |      +----------------------------------|
|      |      |      | A16PRIVREC_BUILD                 |
|      |      |      |    +-----------------------------|
|      |      |      |    | AK16COLPRIV_CHECK           |
|      |      |      |    +-----------------------------|
|      |      |      |    | AK16INVISIBLE_COLUMN_ADD    |
 
 
PROCEDURE  A16_CALL_SEMANTIC (VAR acv : all_command_glob);
-----------------------------------------------------------
 
The procedure executes the command Create View.. semantically, i.e. by
calling the procedure, the syntax tree is processed and the
resulting catalog
information is built and inserted into the system files. There are three
reasons that may cause the procedure to be called:
 
i)a create view command of a user has been issued :
 
In this case, it is necessary to create all the catalog information that
describes a view.
 
ii)a restore schema command of a user has been issued :
 
In this case, it is necessary to create all the catalog information that
describes a view. If the command fails, however,
none of the catalog entries that have already been inserted
need to be undone, because this is done at the
end of the restore schema command.
 
iii)An alter table add or column command of a user has been executed.
In these cases, an implicit save and restore schema
of the relevant table is performed, which means that
the dependent views are re-built. In this case,
however, it is not necessary to re-build all the catalog information
of the view, but only that portion that may have changed.
As in case ii), alterations
that have already been made need not be undone.
 
When the procedure a11get_check_table is called, it is checked first of all
whether a table of the specified name already exists, and whether the current
user has the privilege to create a view.
 
If the procedure has been called as the result of an alter table command and if
the view to be created is a join view, the catalog information of type
tmessbufrecord is deleted so that no error occurs when the new records are
subsequently inserted.
 
By means of ak16get_viewtext_buf, cache areas are then requested for the catalog
information of type tviewtextrecord and tviewdescrecord and are initialized.
 
The procedure a660select then ensures that the select defining the view is
executed and that appropriate entries are made in the catalog records of
type tbaserecord, tviewtextrecord and tviewdescrecord. In addition, the
procedure creates the stack entries of the output columns and of the
qualification in the message buffer. The component a_special_expr of the acv was
set to TRUE before a660select was called in order to prevent operations being
written to column stack entries when the qualification is built, which would
mean that this operation would be lost if an index were created.
 
After a660select has been called, it is also clear which kind of view is being
dealt with;
 
i)The view is a complex view (d_phase_cnt = cak_complex_view_indicator),
i.e. for the accessing of such a view, the view must first be built as a
temporary result before it is actually accessed.
 
ii)The view is a join view, i.e. it references more than one base table.
 
iii)The view references precisely one base table.
 
The procedure ak16viewtext_definition then writes the tviewdescrecord built by
a660select to system file 1 and transfers the view-definition string to the
already partially built tviewtextrecord.
 
If, in the definition of the view, the column names have been defined by a
names list, the column names are renamed in the column descriptions of the
tbaserecords (a16_rename_column).
 
The qualification built in the message buffer and the base tables involved in
the view are inserted into the catalog record of type
tviewqualrecord and are inserted into the catalog.
 
By means of ak16end_view, the privileges of the view are then determined and
the tbaserecords of the view are inserted.
 
The name of the view is entered in the list of the tables visible for the
current user (tak_usertabrecord). If the current user is not the superdba and if
the view created is a PUBLIC view, it, too, is entered in the usertabrecord of
the superdba.
 
If errors have occurred during processing, the cache is deleted and the catalog
alterations that have already been made are rollbacked (a06_partial_rollback) if
the view has not been built as the result of a restore schema execution.
 
PROCEDURE  AK16GET_VIEWTEXT_BUF (
                  VAR acv : all_command_glob;
                  VAR a16v : tak16_viewglob);
-----------------------------------------------------------
 
In the cache, an area for a catalog record of type tviewdesc is requested
starting at address a16dmli.dm_linkbuf and the number of entries is initialized
with 0. In the course of a660select, it is later recorded here which columns of
the tables in the FROM part are referenced by the view and where the
corresponding positions  in the definition string of the view are.
 
Then, a cache area is requested for a catalog record of type tviewtext
starting at address a16dmli.atviewtextbuf and the number of table descriptions
is initialized with 0. In the course of a660select, each table in the FROM part
of the view definition is described here.
 
PROCEDURE  A16PUT_USAGE_DEF  (
                  VAR acv : all_command_glob;
                  VAR put_auth   : user_id;
                  VAR put_tabl   : name;
                  put_loc        : location;
                  VAR using_auth : user_id;
                  VAR using_tabl : name;
                  using_loc      : location;
                  using_tablekind: ttablekind);
-----------------------------------------------------------
 
The table Using_auth.Using_tabl is entered in the catalog information of type
tusagerecord of table put_auth.put_tabl. This records the fact that the view or
the synonym using_auth.using_tabl references the table put_auth.put_tabl, i.e.
that the table occurs either in the FROM part of the view definition of
using_auth.using_tabl or that put_aut.put_tabl is a synonym of
using_auth.using_tabl.
 
PROCEDURE  AK16JOIN_INFORMATION (
                  VAR dmli      : dml_info;
                  firstqualpos  : integer;
                  VAR qualpoint : tsysbufferaddress);
-----------------------------------------------------------
 
The information of the join condition of a view is transferred from the
jrc_joinarr of the a16dmli to the catalog record of type tviewqual starting at
address qualpoint.
 
PROCEDURE  AK16VIEWTEXT_DEFINITION  (
                  VAR acv  : all_command_glob;
                  VAR a16v : tak16_viewglob);
-----------------------------------------------------------
 
The catalog information of type tviewdesc starting at address dm_linkbuf is
inserted into the system file or is updated if the view has been called as the
result of an alter table command.
 
At the time the procedure is called, the tables in the From part of the view
definition have already been described in the vttab part of the record by
a660select. The procedure then transfers the view-definition string to the
record starting at address atviewtextbuf. If the first record is not sufficient
for holding the entire string, a follow-up record is requested in the cache and
the remainder is copied to this record. As usual, the records are chained by
means of the slinkage in
the sysinfo key. The first catalog records remains
allocated in the cache at address atviewtextbuf, since the a16dmli.atarr,
in which the participating tables from the From part are determined, is
subsequently destroyed and since these table names are subsequently still
required. A maximum of 7 buffers with d_fix are allocated in the cache after
the procedure has been called. The catalog information that has been built in
the cache is inserted into the system file if the create view command has not
been called as the result of an alter table command.
 
Finally, the procedure ensures that the dependence of the view on the tables is
recorded in the From part in the catalog information. For this purpose, the view
name is entered in the tusagerecord of each table in the From part
(a16put_usage_def). If the table in the From part is a synonym, the usage
information is entered both in the tusagerecord of the synonym and also in the
tusagerecord of the table specified by the synonym. This is necessary so that
the view is deleted when the table or the synonym is deleted.
 
PROCEDURE  AK16ADD_VIEW_QUALIFICATION (
                  VAR acv  : all_command_glob;
                  VAR a16v : tak16_viewglob;
-----------------------------------------------------------
 
 
When the procedure is called, the descriptions of the output columns and the
qualification have been entered in the message buffer by a660select.
 
atviewtextbuf is the pointer to the catalog record of type  tviewtextrecord
that has been built in the cache.
 
Sequence of actions:
 
The output descriptions and the qualifications are stored in the message buffer
starting at mcol_pos and mqual_pos, respectively.
 
The descriptions of the base tables are written to the record of type
tak_viewqual_basis_record (ak16basetabs_to_qualrec).
 
The viewjoin descriptions are written to the record of type
tak_viewqual_join_record (ak16join_information).
 
The Expression columns are determined and are written to the record of type
tak_viewqual_stack_record (ak16expression_cols).
 
If the view is built in the form of an alter table command, the already
existing catalog record is replaced by the newly built one; otherwise it is
inserted into the system file. The first tviewqualrecord that was built remains
allocated in the cache starting at address a6vqual_basis.
 
PROCEDURE  AK16DESTROY_JUMP_INSUPD (
                  VAR acv  : all_command_glob);
-----------------------------------------------------------
 
In all stack entries of type st_jump_false, the operator is set to op_none and
all entries with operator op_upd_view_and are made into op_and operators. This is
necessary if a qualification with parts to be jumped (after an update) is to be
made into a qualification without parts to be jumped.
 
PROCEDURE  AK16BASETABS_TO_QUALREC (
                  VAR acv  : all_command_glob;
                  VAR a16v : tak16_viewglob;
-----------------------------------------------------------
 
The procedure writes the information of all base tables referenced by the view
to the tviewqualrecord starting at address a6viewbuf. At the time the procedure
is called, only the referenced tables are known in the From part. Since each of
these tables may reference more than one base table, each table in the From
part of the view is broken down into its base tables
(a54_joinview_baserecords). All referenced base tables are then described in
a16dmli.atarr. The catalog information of type tbaserecord of each referenced
base table is loaded into the cache in order to be able to determine the
information to be entered in the tviewqualrecord (location sets, version
number, #Key fields).
 
PROCEDURE  AK16INVISIBLE_COLUMN_ADD (
                  VAR acv            : all_command_glob;
                  VAR usedcollist    : tak16_colprivlist;
                  VAR a16v           : tak16_viewglob;
                  VAR base_arr       : tsyspointerarr);
-----------------------------------------------------------
 
The procedure is called if the view created references precisely one base
table. In this case, all column information of the columns of the base table
that are not referenced by the view are added as invisible columns to the
tbaserecords of the view. This is necessary so that ordered selects also run
via views that reference columns only in the qualification part of the view.
 
The parameter usedcollist holds the external column numbers of the base-table
columns that are referenced by the view. Each column of the base table that is
not in this set is inserted by a16_one_invisible_column_add into the
tbaserecords of the view.
 
PROCEDURE  A16_ONE_INVISIBLE_COLUMN_ADD (
                  VAR acv        : all_command_glob;
                  VAR view_arr   : tsyspointerarr;
                  VAR columninfo : tcolumninfo;
                  tabno          : integer);
-----------------------------------------------------------
 
The column description columninfo is inserted as an invisible column into the
tbaserecords of the view (view_arr). The table number of the column is tabno.
 
The column name results as chr(255) & highest column number. By means of
a06_app_columnname, the column description is inserted into the last
tbaserecord of the view.
 
PROCEDURE  AK16EXPRESSION_COLS (
                  VAR acv        : all_command_glob;
                  VAR a16v       : tak16_viewglob;
                  VAR new_record : boolean);
-----------------------------------------------------------
 
The output qualification starting at mcol_pos in the message buffer is examined
for expression columns. An expression column exists if a column description
consists of more than one stack entry or of a stack entry that does not
describe a column. In this case, the column description is written to the view
qualification record. The stack entry is manipulated as follows in the column
description in the base record:
 
   etype         : st_func
   epos          : Index, starting at which the column-description
                   stack   entries   are   located   in  the  view
                   qualification record.
   elen_var      : Last  index  of  the  column description in the
                   view qualification record.
   ecol_tab[ 2 ] : slinkage of  the  view  qualification  record in
                   which the stack entries are located.
 
 
If values exist in the column description, they are written behind the stack
entries. If not all the descriptions fit into the current view qualification
record, new_record is set to true.
 
PROCEDURE AK16CREATE_PRIVRECORD (
                  VAR acv        : all_command_glob;
                  VAR a16v       : tak16_viewglob;
-----------------------------------------------------------
 
The procedure creates the catalog record of type tprivrecord for the owner of
the view in which the operations are specified that he may execute on the view.
The following statements apply:
 
i)Complex views can, as a basic rule, only be read.
 
ii)Views that contain expression columns or doubly defined columns can only
be read.
 
iii)Views are capable of tnsert only if i) and ii) do not apply and all
mandatory columns of all referenced tables are in the view.
 
iv)Join views are capable of Insert, Update, Delete only if all key columns
of all base tables are in the view. However, it may happen that all other key
columns are also implicitly defined by the key columns in the view and by a
Join = condition.
 
Example :
 
  CREATE TABLE T1 (K1 CHAR(5) KEY, S1 CHAR(20))
  CREATE TABLE T2 (K2 CHAR(5) KEY, S2 CHAR(20))
  CREATE VIEW V1 AS SELECT K1, S1, S2 FROM T1, T2
                  WHERE K1 = K2 WITH CHECK OPTION
 
Although only the key column of T1 is in the view, the value of K2 is known if
that of K1 is specified. In such cases, a join view is also recognized as
capable of update.
 
v)In order to obtain a privilege on a column, the owner of the view must
have this privilege on the referenced column of the table in the From part.
 
Complex views are identified by the d_phase_cnt = cak_complex_view_indicator and
the capability of Insert, Update and Delete is not tested.
In Join Views, it is otherwise checked
by means of a16key_eq_join_predicate whether the view may be updatable and
capable of Insert. Views that reference precisely one base table are
potentially always capable of Insert and Update. Subsequently, a check is made
for double columns and expression columns. In the cache, an area for the
tprivrecord is requested and initialized. If the view may be capable of insert,
the insert privilege is entered in the set of privileges valid for the entire
table. The same applies to the the update and delete privilege in cases where
the view may be updatable. By means of a16privrec_build, these entries are then
verified, i.e. the privileges of the participating table in the FROM part are
cut with these privileges. The privilege record is then finally built. If the
created view references precisely one base table, all columns of the base table
that are not referenced in the select list of the view are entered as invisible
columns in the tbaserecords of the view (ak16invisible_column_add). If the
privilege test has yielded that the view is readable only, there must be an
error message if a definition has been made WITH CHECK OPTION. Otherwise, the
privilege record that has been built is inserted into system file 1. If
invisible columns have been added to the tbaserecords of the view, the
tbaserecords must be re-sorted by a061sort.
 
PROCEDURE  A16PRIVREC_BUILD (
                  VAR acv      : all_command_glob;
                  VAR view_arr : tsyspointerarr;
                  VAR base_arr : tsyspointerarr;
                  viewtextbuf  : tsysbufferaddress;
                  privbuf      : tsysbufferaddress;
                  update_view  : boolean;
                  release      : boolean);
-----------------------------------------------------------
 
The tprivrecord of the view allocated in the cache starting at privbuf has, in
the set of all privileges valid for the entire view, all potentially possible
privileges without considering the privileges of the tables in the From part as
well as their mandatory columns.
 
For each table in the From part of the view, it is now checked whether the
potentially possible privileges are compatible with those in the table. For
this purpose, the tbaserecords of the corresponding table in the FROM part and
the privileges of the owner of the view with respect to the table are loaded
into the cache. If the owner of the view does not have a privilege existing
for the entire table, it, too, must be removed from the privbuf privilege set.
By means of ak16colpriv_check, the privileges are then checked with
regard to individual columns, i.e. it is checked whether all mandatory columns
of the table under consideration have been specified and whether individual
columns are updatable.
 
In the case of a join view, the tbaserecords are then again released; otherwise
they remain permanently allocated in the cache in order later to dispense with
the need for renewed accessing.
 
Finally, it is checked whether all columns of the view apart from the key
columns are updatable. In this case, the Update privilege must again be entered
in the set of privileges valid for the entire view.
 
PROCEDURE  A16KEY_EQ_JOIN_PREDICATE (
                  VAR acv                : all_command_glob;
                  VAR view_arr           : tsyspointerarr;
                  VAR qualbuf            : tsysbufferaddress;
                  with_check_option      : boolean;
                  VAR all_keys_specified : boolean;
                  VAR update_view        : boolean);
-----------------------------------------------------------
 
The procedure checks whether all key columns of all referenced base tables are
explicitly or implicitly specified by the view, i.e. whether all keys of all
base tables can be formed from giving one row of the view. Only in this case
is a join view updatable.
 
First of all, the simple case is checked whereby all Key columns of all bases
tables are referenced by the Select List of the view, with system key columns
being considered always as referenced. A two-dimensional array specified_keys
is used as a test. specified_keys[ tabno, key_no ] = extcolno signifies that
the key_no-th key column of the table tabno has been specified as the
extcolno-th column in the Select List of the view.
Since the number of key columns of
each referenced base table is stored in the tviewqualrecord, it is now easy to
determine whether all key columns of all base tables have been defined in the
select list. If this is not the case and if the view has been defined WITH
CHECK OPTION, the missing key columns may possibly result from the Join
condition and from the known keys. This is determined by a16_check_key_eq_equal
and a16get_eq_join_relations. The key columns that have been implicitly defined
in the described manner are then also entered in the array, with the result
that the same test can once again be performed. If it is found that all key
columns are now specified, the key-column descriptions that are not defined by
the Select List must be inserted as invisible columns into the tbaserecords of
the view. These columns are recognized by an external column number > 10000 in
specified_keys. If this were to result in a column number > 255, the already
inserted invisible columns are removed again and the view is marked as not
updatable.
 
PROCEDURE  A16_CHECK_KEY_EQ_QUAL (
                  VAR acv        : all_command_glob;
                  qual_ptr       : tsysbufferaddress);
-----------------------------------------------------------
 
The procedure checks for each join = condition whether the data types of the
left-hand and right-hand sides are precisely identical and whether the
condition is located in a part of the qualification that has to be checked
after an update. Join conditions that satisfy these requirements are provided
with jkey_equal as operator.
 
PROCEDURE  A16_KEY_EQUAL_JOIN (
                  VAR qual_ptr  : tsysbufferaddress;
                  VAR join_desc : one_viewjoin;
                  tabno         : integer;
                  colno         : integer;
                  VAR jtabno    : integer;
                  VAR jcolno    : integer) : boolean;
-----------------------------------------------------------
 
The procedure returns TRUE if the join condition described by join_desc
references on the left-hand or right-hand side the column specified by tabno
and colno and defines an equal condition to a key column of the same column
number. The corresponding referenced column on the other side of the equal
condition is returned in jtabno and jcolno.
 
PROCEDURE  AK16COLPRIV_CHECK (
                  VAR acv            : all_command_glob;
                  VAR textbuf        : tsysbufferaddress;
                  VAR view_arr       : tsyspointerarr;
                  VAR from_tab_priv  : tprivilege;
                  VAR viewpriv       : tprivilege;
                  tabno              : integer;
                  VAR p_arr          : tsyspointerarr;
                  VAR check_upd_priv : boolean);
-----------------------------------------------------------
 
The procedure checks the compatibility of the privileges of the view to be
created (viewpriv) with the system information of a table in the FROM part of
the view definition.
 
The tbaserecords of the view are specified by view_arr, while those of the From
table under consideration are described by p_arr. View_priv contains the
privileges of the view valid up to this point in time; from_tab_priv contains
the privileges of the owner of the view with respect to the From table under
consideration. The parameter check_upd_priv specifies whether the Update
privilege has to be checked. For each column of the From table, it is first of
all checked whether it is a mandatory column. If this is the case and if the
column is not contained in the select list of the view, the view is not capable
of Insert. If the owner of the view has the Update privilege on the column
under consideration, and if this column is referenced by the Select List, the
Update privilege on this column is entered in the set of the view privilege.
 
FUNCTION  AK16COLUMN_IN_VIEW (
                  VAR p_arr     : tsyspointerarr;
                  rec_no        : integer;
                  tab_no        : integer;
                  VAR extcolno  : integer;
                  VAR is_key    : boolean) : boolean;
-----------------------------------------------------------
 
The procedure returns TRUE if the column of a base table specified by tab_no
and rec_no is stored in the catalog information of type tbaserecord (p_arr),
i.e. if the column is referenced by a view. The external number of the column
in the Select List of the view is returned in extcolno.
 
PROCEDURE  AK16END_VIEW (
                  VAR acv  : all_command_glob;
                  VAR a16v : tak16_viewglob);
-----------------------------------------------------------
 
The procedure ensures the final building of the tbaserecords of the view and
then writes them to system file 1. The calling of a16_create_privrec further
ensures that the operations (Insert, Update, Delete) that the owner of the view
may perform on the view are determined. If there is an updatable join view,
information is created that is required for Update, Insert and Delete
(a59_prepare_join_check). The first system record of type tviewqual is finally
inserted into system file 1.
 
PROCEDURE  AK16BUILD_JOIN_CHECK (
                  VAR acv  : all_command_glob;
                  VAR a16v : tak16_viewglob);
-----------------------------------------------------------
 
In the case of updatable join views, the keys of all participating base tables
are specified in Insert, Update or Delete commands. It must then be checked
beforehand whether a row of the view exists that has these keys in the
corresponding columns. In order to be able to perform this join select
efficiently, the corresponding message buffers are built and inserted into the
system file already when the view is created. Apart from this Select prior to
an Update, it is necessary in the case of a view with check option also to
check the view qualification after the Update. This qualification is generally
different from the qualification before the Update. The corresponding catalog
information is written to the system file also for the select after the update.
 
The message buffer is built and inserted into the system file by the procedure
a59prepare_join_check. This procedure expects the qualification in the message
buffer. On entry into ak16build_join_check, the qualification may still contain
jump_false stack entries that, even in the case of TRUE, still contain a jump
specification in order to mark the parts that do not need checking in the check
after an update. Before the first call of a59prepare_join_check, these stack
entries are made into normal jump_false stack entries, because, in the select
prior to an Update, there are no parts of the qualification that are to be
jumped. Atcheckview = FALSE specifies that the message buffers are being built
for the select before the update.
 
If the view has been defined WITH CHECK OPTION, the catalog information for the
select after the update is then built. For this purpose, the message buffer is
first of all restored. The parts of the qualification that do not need checking
in the check after an update are removed from the qualification. atcheckview =
TRUE indicates to a59prepare_join_check that the catalog information for the
select after an update is now being built. This leads to the granting of other
system info keys (+100).
 
PROCEDURE  AK16ACT_JOINARR (
                  VAR acv  : all_command_glob;
                  VAR dmli : dml_info;
                  lwb      : integer;
                  upb      : integer);
-----------------------------------------------------------
 
A part of a qualification has been removed from the message buffer prior to an
a59prepare_join_check. The part that has been removed related to the stack
entries from lwb to upb. All join conditions that were described in this part
of the stack are removed. The positions must be adjusted in all join
descriptions whose stack entries were located after the part of the
qualification that has been removed.
 
PROCEDURE  A16NEW_BEXTCOLINDEX (VAR p_arr : tsyspointerarr);
-----------------------------------------------------------
 
In the first tbaserecord of the view tbaserecords specified by p_arr, correct
entries are made in the bextcolindex, the breccolindex, the bdefaultset and the
bmantoryset.
 
PROCEDURE  A16_RENAME_COLUMN  (
                  VAR acv  : all_command_glob;
                  VAR a16v : tak16_viewglob);
-----------------------------------------------------------
 
If the column names of the view to be created have been defined by a name list,
the names in the tbaserecords of the view are replaced by the procedure by
those specified by the user. The index of the first syntax-tree entry with the
description of the first column name is in a6collistpos. When all the column
names have been transferred from the SQL-PACKET to the corresponding column
information, the column descriptions must again be sorted according to the
column names (a06_sort).
 
PROCEDURE  AK16INIT_VIEWBASE_REC (
                  VAR acv  : all_command_glob;
                  VAR a16v : tak16_viewglob);
-----------------------------------------------------------
 
The characteristics of the view are finally written to the first tbaserecord of
the view.
 
.CM *-END-* description ---------------------------------
***********************************************************
.CM -lll-
Code    :
 
 
CONST
      c_derived_ind    = 10000;
      c_first_attempt  = true (* ak16_v_create_view *);
      c_basetable      = true (* a11get_check_table *);
      c_unload_allowed = true (* a11get_check_table *);
      c_any_priv       = true (* a11get_check_table *);
      c_all_base_rec   = true (* a11get_check_table *);
      c_add_rec        = true (* a10_add_repl_sysinfo*);
      c_is_rollback    = true;
      c_add_value      = true;
      c_update_entries = true;
      c_new_entries    = false;
 
TYPE
 
      tak16_colinfo = ARRAY[ 1..MAX_COL_PER_TAB_GG00 ] OF RECORD
            tabno    : tsp00_Int2;
            colno    : tsp00_Int2;
            extno    : tsp00_Int2;
            exttabno : tsp00_Int2;
      END;
 
      tak16_colprivlist = ARRAY[ 1..cak00_maxsources ] OF tak_columnset;
      tak16_colprivlist_ptr = ^tak16_colprivlist;
 
      tak16_queueelement = RECORD
            tabno    : tsp00_Int2;
            top      : tsp00_Int2;
            next     : tsp00_Int2;
            pred_cnt : tsp00_Int2;
      END;
 
 
      tak16_successor = RECORD
            tabno : tsp00_Int2;
            suc   : tsp00_Int2;
      END;
 
      tak16_queueelement_arr = ARRAY[ 0..cak00_maxsources ] OF tak16_queueelement;
      tak16_queueelement_arr_ptr = ^tak16_queueelement_arr;
 
      tak16_tabseq = RECORD
            seq_queue  : tak16_queueelement_arr_ptr;
            seq_stack  : ARRAY[ 1..120 ] OF tak16_successor;
            seq_st_ptr : integer;
      END;
 
      tak16_mantory  = ARRAY[ 1..cak00_maxsources ] OF tak_columnset;
      tak16_mantory_ptr  = ^tak16_mantory;
      tak16_link_type = ( is_pred, is_1_to_1 );
      tak16_link_set     = SET OF tak16_link_type;
      tak16_link_set_ptr = ^tak16_link_set;
      tak16_link_relation_ptr = ^tak16_link_set;
 
      tak16_linked_cols   = ARRAY[ 1..MAX_COL_PER_TAB_GG00 ] OF RECORD
            tabno1 : tsp00_Int2;
            recno1 : tsp00_Int2;
            tabno2 : tsp00_Int2;
            recno2 : tsp00_Int2;
      END;
 
      tak16_joinarr = ARRAY [ 1..cak00_maxsources ] OF tsp00_Int2;
      tak16_joinarr_ptr = ^tak16_joinarr;
 
      tak16_linkinfo = RECORD
            lmantory  : tak16_mantory_ptr;
            ljoins    : tak16_joinarr_ptr;
            ljoincnt  : integer;
            lcol_cnt  : integer;
            lpred     : tak16_link_relation_ptr;
            lcolinfo  : tak16_linked_cols;
            ltab_seq  : tak16_tabseq;
      END;
 
 
      tak16_viewglob   = RECORD      (* a16v *)
            a6qualexist      : boolean;
            a6sort           : boolean;
            a6comment        : boolean;
            a6expr_exist     : boolean;
            a6check_option   : boolean;
            a6check_view     : boolean;
            a6resort_joins   : boolean;
            a6replace        : boolean;
            a6replace_view   : boolean;
            a6add_rec        : boolean;
            a6col_list       : boolean;
            a6tablekind      : tgg00_TableKind;
            a6view_kind      : tgg00_TableKind;
            a6systable       : boolean;
            a6noUsageRef     : boolean;
            a6segmentid      : tsp00_C2;
            a6viewtextbuf    : tak_sysbufferaddress;
            a6viewbuf        : tak_sysbufferaddress;
            a6vqual_basis    : tak_sysbufferaddress;
            a6vqual_stack    : tak_sysbufferaddress;
            a6vqual_join     : tak_sysbufferaddress;
            a6ti             : tsp00_Int4;
            a6expr_lastdata  : tsp00_Int4;
            a6keylen         : integer;
            a6mqual_pos      : integer;
            a6oldmaxcol      : integer;
            a6select_pos     : integer;
            a6rec_cnt        : integer;
            a6comment_set    : tak_columnset;
            a6col_map        : tak_colinteger;
            a6tableid        : tgg00_Surrogate;
            a6schemaid       : tgg00_Surrogate;
            a6viewkey        : tgg00_SysInfoKey;
            a6sequence       : ARRAY[ 1..cak00_maxsources ] OF tsp00_Int2;
            a6keylenarr      : ARRAY[ 1..cak00_maxsources ] OF tsp00_Int4;
            a6keycolcount    : ARRAY[ 1..cak00_maxsources ] OF tsp00_Int2;
            a6max_col        : ARRAY[ 1..cak00_maxsources ] OF tsp00_Int2;
            a6is_foreign_key : ARRAY[ 1..cak00_maxsources ] OF boolean;
            a6priv           : tak_privilege;
            a6public_priv    : tak_sprivilege;
            a6scheme_treeid  : tgg00_FileId;
      END;
 
      tak16_keyextno = ARRAY[ 1..cak00_maxsources, 1..cak_maxlinkcolumns ]
            OF tsp00_Int2;
      tak16_viewtabdef_arr = ARRAY[ 1..cak00_maxsources ] OF tak_viewtabdef;
      tak16_viewtabdef_arr_ptr = ^tak16_viewtabdef_arr;
 
 
(*------------------------------*) 
 
PROCEDURE
      a16_call_semantic (VAR acv : tak_all_command_glob);
 
VAR
      _a16v        : tak16_viewglob;
      _b_err       : tgg00_BasisError;
      _info        : tsp00_C32;
 
BEGIN
_a16v.a6ti           := acv.a_ap_tree^[ 0 ].n_lo_level;
_a16v.a6systable     :=
      ( acv.a_ap_tree^[ _a16v.a6ti ].n_subproc = cak_i_internal );
_a16v.a6noUsageRef  :=
      ( acv.a_ap_tree^[ _a16v.a6ti ].n_subproc = cak_i_no       );
_a16v.a6replace_view :=
      ( acv.a_ap_tree^[ _a16v.a6ti ].n_pos = ord( true ) );
_a16v.a6select_pos   := acv.a_ap_tree^[ _a16v.a6ti ].n_length;
_a16v.a6replace  := _a16v.a6replace_view;
&ifdef trace
t01bool (ak_sem, 'a6replace   ', _a16v.a6replace);
&endif
_a16v.a6add_rec := ( acv.a_internal_sql <> sql_alter_table ) AND
      NOT _a16v.a6replace;
IF  acv.a_count_variab <> 0
THEN
    a07_b_put_error( acv, e_variable_not_allowed, 1 )
ELSE
    IF  acv.a_from_select OR ( acv.a_fromsel_n > 0 )
    THEN
        BEGIN
        _info := 'SELECT IN FROM PART OF VIEW     ';
        a07_const_b_put_error( acv, e_not_implemented, 1, @_info,
              sizeof( _info ) )
        END
    ELSE
        BEGIN
        ak16create_view( acv, _a16v, c_first_attempt );
        ak16rest_of_view_create( acv, _a16v );
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  acv.a_returncode <> 0
THEN
    IF  ( acv.a_returncode =
        a071_return_code( e_only_one_recordtype_allowed, acv.a_sqlmode ) ) OR
        ( acv.a_returncode      = cak_e_corelated_subquery_not_allowed )  OR
        ( acv.a_main_returncode = cak_e_corelated_subquery_not_allowed )
    THEN
        BEGIN
        _a16v.a6ti          := acv.a_ap_tree^[ 0 ].n_lo_level;
        acv.a_part_rollback := false;
        acv.a_returncode      := 0;
        acv.a_main_returncode := 0;
        acv.a_errorpos        := 0;
        acv.a_main_errorpos   := 0;
        acv.a_err_parm_cnt                 := 0;
        _a16v.a6viewkey.sentrytyp := cak_etempviewdesc;
        _a16v.a6viewkey.slinkage  := cak_init_linkage;
        a10del_sysinfo( acv, _a16v.a6viewkey, _b_err );
        IF  _b_err <> e_ok
        THEN
            a07_b_put_error( acv, _b_err, 1 );
        (*ENDIF*) 
        _a16v.a6viewkey.sentrytyp := cak_etempviewtext;
        a10del_sysinfo( acv, _a16v.a6viewkey, _b_err );
        IF  _b_err <> e_ok
        THEN
            a07_b_put_error( acv, _b_err, 1 );
        (*ENDIF*) 
        ak16create_view( acv, _a16v, NOT c_first_attempt );
        ak16rest_of_view_create( acv, _a16v );
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  acv.a_returncode = cak_e_schema_mapped
THEN
    BEGIN
    acv.a_try_again       := true;
    acv.a_part_rollback   := false;
    acv.a_main_returncode := 0;
    acv.a_errorpos        := 0;
    acv.a_main_errorpos   := 0;
    acv.a_err_parm_cnt    := 0;
    _a16v.a6viewkey.sentrytyp := cak_etempviewdesc;
    _a16v.a6viewkey.slinkage  := cak_init_linkage;
    a10del_sysinfo( acv, _a16v.a6viewkey, _b_err );
    IF  _b_err <> e_ok
    THEN
        a07_b_put_error( acv, _b_err, 1 );
    (*ENDIF*) 
    _a16v.a6viewkey.sentrytyp := cak_etempviewtext;
    a10del_sysinfo( acv, _a16v.a6viewkey, _b_err );
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16increase_pos_after_long (VAR base_rec : tak_baserecord);
 
VAR
      _colind         : integer;
      _long_cnt       : integer;
      _col_ptr        : tak00_colinfo_ptr;
 
BEGIN
_colind := base_rec.bfirstcolind;
_long_cnt := 0;
WHILE _colind <> 0 DO
    BEGIN
    WITH base_rec.bcolumn[ _colind ]^ DO
        BEGIN
        ccolstack.epos := ccolstack.epos +
              _long_cnt * (mxsp_long_desc - SURROGATE_MXGG00);
        IF  (cdatatyp in [dlonga, dlongb, dlonguni, dstra, dstrb, dstruni ]) AND
            (cdatalen = SURROGATE_MXGG00)
        THEN
            _long_cnt := succ(_long_cnt);
        (*ENDIF*) 
        _colind := cnextind
        END
    (*ENDWITH*) 
    END;
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16create_view (
            VAR acv       : tak_all_command_glob;
            VAR a16v      : tak16_viewglob;
            first_attempt : boolean);
 
VAR
      _new_table    : boolean;
      _dummy        : boolean;
      _tab_kind     : tgg00_TableKind;
      _ix           : integer;
      _jx           : integer;
      _err_ti       : integer;
      _init_ex_kind : tak_execution_kind;
      _a16dmli      : tak_dml_info;
      _a16keyextno   : tak16_keyextno;
 
BEGIN
FOR _ix := 1 TO cak00_maxsources DO
    FOR _jx := 1 TO cak_maxlinkcolumns DO
        _a16keyextno[_ix, _jx] := -1;
    (*ENDFOR*) 
(*ENDFOR*) 
acv.a_ptr1          := NIL;
acv.a_p_arr1.pbasep := NIL;
_init_ex_kind       := acv.a_ex_kind;
acv.a_ex_kind       := parsing_executing;
acv.a_special_expr  := true;
acv.a_fromsel_n     := 0;
a16v.a6keylen       := 0;
a16v.a6sort         := false;
a16v.a6comment      := false;
a16v.a6check_view   := false;
a16v.a6check_option := ( acv.a_ap_tree^[ a16v.a6ti ].n_symb = s_plus );
a16v.a6qualexist    := false;
a16v.a6resort_joins := false;
a16v.a6rec_cnt      := 0;
a16v.a6vqual_basis  := NIL;
a16v.a6vqual_stack  := NIL;
a16v.a6vqual_join   := NIL;
a16v.a6segmentid    := cak00_local_segment_id;
IF  first_attempt
THEN
    a16v.a6tableid := cgg_zero_id;
(*ENDIF*) 
a16v.a6schemaid                    := acv.a_curr_schema_id;
a16v.a6scheme_treeid.fileRoot_gg00 := NIL_PAGE_NO_GG00;
acv.a_info_output := false;
a54_dml_init( acv, _a16dmli, false );
IF  NOT first_attempt
THEN
    _a16dmli.d_phase_cnt := cak_complex_view_indicator;
(*ENDIF*) 
IF  acv.a_internal_sql <> sql_alter_table
THEN
    a10_cache_delete( acv, NOT c_is_rollback );
(*ENDIF*) 
acv.a_viewname := a01_il_b_identifier;
a16v.a6ti      := acv.a_ap_tree^[ a16v.a6ti ].n_lo_level;
_err_ti        := a16v.a6ti;
_new_table     :=
      ( acv.a_internal_sql <> sql_alter_table ) AND NOT a16v.a6replace;
a11get_check_table( acv, _new_table,
      NOT c_basetable, NOT c_unload_allowed, [  ],
      c_any_priv, c_all_base_rec, d_fix, a16v.a6ti,
      _a16dmli.d_viewusername, _a16dmli.d_viewtablen, _a16dmli.d_sparr );
&ifdef trace
t01lidentifier( ak_sem, _a16dmli.d_viewusername );
t01lidentifier( ak_sem, _a16dmli.d_viewtablen );
&endif
IF  acv.a_returncode = 0
THEN
    IF  _new_table
    THEN
        BEGIN
        a103CheckCreateInPrivilege (acv, _a16dmli.d_viewusername, 1);
        IF  acv.a_returncode = 0
        THEN
            a103GetSchemaId (acv, _a16dmli.d_viewusername, 1, a16v.a6schemaid);
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        (* PTS 1140510 *)
        a101_InvalidateListAppend (acv,
              _a16dmli.d_sparr.pbasep^.sbase.bschema,
              _a16dmli.d_sparr.pbasep^.sbase.btablen^);
        (* remark record count of existing view *)
        a16v.a6rec_cnt  := _a16dmli.d_sparr.pbasep^.sbase.breccnt;
        a16v.a6schemaid := _a16dmli.d_sparr.pbasep^.sbase.bschema;
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  a16v.a6replace
THEN
    BEGIN
    IF  acv.a_returncode = 0
    THEN
        BEGIN
        IF  a16v.a6replace_view
        THEN
            (* replace view *)
            BEGIN
            IF  NOT ( _a16dmli.d_sparr.pbasep^.sbase.btablekind in
                [ tonebase, tview, tcomplexview ] )
            THEN
                a07_nb_put_error( acv, e_missing_viewtable,
                      acv.a_ap_tree^[ _err_ti ].n_pos,
                      _a16dmli.d_sparr.pbasep^.sbase.btablen^ )
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  acv.a_returncode = 0
        THEN
            BEGIN
            ak16store_old_view_image( acv, a16v, _a16dmli );
            END
        (*ENDIF*) 
        END
    ELSE
        IF  ( acv.a_returncode =
            a071_return_code( e_unknown_tablename, acv.a_sqlmode ) )
            AND
            a16v.a6replace_view
        THEN
            (* it's a real CREATE command but given as *)
            (* CREATE OR REPLACE ... *)
            BEGIN
&           ifdef trace
            t01name (ak_sem, 'reset a6replace   ');
&           endif
            acv.a_returncode := 0;
            acv.a_errorpos   := 0;
            a16v.a6replace := false;
            a16v.a6add_rec := true;
            a103CheckCreateInPrivilege (acv, _a16dmli.d_viewusername, 1);
            IF  acv.a_returncode = 0
            THEN
                a103GetSchemaId (acv, _a16dmli.d_viewusername, 1, a16v.a6schemaid);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
acv.a_viewSchemaId := a16v.a6schemaid;
acv.a_viewname     := _a16dmli.d_viewtablen;
IF  acv.a_returncode = 0
THEN
    BEGIN
    IF  ( acv.a_internal_sql = sql_alter_table ) OR a16v.a6replace
    THEN
        BEGIN
        a16v.a6tableid     := _a16dmli.d_sparr.pbasep^.sbase.bsurrogate;
        _a16dmli.d_tableid := _a16dmli.d_sparr.pbasep^.sbase.bsurrogate;
        ak16save_priv_comments( a16v, _a16dmli );
        IF  a16v.a6replace
        THEN (* PTS 1128523 *)
            ak16SetSystemProperty ( acv, _a16dmli.d_sparr.pbasep^.sbase, a16v.a6systable );
        (*ENDIF*) 
        a10table_cache_delete( acv, _a16dmli.d_tableid );
        END
    ELSE
        IF  first_attempt
        THEN
            BEGIN
            _tab_kind := tview;
            a11table_reference( acv,
                  a16v.a6schemaid, _a16dmli.d_viewtablen,
                  _tab_kind, false, a16v.a6systable, _a16dmli.d_tableid );
            a16v.a6tableid := _a16dmli.d_tableid
            END
        ELSE
            (* table id has been assigned in first attempt *)
            _a16dmli.d_tableid := a16v.a6tableid;
        (*ENDIF*) 
    (*ENDIF*) 
    acv.a_is_ddl := ddl_create_view;
    a16v.a6ti    := acv.a_ap_tree^[ a16v.a6ti ].n_lo_level;
    IF  acv.a_ap_tree^[ a16v.a6ti ].n_proc = a16
    THEN
        (* columnname-list given *)
        BEGIN
        _a16dmli.d_view_col_node := acv.a_ap_tree^[ a16v.a6ti ].n_sa_level;
        _a16dmli.d_view_col_list := ( _a16dmli.d_view_col_node <> 0 );
        a16v.a6ti                := acv.a_ap_tree^[ a16v.a6ti ].n_lo_level;
        END
    ELSE
        _a16dmli.d_view_col_list := false;
    (*ENDIF*) 
    a16v.a6col_list           := _a16dmli.d_view_col_list;
    _a16dmli.d_view           := true;
    _a16dmli.d_only_sem_check := true;
    _a16dmli.d_resname_found  := NOT _a16dmli.d_view_col_list;
    ak16get_viewtext_buf( acv, a16v, _a16dmli );
    IF  acv.a_returncode = 0
    THEN
        BEGIN
        acv.a_unionrec_ptr  := NIL;
        acv.a_p_arr1.pcount := 0;
        acv.a_p_arr1.pbasep := NIL;
        acv.a_from_select   := false;
        acv.a_union_cnt     := 0;
        a660select( acv, a16v.a6ti, _a16dmli, _dummy );
&       ifdef trace
        t01messblock (ak_sem, 'a16 mblock  ', acv.a_mblock);
&       endif
        END;
    (*ENDIF*) 
    IF  a101_AnySchemaMapped(acv)
    THEN
        BEGIN
        a101_RenameSchemaNames (acv);
        IF  acv.a_returncode = 0
        THEN
            acv.a_returncode := cak_e_schema_mapped;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  acv.a_returncode = 0
    THEN
        BEGIN
        a16v.a6check_view   := false;
        IF  ( a16v.a6check_option OR
            (* updateable joinview needs WITH CHECK OPTION *)
            ( _a16dmli.d_cntfromtab = 1 ))
        THEN
            (* inheritance of WITH CHECK OPTION *)
            FOR _ix := 1 TO _a16dmli.d_cntfromtab DO
                IF  _a16dmli.d_tabarr^[ _ix ].oviewcheck
                THEN
                    a16v.a6check_view := true;
                (*ENDIF*) 
            (*ENDFOR*) 
        (*ENDIF*) 
        IF  _a16dmli.d_outer_join
        THEN
            _a16dmli.d_phase_cnt := cak_complex_view_indicator;
        (*ENDIF*) 
        IF  acv.a_date_time_used
        THEN
            _a16dmli.d_esparr.pbasep^.sbase.bview_attributes :=
                  _a16dmli.d_esparr.pbasep^.sbase.bview_attributes + [va_date_time_used];
        (*ENDIF*) 
        IF  _a16dmli.d_phase_cnt = cak_complex_view_indicator
        THEN
            BEGIN
            IF  _a16dmli.d_corr <> no_correlation
            THEN
                IF  acv.a_ap_tree^[ a16v.a6ti ].n_subproc <>
                    cak_x_start_union
                THEN
                    _a16dmli.d_esparr.pbasep^.sbase.bview_attributes :=
                          _a16dmli.d_esparr.pbasep^.sbase.bview_attributes + [va_correlation];
                (*ENDIF*) 
            (*ENDIF*) 
            a16v.a6view_kind := tcomplexview
            END
        ELSE
            BEGIN
            IF  _a16dmli.d_maxcounttabs = 1
            THEN
                a16v.a6view_kind := tonebase
            ELSE
                a16v.a6view_kind := tview;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        a16v.a6tablekind := a16v.a6view_kind;
        ak16viewtext_definition( acv, a16v, _a16dmli );
        END;
    (*ENDIF*) 
    IF  a16v.a6replace AND ( acv.a_returncode = 0 )
    THEN
        ak16compare_structure( acv, a16v, _a16dmli );
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  ( acv.a_returncode = 0 ) AND a16v.a6add_rec
THEN
    (* create permanent table reference entry *)
    ak16table_ref( acv, a16v, _a16dmli );
(*ENDIF*) 
IF  ( acv.a_returncode = 0 ) AND
    ( _a16dmli.d_phase_cnt < cak_complex_view_indicator )
THEN
    ak16add_view_qualification( acv, a16v, _a16dmli, _a16keyextno );
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    ak16end_view( acv, a16v, _a16dmli, _a16keyextno );
(*ENDIF*) 
;
a54_dml_finalize( _a16dmli, acv.a_transinf.tri_trans );
IF  acv.a_returncode = 0
THEN
    acv.a_error_tableid := a16v.a6tableid;
(*ENDIF*) 
acv.a_ex_kind := _init_ex_kind;
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16act_joinarr (
            VAR a16dmli : tak_dml_info;
            lwb      : integer;
            upb      : integer);
 
VAR
      _i, _j : integer;
 
BEGIN
_i := 0;
&ifdef TRACE
t01int4( ak_sem, 'lwb =       ', lwb );
t01int4( ak_sem, 'upb =       ', upb );
&endif
WHILE _i < a16dmli.d_joins.jrc_cnt DO
    WITH a16dmli.d_joins.jrc_joinarr^[ _i ], jo_recs[ 1 ] DO
        BEGIN
&       ifdef TRACE
        t01int4( ak_sem, 'jstartstack=', jop_startstack );
&       endif
        IF  jop_startstack >= lwb
        THEN
            IF  jop_startstack > upb
            THEN
                BEGIN
                jop_startstack := jop_startstack - ( upb - lwb );
                jo_recs[ 2 ].jop_startstack:= jo_recs[ 2 ].jop_startstack
                      - ( upb - lwb )
                END
            ELSE
                BEGIN
                FOR _j := _i + 1 TO a16dmli.d_joins.jrc_cnt DO
                    a16dmli.d_joins.jrc_joinarr^[ _j - 1 ] :=
                          a16dmli.d_joins.jrc_joinarr^[ _j ];
                (*ENDFOR*) 
                a16dmli.d_joins.jrc_cnt := pred( a16dmli.d_joins.jrc_cnt );
                _i := pred( _i );
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        _i := succ( _i );
        END;
    (*ENDWITH*) 
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16add_view_qualification (
            VAR acv         : tak_all_command_glob;
            VAR a16v        : tak16_viewglob;
            VAR a16dmli     : tak_dml_info;
            VAR a16keyextno : tak16_keyextno);
 
VAR
      _rest_len        : tsp00_Int4;
      _move_len        : tsp00_Int4;
      _stpointer       : tsp00_Int4;
      _qual_val_len    : tsp00_Int4;
      _data_pos        : tsp00_Int4;
      _vdatapos        : tsp00_Int4;
      _i               : tsp00_Int4;
      _write_idx       : tsp00_Int4;
      _viewpos         : tsp00_Int2;
      _b_err           : tgg00_BasisError;
      _first_value     : boolean;
 
BEGIN
_data_pos     := 0;
_qual_val_len := 0;
_b_err        := e_ok;
(* assume that all data count for expression columns *)
(* therefore last data position = mb_data_len        *)
a16v.a6expr_lastdata := acv.a_mblock.mb_data_len;
(* let mcol_pos points to output columns, mcol_cnt is amount of output cols *)
acv.a_mblock.mb_qual^.mcol_pos  := acv.a_mblock.mb_qual^.mqual_pos;
(* let mqual_pos points to qualification *)
acv.a_mblock.mb_qual^.mqual_pos := acv.a_mblock.mb_qual^.mqual_pos +
      acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mqual_pos ].epos - 1;
acv.a_mblock.mb_qual^.mcol_cnt  := acv.a_mblock.mb_qual^.mqual_pos -
      acv.a_mblock.mb_qual^.mcol_pos;
acv.a_mblock.mb_qual^.mqual_cnt := acv.a_mblock.mb_qual^.mfirst_free -
      acv.a_mblock.mb_qual^.mqual_pos;
IF  acv.a_mblock.mb_qual^.mqual_cnt = 0
THEN
    a16dmli.d_esparr.pbasep^.sbase.bv_checkopt := false;
(*ENDIF*) 
_stpointer       := acv.a_mblock.mb_qual^.mqual_pos;
a16v.a6mqual_pos := _stpointer;
IF  a16v.a6check_option
THEN
    BEGIN
    (* mview_pos point to qualification for WITH CHECK OPTIION *)
    acv.a_mblock.mb_qual^.mview_pos := _stpointer;
    IF  acv.a_sqlmode = sqlm_ansi
    THEN
        ak16destroy_jump_insupd( acv );
    (*ENDIF*) 
    END;
(*ENDIF*) 
;
&ifdef TRACE
t01messblock( ak_sem, 'view mblock ', acv.a_mblock );
&endif
(* create viewqual_basis record *)
a16v.a6viewkey.sentrytyp := cak_eviewqual_basis;
a16v.a6viewkey.slinkage  := cak_init_linkage;
a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_fix,
      sizeof( tak_viewqual_basis_record ), a16v.a6vqual_basis, _b_err );
IF  _b_err = e_ok
THEN
    BEGIN
    a16v.a6vqual_basis^.sviewqual_basis.vsegmentid      := a16v.a6segmentid;
    a16v.a6vqual_basis^.sviewqual_basis.vjoin_exists    := false;
    a16v.a6vqual_basis^.sviewqual_basis.vstack_exists   := false;
    a16v.a6vqual_basis^.sviewqual_basis.vderived_exists := false;
    a16v.a6vqual_basis^.sviewqual_basis.vfiller         := false;
    (* precondition: all information fit in one record *)
    ak16basetabs_to_qualrec( acv, a16v, a16dmli, a16keyextno );
    ;
    (* don't put this record in catalog, this will be done in ak16end_view() *)
    END;
(*ENDIF*) 
;
(* create viewqual_join record *)
IF  ( a16dmli.d_joins.jrc_cnt > 0 ) AND ( _b_err = e_ok )
THEN
    BEGIN
&   ifdef trace
    t01name( ak_sem, 'write vqual join  ' );
&   endif
    ak16join_information( acv, a16v, a16dmli,
          _stpointer, c_new_entries, _b_err );
    END;
(*ENDIF*) 
;
(* create viewqual_stack record *)
IF  ( acv.a_mblock.mb_qual^.mqual_cnt > 0 ) AND ( _b_err = e_ok )
THEN
    BEGIN
&   ifdef trace
    t01name( ak_sem, 'write vqual stack ' );
&   endif
    a16v.a6qualexist := true;
    _first_value     := true;
    a16v.a6vqual_basis^.sviewqual_basis.vstack_exists := true;
    a16v.a6viewkey.sentrytyp := cak_eviewqual_stack;
    a16v.a6viewkey.slinkage  := cak_init_linkage;
    a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_fix,
          sizeof ( tak_viewqual_stack_record ), a16v.a6vqual_stack, _b_err );
    IF  _b_err = e_ok
    THEN
        BEGIN
        IF  NOT ( a16v.a6check_option ) AND a16v.a6check_view
        THEN
            (* current view without WITH CHECK OPTION and *)
            (* underlying view(s) with WITH CHECK OPTION  *)
            a16v.a6vqual_stack^.sviewqual_stack.vview_offs :=
                  acv.a_mblock.mb_qual^.mview_pos - _stpointer
        ELSE
            a16v.a6vqual_stack^.sviewqual_stack.vview_offs := 0;
        (*ENDIF*) 
        _viewpos := a16v.a6vqual_stack^.sviewqual_stack.vview_offs;
        a16v.a6vqual_stack^.sviewqual_stack.vsegmentid := a16v.a6segmentid;
        a16v.a6vqual_stack^.sviewqual_stack.vfiller    := '00';
        a16v.a6vqual_stack^.sviewqual_stack.vstcount   :=
              acv.a_mblock.mb_qual^.mqual_cnt;
        a16v.a6vqual_stack^.sviewqual_stack.vdatapos   := 0;
        a16v.a6vqual_stack^.sviewqual_stack.vdatalen   := 0;
        a16v.a6viewbuf := a16v.a6vqual_stack;
        END;
    (*ENDIF*) 
    _i         := 1;
    _write_idx := 1;
    WHILE ( _i <= acv.a_mblock.mb_qual^.mqual_cnt ) AND
          ( _b_err = e_ok ) DO
        BEGIN
        IF  _write_idx > cak_max_viewqual_stack
        THEN
            (* record overflow handling *)
            BEGIN
            ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec,
                  sizeof( a16v.a6viewbuf^.sviewqual_stack ) -
                  sizeof( a16v.a6viewbuf^.sviewqual_stack.vstack ) +
                  ( _write_idx - 1 ) *
                  sizeof(  a16v.a6viewbuf^.sviewqual_stack.vstack[ 1 ] ),
                  _b_err );
            IF  _b_err = e_ok
            THEN
                (* get new catalog record *)
                BEGIN
                a06inc_linkage( a16v.a6viewkey.slinkage );
                a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
                      sizeof( tak_viewqual_stack_record ),
                      a16v.a6viewbuf, _b_err );
                IF  _b_err = e_ok
                THEN
                    BEGIN
                    a16v.a6viewbuf^.sviewqual_stack.vsegmentid := a16v.a6segmentid;
                    a16v.a6viewbuf^.sviewqual_stack.vfiller    := '00';
                    a16v.a6viewbuf^.sviewqual_stack.vview_offs := _viewpos;
                    a16v.a6viewbuf^.sviewqual_stack.vstcount   :=
                          acv.a_mblock.mb_qual^.mqual_cnt;
                    (* write temporary datapos/datalen *)
                    a16v.a6viewbuf^.sviewqual_stack.vdatapos   := 0;
                    a16v.a6viewbuf^.sviewqual_stack.vdatalen   := 0;
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            _write_idx := 1;
            END;
        (*ENDIF*) 
        IF  _b_err = e_ok
        THEN
            BEGIN
            (* write stack information *)
            a16v.a6viewbuf^.sviewqual_stack.vstack[ _write_idx ] :=
                  acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mqual_pos + _i - 1 ];
            IF  _first_value AND
                ( acv.a_mblock.
                mb_st^[ acv.a_mblock.mb_qual^.mqual_pos + _i - 1 ].etype in
                [ st_value, st_language, st_format, st_date,
                st_time, st_timestamp,
                (* PTS 1116175 E.Z. *)
                st_utcdate,
                (* PTS 1109925 E.Z. *)
                st_utcdiff, st_user, st_usergroup, st_current_schema,
                st_uid, st_sysdba, st_localsysdba, st_transaction,
                st_timezone (* PTS 1122262 E.Z. *)
                ,
                st_dummy] )
            THEN
                BEGIN
                _first_value  := false;
                _data_pos     := acv.a_mblock.
                      mb_st^[ acv.a_mblock.mb_qual^.mqual_pos + _i - 1 ].epos;
                _qual_val_len := acv.a_mblock.mb_data_len - ( _data_pos - 1 );
                (* remark last data position for expression columns *)
                a16v.a6expr_lastdata  := _data_pos - 1;
&               ifdef TRACE
                t01int4( ak_sem, 'qual_val_len', _qual_val_len );
                t01int4( ak_sem, 'expcol data ', a16v.a6expr_lastdata );
&               endif
                END;
&           ifdef TRACE
            (*ENDIF*) 
            t01stackentry( ak_sem, a16v.a6viewbuf^.sviewqual_stack.
                  vstack[ _write_idx ], _i );
&           endif
            END;
        (*ENDIF*) 
        _i         := succ( _i );
        _write_idx := succ( _write_idx );
        END;
    (*ENDWHILE*) 
    ;
    (* remark record length *)
    a16v.a6viewbuf^.b_sl := sizeof( a16v.a6viewbuf^.sviewqual_stack ) -
          sizeof( a16v.a6viewbuf^.sviewqual_stack.vstack ) +
          ( _write_idx - 1 ) *
          sizeof(  a16v.a6viewbuf^.sviewqual_stack.vstack [ 1 ] );
    (* append view qualification data  *)
    IF  ( _qual_val_len > 0 ) AND ( _b_err = e_ok )
    THEN
        BEGIN
&       ifdef trace
        t01name( ak_sem, 'write vqual data  ' );
&       endif
        _vdatapos := ( acv.a_mblock.mb_qual^.mqual_cnt ) *
              sizeof(  a16v.a6viewbuf^.sviewqual_stack.vstack [ 1 ] ) + 1;
        (* calculate relative record data position *)
        _i := _vdatapos MOD cak_max_viewqual_data;
        IF  _i = 0
        THEN
            _i := cak_max_viewqual_data;
        (*ENDIF*) 
        ;
&       ifdef trace
        t01int4( ak_sem, 'vdatapos    ', _vdatapos );
&       endif
        (* check, if we need a new record *)
        IF  _i = 1
        THEN
            BEGIN
            (* record length already written *)
            ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec, 0, _b_err );
            IF  _b_err = e_ok
            THEN
                (* get new catalog record *)
                BEGIN
                a06inc_linkage( a16v.a6viewkey.slinkage );
                a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
                      sizeof( tak_viewqual_stack_record ),
                      a16v.a6viewbuf, _b_err );
                IF  _b_err = e_ok
                THEN
                    BEGIN
                    a16v.a6viewbuf^.sviewqual_stack.vsegmentid :=
                          a16v.a6segmentid;
                    a16v.a6viewbuf^.sviewqual_stack.vview_offs := _viewpos;
                    a16v.a6viewbuf^.sviewqual_stack.vstcount   :=
                          acv.a_mblock.mb_qual^.mqual_cnt;
                    a16v.a6viewbuf^.b_sl :=
                          sizeof( tak_viewqual_stack_record ) -
                          sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata );
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        _rest_len := _qual_val_len;
        WHILE ( _rest_len > 0 ) AND ( _b_err = e_ok ) DO
            BEGIN
            a16v.a6viewbuf^.sviewqual_stack.vdatapos := _vdatapos;
            a16v.a6viewbuf^.sviewqual_stack.vdatalen := _qual_val_len;
            IF  _rest_len > sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata ) -
                ( _i - 1 )
            THEN
                _move_len   := sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata ) -
                      ( _i - 1 )
            ELSE
                _move_len := _rest_len;
            (*ENDIF*) 
&           ifdef trace
            t01int4( ak_sem, '_rest_len   ', _rest_len );
            t01int4( ak_sem, '_move_len   ', _move_len );
            t01moveobj( ak_sem, acv.a_mblock.mb_data^.mbp_buf,
                  _data_pos, _data_pos + _move_len - 1 );
&           endif
            SAPDB_PascalMove ('VAK16 ',   1,    
                  acv.a_mblock.mb_data_size,
                  sizeof( a16v.a6viewbuf^.sviewqual_stack ),
                  @acv.a_mblock.mb_data^.mbp_buf, _data_pos,
                  @a16v.a6viewbuf^.sviewqual_stack, a16v.a6viewbuf^.b_sl + 1,
                  _move_len, _b_err);
            _data_pos := _data_pos + _move_len;
            _rest_len := _rest_len - _move_len;
            IF  _rest_len > 0
            THEN
                (* record overflow handling *)
                BEGIN
                _i := 1;
                ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec,
                      a16v.a6viewbuf^.b_sl + _move_len, _b_err );
                IF  _b_err = e_ok
                THEN
                    (* get new catalog record *)
                    BEGIN
                    a06inc_linkage( a16v.a6viewkey.slinkage );
                    a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
                          sizeof( tak_viewqual_stack_record ),
                          a16v.a6viewbuf, _b_err );
                    IF  _b_err = e_ok
                    THEN
                        BEGIN
                        a16v.a6viewbuf^.sviewqual_stack.vsegmentid :=
                              a16v.a6segmentid;
                        a16v.a6viewbuf^.sviewqual_stack.vview_offs := _viewpos;
                        a16v.a6viewbuf^.sviewqual_stack.vstcount   :=
                              acv.a_mblock.mb_qual^.mqual_cnt;
                        a16v.a6viewbuf^.b_sl :=
                              sizeof( tak_viewqual_stack_record ) -
                              sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata );
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        ;
        (* write last data record *)
        ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec,
              a16v.a6viewbuf^.b_sl + _move_len, _b_err );
        (* write correct vdatapos, vdatalen in records with stack entries *)
        a16v.a6viewkey.slinkage := cak_zero_linkage;
        _i := a16v.a6viewbuf^.sviewqual_stack.vstcount;
        WHILE _i > 0 DO
            BEGIN
            a06inc_linkage( a16v.a6viewkey.slinkage );
            a10get_sysinfo( acv, a16v.a6viewkey, d_release, a16v.a6viewbuf,
                  _b_err);
            IF  _b_err = e_ok
            THEN
                BEGIN
                a16v.a6viewbuf^.sviewqual_stack.vdatapos := _vdatapos;
                a16v.a6viewbuf^.sviewqual_stack.vdatalen := _qual_val_len;
                a10repl_sysinfo( acv, a16v.a6viewbuf, _b_err );
                END;
            (*ENDIF*) 
            _i := _i - cak_max_viewqual_stack;
            END;
        (*ENDWHILE*) 
        END
    ELSE
        (* write last stack record; record length was already written *)
        ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec, 0, _b_err );
    (*ENDIF*) 
    END;
(*ENDIF*) 
;
(* create viewqual_stack record for expression columns *)
IF  _b_err = e_ok
THEN
    BEGIN
&   ifdef trace
    t01name( ak_sem, 'write vqual expcol' );
&   endif
    a16v.a6viewkey.sentrytyp := cak_eviewqual_expcol;
    a16v.a6viewkey.slinkage  := cak_init_linkage;
    a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
          sizeof( tak_viewqual_stack_record ), a16v.a6viewbuf, _b_err );
    IF  _b_err = e_ok
    THEN
        BEGIN
        a16v.a6viewbuf^.sviewqual_stack.vsegmentid := a16v.a6segmentid;
        a16v.a6viewbuf^.sviewqual_stack.vview_offs := 0;
        a16v.a6viewbuf^.sviewqual_stack.vfiller    := '00';
        a16v.a6viewbuf^.sviewqual_stack.vdatapos   := 0;
        a16v.a6viewbuf^.sviewqual_stack.vdatalen   := 0;
        ak16expression_cols( acv, a16v, a16dmli );
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  _b_err <> e_ok
THEN
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16basetabs_to_qualrec (
            VAR acv         : tak_all_command_glob;
            VAR a16v        : tak16_viewglob;
            VAR a16dmli     : tak_dml_info;
            VAR a16keyextno : tak16_keyextno);
 
VAR
      _first    : boolean;
      _ok       : boolean;
      _i, _j    : integer;
      _dstate   : tak_directory_state;
      _keyind   : integer;
 
BEGIN
WITH a16v.a6vqual_basis^, sviewqual_basis DO
    BEGIN
&   ifdef TRACE
    t01str30( ak_sem, 'Tabellen im From Part :       ' );
    FOR _i := 1 TO a16dmli.d_cntfromtab DO
        BEGIN
        t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _i ].ouser );
        t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _i ].otable );
        END;
    (*ENDFOR*) 
&   endif
    a16dmli.d_sparr.pbasep := NIL;
    (* resolve tables belongs to views *)
    a54_joinview_baserecords( acv, a16dmli );
    IF  ( a16dmli.d_cntfromtab > cak_max_viewqual_tab )
    THEN
        a07_b_put_error( acv, e_too_many_sourcetables, 1 );
    (*ENDIF*) 
    IF  acv.a_returncode = 0
    THEN
        BEGIN
        a10rel_sysinfo( a16dmli.d_sparr.pbasep );
        IF  a16v.a6view_kind = tonebase
        THEN
            _dstate := d_fix
        ELSE
            _dstate := d_release;
        (*ENDIF*) 
&       ifdef trace
        t01int4( ak_sem, 'a6view_kind ', ord( a16v.a6view_kind ) );
&       endif
        a16v.a6vqual_basis^.sviewqual_basis.vbasetabcnt := a16dmli.d_cntfromtab;
        (* table infos *)
        FOR _i := 1 TO a16dmli.d_cntfromtab DO
            WITH a16v.a6vqual_basis^.sviewqual_basis.vtable[ _i ] DO
                BEGIN
&               ifdef TRACE
                t01str30( ak_sem, 'Referenzierte Basistabelle :  ' );
                t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _i ].ouser );
                t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _i ].otable );
&               endif
                vttableid     := a16dmli.d_tabarr^[ _i ].otreeid.fileTabId_gg00;
                vtins_for_upd := true;
                vtone_to_one  := ( a16dmli.d_cntfromtab = 1 );
                _j            := 1;
                _first        := true;
                WHILE ( _j < _i ) AND ( _first ) DO
                    IF  ( a16dmli.d_tabarr^[ _j ].otreeid.fileTabId_gg00 =
                        vttableid)
                    THEN
                        _first := false
                    ELSE
                        _j := succ( _j );
                    (*ENDIF*) 
                (*ENDWHILE*) 
                IF  _first
                THEN
                    BEGIN
                    a06_systable_get( acv, _dstate, vttableid,
                          a16dmli.d_sparr.pbasep, true (* get all *), _ok );
                    IF  NOT ( _ok )
                    THEN
                        a07ak_system_error( acv, 16, 1 )
                    ELSE
                        BEGIN
                        WITH a16dmli.d_sparr.pbasep^.sbase DO
                            BEGIN
                            a16v.a6is_foreign_key[ _i ] :=
                                  ( is_secondary_table in blinkexist );
                            a16v.a6keycolcount[ _i ]    := bkeycolcount;
                            IF  bkeycolcount <= cak_maxlinkcolumns
                            THEN
                                BEGIN
                                _keyind := bfirstcolind;
                                FOR _j := 1 TO bkeycolcount DO
                                    WITH a16dmli.d_sparr.pbasep^.sbase.
                                         bcolumn[ _keyind ]^ DO
                                        BEGIN
                                        (* remark extern columns for table _i *)
                                        a16keyextno[ _i, _j ] := cextcolno;
                                        _keyind              := cnextind
                                        END;
                                    (*ENDWITH*) 
                                (*ENDFOR*) 
                                END;
                            (*ENDIF*) 
                            a16v.a6max_col [ _i ] := bmaxcol;
                            vtnot_used_links      := [  ];
                            WITH a16dmli.d_sparr.pbasep^.sbase,
                                 bcolumn[ blastkeyind ]^ DO
                                a16v.a6keylenarr[ _i ] := ccolstack.epos +
                                      cinoutlen - 1;
                            (*ENDWITH*) 
                            END;
                        (*ENDWITH*) 
                        END;
                    (*ENDIF*) 
                    END
                ELSE
                    (* table already in vtable[] *)
                    BEGIN
                    vtnot_used_links         := [  ];
                    vtins_for_upd            := vtable[ _j ].vtins_for_upd;
                    vtone_to_one             := vtable[ _j ].vtone_to_one;
                    a16v.a6keycolcount[ _i ] := a16v.a6keycolcount[ _j ];
                    a16keyextno[ _i ]        := a16keyextno[ _j ];
                    a16v.a6max_col[ _i ]     := a16v.a6max_col[ _j ];
                    a16v.a6is_foreign_key[ _i ] := a16v.a6is_foreign_key[ _j ];
                    END;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDFOR*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
a16v.a6vqual_basis^.b_sl := sizeof( a16v.a6vqual_basis^.sviewqual_basis ) -
      sizeof( a16v.a6vqual_basis^.sviewqual_basis.vtable ) +
      a16dmli.d_cntfromtab *
      sizeof( a16v.a6vqual_basis^.sviewqual_basis.vtable[ 1 ] );
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16build_join_check (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
VAR
      _rel_pos         : integer;
      _rest_len        : integer;
      _move_len        : integer;
      _data_pos        : integer;
      _distance        : integer;
      _b_err           : tgg00_BasisError;
      _treeid          : tgg00_FileId;
      _i               : tsp00_Int2;
      _j               : tsp00_Int2;
      _k               : tsp00_Int2;
      _mqual_pos       : tsp00_Int2;
      _jump_entries    : boolean;
 
BEGIN
_b_err := e_ok;
_k     := pred( acv.a_mblock.mb_qual^.mqual_pos );
(* set mqual_pos to output column list *)
acv.a_mblock.mb_qual^.mqual_pos := acv.a_mblock.mb_qual^.mcol_pos;
acv.a_mblock.mb_qual^.mqual_cnt := acv.a_mblock.mb_qual^.mqual_cnt +
      acv.a_mblock.mb_qual^.mcol_cnt;
_treeid := acv.a_mblock.mb_qual^.mtree;
a16dmli.d_esparr.pbasep^.sbase.bmaxreclen   := a16v.a6keylen;
a16dmli.d_esparr.pbasep^.sbase.bkeycolcount :=
      a16v.a6keycolcount[ a16v.a6sequence[ 1 ] ];
ak16destroy_jump_insupd( acv );
&ifdef TRACE
t01stackdesc( ak_sem, 'mblock      ', acv.a_mblock.mb_st,
      acv.a_mblock.mb_qual^.mstack_desc );
&endif
(*========================================================*)
(* Build the cataloginformation needed to select a record *)
(* of the view in case of delete and update commands      *)
(*========================================================*)
a16dmli.d_checkview := false;
IF  ( a16v.a6replace )
THEN
    BEGIN
    (* replace permanent MBLOCKS from old view definition *)
    ak16del_permmblocks( acv, a16dmli );
    END;
(*ENDIF*) 
a59_prepare_join_check( acv, a16dmli, a16v.a6keylen );
;
ak16join_information( acv, a16v, a16dmli, a16v.a6mqual_pos,
      c_update_entries, _b_err );
IF  ( _b_err <> e_ok )
THEN
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
;
(*======================================================*)
(* Parts of the view qualification have to be checked   *)
(* after an insert or update command. Build the         *)
(* cataloginformation needed for the required select    *)
(* operation after an insert or update by ignoring      *)
(* the parts of qualifications which have to be skipped *)
(*======================================================*)
;
(*======== Restore message-buffer ========*)
a06a_mblock_init( acv, m_select, mm_nil, _treeid );
IF  a16v.a6vqual_basis^.sviewqual_basis.vstack_exists
THEN
    BEGIN
    a16v.a6viewkey := a16v.a6vqual_stack^.syskey; (* --> linkage = init_linkage *)
    acv.a_mblock.mb_qual^.mqual_pos := _k;
    (* write new st_jump_output entry *)
    acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mqual_pos ].
          etype    := st_jump_output;
    acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mqual_pos ].
          eop      := op_none;
    acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mqual_pos ].
          epos     := 2;
    acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mqual_pos ].
          elen_var := 0;
    acv.a_mblock.mb_st^[ acv.a_mblock.mb_qual^.mqual_pos ].
          ecol_pos := 0;
    _rel_pos := a16v.a6vqual_stack^.sviewqual_stack.vview_offs;
&   ifdef trace
    t01sname( ak_sem, 'get stack   ' );
    t01int4( ak_sem, 'vview_offs  ', _rel_pos );
&   endif
    (* get record with vstack[ vview_offs ], calculate relative position *)
    (* of vview_pos on this record                                       *)
    WHILE _rel_pos + 1 > cak_max_viewqual_stack DO
        BEGIN
        a06inc_linkage( a16v.a6viewkey.slinkage );
        (* calculate relative record stack position *)
        _rel_pos := _rel_pos - cak_max_viewqual_stack;
        END;
    (*ENDWHILE*) 
    a10get_sysinfo( acv, a16v.a6viewkey, d_release, a16v.a6viewbuf, _b_err );
    IF  _b_err <> e_ok
    THEN
        a07_b_put_error( acv, _b_err, 1 )
    ELSE
        BEGIN
        (* rest of stack entries in view to check *)
        _rest_len := a16v.a6viewbuf^.sviewqual_stack.vstcount -
              a16v.a6viewbuf^.sviewqual_stack.vview_offs;
&       ifdef trace
        t01int4( ak_sem, '_rel_pos    ', _rel_pos );
&       endif
        WHILE ( _rest_len > 0 ) AND ( acv.a_returncode = 0 ) DO
            BEGIN
            IF  _rel_pos + _rest_len > cak_max_viewqual_stack
            THEN
                _move_len := cak_max_viewqual_stack - _rel_pos
            ELSE
                _move_len := _rest_len;
            (*ENDIF*) 
            _mqual_pos := acv.a_mblock.mb_qual^.mqual_pos +
                  ( a16v.a6viewbuf^.sviewqual_stack.vstcount -
                  a16v.a6viewbuf^.sviewqual_stack.vview_offs ) - _rest_len + 1;
&           ifdef trace
            t01int4( ak_sem, '_move_len   ', _move_len );
            t01int4( ak_sem, '_rest_count ', _rest_len );
            t01int4( ak_sem, '_mqual_pos  ', _mqual_pos );
&           endif
            SAPDB_PascalMove ('VAK16 ',   2,    
                  sizeof( a16v.a6viewbuf^.sviewqual_stack.vstack ),
                  ( acv.a_mblock.mb_qual^.mst_max -
                  acv.a_mblock.mb_qual^.mqual_pos ) * STACK_ENTRY_MXGG00,
                  @a16v.a6viewbuf^.sviewqual_stack.vstack[ 1 + _rel_pos ], 1,
                  @acv.a_mblock.mb_st^[ _mqual_pos ], 1,
                  _move_len * sizeof( tgg00_StackEntry ),
                  acv.a_returncode );
            _rest_len := _rest_len - _move_len;
            IF  _rest_len > 0
            THEN
                (* record overflow handling *)
                BEGIN
                _rel_pos  := 0;
                a06inc_linkage( a16v.a6viewkey.slinkage );
                a10get_sysinfo( acv, a16v.a6viewkey, d_release,
                      a16v.a6viewbuf, _b_err );
                IF  _b_err <> e_ok
                THEN
                    a07_b_put_error( acv, _b_err, 1 );
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        acv.a_mblock.mb_qual^.mqual_cnt   :=
              a16v.a6viewbuf^.sviewqual_stack.vstcount -
              a16v.a6viewbuf^.sviewqual_stack.vview_offs + 1 (* st_jump_out *);
        acv.a_mblock.mb_qual^.mfirst_free :=
              acv.a_mblock.mb_qual^.mqual_pos + acv.a_mblock.mb_qual^.mqual_cnt;
        IF  a16v.a6viewbuf^.sviewqual_stack.vview_offs > 0
        THEN
            ak16act_joinarr( a16dmli, acv.a_mblock.mb_qual^.mqual_pos,
                  acv.a_mblock.mb_qual^.mqual_pos +
                  a16v.a6viewbuf^.sviewqual_stack.vview_offs );
        (*ENDIF*) 
        IF  a16v.a6viewbuf^.sviewqual_stack.vdatalen > 0
        THEN
            BEGIN
            _rel_pos := a16v.a6viewbuf^.sviewqual_stack.vdatapos;
&           ifdef trace
            t01name( ak_sem, 'get stack data    ' );
            t01int4( ak_sem, 'vdatalen    ', a16v.a6viewbuf^.
                  sviewqual_stack.vdatalen );
            t01int4( ak_sem, 'vdatapos    ', _rel_pos );
&           endif
            a16v.a6viewkey.slinkage  := cak_init_linkage;
            WHILE _rel_pos > cak_max_viewqual_data DO
                BEGIN
                a06inc_linkage( a16v.a6viewkey.slinkage );
                (* calculate relative position on record *)
                _rel_pos := _rel_pos - cak_max_viewqual_data;
                END;
            (*ENDWHILE*) 
&           ifdef trace
            t01int4( ak_sem, '_rel_pos    ', _rel_pos );
&           endif
            a10get_sysinfo( acv, a16v.a6viewkey, d_release,
                  a16v.a6viewbuf, _b_err );
            IF  _b_err = e_ok
            THEN
                BEGIN
                (* rest length *)
                _rest_len := a16v.a6viewbuf^.sviewqual_stack.vdatalen;
                _data_pos := 1;
                WHILE ( _rest_len > 0 ) AND ( _b_err = e_ok ) DO
                    BEGIN
                    IF  _rest_len > cak_max_viewqual_data - ( _rel_pos - 1 )
                    THEN
                        _move_len := cak_max_viewqual_data - ( _rel_pos - 1 )
                    ELSE
                        _move_len := _rest_len;
                    (*ENDIF*) 
&                   ifdef trace
                    t01int4( ak_sem, '_rest_len   ', _rest_len );
                    t01int4( ak_sem, '_move_len   ', _move_len );
                    t01int4( ak_sem, '_data_pos   ', _data_pos );
&                   endif
                    SAPDB_PascalMove ('VAK16 ',   3,    
                          sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata ),
                          acv.a_mblock.mb_data_size,
                          @a16v.a6viewbuf^.sviewqual_stack.vdata, _rel_pos,
                          @acv.a_mblock.mb_data^.mbp_buf, _data_pos,
                          _move_len, _b_err);
                    _rest_len := _rest_len - _move_len;
                    _data_pos := _data_pos + _move_len;
                    IF  _rest_len > 0
                    THEN
                        (* record overflow handling *)
                        BEGIN
                        _rel_pos  := 1;
                        a06inc_linkage( a16v.a6viewkey.slinkage );
                        a10get_sysinfo( acv, a16v.a6viewkey, d_release,
                              a16v.a6viewbuf, _b_err );
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDWHILE*) 
                END;
            (*ENDIF*) 
            IF  _b_err <> e_ok
            THEN
                a07_b_put_error( acv, _b_err, 1 );
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
;
&ifdef TRACE
t01stackdesc( ak_sem, 'mblock2     ', acv.a_mblock.mb_st,
      acv.a_mblock.mb_qual^.mstack_desc );
a683_output( ak_sem, a16dmli.d_joins );
&endif
_i := acv.a_mblock.mb_qual^.mqual_pos;
_j := _i;
WHILE _i < acv.a_mblock.mb_qual^.mqual_pos +
      acv.a_mblock.mb_qual^.mqual_cnt DO
    BEGIN
    IF  (( acv.a_mblock.mb_st^[ _i ].etype = st_jump_false ) AND
        ( acv.a_mblock.mb_st^[ _i ].eop = op_jmp_ins_upd ))
    THEN
        BEGIN
        _jump_entries := true;
        _distance     := acv.a_mblock.mb_st^[ _i ].elen_var;
        END
    ELSE
        IF  (( acv.a_mblock.mb_st^[ _i ].etype = st_op ) AND
            ( acv.a_mblock.mb_st^[ _i ].eop = op_upd_view_and ))
        THEN
            BEGIN
            _jump_entries := true;
            _distance     := 1;
            END
        ELSE
            BEGIN
            _jump_entries := false;
            acv.a_mblock.mb_st^[ _j ] := acv.a_mblock.mb_st^[ _i ];
&           ifdef TRACE
            t01stackentry( ak_sem, acv.a_mblock.mb_st^[ _i ], _i );
&           endif
            _j := succ( _j );
            _i := succ( _i );
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  _jump_entries
    THEN
        BEGIN
        ak16act_joinarr( a16dmli, _j, _j + _distance );
        _i     := _i + _distance;
        FOR _k := acv.a_mblock.mb_qual^.mqual_pos TO _j - 1 DO
            IF  (( acv.a_mblock.mb_st^[ _k ].etype = st_jump_false )
                OR
                ( acv.a_mblock.mb_st^[ _k ].etype = st_jump_true )) AND
                ( acv.a_mblock.mb_st^[ _k ].epos > _j )
            THEN
                acv.a_mblock.mb_st^[ _k ].epos :=
                      acv.a_mblock.mb_st^[ _k ].epos - _distance;
            (*ENDIF*) 
        (*ENDFOR*) 
        END
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
&ifdef TRACE
t01stackdesc( ak_sem, 'mblock3     ', acv.a_mblock.mb_st,
      acv.a_mblock.mb_qual^.mstack_desc );
a683_output( ak_sem, a16dmli.d_joins );
t01int4( ak_sem, 'i =         ',_i );
t01int4( ak_sem, 'j =         ',_j );
&endif
acv.a_mblock.mb_qual^.mqual_cnt := _j - acv.a_mblock.mb_qual^.mqual_pos;
acv.a_mblock.mb_qual^.mview_pos := 0;
acv.a_mblock.mb_qual^.mview_cnt := 0;
a16dmli.d_checkview := true; (* other key(linkage) for join messblocks *)
&ifdef TRACE
t01stackdesc( ak_sem, 'mblock4     ', acv.a_mblock.mb_st,
      acv.a_mblock.mb_qual^.mstack_desc );
&endif
IF  ( a16v.a6replace )
THEN
    BEGIN
    (* replace permanent MBLOCKS from old view definition *)
    ak16del_permmblocks( acv, a16dmli );
    END;
(*ENDIF*) 
a59_prepare_join_check( acv, a16dmli, a16v.a6keylen );
;
ak16join_information( acv, a16v, a16dmli, acv.a_mblock.mb_qual^.mqual_pos + 1,
      c_new_entries, _b_err );
IF  ( _b_err <> e_ok )
THEN
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16select_grant_option (
            VAR acv       : tak_all_command_glob;
            view_ptr      : tak_sysbufferaddress;
            tabno         : integer;
            VAR from_priv : tak_privilege;
            VAR viewpriv  : tak_privilege);
 
VAR
      _b_err    : tgg00_BasisError;
      _i        : integer;
      _vdescbuf : tak_sysbufferaddress;
      _sysk     : tgg00_SysInfoKey;
 
BEGIN
_sysk           := view_ptr^.syskey;
_sysk.sentrytyp := cak_eviewdesc;
a10get_sysinfo( acv, _sysk, d_release, _vdescbuf, _b_err );
IF  _b_err = e_ok
THEN
    BEGIN
    WITH _vdescbuf^.sviewdesc DO
        FOR _i := 1 TO vdesc_cnt DO
            WITH vdescription[ _i ] DO
                IF  ( vfromtabno = tabno ) AND ( vextcolno > 0 )
                THEN
                    BEGIN
                    IF  NOT ( ( r_sel in from_priv.priv_all_grant_set ) OR
                        ( ( priv_col_sel_grant in from_priv.priv_col_exist )
                        AND
                        ( vfromextcolno in
                        from_priv.priv_grant_sel_set ) ) )
                    THEN
                        viewpriv.priv_grant_sel_set :=
                              viewpriv.priv_grant_sel_set -
                              [ vextcolno ]
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDWITH*) 
        (*ENDFOR*) 
    (*ENDWITH*) 
    END
ELSE
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16SetSystemProperty (
            VAR acv       : tak_all_command_glob;
            VAR viewBase  : tak_baserecord;
            isSystemView  : boolean);
 
VAR
      _e          : tgg00_BasisError;
      _pReference : tak_sysbufferaddress;
      _sysk       : tgg00_SysInfoKey;
 
BEGIN
_sysk.sauthid     := viewBase.bschema;
_sysk.sentrytyp   := cak_etableref;
_sysk.slinkage    := cak_init_linkage;
_sysk.sidentifier := viewBase.btablen^;
_sysk.skeylen     := mxak_standard_sysk + sizeof (_sysk.sidentifier);
a10get_sysinfo( acv, _sysk, d_release, _pReference, _e );
IF  _e = e_ok
THEN
    IF  _pReference^.stableref.rsystable <> isSystemView
    THEN
        BEGIN
        _pReference^.stableref.rsystable := isSystemView;
        a10repl_sysinfo( acv, _pReference, _e );
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  _e <> e_ok
THEN
    a07_b_put_error (acv, _e, 1)
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16colpriv_check (
            VAR acv            : tak_all_command_glob;
            textbuf            : tak_sysbufferaddress;
            vqual_basis        : tak_sysbufferaddress;
            VAR view_rec       : tak_baserecord;
            VAR from_tab_priv  : tak_privilege;
            VAR viewpriv       : tak_privilege;
            tabno              : integer;
            VAR from_rec       : tak_baserecord);
 
VAR
      _col_in_view    : boolean;
      _is_key         : boolean;
      _update_priv    : boolean;
      _upd_grant_priv : boolean;
      _colind         : integer;
      _rec_no         : integer;
      _tab_no         : integer;
      _extcolno       : tsp00_Int2;
      _col_ptr        : tak00_colinfo_ptr;
      _extno          : integer;
 
BEGIN
_colind := from_rec.bfirstcolind;
_extno  := 0; (* just to avoind warnings: uninitialized _extno *)
WHILE _colind <> 0 DO
    BEGIN
    WITH from_rec.bcolumn[ _colind ]^ DO
        BEGIN
&       ifdef trace
        t01buf1( ak_sem, from_rec.bcolumn[ _colind ]^, 1, 44 );
&       endif
        _rec_no := creccolno;
        _tab_no := ctabno + textbuf^.sviewtext.vttab[ tabno ].vtttabcount;
        _col_in_view := ak16column_in_view( view_rec,
              _rec_no, _tab_no, _extcolno, _is_key );
        IF  NOT ( ctopt in ccolpropset )    AND
            NOT ( ctdefault in ccolpropset )
        THEN
            IF  NOT ( _col_in_view ) (* PTS 1129006 *)
            THEN
                IF  NOT ak16derived_column( acv, vqual_basis, _tab_no,
                    _rec_no, _extno )
                THEN
                    BEGIN
                    IF  _tab_no <> 0
                    THEN
                        vqual_basis^.sviewqual_basis.
                              vtable[ _tab_no ].vtins_for_upd := false;
                    (*ENDIF*) 
                    viewpriv.priv_all_set :=
                          viewpriv.priv_all_set - [ r_ins ]
                    END
                ELSE
                    IF  NOT ( ctkey in ccolpropset )
                    THEN
                        BEGIN
                        a06extcolno( view_rec, _extno, _col_ptr );
                        _col_ptr^.ccolpropset :=
                              _col_ptr^.ccolpropset - [ ctopt ];
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        _update_priv := ( r_upd in from_tab_priv.priv_all_set )
              OR
              (( priv_col_upd in from_tab_priv.priv_col_exist ) AND
              ( cextcolno in from_tab_priv.priv_upd_set ));
        _upd_grant_priv := ( r_upd in from_tab_priv.priv_all_grant_set )
              OR
              (( priv_col_upd_grant in from_tab_priv.priv_col_exist )
              AND
              ( cextcolno in from_tab_priv.priv_grant_upd_set ));
        IF  _update_priv
        THEN
            BEGIN
            IF  _col_in_view
            THEN
                BEGIN
                viewpriv.priv_upd_set := viewpriv.priv_upd_set
                      + [ _extcolno ];
                IF  _upd_grant_priv
                THEN
                    viewpriv.priv_grant_upd_set :=
                          viewpriv.priv_grant_upd_set
                          + [ _extcolno ]
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  NOT ( _col_in_view ) AND ( ctlink in ccolpropset ) AND
                ( vqual_basis^.sviewqual_basis.vtable[ _tab_no ].vtone_to_one )
            THEN
                IF  ak16derived_column( acv, vqual_basis, _tab_no,
                    _rec_no, _extno )
                THEN
                    BEGIN
                    IF  NOT ( vqual_basis^.sviewqual_basis.
                        vtable[ _tab_no ].vtone_to_one )
                    THEN
                        BEGIN
                        viewpriv.priv_upd_set :=
                              viewpriv.priv_upd_set + [ _extno ];
                        IF  _upd_grant_priv
                        THEN
                            viewpriv.priv_grant_upd_set :=
                                  viewpriv.priv_grant_upd_set
                                  + [ _extcolno ]
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        _colind := cnextind
        END;
    (*ENDWITH*) 
    END;
(*ENDWHILE*) 
&ifdef TRACE
a06td_priv( viewpriv, 'ak16colpriv_check ', true );
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16link_check (
            VAR acv             : tak_all_command_glob;
            VAR a16v            : tak16_viewglob;
            VAR a16dmli         : tak_dml_info;
            VAR a16keyextno     : tak16_keyextno;
            VAR linkdef         : tak_linkdef;
            sec_tabno           : integer;
            prim_tabno          : integer;
            VAR link_info       : tak16_linkinfo;
            link_no             : integer;
            VAR updateable_view : boolean;
            VAR b_err           : tgg00_BasisError);
 
CONST
      c_not_found = csp_maxint2;
 
VAR
      _catalog_ptr    : tak_sysbufferaddress;
      _catalog_key    : tgg00_SysInfoKey;
      _is_1_to_1_link : boolean;
      _eq_found       : boolean;
      _key_col        : integer;
      _jindex         : integer;
      _init_col_cnt   : integer;
      _init_join_cnt  : integer;
      _read_cnt       : integer;
      _init_mantory   : tak16_mantory_ptr;
 
      _cast         : RECORD
            CASE integer OF
                1 :
                    (addr: tsp00_Addr);
                2 :
                    (mptr : tak16_mantory_ptr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
&ifdef trace
t01int4( ak_sem, 'prim_tabno  ', prim_tabno );
t01int4( ak_sem, 'sec_tabno   ', sec_tabno );
&endif
_init_col_cnt   := link_info.lcol_cnt;
;
_init_mantory   := NIL;
_cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
      a16dmli.d_cntfromtab * sizeof(tak_columnset) );
_init_mantory   := _cast.mptr;
IF  ( _init_mantory = NIL )
THEN
    b_err := e_no_more_memory
ELSE
    SAPDB_PascalForcedMove(
          a16dmli.d_cntfromtab * sizeof(tak_columnset),
          a16dmli.d_cntfromtab * sizeof(tak_columnset),
          @link_info.lmantory^, 1, @_init_mantory^, 1,
          a16dmli.d_cntfromtab * sizeof(tak_columnset));
(*ENDIF*) 
;
_init_join_cnt  := link_info.ljoincnt;
_key_col        := 1;
_is_1_to_1_link :=
      a16v.a6keycolcount[ prim_tabno ] = a16v.a6keycolcount[ sec_tabno ];
WHILE ( _key_col <= a16v.a6keycolcount[ prim_tabno ] ) AND
      ( b_err = e_ok ) DO
    BEGIN
    _eq_found  := false;
    IF  a16v.a6vqual_basis^.sviewqual_basis.vjoin_exists
    THEN
        BEGIN
        _jindex    := 1;
        _catalog_key    := a16v.a6vqual_join^.syskey;
        _catalog_ptr    := a16v.a6vqual_join;
        _read_cnt  := 0;
        WHILE ( b_err = e_ok ) AND
              ( _read_cnt < _catalog_ptr^.sviewqual_join.vjoincount )
              AND ( NOT _eq_found ) DO
            BEGIN
            IF  _jindex  > cak_max_viewqual_join
            THEN
                (* record overflow handling *)
                BEGIN
                a06inc_linkage( _catalog_key.slinkage );
                a10get_sysinfo( acv, _catalog_key, d_release,
                      _catalog_ptr, b_err );
                _jindex := 1;
                END;
            (*ENDIF*) 
            IF  b_err = e_ok
            THEN
                BEGIN
                ak16eq_join( _catalog_ptr^.sviewqual_join.vjoin[ _jindex ],
                      prim_tabno, a16keyextno[ prim_tabno, _key_col ],
                      sec_tabno, linkdef.lseccolseq[ _key_col ], _eq_found );
                IF  ( a16v.a6check_view ) AND ( _eq_found )
                THEN
                    ak16st_in_check_option_part( acv, a16v, _jindex,
                          _catalog_ptr, _eq_found );
                (*ENDIF*) 
                IF  _eq_found
                THEN
                    BEGIN
&                   ifdef trace
                    t01sname( ak_sem, 'eq found    ' );
&                   endif
                    link_info.ljoincnt := succ( link_info.ljoincnt );
&                   ifdef trace
                    IF  ( link_info.ljoincnt > a16dmli.d_joins.jrc_capacity )
                    THEN
                        g01abort (csp3_allocat, csp3_n_join,
                              'HEAP MEMORY DESTROYED   ', link_info.ljoincnt );
&                   endif
                    (*ENDIF*) 
                    link_info.ljoins^[ link_info.ljoincnt ] := _read_cnt;
                    a16v.a6vqual_basis^.sviewqual_basis.
                          vtable[ sec_tabno ].vtnot_used_links :=
                          a16v.a6vqual_basis^.sviewqual_basis.
                          vtable[ sec_tabno ].vtnot_used_links + [ link_no ];
                    link_info.lcol_cnt := succ( link_info.lcol_cnt );
                    WITH link_info.lcolinfo[ link_info.lcol_cnt ] DO
                        BEGIN
                        tabno1 := prim_tabno;
                        recno1 := a16keyextno[ prim_tabno, _key_col ];
                        tabno2 := sec_tabno;
                        recno2 := linkdef.lseccolseq[ _key_col ];
                        IF  recno2 <> a16keyextno[ sec_tabno, _key_col ]
                        THEN
                            _is_1_to_1_link := false;
                        (*ENDIF*) 
                        link_info.lmantory^[ tabno1 ] :=
                              link_info.lmantory^[ tabno1 ] + [ recno1 ];
                        link_info.lmantory^[ tabno2 ] :=
                              link_info.lmantory^[ tabno2 ] + [ recno2 ]
                        END;
                    (*ENDWITH*) 
                    END
                ELSE
                    _jindex := succ( _jindex );
                (*ENDIF*) 
                _read_cnt := succ( _read_cnt );
                END;
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        END;
    (*ENDIF*) 
    IF  NOT _eq_found
    THEN
        _key_col := c_not_found
    ELSE
        _key_col := succ( _key_col );
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
IF  ( _key_col <> c_not_found )
THEN
    BEGIN
&   ifdef trace
    t01sname( ak_sem, 'found       ' );
&   endif
    (*IF  is_pred in link_info.lpred[ sec_tabno, prim_tabno ]*)
    IF  ( ak16test_link_relation( a16dmli, link_info.lpred,
        sec_tabno, prim_tabno, is_pred ) )
    THEN
        updateable_view := false
    ELSE
        WITH link_info.ltab_seq DO
            BEGIN
            IF  _is_1_to_1_link
            THEN
                (*
                      link_info.lpred [ sec_tabno, prim_tabno ] :=
                      [ is_pred, is_1_to_1 ]
                      *)
                ak16set_link_relation( a16dmli, link_info.lpred, NOT c_add_value,
                      sec_tabno, prim_tabno, [ is_pred, is_1_to_1 ] )
            ELSE
                (*link_info.lpred [ sec_tabno, prim_tabno ] := [ is_pred ];*)
                ak16set_link_relation( a16dmli, link_info.lpred, NOT c_add_value,
                      sec_tabno, prim_tabno, [ is_pred ] );
            (*ENDIF*) 
&           ifdef trace
            t01int4( ak_sem, 'prim_tabno= ', prim_tabno );
            t01int4( ak_sem, 'sec_tabno=  ', sec_tabno );
&           endif
            link_info.ltab_seq.seq_queue^[ prim_tabno ].pred_cnt :=
                  succ( link_info.ltab_seq.seq_queue^[ prim_tabno ].pred_cnt );
            link_info.ltab_seq.seq_stack[ link_info.ltab_seq.seq_st_ptr ].
                  suc := link_info.ltab_seq.seq_queue^[ sec_tabno ].top;
            link_info.ltab_seq.seq_stack[ link_info.ltab_seq.seq_st_ptr ].
                  tabno  := prim_tabno;
            link_info.ltab_seq.seq_queue^[ sec_tabno ].top :=
                  link_info.ltab_seq.seq_st_ptr;
            link_info.ltab_seq.seq_st_ptr :=
                  succ( link_info.ltab_seq.seq_st_ptr );
            END
        (*ENDWITH*) 
    (*ENDIF*) 
    END
ELSE
    BEGIN
    link_info.lcol_cnt := _init_col_cnt;
    (* link_info.lmantory := _init_mantory; *)
    IF  ( _init_mantory <> NIL )
    THEN
        SAPDB_PascalForcedMove(
              a16dmli.d_cntfromtab * sizeof(tak_columnset),
              a16dmli.d_cntfromtab * sizeof(tak_columnset),
              @_init_mantory^, 1, @link_info.lmantory^, 1,
              a16dmli.d_cntfromtab * sizeof(tak_columnset));
    (*ENDIF*) 
    link_info.ljoincnt := _init_join_cnt
    END;
(*ENDIF*) 
IF  ( _init_mantory <> NIL )
THEN
    BEGIN
    _cast.mptr := _init_mantory;
    gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16check_updatability (
            VAR acv             : tak_all_command_glob;
            VAR a16v            : tak16_viewglob;
            VAR a16dmli         : tak_dml_info;
            VAR a16keyextno     : tak16_keyextno;
            VAR updateable_view : boolean);
 
VAR
      _is_predecessor     : boolean;
      _is_1_to_one        : boolean;
      _i, _j              : integer;
      _link_info          : tak16_linkinfo;
 
BEGIN
ak16linkinfo_init( acv, a16dmli, _link_info );
FOR _j := a16dmli.d_esparr.pbasep^.sbase.bfirstindex
      TO a16dmli.d_esparr.pbasep^.sbase.blastindex DO
    a16dmli.d_esparr.pbasep^.sbase.
          bcolumn[ _j ]^.ccolpropset := a16dmli.d_esparr.pbasep^.sbase.
          bcolumn[ _j ]^.ccolpropset - [ ctlink, ctjoinviewkey ];
(*ENDFOR*) 
updateable_view := true;
_link_info.lcol_cnt := 0;
FOR _i := 1 TO a16v.a6vqual_basis^.sviewqual_basis.vbasetabcnt DO
    BEGIN
    FOR _j := 1 TO a16v.a6vqual_basis^.sviewqual_basis.vbasetabcnt DO
        (*_link_info.lpred [ _i, _j ] := [  ];*)
        ak16set_link_relation( a16dmli, _link_info.lpred, NOT c_add_value,
              _i, _j, [  ] );
    (*ENDFOR*) 
    _link_info.lmantory^[ _i ] := [  ];
    END;
(*ENDFOR*) 
_link_info.ltab_seq.seq_st_ptr := 1;
FOR _i := 0 TO a16v.a6vqual_basis^.sviewqual_basis.vbasetabcnt DO
    BEGIN
    _link_info.ltab_seq.seq_queue^[ _i ].tabno    := _i;
    _link_info.ltab_seq.seq_queue^[ _i ].top      := 0;
    _link_info.ltab_seq.seq_queue^[ _i ].next     := 0;
    _link_info.ltab_seq.seq_queue^[ _i ].pred_cnt := 0;
    END;
(*ENDFOR*) 
_i := 1;
_link_info.ljoincnt := 0;
WHILE ( _i <= a16v.a6vqual_basis^.sviewqual_basis.vbasetabcnt ) AND
      updateable_view DO
    BEGIN
    IF  a16v.a6is_foreign_key[ _i ]
    THEN
        ak16determine_known_links( acv, a16v, a16dmli, a16keyextno,
              _i, _link_info, updateable_view );
    (*ENDIF*) 
    _i := succ( _i );
    END;
(*ENDWHILE*) 
&ifdef trace
FOR _i := 1 TO a16v.a6vqual_basis^.sviewqual_basis.vbasetabcnt DO
    FOR _j := 1 TO a16v.a6vqual_basis^.sviewqual_basis.vbasetabcnt DO
        (*IF  is_pred in _link_info.lpred [ _i,_j ]*)
        IF  ( ak16test_link_relation( a16dmli, _link_info.lpred,
            _i, _j, is_pred ) )
        THEN
            BEGIN
            t01p2int4( ak_sem, 'sectableno =', _i, 'primtableno=', _j );
            t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _i ].ouser );
            t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _i ].otable );
            t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _j ].ouser );
            t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _j ].otable );
            (*IF  is_1_to_1 in _link_info.lpred[ _i,_j ]*)
            IF  ( ak16test_link_relation( a16dmli, _link_info.lpred,
                _i, _j, is_1_to_1 ) )
            THEN
                t01int4( ak_sem, '1:1 relation', 1 )
            ELSE
                t01int4( ak_sem, '1:n relation', 1 );
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDFOR*) 
(*ENDFOR*) 
FOR _i := 1 TO _link_info.lcol_cnt DO
    WITH _link_info.lcolinfo[ _i ] DO
        t01p4int4( ak_sem, 'colinfo    =', tabno1, recno1,
              tabno2, recno2 );
    (*ENDWITH*) 
(*ENDFOR*) 
&endif
IF  acv.a_returncode = 0
THEN
    ak16tab_sequence( a16v, a16dmli, _link_info, updateable_view );
(*ENDIF*) 
IF  ( acv.a_returncode = 0 ) AND ( updateable_view )
THEN
    BEGIN
    _i := 2;
    WHILE ( _i <= a16dmli.d_cntfromtab ) AND ( updateable_view ) DO
        BEGIN
        _is_predecessor := false;
        _is_1_to_one    := true;
        ak16is_pred( a16v, a16dmli, _link_info, a16v.a6sequence[ 1 ],
              a16v.a6sequence[ _i ], _is_predecessor, _is_1_to_one );
        IF  _is_1_to_one
        THEN
            (*
                  _link_info.lpred[ a16v.a6sequence[ 1 ], a16v.a6sequence[ _i ] ] :=
                  _link_info.
                  lpred[ a16v.a6sequence[ 1 ], a16v.a6sequence[ _i ] ] +
                  [ is_1_to_1 ];
                  *)
            ak16set_link_relation( a16dmli, _link_info.lpred, c_add_value,
                  a16v.a6sequence[ 1 ], a16v.a6sequence[ _i ], [ is_1_to_1 ] );
&       ifdef trace
        (*ENDIF*) 
        IF  _is_predecessor
        THEN
            t01p2int4( ak_sem, 'Table       ', a16v.a6sequence[ 1 ],
                  'is pred of  ', a16v.a6sequence[ _i ] )
        ELSE
            t01p2int4( ak_sem, 'Table       ', a16v.a6sequence[ 1 ],
                  'is not pred ', a16v.a6sequence[ _i ] );
        (*ENDIF*) 
        WITH a16dmli.d_tabarr^[ a16v.a6sequence[ _i ] ] DO
            BEGIN
            t01lidentifier( ak_sem, ouser );
            t01lidentifier( ak_sem, otable );
            END;
        (*ENDWITH*) 
&       endif
        updateable_view := _is_predecessor;
        _i := succ( _i );
        END;
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
IF  ( acv.a_returncode = 0 ) AND updateable_view
THEN
    ak16mantory_check( acv, a16v, a16dmli, a16keyextno,
          _link_info, updateable_view );
(*ENDIF*) 
IF  ( acv.a_returncode = 0 ) AND updateable_view
THEN
    BEGIN
    a16dmli.d_esparr.pbasep^.sbase.bindexexist :=
          NOT( a16dmli.d_joins.jrc_cnt = _link_info.ljoincnt );
    FOR _i := 1 TO a16dmli.d_cntfromtab DO
        IF  ( _i = a16v.a6sequence[ 1 ] ) OR
            (* is_1_to_1 in _link_info.lpred[ a16v.a6sequence[ 1 ], _i ] *)
            ak16test_link_relation( a16dmli, _link_info.lpred,
            a16v.a6sequence[ 1 ], _i, is_1_to_1 )
        THEN
            a16v.a6vqual_basis^.sviewqual_basis.
                  vtable[ _i ].vtone_to_one := true;
        (*ENDIF*) 
    (*ENDFOR*) 
    END;
(*ENDIF*) 
;
&ifdef trace
a683_output( ak_sem, a16dmli.d_joins );
&endif
IF  ( acv.a_returncode = 0 ) AND ( updateable_view )
THEN
    ak16sort_joins( acv, a16v, a16dmli, _link_info );
(*ENDIF*) 
ak16_linkinfo_finalize( acv, _link_info );
;
&ifdef trace
a683_output( ak_sem, a16dmli.d_joins );
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16create_privrecord  (
            VAR acv         : tak_all_command_glob;
            VAR a16v        : tak16_viewglob;
            VAR a16dmli     : tak_dml_info;
            VAR a16keyextno : tak16_keyextno);
 
VAR
      _updateable_view    : boolean;
      _dummy_bool         : boolean;
      _is_ddl             : tak_ddl_descriptor;
      _b_err              : tgg00_BasisError;
      _i, _j              : integer;
      _required_len       : integer;
      _privbuf            : tak_sysbufferaddress;
      _base_ptr           : tak_sysbufferaddress;
      _dummy_name         : tsp00_KnlIdentifier;
      _privkey            : tgg00_SysInfoKey;
      _usedcollist        : tak16_colprivlist_ptr;
      _old_priv           : tak_privilege;
      _join_check         : boolean;
 
      _cast               : RECORD
            CASE integer OF
                1 :
                    (addr: tsp00_Addr);
                2 :
                    (cptr : tak16_colprivlist_ptr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
&ifdef trace
t01name( ak_sem, 'create privrecord ' );
&endif
_usedcollist := NIL;
_cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
      a16dmli.d_cntfromtab * sizeof(tak_columnset));
_usedcollist := _cast.cptr;
IF  ( _usedcollist <> NIL )
THEN
    WITH a16dmli.d_esparr  DO
        BEGIN
        IF  a16v.a6replace
        THEN
            a06user_get_priv( acv, a16dmli.d_esparr.pbasep,
                  acv.a_curr_user_id, _old_priv );
        (*ENDIF*) 
        _updateable_view := false;
        IF  ( a16dmli.d_phase_cnt = 1 )
        THEN
            IF  a16dmli.d_cntfromtab = 1
            THEN
                _updateable_view := true
            ELSE
                IF  ( a16v.a6check_view ) OR ( a16v.a6check_option )
                THEN
                    ak16check_updatability( acv, a16v, a16dmli, a16keyextno,
                          _updateable_view );
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        IF  acv.a_returncode = 0
        THEN
            a16new_bextcolindex( a16dmli.d_esparr.pbasep^.sbase );
        (*ENDIF*) 
        _privkey.stableid   := a16dmli.d_tableid;
        _privkey.sentrytyp  := cak_eprivuser;
        _privkey.slinkage   := cak_init_linkage;
        _privkey.suserid    := acv.a_curr_user_id;
        _privkey.sgrantuser := acv.a_curr_user_id;
        _privkey.skeylen    := mxak_standard_sysk + 2 * SURROGATE_MXGG00;
        _required_len       := sizeof( tak_privuserrecord );
        a10_nil_get_sysinfo( acv, _privkey, d_fix, _required_len, _privbuf, _b_err );
        IF  _b_err = e_ok
        THEN
            WITH a16v.a6priv DO
                BEGIN
                pbasep^.sbase.bsegmentid := a16v.a6segmentid;
                WITH _privbuf^.sprivuser DO
                    BEGIN
                    pru_segmentid := a16v.a6segmentid;
                    pru_date      := pbasep^.sbase.bdatecreate;
                    pru_time      := pbasep^.sbase.btimecreate
                    END;
                (*ENDWITH*) 
                a16v.a6priv                := a01emptypriv;
                a16v.a6priv.priv_all_set   := [ r_sel ];
                IF  a16dmli.d_phase_cnt = 1
                THEN
                    IF  _updateable_view AND ( a16dmli.d_distinct = no_distinct )
                    THEN
                        IF  a16v.a6expr_exist
                        THEN
                            priv_all_set := priv_all_set + [ r_del ]
                        ELSE
                            priv_all_set := priv_all_set + [ r_ins, r_del ];
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                a16v.a6priv.priv_all_grant_set := a16v.a6priv.priv_all_set;
                a16privrec_build( acv, a16dmli.d_esparr.pbasep, _base_ptr,
                      a16v.a6viewtextbuf, a16v.a6vqual_basis, a16v.a6priv,
                      a16v.a6view_kind <> tonebase );
                IF  NOT _updateable_view
                THEN
                    BEGIN
                    a16v.a6priv.priv_all_set :=
                          a16v.a6priv.priv_all_set - [ r_ins, r_del, r_upd ];
                    a16v.a6priv.priv_all_grant_set :=
                          a16v.a6priv.priv_all_grant_set - [ r_ins, r_del, r_upd ];
                    a16v.a6priv.priv_upd_set       := [  ];
                    a16v.a6priv.priv_grant_upd_set := [  ];
                    a16v.a6priv.priv_col_exist     := a16v.a6priv.priv_col_exist -
                          [ priv_col_upd, priv_col_upd_grant ]
                    END;
                (*ENDIF*) 
                IF  a16dmli.d_phase_cnt = 1
                THEN
                    BEGIN
                    FOR _i := 1 TO a16dmli.d_cntfromtab DO
                        _usedcollist^[ _i ] := [  ];
                    (*ENDFOR*) 
                    FOR _j := pbasep^.sbase.bfirstindex TO pbasep^.sbase.blastindex DO
                        BEGIN
&                       ifdef trace
                        IF  (( pbasep^.sbase.bcolumn[ _j ]^.ctabno <=
                            cak00_maxsources ) AND
                            ( pbasep^.sbase.bcolumn[ _j ]^.ctabno >
                            a16dmli.d_cntfromtab ))
                        THEN
                            g01abort (csp3_allocat, csp3_n_join,
                                  'HEAP MEMORY DESTROYED   ',
                                  pbasep^.sbase.bcolumn[ _j ]^.ctabno );
&                       endif
                        (*ENDIF*) 
                        IF  ( pbasep^.sbase.bcolumn[ _j ]^.ctabno <= cak00_maxsources ) AND
                            ( pbasep^.sbase.bcolumn[ _j ]^.
                            ccolstack.etype <> st_func )
                        THEN
                            IF  NOT ( pbasep^.sbase.bcolumn[ _j ]^.creccolno in
                                _usedcollist^[ pbasep^.sbase.
                                bcolumn[ _j ]^.ctabno ] )
                            THEN
                                _usedcollist^[ pbasep^.sbase.
                                      bcolumn[ _j ]^.ctabno ] :=
                                      _usedcollist^[ pbasep^.sbase.
                                      bcolumn[ _j ]^.ctabno ] +
                                      [ pbasep^.sbase.bcolumn[ _j ]^.creccolno ]
                            ELSE
                                priv_all_set := priv_all_set
                                      - [ r_ins, r_upd ];
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END;
                    (*ENDFOR*) 
                    END;
                (*ENDIF*) 
                IF  a16v.a6view_kind = tonebase
                THEN
                    ak16invisible_column_add( acv,
                          _usedcollist^, a16v, a16dmli, _base_ptr )
                ELSE (* released in a16privrec_build *)
                    a16dmli.d_acttabindex := 0;
                (*ENDIF*) 
                IF  NOT ( r_ins in priv_all_set )           AND
                    NOT ( r_upd in priv_all_set )           AND
                    NOT ( r_del in priv_all_set )           AND
                    NOT ( priv_col_upd in priv_col_exist )  AND
                    a16v.a6check_option
                THEN
                    IF  acv.a_internal_sql = sql_alter_table
                    THEN
                        a07_nb_put_error( acv,
                              e_view_def_contradicts_table_de,
                              1, a16dmli.d_esparr.pbasep^.sbase.btablen^ )
                    ELSE
                        a07_b_put_error( acv, e_check_option_not_allowed, 1 )
                    (*ENDIF*) 
                ELSE
                    BEGIN
                    IF  (( r_ins in priv_all_set ) OR
                        ( r_upd in priv_all_set )  OR
                        ( r_del in priv_all_set )  OR
                        ( priv_col_upd in priv_col_exist ))
                        AND
                        ( a16dmli.d_cntfromtab > 1 )
                    THEN
                        ak16store_tab_sequence( acv, a16v, a16dmli );
                    (*ENDIF*) 
                    _join_check := ( a16dmli.d_cntfromtab > 1 ) AND
                          (( r_ins in priv_all_set ) OR
                          ( r_upd in priv_all_set )  OR
                          ( priv_col_upd in priv_col_exist ));
                    IF  a16v.a6resort_joins AND (acv.a_returncode = 0)
                    THEN
                        ak16resort_joinarr( acv, a16v, _b_err );
                    (*ENDIF*) 
                    IF  a16v.a6qualexist AND _join_check AND
                        (acv.a_returncode = 0)
                    THEN
                        ak16build_join_check( acv, a16v, a16dmli );
                    (*ENDIF*) 
                    IF  NOT ( r_ins in priv_all_set ) AND
                        NOT ( r_upd in priv_all_set ) AND
                        NOT ( r_del in priv_all_set ) AND
                        NOT ( priv_col_upd in priv_col_exist )
                    THEN
                        FOR _j := a16dmli.d_esparr.pbasep^.sbase.bfirstindex TO
                              a16dmli.d_esparr.pbasep^.sbase.blastindex DO
                            a16dmli.d_esparr.pbasep^.sbase.
                                  bcolumn[ _j ]^.ccolpropset :=
                                  a16dmli.d_esparr.pbasep^.sbase.
                                  bcolumn[ _j ]^.ccolpropset - [ctjoinviewkey];
                        (*ENDFOR*) 
                    (*ENDIF*) 
                    priv_all_grant_set :=
                          priv_all_grant_set * priv_all_set;
                    IF  a16v.a6priv.priv_c132 = a01emptypriv.priv_c132
                    THEN
                        a07ak_system_error( acv, 16, 3 )
                    ELSE
                        a22add_priv_rec( acv, a16dmli.d_esparr.pbasep,
                              a16v.a6priv, _privbuf, a16v.a6add_rec, _dummy_bool );
                    (*ENDIF*) 
                    a10_rel_sysinfo( acv, _privbuf^.syskey );
                    IF  a16v.a6replace AND
                        ( a16v.a6priv.priv_c132 <> _old_priv.priv_c132 )
                    THEN
                        ak16modify_privileges( acv, a16v, a16dmli );
                    (*ENDIF*) 
                    IF  (acv.a_internal_sql = sql_alter_table) OR (a16v.a6replace)
                    THEN
                        BEGIN (* create new public privilege *)
                        a16v.a6public_priv.priv_all_set :=
                              a16v.a6public_priv.priv_all_set *
                              a16v.a6priv.priv_all_set;
                        IF  r_sel in a16v.a6priv.priv_all_set
                        THEN
                            a16v.a6priv.priv_sel_set := a01fullset;
                        (*ENDIF*) 
                        a16v.a6public_priv.priv_sel_set :=
                              a16v.a6public_priv.priv_sel_set *
                              a16v.a6priv.priv_sel_set;
                        IF  r_upd in a16v.a6priv.priv_all_set
                        THEN
                            a16v.a6priv.priv_upd_set := a01fullset;
                        (*ENDIF*) 
                        a16v.a6public_priv.priv_upd_set :=
                              a16v.a6public_priv.priv_upd_set *
                              a16v.a6priv.priv_upd_set;
                        IF  a16v.a6public_priv.priv_sel_set <> [  ]
                        THEN
                            a16v.a6public_priv.priv_col_exist :=
                                  [ priv_col_sel ];
                        (*ENDIF*) 
                        IF  a16v.a6public_priv.priv_upd_set <> [  ]
                        THEN
                            a16v.a6public_priv.priv_col_exist :=
                                  a16v.a6public_priv.priv_col_exist +
                                  [ priv_col_upd ];
                        (*ENDIF*) 
                        a16dmli.d_esparr.pbasep^.sbase.bpriv_all_set :=
                              a16v.a6public_priv.priv_all_set;
                        a16dmli.d_esparr.pbasep^.sbase.bpriv_col_exist :=
                              a16v.a6public_priv.priv_col_exist;
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        IF  _b_err <> e_ok
        THEN
            a07_b_put_error( acv, _b_err, 1 )
        ELSE
            IF  acv.a_returncode = 0
            THEN
                IF  a16v.a6sort
                THEN
                    BEGIN
                    _is_ddl   := acv.a_is_ddl;
                    acv.a_is_ddl := no_ddl;
                    a061sort( acv, a16dmli.d_esparr.pbasep^.sbase, 0,
                          _dummy_bool, _dummy_name );
                    acv.a_is_ddl := _is_ddl;
                    IF  _dummy_bool
                    THEN
                        a07ak_system_error( acv, 16, 4 )
                    ELSE
                        IF  acv.a_returncode = 0
                        THEN
                            a16new_bextcolindex( a16dmli.d_esparr.pbasep^.sbase );
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDWITH*) 
ELSE
    a07_b_put_error( acv, e_no_more_memory, 1 );
(*ENDIF*) 
IF  ( _usedcollist <> NIL )
THEN
    BEGIN
    _cast.cptr := _usedcollist;
    gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16rest_of_view_create (
            VAR acv  : tak_all_command_glob;
            VAR a16v : tak16_viewglob);
 
VAR
      dummy_cnt    : integer;
 
BEGIN
IF  a16v.a6replace
THEN
    ak16restore_scheme( acv, a16v.a6scheme_treeid );
(*ENDIF*) 
IF  ( acv.a_returncode <> 0 )
THEN
    BEGIN
    ak16clean_up( acv, a16v );
    IF  acv.a_internal_sql = no_internal_sql
    THEN
        acv.a_part_rollback := true
    (*ENDIF*) 
    END
ELSE
    BEGIN
    a10_all_release( acv );
    END;
(*ENDIF*) 
a660_prefix_delete( acv, acv.a_pars_last_key, dummy_cnt, cak_complete_prefix );
END;
 
(*------------------------------*) 
 
FUNCTION
      ak16derived_column (
            VAR acv     : tak_all_command_glob;
            vqual_basis : tak_sysbufferaddress;
            tabno       : integer;
            recno       : integer;
            VAR extno   : integer) : boolean;
 
VAR
      _catalog_ptr  : tak_sysbufferaddress;
      _catalog_key  : tgg00_SysInfoKey;
      _i            : integer;
      _read_idx     : integer;
      _b_err        : tgg00_BasisError;
 
BEGIN
&ifdef trace
t01int4( ak_sem, 'tabno=      ', tabno );
t01int4( ak_sem, 'recno=      ', recno );
&endif
_b_err := e_ok;
ak16derived_column := false;
IF  vqual_basis^.sviewqual_basis.vderived_exists
THEN
    BEGIN
    _catalog_key             := vqual_basis^.syskey;
    _catalog_key.slinkage    := cak_init_linkage;
    _catalog_key.sentrytyp   := cak_eviewqual_derivedcol;
    a10get_sysinfo( acv, _catalog_key, d_release, _catalog_ptr, _b_err );
    _i        := 1;
    _read_idx := 1;
    WHILE ( _i <= _catalog_ptr^.sviewqual_derivedcol.vderivedcnt ) AND
          ( _b_err = e_ok ) DO
        BEGIN
        IF  _read_idx > cak_max_viewqual_derivedcol
        THEN
            (* record overflow handling *)
            BEGIN
            a06inc_linkage( _catalog_key.slinkage );
            a10get_sysinfo( acv, _catalog_key, d_release,
                  _catalog_ptr, _b_err );
            _read_idx := 1;
            END;
        (*ENDIF*) 
        IF  _b_err = e_ok
        THEN
            IF  ( _catalog_ptr^.sviewqual_derivedcol.
                vderived_cols[ _read_idx ].dtabno = tabno )
                AND
                ( _catalog_ptr^.sviewqual_derivedcol.
                vderived_cols[ _read_idx ].drecno = recno )
            THEN
                BEGIN
                _i    := csp_maxint2; (* exit while *)
                extno := _catalog_ptr^.sviewqual_derivedcol.
                      vderived_cols[ _read_idx ].dextno;
                ak16derived_column := true;
                END
            ELSE
                BEGIN
                _i        := succ( _i );
                _read_idx := succ( _read_idx );
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
IF  _b_err <> e_ok
THEN
    a07_b_put_error( acv, _b_err, 1 )
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16destroy_jump_insupd (VAR acv : tak_all_command_glob);
 
VAR
      _i : integer;
 
BEGIN
FOR _i := acv.a_mblock.mb_qual^.mqual_pos TO acv.a_mblock.mb_qual^.mqual_pos +
      acv.a_mblock.mb_qual^.mqual_cnt - 1 DO
    BEGIN
    IF  acv.a_mblock.mb_st^[ _i ].etype = st_jump_false
    THEN
        acv.a_mblock.mb_st^[ _i ].eop := op_none
    ELSE
        (* op_upd_view_and -> op_and *)
        IF  ( acv.a_mblock.mb_st^[ _i ].etype = st_op ) AND
            ( acv.a_mblock.mb_st^[ _i ].eop = op_upd_view_and )
        THEN
            acv.a_mblock.mb_st^[ _i ].eop := op_and;
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDFOR*) 
acv.a_mblock.mb_qual^.mview_cnt := 0;
acv.a_mblock.mb_qual^.mview_pos := 0;
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16determine_known_links (
            VAR acv             : tak_all_command_glob;
            VAR a16v            : tak16_viewglob;
            VAR a16dmli         : tak_dml_info;
            VAR a16keyextno     : tak16_keyextno;
            tab_no              : integer;
            VAR link_info       : tak16_linkinfo;
            VAR updateable_view : boolean);
 
VAR
      _b_err    : tgg00_BasisError;
      _link_cnt : integer;
      _j        : integer;
      _index    : integer;
      _link_no  : integer;
      _link_ptr : tak_sysbufferaddress;
      _link_key : tgg00_SysInfoKey;
&     ifdef trace
      _link_name: tsp00_KnlIdentifier;
      _catalog_ptr : tak_sysbufferaddress;
      _catalog_key : tgg00_SysInfoKey;
      _x           : integer;
&     endif
 
BEGIN
_b_err := e_ok;
&ifdef trace
t01str30 (ak_sem, '===== foreign key table is ===');
t01lidentifier  (ak_sem, a16dmli.d_tabarr^[ tab_no ].ouser);
t01lidentifier  (ak_sem, a16dmli.d_tabarr^[ tab_no ].otable);
t01str30 (ak_sem, '===== join predicates      ===');
IF  a16v.a6vqual_basis^.sviewqual_basis.vjoin_exists
THEN
    BEGIN
    _catalog_ptr := a16v.a6vqual_join;
    _catalog_key := a16v.a6vqual_join^.syskey;
    _x := 0;
    FOR _j := 1 TO a16v.a6vqual_join^.sviewqual_join.vjoincount DO
        BEGIN
        _x := succ( _x );
        IF  _x > cak_max_viewqual_join
        THEN
            BEGIN
            a06inc_linkage( _catalog_key.slinkage );
            a10get_sysinfo( acv, _catalog_key, d_release, _catalog_ptr, _b_err );
            _x := 1;
            END;
        (*ENDIF*) 
        IF  _b_err = e_ok
        THEN
            BEGIN
            t01p2int4 (ak_sem, 'j1tableno   ', _catalog_ptr^.sviewqual_join.vjoin[ _x ].j1tableno,
                  'j2tableno   ', _catalog_ptr^.sviewqual_join.vjoin[ _x ].j2tableno);
            t01p2int4 (ak_sem, 'fieldno1    ', _catalog_ptr^.sviewqual_join.vjoin[ _x ].j1fieldno,
                  'filedno2    ', _catalog_ptr^.sviewqual_join.vjoin[ _x ].j2fieldno);
            END;
        (*ENDIF*) 
        END;
    (*ENDFOR*) 
    END;
&endif
(*ENDIF*) 
_link_no            := 0;
_link_key           := a01defaultkey;
_link_key.stableid  := a16dmli.d_tabarr^[ tab_no ].otreeid.fileTabId_gg00;
_link_key.sentrytyp := cak_eforeignkey;
_link_key.slinkage  := cak_zero_linkage;
REPEAT
    _link_no := succ( _link_no );
    IF  ( _link_no MOD cak_maxlinkdef ) = 1
    THEN
        BEGIN
        IF  _link_key.slinkage <> cak_zero_linkage
        THEN
            a10_rel_sysinfo( acv, _link_key );
        (*ENDIF*) 
        a06inc_linkage( _link_key.slinkage );
        _index := 1;
        END
    ELSE
        _index := succ( _index );
    (*ENDIF*) 
    a10get_sysinfo( acv, _link_key, d_fix, _link_ptr, _b_err );
    IF  _b_err = e_ok
    THEN
        BEGIN
        IF  _link_no = 1
        THEN
            _link_cnt := _link_ptr^.slink.linkcount;
&       ifdef trace
        (*ENDIF*) 
        t01str30( ak_sem,
              '=== current link is       ====' );
        a25get_linkname( acv, _link_ptr, _index, _link_name );
        t01lidentifier( ak_sem, _link_name );
&       endif
        _j := 1;
        WHILE ( _j <= a16dmli.d_cntfromtab ) AND ( updateable_view ) AND
              ( _b_err = e_ok ) DO
            BEGIN
            IF  ( tab_no <> _j ) AND ( a16dmli.d_tabarr^[ _j ].
                otreeid.fileTabId_gg00 = _link_ptr^.slink.
                linkdef[ _index ].ltableid )
            THEN
                BEGIN
&               ifdef TRACE
                t01str30( ak_sem, '===== primary key table is ===' );
                t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _j ].ouser );
                t01lidentifier( ak_sem, a16dmli.d_tabarr^[ _j ].otable );
&               endif
                ak16link_check( acv, a16v, a16dmli, a16keyextno,
                      _link_ptr^.slink.linkdef[ _link_no ],
                      tab_no(*secondary table*), _j(*primary table*),
                      (* tab_no REFERENCES _j *)
                      link_info, _link_no, updateable_view, _b_err );
                IF  _b_err <> e_ok
                THEN
                    a07_b_put_error( acv, _b_err, 1 );
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            _j := succ( _j );
            END
        (*ENDWHILE*) 
        END
    ELSE
        IF  _b_err = e_sysinfo_not_found
        THEN
            _link_cnt := _link_no
        ELSE
            a07_b_put_error( acv, _b_err, 1 );
        (*ENDIF*) 
    (*ENDIF*) 
UNTIL
    ( _link_no = _link_cnt ) OR
    ( acv.a_returncode <> 0 ) OR
    NOT ( updateable_view );
(*ENDREPEAT*) 
IF  _link_key.slinkage <> cak_zero_linkage
THEN
    a10_rel_sysinfo( acv, _link_key );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16end_view (
            VAR acv         : tak_all_command_glob;
            VAR a16v        : tak16_viewglob;
            VAR a16dmli     : tak_dml_info;
            VAR a16keyextno : tak16_keyextno);
 
VAR
      _b_err    : tgg00_BasisError;
      _ix       : integer;
      _jx       : integer;
      _tab_kind : tak_usertab_descriptor;
 
BEGIN
ak16init_viewbase_rec( acv, a16v, a16dmli );
a16dmli.d_esparr.pbasep^.sbase.bv_qualexist := a16v.a6qualexist;
IF  a16dmli.d_phase_cnt < cak_complex_view_indicator
THEN
    a16dmli.d_esparr.pbasep^.sbase.bv_tabcount := a16dmli.d_cntfromtab
ELSE
    a16dmli.d_esparr.pbasep^.sbase.bv_tabcount := 1;
(*ENDIF*) 
FOR _ix := 1 TO a16dmli.d_esparr.pbasep^.sbase.bmaxcol DO
    a16dmli.d_esparr.pbasep^.sbase.bextcolindex [ _ix ] := cak_cdropped;
(*ENDFOR*) 
a16new_bextcolindex( a16dmli.d_esparr.pbasep^.sbase );
ak16create_privrecord( acv, a16v, a16dmli, a16keyextno );
IF  acv.a_returncode = 0
THEN
    a11sort( a16dmli.d_esparr.pbasep^.sbase );
(*ENDIF*) 
IF  (acv.a_returncode = 0) AND (a16dmli.d_esparr.pbasep^.sbase.btablekind = tcomplexview)
THEN
    ak16increase_pos_after_long ( a16dmli.d_esparr.pbasep^.sbase );
(*ENDIF*) 
IF  ( acv.a_returncode = 0 ) AND
    ( a16dmli.d_esparr.pbasep^.sbase.btablekind = tview ) AND
    (( r_ins in a16v.a6priv.priv_all_set ) OR
    ( r_upd in a16v.a6priv.priv_all_set ) OR
    ( priv_col_upd in a16v.a6priv.priv_col_exist ))
THEN
    a16constraint_check( acv, a16dmli.d_esparr.pbasep^.sbase,
          a16v.a6vqual_basis );
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    WITH a16dmli.d_esparr.pbasep^.sbase DO
        BEGIN
        IF  ( acv.a_internal_sql = sql_alter_table ) AND
            ( a16v.a6comment_set  <> [ ] )
        THEN
            FOR _jx := bfirstindex TO blastindex DO
                IF  bcolumn[ _jx ]^.cextcolno in a16v.a6comment_set
                THEN
                    bcolumn[ _jx ]^.ccolpropset :=
                          bcolumn[ _jx ]^.ccolpropset + [ ctcomment ];
                (*ENDIF*) 
            (*ENDFOR*) 
        (*ENDIF*) 
        bsegmentid  := a16v.a6segmentid;
        breccnt     := a16v.a6rec_cnt;
        (* create view catalog record *)
        IF  a16v.a6noUsageRef
        THEN (* PTS 1127509 *)
            battributes := battributes + [ta_no_references_view];
        (*ENDIF*) 
        a10_add_repl_sysinfo( acv, a16dmli.d_esparr.pbasep, c_add_rec, _b_err );
        IF  ( _b_err = e_ok ) AND ( a16v.a6vqual_basis <> NIL )
        THEN
            BEGIN
            (* now write basis record of view *)
            a10_add_repl_sysinfo( acv, a16v.a6vqual_basis, a16v.a6add_rec, _b_err );
            IF  _b_err = e_sysinfo_not_found
            THEN
                (* may happen in the course of replace view, *)
                (* if old view is complex and new is not     *)
                a10add_sysinfo( acv, a16v.a6viewbuf, _b_err );
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  _b_err <> e_ok
        THEN
            a07_b_put_error( acv, _b_err, 1 )
        ELSE
            IF  (a16dmli.d_esparr.pbasep^.sbase.bschema <> acv.a_curr_user_id)
                AND
                a16v.a6add_rec
            THEN
                BEGIN
                _tab_kind := ut_view;
                IF  acv.a_initial_segment_header.sp1c_producer = sp1pr_installation
                THEN
                    IF  acv.a_curr_schema = a01_i_sys
                    THEN
                        _tab_kind := ut_oracle_systable
                    ELSE
                        IF  a16v.a6systable
                            AND
                            (acv.a_current_user_kind = usysdba)
                        THEN
                            _tab_kind := ut_internal_systable;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                a19add_usertab  (acv, acv.a_curr_user_id,
                      a16dmli.d_esparr.pbasep^.sbase.bsurrogate, _tab_kind);
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16eq_join (
            VAR join        : tak_one_viewjoin;
            tabno1          : integer; (* primary *)
            colno1          : integer;
            tabno2          : integer; (* secondary *)
            colno2          : integer;
            VAR eq_found    : boolean);
 
BEGIN
eq_found := false;
&ifdef trace
t01int4 (ak_sem,'tableno1=   ', tabno1);
t01int4 (ak_sem,'colno1      ', colno1);
t01int4 (ak_sem,'tableno2=   ', tabno2);
t01int4 (ak_sem,'colno2      ', colno2);
t01op (ak_sem, 'operator=   ', join.j12operator);
t01int4 (ak_sem,'j1tableno=  ', join.j1tableno);
t01int4 (ak_sem,'j1fieldno=  ', join.j1fieldno);
t01int4 (ak_sem,'j2tableno=  ', join.j2tableno);
t01int4 (ak_sem,'j2fieldno   ', join.j2fieldno);
&endif
IF  ( join.j1cntstack  = 1 ) AND ( join.j2cntstack  = 1 ) AND ( join.j12operator = op_eq )
THEN
    IF  (( join.j1tableno = tabno1 ) AND ( join.j1fieldno = colno1 )
        AND
        ( join.j2tableno = tabno2 )  AND ( join.j2fieldno = colno2 ))
        OR
        (( join.j1tableno = tabno2 ) AND ( join.j1fieldno = colno2 )
        AND
        ( join.j2tableno = tabno1 )  AND ( join.j2fieldno = colno1 ))
    THEN
        eq_found := true;
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16expression_cols  (
            VAR acv        : tak_all_command_glob;
            VAR a16v       : tak16_viewglob;
            VAR a16dmli    : tak_dml_info);
 
VAR
      _col_ptr        : tak00_colinfo_ptr;
      _dummykey       : tgg00_SysInfoKey;
      _last_tabno     : tsp00_Int4;
      _stpointer      : tsp00_Int4;
      _j              : tsp00_Int4;
      _k              : tsp00_Int4;
      _colno          : tsp00_Int4;
      _count          : tsp00_Int4;
      _write_idx      : tsp00_Int4;
      _vstcount       : tsp00_Int4;
      _vdatapos       : tsp00_Int4;
      _vdatalen       : tsp00_Int4;
      _move_len       : tsp00_Int4;
      _data_len       : tsp00_Int4;
      _data_pos       : tsp00_Int4;
      _firstdatapos   : tsp00_Int4;
      _op             : tgg00_StackOpFunc;
      _expr_found     : boolean;
      _one_tab_expr   : boolean;
      _firstdata      : boolean;
      _b_err          : tgg00_BasisError;
 
BEGIN
&ifdef trace
t01messblock( ak_sem, 'a_mblock    ', acv.a_mblock );
&endif
a16v.a6expr_exist := false;
_stpointer := acv.a_mblock.mb_qual^.mcol_pos;
_count     := 0;
_op        := op_f_none;
_b_err     := e_ok;
FOR _j := a16dmli.d_esparr.pbasep^.sbase.bfirstindex TO
      a16dmli.d_esparr.pbasep^.sbase.blastindex DO
    BEGIN
    a16dmli.d_esparr.pbasep^.sbase.bextcolindex
          [ a16dmli.d_esparr.pbasep^.sbase.bcolumn[ _j ]^.cextcolno ] :=
          _count;
    _count := succ( _count );
    END;
(*ENDFOR*) 
IF  acv.a_mblock.mb_st^[ _stpointer ].etype = st_jump_output
THEN
    (* step over st_jump_out *)
    _stpointer := succ( _stpointer );
(*ENDIF*) 
_vstcount  := 0; (* count all stack entries *)
_vdatapos  := 0;
_vdatalen  := 0;
_colno     := 1;
_write_idx := 1;
_firstdata := true;
&ifdef trace
t01int4( ak_sem, '_stpointer  ', _stpointer );
&endif
WHILE ( _colno <= a16dmli.d_esparr.pbasep^.sbase.bmaxcol ) AND
      ( _b_err = e_ok ) DO
    BEGIN
    _expr_found := false;
    _j          := _stpointer;
&   ifdef trace
    t01int4( ak_sem, 'search at   ', _j );
&   endif
    REPEAT
        IF  ( acv.a_mblock.mb_st^[ _j ].etype <> st_column ) AND
            ( acv.a_mblock.mb_st^[ _j ].etype <> st_fixkey ) AND
            ( acv.a_mblock.mb_st^[ _j ].etype <> st_varkey ) AND
            ( acv.a_mblock.mb_st^[ _j ].etype <> st_fixcol ) AND
            ( acv.a_mblock.mb_st^[ _j ].etype <> st_varcol ) AND
            ( acv.a_mblock.mb_st^[ _j ].etype <> st_varlongchar ) AND
            ( acv.a_mblock.mb_st^[ _j ].etype <> st_output )
        THEN
            _expr_found := true;
        (*ENDIF*) 
        _j := succ( _j );
    UNTIL
        acv.a_mblock.mb_st^[ _j ].etype = st_output;
    (*ENDREPEAT*) 
    IF  ( _j - _stpointer > 1 ) OR ( _expr_found )
    THEN
        BEGIN (* Expression - Column *)
        a16v.a6expr_exist := true;
        (* _count count stack entries for one expression column *)
        _count        := 0;
        _last_tabno   := 0;
        _one_tab_expr := true;
        a06extcolno( a16dmli.d_esparr.pbasep^.sbase, _colno, _col_ptr );
        _col_ptr^.ccolpropset := _col_ptr^.ccolpropset + [ ctexpression ];
        _col_ptr^.creccolno   := _col_ptr^.cextcolno;
        (* sign for expression columns : elen_var = _count, etype = st_func *)
        IF  _write_idx > cak_max_viewqual_stack
        THEN
            (* we will get a new record *)
            BEGIN
            (* write relative position on record *)
            _col_ptr^.ccolstack.epos  := 1;
&           ifdef trace
            t01sname( ak_sem, 'prep new rec' );
&           endif
            _dummykey := a16v.a6viewbuf^.syskey;
            a06inc_linkage( _dummykey.slinkage );
            _col_ptr^.ccolstack.ecol_tab[ 1 ] := _dummykey.slinkage[ 2 ];
            END
        ELSE
            BEGIN
            (* write relative position on record *)
            _col_ptr^.ccolstack.epos  := _write_idx;
            _col_ptr^.ccolstack.ecol_tab[ 1 ] :=
                  a16v.a6viewbuf^.syskey.slinkage[ 2 ];
            END;
        (*ENDIF*) 
        _col_ptr^.ccolstack.etype := st_func;
&       ifdef trace
        t01sname( ak_sem, 'column:     ' );
        t01buf( ak_sem, _col_ptr^.ccolumnn, 1, ord( _col_ptr^.ccolumnn_len ) );
        t01int4( ak_sem, 'rel offset  ', _write_idx );
        t01int4( ak_sem, 'expr start  ', _stpointer );
        t01int4( ak_sem, 'expr stop   ', _j - 1 );
        t01int4( ak_sem, 'record linka',
              ord( a16v.a6viewbuf^.syskey.slinkage[ 2 ] ) );
        t01int4( ak_sem, 'stack count ', ( _j - 1 ) - _stpointer );
&       endif
        (* write stack entries for expression column *)
        FOR _k := _stpointer TO _j - 1 DO
            BEGIN
            IF  (( _k <> _j - 1 ) OR
                ( acv.a_mblock.mb_st^[ _k ].etype <> st_result ))
                AND ( _b_err = e_ok )
            THEN
                BEGIN
                (* check if we need a new record *)
                IF  _write_idx > cak_max_viewqual_stack
                THEN
                    (* record overflow handling *)
                    BEGIN
&                   ifdef trace
                    t01sname( ak_sem, 'rec overflow');
&                   endif
                    ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec,
                          sizeof( a16v.a6viewbuf^.sviewqual_stack ) -
                          sizeof( a16v.a6viewbuf^.sviewqual_stack.vstack ) +
                          ( _write_idx - 1 ) *
                          sizeof(  a16v.a6viewbuf^.sviewqual_stack.vstack[ 1 ] ),
                          _b_err );
                    IF  _b_err = e_ok
                    THEN
                        (* get new catalog record *)
                        BEGIN
                        a06inc_linkage( a16v.a6viewkey.slinkage );
                        a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
                              sizeof( tak_viewqual_stack_record ),
                              a16v.a6viewbuf, _b_err );
                        IF  _b_err = e_ok
                        THEN
                            (* initialize new record *)
                            BEGIN
                            a16v.a6viewbuf^.sviewqual_stack.vsegmentid :=
                                  a16v.a6segmentid;
                            a16v.a6viewbuf^.sviewqual_stack.vfiller    := '00';
                            a16v.a6viewbuf^.sviewqual_stack.vview_offs := 0;
                            (* temporary write 0 count *)
                            a16v.a6viewbuf^.sviewqual_stack.vdatapos   := 0;
                            a16v.a6viewbuf^.sviewqual_stack.vdatalen   := 0;
                            a16v.a6viewbuf^.sviewqual_stack.vstcount   := 0;
                            END;
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    _write_idx := 1;
                    END;
                (*ENDIF*) 
                IF  acv.a_mblock.mb_st^[ _k ].etype in
                    [ st_column, st_fixkey, st_varkey, st_fixcol,
                    st_varcol, st_varlongchar ]
                THEN
                    BEGIN
                    IF  _last_tabno = 0
                    THEN
                        _last_tabno :=
                              ord( acv.a_mblock.mb_st^ [_k].ecol_tab[ 2 ] )
                    ELSE
                        IF  ( acv.a_mblock.mb_st^[ _k ].ecol_tab[ 2 ] ) <>
                            chr( _last_tabno )
                        THEN
                            _one_tab_expr := false
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                ELSE
                    IF  acv.a_mblock.mb_st^[ _k ].etype = st_func
                    THEN
                        CASE acv.a_mblock.mb_st^[ _k ].eop_func OF
                            op_f_count, op_f_dis_count, op_f_all_count,
                            op_f_sum, op_f_dis_sum,
                            op_f_min, op_f_max :
                                BEGIN
                                _op := op_f_sum;
                                END;
                            op_f_avg, op_f_dis_avg,
                            op_f_stddev, op_f_dis_stddev,
                            op_f_variance, op_f_dis_variance :
                                BEGIN
                                _op := op_f_avg;
                                END;
                            END;
                        (*ENDCASE*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  _b_err = e_ok
                THEN
                    BEGIN
                    (* that's it, write the stack entry *)
                    a16v.a6viewbuf^.sviewqual_stack.vstack[ _write_idx ] :=
                          acv.a_mblock.mb_st^[ _k ];
                    IF  ( a16v.a6viewbuf^.sviewqual_stack.vstack[ _write_idx ].
                        etype in [ st_value, st_language, st_format,
                        st_date, st_time, st_timestamp,
                        (* PTS 1116175 E.Z. *)
                        st_utcdate,
                        (* PTS 1109925 E.Z. *)
                        st_utcdiff,
                        st_user, st_usergroup, st_current_schema, st_uid,
                        st_sysdba, st_localsysdba, st_transaction,
                        st_timezone (* PTS 1122262 E.Z. *)
                        ] )
                    THEN
                        BEGIN
                        IF  _firstdata
                        THEN
                            BEGIN
                            (* remark first data position *)
                            _firstdatapos := a16v.a6viewbuf^.sviewqual_stack.
                                  vstack[ _write_idx ].epos;
                            (* now calculate real data length for expression data *)
                            _vdatalen  := ( a16v.a6expr_lastdata -
                                  _firstdatapos ) + 1;
                            _firstdata := false;
&                           ifdef trace
                            t01int4( ak_sem, '_firstdatapo', _firstdatapos );
                            t01int4( ak_sem, '_vdatalen   ', _vdatalen );
&                           endif
                            END;
                        (* write new epos of stack entries                *)
                        (* epos points act as relative offset to vdatapos *)
                        (*ENDIF*) 
                        a16v.a6viewbuf^.sviewqual_stack.vstack[ _write_idx ].
                              epos := a16v.a6viewbuf^.sviewqual_stack.
                              vstack[ _write_idx ].epos - _firstdatapos;
                        END;
&                   ifdef trace
                    (*ENDIF*) 
                    t01stackentry( ak_sem, a16v.a6viewbuf^.sviewqual_stack.
                          vstack[ _write_idx ], _k );
&                   endif
                    END;
                (*ENDIF*) 
                _write_idx := succ( _write_idx );
                _vstcount  := succ( _vstcount );
                _count     := succ( _count );
                END;
            (*ENDIF*) 
            END;
        (*ENDFOR*) 
        IF  _one_tab_expr
        THEN
            _col_ptr^.ctabno := _last_tabno
        ELSE
            _col_ptr^.ctabno := cak00_maxsources + 1;
        (*ENDIF*) 
        _col_ptr^.ccolstack.eop_func := _op;
        (* write stack entry count for actual column *)
        _col_ptr^.ccolstack.elen_var := _count;
        END;
    (*ENDIF*) 
    _colno     := succ( _colno );
    _stpointer := succ( _j );
    END;
(*ENDWHILE*) 
IF  a16v.a6expr_exist AND ( _b_err = e_ok )
THEN
    BEGIN
    (* write record length *)
    a16v.a6viewbuf^.b_sl := sizeof( a16v.a6viewbuf^.sviewqual_stack ) -
          sizeof( a16v.a6viewbuf^.sviewqual_stack.vstack ) +
          ( _write_idx - 1 ) *
          sizeof(  a16v.a6viewbuf^.sviewqual_stack.vstack[ 1 ] );
    IF  ( _vdatalen > 0 ) AND
        ( acv.a_returncode = 0 )
    THEN
        (* write data of expression columns *)
        BEGIN
        _vdatapos := _vstcount *
              sizeof(  a16v.a6viewbuf^.sviewqual_stack.vstack [ 1 ] ) + 1;
        _data_len := _vdatalen;
        _data_pos := cgg_rec_key_offset + 1;
&       ifdef trace
        t01name( ak_sem, 'write expcol data ' );
        t01int4( ak_sem, 'vstcount    ', _vstcount );
        t01int4( ak_sem, 'vdatapos    ', _vdatapos );
        t01int4( ak_sem, 'vdatalen    ', _data_len );
&       endif
        (* calculate relative record data position *)
        _k := _vdatapos MOD cak_max_viewqual_data;
        IF  _k = 0
        THEN
            _k := cak_max_viewqual_data;
        (*ENDIF*) 
        ;
        (* check, if we need a new record *)
        IF  _k = 1
        THEN
            BEGIN
            ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec, 0, _b_err );
            IF  _b_err = e_ok
            THEN
                (* get new catalog record *)
                BEGIN
                a06inc_linkage( a16v.a6viewkey.slinkage );
                a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
                      sizeof( tak_viewqual_stack_record ),
                      a16v.a6viewbuf, _b_err );
                IF  _b_err = e_ok
                THEN
                    BEGIN
                    a16v.a6viewbuf^.sviewqual_stack.vsegmentid :=
                          a16v.a6segmentid;
                    a16v.a6viewbuf^.sviewqual_stack.vfiller    := '00';
                    a16v.a6viewbuf^.sviewqual_stack.vview_offs := 0;
                    (* write already actual stack count *)
                    a16v.a6viewbuf^.sviewqual_stack.vstcount   := _vstcount;
                    a16v.a6viewbuf^.b_sl :=
                          sizeof( tak_viewqual_stack_record ) -
                          sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata );
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
&       ifdef trace
        (*ENDIF*) 
        t01int4( ak_sem, 'write on lin', ord( a16v.a6viewkey.slinkage[ 2 ] ) );
&       endif
        WHILE ( _data_len > 0 ) AND ( _b_err = e_ok ) DO
            BEGIN
            a16v.a6viewbuf^.sviewqual_stack.vdatapos   := _vdatapos;
            a16v.a6viewbuf^.sviewqual_stack.vdatalen   := _vdatalen;
            IF  _data_len > sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata ) -
                ( _k - 1 )
            THEN
                _move_len   := sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata ) -
                      ( _k - 1 )
            ELSE
                _move_len := _data_len;
            (*ENDIF*) 
            SAPDB_PascalMove ('VAK16 ',   4,    
                  acv.a_mblock.mb_data_size,
                  sizeof( a16v.a6viewbuf^.sviewqual_stack ),
                  @acv.a_mblock.mb_data^.mbp_buf, _data_pos,
                  @a16v.a6viewbuf^.sviewqual_stack, a16v.a6viewbuf^.b_sl + 1,
                  _move_len, _b_err );
&           ifdef trace
            t01int4( ak_sem, 'written     ', _move_len );
            t01moveobj( ak_sem, acv.a_mblock.mb_data^.mbp_buf,
                  _data_pos, _data_pos + _move_len - 1 );
&           endif
            (* write record length *)
            _data_pos              := _data_pos + _move_len;
            _data_len              := _data_len - _move_len;
            IF  _data_len > 0
            THEN
                (* record overflow handling *)
                BEGIN
                _k := 1;
                ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec,
                      a16v.a6viewbuf^.b_sl + _move_len, _b_err );
                IF  _b_err = e_ok
                THEN
                    (* get new catalog record *)
                    BEGIN
                    a06inc_linkage( a16v.a6viewkey.slinkage );
                    a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
                          sizeof( tak_viewqual_stack_record ),
                          a16v.a6viewbuf, _b_err );
                    IF  _b_err = e_ok
                    THEN
                        BEGIN
                        a16v.a6viewbuf^.sviewqual_stack.vsegmentid :=
                              a16v.a6segmentid;
                        a16v.a6viewbuf^.sviewqual_stack.vfiller    := '00';
                        (* write already actual stack count *)
                        a16v.a6viewbuf^.sviewqual_stack.vstcount   := _vstcount;
                        a16v.a6viewbuf^.sviewqual_stack.vview_offs := 0;
                        a16v.a6viewbuf^.b_sl :=
                              sizeof( tak_viewqual_stack_record ) -
                              sizeof( a16v.a6viewbuf^.sviewqual_stack.vdata );
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        ;
        (* write last stack record *)
        ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec,
              a16v.a6viewbuf^.b_sl + _move_len, _b_err );
        END
    ELSE
        (* write last stack record; record length was already written *)
        ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec, 0, _b_err );
    (*ENDIF*) 
    ;
    (* write real vstcount, vdatapos, vdatalen for records with stack entries *)
&   ifdef trace
    t01name( ak_sem, 'write correct data' );
    t01int4( ak_sem, 'stack count ', _vstcount );
    t01int4( ak_sem, 'data positon', _vdatapos );
    t01int4( ak_sem, 'data length ', _vdatalen );
&   endif
    a16v.a6viewkey.sentrytyp := cak_eviewqual_expcol;
    a16v.a6viewkey.slinkage  := cak_zero_linkage;
    _k := _vstcount;
    WHILE _k > 0 DO
        BEGIN
        a06inc_linkage( a16v.a6viewkey.slinkage );
        a10get_sysinfo( acv, a16v.a6viewkey, d_release, a16v.a6viewbuf, _b_err);
        IF  _b_err <> e_ok
        THEN
            a07_b_put_error( acv, _b_err, 1 )
        ELSE
            BEGIN
            a16v.a6viewbuf^.sviewqual_stack.vstcount := _vstcount;
            a16v.a6viewbuf^.sviewqual_stack.vdatapos := _vdatapos;
            a16v.a6viewbuf^.sviewqual_stack.vdatalen := _vdatalen;
            a10repl_sysinfo( acv, a16v.a6viewbuf, _b_err );
            END;
        (*ENDIF*) 
        _k := _k - cak_max_viewqual_stack;
        END;
    (*ENDWHILE*) 
    END
ELSE
    (* delete created catalog record *)
    a10key_del( acv, a16v.a6viewbuf );
(*ENDIF*) 
IF  _b_err <> e_ok
THEN
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16get_viewtext_buf (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
VAR
      _p : tak_sysbufferaddress;
 
BEGIN
(* a660select will fill this entries *)
a16v.a6viewkey           := a01defaultkey;
a16v.a6viewkey.stableid  := a16dmli.d_tableid;
a16v.a6viewkey.sentrytyp := cak_etempviewdesc;
ak16alloc_temp_record( acv, a16v.a6viewkey, _p );
IF  acv.a_returncode = 0
THEN
    BEGIN
    a16v.a6viewkey.sentrytyp := cak_etempviewtext;
    ak16alloc_temp_record( acv, a16v.a6viewkey, _p );
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16init_viewbase_rec (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
BEGIN
WITH a16dmli.d_esparr.pbasep^, sbase DO
    BEGIN
    bauthid         := acv.a_curr_user_id;
    bschema         := a16v.a6schemaid;
    bschemacontext  := acv.a_curr_schema_id;
    btablen^        := a16dmli.d_viewtablen;
    btablekind      := a16v.a6tablekind;
    blinkexist      := [  ];
    bindexexist     := false;
    bunloaded       := false;
    bpriv_all_set   := [  ];
    bpriv_col_exist := [  ];
    bv_level        := a16dmli.d_phase_cnt;
    bv_distinct     := a16dmli.d_distinct;
    bv_viewlist     := a16v.a6col_list;
    bv_checkopt     := ( a16v.a6check_option OR a16v.a6check_view );
    bavgrowlen      := cak_initavgrowlen;
    IF  acv.a_internal_sql <> sql_alter_table
    THEN
        bsqlmode := acv.a_sqlmode;
    (*ENDIF*) 
    bnamed_constr   := 0;
    brecreate_view  := false;
&   ifdef trace
    t01int4( ak_sem, 'a6comment   ', ord( a16v.a6comment ) );
    t01int4( ak_sem, 'a6tablekind ', ord( a16v.a6tablekind ) );
&   endif
    bcomment     := a16v.a6comment;
    battributes  := [ ];
    IF  a16v.a6tablekind = tonebase
    THEN
        WITH a16dmli.d_sparr DO
            BEGIN
            (* d_sparr points to calogrecords of the *)
            (* underlying base table                 *)
            bkeycolcount  := pbasep^.sbase.bkeycolcount;
            blinkexist    := pbasep^.sbase.blinkexist;
            bindexexist   := pbasep^.sbase.bindexexist;
            bunloaded     := pbasep^.sbase.bunloaded;
            bpages        := pbasep^.sbase.bpages;
            brows         := pbasep^.sbase.brows;
            blenfixedcol  := pbasep^.sbase.blenfixedcol;
            bmaxreclen    := pbasep^.sbase.bmaxreclen;
            bvarcolcount  := pbasep^.sbase.bvarcolcount;
            bavgrowlen    := pbasep^.sbase.bavgrowlen;
            btreeid       := pbasep^.sbase.btreeid;
            bv_tablekind  := pbasep^.sbase.btablekind;
            blongvarcolcnt:= pbasep^.sbase.blongvarcolcnt;
            bstringcount  := pbasep^.sbase.bstringcount;
            bnamed_constr := pbasep^.sbase.bnamed_constr;
            bshowkind     := pbasep^.sbase.bshowkind;
            a10rel_sysinfo( a16dmli.d_sparr.pbasep );
            END
        (*ENDWITH*) 
    ELSE
        BEGIN
        btreeid                   := b01niltree_id;
        btreeid.fileHandling_gg00 := [  ];
        bkeycolcount     := 0;
        bpages           := cak_initpages;
        bv_tablekind     := tempty;
        bstringcount     := 0;
        blinkexist       := [  ];
        bindexexist      := false;
        bunloaded        := false;
        bnamed_constr    := 0;
        bshowkind        := sh_no_kind
        END;
    (*ENDIF*) 
    blastkeyind := 0;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16invisible_column_add (
            VAR acv            : tak_all_command_glob;
            VAR usedcollist    : tak16_colprivlist;
            VAR a16v           : tak16_viewglob;
            VAR a16dmli        : tak_dml_info;
            base_ptr           : tak_sysbufferaddress);
 
VAR
      _colind    : integer;
      _new_ind   : integer;
      _col_name  : tsp00_KnlIdentifier;
      _col_ptr   : tak00_colinfo_ptr;
 
BEGIN
_colind  := base_ptr^.sbase.bfirstcolind;
WHILE _colind <> 0 DO
    WITH base_ptr^.sbase.bcolumn[ _colind ]^ DO
        BEGIN
        IF  NOT ( creccolno in usedcollist[ 1 ] )
        THEN
            BEGIN
            a16v.a6sort    := true;
            _col_name      := a01_il_b_identifier;
            _col_name[ 1 ] := chr( 255 );
            _col_name[ 2 ] :=
                  chr( ( a16dmli.d_esparr.pbasep^.sbase.bmaxcol + 1 ) DIV 256 );
            _col_name[ 3 ] :=
                  chr( ( a16dmli.d_esparr.pbasep^.sbase.bmaxcol + 1 ) MOD 256 );
            IF  a16dmli.d_esparr.pbasep^.sbase.bmaxcol = MAX_COL_PER_TAB_GG00
            THEN
                a07_b_put_error( acv, e_too_many_internal_columns, 1 )
            ELSE
                a061app_columnname( acv,
                      a16dmli.d_esparr.pbasep^.sbase, _col_name, _new_ind );
            (*ENDIF*) 
            IF  acv.a_returncode = 0
            THEN
                BEGIN
                _col_ptr := @a16dmli.d_esparr.pbasep^.sbase.bcolumn[ _new_ind ]^;
                a061copy_colinfo( base_ptr^.sbase.bcolumn[ _colind ]^,
                      _col_ptr^ );
                _col_ptr^.ccolpropset := _col_ptr^.ccolpropset +
                      [ ctinvisible ];
                _col_ptr^.cextcolno :=
                      a16dmli.d_esparr.pbasep^.sbase.bmaxcol;
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        _colind := cnextind;
        END;
    (*ENDWITH*) 
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16is_pred (
            VAR a16v           : tak16_viewglob;
            VAR a16dmli        : tak_dml_info;
            VAR link_info      : tak16_linkinfo;
            tabno1             : integer;
            tabno2             : integer;
            VAR is_predecessor : boolean;
            VAR is_1_to_one    : boolean);
 
VAR
      _i          : integer;
      _aux_1_to_1 : boolean;
 
BEGIN
WITH link_info DO
    BEGIN
    (*IF  is_pred in lpred [ tabno1, tabno2 ]*)
    IF  ( ak16test_link_relation( a16dmli, link_info.lpred,
        tabno1, tabno2, is_pred ) )
    THEN
        BEGIN
        (*IF  NOT ( is_1_to_1 in lpred[ tabno1, tabno2 ] )*)
        IF  ( NOT  ( ak16test_link_relation( a16dmli, link_info.lpred,
            tabno1, tabno2, is_1_to_1 )) )
        THEN
            is_1_to_one := false;
        (*ENDIF*) 
        is_predecessor := true
        END
    ELSE
        BEGIN
        _i := 1;
        WHILE ( _i <= a16dmli.d_cntfromtab ) AND NOT( is_predecessor ) DO
            BEGIN
            _aux_1_to_1 := is_1_to_one;
            (*IF  is_pred in lpred[ tabno1, _i ]*)
            IF  ( ak16test_link_relation( a16dmli, link_info.lpred,
                tabno1, _i, is_pred ) )
            THEN
                BEGIN
                (*IF  NOT ( is_1_to_1 in lpred[ tabno1, _i ] )*)
                IF  ( NOT  ( ak16test_link_relation( a16dmli, link_info.lpred,
                    tabno1, _i, is_1_to_1 )) )
                THEN
                    is_1_to_one := false;
                (*ENDIF*) 
                ak16is_pred( a16v, a16dmli, link_info,
                      _i, tabno2, is_predecessor, is_1_to_one )
                END;
            (*ENDIF*) 
            IF  NOT is_predecessor
            THEN
                is_1_to_one := _aux_1_to_1;
            (*ENDIF*) 
            _i := succ( _i );
            END;
        (*ENDWHILE*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16join_information (
            VAR acv        : tak_all_command_glob;
            VAR a16v       : tak16_viewglob;
            VAR a16dmli    : tak_dml_info;
            firstqualpos   : integer;
            update_entries : boolean;
            VAR b_err      : tgg00_BasisError);
 
VAR
      _i           : integer;
      _write_idx   : integer;
      _catalog_key : tgg00_SysInfoKey;
      _qualpoint   : tak_sysbufferaddress;
 
BEGIN
&ifdef trace
t01int4( ak_sem, 'firstqualpos', firstqualpos );
a683_output( ak_sem, a16dmli.d_joins );
&endif
IF  ( NOT update_entries )
THEN
    BEGIN
    a16v.a6vqual_basis^.sviewqual_basis.vjoin_exists := true;
    IF  ( a16dmli.d_checkview )
    THEN
        a16v.a6viewkey.sentrytyp := cak_eviewqual_join_check
    ELSE
        a16v.a6viewkey.sentrytyp := cak_eviewqual_join;
    (*ENDIF*) 
    a16v.a6viewkey.slinkage  := cak_init_linkage;
    a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_fix,
          sizeof( tak_viewqual_join_record ), a16v.a6vqual_join, b_err );
    IF  b_err = e_ok
    THEN
        BEGIN
        a16v.a6vqual_join^.sviewqual_join.vsegmentid := a16v.a6segmentid;
        a16v.a6vqual_join^.sviewqual_join.vjoincount := a16dmli.d_joins.jrc_cnt;
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
_qualpoint := a16v.a6vqual_join;
_i         := 0;
_write_idx := 1;
WHILE ( _i <= a16dmli.d_joins.jrc_cnt - 1 ) AND ( b_err = e_ok ) DO
    BEGIN
    IF  _write_idx > cak_max_viewqual_join
    THEN
        (* put filled record into cache *)
        (* get new/next catalog record  *)
        BEGIN
        IF  update_entries
        THEN
            BEGIN
            a10repl_sysinfo( acv, _qualpoint, b_err );
            (* get next record *)
            _catalog_key := _qualpoint^.syskey;
            a06inc_linkage( _catalog_key.slinkage );
            a10get_sysinfo( acv, _catalog_key, d_release, _qualpoint, b_err );
            IF  b_err <> e_ok
            THEN
                a07_b_put_error( acv, b_err, 1 );
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            ak16finalize_record( acv, _qualpoint, a16v.a6add_rec,
                  sizeof( _qualpoint^.sviewqual_join ) -
                  sizeof( _qualpoint^.sviewqual_join.vjoin ) +
                  ( _write_idx - 1 ) *
                  sizeof( _qualpoint^.sviewqual_join.vjoin[ 1 ] ),
                  b_err );
            (* get new record *)
            a06inc_linkage( a16v.a6viewkey.slinkage );
            a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
                  sizeof( tak_viewqual_join_record ), _qualpoint, b_err );
            IF  b_err = e_ok
            THEN
                BEGIN
                _qualpoint^.sviewqual_join.vsegmentid   := a16v.a6segmentid;
                _qualpoint^.sviewqual_join.vjoincount   := a16dmli.d_joins.jrc_cnt;
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        _write_idx := 1;
        END; (* get new record *)
    (*ENDIF*) 
    IF  b_err = e_ok
    THEN
        WITH _qualpoint^.sviewqual_join.vjoin[ _write_idx ] DO
            BEGIN
            WITH a16dmli.d_joins.jrc_joinarr^[ _i ].jo_recs[ 1 ] DO
                BEGIN
                j1tableno    := jop_tableno;
                j1fieldno    := jop_fieldno;
                j1startstack := jop_startstack - firstqualpos + 1;
                j1cntstack   := jop_cntstack;
                j1propset    := jop_propset;
                j1inoutlen   := jop_inoutlen;
                j1outpos     := jop_outpos;
                j1datatype   := jop_datatyp;
                END;
            (*ENDWITH*) 
            WITH a16dmli.d_joins.jrc_joinarr^[ _i ].jo_recs[ 2 ] DO
                BEGIN
                j2tableno    := jop_tableno;
                j2fieldno    := jop_fieldno;
                j2cntstack   := jop_cntstack;
                j2propset    := jop_propset;
                j2inoutlen   := jop_inoutlen;
                j2outpos     := jop_outpos;
                j2datatype   := jop_datatyp;
                END;
            (*ENDWITH*) 
            j12operator := a16dmli.d_joins.jrc_joinarr^[ _i ].jo_op;
            j12partno :=  a16dmli.d_joins.jrc_joinarr^[ _i ].jo_partno;
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    _i         := succ( _i );
    _write_idx := succ( _write_idx );
    END;
(*ENDWHILE*) 
;
(* write last record *)
IF  update_entries
THEN
    (* update catalog record *)
    a10repl_sysinfo( acv, _qualpoint, b_err )
ELSE
    BEGIN
    (* write correct catalog record length *)
    ak16finalize_record( acv, _qualpoint, a16v.a6add_rec,
          sizeof( _qualpoint^.sviewqual_join ) -
          sizeof( _qualpoint^.sviewqual_join.vjoin ) +
          ( _write_idx - 1 ) *
          sizeof( _qualpoint^.sviewqual_join.vjoin[ 1 ] ), b_err );
    END;
(*ENDIF*) 
IF  b_err <> e_ok
THEN
    a07_b_put_error( acv, b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16mantory_check (
            VAR acv             : tak_all_command_glob;
            VAR a16v            : tak16_viewglob;
            VAR a16dmli         : tak_dml_info;
            VAR a16keyextno     : tak16_keyextno;
            VAR link_info       : tak16_linkinfo;
            VAR updateable_view : boolean);
 
VAR
      _more_found : boolean;
      _dummy      : boolean;
      _key_col    : boolean;
      _i          : integer;
      _j          : integer;
      _tab        : integer;
      _col        : integer;
      _recno      : integer;
      _extcolno   : integer;
      _tab_no     : integer;
      _col_cnt    : integer;
      _write_idx  : integer;
      _derivedcnt : integer;
      _col_ptr    : tak00_colinfo_ptr;
      _max_col    : ARRAY[ 1..cak00_maxsources ] OF integer;
      _col_info   : tak16_colinfo;
      _b_err      : tgg00_BasisError;
      _tmpmod     : integer;
&     ifdef trace
      columnName  : tsp00_KnlIdentifier;
&     endif
 
BEGIN
WITH link_info DO
    BEGIN
    _tab := a16v.a6sequence[ 1 ];
    FOR _i := 1 TO a16v.a6keycolcount[ _tab ] DO
        lmantory^[ _tab ] := lmantory^[ _tab ] + [ a16keyextno[ _tab, _i ] ];
    (*ENDFOR*) 
&   ifdef trace
    FOR _i := 1 TO lcol_cnt DO
        WITH lcolinfo[ _i ] DO
            t01p4int4( ak_sem, 'lcol_info   ', tabno1, recno1, tabno2, recno2 );
        (*ENDWITH*) 
    (*ENDFOR*) 
&   endif
    _col_cnt := 0;
    FOR _i := 1 TO a16dmli.d_cntfromtab DO
        BEGIN
        FOR _j := 1 TO a16v.a6max_col[ _i ] DO
            IF  _j in lmantory^[ _i ]
            THEN
                BEGIN
                _col_cnt := succ( _col_cnt );
                _max_col[ _i ] := _j;
                _col_info[ _col_cnt ].tabno := _i;
                _col_info[ _col_cnt ].colno := _j;
                IF  NOT ( ak16column_in_view( a16dmli.d_esparr.pbasep^.sbase,
                    _col_info[ _col_cnt ].colno, _col_info[ _col_cnt ].tabno,
                    _col_info[ _col_cnt ].extno, _dummy ) )
                THEN
                    _col_info[ _col_cnt ].extno := 0;
                (*ENDIF*) 
                _col_info[ _col_cnt ].exttabno  := _i;
&               ifdef trace
                t01p4int4( ak_sem, 'mantory_col=', _col_info[ _col_cnt ].tabno,
                      _col_info[ _col_cnt ].colno,
                      _col_info[ _col_cnt ].extno, 0 );
&               endif
                END;
            (*ENDIF*) 
        (*ENDFOR*) 
        END;
    (*ENDFOR*) 
&   ifdef trace
    FOR _i := 1 TO a16dmli.d_cntfromtab DO
        t01p2int4( ak_sem, 'tabno=      ', _i, 'maxcol      ', _max_col[ _i ] );
    (*ENDFOR*) 
    t01int4( ak_sem, 'update_view ', ord( updateable_view ) );
&   endif
    REPEAT
        _more_found := false;
        FOR _tab := 1 TO a16dmli.d_cntfromtab DO
            FOR _col := 1 TO _max_col[ _tab ] DO
                IF  ak16specified( _col_info, _col_cnt, _tab, _col, _extcolno )
                THEN
                    FOR _i := 1 TO lcol_cnt DO
                        WITH lcolinfo[ _i ] DO
                            BEGIN
                            _tab_no := 0;
                            _recno  := 0;
                            IF  ( tabno1 = _tab ) AND ( recno1 = _col )
                            THEN
                                BEGIN
                                _tab_no := tabno2;
                                _recno  := recno2
                                END
                            ELSE
                                IF  ( tabno2 = _tab ) AND ( recno2 = _col )
                                THEN
                                    BEGIN
                                    _tab_no := tabno1;
                                    _recno  := recno1
                                    END;
&                               ifdef trace
                                (*ENDIF*) 
                            (*ENDIF*) 
                            t01p2int4( ak_sem, 'search tabno', _tab_no,
                                  'search_colno', _recno );
&                           endif
                            IF  _tab_no > 0
                            THEN
                                BEGIN
                                _j := 1;
                                WHILE _j <= _col_cnt DO
                                    IF  _col_info[ _j ].tabno = _tab_no
                                    THEN
                                        BEGIN
                                        IF  _col_info[ _j ].colno = _recno
                                        THEN
                                            BEGIN
                                            IF  _col_info[ _j ].extno = 0
                                            THEN
                                                BEGIN
                                                _col_info[ _j ].extno :=
                                                      ( _extcolno MOD
                                                      c_derived_ind ) +
                                                      c_derived_ind;
                                                _col_info[ _j ].exttabno :=
                                                      _tab;
                                                _more_found := true;
                                                _j := succ( _j );
                                                END
                                            ELSE
                                                BEGIN
                                                _tmpmod :=  _col_info[ _j ].extno
                                                      MOD c_derived_ind ;
                                                IF  (_tmpmod) <>
                                                    ( _extcolno MOD
                                                    c_derived_ind )
                                                THEN
                                                    BEGIN
&                                                   ifdef trace
                                                    t01int4( ak_sem,'extno found ',
                                                       _extcolno );
                                                    t01int4( ak_sem,'extno stored',
                                                       _col_info[ _j ].extno );
                                                    t01int4( ak_sem,'tabno stored',
                                                       _col_info[ _j ].tabno );
                                                    t01int4( ak_sem,'recno stored',
                                                       _col_info[ _j ].colno );
&                                                   endif
                                                    _j := succ( _col_cnt );
                                                    updateable_view := false;
                                                    END
                                                ELSE
                                                    _j := succ( _j );
                                                (*ENDIF*) 
                                                END
                                            (*ENDIF*) 
                                            END
                                        ELSE
                                            IF  _col_info[ _j ].colno >
                                                _recno
                                            THEN
                                                _j := succ( _col_cnt )
                                            ELSE
                                                _j := succ( _j );
                                            (*ENDIF*) 
                                        (*ENDIF*) 
                                        END
                                    ELSE
                                        IF  _col_info[ _j ].tabno > _tab_no
                                        THEN
                                            _j := succ( _col_cnt )
                                        ELSE
                                            _j := succ( _j );
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                (*ENDWHILE*) 
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDWITH*) 
                    (*ENDFOR*) 
&               ifdef trace
                (*ENDIF*) 
            (*ENDFOR*) 
        (*ENDFOR*) 
        t01int4( ak_sem, 'more_found  ', ord( _more_found ) );
        t01int4( ak_sem, 'update_view ', ord( updateable_view ) );
&       endif
    UNTIL
        NOT ( _more_found ) OR NOT ( updateable_view );
    (*ENDREPEAT*) 
&   ifdef trace
    t01str30 (ak_sem,'======== column dependancy ===');
    FOR _i := 1 TO _col_cnt DO
        WITH _col_info[ _i ] DO
            t01p4int4 (ak_sem, 'mantory_col=',
                  tabno, colno, extno, exttabno);
        (*ENDWITH*) 
    (*ENDFOR*) 
&   endif
    IF  updateable_view
    THEN
        BEGIN
        _i := 1;
        WHILE _i <= _col_cnt DO
            IF  _col_info[ _i ].extno = 0
            THEN
                BEGIN
                (* mandatory column can not be derived from     *)
                (* key or foreign key column ==> not updatable  *)
                updateable_view := false;
                _i := succ( _col_cnt ); (* exit while *)
                END
            ELSE
                _i := succ( _i );
            (*ENDIF*) 
        (*ENDWHILE*) 
        END;
    (*ENDIF*) 
    IF  updateable_view
    THEN
        BEGIN
        _b_err := e_ok;
        a16v.a6vqual_basis^.sviewqual_basis.vderived_exists := true;
        a16v.a6viewkey.sentrytyp := cak_eviewqual_derivedcol;
        a16v.a6viewkey.slinkage  := cak_init_linkage;
        a10_nil_get_sysinfo( acv, a16v.a6viewkey,
              d_release, sizeof( tak_viewqual_derivedcol_record ),
              a16v.a6viewbuf, _b_err );
        IF  _b_err = e_ok
        THEN
            BEGIN
            (* remark header of join information *)
            a16v.a6viewbuf^.sviewqual_derivedcol.vsegmentid  := a16v.a6segmentid;
            (* write temporary count *)
            a16v.a6viewbuf^.sviewqual_derivedcol.vderivedcnt := 0;
            _derivedcnt := 0;
            _write_idx  := 1;
            FOR _i := 1 TO _col_cnt DO
                BEGIN
                IF  _col_info[ _i ].extno > c_derived_ind
                THEN
                    BEGIN
                    IF  _write_idx > cak_max_viewqual_derivedcol
                    THEN
                        (* record overflow handling *)
                        BEGIN
                        ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec,
                              sizeof( a16v.a6viewbuf^.
                              sviewqual_derivedcol ) - sizeof( a16v.a6viewbuf^.
                              sviewqual_derivedcol.vderived_cols ) +
                              ( _write_idx - 1 ) * sizeof( a16v.a6viewbuf^.
                              sviewqual_derivedcol.vderived_cols[ 1 ] ), _b_err );
                        IF  _b_err = e_ok
                        THEN
                            (* get new catalog record *)
                            BEGIN
                            a06inc_linkage( a16v.a6viewkey.slinkage );
                            a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
                                  sizeof( tak_viewqual_derivedcol_record ),
                                  a16v.a6viewbuf, _b_err );
                            IF  _b_err = e_ok
                            THEN
                                BEGIN
                                a16v.a6viewbuf^.sviewqual_stack.
                                      vsegmentid := a16v.a6segmentid;
                                (* write temporary 0 count *)
                                a16v.a6viewbuf^.sviewqual_derivedcol.
                                      vderivedcnt  := 0;
                                END;
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        _write_idx := 1;
                        END;
                    (*ENDIF*) 
                    IF  _b_err = e_ok
                    THEN
                        BEGIN
                        a16v.a6viewbuf^.sviewqual_derivedcol.
                              vderived_cols [ _write_idx ].dtabno :=
                              _col_info[ _i ].tabno;
                        a16v.a6viewbuf^.sviewqual_derivedcol.
                              vderived_cols [ _write_idx ].drecno :=
                              _col_info[ _i ].colno;
                        a16v.a6viewbuf^.sviewqual_derivedcol.
                              vderived_cols [ _write_idx ].dextno :=
                              _col_info[ _i ].extno - c_derived_ind;
                        a16v.a6viewbuf^.sviewqual_derivedcol.
                              vderived_cols [ _write_idx ].dexttabno :=
                              _col_info[ _i ].exttabno;
                        _write_idx  := succ( _write_idx );
                        END;
                    (*ENDIF*) 
                    _derivedcnt := succ( _derivedcnt );
                    END;
                (*ENDIF*) 
                IF  _col_info[ _i ].extno < c_derived_ind
                THEN
                    BEGIN
                    a06extcolno( a16dmli.d_esparr.pbasep^.sbase,
                          _col_info[ _i ].extno, _col_ptr );
                    ak16opt_check( acv, a16v, _col_ptr^, _col_info, _col_cnt );
                    _col_ptr^.ccolpropset := _col_ptr^.ccolpropset + [ ctlink ]
                    END;
                (*ENDIF*) 
                _key_col := false;
                IF  _col_info[ _i ].tabno = a16v.a6sequence[ 1 ]
                THEN
                    BEGIN
                    _j := 1;
                    WHILE  _j <= a16v.a6keycolcount[ a16v.a6sequence[ 1 ] ] DO
                        IF  _col_info[ _i ].colno =
                            a16keyextno[ _col_info[ _i ].tabno, _j ]
                        THEN
                            BEGIN
                            _key_col := true;
                            _j       := csp_maxint2; (* exit while *)
                            END
                        ELSE
                            _j := succ( _j );
                        (*ENDIF*) 
                    (*ENDWHILE*) 
                    END;
                (*ENDIF*) 
                IF  _key_col
                THEN
                    BEGIN
                    _col := _col_info[ _i ].extno MOD c_derived_ind;
                    a06extcolno( a16dmli.d_esparr.pbasep^.sbase, _col, _col_ptr );
&                   ifdef trace
                    t01sname( ak_sem, 'key is      ');
                    a061get_colname (_col_ptr^, columnName);
                    t01lidentifier( ak_sem, columnName );
&                   endif
                    _col_ptr^.ccolpropset := _col_ptr^.ccolpropset +
                          [ ctjoinviewkey ];
                    END;
                (*ENDIF*) 
                END;
            (*ENDFOR*) 
            END;
        (*ENDIF*) 
        ;
        (* write last record *)
        IF  _b_err = e_ok
        THEN
            BEGIN
            ak16finalize_record( acv, a16v.a6viewbuf, a16v.a6add_rec,
                  sizeof( a16v.a6viewbuf^.
                  sviewqual_derivedcol) - sizeof( a16v.a6viewbuf^.
                  sviewqual_derivedcol.vderived_cols ) +
                  ( _write_idx - 1 ) * sizeof( a16v.a6viewbuf^.
                  sviewqual_derivedcol.vderived_cols[ 1 ] ), _b_err );
            END;
        (*ENDIF*) 
        ;
        (* write correct vderivedcnt *)
        IF  _b_err = e_ok
        THEN
            BEGIN
            a16v.a6viewkey.sentrytyp := cak_eviewqual_derivedcol;
            a16v.a6viewkey.slinkage  := cak_zero_linkage;
            _i := _derivedcnt;
            WHILE _i > 0 DO
                BEGIN
                a06inc_linkage( a16v.a6viewkey.slinkage );
                a10get_sysinfo( acv, a16v.a6viewkey, d_release,
                      a16v.a6viewbuf, _b_err );
                IF  _b_err = e_ok
                THEN
                    BEGIN
                    a16v.a6viewbuf^.sviewqual_derivedcol.vderivedcnt :=
                          _derivedcnt;
                    a10repl_sysinfo( acv, a16v.a6viewbuf, _b_err );
                    END;
                (*ENDIF*) 
                _i := _i - cak_max_viewqual_derivedcol;
                END;
            (*ENDWHILE*) 
            END;
        (*ENDIF*) 
        IF  _b_err <> e_ok
        THEN
            a07_b_put_error( acv, _b_err, 1 );
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16opt_check (
            VAR acv      : tak_all_command_glob;
            VAR a16v     : tak16_viewglob;
            VAR col_info : tak00_columninfo;
            VAR man_info : tak16_colinfo;
            col_cnt      : integer);
 
VAR
      _b_err         : tgg00_BasisError;
      _res           : tsp00_LcompResult;
      _i             : integer;
      _rbuf1         : tak_sysbufferaddress;
      _rbuf2         : tak_sysbufferaddress;
      _sysk          : tgg00_SysInfoKey;
 
BEGIN
&ifdef trace
t01buf1( ak_sem, col_info, 1, 44 );
&endif
WITH a16v.a6vqual_basis^.sviewqual_basis DO
    BEGIN
    _i := 1;
    col_info.ccolpropset := col_info.ccolpropset - [ ctopt ];
    WHILE ( _i <= col_cnt ) AND ( ctdefault in col_info.ccolpropset ) DO
        BEGIN
        IF  ( man_info[ _i ].extno > c_derived_ind ) AND
            ( man_info[ _i ].extno - c_derived_ind = col_info.cextcolno )
        THEN
            BEGIN
            (* check if current column and derived column have *)
            (* the same default value => column is optional    *)
&           ifdef trace
            t01int4 (ak_sem, 'extno       ', man_info[ _i ].extno);
            t01int4 (ak_sem, 'tabno       ', man_info[ _i ].tabno);
            t01int4 (ak_sem, 'colno       ', man_info[ _i ].colno);
&           endif
            _sysk.stableid :=
                  vtable[ man_info[ _i ].tabno ].vttableid;
            _sysk.sentrytyp     := cak_edefault;
            _sysk.slinkage[ 1 ] := chr( man_info[ _i ].colno DIV 256 );
            _sysk.slinkage[ 2 ] := chr( man_info[ _i ].colno MOD 256 );
            _sysk.skeylen       := mxak_standard_sysk;
            a10get_sysinfo( acv, _sysk, d_fix, _rbuf1, _b_err );
            IF  _b_err = e_ok
            THEN
                BEGIN
                _sysk.stableid      := vtable[ col_info.ctabno ].vttableid;
                _sysk.sentrytyp     := cak_edefault;
                _sysk.slinkage[ 1 ] := chr( col_info.creccolno DIV 256 );
                _sysk.slinkage[ 2 ] := chr( col_info.creccolno MOD 256 );
                _sysk.skeylen       := mxak_standard_sysk;
                a10get_sysinfo( acv, _sysk, d_release,
                      _rbuf2, _b_err );
                a10_rel_sysinfo( acv, _rbuf1^.syskey )
                END;
            (*ENDIF*) 
            IF  _b_err = e_ok
            THEN
                BEGIN
                IF  ( _rbuf1^.sdefault.dfdefault_function = 0 ) AND
                    ( _rbuf2^.sdefault.dfdefault_function = 0 )
                THEN (* no default function for both default's *)
                    s30cmp( _rbuf1^.sdefault.dfvalues, 2,
                          a14LengthOfDefaultValue( _rbuf1^.sdefault),
                          _rbuf2^.sdefault.dfvalues, 2,
                          a14LengthOfDefaultValue(_rbuf2^.sdefault), _res )
                ELSE
                    _res := l_less;
                (*ENDIF*) 
                IF  _res <> l_equal
                THEN
                    _b_err := e_key_not_found;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  _b_err <> e_ok
            THEN
                col_info.ccolpropset := col_info.ccolpropset - [ ctdefault ];
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        _i := succ( _i );
        END;
    (*ENDWHILE*) 
    IF  ctdefault in col_info.ccolpropset
    THEN
        col_info.ccolpropset := col_info.ccolpropset + [ ctopt ];
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16clean_up (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob);
 
CONST
      c_temp = true;
 
VAR
      _b_err        : tgg00_BasisError;
      _aux_return   : tsp00_Int2;
      _aux_errorpos : tsp00_Int4;
      _qual         : tak_del_tab_qual;
 
BEGIN
IF  a16v.a6tableid <> cgg_zero_id
THEN
    BEGIN
    _aux_return   := acv.a_returncode;
    _aux_errorpos := acv.a_errorpos;
    acv.a_returncode := 0;
    _qual.del_colno := 0;
    a10_del_tab_sysinfo( acv,
          a16v.a6tableid, _qual, c_temp, _b_err );
    acv.a_returncode := _aux_return;
    acv.a_errorpos   := _aux_errorpos;
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16compare_structure (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
VAR
      _col_name       : tsp00_KnlIdentifier;
      _old_ptr        : tak_sysbufferaddress;
      _col_ptr        : tak00_colinfo_ptr;
      _old_key        : tgg00_SysInfoKey;
      _ix             : integer;
      _cx             : integer;
      _aux_return     : tsp00_Int2;
      _aux_errorpos   : tsp00_Int4;
      _b_err          : tgg00_BasisError;
 
BEGIN
(* new view structure in a16dmli.d_esparr *)
_old_key           := a01defaultkey;
_old_key.stableid  := a16v.a6tableid;
_old_key.sentrytyp := cak_eresult;
a10get_sysinfo( acv, _old_key, d_fix, _old_ptr, _b_err );
IF  _b_err <> e_ok
THEN
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
IF  acv.a_returncode = 0
THEN
    BEGIN
    a16v.a6oldmaxcol := _old_ptr^.sbase.bmaxcol;
    FOR _ix := 1 TO _old_ptr^.sbase.bmaxcol DO
        a16v.a6col_map[ _ix ] := 0;
    (*ENDFOR*) 
    FOR _cx := _old_ptr^.sbase.bfirstindex TO _old_ptr^.sbase.blastindex DO
        IF  NOT ( ctdropped in _old_ptr^.sbase.bcolumn[ _cx ]^.ccolpropset )
            AND
            NOT ( ctinvisible in _old_ptr^.sbase.bcolumn[ _cx ]^.ccolpropset )
        THEN
            BEGIN
            a061get_colname( _old_ptr^.sbase.bcolumn[ _cx ]^, _col_name );
            IF  a061exist_columnname( a16dmli.d_esparr.pbasep^.sbase,
                _col_name, _col_ptr )
            THEN
                a16v.a6col_map
                      [ _old_ptr^.sbase.bcolumn[ _cx ]^.cextcolno ] :=
                      _col_ptr^.cextcolno;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDFOR*) 
    END;
(*ENDIF*) 
_aux_return   := acv.a_returncode;
_aux_errorpos := acv.a_errorpos;
acv.a_returncode := 0;
_old_key.slinkage := cak_init_linkage;
a10del_sysinfo( acv, _old_key, _b_err );
IF  _aux_return <> 0
THEN
    BEGIN
    acv.a_returncode := _aux_return;
    acv.a_errorpos   := _aux_errorpos;
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16modify_privileges (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
VAR
      _b_err : tgg00_BasisError;
      _ix    : integer;
      _p     : tak_priv_descriptors;
      _sysp  : tak_sysbufferaddress;
      _opriv : tak_columnset;
      _sysk  : tgg00_SysInfoKey;
      _priv  : tak_privilege;
 
BEGIN
_sysk           := a16dmli.d_esparr.pbasep^.syskey;
_sysk.sentrytyp := cak_epriv;
REPEAT
    _priv := a01emptypriv;
    a10next_sysinfo( acv, _sysk, 0, d_release, cak_edummy, _sysp, _b_err );
    IF  _b_err = e_ok
    THEN
        IF  _sysp^.syskey.sentrytyp = cak_epriv
        THEN
            a06unpack_priv( _sysp^.spriv.pr_priv, _priv )
        ELSE
            IF  _sysp^.syskey.sentrytyp = cak_eprivuser
            THEN
                a06unpack_priv( _sysp^.sprivuser.pru_priv, _priv )
            ELSE
                _b_err := e_no_next_record;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    IF  _b_err = e_ok
    THEN
        IF  _sysp^.spriv.pr_userid <> acv.a_curr_user_id
        THEN
            BEGIN
            _priv.priv_all_set :=
                  _priv.priv_all_set * a16v.a6priv.priv_all_set;
            _priv.priv_all_grant_set :=
                  _priv.priv_all_grant_set * a16v.a6priv.priv_all_grant_set;
            IF  _priv.priv_col_exist <> [ ]
            THEN
                FOR _p := priv_col_sel TO priv_col_upd_grant DO
                    BEGIN
&                   ifdef trace
                    CASE _p OF
                        priv_col_sel :
                            t01int4 (ak_sem, 'col select  ', 1);
                        priv_col_upd :
                            t01int4 (ak_sem, 'col update  ', 1);
                        priv_col_sel_grant :
                            t01int4 (ak_sem, 'col select g', 1);
                        priv_col_upd_grant :
                            t01int4 (ak_sem, 'col update g', 1);
                        END;
                    (*ENDCASE*) 
                    FOR _ix := 1 TO MAX_COL_PER_TAB_GG00 DO
                        IF  _ix in _priv.priv_col[ _p ]
                        THEN
                            BEGIN
                            t01int4 (ak_sem, 'col no      ', _ix);
                            t01int4 (ak_sem, 'map col no  ',
                                  a16v.a6col_map[ _ix ]);
                            END;
&                       endif
                        (*ENDIF*) 
                    (*ENDFOR*) 
                    _opriv               := _priv.priv_col[ _p ];
                    _priv.priv_col[ _p ] := [ ];
                    FOR _ix := 1 TO  a16v.a6oldmaxcol DO
                        IF  _ix in _opriv
                        THEN
                            IF  ( a16v.a6col_map[ _ix ] in
                                a16v.a6priv.priv_col[ _p ] )
                                OR
                                (( _p = priv_col_sel ) AND
                                ( r_sel in a16v.a6priv.priv_all_set ))
                                OR
                                (( _p = priv_col_upd ) AND
                                ( r_upd in a16v.a6priv.priv_all_set ))
                                OR
                                (( _p = priv_col_sel_grant ) AND
                                ( r_sel in a16v.a6priv.priv_all_grant_set ))
                                OR
                                (( _p = priv_col_upd_grant ) AND
                                ( r_upd in a16v.a6priv.priv_all_grant_set ))
                            THEN
                                _priv.priv_col[ _p ] :=
                                      _priv.priv_col[ _p ] +
                                      [ a16v.a6col_map[ _ix ] ];
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDFOR*) 
                    IF  _priv.priv_col[ _p ] <> [ ]
                    THEN
                        _priv.priv_col_exist :=
                              _priv.priv_col_exist + [ _p ]
                    (*ENDIF*) 
                    END;
                (*ENDFOR*) 
            (*ENDIF*) 
            IF  _priv.priv_c132 = a01emptypriv.priv_c132
            THEN
                a10del_sysinfo( acv, _sysk, _b_err )
            ELSE
                BEGIN
                IF  _sysp^.syskey.sentrytyp = cak_epriv
                THEN
                    a22pack_priv( _sysp, _priv, _sysp^.spriv.pr_priv )
                ELSE
                    a22pack_priv( _sysp,
                          _priv, _sysp^.sprivuser.pru_priv );
                (*ENDIF*) 
                a10_add_repl_sysinfo( acv, _sysp, false, _b_err );
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
UNTIL
    _b_err <> e_ok;
(*ENDREPEAT*) 
IF  _b_err <> e_no_next_record
THEN
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16save_priv_comments (
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
VAR
      _jx           : integer;
 
BEGIN
a16v.a6public_priv.priv_all_set   := a16dmli.d_sparr.pbasep^.sbase.bpriv_all_set;
a16v.a6public_priv.priv_col_exist := a16dmli.d_sparr.pbasep^.sbase.bpriv_col_exist;
a16v.a6comment     := a16dmli.d_sparr.pbasep^.sbase.bcomment;
a16v.a6comment_set := [ ];
FOR _jx := a16dmli.d_sparr.pbasep^.sbase.bfirstindex
      TO a16dmli.d_sparr.pbasep^.sbase.blastindex DO
    IF  ctcomment in a16dmli.d_sparr.pbasep^.sbase.bcolumn[ _jx ]^.ccolpropset
    THEN
        a16v.a6comment_set := a16v.a6comment_set +
              [ a16dmli.d_sparr.pbasep^.sbase.bcolumn[ _jx ]^.cextcolno ];
    (*ENDIF*) 
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16store_old_view_image (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
VAR
      _b_err          : tgg00_BasisError;
      _ix             : integer;
      _sysbuf         : tak_sysbufferaddress;
      _new_key        : tgg00_SysInfoKey;
      _old_key        : tgg00_SysInfoKey;
      _viewscanpar    : tak_save_viewscan_par;
 
BEGIN
IF  acv.a_returncode = 0
THEN
    BEGIN
    (* delete all column comments *)
    FOR _ix := a16dmli.d_sparr.pbasep^.sbase.bfirstindex TO
          a16dmli.d_sparr.pbasep^.sbase.blastindex DO
        WITH a16dmli.d_sparr.pbasep^.sbase.bcolumn[_ix]^DO
            IF  ctcomment in ccolpropset
            THEN
                a26drop_comment (acv, cm_column,
                      a16dmli.d_sparr.pbasep^.sbase.bsurrogate,
                      a16dmli.d_sparr.pbasep^.sbase.bsurrogate,
                      cextcolno);
            (*ENDIF*) 
        (*ENDWITH*) 
    (*ENDFOR*) 
    a27init_viewscanpar( acv, _viewscanpar, v_save_scheme );
    WITH _viewscanpar DO
        BEGIN
        vsc_base_tabid := a16dmli.d_sparr.pbasep^.syskey.stableid;
        vsc_first_save := true;
        vsc_last_save  := true;
        acv.a_p_arr1   := a16dmli.d_sparr;
        a15catalog_save( acv, _viewscanpar );
        a16v.a6scheme_treeid := _viewscanpar.vsc_tree_id
        END;
    (*ENDWITH*) 
    _old_key           := a16dmli.d_sparr.pbasep^.syskey;
    _old_key.sentrytyp := cak_eviewtext;
    a10get_sysinfo( acv, _old_key, d_fix, _sysbuf, _b_err );
    IF  _b_err = e_ok
    THEN
        BEGIN
        _ix := 1;
        WHILE _ix <= _sysbuf^.sviewtext.vttabcount DO
            BEGIN
            a11del_usage_entry( acv, _sysbuf^.sviewtext.
                  vttab[ _ix ].vtttableid, _viewscanpar.vsc_base_tabid );
            _ix := _ix + 1
            END;
        (*ENDWHILE*) 
        END;
    (*ENDIF*) 
    _old_key.sentrytyp := cak_etable;
    _new_key           := _old_key;
    _new_key.sentrytyp := cak_eresult;
    a10_copy_catalog_rec( acv, _old_key, false (* don't delete old record *),
          _new_key, a16dmli.d_sparr.pbasep^.sbase.bsegmentid,
          true (* add new record *), _b_err );
    IF  _b_err <> e_ok
    THEN
        a07_b_put_error( acv, _b_err, 1 );
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16table_ref (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
VAR
      _b_err      : tgg00_BasisError;
      _tabref_buf : tak_sysbufferaddress;
      _sysk       : tgg00_SysInfoKey;
      _permkey    : tgg00_SysInfoKey;
 
BEGIN
_sysk              := a01defaultkey;
_sysk.sauthid      := a16v.a6schemaid;
_sysk.sidentifier  := a16dmli.d_viewtablen;
_sysk.sentrytyp    := cak_etemptableref;
(* this entry has longer key than standard key *)
_sysk.skeylen      := mxak_standard_sysk + sizeof( _sysk.sidentifier );
_permkey           := _sysk;
_permkey.sentrytyp := cak_etableref;
a10get_sysinfo( acv, _sysk, d_release, _tabref_buf, _b_err );
IF  _b_err = e_ok
THEN
    a10_copy_catalog_rec( acv, _sysk, true(* del old rec *),
          _permkey, a16v.a6segmentid, true(* add new record *), _b_err );
(*ENDIF*) 
IF  _b_err <> e_ok
THEN
    IF  _b_err = e_duplicate_sysinfo (* PTS 1110817 *)
    THEN
        a07_nb_put_error (acv, e_duplicate_tablename, 1, a16dmli.d_viewtablen)
    ELSE
        a07_b_put_error( acv, _b_err, 1 );
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16sort_joins (
            VAR acv       : tak_all_command_glob;
            VAR a16v      : tak16_viewglob;
            VAR a16dmli   : tak_dml_info;
            VAR link_info : tak16_linkinfo);
 
VAR
      _i            : integer;
      _j            : integer;
      _aux_joins    : tak_joinrec;
      (*_handled      : SET OF 0..MAX_JOINS_GG04;*)
      _copied       : tsp00_Addr;
      _b_err        : tgg00_BasisError;
 
      _cast         : RECORD
            CASE boolean OF
                true :
                    (addr: tsp00_Addr);
                false :
                    (ptr : tak_joinarr_ptr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
a16v.a6resort_joins := true;
&ifdef trace
FOR _i := 1 TO link_info.ljoincnt DO
    t01int4 (ak_sem, 'joinsequence', link_info.ljoins^[ _i ]);
(*ENDFOR*) 
&endif
_aux_joins := a16dmli.d_joins;
_aux_joins.jrc_joinarr := NIL;
_cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
      a16dmli.d_joins.jrc_capacity * sizeof(tak_one_join) );
_aux_joins.jrc_joinarr := _cast.ptr;
_copied := NIL;
_copied := gg12InitBitArray( acv.a_transinf.tri_trans, a16dmli.d_joins.jrc_cnt );
IF  (( _aux_joins.jrc_joinarr <> NIL ) AND ( _copied <> NIL ))
THEN
    BEGIN
    _b_err := e_ok;
    SAPDB_PascalMove ('VAK16 ',   5,    
          a16dmli.d_joins.jrc_capacity * sizeof(tak_one_join),
          _aux_joins.jrc_capacity * sizeof(tak_one_join),
          @a16dmli.d_joins.jrc_joinarr^, 1,
          @_aux_joins.jrc_joinarr^, 1,
          a16dmli.d_joins.jrc_capacity * sizeof(tak_one_join),
          _b_err);
    IF  ( _b_err = e_ok )
    THEN
        BEGIN
        (*_copied   := [  ];*)
        FOR _i := 1 TO link_info.ljoincnt DO
            BEGIN
            a16dmli.d_joins.jrc_joinarr^[ _i - 1 ] :=
                  _aux_joins.jrc_joinarr^[ link_info.ljoins^[ _i ] ];
            (*_copied := _copied + [ link_info.ljoins^[ _i ] ];*)
            gg12SetBit( _copied, link_info.ljoins^[ _i ], true );
&           ifdef trace
            t01int4 (ak_sem, 'overwritten ', link_info.ljoins^[ _i ]);
&           endif
            END;
        (*ENDFOR*) 
        _j := link_info.ljoincnt;
        FOR _i := 1 TO a16dmli.d_joins.jrc_cnt DO
            (*IF  NOT (( _i - 1 ) in _copied )*)
            IF  ( NOT gg12GetBit( _copied, _i - 1 ) )
            THEN
                (* entry on [_i-1] is overwritten*)
                BEGIN
                _j := succ( _j );
                a16dmli.d_joins.jrc_joinarr^[ _j-1 ] :=
                      _aux_joins.jrc_joinarr^[ _i-1 ];
                END;
            (*ENDIF*) 
        (*ENDFOR*) 
        _b_err := e_ok;
        ak16join_information( acv, a16v, a16dmli, a16v.a6mqual_pos,
              c_update_entries, _b_err );
        IF  _b_err <> e_ok
        THEN
            a07_b_put_error( acv, _b_err, 1 );
        (*ENDIF*) 
        END
    ELSE
        a07_b_put_error( acv, _b_err, 1 );
    (*ENDIF*) 
    END
ELSE
    a07_b_put_error( acv, e_no_more_memory, 1 );
(*ENDIF*) 
IF  ( _aux_joins.jrc_joinarr <> NIL )
THEN
    BEGIN
    _cast.ptr := _aux_joins.jrc_joinarr;
    gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
    END;
(*ENDIF*) 
IF  ( _copied <> NIL )
THEN
    gg12FinalizeBitArray( acv.a_transinf.tri_trans, _copied );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      ak16specified (
            VAR col_info : tak16_colinfo;
            col_cnt      : integer;
            tab_no       : integer;
            col_no       : integer;
            VAR extcolno : integer) : boolean;
 
VAR
      _i : integer;
 
BEGIN
ak16specified := false;
_i := 1;
WHILE _i <= col_cnt DO
    BEGIN
    IF  col_info[ _i ].tabno = tab_no
    THEN
        BEGIN
        IF  col_info[ _i ].colno = col_no
        THEN
            BEGIN
            IF  col_info[ _i ].extno > 0
            THEN
                BEGIN
                ak16specified := true;
                extcolno      := col_info[ _i ].extno;
&               ifdef trace
                t01str30 (ak_sem, '========= is specified =======');
                t01p4int4 (ak_sem, 'tab col ext ',
                      tab_no, col_no, extcolno, 0);
&               endif
                END;
            (*ENDIF*) 
            _i := succ( col_cnt );
            END
        ELSE
            IF  col_info[ _i ].colno > col_no
            THEN
                _i := succ( col_cnt )
            ELSE
                _i := succ( _i );
            (*ENDIF*) 
        (*ENDIF*) 
        END
    ELSE
        IF  col_info[ _i ].tabno > tab_no
        THEN
            _i := succ( col_cnt )
        ELSE
            _i := succ( _i );
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16st_in_check_option_part (
            VAR acv             : tak_all_command_glob;
            VAR a16v            : tak16_viewglob;
            join_index          : integer;
            catalog_joinptr     : tak_sysbufferaddress;
            VAR in_check_option : boolean);
 
VAR
      _catalog_ptr : tak_sysbufferaddress;
      _catalog_key : tgg00_SysInfoKey;
      _j           : integer;
      _i           : integer;
      _b_err       : tgg00_BasisError;
 
BEGIN
WITH catalog_joinptr^.sviewqual_join.vjoin[ join_index ] DO
    BEGIN
    _b_err := e_ok;
    (* check, whether equal join qual. lies in check option part *)
    IF  a16v.a6vqual_stack^.sviewqual_stack.vview_offs > 0
    THEN
        BEGIN
        IF  j1startstack < a16v.a6vqual_stack^.sviewqual_stack.vview_offs + 1
        THEN
            in_check_option := false
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    _catalog_ptr := a16v.a6vqual_stack;
    _catalog_key := _catalog_ptr^.syskey;
    (* get rigth catalog record *)
    _j := j1startstack;
    WHILE _j > cak_max_viewqual_stack DO
        BEGIN
        a06inc_linkage( _catalog_key.slinkage );
        _j := _j - cak_max_viewqual_stack;
        END;
    (*ENDWHILE*) 
    _j := j1startstack;
    a10get_sysinfo( acv, _catalog_key, d_release, _catalog_ptr, _b_err );
    WHILE ( _j >= a16v.a6vqual_stack^.sviewqual_stack.vview_offs + 1 )
          AND in_check_option AND ( _b_err = e_ok ) DO
        BEGIN
        IF  _j MOD cak_max_viewqual_stack = 0
        THEN
            _i := cak_max_viewqual_stack
        ELSE
            _i := _j MOD cak_max_viewqual_stack;
        (*ENDIF*) 
        IF  _catalog_ptr^.sviewqual_stack.vstack[ _i ].etype = st_jump_false
        THEN
            IF  _catalog_ptr^.sviewqual_stack.vstack[ _i ].eop = op_jmp_ins_upd
            THEN
                BEGIN
                IF  _catalog_ptr^.sviewqual_stack.vstack[ _i ].elen_var +
                    _j - 1 > j1startstack
                THEN
                    in_check_option := false;
                (* exit while *)
                (*ENDIF*) 
                _j := a16v.a6vqual_stack^.sviewqual_stack.vview_offs + 1;
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        _j := pred( _j );
        IF  ( _j MOD cak_max_viewqual_stack = 0 ) AND
            ( _j >= a16v.a6vqual_stack^.sviewqual_stack.vview_offs + 1 )
        THEN
            (* record underflow handling *)
            BEGIN
            a06pred_linkage( _catalog_key.slinkage );
            a10get_sysinfo( acv, _catalog_key, d_release, _catalog_ptr, _b_err );
            END;
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
IF  _b_err <> e_ok
THEN
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16store_tab_sequence (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
VAR
      _catalog_ptr : tak_sysbufferaddress;
      _catalog_key : tgg00_SysInfoKey;
      _arr_idx     : integer;
      _i           : integer;
      _j           : integer;
      _k           : integer;
      _aux_atarr   : tak_all_from_tables_ptr;
      _base_tables : tak16_viewtabdef_arr_ptr;
      _b_err       : tgg00_BasisError;
      _sequence_map: ARRAY[ 1..cak00_maxsources ] OF tsp00_Int2;
 
      _cast         : RECORD
            CASE integer OF
                1 :
                    (addr: tsp00_Addr);
                2 :
                    (tptr : tak_all_from_tables_ptr);
                3 :
                    (vptr : tak16_viewtabdef_arr_ptr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
IF  ( acv.a_returncode = 0 )
THEN
    BEGIN
    _aux_atarr   := NIL;
    _base_tables := NIL;
    _cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
          a16dmli.d_cntfromtab * sizeof(tak_one_table) );
    _aux_atarr := _cast.tptr;
    _cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
          a16dmli.d_cntfromtab * sizeof(tak_viewtabdef) );
    _base_tables := _cast.vptr;
    IF  (( _aux_atarr <> NIL ) AND ( _base_tables <> NIL ))
    THEN
        BEGIN
        (* sequence contains sequence in which the tables have to be     *)
        (* executed in case of an insert or update order. Assign new     *)
        (* table numbers in column infos and qualification stack entries *)
        a16v.a6keylen := a16v.a6keylenarr[ a16v.a6sequence[ 1 ] ];
        _b_err := e_ok;
&       ifdef trace
        t01int4 (ak_sem, 'a6keylen    ', a16v.a6keylen);
&       endif
        FOR _i := 1 TO a16dmli.d_cntfromtab DO
            BEGIN
            (* resort table names to new insert/update order *)
            _sequence_map[ a16v.a6sequence[ _i ] ] := _i;
            ;
            (* resort vtable to new insert/update order into _base_tables *)
            _base_tables^[ _i ] := a16v.a6vqual_basis^.
                  sviewqual_basis.vtable[ a16v.a6sequence[ _i ] ];
            (* resort d_tabarr to new insert/update order into _aux_atarr *)
            _aux_atarr^[ _i ] := a16dmli.d_tabarr^[ a16v.a6sequence[ _i ] ];
            END;
        (*ENDFOR*) 
        SAPDB_PascalMove ('VAK16 ',   6,    
              a16dmli.d_cntfromtab * sizeof(tak_viewtabdef),
              a16v.a6vqual_basis^.sviewqual_basis.vbasetabcnt * sizeof(tak_viewtabdef),
              @_base_tables^, 1,
              @a16v.a6vqual_basis^.sviewqual_basis.vtable, 1,
              a16dmli.d_cntfromtab * sizeof(tak_viewtabdef),
              _b_err);
        SAPDB_PascalMove ('VAK16 ',   7,    
              a16dmli.d_cntfromtab * sizeof(tak_one_table),
              a16dmli.d_tabarr_capacity * sizeof(tak_one_table),
              @_aux_atarr^, 1,
              @a16dmli.d_tabarr^, 1,
              a16dmli.d_cntfromtab * sizeof(tak_one_table),
              _b_err);
        ;
        (* rename tables to new insert/update order (use _sequence_map) *)
        (* update base record *)
        WITH a16dmli.d_esparr.pbasep^.sbase DO
            FOR _k := bfirstindex TO blastindex DO
                WITH bcolumn[ _k ]^ DO
                    BEGIN
                    ctabno := _sequence_map[ ctabno ];
                    END;
                (*ENDWITH*) 
            (*ENDFOR*) 
        (*ENDWITH*) 
        ;
        (* update tak_viewqual_derivedcol_record *)
        IF  a16v.a6vqual_basis^.sviewqual_basis.vderived_exists
        THEN
            BEGIN
            _catalog_key            := a16v.a6viewkey;
            _catalog_key.slinkage   := cak_init_linkage;
            _catalog_key.sentrytyp  := cak_eviewqual_derivedcol;
            a10get_sysinfo( acv, _catalog_key, d_release, _catalog_ptr, _b_err );
            _arr_idx := 1;
            _j       := 1;
            WHILE ( _j <= _catalog_ptr^.sviewqual_derivedcol.vderivedcnt ) AND
                  ( _b_err = e_ok ) DO
                BEGIN
                IF  ( _arr_idx > cak_max_viewqual_derivedcol )
                THEN
                    (* record overflow handling *)
                    BEGIN
                    a10repl_sysinfo( acv, _catalog_ptr, _b_err );
                    IF  ( _b_err = e_ok )
                    THEN
                        BEGIN
                        a06inc_linkage( _catalog_key.slinkage );
                        a10get_sysinfo( acv, _catalog_key, d_release,
                              _catalog_ptr, _b_err );
                        END;
                    (*ENDIF*) 
                    _arr_idx := 1;
                    END;
                (*ENDIF*) 
                IF  ( _b_err = e_ok )
                THEN
                    BEGIN
                    _catalog_ptr^.sviewqual_derivedcol.
                          vderived_cols[ _arr_idx ].dtabno :=
                          _sequence_map[ _catalog_ptr^.sviewqual_derivedcol.
                          vderived_cols[ _arr_idx ].dtabno ];
                    _catalog_ptr^.sviewqual_derivedcol.
                          vderived_cols[ _arr_idx ].dexttabno :=
                          _sequence_map[ _catalog_ptr^.sviewqual_derivedcol.
                          vderived_cols[ _arr_idx ].dexttabno ];
                    _j       := succ( _j );
                    _arr_idx := succ( _arr_idx );
                    END;
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            a10repl_sysinfo( acv, _catalog_ptr, _b_err );
            IF  ( _b_err <> e_ok )
            THEN
                a07_b_put_error( acv, _b_err, 1 );
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        ;
        (* update d_joins.jrc_joinarr *)
        FOR _j := 1 TO a16dmli.d_joins.jrc_cnt DO
            FOR _k := 1 TO 2 DO
                WITH a16dmli.d_joins.jrc_joinarr^[ _j - 1 ].jo_recs[ _k ] DO
                    BEGIN
                    IF  ( jop_tableno <> cak68_join_value )
                    THEN
                        jop_tableno := _sequence_map[ jop_tableno ];
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDFOR*) 
        (*ENDFOR*) 
        ;
        (* update jrc_joinarr on tak_viewqual_join_record *)
        IF  a16v.a6vqual_basis^.sviewqual_basis.vjoin_exists
        THEN
            BEGIN
            _catalog_ptr := a16v.a6vqual_join;
            _catalog_key := _catalog_ptr^.syskey;
            _arr_idx := 1;
            _j       := 1;
            WHILE ( _j <= _catalog_ptr^.sviewqual_join.vjoincount ) AND
                  ( _b_err = e_ok ) DO
                BEGIN
                IF  ( _arr_idx > cak_max_viewqual_join )
                THEN
                    (* record overflow handling *)
                    BEGIN
                    a10repl_sysinfo( acv, _catalog_ptr, _b_err );
                    IF  ( _b_err = e_ok )
                    THEN
                        BEGIN
                        a06inc_linkage( _catalog_key.slinkage );
                        a10get_sysinfo( acv, _catalog_key, d_release,
                              _catalog_ptr, _b_err );
                        END;
                    (*ENDIF*) 
                    _arr_idx := 1;
                    END;
                (*ENDIF*) 
                IF  ( _b_err = e_ok )
                THEN
                    BEGIN
                    IF  ( _catalog_ptr^.sviewqual_join.vjoin[ _arr_idx ].
                        j1tableno <> cak68_join_value )
                    THEN
                        _catalog_ptr^.sviewqual_join.vjoin[ _arr_idx ].j1tableno :=
                              _sequence_map[ _catalog_ptr^.sviewqual_join.
                              vjoin[ _arr_idx ].j1tableno ];
                    (*ENDIF*) 
                    IF  ( _catalog_ptr^.sviewqual_join.vjoin[ _arr_idx ].
                        j2tableno <> cak68_join_value )
                    THEN
                        _catalog_ptr^.sviewqual_join.vjoin[ _arr_idx ].j2tableno :=
                              _sequence_map[ _catalog_ptr^.sviewqual_join.
                              vjoin[ _arr_idx ].j2tableno ];
                    (*ENDIF*) 
                    _j       := succ( _j );
                    _arr_idx := succ( _arr_idx );
                    END;
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            a10repl_sysinfo( acv, _catalog_ptr, _b_err );
            IF  ( _b_err <> e_ok )
            THEN
                a07_b_put_error( acv, _b_err, 1 );
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        ;
        (* update tak_viewqual_stack_record *)
        IF  a16v.a6vqual_basis^.sviewqual_basis.vstack_exists
        THEN
            BEGIN
&           ifdef trace
            t01int4 (ak_sem, 'a6sequen[_i]', a16v.a6sequence[ _i ]);
&           endif
            _catalog_ptr := a16v.a6vqual_stack;
            _catalog_key := _catalog_ptr^.syskey;
            _arr_idx := 1;
            _j       := 1;
            WHILE ( _j <= _catalog_ptr^.sviewqual_stack.vstcount ) AND
                  ( _b_err = e_ok ) DO
                BEGIN
                IF  ( _arr_idx > cak_max_viewqual_stack )
                THEN
                    (* record overflow handling *)
                    BEGIN
                    a10repl_sysinfo( acv, _catalog_ptr, _b_err );
                    IF  ( _b_err = e_ok )
                    THEN
                        BEGIN
                        a06inc_linkage( _catalog_key.slinkage );
                        a10get_sysinfo( acv, _catalog_key, d_release,
                              _catalog_ptr, _b_err );
                        END;
                    (*ENDIF*) 
                    _arr_idx := 1;
                    END;
                (*ENDIF*) 
                ;
&               ifdef trace
                t01int4( ak_sem, '_arr_idx    ', _arr_idx );
                t01stackentry(ak_sem,
                      _catalog_ptr^.sviewqual_stack.vstack[_arr_idx], _arr_idx );
&               endif
                IF  ( _b_err = e_ok ) AND (
                    ( _catalog_ptr^.sviewqual_stack.vstack[ _arr_idx ].
                    etype = st_column ) OR
                    ( _catalog_ptr^.sviewqual_stack.vstack[ _arr_idx ].
                    etype = st_fixkey ) OR
                    ( _catalog_ptr^.sviewqual_stack.vstack[ _arr_idx ].
                    etype = st_varkey ) OR
                    ( _catalog_ptr^.sviewqual_stack.vstack[ _arr_idx ].
                    etype = st_fixcol ) OR
                    ( _catalog_ptr^.sviewqual_stack.vstack[ _arr_idx ].
                    etype = st_varcol )OR
                    ( _catalog_ptr^.sviewqual_stack.vstack[ _arr_idx ].
                    etype = st_varlongchar ))
                THEN
                    BEGIN
                    _catalog_ptr^.sviewqual_stack.
                          vstack[ _arr_idx ].ecol_tab[ 2 ] :=
                          chr( _sequence_map[ ord( _catalog_ptr^.sviewqual_stack.
                          vstack[ _arr_idx ].ecol_tab[ 2 ] ) ] );
&                   ifdef trace
                    t01sname( ak_sem, 'changed to  ' );
                    t01stackentry(ak_sem,
                          _catalog_ptr^.sviewqual_stack.vstack[_arr_idx], _arr_idx );
&                   endif
                    END;
                (*ENDIF*) 
                _j       := succ( _j );
                _arr_idx := succ( _arr_idx );
                END;
            (*ENDWHILE*) 
            a10repl_sysinfo( acv, _catalog_ptr, _b_err );
            IF  ( _b_err <> e_ok )
            THEN
                a07_b_put_error( acv, _b_err, 1 );
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        ;
        (* update messblock *)
        FOR _j := acv.a_mblock.mb_qual^.mcol_pos TO
              acv.a_mblock.mb_qual^.mqual_pos + acv.a_mblock.mb_qual^.mqual_cnt - 1 DO
            IF  ( acv.a_mblock.mb_st^[ _j ].etype = st_column ) OR
                ( acv.a_mblock.mb_st^[ _j ].etype = st_fixkey ) OR
                ( acv.a_mblock.mb_st^[ _j ].etype = st_varkey ) OR
                ( acv.a_mblock.mb_st^[ _j ].etype = st_fixcol ) OR
                ( acv.a_mblock.mb_st^[ _j ].etype = st_varcol ) OR
                ( acv.a_mblock.mb_st^[ _j ].etype = st_varlongchar )
            THEN
                BEGIN
                acv.a_mblock.mb_st^[ _j ].ecol_tab[ 2 ] :=
                      chr( _sequence_map[ ord( acv.a_mblock.
                      mb_st^[ _j ].ecol_tab[ 2 ] ) ] )
                END;
            (*ENDIF*) 
        (*ENDFOR*) 
        ;
&       ifdef trace
        t01qual( ak_sem, acv.a_mblock.mb_qual^ );
&       endif
        IF  ( _b_err <> e_ok )
        THEN
            a07_b_put_error( acv, _b_err, 1 );
        (*ENDIF*) 
        END
    ELSE
        a07_b_put_error( acv, e_no_more_memory, 1 );
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  ( _aux_atarr <> NIL )
THEN
    BEGIN
    _cast.tptr := _aux_atarr;
    gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
    END;
(*ENDIF*) 
IF  ( _base_tables <> NIL )
THEN
    BEGIN
    _cast.vptr := _base_tables;
    gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16tab_sequence (
            VAR a16v            : tak16_viewglob;
            VAR a16dmli         : tak_dml_info;
            VAR link_info       : tak16_linkinfo;
            VAR updateable_view : boolean);
 
VAR
      _i           : integer;
      _j           : integer;
      _tab_no      : integer;
      _queue_left  : integer;
      _queue_right : integer;
      _st_ptr      : integer;
      _sequence_cnt: integer;
 
BEGIN
_queue_left  := 0;
_queue_right := 0;
FOR _i := 1 TO a16dmli.d_cntfromtab DO
    IF  link_info.ltab_seq.seq_queue^[ _i ].pred_cnt = 0
    THEN
        BEGIN
        link_info.ltab_seq.seq_queue^[ _queue_right ].next := _i;
        _queue_right                   := _i
        END;
    (*ENDIF*) 
(*ENDFOR*) 
;
&ifdef trace
FOR _i := 0 TO a16dmli.d_cntfromtab DO
    WITH link_info.ltab_seq.seq_queue^[ _i ] DO
        BEGIN
        t01int4 (ak_sem, 'tab_no =    ', tabno);
        t01int4 (ak_sem, 'next   =    ', next);
        t01int4 (ak_sem, 'top    =    ', top);
        t01int4 (ak_sem, 'pred_cnt =  ', pred_cnt);
        _j := top;
        WHILE _j <> 0 DO
            BEGIN
            t01int4 (ak_sem, 'stacktabno  ', link_info.ltab_seq.seq_stack[ _j ].tabno);
            t01int4 (ak_sem, 'succ =      ', link_info.ltab_seq.seq_stack[ _j ].suc);
            _j := link_info.ltab_seq.seq_stack[ _j ].suc;
            END;
        (*ENDWHILE*) 
        END;
    (*ENDWITH*) 
(*ENDFOR*) 
&endif
(* topological sort, there are any "pred_cnt = 0" *)
_sequence_cnt := 0;
WHILE _queue_left <> _queue_right DO
    BEGIN
    _sequence_cnt := succ( _sequence_cnt );
    _queue_left   := link_info.ltab_seq.seq_queue^[ _queue_left ].next;
    a16v.a6sequence[ _sequence_cnt ] :=
          link_info.ltab_seq.seq_queue^[ _queue_left ].tabno;
&   ifdef trace
    t01int4 (ak_sem, 'sequence =  ', a16v.a6sequence[ _sequence_cnt ]);
&   endif
    _st_ptr       := link_info.ltab_seq.seq_queue^[ _queue_left ].top;
    WHILE _st_ptr <> 0 DO
        BEGIN
        _tab_no := link_info.ltab_seq.seq_stack[ _st_ptr ].tabno;
        link_info.ltab_seq.seq_queue^[ _tab_no ].pred_cnt :=
              pred( link_info.ltab_seq.seq_queue^[ _tab_no ].pred_cnt );
        IF  link_info.ltab_seq.seq_queue^[ _tab_no ].pred_cnt = 0
        THEN
            BEGIN
            link_info.ltab_seq.seq_queue^[ _queue_right ].next := _tab_no;
            _queue_right := link_info.ltab_seq.seq_queue^[ _tab_no ].tabno
            END;
        (*ENDIF*) 
        _st_ptr := link_info.ltab_seq.seq_stack[ _st_ptr ].suc;
        END;
    (*ENDWHILE*) 
    END;
(*ENDWHILE*) 
IF  _sequence_cnt <> a16dmli.d_cntfromtab
THEN
    updateable_view := false;
&ifdef trace
(*ENDIF*) 
t01str30 (ak_sem, '==== sequence of tables ======');
FOR _i := 1 TO a16dmli.d_cntfromtab DO
    WITH a16dmli.d_tabarr^[ a16v.a6sequence[ _i ] ] DO
        BEGIN
        t01lidentifier (ak_sem, ouser);
        t01lidentifier (ak_sem, otable);
        END;
    (*ENDWITH*) 
(*ENDFOR*) 
t01str30 (ak_sem, '==============================');
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16viewtext_definition  (
            VAR acv     : tak_all_command_glob;
            VAR a16v    : tak16_viewglob;
            VAR a16dmli : tak_dml_info);
 
CONST
      c_del_old_rec = true;
      c_new_rec     = true;
      c_no_new_rec  = false;
 
VAR
      _pos          : integer;
      _i            : integer;
      _j            : integer;
      _k            : integer;
      _buf_pos      : integer;
      _catalog_ptr  : tak_sysbufferaddress;
      _viewtextbuf  : tak_sysbufferaddress;
      _tabid        : tgg00_Surrogate;
      _permkey      : tgg00_SysInfoKey;
      _b_err        : tgg00_BasisError;
      _init_ex_kind : tak_execution_kind;
      _sortCount    : integer;
      _sortIndex    : ARRAY[1..1024] OF integer;
      _next_exist   : boolean;
      _found        : boolean;
 
BEGIN
a16v.a6viewkey.sentrytyp := cak_etempviewtext;
a16v.a6viewkey.slinkage  := cak_init_linkage;
(* entries was created in ak16get_viewtext_buf() *)
a10get_sysinfo( acv, a16v.a6viewkey, d_release, _catalog_ptr, _b_err );
IF  _b_err = e_ok
THEN
    BEGIN
    (* check, if catalog information of view becomes        *)
    (* replicated <=> the catalog information of one of the *)
    (* underlying tables is replicated                      *)
    a16v.a6segmentid  := cak00_local_segment_id;
    _i := 1;
    (* vttabcount written in a660_from_part()               *)
    WHILE ( _i <= _catalog_ptr^.sviewtext.vttabcount ) DO
        WITH _catalog_ptr^.sviewtext.vttab[ _i ] DO
            BEGIN
            IF  a01equal_char( acv.a_cmd_part^.sp1p_buf,
                vtttab_n_pos - a01char_size, '"' )
            THEN
                vtttab_n_pos := vtttab_n_pos - a01char_size;
            (*ENDIF*) 
            ;
&           ifdef trace
            t01int4 (ak_sem, 'vtttab_n_pos', vtttab_n_pos);
&           endif
            _i := _i + 1;
            END;
        (*ENDWITH*) 
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
a16v.a6viewkey.sentrytyp := cak_etempviewdesc;
a16v.a6viewkey.slinkage  := cak_init_linkage;
_permkey             := a16v.a6viewkey;
_permkey.sentrytyp   := cak_eviewdesc;
(* rename temp viewdesc catalog record to perm viewdesc *)
a10_copy_catalog_rec( acv, a16v.a6viewkey,
      c_del_old_rec, _permkey, a16v.a6segmentid, c_no_new_rec, _b_err );
IF  _b_err = e_ok
THEN
    a10get_sysinfo( acv, _permkey, d_fix, _catalog_ptr, _b_err );
(*ENDIF*) 
IF  _b_err = e_ok
THEN
    BEGIN
    (* rename temp viewtext catalog record to perm viewtext *)
    (* catalog record and alloc it at address a6viewtextbuf *)
    a16v.a6viewkey.sentrytyp := cak_etempviewtext;
    _permkey.sentrytyp   := cak_eviewtext;
    a10_copy_catalog_rec( acv, a16v.a6viewkey,
          c_del_old_rec, _permkey, a16v.a6segmentid, c_no_new_rec, _b_err );
    END;
(*ENDIF*) 
IF  _b_err = e_ok
THEN
    BEGIN
    a10get_sysinfo( acv, _permkey, d_fix, a16v.a6viewbuf, _b_err );
    a16v.a6viewtextbuf := a16v.a6viewbuf
    END;
(*ENDIF*) 
IF  ( acv.a_init_ddl = ddl_create_view ) AND ( _b_err = e_ok )
THEN
    BEGIN
    a27ModifyAppendSchemas (acv, a16v.a6viewtextbuf, _catalog_ptr );
    IF  acv.a_returncode = 0
    THEN
        a27substitute_synonyms( acv, a16v.a6viewtextbuf, _catalog_ptr );
    (* Remove unnecessary blanks of view definition string    *)
    (* by parsing cmh_var_part again in state acv_compact_varpart *)
    (*ENDIF*) 
    _init_ex_kind := acv.a_ex_kind;
    acv.a_ex_kind := only_executing;
    a10_rel_sysinfo( acv, _catalog_ptr^.syskey );
    END;
(*ENDIF*) 
IF  _b_err = e_ok
THEN
    BEGIN
    _catalog_ptr^.b_sl := cak_viewdesc_offset + _catalog_ptr^.sviewdesc.vdesc_cnt *
          sizeof( _catalog_ptr^.sviewdesc.vdescription[ 1 ] );
    a10_add_repl_sysinfo( acv, _catalog_ptr, a16v.a6add_rec, _b_err );
    END;
(*ENDIF*) 
IF  _b_err = e_ok
THEN
    BEGIN
    IF  _catalog_ptr^.sviewdesc.vdesc_next
    THEN
        BEGIN
        a16v.a6viewkey.sentrytyp := cak_etempviewdesc;
        REPEAT
            (* Copy temp Viewdesc Record into permanent Catalog *)
            a06inc_linkage( a16v.a6viewkey.slinkage );
            a10get_sysinfo( acv, a16v.a6viewkey, d_release, _catalog_ptr, _b_err );
            IF  _b_err = e_ok
            THEN
                BEGIN
                _next_exist := _catalog_ptr^.sviewdesc.vdesc_next;
                _catalog_ptr^.b_sl := cak_viewdesc_offset +
                      _catalog_ptr^.sviewdesc.vdesc_cnt *
                      sizeof( _catalog_ptr^.sviewdesc.vdescription[ 1 ] );
                _permkey           := a16v.a6viewkey;
                _permkey.sentrytyp := cak_eviewdesc;
                a10_copy_catalog_rec( acv, a16v.a6viewkey,
                      c_del_old_rec, _permkey, a16v.a6segmentid,
                      c_new_rec, _b_err );
                END;
            (*ENDIF*) 
        UNTIL
            NOT _next_exist OR ( _b_err <> e_ok );
        (*ENDREPEAT*) 
        END;
    (*ENDIF*) 
    a16v.a6viewkey := a16v.a6viewtextbuf^.syskey
    END;
(*ENDIF*) 
_pos         := 1;
_viewtextbuf := a16v.a6viewbuf;
WHILE ( _pos < acv.a_cmd_part^.sp1p_buf_len ) AND ( _b_err = e_ok ) DO
    BEGIN
    IF  a16v.a6viewkey.slinkage > cak_init_linkage
    THEN
        a10_nil_get_sysinfo( acv, a16v.a6viewkey, d_release,
              mxak_viewtextrec, _viewtextbuf, _b_err );
    (*ENDIF*) 
    IF  _b_err = e_ok
    THEN
        BEGIN
        IF  a16v.a6viewkey.slinkage > cak_init_linkage
        THEN
            _viewtextbuf^.sviewtext.vttabcount := 0;
        (*ENDIF*) 
        _buf_pos := _viewtextbuf^.sviewtext.vttabcount * mxak_vttabdef + 1;
        _viewtextbuf^.sviewtext.vtselect_pos := _buf_pos +
              a16v.a6select_pos - 1;
&       ifdef trace
        t01p2int4 (ak_sem, 'buf_pos     ', _buf_pos,
              'select_pos  ', _viewtextbuf^.sviewtext.vtselect_pos);
&       endif
        REPEAT
            _viewtextbuf^.sviewtext.vttbuf[ _buf_pos ] :=
                  acv.a_cmd_part^.sp1p_buf[ _pos ];
            _buf_pos := succ( _buf_pos );
            _pos     := succ( _pos );
        UNTIL
            ( _buf_pos > mxak_viewtext ) OR
            ( _pos > acv.a_cmd_part^.sp1p_buf_len );
        (*ENDREPEAT*) 
        _viewtextbuf^.sviewtext.vttextlength := _buf_pos -
              _viewtextbuf^.sviewtext.vttabcount * mxak_vttabdef - 1;
        _viewtextbuf^.sviewtext.vtnextexist  :=
              ( _pos < acv.a_cmd_part^.sp1p_buf_len );
        CASE acv.a_sqlmode OF
            sqlm_ansi   :
                _viewtextbuf^.sviewtext.vtcontext := 10;
            sqlm_db2    :
                _viewtextbuf^.sviewtext.vtcontext := 20;
            sqlm_oracle :
                _viewtextbuf^.sviewtext.vtcontext := 30;
            sqlm_internal :
                _viewtextbuf^.sviewtext.vtcontext :=  0;
            END;
        (*ENDCASE*) 
        _viewtextbuf^.sviewtext.vtcontext := _viewtextbuf^.sviewtext.vtcontext +
              ord( acv.a_dt_format );
        _viewtextbuf^.b_sl := _buf_pos - 1 +
              mxak_viewtext_offset + cak_sysbufferoffset;
        IF  ( acv.a_internal_sql <> sql_alter_table ) OR
            ( acv.a_init_ddl = ddl_alter_key )
        THEN
            a10_add_repl_sysinfo( acv, _viewtextbuf,
                  ( acv.a_init_ddl <> ddl_alter_key ) AND
                  NOT a16v.a6replace, _b_err);
        (*ENDIF*) 
        a06inc_linkage( a16v.a6viewkey.slinkage );
        END;
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
IF  _b_err = e_ok
THEN
    BEGIN
    IF  (acv.a_internal_sql <> sql_alter_table) AND (NOT a16v.a6noUsageRef)
    THEN
        BEGIN
        _sortCount := 0;
        (* for option 'NO REFERENCES', sort tableid of *)
        (* referenced tables to avoid deadlocks        *)
        FOR _i := 1 TO a16v.a6viewbuf^.sviewtext.vttabcount DO
            BEGIN
            _found := false;
            _j     := 1;
            WHILE NOT _found AND (_j <= _sortCount) DO
                BEGIN
                IF  a16v.a6viewbuf^.sviewtext.vttab[ _i ].vtttableid >
                    a16v.a6viewbuf^.sviewtext.vttab[_sortIndex[_j]].vtttableid
                THEN
                    _j := _j + 1
                ELSE
                    _found := true;
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            IF  _found
            THEN (* check, if tableid has already been found *)
                _found :=
                      a16v.a6viewbuf^.sviewtext.vttab[ _i ].vtttableid =
                      a16v.a6viewbuf^.sviewtext.vttab[_sortIndex[_j]].vtttableid;
            (*ENDIF*) 
            IF  NOT _found
            THEN
                BEGIN
                FOR _k := _sortCount DOWNTO _j DO
                    _sortIndex[_k+1] := _sortIndex[_k];
                (*ENDFOR*) 
                _sortIndex[_j] := _i;
                _sortCount     := _sortCount + 1;
                END;
            (*ENDIF*) 
            END;
        (*ENDFOR*) 
        (* tableid's are sorted and unique now, update references *)
        FOR _i := 1 TO _sortCount DO
            BEGIN
            _tabid := a16dmli.d_tableid;
            a16put_usage_def( acv, a16v.a6viewbuf^.sviewtext.
                  vttab[ _sortIndex[_i ]].vtttableid, _tabid, a16v.a6tablekind );
            END;
        (*ENDFOR*) 
        END;
    (*ENDIF*) 
    END
ELSE
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a16new_bextcolindex (VAR base_rec : tak_baserecord);
 
VAR
      _j      : integer;
      _count  : integer;
 
BEGIN
_count := 0;
FOR _j := base_rec.bfirstindex TO base_rec.blastindex DO
    BEGIN
    base_rec.bextcolindex[ base_rec.bcolumn[ _j ]^.cextcolno ] := _count;
    _count := _count + 1;
    END;
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a16privrec_build (
            VAR acv      : tak_all_command_glob;
            view_ptr     : tak_sysbufferaddress;
            VAR base_ptr : tak_sysbufferaddress;
            viewtextbuf  : tak_sysbufferaddress;
            vqual_basis  : tak_sysbufferaddress;
            VAR viewpriv : tak_privilege;
            release      : boolean);
 
VAR
      _ok            : boolean;
      _i             : integer;
      _j             : integer;
      _owner_id      : tgg00_Surrogate;
      _from_tab_priv : tak_privilege;
 
BEGIN
WITH viewtextbuf^.sviewtext DO
    BEGIN
    viewpriv.priv_col_exist     := [  ];
    viewpriv.priv_upd_set       := [  ];
    viewpriv.priv_sel_set       := [  ];
    viewpriv.priv_grant_upd_set := [  ];
    viewpriv.priv_grant_sel_set := [  ];
    WITH view_ptr^.sbase DO
        FOR _j := bfirstindex TO blastindex DO
            WITH bcolumn[ _j ]^ DO
                BEGIN
                ccolpropset := ccolpropset - [ctcomment, ctaltered];
                IF  NOT ( ctdropped in ccolpropset   ) AND
                    NOT ( ctinvisible in ccolpropset )
                THEN
                    viewpriv.priv_grant_sel_set :=
                          viewpriv.priv_grant_sel_set +
                          [ cextcolno ];
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDFOR*) 
    (*ENDWITH*) 
    _i := 1;
    WHILE ( _i <= vttabcount ) DO
        BEGIN
        WITH vttab[ _i ] DO
            a06_systable_get( acv, d_fix, vtttableid, base_ptr, true, _ok );
        (*ENDWITH*) 
        IF  _ok
        THEN
            BEGIN
            IF  base_ptr^.sbase.bv_tablekind = tcatalog_table
            THEN
                BEGIN
                view_ptr^.sbase.bv_tablekind := tcatalog_table;
                IF  vtfromtabcnt = 1
                THEN
                    view_ptr^.sbase.bshowkind := base_ptr^.sbase.bshowkind;
                (*ENDIF*) 
                END
            ELSE
                IF  ( base_ptr^.sbase.btablekind in [ tdb2view ] )
                    AND
                    ( acv.a_is_ddl = ddl_create_view )
                THEN
                    a07_b_put_error( acv, e_not_implemented, 1 );
                (*ENDIF*) 
            (*ENDIF*) 
            _owner_id := view_ptr^.sbase.bauthid;
            a06user_get_priv( acv, base_ptr, _owner_id, _from_tab_priv );
            END
        ELSE
            BEGIN
            _i := succ( vttabcount );
            a07ak_system_error( acv, 16, 2 );
            END;
        (*ENDIF*) 
        viewpriv.priv_all_set := viewpriv.priv_all_set *
              _from_tab_priv.priv_all_set + [ r_sel ];
        viewpriv.priv_all_grant_set := viewpriv.priv_all_grant_set *
              _from_tab_priv.priv_all_grant_set;
&       ifdef TRACE
        a06td_priv (_from_tab_priv, 'fromtabpriv       ', true);
        a06td_priv (viewpriv, 'curr_viewpriv     ', true);
&       endif
        IF  acv.a_returncode = 0
        THEN
            ak16select_grant_option( acv, view_ptr, _i,
                  _from_tab_priv, viewpriv );
        (*ENDIF*) 
        IF  acv.a_returncode = 0
        THEN
            IF  NOT ( view_ptr^.sbase.btablekind in [ tcomplexview ] )
            THEN
                ak16colpriv_check( acv, viewtextbuf, vqual_basis,
                      view_ptr^.sbase, _from_tab_priv, viewpriv,
                      _i, base_ptr^.sbase );
            (*ENDIF*) 
        (*ENDIF*) 
        IF  release AND ( acv.a_returncode = 0 )
        THEN
            a10_rel_sysinfo( acv, base_ptr^.syskey );
        (*ENDIF*) 
        _i := succ( _i );
        END;
    (*ENDWHILE*) 
    IF  acv.a_returncode = 0
    THEN
        WITH viewpriv DO
            BEGIN
            IF  priv_upd_set + priv_grant_sel_set <> [  ]
            THEN
                BEGIN
                IF  priv_upd_set <> [  ]
                THEN
                    BEGIN
                    priv_all_set       := priv_all_set       + [ r_upd ];
                    priv_all_grant_set := priv_all_grant_set + [ r_upd ];
                    END;
                (*ENDIF*) 
                IF  priv_grant_sel_set  <> [  ]
                THEN
                    priv_all_grant_set := priv_all_grant_set + [ r_sel ];
                (*ENDIF*) 
                _j := view_ptr^.sbase.bfirstindex;
                WHILE  _j <= view_ptr^.sbase.blastindex DO
                    WITH view_ptr^.sbase.bcolumn[ _j ]^ DO
                        BEGIN
                        IF  NOT ( ctinvisible in ccolpropset ) AND
                            NOT ( ctdropped in ccolpropset )
                        THEN
                            BEGIN
                            IF  NOT ( cextcolno in priv_grant_sel_set )
                            THEN
                                priv_all_grant_set :=
                                      priv_all_grant_set - [ r_sel ];
                            (*ENDIF*) 
                            IF  priv_upd_set <> [  ]
                            THEN
                                BEGIN
                                IF  NOT ( cextcolno in priv_upd_set )
                                THEN
                                    priv_all_set :=
                                          priv_all_set - [ r_upd ];
                                (*ENDIF*) 
                                IF  NOT ( cextcolno in
                                    priv_grant_upd_set )
                                THEN
                                    priv_all_grant_set :=
                                          priv_all_grant_set - [ r_upd ];
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        _j := succ( _j );
                        END;
                    (*ENDWITH*) 
                (*ENDWHILE*) 
                IF  r_upd in priv_all_set
                THEN
                    BEGIN
                    priv_col_exist := priv_col_exist - [ priv_col_upd ];
                    priv_upd_set   := [  ];
                    END
                ELSE
                    IF  priv_upd_set <> [  ]
                    THEN
                        priv_col_exist := priv_col_exist + [ priv_col_upd ];
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  r_upd in priv_all_grant_set
                THEN
                    BEGIN
                    priv_col_exist := priv_col_exist-[ priv_col_upd_grant ];
                    priv_grant_upd_set := [  ];
                    END
                ELSE
                    IF  priv_grant_upd_set <> [  ]
                    THEN
                        priv_col_exist :=
                              priv_col_exist + [ priv_col_upd_grant ];
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  r_sel in priv_all_grant_set
                THEN
                    BEGIN
                    priv_col_exist := priv_col_exist-[ priv_col_sel_grant ];
                    priv_grant_sel_set := [  ];
                    END
                ELSE
                    IF  priv_grant_sel_set <> [  ]
                    THEN
                        priv_col_exist :=
                              priv_col_exist + [ priv_col_sel_grant ];
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
&   ifdef TRACE
    (*ENDIF*) 
    a06td_priv (viewpriv, 'a16privrec_build  ',true);
&   endif
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a16put_usage_def  (
            VAR acv            : tak_all_command_glob;
            VAR put_tableid    : tgg00_Surrogate;
            VAR using_tableid  : tgg00_Surrogate;
            using_tablekind    : tgg00_TableKind);
 
VAR
      _replace     : boolean;
      _new_sysinfo : boolean;
      _place_found : boolean;
      _b_err       : tgg00_BasisError;
      _ix          : integer;
      _usebuf      : tak_sysbufferaddress;
      _usekey      : tgg00_SysInfoKey;
 
BEGIN
_usekey           := a01defaultkey;
_usekey.stableid  := put_tableid;
_usekey.sentrytyp := cak_eusage;
IF  _usekey.ssite <> cak_show_table_site
THEN
    BEGIN
    _place_found := false;
    a10_lock_sysinfo (acv, _usekey, lckRowExcl_egg00);
    WHILE ( acv.a_returncode = 0 ) AND
          ( NOT( _place_found ) ) DO
        BEGIN
        _replace       := false;
        _new_sysinfo   := false;
        a10_fix_len_get_sysinfo( acv, _usekey, d_release,
              cak_sysbufferoffset + mxak_usage_offset + mxak_usagedef,
              mxak_usagedef, _usebuf, _b_err);
        IF  acv.a_returncode = 0
        THEN
            WITH _usebuf^, susage DO
                BEGIN
                IF  _b_err = e_sysinfo_not_found
                THEN
                    BEGIN
                    _new_sysinfo  := true;
                    b_sl := cak_sysbufferoffset + mxak_usage_offset;
                    usagefiller     := 0;
                    usagefull       := false;
                    usagenext_exist := false;
                    usagecount      := 0;
                    usagesegmentid  := cak00_public_segment_id;
                    END
                ELSE
                    BEGIN
                    _ix := 1;
                    WHILE _ix <= _usebuf^.susage.usagecount DO
                        WITH _usebuf^.susage.usagedef[_ix] DO
                            IF  ( usa_tableid   = using_tableid ) AND
                                ( usa_tablekind = using_tablekind )
                            THEN
                                BEGIN
                                _place_found := true;
                                _ix          := cak_max_usage + 1
                                END
                            ELSE
                                _ix := _ix + 1
                            (*ENDIF*) 
                        (*ENDWITH*) 
                    (*ENDWHILE*) 
                    END;
                (*ENDIF*) 
                IF  NOT _place_found
                THEN
                    IF  usagecount = cak_max_usage
                    THEN
                        BEGIN (* current tusagerecord full *)
                        IF  NOT ( usagenext_exist )
                        THEN
                            BEGIN
                            usagenext_exist := true;
                            _replace         := true;
                            END;
                        (*ENDIF*) 
                        END
                    ELSE (* place found in current tusagerecord *)
                        BEGIN
                        _place_found := true;
                        _replace     := true;
                        b_sl         := b_sl + mxak_usagedef;
                        usagecount   := succ( usagecount );
                        WITH usagedef [ usagecount ] DO
                            BEGIN
                            usa_tableid   := using_tableid;
                            usa_filler    := 0;
                            usa_tablekind := using_tablekind;
                            usa_empty     := false;
                            END;
                        (*ENDWITH*) 
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                _b_err := e_ok;
                IF  _new_sysinfo OR _replace
                THEN
                    a10_add_repl_sysinfo( acv,
                          _usebuf, _new_sysinfo, _b_err );
                (*ENDIF*) 
                IF  _b_err <> e_ok
                THEN
                    a07_b_put_error( acv, _b_err, 1 )
                ELSE
                    a10_rel_sysinfo( acv, _usebuf^.syskey );
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        a06inc_linkage( _usekey.slinkage );
        END;
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      ak16column_in_view (
            VAR view_rec  : tak_baserecord;
            rec_no        : integer;
            tab_no        : integer;
            VAR extcolno  : tsp00_Int2;
            VAR is_key    : boolean) : boolean;
 
VAR
      _found : boolean;
      _j     : integer;
 
BEGIN
&ifdef trace
t01p2int4 (ak_sem, 'tabno       ', tab_no, 'colno       ', rec_no);
&endif
_found    := false;
extcolno  := 0;
_j := view_rec.bfirstindex;
WHILE ( _j <= view_rec.blastindex ) AND NOT ( _found ) DO
    BEGIN
    IF  ( view_rec.bcolumn[ _j ]^.ctabno = tab_no ) AND
        ( view_rec.bcolumn[ _j ]^.creccolno = rec_no )
        AND NOT ( ctdropped    in view_rec.bcolumn[ _j ]^.ccolpropset )
        AND NOT ( ctexpression in view_rec.bcolumn[ _j ]^.ccolpropset )
    THEN
        BEGIN
&       ifdef trace
        t01buf1 (ak_sem, view_rec.bcolumn[ _j ]^, 1, 44);
&       endif
        _found   := true;
        extcolno := view_rec.bcolumn[ _j ]^.cextcolno MOD c_derived_ind;
        IF  view_rec.btablekind = tview
        THEN
            is_key := ( ctjoinviewkey in view_rec.bcolumn[ _j ]^.ccolpropset )
        ELSE
            is_key := ( ctkey in view_rec.bcolumn[ _j ]^.ccolpropset );
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    _j := _j + 1;
    END;
(*ENDWHILE*) 
ak16column_in_view := _found;
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16resort_joinarr (
            VAR acv          : tak_all_command_glob;
            VAR a16v         : tak16_viewglob;
            VAR b_err        : tgg00_BasisError);
 
VAR
      _catalog_inner    : tak_sysbufferaddress;
      _catalog_outer    : tak_sysbufferaddress;
      _catalog_key      : tgg00_SysInfoKey;
      _outer_cnt        : integer;
      _inner_cnt        : integer;
      _arr_idx_inner    : integer;
      _arr_idx_outer    : integer;
      _min_stack_pos    : integer;
      _min_index        : integer;
      _lower_entry      : tak_one_viewjoin;
 
BEGIN
_catalog_outer := a16v.a6vqual_join;
_arr_idx_outer := 1;
_outer_cnt     := 1;
WHILE ( _outer_cnt <= _catalog_outer^.sviewqual_join.vjoincount ) AND
      ( b_err = e_ok ) DO
    BEGIN
    IF  _arr_idx_outer  > cak_max_viewqual_join
    THEN
        (* record overflow handling *)
        BEGIN
        (* replace previous catalog record *)
        a10repl_sysinfo( acv, _catalog_outer, b_err );
        _catalog_key := _catalog_outer^.syskey;
        IF  _catalog_outer^.syskey.slinkage <> cak_init_linkage
        THEN
            a10rel_sysinfo( _catalog_outer );
        (*ENDIF*) 
        a06inc_linkage( _catalog_key.slinkage );
        a10get_sysinfo( acv, _catalog_key, d_fix, _catalog_outer, b_err );
        _arr_idx_outer := 1;
        END;
    (*ENDIF*) 
    _min_stack_pos   := csp_maxint2;
    _inner_cnt       := _outer_cnt;
    _arr_idx_inner   := _arr_idx_outer;
    _catalog_inner   := _catalog_outer;
    WHILE ( _inner_cnt <= _catalog_inner^.sviewqual_join.vjoincount ) AND
          ( b_err = e_ok ) DO
        BEGIN
        IF  _arr_idx_inner  > cak_max_viewqual_join
        THEN
            (* record overflow handling *)
            BEGIN
            _catalog_key := _catalog_inner^.syskey;
            a06inc_linkage( _catalog_key.slinkage );
            a10get_sysinfo( acv, _catalog_key, d_release, _catalog_inner, b_err );
            _arr_idx_inner := 1;
            END;
        (*ENDIF*) 
        IF  ( _catalog_inner^.sviewqual_join.vjoin[ _arr_idx_inner ].
            j1startstack < _min_stack_pos ) AND ( b_err = e_ok )
        THEN
            BEGIN
            _min_stack_pos   := _catalog_inner^.sviewqual_join.
                  vjoin[ _arr_idx_inner ].j1startstack;
            _min_index       := _arr_idx_inner;
            END;
        (*ENDIF*) 
        _inner_cnt      := succ( _inner_cnt );
        _arr_idx_inner  := succ( _arr_idx_inner );
        END;
    (*ENDWHILE*) 
    IF  (( _arr_idx_outer <> _min_index ) OR
        ( _catalog_inner^.syskey.slinkage <> _catalog_outer^.syskey.slinkage ))
        AND
        ( b_err = e_ok )
    THEN
        BEGIN
        (* put greater value *)
        (* _catalog_inner points to record with lower entry *)
        _lower_entry := _catalog_inner^.sviewqual_join.vjoin[ _min_index ];
        _catalog_inner^.sviewqual_join.vjoin[ _min_index ] :=
              (* greater j1startstack *)
              _catalog_outer^.sviewqual_join.vjoin[ _arr_idx_outer ];
        a10repl_sysinfo( acv, _catalog_inner, b_err );
        IF  b_err = e_ok
        THEN
            BEGIN
            _catalog_outer^.sviewqual_join.vjoin[ _arr_idx_outer ] :=
                  _lower_entry;
            a10repl_sysinfo( acv, _catalog_outer, b_err );
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    _outer_cnt      := succ( _outer_cnt );
    _arr_idx_outer  := succ( _arr_idx_outer );
    END;
(*ENDWHILE*) 
IF  _catalog_outer^.syskey.slinkage <> cak_init_linkage
THEN
    (* pointer on _catalog_outer got with d_fix *)
    a10rel_sysinfo( _catalog_outer );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16restore_scheme (
            VAR acv         : tak_all_command_glob;
            VAR scheme_tree : tgg00_FileId);
 
VAR
      _ret_code    : integer;
      _viewscanpar : tak_save_viewscan_par;
 
BEGIN
IF  scheme_tree.fileRoot_gg00 <> NIL_PAGE_NO_GG00
THEN
    BEGIN
    a27init_viewscanpar( acv, _viewscanpar, v_save_scheme );
    _viewscanpar.vsc_tree_id := scheme_tree;
    _ret_code           := acv.a_returncode;
    acv.a_internal_sql := sql_alter_table;
    a15restore_catalog( acv, scheme_tree, _viewscanpar );
    acv.a_internal_sql := no_internal_sql;
    b01empty_file( acv.a_transinf.tri_trans, acv.a_into_tree );
    IF  ( acv.a_returncode < 0 ) AND ( _ret_code = 0 )
    THEN
        BEGIN
        acv.a_returncode := 0;
        a07_b_put_error( acv, e_too_many_differences, 1 );
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a16col_to_view_description (
            VAR acv      : tak_all_command_glob;
            VAR dmli     : tak_dml_info;
            VAR col_info : tak00_columninfo;
            use_extcolno : boolean);
 
VAR
      b_err    : tgg00_BasisError;
      p        : tak_sysbufferaddress;
      tabno    : integer;
      sysk     : tgg00_SysInfoKey;
 
BEGIN
IF  acv.a_returncode = 0
THEN
    BEGIN
    p := NIL;
    IF  ( acv.a_opt_info_ptr <> NIL ) AND
        NOT ( acv.a_from_select )
    THEN
        BEGIN
        IF  acv.a_queryrewrite_mode = Statement_Rewrite (* PTS 1128197 D.T. *)
        THEN
            a664col_info( acv, dmli.d_outcolno - 1,
                  col_info.cextcolno, dmli.d_n_pos, dmli.d_act_node );
        (*ENDIF*) 
        END
    ELSE
        IF  (( dmli.d_phase_cnt <= cak_complex_view_indicator )
            AND
            ( acv.a_is_ddl <> no_ddl )
            AND
            ( acv.a_is_ddl <> ddl_create_as_select ))
            OR
            (dmli.d_viewdescbuf <> NIL)
        THEN
            BEGIN
            IF  dmli.d_view
            THEN
                BEGIN
                sysk           := a01defaultkey;
                sysk.stableid  := dmli.d_tableid;
                sysk.sentrytyp := cak_etempviewtext;
                a10get_sysinfo( acv, sysk, d_release, p, b_err );
                IF  b_err = e_ok
                THEN
                    tabno := p^.sviewtext.vttabcount
                ELSE
                    a07_b_put_error( acv, b_err, 1 );
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            a16inc_vdesc_cnt( acv, dmli, p );
            IF  ( acv.a_returncode = 0 ) AND ( p <> NIL )
            THEN
                WITH dmli, p^.sviewdesc, vdescription[ vdesc_cnt ] DO
                    BEGIN
                    IF  d_view
                    THEN
                        vfromtabno := tabno - d_cntfromtab + d_acttabindex
                    ELSE
                        vfromtabno := 0;
                    (*ENDIF*) 
                    vfromextcolno := col_info.cextcolno;
                    vn_pos        := d_n_pos;
                    IF  abs( vn_pos ) > a01char_size
                    THEN
                        IF  a01equal_char( acv.a_cmd_part^.sp1p_buf,
                            abs( vn_pos ) - a01char_size, '"' )
                        THEN
                            IF  vn_pos > 0
                            THEN
                                vn_pos := vn_pos - a01char_size
                            ELSE
                                vn_pos := vn_pos + a01char_size;
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    IF  use_extcolno AND (d_esparr.pbasep <> NIL)
                    THEN
                        vextcolno := d_esparr.pbasep^.sbase.bmaxcol + 1
                    ELSE
                        vextcolno := 0;
                    (*ENDIF*) 
                    vdatatype := dunknown;
&                   ifdef trace
                    t01p4int4 (ak_sem, 'vdescription', vfromtabno,
                          vfromextcolno, vn_pos, vextcolno);
&                   endif
                    IF  acv.a_is_ddl = ddl_create_view
                    THEN
                        a10_add_repl_sysinfo( acv, p, false, b_err );
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a16inc_vdesc_cnt (
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info;
            VAR p    : tak_sysbufferaddress);
 
VAR
      _b_err   : tgg00_BasisError;
      _sysk    : tgg00_SysInfoKey;
 
BEGIN
IF  acv.a_is_ddl = ddl_create_view
THEN
    BEGIN
    _sysk           := a01defaultkey;
    _sysk.stableid  := dmli.d_tableid;
    _sysk.sentrytyp := cak_etempviewdesc;
    _sysk.slinkage  := dmli.d_viewdesc_linkage;
    a10get_sysinfo( acv, _sysk, d_release, p, _b_err );
    END
ELSE
    BEGIN
    _b_err := e_ok;
    IF  dmli.d_viewdescbuf <> NIL
    THEN
        p := dmli.d_viewdescbuf
    ELSE
        (* viewdesc catalog record is allocated at address d_linkbuf *)
        p      := dmli.d_linkbuf;
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  _b_err = e_ok
THEN
    BEGIN
    IF  p <> NIL
    THEN
        IF  p^.sviewdesc.vdesc_cnt + 1 > cak_maxviewdesc
        THEN
            BEGIN
            (*======== current view desc record full ========= *)
            IF  acv.a_is_ddl <> ddl_create_view
            THEN
                a07_b_put_error( acv, e_too_long_viewtext, 1 )
            ELSE
                BEGIN
                p^.sviewdesc.vdesc_next := true;
                a10_add_repl_sysinfo( acv, p, false, _b_err );
                IF  _b_err = e_ok
                THEN
                    BEGIN
                    a06inc_linkage( _sysk.slinkage );
                    dmli.d_viewdesc_linkage := _sysk.slinkage;
                    ak16alloc_temp_record( acv, _sysk, p );
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  p <> NIL
    THEN
        p^.sviewdesc.vdesc_cnt := succ( p^.sviewdesc.vdesc_cnt );
    (*ENDIF*) 
    END
ELSE
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16alloc_temp_record (
            VAR acv  : tak_all_command_glob;
            VAR sysk : tgg00_SysInfoKey;
            VAR p    : tak_sysbufferaddress);
 
VAR
      _b_err   : tgg00_BasisError;
      _req_len : integer;
 
BEGIN
p := NIL;
IF  sysk.sentrytyp = cak_etempviewdesc
THEN
    _req_len := cak_viewdesc_offset +
          cak_maxviewdesc * sizeof( tak_vcolumndescription )
ELSE
    _req_len := mxak_viewtextrec;
(*ENDIF*) 
a10_nil_get_sysinfo( acv, sysk, d_release, _req_len, p, _b_err );
IF  (_b_err = e_ok) OR (_b_err = e_duplicate_sysinfo)
THEN
    BEGIN
    p^.b_sl := _req_len;
    IF  sysk.sentrytyp = cak_etempviewdesc
    THEN
        BEGIN
        p^.sviewdesc.vdesc_cnt   := 0;
        p^.sviewdesc.vdesc_next  := false;
        p^.sviewdesc.vdesc_fill1 := false;
        p^.sviewdesc.vdesc_fill2 := 0;
        END
    ELSE
        BEGIN
        p^.sviewtext.vtfromtabcnt := 0;
        p^.sviewtext.vttabcount   := 0;
        END;
    (*ENDIF*) 
    a10_add_repl_sysinfo( acv, p, e_ok = _b_err, _b_err );
    END;
(*ENDIF*) 
IF  _b_err <> e_ok
THEN
    a07_b_put_error( acv, _b_err, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a16constraint_check (
            VAR acv      : tak_all_command_glob;
            VAR view_rec : tak_baserecord;
            qualbuf      : tak_sysbufferaddress);
 
VAR
      _ok             : boolean;
      _dummy_bool     : boolean;
      _b_err          : tgg00_BasisError;
      _p              : tak_sysbufferaddress;
      _base_ptr       : tak_sysbufferaddress;
      _i              : integer;
      _colno          : integer;
      _dummy_int      : tsp00_Int2;
      _tabno          : integer;
      _constraint_cnt : integer;
      _constraint_n   : tsp00_KnlIdentifier;
      _constraint_ptr : ^tsp00_KnlIdentifier;
      _dupl_file      : tgg00_FileId;
      _sysk           : tgg00_SysInfoKey;
 
BEGIN
_sysk           := a01defaultkey;
_sysk.sentrytyp := cak_econstraint;
_dupl_file      := acv.a_pars_curr;
_dupl_file.fileTfnTemp_gg00 := ttfnDistinct_egg00;
b01tcreate_file( acv.a_transinf.tri_trans, _dupl_file );
IF  acv.a_transinf.tri_trans.trError_gg00 <> e_ok
THEN
    a07_b_put_error( acv, acv.a_transinf.tri_trans.trError_gg00, 1 );
(*ENDIF*) 
_tabno := 1;
WHILE ( _tabno <= qualbuf^.sviewqual_basis.vbasetabcnt ) AND
      ( acv.a_returncode = 0 ) DO
    BEGIN
    _i := 1;
    WHILE _i < _tabno DO
        IF  qualbuf^.sviewqual_basis.vtable[ _i ].vttableid =
            qualbuf^.sviewqual_basis.vtable[ _tabno ].vttableid
        THEN
            _i := csp_maxint2
        ELSE
            _i := _i + 1;
        (*ENDIF*) 
    (*ENDWHILE*) 
    IF  _i = csp_maxint2
    THEN (* table already handled *)
        _constraint_cnt := 0
    ELSE
        BEGIN
        a06_systable_get( acv, d_release, qualbuf^.sviewqual_basis.vtable[ _tabno ].vttableid,
              _base_ptr, false, _ok );
        IF  _ok
        THEN
            _constraint_cnt := _base_ptr^.sbase.bnamed_constr
        ELSE
            BEGIN
            a07ak_system_error( acv, 16, 6 );
            _constraint_cnt := 0
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    _i := 1;
    WHILE _i <= _constraint_cnt DO
        BEGIN
        _sysk.stableid  := qualbuf^.sviewqual_basis.vtable[ _tabno ].vttableid;
        _sysk.slinkage[ 1 ] := chr( _i DIV 256 );
        _sysk.slinkage[ 2 ] := chr( _i MOD 256 );
        a10get_sysinfo( acv, _sysk, d_release, _p, _b_err );
        IF  _b_err = e_ok
        THEN
            BEGIN
            _colno := 1;
            WHILE _colno <= _base_ptr^.sbase.bmaxcol DO
                BEGIN
                (* check, if any column of constraint is in view *)
                IF  _colno in _p^.sconstraint.ccolset
                THEN
                    IF  ak16column_in_view( view_rec,
                        _colno, _tabno, _dummy_int, _dummy_bool )
                    THEN
                        _colno := csp_maxint2 - 1;
                    (*ENDIF*) 
                (*ENDIF*) 
                _colno := _colno + 1
                END;
            (*ENDWHILE*) 
            IF  _colno = csp_maxint2
            THEN
                BEGIN
                (* constraint is inherited *)
                a11getconstraintname( _p^.sconstraint, _constraint_n );
                _constraint_ptr  := @acv.a_mblock.mb_data^.mbp_buf
                      [ cgg_rec_key_offset + 1 ];
                _constraint_ptr^ := _constraint_n;
                WITH acv.a_mblock.mb_data^ DO
                    BEGIN
                    mbp_keylen := sizeof( _constraint_n );
                    mbp_reclen := cgg_rec_key_offset +
                          sizeof( _constraint_n );
                    mbp_varcol_offset := 0;
                    mbp_varcol_cnt    := 0;
                    END;
                (*ENDWITH*) 
                b07cadd_record( acv.a_transinf.tri_trans,
                      _dupl_file, acv.a_mblock.mb_data^.mbp_rec );
                IF  acv.a_transinf.tri_trans.trError_gg00 = e_duplicate_key
                THEN
                    IF  acv.a_init_ddl = ddl_create_view
                    THEN
                        a07_nb_put_error( acv, e_duplicate_constraint, 1,
                              _constraint_n )
                    ELSE
                        a07_nb_put_error( acv,
                              e_view_def_contradicts_table_de,
                              1, view_rec.btablen^ )
                    (*ENDIF*) 
                ELSE
                    _b_err := acv.a_transinf.tri_trans.trError_gg00
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  _b_err <> e_ok
        THEN
            BEGIN
            _i := csp_maxint2;
            a07_b_put_error( acv, _b_err, 1 );
            END
        ELSE
            _i := succ( _i );
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    _tabno := succ( _tabno );
    END;
(*ENDWHILE*) 
b01destroy_file( acv.a_transinf.tri_trans, _dupl_file );
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16finalize_record (
            VAR acv         : tak_all_command_glob;
            VAR syspoint    : tak_sysbufferaddress;
            add_sysinfo     : boolean;
            rec_length      : integer;
            VAR b_err       : tgg00_BasisError);
 
BEGIN
IF  ( acv.a_returncode = 0 ) AND ( b_err = e_ok )
THEN
    BEGIN
    (* write correct record length *)
    IF  rec_length > 0
    THEN
        syspoint^.b_sl := rec_length;
    (*ENDIF*) 
    ;
    (* put prior record in catalog *)
    a10_add_repl_sysinfo( acv, syspoint, add_sysinfo, b_err );
    IF  b_err = e_sysinfo_not_found
    THEN
        (* may happen in the course of replace view, *)
        (*  if old view is complex and new is not    *)
        a10add_sysinfo( acv, syspoint, b_err );
    (*ENDIF*) 
    IF  b_err <> e_ok
    THEN
        a07_b_put_error( acv, b_err, 1 );
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16linkinfo_init (
            VAR acv       : tak_all_command_glob;
            VAR a16dmli   : tak_dml_info;
            VAR link_info : tak16_linkinfo);
 
VAR
 
      _cast         : RECORD
            CASE integer OF
                1 :
                    (addr: tsp00_Addr);
                2 :
                    (jptr : tak16_joinarr_ptr);
                3 :
                    (mptr : tak16_mantory_ptr);
                4 :
                    (lptr : tak16_queueelement_arr_ptr);
                5 :
                    (rptr : tak16_link_relation_ptr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
link_info.ljoins   := NIL;
link_info.ljoincnt := 0;
_cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
      a16dmli.d_joins.jrc_capacity * sizeof(tsp00_Int2) );
(* value of ljoincnt at most value of a16dmli.d_joins.jrc_cnt *)
link_info.ljoins := _cast.jptr;
;
link_info.lmantory   := NIL;
_cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
      a16dmli.d_cntfromtab * sizeof(tak_columnset) );
link_info.lmantory := _cast.mptr;
;
link_info.ltab_seq.seq_queue := NIL;
_cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
      ( a16dmli.d_cntfromtab + 1 ) * sizeof(tak16_queueelement) );
link_info.ltab_seq.seq_queue := _cast.lptr;
;
(* reserve memory for informations about link relation *)
_cast.addr := gg941Allocate( acv.a_transinf.tri_trans,
      a16dmli.d_cntfromtab * a16dmli.d_cntfromtab * sizeof(tak16_link_set) );
link_info.lpred := _cast.rptr;
IF  (( link_info.ljoins = NIL ) OR ( link_info.lmantory = NIL ) OR
    ( link_info.ltab_seq.seq_queue = NIL ) OR ( link_info.lpred = NIL ))
THEN
    a07_b_put_error( acv, e_no_more_memory, 1 );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16_linkinfo_finalize (
            VAR acv       : tak_all_command_glob;
            VAR link_info : tak16_linkinfo);
 
VAR
 
      _cast         : RECORD
            CASE integer OF
                1 :
                    (addr: tsp00_Addr);
                2 :
                    (jptr : tak16_joinarr_ptr);
                3 :
                    (mptr : tak16_mantory_ptr);
                4 :
                    (lptr : tak16_queueelement_arr_ptr);
                5 :
                    (rptr : tak16_link_relation_ptr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
_cast.jptr := link_info.ljoins;
gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
link_info.ljoincnt := 0;
link_info.ljoins   := NIL;
;
_cast.mptr := link_info.lmantory;
gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
link_info.lmantory := NIL;
;
_cast.lptr := link_info.ltab_seq.seq_queue;
gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
link_info.ltab_seq.seq_queue := NIL;
;
_cast.rptr := link_info.lpred;
gg941Deallocate( acv.a_transinf.tri_trans, _cast.addr );
link_info.lpred := NIL;
END;
 
(*------------------------------*) 
 
FUNCTION
      ak16test_link_relation(
            VAR dmli    : tak_dml_info;
            linkrel     : tak16_link_relation_ptr;
            dim1        : tsp00_Int2;
            dim2        : tsp00_Int2;
            candidate   : tak16_link_type ) : boolean;
 
VAR
 
      _cast                : RECORD
            CASE integer OF
                1 :
                    (addr: tsp00_MoveObjPtr);
                2 :
                    (ptr : tak16_link_relation_ptr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
&ifdef diagnose
IF  (( dim1 > dmli.d_cntfromtab ) OR
    ( dim2 > dmli.d_cntfromtab ))
THEN
    BEGIN
    IF  ( dim1 > dmli.d_cntfromtab )
    THEN
        g01abort( ord(e_move_error), csp3_n_view,
              'TABLE CNT RANGE CHECK   ', dim1)
    ELSE
        g01abort( ord(e_move_error), csp3_n_view,
              'TABLE CNT RANGE CHECK   ', dim2);
    (*ENDIF*) 
    END;
(*ENDIF*) 
;
&endif
_cast.addr := s35add_moveobj_ptr_ptocm( @(linkrel^),
      ((dim1 - 1) * dmli.d_cntfromtab * sizeof( tak16_link_set ) +
      (dim2 - 1) * sizeof( tak16_link_set )));
ak16test_link_relation := ( candidate in _cast.ptr^ );
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16set_link_relation(
            VAR dmli    : tak_dml_info;
            linkrel     : tak16_link_relation_ptr;
            add_value   : boolean;
            dim1        : tsp00_Int2;
            dim2        : tsp00_Int2;
            value       : tak16_link_set);
 
VAR
 
      _cast                : RECORD
            CASE integer OF
                1 :
                    (addr: tsp00_MoveObjPtr);
                2 :
                    (ptr : tak16_link_relation_ptr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
&ifdef diagnose
IF  (( dim1 > dmli.d_cntfromtab ) OR
    ( dim2 > dmli.d_cntfromtab ))
THEN
    BEGIN
    IF  ( dim1 > dmli.d_cntfromtab )
    THEN
        g01abort( ord(e_move_error), csp3_n_view,
              'TABLE CNT RANGE CHECK   ', dim1)
    ELSE
        g01abort( ord(e_move_error), csp3_n_view,
              'TABLE CNT RANGE CHECK   ', dim2);
    (*ENDIF*) 
    END;
(*ENDIF*) 
;
&endif
_cast.addr := s35add_moveobj_ptr_ptocm( @(linkrel^),
      ((dim1 - 1) * dmli.d_cntfromtab * sizeof( tak16_link_set ) +
      (dim2 - 1) * sizeof( tak16_link_set )));
IF  ( add_value )
THEN
    _cast.ptr^ := _cast.ptr^ + value
ELSE
    _cast.ptr^ := value;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak16del_permmblocks(
            VAR acv       : tak_all_command_glob;
            VAR a16dmli   : tak_dml_info);
 
VAR
      _dummy   : tak_parskey;
      _syskey  : tgg00_SysInfoKey;
      _b_err   : tgg00_BasisError;
      _i       : tsp00_Int2;
 
BEGIN
_i     := 0;
_b_err := e_ok;
WHILE ( _i < cak00_maxsources ) AND ( _b_err = e_ok ) DO
    BEGIN
    _i := succ(_i);
    a682join_MBlock_key( acv, a16dmli, _dummy,
          a16dmli.d_tableid, _i, _syskey, false );
    a10del_sysinfo( acv, _syskey, _b_err );
&   ifdef trace
    t01basis_error (ak_sem, '_b_err      ', _b_err );
&   endif
    END;
(*ENDWHILE*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
