.nf
 
 
    ========== licence begin  GPL
    Copyright (c) 2000-2004 SAP AG
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
 
.fo
*****************************************************
Copyright (c) 2000-2004 SAP AG
SAP Database Technology
 
Release :      Date : 2000-11-22
*****************************************************
modname : VAK24
changed : 2000-11-22
module  : AK_Index
 
Author  : ThomasA
Created : 1985-10-16
*****************************************************
 
Purpose : Semantische Routinen fur create index.
 
Define  :
 
        PROCEDURE
              a24assign_indexname (
                    VAR acv          : tak_all_command_glob;
                    ibuf             : tak_sysbufferaddress;
                    index            : integer;
                    VAR indexname    : tsp00_KnlIdentifier);
 
        PROCEDURE
              a24init_index_scan (
                    VAR acv            : tak_all_command_glob;
                    VAR tabid          : tgg00_Surrogate;
                    VAR index_scan_rec : tak_index_scan_record);
 
        PROCEDURE
              a24get_indexname (
                    VAR acv        : tak_all_command_glob;
                    indexbuf       : tak_sysbufferaddress;
                    index          : integer;
                    VAR index_name : tsp00_KnlIdentifier);
 
        PROCEDURE
              a24find_indexname (
                    VAR acv            : tak_all_command_glob;
                    VAR tabid          : tgg00_Surrogate;
                    VAR indexname      : tsp00_KnlIdentifier;
                    VAR index_scan_rec : tak_index_scan_record);
 
        PROCEDURE
              a24fnd_indexno (
                    VAR acv            : tak_all_command_glob;
                    VAR tabid          : tgg00_Surrogate;
                    indexno            : integer;
                    VAR index_scan_rec : tak_index_scan_record);
 
        PROCEDURE
              a24finish_index_scan (
                    VAR acv            : tak_all_command_glob;
                    VAR index_scan_rec : tak_index_scan_record);
 
        FUNCTION
              a24IndexFieldCount (
                    VAR index_def : tak_multindex) : integer;
 
        FUNCTION
              a24IndexMatch (
                    VAR acv        : tak_all_command_glob;
                    VAR index_def  : tak_multindex;
                    stackStart     : integer;
                    stackEnd       : integer) : boolean;
 
        FUNCTION
              a24IsFunctionBasedIndex(VAR index_def : tak_multindex) : boolean;
 
        FUNCTION
              a24LookForFunctionBasedIndex (
                    VAR acv        : tak_all_command_glob;
                    stackStart     : integer;
                    stackEnd       : integer;
                    VAR stackNext  : integer) : boolean;
 
        PROCEDURE
              a24MigrateUnnamedIndex (
                    VAR acv  : tak_all_command_glob;
                    pBase    : tak_sysbufferaddress;
                    opType   : tgg00_StackOpType;
                    colptr   : tak00_colinfo_ptr);
 
        FUNCTION
              a24next_named_index (
                    VAR acv            : tak_all_command_glob;
                    VAR index_scan_rec : tak_index_scan_record) : boolean;
 
        PROCEDURE
              a24_call_semantic  (
                    VAR acv       : tak_all_command_glob;
                    ignore_errors : boolean);
 
        PROCEDURE
              a24drop_multiple_index (
                    VAR acv          : tak_all_command_glob;
                    VAR viewscanpar  : tak_viewscan_par;
                    indexname_errpos  : integer;
                    do_a38_input      : boolean);
 
        PROCEDURE
              a24ObjectIndex (
                    VAR acv            : tak_all_command_glob;
                    VAR ClassSurrogate : tgg00_Surrogate;
                    VAR ColDesc        : tgg00_ObjColDesc;
                    VAR e              : tgg00_BasisError); (* PTS 1106736 *)
 
        PROCEDURE
              a24RecreateBadIndexes (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a24send_index_command_to_kb (
                    VAR acv         : tak_all_command_glob;
                    VAR viewscanpar : tak_viewscan_par;
                    index_no        : integer;
                    m_type          : tgg00_MessType;
                    mm_type         : tgg00_MessType2);
 
        PROCEDURE
              a24unique_spec (
                    VAR acv         : tak_all_command_glob;
                    unique_node     : integer);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
&       ifdef TRACE
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01bool (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    curr_bool: boolean);
 
        PROCEDURE
              t01line (
                    level  : tgg00_Debug;
                    VAR ln : tsp00_Line);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01c18 (
                    debuf : tgg00_Debug;
                    c18 : tsp00_C18);
 
        PROCEDURE
              t01stackentry (
                    debug          : tgg00_Debug;
                    VAR st         : tgg00_StackEntry;
                    entry_index    : integer);
 
      ------------------------------ 
 
        FROM
              Syntax-Tree-Printer : VAK99;
 
        VAR
              a99blankline : tsp00_Line;
&       endif
 
      ------------------------------ 
 
        FROM
              AK_Domain : VAK12;
 
        FUNCTION
              a12dbfunc_exist (VAR acv : tak_all_command_glob;
                    VAR owner       : tsp00_KnlIdentifier;
                    VAR dbfunc_name : tsp00_KnlIdentifier;
                    dstate          : tak_directory_state;
                    VAR method_buf  : tak_sysbufferaddress) : boolean;
 
        PROCEDURE
              a12describe_param  (VAR acv : tak_all_command_glob;
                    method_buf   : tak_sysbufferaddress;
                    param_no     : integer;
                    VAR colinf   : tak00_scolinf);
 
        PROCEDURE
              a12output_parameter (VAR acv : tak_all_command_glob;
                    method_buf     : tak_sysbufferaddress;
                    VAR inout_idx  : integer;
                    VAR colinf     : tak00_scolinf);
 
      ------------------------------ 
 
        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_Trigger : VAK262;
 
        PROCEDURE
              a262CalcOutputLen (
                    VAR acv         : tak_all_command_glob;
                    VAR methodRec   : tak_methodrecord;
                    pParamTable     : tak_sysbufferaddress;
                    VAR constParams : tak_colinteger;
                    VAR dataLength  : tsp00_Int2;
                    VAR ioLength    : tsp00_Int2;
                    VAR fraction    : tsp00_Int2);
 
        FUNCTION
              a262EvalOutputLenProlog (
                    VAR  acv        : tak_all_command_glob;
                    VAR  functionId : tgg00_Surrogate) : tak_sysbufferaddress;
 
        PROCEDURE
              a262SetParameterProperties (
                    VAR acv       : tak_all_command_glob;
                    pParamTable   : tak_sysbufferaddress;
                    paramNo       : integer;
                    paramDataType : tsp00_DataType;
                    dataLength    : integer;
                    inOutLength   : integer;
                    fraction      : integer);
 
      ------------------------------ 
 
        FROM
              AK_show_syntax : VAK41;
 
        PROCEDURE
              a41init_show_glob (
                    VAR a41v  : tak40_show_glob;
                    mess_code : tsp00_CodeType);
 
      ------------------------------ 
 
        FROM
              AK_universal_show_tools : VAK40;
 
        PROCEDURE
              a40init_table_scan (
                    VAR acv          : tak_all_command_glob;
                    VAR a41v         : tak40_show_glob;
                    scan_temp        : boolean;
                    scan_private     : boolean;
                    scan_non_private : boolean;
                    scan_public      : boolean;
                    use_synonyms     : boolean;
                    all_base         : boolean);
 
        FUNCTION
              a40next_table (
                    VAR acv  : tak_all_command_glob;
                    VAR a41v : tak40_show_glob) : boolean;
 
      ------------------------------ 
 
        FROM
              AK_Lock_Commit_Rollback : VAK52;
 
        PROCEDURE
              a52_ex_commit_rollback (
                    VAR acv        : tak_all_command_glob;
                    m_type         : tgg00_MessType;
                    n_rel          : boolean;
                    normal_release : boolean);
 
      ------------------------------ 
 
        FROM
              AK_data_dictionary : VAK38;
 
        PROCEDURE
              a38index_drop (
                    VAR acv        : tak_all_command_glob;
                    VAR username   : tsp00_KnlIdentifier;
                    VAR tablename  : tsp00_KnlIdentifier;
                    VAR columnname : tsp00_KnlIdentifier;
                    VAR indexname  : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              AK_update_statistics : VAK28;
 
        PROCEDURE
              a28table_upd_statistics (
                    VAR acv      : tak_all_command_glob;
                    sample_rows  : tsp00_Int4;
                    sample_pct   : integer;
                    page_cnt     : tsp00_Int4;
                    rec_cnt      : tsp00_Int4;
                    sec_cnt      : tsp00_Int4;
                    colno        : integer;
                    add          : boolean;
                    commit       : boolean);
 
      ------------------------------ 
 
        FROM
              AK_VIEW_SCAN : VAK27;
 
        PROCEDURE
              a27init_viewscanpar (
                    VAR acv         : tak_all_command_glob;
                    VAR viewscanpar : tak_viewscan_par;
                    v_type          : tak_viewscantype);
 
        PROCEDURE
              a27view_scan   (
                    VAR acv         : tak_all_command_glob;
                    VAR tableid     : tgg00_Surrogate;
                    VAR viewscanpar : tak_viewscan_par);
 
      ------------------------------ 
 
        FROM
              AK_Link : VAK25;
 
        FUNCTION
              a25is_link_index (
                    VAR acv   : tak_all_command_glob;
                    col_count : integer;
                    index_id  : integer) : boolean;
 
      ------------------------------ 
 
        FROM
              AK_Table   : VAK11;
 
        PROCEDURE
              a11put_date_time (
                    VAR date : tsp00_Int4;
                    VAR time : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Systeminfo_cache   : VAK10;
 
        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_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
              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_add_repl_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    add_sysinfo  : boolean;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10_nil_get_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syskey   : tgg00_SysInfoKey;
                    dstate       : tak_directory_state;
                    syslen       : tsp00_Int2;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10repl_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10del_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syskey   : tgg00_SysInfoKey;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10_rel_sysinfo (
                    VAR acv    : tak_all_command_glob;
                    VAR syskey : tgg00_SysInfoKey);
 
        PROCEDURE
              a10_version (
                    VAR acv        : tak_all_command_glob;
                    VAR base_rec   : tak_baserecord;
                    m_type         : tgg00_MessType;
                    view_scan      : boolean);
 
        PROCEDURE
              a10_cache_delete  (
                    VAR acv     : tak_all_command_glob;
                    is_rollback : boolean);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK07;
 
        PROCEDURE
              a07_b_put_error (
                    VAR acv : tak_all_command_glob;
                    b_err : tgg00_BasisError;
                    err_code : tsp00_Int4);
 
        PROCEDURE
              a07_kw_put_error (
                    VAR acv  : tak_all_command_glob;
                    b_err    : tgg00_BasisError;
                    err_code : tsp00_Int4;
                    kw       : integer);
 
        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_universal_semantic_tools : VAK06;
 
        PROCEDURE
              a06a_mblock_init (
                    VAR acv         : tak_all_command_glob;
                    mtype           : tgg00_MessType;
                    m2type          : tgg00_MessType2;
                    VAR tree        : tgg00_FileId);
 
        PROCEDURE
              a06determine_username (
                    VAR acv       : tak_all_command_glob;
                    VAR userid    : tgg00_Surrogate;
                    VAR user_name : tsp00_KnlIdentifier);
 
        PROCEDURE
              a06extcolno (
                    VAR baserec  : tak_baserecord;
                    extcolno     : integer;
                    VAR col_ptr  : tak00_colinfo_ptr);
 
        PROCEDURE
              a06get_username (
                    VAR acv        : tak_all_command_glob;
                    VAR tree_index : integer;
                    VAR username   : tsp00_KnlIdentifier);
 
        PROCEDURE
              a06inc_linkage (VAR linkage : tsp00_C2);
 
        FUNCTION
              a06_table_exist (
                    VAR acv     : tak_all_command_glob;
                    dstate      : tak_directory_state;
                    VAR authid  : tsp00_KnlIdentifier;
                    VAR tablen  : tsp00_KnlIdentifier;
                    VAR d_sparr : tak_syspointerarr;
                    get_all     : boolean) : boolean;
 
        PROCEDURE
              a06_get_priv  (
                    VAR acv  : tak_all_command_glob;
                    VAR brec : tak_sysbufferaddress;
                    VAR priv : tak_privilege);
 
        PROCEDURE
              a06rsend_mess_buf (
                    VAR acv              : tak_all_command_glob;
                    VAR mblock           : tgg00_MessBlock;
                    result_req           : boolean;
                    VAR e                : tgg00_BasisError);
 
        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);
 
      ------------------------------ 
 
        FROM
              AK_Identifier_Handling : VAK061;
 
        PROCEDURE
              a061assign_colname (
                    value       : tsp00_C18;
                    VAR colname : tsp00_KnlIdentifier);
 
        FUNCTION
              a061exist_columnname (
                    VAR base_rec    : tak_baserecord;
                    VAR column      : tsp00_KnlIdentifier;
                    VAR colinfo_ptr : tak00_colinfo_ptr) : boolean;
 
        FUNCTION
              a061identifier_len (VAR id : tsp00_KnlIdentifier) : integer;
 
      ------------------------------ 
 
        FROM
              AK_semantic_scanner_tools : VAK05;
 
        PROCEDURE
              a05identifier_get (
                    VAR acv     : tak_all_command_glob;
                    tree_index  : integer;
                    obj_len     : integer;
                    VAR moveobj : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              Scanner : VAK01;
 
        VAR
              a01defaultkey        : tgg00_SysInfoKey;
              a01_il_b_identifier  : tsp00_KnlIdentifier;
 
        PROCEDURE
              a01setl_identifier (
                    VAR id         : tsp00_KnlIdentifier;
                    set_identifier : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_1  : VBD01;
 
        VAR
              b01niltree_id      : tgg00_FileId;
 
        PROCEDURE
              b01get_bad_indexid (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_3 : VBD03;
 
        PROCEDURE
              bd03ResetUsageInfo (
                    VAR Trans       : tgg00_TransContext;
                    VAR FiledId     : tgg00_FileId);
 
        PROCEDURE
              bd03SetToNotAccessible(
                    VAR Trans   : tgg00_TransContext;
                    VAR FiledId : tgg00_FileId );
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01unicode        : boolean;
 
        PROCEDURE
              g01optextmsg (
                    msg_prio  : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C40);
 
      ------------------------------ 
 
        FROM
              Select_Help_Procedures : VGG04;
 
        PROCEDURE
              g04index_tree_build (
                    VAR file_id    : tgg00_FileId;
                    VAR index_tree : tgg00_FileId;
                    index_no       : tsp00_Int2);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    obj_upb     : tsp00_Int4;
                    obj         : tsp00_MoveObjPtr;
                    obj_pos     : tsp00_Int4;
                    length      : tsp00_Int4;
                    fillchar    : char;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalUnicodeFill (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    obj_upb     : tsp00_Int4;
                    obj         : tsp00_MoveObjPtr;
                    obj_pos     : tsp00_Int4;
                    length      : tsp00_Int4;
                    fillchar    : tsp00_C2;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalForcedUnicodeFill (
                    obj_upb     : tsp00_Int4;
                    obj         : tsp00_MoveObjPtr;
                    obj_pos     : tsp00_Int4;
                    length      : tsp00_Int4;
                    fillchar    : tsp00_C2 );
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalOverlappingMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalForcedFill (
                    size        : tsp00_Int4;
                    m           : tsp00_MoveObjPtr;
                    pos         : tsp00_Int4;
                    len         : tsp00_Int4;
                    fillchar    : char);
 
        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);
 
        PROCEDURE
              SAPDB_PascalForcedOverlappingMove (
                    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);
 
        PROCEDURE
              g10mv (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              s10mv (
                    source_upb  : tsp00_Int4;
                    destin_upb  : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    source_pos  : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    destin_pos  : tsp00_Int4;
                    length      : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              GG_edit_routines : VGG17;
 
        PROCEDURE
              g17sname_to_line (
                    n             : tsp00_Sname;
                    VAR ln_len    : integer;
                    VAR ln        : tsp00_Line);
 
        PROCEDURE
              g17trimint4_to_line (
                    int4       : tsp00_Int4;
                    VAR ln_len : integer;
                    VAR ln     : tsp00_Line);
 
        PROCEDURE
              g17int4to_line (
                    int       : tsp00_Int4;
                    with_zero : boolean;
                    int_len   : integer;
                    ln_pos    : integer;
                    VAR ln    : tsp00_KnlIdentifier);
 
.CM *-END-* use -----------------------------------------
***********************************************************
 
Synonym :
 
        PROCEDURE
              a05identifier_get;
 
              tsp00_MoveObj tsp00_KnlIdentifier
 
        PROCEDURE
              g17int4to_line;
 
              tsp00_Line tsp00_KnlIdentifier;
 
.CM *-END-* synonym -------------------------------------
***********************************************************
.sp
.cp 30
.fo
.oc _/1
Specification:
 
PROCEDURE  A24_CALL_SEMANTIC:
.sp 1;.fo
Die Prozedur dient als Verteiler f?ur die verschiedenen Create und
Drop Index Befehle.
Der Name der betroffenen Tabelle sowie der Indexname, falls spezifiziert,
werden in a20v gelesen. Falls bei Drop Index nur der Indexname
spezifiziert ist, wird die zugeh?orige Basistabelle durch
die Prozedur ==> a24_get_tablename bestimmt.
Die Systeminformationen der Tabelle werden in
den Cache geladen und das Ownerprivileg des aktuellen Benutzers wird
gepr?uft. Die Versionsnummer der Basistabelle wird erh?oht.
In Abh?angigkeit vom Auftrag wird eine der folgenden Prozeduren
aufgerufen :
.nf;.sp
     create_multiple_index
     drop_index_by_columnname
     a24drop_multiple_index
.sp;.fo
Die Basis-Systems?atze der Tabelle werden mit aktualisierten
Versionsnummern zur?uckgeschrieben (==> a24_replace_base_records).
Falls der Create Index Auftrag nur geparsed wird, wird der Auftrag
zum creieren des Indexes mit message2_type = mm_parse an KB gesendet,
was dazu f?uhrt, da?z eine leere Indexdatei erstellt wird.
Beim Executen mu?z der Auftrag immer mit ADBS gesendet werden, da
Parse-Execute nicht m?oglich ist.
.sp4
.nf
PROCEDURE  CREATE_INDEX_BY_COLUMNNAME
.sp
.fo
Die Prozedur wird aufgerufen, falls ein Create Index
<Tablename>.<Columnname> abgesetzt wurde.
Die Prozedur create_single_index wird aufgerufen.
.sp4
PROCEDURE  CREATE_SINGLE_INDEX
.sp
Die Spalte, ?uber die ein Index creiert werden soll, wird in a20v
eingelesen (==> get_columnname).
Die Information ?uber den Index wird in der Spaltenbeschreibung
im Basisrecord der Tabelle vermerkt (ecol_tab[ 1 ] = externe Spaltennr).
Eine Beschreibung des Indexes wird in den Systeminformationen
abgelegt. Dabei sind zwei F?alle zu unterscheiden :
.sp
.nf
i)  Der Index ist unbenannt (Index_no = 0)
.sp;.fo
.in +4
Es wird ein Single-Index_Systemsatz mit der Beschreibung des Indexes
in die Systeminformationen eingef?ugt.
.in -4
.nf
.sp
ii) Der Index ist benannt (Index_no > 0)
.sp;.fo
.in +4
Die Bescheibung des Single-Index wird in dem durch a2multbuf
spezifizierten Multi-Index_Record der Tabelle als Index_no-te
Beschreibung abgelegt.
.in -4
.fo;.sp
Der Index wird in allen von der Basistabelle abh?angigen Views
vermerkt (==> repl_index_in_views).
Der Auftrag zum Aufbau des Indexes wird an KB gesendet (==>
a24send_index_command_to_kb).
.sp 4
.cp 9
PROCEDURE  CREATE_MULTIPLE_INDEX :
.sp
Im Multiindex-Systemsatz der Tabelle a2authid.a2tablen wird ein Platz
f?ur die Indexbeschreibung des zu erzeugenden Indexes gesucht, und
die allgemeinen Angaben bzgl. des Indexes werden hier abgelegt.
Die Spaltenbeschreibungen der beteiligten Spalte(n) werden durch
==> create_single_index falls nur eine Spalte beteiligt ist, bzw. durch
==> column_to_multi_index falls mehrere Spalten beteiligt sind,
in den Multi-index-Systemsatz geschrieben.
In den Stackentries der beteiligten Spalten werden folgende
Beschreibungen abgelegt :
.sp;.nf
    etype         : Columnbeschreibung
    eop           : Operator asc, desc, unique
    elen_var      : Lnge der Spalte (inoutlen)
    ecol_tab[ 1 ] : Indexnr. der Invertierung
.sp;.fo
Falls der multiple Index aus mehr als 1 Spalte besteht,
wird er durch ==> a24view_repl_col_info in den von a2authid.tablen
abh?angigen Views vermerkt und der Auftrag zum Aufbau des Indexes
wird an KB gesendet.
.sp 4
.cp 10
PROCEDURE A24_GET_TABLE
.sp;.fo
Die Prozedur pr?uft, ob der durch a2indexn spezifizierte Indexname
unter allen Tabellen, auf die der aktuelle Benutzer Zugriff hat,
eindeutig ist, bzw. ob ?uberhaupt ein Index dieses Names existiert.
.br;.nf
1. Indexname ist nicht eindeutig
   ==> Fehlermeldung Indexname must be unique
2. Indexname existiert nicht
   ==> Fehlermeldung unknown Indexname
.sp 3
.cp 4
FUNCTION INDEXNAME_EXIST
.sp;.fo
Die Prozedur liefert den Wert True, falls die Tabelle authid.tablen
den Index mit Namen a2indexn besitzt, sonst false.
.sp 3
.cp 12
PROCEDURE  DROP_INDEX_BY_COLUMNNAME
.sp
Die Prozedur wird aufgerufen, wenn ein Auftrag der Form
drop index <Tablename>.<Columnname> bearbeitet wird.
Die betroffene Spalte wird durch ==> get_columnname in a20v
eingelesen. Das L?oschen des Indexes geschieht durch
==> drop_single_index.
.sp 4
PROCEDURE DROP_SINGLE_INDEX
.sp
Der Single-Index der durch a2colbuf und a2colind spezifizierten
Spalte wird gel?oscht (==> a24send_index_command_to_kb).
Im ccolpropset der Spalte wird der Indexindikator gel?oscht.
In allen Views, die die Spalte enthalten, werden die Indexinformationen
durch Aufruf von (==> a24_view_repl) gel?oscht.
Falls der Index in der Form tablen.columname gel?oscht wurde, wird
zun?achst versucht, den Single-Index-Systemsatz des Indexes aus den
Systeminformationen zu l?oschen (unbenannter Single-Index). Falls
dieser nicht existiert, handelt es sich um einen benannten
Single-Index, der aus dem Multi-Index-Systemsatz gel?oscht wird
(==> search_single_multi, ==> del_index_from_multbuf).
.sp 4
.cp 13
.sp 4
PROCEDURE A24DROP_MULTIPLE_INDEX
.sp
In den Multi-Index-Systeminformationen der Basistabelle wird der
zu l?oschende Indexname gesucht.
Falls der Index nur aus einer Spalte besteht (benannter Single-Index),
wird er durch ==> drop_single_index gel?oscht.
Andernfalls wird der ctmulti - Eintrag in den betroffenen
Spaltendefinitionen in den Basisrecords und in allen
betroffenen Views gel?oscht (==> a24view_repl_col_info).
Der Index wird im Multi-Index-Systemsatz gel?oscht (==>
del_index_from_multbuf).
.sp 4
.cp 8
PROCEDURE  A24_GET_FIRST_SYSINFO:
.sp
Pr?uft, ob der Systemsatz schon existiert. Wenn dies der Fall ist,
wird die Fehlermeldung duplicate_name ausgegeben.
Andernfalls wird, wenn syslen <> 0 ist, im Cache Platz
gesucht und die Bufferaddresse an syspoint zur?uckgegeben.
.sp 4
.cp 7
.br
Existiert der Satz noch nicht, wird Platz im Cache
von der L?ange syslen reserviert und new wird auf true
gesetzt.
.br
Ist syslen = 0 angegeben, so wird nur new auf true
gesetzt. Syspoint ist dann nicht belegt.
.sp 4
.cp 9
PROCEDURE  VIEW_REPL_INDEX:
.sp
Alle Views, die von der Basistabelle, auf der der Index
creiert bzw. gel?oscht wurde, abh?angig sind, werden untersucht,
ob sie auf die invertierte(n) Spalte(n) zugreifen.
Dies gilt sowohl f?ur den Fall, da?z die Spalte durch die
Selectliste betroffen wird als auch f?ur den Fall, da?z sie
nur in der Qualifikation vorkommt.
.br
.cp 8
Falls die Spalten in der Selectliste vorkommen, m?ussen in
den entsprechenden Spaltenbeschreibungen der View die
Indexinformationen vermerkt werden.
Falls die Spalte eines Singleindexes in der Qualifikation
der View vorkommt, mu?z in den entsprechenden Stackentries
in ecol_tab(1) die externe Spaltennummer bei Create bzw.
0 bei Drop Index eingetragen werden.
.cp 9
Zur Untersuchung der Spalten wird ein Record tiviewrepl
bei der Indexabarbeitung belegt, in dem Informationen
zur ?Anderung der Spaltenbeschreibung stehen.
.nf;.sp
tiviewrepl = RECORD
  ivrcount : Anzahl der zu?andernden Spalten
  ivrtabno : Tabellennummer der zugeh?origen Basistabelle
  ivsingle : True bei Single-Indexen, sonst false
  irvinfo  : Informatonen der Spalte
.cp 12
.sp
je Spalte steht in ivrinfo
.sp
  ivmode := ivcreate  ein Index f?ur diese Spalte wurde
                      creiert (single oder multi)
          = ivsingledrop ein Singleindex dieser Spalte
                      wurde gel?oscht
          = ivmultidrop ein Multiplerindex dieser Spalte
                      wurde gel?oscht
  ivcolind : index im ivcolbuf der bcolumn Spaltenbeschreibung
  ivcolbuf : tsysbufferaddress des Basis-Systemsatzes, indem die
             Spaltenbeschreibung in bcolumn[ ivcolind ] liegt.
.sp
.fo
Das Auffinden der von der Basistabelle abh?angigen Views
erfolgt nach dem
gleichen Mechanismus wie bei drop table (a11drop_table).
.sp 4
.cp 5
PROCEDURE  GET_MULTBUF
.sp
Der Multi-Index-Systemsatz wird in den Cache geladen.
(a2multbuf ist Pointer auf diesen Satz).
.sp 4
.cp 10
PROCEDURE  DEL_INDEX_FROM_MULTBUF
.sp
Die Index-te Indexbeschreibung wird auf dem durch a2multbuf referierten
Multi-Index-Systemsatz gel?oscht. Falls der Systemsatz mehr als
eine Beschreibung enth?alt, geschieht dies dadurch, da?z die Index-te
Beschreibung durch die letzte ersetzt wird.
Andernfalls wird der Systemsatz gel?oscht.
.sp 4
.cp 8
PROCEDURE  SEND_INDEX_COMMAND_TO_KB
.sp
Die Prozedur wird benutzt, um KB den Auftrag zum Aufbau bzw. L?oschen
eines Indexes zu senden. Falls der Befehl beim Create Index nur
geparsed wird, wird der Message2_Type auf mm_parse gesetzt, was
zur Folge hat, da?z eine leere Indexdatei aufgebaut wird.
Die Beschreibungen der beteiligten Spalten werden in Part1 abgelegt.
.sp 4
.cp 8
PROCEDURE  GET_COLUMNNAME
.sp
Die Prozedur liest den Spaltennamen aus dem Auftragssegment in a2coln,
pr?uft, ob sie existiert und einen zul?assigen Datentyp besitzt und
aktualisiert die Sysusagetabelle. Ferner wird die Sortiereigenschaft
der Spalte in a2op_order vermerkt.
.sp 4
.cp 6
PROCEDURE  A24_REPLACE_BASE_RECORDS
.sp
Die Basis-Systems?atze der Tabelle a2authid.a2tablen werden mit den
aktualisierten Versionsnummern in die Systeminformationen
zur?uckgeschrieben.
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      c_user_def_name           = true;
      c_do_a38_input            = true;
      c_user_create_index       = true;
      c_is_rollback             = true;
      c_unnamed_index_migration = true;
 
 
(*------------------------------*) 
 
PROCEDURE
      a24find_indexname (
            VAR acv            : tak_all_command_glob;
            VAR tabid          : tgg00_Surrogate;
            VAR indexname      : tsp00_KnlIdentifier;
            VAR index_scan_rec : tak_index_scan_record);
 
VAR
      exit_loop      : boolean;
      curr_indexname : tsp00_KnlIdentifier;
 
BEGIN
(* searches for the index 'indexname' on the table identified by *)
(* tabid. If found isr_buf^.smindex.indexdef[isr_index] contains *)
(* the required index definition.                                *)
(* If not found isr_buf is nil and isr_index = 0                 *)
a24init_index_scan( acv, tabid, index_scan_rec );
exit_loop := false;
REPEAT
    IF  ( a24next_named_index (acv, index_scan_rec) )
    THEN
        BEGIN
        a24get_indexname( acv, index_scan_rec.isr_buf,
              index_scan_rec.isr_index, curr_indexname );
        IF  ( curr_indexname = indexname )
        THEN (* indexname found *)
            exit_loop := true
        (*ENDIF*) 
        END
    ELSE
        BEGIN (* indexname not found *)
        index_scan_rec.isr_buf   := NIL;
        index_scan_rec.isr_index := 0;
        exit_loop                := true
        END;
    (*ENDIF*) 
UNTIL
    exit_loop;
(*ENDREPEAT*) 
a24finish_index_scan( acv, index_scan_rec );
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24fnd_indexno (
            VAR acv            : tak_all_command_glob;
            VAR tabid          : tgg00_Surrogate;
            indexno            : integer;
            VAR index_scan_rec : tak_index_scan_record);
 
VAR
      exit_loop : boolean;
 
BEGIN
(* searches for the index identified by indexno on           *)
(* the table identified by tabid.                            *)
(* If found isr_buf^.smindex.indexdef[isr_index] contains    *)
(* the required index definition.                            *)
(* If not found isr_buf is nil and isr_index = 0             *)
a24init_index_scan (acv, tabid, index_scan_rec);
exit_loop := false;
WITH index_scan_rec DO
    REPEAT
        IF  a24next_named_index (acv, index_scan_rec)
        THEN
            BEGIN
            IF  isr_buf^.smindex.indexdef[isr_index].indexno = indexno
            THEN (* indexno found *)
                exit_loop := true
            (*ENDIF*) 
            END
        ELSE
            BEGIN (* indexno not found *)
            isr_buf   := NIL;
            isr_index := 0;
            exit_loop := true
            END;
        (*ENDIF*) 
    UNTIL
        exit_loop;
    (*ENDREPEAT*) 
(*ENDWITH*) 
a24finish_index_scan (acv, index_scan_rec)
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24get_indexname (
            VAR acv        : tak_all_command_glob;
            indexbuf       : tak_sysbufferaddress;
            index          : integer;
            VAR index_name : tsp00_KnlIdentifier);
 
VAR
      b_err     : tgg00_BasisError;
      offset    : integer;
      rest_len  : integer;
      len       : integer;
      iname_pos : integer;
      sysk      : tgg00_SysInfoKey;
 
BEGIN
s10mv( sizeof( indexbuf^.smindex.indexdef[ index ].indexn_prefix ),
      sizeof( index_name ),
      @indexbuf^.smindex.indexdef[ index ].indexn_prefix, 1,
      @index_name, 1,
      sizeof( indexbuf^.smindex.indexdef[ index ].indexn_prefix ));
iname_pos := sizeof( indexbuf^.smindex.indexdef[ index ].indexn_prefix ) + 1;
rest_len  := indexbuf^.smindex.indexdef[ index ].isuffixlen;
IF  ( rest_len > 0 )
THEN
    BEGIN
    len := sizeof( indexbuf^.smindex.indexdef[ index ].icolstack ) -
          indexbuf^.smindex.indexdef[ index ].icount *
          sizeof( indexbuf^.smindex.indexdef[ index ].icolstack[ 1 ] );
    IF  ( len > rest_len )
    THEN
        len := rest_len;
    (*ENDIF*) 
    g10mv ('VAK24 ',   1,    
          sizeof( indexbuf^.smindex.indexdef[ index ].icolstack ),
          sizeof( index_name ),
          @indexbuf^.smindex.indexdef[ index ].icolstack,
          indexbuf^.smindex.indexdef[ index ].icount *
          sizeof( indexbuf^.smindex.indexdef[ index ].icolstack[ 1 ] ) + 1,
          @index_name, iname_pos, len, acv.a_returncode);
    iname_pos := iname_pos + len;
    rest_len  := rest_len - len;
    END;
(*ENDIF*) 
IF  ( rest_len > 0 )
THEN
    BEGIN
    sysk               := indexbuf^.syskey;
    sysk.slinkage[ 1 ] := chr( index );
    a10get_sysinfo( acv, sysk, d_release, indexbuf, b_err );
    IF  ( b_err <> e_ok )
    THEN
        a07_b_put_error( acv, b_err, 1 )
    ELSE
        BEGIN
        offset := cgg_rec_key_offset + indexbuf^.syskey.skeylen +
              sizeof( indexbuf^.smindex.isegmentid );
        g10mv ('VAK24 ',   2,    
              sizeof( indexbuf^.smindex ), sizeof( index_name ),
              @indexbuf^.smindex, offset + 1,
              @index_name, iname_pos,
              indexbuf^.b_sl - offset, acv.a_returncode);
        iname_pos := iname_pos + indexbuf^.b_sl - offset;
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
g10mv ('VAK24 ',   3,    
      sizeof( a01_il_b_identifier ), sizeof( index_name ),
      @a01_il_b_identifier, 1, @index_name, iname_pos,
      sizeof( index_name ) - iname_pos + 1, acv.a_returncode);
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24init_index_scan (
            VAR acv            : tak_all_command_glob;
            VAR tabid          : tgg00_Surrogate;
            VAR index_scan_rec : tak_index_scan_record);
 
VAR
      b_err : tgg00_BasisError;
 
BEGIN
index_scan_rec.isr_index          := 0;
index_scan_rec.isr_sysk           := a01defaultkey;
index_scan_rec.isr_sysk.stableid  := tabid;
index_scan_rec.isr_sysk.sentrytyp := cak_emindex;
a10get_sysinfo( acv, index_scan_rec.isr_sysk, d_fix,
      index_scan_rec.isr_buf, b_err );
IF  ( b_err <> e_ok )
THEN
    IF  ( b_err <> e_sysinfo_not_found )
    THEN
        a07_b_put_error( acv, e_old_fileversion, 1 )
    ELSE
        a07_b_put_error( acv, b_err, 1 );
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      a24next_named_index (
            VAR acv            : tak_all_command_glob;
            VAR index_scan_rec : tak_index_scan_record) : boolean;
 
VAR
      b_err : tgg00_BasisError;
 
BEGIN
a24next_named_index := false;
IF  ( index_scan_rec.isr_buf <> NIL ) AND
    ( acv.a_returncode = 0 )
THEN
    BEGIN
    IF  ( index_scan_rec.isr_index = cak_max_index_per_rec )
    THEN
        BEGIN
        (* we need next index container *)
        a10_rel_sysinfo( acv, index_scan_rec.isr_sysk );
        IF  ( index_scan_rec.isr_buf^.smindex.indexnext )
        THEN
            BEGIN
            a06inc_linkage( index_scan_rec.isr_sysk.slinkage );
            a10get_sysinfo( acv, index_scan_rec.isr_sysk, d_fix,
                  index_scan_rec.isr_buf, b_err );
            IF  ( b_err <> e_ok )
            THEN
                IF  ( b_err = e_sysinfo_not_found )
                THEN
                    a07_b_put_error( acv, e_old_fileversion, 1 )
                ELSE
                    a07_b_put_error( acv, b_err, 1 )
                (*ENDIF*) 
            ELSE
                BEGIN
                index_scan_rec.isr_index := 1;
&               ifdef trace
                ak24trace_index( index_scan_rec.isr_buf^.smindex.indexdef[ 1 ] );
&               endif
                a24next_named_index := true;
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END
    ELSE
        IF  ( index_scan_rec.isr_index <
            index_scan_rec.isr_buf^.smindex.indexcount )
        THEN
            BEGIN
            index_scan_rec.isr_index := succ( index_scan_rec.isr_index );
&           ifdef trace
            ak24trace_index( index_scan_rec.isr_buf^.smindex.
                  indexdef[ index_scan_rec.isr_index ] );
&           endif
            a24next_named_index := true;
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24finish_index_scan (
            VAR acv            : tak_all_command_glob;
            VAR index_scan_rec : tak_index_scan_record);
 
BEGIN
a10_rel_sysinfo( acv, index_scan_rec.isr_sysk );
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24_call_semantic  (
            VAR acv       : tak_all_command_glob;
            ignore_errors : boolean);
 
VAR
      b_err             : tgg00_BasisError;
      err_kw            : integer;
      command_no        : integer;
      aux_ti            : integer;
      ti                : integer;
      index_errpos      : integer;
      dummy_indexno     : tsp00_Int2;
      colptr            : tak00_colinfo_ptr;
      priv              : tak_privilege;
      viewscanpar       : tak_viewscan_par;
 
BEGIN
WITH acv, viewscanpar DO
    IF  a_ap_tree^[ a_ap_tree^[ 0 ].n_lo_level ] .n_subproc = cak_x_recreate_bad_index
    THEN
        (* PTS 1130869 E.Z. *)
        IF  (acv.a_current_user_kind <> usysdba) AND
            (acv.a_current_user_kind <> ucontroluser)
        THEN
            a07_kw_put_error (acv, e_missing_privilege, 1, cak_i_sysdba)
        ELSE
            a24RecreateBadIndexes (acv)
        (*ENDIF*) 
    ELSE
        BEGIN
        err_kw := cak_i_no_keyword;
        a27init_viewscanpar (acv, viewscanpar, v_index);
        a10_cache_delete (acv, NOT c_is_rollback);
        WITH a_ap_tree^[ a_ap_tree^[ 0 ].n_lo_level ] DO
            BEGIN
            vsc_unique  := (n_subproc = cak_x_create_unique_index);
            command_no  := n_subproc;
            ti          := n_lo_level;
            END;
        (*ENDWITH*) 
        vsc_ignore_error  := ignore_errors;
        WITH a_ap_tree^[ti] DO
            BEGIN
            a05identifier_get (acv, ti,
                  sizeof(vsc_indexname), vsc_indexname);
            index_errpos := n_pos;
            aux_ti       := ti;
            ti           := n_sa_level
            END;
        (*ENDWITH*) 
        IF  ti <> 0
        THEN
            BEGIN
            IF  a_ap_tree^[ti].n_symb = s_authid
            THEN
                a06get_username (acv, ti, vsc_baseauthname)
            ELSE
                vsc_baseauthname := a_curr_user_name;
            (*ENDIF*) 
            IF  a_ap_tree^[ti].n_symb = s_tablename
            THEN
                a05identifier_get (acv, ti,
                      sizeof(vsc_basetablen), vsc_basetablen);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  vsc_basetablen = a01_il_b_identifier
        THEN
            BEGIN
            vsc_ti := aux_ti;
            ak24get_tablename (acv, viewscanpar);
            END
        ELSE
            vsc_ti := ti;
        (*ENDIF*) 
        b_err := e_ok;
        IF  a_returncode = 0
        THEN
            IF  NOT  a06_table_exist (acv, d_fix,
                vsc_baseauthname, vsc_basetablen, a_p_arr1, true)
            THEN
                b_err := e_unknown_tablename
            ELSE
                WITH a_p_arr1.pbasep^.sbase DO
                    BEGIN
                    a06_get_priv (acv, a_p_arr1.pbasep, priv);
                    IF  (priv.priv_all_set = [])
                        AND
                        (priv.priv_col_exist = [])
                    THEN
                        b_err := e_unknown_tablename
                    ELSE
                        IF  NOT (r_index in priv.priv_all_set)
                            AND
                            NOT ((ignore_errors)            AND
                            (a_current_user_kind = usysdba))
                        THEN
                            BEGIN
                            err_kw := cak_i_index;
                            b_err := e_missing_privilege
                            END
                        ELSE
                            IF  (btablekind <> twithkey   ) AND
                                (btablekind <> twithoutkey)
                                (* PTS 1111576 E.Z. *)
                            THEN
                                b_err := e_missing_basetable
                            ELSE
                                IF  bunloaded
                                THEN
                                    b_err := e_table_is_unloaded
                                (*ENDIF*) 
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
        (*ENDIF*) 
        IF  b_err <> e_ok
        THEN
            a07_kw_put_error (acv, b_err,
                  a_ap_tree^[ vsc_ti ].n_pos, err_kw);
        (* variables for SP-call: create/drop index *)
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            WITH a_p_arr1.pbasep^, sbase DO
                BEGIN
                WITH bcolumn[blastkeyind]^ DO
                    vsc_keylen := pred(ccolstack.epos + cinoutlen);
                (*ENDWITH*) 
                vsc_base_tabid  := btreeid.fileTabId_gg00;
                vsc_basetablen  := btablen^;
                colptr := NIL;
                CASE command_no OF
                    cak_i_alter :
                        ak24alter_index (acv, viewscanpar, a_ap_tree^[a_ap_tree^[0].n_lo_level ].n_pos);
                    cak_i_rename :
                        (* ADIS change request 1000032 *)
                        ak24rename_index (acv, viewscanpar);
                    OTHERWISE
                        BEGIN
                        vsc_ti  := a_ap_tree^[ vsc_ti ].n_sa_level;
                        IF  command_no = cak_x_drop_index
                        THEN
                            a24drop_multiple_index (acv,
                                  viewscanpar, index_errpos, c_do_a38_input)
                        ELSE
                            ak24CreateIndex (acv, viewscanpar, a_p_arr1,
                                  colptr, colptr,
                                  c_user_def_name, c_user_create_index,
                                  NOT c_unnamed_index_migration, dummy_indexno);
                        (*ENDIF*) 
                        END;
                    END;
                (*ENDCASE*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        ak24replace_base_records (acv, viewscanpar,
              (command_no = cak_i_rename) OR (command_no = cak_i_alter));
        IF  a_returncode <> 0
        THEN
            a_part_rollback := true;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      a24IndexFieldCount (
            VAR index_def : tak_multindex) : integer;
 
BEGIN
IF  index_def.icolstack[1].etype = st_func
THEN
    a24IndexFieldCount := 1
ELSE
    a24IndexFieldCount := index_def.icount;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      a24IsFunctionBasedIndex(VAR index_def : tak_multindex) : boolean;
 
BEGIN
a24IsFunctionBasedIndex := index_def.icolstack[1].etype = st_func;
END;
 
(*------------------------------*) 
 
FUNCTION
      a24IndexMatch (
            VAR acv        : tak_all_command_glob;
            VAR index_def  : tak_multindex;
            stackStart     : integer;
            stackEnd       : integer) : boolean;
 
VAR
      indexMatch  : boolean;
      checkResult : boolean;
      stackIndex  : integer;
 
BEGIN
indexMatch := false;
&ifdef trace
FOR stackIndex := stackStart TO stackEnd DO
    t01stackentry (ak_strat, acv.a_mblock.mb_st^[stackIndex], stackIndex);
(*ENDFOR*) 
&endif
IF  index_def.icolstack[1].etype = st_func
THEN
    BEGIN
    indexMatch  := true;
    checkResult := false;
    stackIndex  := stackStart;
    WHILE indexMatch AND (stackIndex < stackEnd) DO
        BEGIN
        CASE acv.a_mblock.mb_st^[stackIndex  ].etype OF
            st_fixkey, st_fixcol, st_varkey, st_varcol, st_varlongchar :
                IF  checkResult
                THEN
                    indexMatch := false
                ELSE
                    IF  (stackIndex + 1 < stackEnd) AND
                        (acv.a_mblock.mb_st^[stackIndex+1].etype = st_build_in_func) AND
                        (acv.a_mblock.mb_st^[stackIndex+1].eop_build_in = op_b_uni_trans)
                    THEN
                        stackIndex  := stackIndex + 1;
                    (*ENDIF*) 
                (*ENDIF*) 
            st_result :
                IF  NOT checkResult
                THEN
                    indexMatch := false;
                (*ENDIF*) 
            st_surrogate :
                IF  acv.a_mblock.mb_st^[stackIndex].esurrogate <> index_def.icolstack[2].esurrogate
                THEN
                    indexMatch := false;
                (*ENDIF*) 
            OTHERWISE
                indexMatch := false;
            END;
        (*ENDCASE*) 
        checkResult := NOT checkResult;
        stackIndex  := stackIndex + 1;
        END;
    (*ENDWHILE*) 
    END;
&ifdef trace
(*ENDIF*) 
t01bool (ak_strat, 'indexMatch  ', indexMatch);
&endif
a24IndexMatch := indexMatch;
END;
 
(*------------------------------*) 
 
FUNCTION
      a24LookForFunctionBasedIndex (
            VAR acv        : tak_all_command_glob;
            stackStart     : integer;
            stackEnd       : integer;
            VAR stackNext  : integer) : boolean;
 
VAR
      idx          : integer;
      stackIndex   : integer;
      indexMatch   : boolean;
      isColumn     : boolean;
      functionId   : tgg00_StackEntry;
      IndexScanRec : tak_index_scan_record;
 
BEGIN
indexMatch := true;
&ifdef trace
FOR stackIndex := stackStart TO stackEnd DO
    t01stackentry (ak_strat, acv.a_mblock.mb_st^[stackIndex], stackIndex);
(*ENDFOR*) 
&endif
stackIndex := stackStart;
WHILE stackIndex < stackEnd DO
    BEGIN
    isColumn := acv.a_mblock.mb_st^[stackIndex].etype in
          [st_fixkey, st_fixcol, st_varkey, st_varcol, st_varlongchar];
    IF  isColumn AND (acv.a_mblock.mb_st^[stackIndex+1].etype = st_result)
    THEN
        stackIndex := stackIndex + 2
    ELSE
        IF  isColumn AND
            (acv.a_mblock.mb_st^[stackIndex+1].etype        = st_build_in_func) AND
            (acv.a_mblock.mb_st^[stackIndex+1].eop_build_in = op_b_uni_trans) AND
            (acv.a_mblock.mb_st^[stackIndex+2].etype        = st_result)
        THEN
            stackIndex := stackIndex + 3
        ELSE
            IF  acv.a_mblock.mb_st^[stackIndex].etype = st_surrogate
            THEN
                BEGIN
                stackEnd   := stackIndex;
                functionId := acv.a_mblock.mb_st^[stackIndex];
                stackNext  := stackIndex + 2;
                END
            ELSE
                BEGIN
                indexMatch := false;
                stackEnd   := stackIndex; (* exit loop *)
                END;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
&ifdef trace
t01bool (ak_strat, 'func call   ', indexMatch);
&endif
IF  indexMatch
THEN
    BEGIN
    indexMatch := false;
    a24init_index_scan (acv, acv.a_mblock.mb_qual^.mtree.fileTabId_gg00, IndexScanRec);
    WHILE NOT indexMatch AND a24next_named_index (acv, IndexScanRec) DO
        WITH IndexScanRec, isr_buf^.smindex.indexdef[isr_index] DO
            BEGIN
            IF  (icolstack[1].etype = st_func) AND (icolstack[2].esurrogate = functionId.esurrogate)
            THEN
                BEGIN
                stackIndex := stackStart;
                indexMatch := true;
                idx        := 3; (* skip st_func and function id *)
                WHILE stackIndex < stackEnd DO
                    BEGIN
                    IF  (acv.a_mblock.mb_st^[stackIndex].etype    <> icolstack[idx].etype   ) OR
                        (acv.a_mblock.mb_st^[stackIndex].epos     <> icolstack[idx].epos    ) OR
                        (acv.a_mblock.mb_st^[stackIndex].elen_var <> icolstack[idx].elen_var)
                    THEN
                        BEGIN (* index does not match, try next one *)
                        indexMatch := false;
                        stackIndex := stackEnd;
                        END;
                    (*ENDIF*) 
                    idx := idx + 1;
                    IF  acv.a_mblock.mb_st^[stackIndex+1].etype = st_build_in_func
                    THEN
                        stackIndex := stackIndex + 3
                    ELSE
                        stackIndex := stackIndex + 2;
                    (*ENDIF*) 
                    END;
                (*ENDWHILE*) 
                IF  indexMatch
                THEN
                    IF  stackIndex <> stackEnd
                    THEN
                        indexMatch := false
                    ELSE (* set index flag for optimizer *)
                        acv.a_mblock.mb_st^[stackEnd+1].ecol_tab[2] := chr(101);
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDWHILE*) 
    a24finish_index_scan (acv, IndexScanRec);
    END;
&ifdef trace
(*ENDIF*) 
t01bool (ak_strat, 'index found ', indexMatch);
&endif
a24LookForFunctionBasedIndex := indexMatch;
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24MigrateUnnamedIndex (
            VAR acv  : tak_all_command_glob;
            pBase    : tak_sysbufferaddress;
            opType   : tgg00_StackOpType;
            colptr   : tak00_colinfo_ptr);
 
VAR
      dummy_indexno    : tsp00_Int2;
      base_owner       : tsp00_KnlIdentifier;
      viewscanpar      : tak_viewscan_par;
 
BEGIN
a27init_viewscanpar (acv, viewscanpar, v_index);
acv.a_p_arr1.pbasep := pBase;
viewscanpar.vsc_op_order := opType;
a06determine_username (acv,
      pBase^.sbase.bauthid, base_owner);
viewscanpar.vsc_baseauthname  := base_owner;
viewscanpar.vsc_basetablen    := pBase^.sbase.btablen^;
viewscanpar.vsc_unique        := opType in [op_unique, op_unique_desc];
acv.a_is_ddl                  := ddl_create_index;
acv.a_init_ddl                := ddl_create_index;
ak24CreateIndex (acv, viewscanpar, acv.a_p_arr1,
      colptr, colptr,
      false, c_user_create_index,
      c_unnamed_index_migration, dummy_indexno);
acv.a_is_ddl   := no_ddl;
acv.a_init_ddl := no_ddl;
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24unique_spec (
            VAR acv         : tak_all_command_glob;
            unique_node     : integer);
 
VAR
      user_def_name    : boolean;
      count            : integer;
      curr_unique_node : integer;
      dummy_indexno    : tsp00_Int2;
      colptr           : tak00_colinfo_ptr;
      indexname        : tsp00_KnlIdentifier;
      base_owner       : tsp00_KnlIdentifier;
      viewscanpar      : tak_viewscan_par;
 
BEGIN
WITH acv, viewscanpar DO
    BEGIN
    curr_unique_node := unique_node;
    a06determine_username (acv,
          a_p_arr1.pbasep^.sbase.bauthid, base_owner);
    count     := 0;
&   ifdef trace
    t01int4 (ak_sem, 'unique_node ', curr_unique_node);
&   endif
    REPEAT
        IF  a_ap_tree^[ curr_unique_node ].n_symb in [s_index, s_rowno]
        THEN
            BEGIN
            a27init_viewscanpar (acv, viewscanpar, v_index);
            vsc_op_order      := op_unique;
            vsc_baseauthname  := base_owner;
            vsc_basetablen    := a_p_arr1.pbasep^.sbase.btablen^;
            vsc_unique        :=
                  a_ap_tree^[curr_unique_node].n_subproc = cak_i_unique;
            vsc_ti     := a_ap_tree^[curr_unique_node].n_sa_level;
            IF  a_ap_tree^[vsc_ti].n_symb = s_reference_name
            THEN
                BEGIN
                (* user defined name *)
                user_def_name := true;
                a05identifier_get (acv, vsc_ti,
                      sizeof(indexname), indexname);
                vsc_ti := a_ap_tree^[vsc_ti].n_sa_level
                END
            ELSE
                IF  a_ap_tree^[curr_unique_node].n_symb  = s_index
                THEN
                    BEGIN
                    a061assign_colname ('INDEX             ',
                          indexname);
                    user_def_name := false
                    END
                ELSE
                    BEGIN
                    a061assign_colname ('PRIMARY KEY       ',
                          indexname);
                    user_def_name := true
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            vsc_indexname := indexname;
            IF  NOT user_def_name
            THEN
                BEGIN
                count := count + 1;
                g17int4to_line (count, true, 3, 6, vsc_indexname);
                IF  g01unicode
                THEN
                    a01setl_identifier (vsc_indexname, vsc_indexname)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            colptr := NIL;
            ak24CreateIndex (acv, viewscanpar, a_p_arr1,
                  colptr, colptr,
                  user_def_name, c_user_create_index,
                  NOT c_unnamed_index_migration, dummy_indexno)
            END;
        (*ENDIF*) 
        curr_unique_node := a_ap_tree^[curr_unique_node].n_lo_level;
    UNTIL
        (curr_unique_node = 0) OR (a_returncode <> 0);
    (*ENDREPEAT*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24check_duplicate_index (
            VAR acv           : tak_all_command_glob;
            check_all_columns : boolean;
            VAR same_index    : boolean);
 
VAR
      exit_loop      : boolean;
      col_count      : integer;
      j              : integer;
      key_index      : integer;
      index_scan_rec : tak_index_scan_record;
 
BEGIN
WITH acv, a_ptr1^.smindex, indexdef[indexcount], index_scan_rec DO
    BEGIN
    same_index := false;
    IF  icount = a_p_arr1.pbasep^.sbase.bkeycolcount
    THEN
        BEGIN
        (* check, if index definition agrees with key definiton *)
        (* ==> error, except in sqlmode oracle                  *)
        key_index  := a_p_arr1.pbasep^.sbase.bfirstcolind;
        same_index := true;
        j := 1;
        WHILE j <= icount DO
            IF  (icolseq[ j ] <> a_p_arr1.pbasep^.
                sbase.bcolumn[ key_index ]^.cextcolno) OR
                (icolstack[ j ].eop = op_order_desc ) OR
                (icolstack[ j ].eop = op_unique_desc)
            THEN
                BEGIN
                j          := icount + 1;
                same_index := false
                END
            ELSE
                BEGIN
                key_index :=
                      a_p_arr1.pbasep^.sbase.bcolumn[key_index]^.cnextind;
                j         := j + 1;
                END;
            (*ENDIF*) 
        (*ENDWHILE*) 
        END;
    (*ENDIF*) 
    a24init_index_scan (acv, a_p_arr1.pbasep^.syskey.stableid,
          index_scan_rec);
    WHILE a24next_named_index (acv, index_scan_rec) AND
          NOT same_index DO
        BEGIN
        (* check, if new index agrees with curr index ==> error *)
        IF  check_all_columns
        THEN
            BEGIN
            exit_loop := false;
            col_count := 0;
            REPEAT
                IF  col_count = MAX_COL_SEQUENCE_GG00
                THEN
                    exit_loop := true
                ELSE
                    IF  isr_buf^.smindex.
                        indexdef[isr_index].icolseq[col_count + 1] > 0
                    THEN
                        col_count := col_count + 1
                    ELSE
                        exit_loop := true;
                    (*ENDIF*) 
                (*ENDIF*) 
            UNTIL
                exit_loop;
            (*ENDREPEAT*) 
            END
        ELSE
            col_count := isr_buf^.smindex.indexdef[isr_index].icount;
        (*ENDIF*) 
        IF  (icount = col_count) AND
            ((isr_buf <> a_ptr1) OR (isr_index <> indexcount))
        THEN
            BEGIN
            same_index := true;
            FOR j := 1 TO icount DO
                IF  (icolseq[ j ] <> isr_buf^.smindex.
                    indexdef[ isr_index ].icolseq[ j ]) OR
                    (icolstack[ j ].eop <> isr_buf^.smindex.
                    indexdef[ isr_index ].icolstack[ j ].eop)
                THEN
                    same_index := false;
                (*ENDIF*) 
            (*ENDFOR*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24CreateIndex (
            VAR acv               : tak_all_command_glob;
            VAR viewscanpar       : tak_viewscan_par;
            VAR p_arr             : tak_syspointerarr;
            old_colptr            : tak00_colinfo_ptr;
            new_colptr            : tak00_colinfo_ptr;
            user_def_name         : boolean;
            user_create_index     : boolean;
            unnamedIndexMigration : boolean;
            VAR new_indexno       : tsp00_Int2);
 
CONST
      c_add                 = true;
      c_commit              = true;
      c_check_all_columns   = true;
 
VAR
      new_sysinfo  : boolean;
      dupl_index   : boolean;
      b_err        : tgg00_BasisError;
      ix           : integer;
      j            : integer;
      len          : integer;
      ti           : integer;
      val          : integer;
      allindex     : integer;                         (* h.b. PTS 1107564 *)
      sysk         : tgg00_SysInfoKey;
      curr_indexn  : tsp00_KnlIdentifier;
      indexnoset   : SET OF 1..MAX_INV_PER_TAB_GG00;  (* h.b. PTS 1107564 *)
      name_set     : SET OF 0..MAX_INV_PER_TAB_GG00 ; (* PTS 1124453 E.Z. *)
 
BEGIN
WITH acv, viewscanpar DO
    BEGIN
    IF  (a_returncode = 0)
    THEN
        BEGIN
        allindex       := 0; (* h.b. PTS 1107564 *)
        indexnoset     := [  ];
        new_indexno    := 0;
        ix             := cak_is_undefined;
        (* get mindex record *)
        name_set       := [];
        sysk           := a_p_arr1.pbasep^.syskey;
        sysk.sentrytyp := cak_emindex;
        REPEAT
            a10_fix_len_get_sysinfo (acv, sysk, d_fix,
                  sizeof(tak_mindexrecord), mxak_multindex, a_ptr1, b_err);
            IF  a_returncode = 0
            THEN
                WITH  a_ptr1^, smindex DO
                    BEGIN
                    IF  b_err = e_sysinfo_not_found
                    THEN (* mindex record created *)
                        BEGIN
                        new_sysinfo:= true;
                        b_sl       := cak_sysbufferoffset + 4;
                        indexcount := 0;
                        indexnext  := false;
                        isegmentid := p_arr.pbasep^.sbase.bsegmentid;
                        END
                    ELSE
                        new_sysinfo := false;
                    (*ENDIF*) 
                    FOR j := 1 TO indexcount DO
                        WITH indexdef[ j ] DO
                            BEGIN
                            (* h.b. PTS 1107564 *)
                            allindex   := succ(allindex);
                            indexnoset := indexnoset + [ indexno ];
                            a24get_indexname (acv, a_ptr1, j,
                                  curr_indexn);
                            IF  curr_indexn = vsc_indexname
                            THEN
                                a07_b_put_error (acv,
                                      e_duplicate_indexname, 1)
                            ELSE
                                IF  (vsc_indexname = a01_il_b_identifier) AND
                                    (
                                    NOT g01unicode AND
                                    (indexn_prefix[1]  = 'I')            AND
                                    (indexn_prefix[2]  = 'N')            AND
                                    (indexn_prefix[3]  = 'D')            AND
                                    (indexn_prefix[4]  = 'E')            AND
                                    (indexn_prefix[5]  = 'X')            AND
                                    (indexn_prefix[6]  in ['0'..'9'])    AND
                                    (indexn_prefix[7]  in ['0'..'9'])    AND
                                    (indexn_prefix[8]  in ['0'..'9'])
                                    )
                                    OR
                                    (
                                    g01unicode AND
                                    (indexn_prefix[ 1]  = csp_unicode_mark) AND
                                    (indexn_prefix[ 2]  = 'I')              AND
                                    (indexn_prefix[ 3]  = csp_unicode_mark) AND
                                    (indexn_prefix[ 4]  = 'N')              AND
                                    (indexn_prefix[ 5]  = csp_unicode_mark) AND
                                    (indexn_prefix[ 6]  = 'D')              AND
                                    (indexn_prefix[ 7]  = csp_unicode_mark) AND
                                    (indexn_prefix[ 8]  = 'E')              AND
                                    (indexn_prefix[ 9]  = csp_unicode_mark) AND
                                    (indexn_prefix[10]  = 'X')              AND
                                    (indexn_prefix[11]  = csp_unicode_mark) AND
                                    (indexn_prefix[12]  in ['0'..'9'])      AND
                                    (indexn_prefix[13]  = csp_unicode_mark) AND
                                    (indexn_prefix[14]  in ['0'..'9'])      AND
                                    (indexn_prefix[15]  = csp_unicode_mark) AND
                                    (indexn_prefix[16]  in ['0'..'9'])
                                    )
                                THEN
                                    BEGIN
                                    IF  NOT g01unicode
                                    THEN
                                        val := (ord(indexn_prefix[6]) - ord('0')) * 100 +
                                              (ord(indexn_prefix[7]) - ord('0')) * 10 +
                                              (ord(indexn_prefix[8]) - ord('0'))
                                    ELSE
                                        val := (ord(indexn_prefix[12]) - ord('0')) * 100 +
                                              (ord(indexn_prefix[14]) - ord('0')) * 10 +
                                              (ord(indexn_prefix[16]) - ord('0'));
                                    (*ENDIF*) 
                                    IF  val < 255
                                    THEN
                                        name_set := name_set + [val];
                                    (*ENDIF*) 
                                    END;
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END;
                        (*ENDWITH*) 
                    (*ENDFOR*) 
                    IF  allindex >= MAX_INV_PER_TAB_GG00 (* h.b. PTS 1107564 *)
                    THEN
                        a07_b_put_error (acv, e_too_many_indices, 1)
                    ELSE
                        BEGIN
                        IF  indexcount < cak_max_index_per_rec
                        THEN
                            BEGIN
                            (* place for new index found *)
                            b_sl       := b_sl + mxak_multindex;
                            indexcount := indexcount + 1;
                            ix         := indexcount
                            END
                        ELSE
                            IF  cak_max_index_per_rec * ord (sysk.slinkage[2]) >=
                                MAX_INV_PER_TAB_GG00
                            THEN
                                a07_b_put_error (acv, e_too_many_indices, 1)
                            ELSE
                                BEGIN
                                a10_rel_sysinfo (acv, sysk);
                                IF  NOT indexnext
                                THEN
                                    BEGIN
                                    indexnext := true;
                                    a10_add_repl_sysinfo (acv,
                                          a_ptr1, false, b_err);
                                    IF  b_err <> e_ok
                                    THEN
                                        a07_b_put_error (acv, b_err, 1)
                                    (*ENDIF*) 
                                    END;
                                (*ENDIF*) 
                                a06inc_linkage (sysk.slinkage);
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
        UNTIL
            (ix <> cak_is_undefined) OR (a_returncode <> 0);
        (*ENDREPEAT*) 
        (* ix = index of indexdef in multindex record *)
        IF  a_returncode = 0
        THEN
            WITH a_ptr1^, smindex, indexdef [ ix ] DO
                BEGIN
                IF  vsc_indexname = a01_il_b_identifier
                THEN
                    BEGIN
                    a061assign_colname ('INDEX             ',
                          vsc_indexname);
                    val := 1;
                    WHILE val in name_set DO
                        val := val + 1;
                    (*ENDWHILE*) 
                    g17int4to_line (val, true, 3, 6, vsc_indexname);
                    IF  g01unicode
                    THEN
                        a01setl_identifier (vsc_indexname, vsc_indexname)
                    (*ENDIF*) 
                    END;
                (* initialize new index description *)
                (*ENDIF*) 
                indexno    := 0;
                REPEAT
                    indexno := succ(indexno);
                UNTIL
                    NOT (indexno in indexnoset);
                (*ENDREPEAT*) 
                new_indexno := indexno;
                icount    := 0;
                a11put_date_time (idatecre, itimecre);
                FOR j := 1 TO MAX_COL_SEQUENCE_GG00 DO
                    icolseq [ j ] := 0;
                (*ENDFOR*) 
                ipages              := 0;
                ifiller             := false;
                ifiller1            := false; (* PTS 1114312 *)
                idisabled           := false;
                icomment            := false;
                irows               := cak_initrows;
                iinvl               := cak_initinvlist;
                (* PTS 1113579 E.Z. *)
                ti := -1;
                IF  user_create_index
                THEN
                    BEGIN
                    iunique             := vsc_unique;
                    vsc_index_col_count := 0;
                    vsc_mode            := cmd_create_index;
                    IF  unnamedIndexMigration
                    THEN
                        BEGIN
                        new_colptr^.ccolpropset   := new_colptr^.ccolpropset + [ ctmulti ];
                        vsc_index_col_count       := 1;
                        vsc_col_info[1]           := new_colptr;
                        icount                    := 1;
                        icolseq   [1]             := new_colptr^.cextcolno;
                        icolstack [1]             := new_colptr^.ccolstack;
                        icolstack [1].eop         := vsc_op_order;
                        icolstack [1].ecol_tab[1] := chr (indexno);
                        END
                    ELSE
                        BEGIN
                        vsc_tabno           := 1;
                        len                 := 0;
                        ti                  := vsc_ti;
                        REPEAT
                            IF  acv.a_ap_tree^[vsc_ti].n_symb = s_user_func
                            THEN
                                ak24FunctionBasedIndex (acv, viewscanpar, indexdef[ ix ], len)
                            ELSE
                                ak24column_to_index (acv, viewscanpar,
                                      indexdef[ ix ], len);
                            (*ENDIF*) 
                        UNTIL
                            (vsc_ti = 0) OR (a_returncode <> 0);
                        (*ENDREPEAT*) 
                        END;
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    icount        := 1;
                    icolseq[1]    := new_colptr^.cextcolno;
                    iunique       := new_colptr^.ccolstack.eop in [op_unique, op_unique_desc];
                    old_colptr^.ccolpropset := old_colptr^.ccolpropset + [ ctmulti ];
                    old_colptr^.ccolstack.ecol_tab[1] := chr(0);
                    new_colptr^.ccolpropset := new_colptr^.ccolpropset + [ ctmulti ];
                    new_colptr^.ccolstack.ecol_tab[1] := chr(0);
                    icolstack[1]  := new_colptr^.ccolstack;
                    END;
                (*ENDIF*) 
                ak24check_duplicate_index (acv,
                      c_check_all_columns, dupl_index);
                IF  dupl_index
                THEN
                    BEGIN
                    IF  (icount = 1) AND (NOT user_def_name)
                    THEN
                        a07_b_put_error (acv, e_column_indexed,
                              a_ap_tree^[ti].n_pos)
                    ELSE
                        a07_nb_put_error (acv, e_column_indexed,
                              a_ap_tree^[ti].n_pos,
                              vsc_indexname)
                    (*ENDIF*) 
                    END
                ELSE
                    ak24assign_indexname (acv, viewscanpar, a_ptr1, ix, vsc_indexname);
                (*ENDIF*) 
                IF  user_create_index
                THEN
                    BEGIN
                    a24send_index_command_to_kb (acv,
                          viewscanpar, ix, m_create_index, mm_nil);
                    indexdef[indexcount].ipages :=
                          a_mblock.mb_data^.mbp_sample.indexnodes;
                    IF  ( icount = 1 )
                    THEN
                        a28table_upd_statistics (acv,
                              cak_is_undefined, cak_is_undefined,
                              a_mblock.mb_data^.mbp_sample.leafnodes,
                              a_mblock.mb_data^.mbp_sample.prim_key_cnt,
                              a_mblock.mb_data^.mbp_sample.sec_key_cnt,
                              icolseq[1], NOT c_add, NOT c_commit)
                    ELSE
                        a28table_upd_statistics (acv,
                              cak_is_undefined, cak_is_undefined,
                              a_mblock.mb_data^.mbp_sample.leafnodes,
                              a_mblock.mb_data^.mbp_sample.prim_key_cnt,
                              cak_is_undefined, cak_is_undefined,
                              NOT c_add, NOT c_commit);
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        a10_add_repl_sysinfo (acv,
              a_ptr1, new_sysinfo, b_err);
        IF  b_err <> e_ok
        THEN
            a07_b_put_error (acv, b_err, 1)
        ELSE
            p_arr.pbasep^.sbase.bindexexist := true;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24column_to_index (
            VAR acv          : tak_all_command_glob;
            VAR viewscanpar  : tak_viewscan_par;
            VAR multindexdef : tak_multindex;
            VAR len          : integer);
 
VAR
      i        : integer;
      errorpos : integer;
 
BEGIN
WITH acv, viewscanpar DO
    BEGIN
    ak24get_columnname (acv, viewscanpar, errorpos);
    IF  a_returncode = 0
    THEN
        WITH vsc_col_ptr^, multindexdef DO
            BEGIN
            IF  icount < MAX_COL_SEQUENCE_GG00
            THEN
                BEGIN
                FOR i := 1 TO icount DO
                    IF  cextcolno = icolseq [ i ]
                    THEN
                        a07_b_put_error (acv,
                              e_duplicate_columnname, errorpos);
                    (*ENDIF*) 
                (*ENDFOR*) 
                END
            ELSE
                a07_b_put_error (acv, e_too_many_columns, errorpos);
            (*ENDIF*) 
            IF  a_returncode = 0
            THEN
                BEGIN
                ccolpropset := ccolpropset + [ ctmulti  ];
                vsc_index_col_count := succ(vsc_index_col_count);
                vsc_col_info[vsc_index_col_count]  := vsc_col_ptr;
                icount                             := succ(icount);
                icolseq   [ icount ]               := cextcolno;
                icolstack [ icount ]               := ccolstack;
                icolstack [ icount ].eop           := vsc_op_order;
                icolstack [ icount ].ecol_tab[ 1 ] := chr (indexno);
                len := len + cinoutlen;
                IF  len > mxsp_key
                THEN
                    a07_b_put_error (acv, e_too_long_key, errorpos)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24FunctionBasedIndex (
            VAR acv          : tak_all_command_glob;
            VAR viewscanpar  : tak_viewscan_par;
            VAR indexdef     : tak_multindex;
            VAR len          : integer);
 
VAR
      toUnicode       : boolean;
      ix              : integer;
      paramNo         : integer;
      errorPos        : integer;
      outIdx          : integer;
      treeIndex       : integer;
      paramDesc       : tak00_scolinf;
      outParamDesc    : tak00_scolinf;
      pMethod         : tak_sysbufferaddress;
      pEvalDataLength : tak_sysbufferaddress;
      columnName      : tsp00_KnlIdentifier;
      functionName    : tsp00_KnlIdentifier;
      pStackEntry     : ^tgg00_StackEntry;
      constParams     : tak_colinteger;
 
BEGIN
a05identifier_get (acv, viewscanpar.vsc_ti,
      sizeof(functionName), functionName);
IF  a12dbfunc_exist (acv, acv.a_curr_user_name, functionName, d_release, pMethod)
THEN
    IF  pMethod^.smethod.me_sql
    THEN
        a07_b_put_error (acv, e_dbfunc_with_sql_not_allowed, 1)
    ELSE
        BEGIN
        (* no constant parameters for output length evaluation *)
        FOR ix := 1 TO pMethod^.smethod.me_param_cnt DO
            constParams[ix]  := cak_is_undefined;
        (*ENDFOR*) 
        a12output_parameter (acv, pMethod, outIdx, outParamDesc);
        IF  outParamDesc.sci_len = 0
        THEN (* unknown return length, depending on input parameters *)
            pEvalDataLength := a262EvalOutputLenProlog (acv, pMethod^.smethod.me_surrogate)
        ELSE
            pEvalDataLength := NIL;
        (*ENDIF*) 
        indexdef.icount := indexdef.icount + 1;
        indexdef.icolstack[indexdef.icount].etype    := st_func;
        indexdef.icolstack[indexdef.icount].eop_func := op_f_none;
        IF  viewscanpar.vsc_unique
        THEN
            indexdef.icolstack[indexdef.icount].eop := op_unique
        ELSE
            indexdef.icolstack[indexdef.icount].eop := op_order_asc;
        (*ENDIF*) 
        indexdef.icolstack[indexdef.icount].ecol_tab[1] := chr (indexdef.indexno);
        indexdef.icolstack[indexdef.icount].epos        := pMethod^.smethod.me_param_cnt - 1;
        indexdef.icount := indexdef.icount + 1;
        pStackEntry     := @pMethod^.smethod.me_surrogate;
        indexdef.icolstack[indexdef.icount] :=  pStackEntry^;
        paramNo            := 0;
        viewscanpar.vsc_ti := acv.a_ap_tree^[viewscanpar.vsc_ti].n_lo_level;
        WHILE (viewscanpar.vsc_ti <> 0) AND (acv.a_returncode = 0) DO
            BEGIN
            treeIndex := viewscanpar.vsc_ti;
            errorPos   := acv.a_ap_tree^[viewscanpar.vsc_ti].n_pos;
            a05identifier_get (acv, viewscanpar.vsc_ti, sizeof(columnName), columnName);
            IF  NOT (a061exist_columnname (acv.a_p_arr1.pbasep^.sbase,
                columnName, viewscanpar.vsc_col_ptr))
            THEN
                a07_nb_put_error (acv, e_unknown_columnname,
                      errorPos, columnName)
            ELSE
                BEGIN
                paramNo := paramNo + 1;
                IF  paramNo > pMethod^.smethod.me_param_cnt - 1
                THEN
                    a07_b_put_error (acv, e_too_many_variables, errorPos)
                ELSE
                    BEGIN
                    a12describe_param (acv, pMethod, paramNo, paramDesc);
                    toUnicode := (viewscanpar.vsc_col_ptr^.cdatatyp = dcha) AND
                          (paramDesc.sci_typ = dunicode);
                    IF  NOT toUnicode AND
                        (viewscanpar.vsc_col_ptr^.cdatatyp <> paramDesc.sci_typ)
                    THEN
                        a07_b_put_error (acv, e_incompatible_datatypes, errorPos)
                    ELSE
                        BEGIN
                        indexdef.icolseq[paramNo] := viewscanpar.vsc_col_ptr^.cextcolno;
                        indexdef.icount           := indexdef.icount + 1;
                        indexdef.icolstack[indexdef.icount] := viewscanpar.vsc_col_ptr^.ccolstack;
                        IF  paramDesc.sci_iolen = 0
                        THEN (* undefined parameter length *)
                            BEGIN
                            indexdef.icolstack[indexdef.icount].ecol_pos := viewscanpar.vsc_col_ptr^.cinoutlen;
                            IF  pEvalDataLength <> NIL
                            THEN
                                a262SetParameterProperties (acv, pEvalDataLength, paramNo,
                                      viewscanpar.vsc_col_ptr^.cdatatyp, viewscanpar.vsc_col_ptr^.cdatalen,
                                      viewscanpar.vsc_col_ptr^.cinoutlen,
                                      viewscanpar.vsc_col_ptr^.cdatafrac - cak_frac_offset);
                            (*ENDIF*) 
                            END
                        ELSE
                            BEGIN
                            indexdef.icolstack[indexdef.icount].ecol_pos := paramDesc.sci_iolen;
                            IF  pEvalDataLength <> NIL
                            THEN
                                a262SetParameterProperties (acv, pEvalDataLength, paramNo,
                                      viewscanpar.vsc_col_ptr^.cdatatyp, paramDesc.sci_len,
                                      paramDesc.sci_iolen, paramDesc.sci_frac);
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        IF  toUnicode
                        THEN
                            BEGIN
                            indexdef.icolstack[indexdef.icount].eop      := op_dbyte_translate;
                            indexdef.icolstack[indexdef.icount].ecol_pos :=
                                  1 + (indexdef.icolstack[indexdef.icount].ecol_pos - 1) * 2;
                            END;
                        (*ENDIF*) 
                        viewscanpar.vsc_ti := acv.a_ap_tree^[viewscanpar.vsc_ti].n_sa_level;
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        treeIndex := acv.a_ap_tree^[treeIndex].n_lo_level;
        IF  treeIndex <> 0
        THEN
            IF  acv.a_ap_tree^[treeIndex].n_symb = s_desc
            THEN
                IF  viewscanpar.vsc_unique
                THEN
                    indexdef.icolstack[1].eop := op_unique_desc
                ELSE
                    indexdef.icolstack[1].eop := op_order_desc;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        IF  paramNo < pMethod^.smethod.me_param_cnt - 1
        THEN
            a07_b_put_error (acv, e_too_few_values, errorPos);
        (*ENDIF*) 
        IF  pEvalDataLength <> NIL
        THEN
            a262CalcOutputLen (acv, pMethod^.smethod, pEvalDataLength, constParams,
                  outParamDesc.sci_len, outParamDesc.sci_iolen, outParamDesc.sci_frac);
        (*ENDIF*) 
        indexdef.icolstack[1].elen_var := outParamDesc.sci_iolen;
        IF  outParamDesc.sci_iolen > mxsp_key
        THEN
            a07_b_put_error (acv, e_too_long_key, outParamDesc.sci_iolen)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24drop_multiple_index (
            VAR acv           : tak_all_command_glob;
            VAR viewscanpar   : tak_viewscan_par;
            indexname_errpos  : integer;
            do_a38_input      : boolean);
 
VAR
      b_err          : tgg00_BasisError;
      i              : integer;
      j              : integer;
      drop_index     : integer;
      extcolno       : integer;
      last_index     : integer;
      last_buf       : tak_sysbufferaddress;
      col_ptr        : tak00_colinfo_ptr;
      curr_indexname : tsp00_KnlIdentifier;
      mcolset        : tak_columnset;
      dcolset        : tak_columnset;
      icolset        : tak_columnset;
      sysk           : tgg00_SysInfoKey;
      index_scan_rec : tak_index_scan_record;
 
BEGIN
WITH acv, viewscanpar DO
    BEGIN
    IF  a_p_arr1.pbasep^.sbase.bindexexist
    THEN
        BEGIN
        IF  do_a38_input
        THEN
            a38index_drop (acv, vsc_baseauthname,
                  vsc_basetablen, a01_il_b_identifier, vsc_indexname);
        (*ENDIF*) 
        a24init_index_scan (acv, a_p_arr1.pbasep^.syskey.stableid,
              index_scan_rec);
        END
    ELSE
        a07_nb_put_error (acv, e_unknown_indexname,
              indexname_errpos, vsc_indexname);
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        WITH index_scan_rec DO
            BEGIN
            icolset    := [  ];
            mcolset    := [  ];
            drop_index := 0;
            WHILE a24next_named_index (acv, index_scan_rec) DO
                BEGIN
                WITH isr_buf^.smindex.indexdef[isr_index] DO
                    BEGIN
                    a24get_indexname (acv, isr_buf, isr_index,
                          curr_indexname);
                    IF  curr_indexname = vsc_indexname
                    THEN
                        BEGIN
                        FOR j := 1 TO icount DO
                            icolset := icolset + [icolseq[j]];
                        (*ENDFOR*) 
                        extcolno   := icolseq[ 1 ];
                        drop_index := isr_index;
                        sysk       := isr_sysk
                        END
                    ELSE
                        FOR j := 1 TO icount DO
                            mcolset:= mcolset + [icolseq[j]];
                        (*ENDFOR*) 
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
                last_index := isr_index;
                last_buf   := isr_buf
                END;
            (*ENDWHILE*) 
            IF  drop_index = 0
            THEN
                a07_nb_put_error (acv, e_unknown_indexname,
                      indexname_errpos, vsc_indexname)
            ELSE
                BEGIN
                a10get_sysinfo (acv,
                      sysk, d_fix, a_ptr1, b_err);
                IF  b_err <> e_ok
                THEN
                    a07_b_put_error (acv, b_err, 1)
                ELSE
                    dcolset := icolset - mcolset
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    IF  (a_returncode = 0)
    THEN
        BEGIN
        IF  acv.a_returncode = 0
        THEN
            IF  (acv.a_init_ddl <> ddl_alter_key) AND
                (unique_pk_table in
                acv.a_p_arr1.pbasep^.sbase.blinkexist)
            THEN
                WITH a_ptr1^.smindex.indexdef[ drop_index ] DO
                    IF  a25is_link_index (acv, icount, indexno)
                    THEN
                        a07_b_put_error (acv,
                              e_referenced_index_not_allowed, 1);
                    (*ENDIF*) 
                (*ENDWITH*) 
            (*ENDIF*) 
        (*ENDIF*) 
        vsc_index_col_count := 0;
        vsc_mode            := cmd_drop_index;
        vsc_tabno           := 1;
        IF  (dcolset <> [  ]) AND (a_returncode = 0)
        THEN
            WITH a_ptr1^.smindex, indexdef[ drop_index ] DO
                BEGIN
                FOR i := 1 TO a_p_arr1.pbasep^.sbase.bmaxcol DO
                    IF  (i in dcolset)
                    THEN
                        BEGIN
                        (* calculate colbuf *)
                        a06extcolno (a_p_arr1.pbasep^.sbase, i, col_ptr);
                        col_ptr^.ccolpropset :=
                              col_ptr^.ccolpropset - [ ctmulti ];
                        vsc_index_col_count  := vsc_index_col_count + 1;
                        vsc_col_info[vsc_index_col_count] := col_ptr
                        END;
                    (*ENDIF*) 
                (*ENDFOR*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        a24send_index_command_to_kb (acv,
              viewscanpar, drop_index, m_drop, mm_index);
        END;
    (*ENDIF*) 
    ak24del_index_from_multbuf (acv, viewscanpar, a_ptr1, drop_index,
          last_buf, last_index);
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24assign_indexname (
            VAR acv          : tak_all_command_glob;
            ibuf             : tak_sysbufferaddress;
            index            : integer;
            VAR indexname    : tsp00_KnlIdentifier);
 
VAR
      viewscanpardummy : tak_viewscan_par;
 
BEGIN
(* PTS 1117498 M.Ki. *)
ak24assign_indexname (acv, viewscanpardummy, ibuf, index, indexname);
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24assign_indexname (
            VAR acv          : tak_all_command_glob;
            VAR viewscanpar  : tak_viewscan_par;
            ibuf             : tak_sysbufferaddress;
            index            : integer;
            VAR indexname    : tsp00_KnlIdentifier);
 
VAR
      b_err      : tgg00_BasisError;
      suffix_len : integer;
      name_pos   : integer;
      isuffixlen : integer;
      rest_len   : integer;
      move_len   : integer;
      offset     : integer;
      suffix_p   : tak_sysbufferaddress;
      sysk       : tgg00_SysInfoKey;
 
BEGIN
WITH acv, viewscanpar, ibuf^.smindex.indexdef[index] DO
    BEGIN
    suffix_len := a061identifier_len (indexname) -
          sizeof (indexn_prefix);
    s10mv (sizeof (indexname), sizeof (indexn_prefix),
          @indexname, 1, @indexn_prefix, 1,
          sizeof (indexn_prefix));
    name_pos := sizeof (indexn_prefix) + 1;
    IF  suffix_len < 0
    THEN
        isuffixlen := 0
    ELSE
        isuffixlen := suffix_len;
    (*ENDIF*) 
    rest_len := isuffixlen;
    IF  rest_len > 0
    THEN
        BEGIN
        move_len := sizeof (icolstack) -
              icount * sizeof (icolstack[1]);
        IF  move_len > rest_len
        THEN
            move_len := rest_len;
        (*ENDIF*) 
        g10mv ('VAK24 ',   4,    
              sizeof (indexname), sizeof (icolstack),
              @indexname, name_pos,
              @icolstack, icount * sizeof (icolstack[1]) + 1,
              move_len, a_returncode);
        name_pos := name_pos + move_len;
        rest_len := rest_len - move_len
        END;
    (*ENDIF*) 
    IF  rest_len > 0
    THEN
        BEGIN
        sysk             := ibuf^.syskey;
        sysk.slinkage[1] := chr(index);
        offset := cgg_rec_key_offset + sysk.skeylen +
              sizeof (ibuf^.smindex.isegmentid);
        a10_nil_get_sysinfo (acv, sysk, d_release,
              offset + rest_len, suffix_p, b_err);
        IF  b_err = e_ok
        THEN
            BEGIN
            g10mv ('VAK24 ',   5,    
                  sizeof (indexname),
                  sizeof (indexname),
                  @indexname, name_pos,
                  @suffix_p^.smindex, offset + 1,
                  rest_len, b_err);
            IF  b_err = e_ok
            THEN
                a10_add_repl_sysinfo (acv, suffix_p, true, b_err)
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  b_err <> e_ok
        THEN
            a07_b_put_error (acv, b_err, 1)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24get_tablename (
            VAR acv           : tak_all_command_glob;
            VAR viewscanpar   : tak_viewscan_par);
 
CONST
      no_temp          = false;
      scan_private     = true;
      scan_nonprivate  = true;
      scan_public      = true;
      no_synonyms      = false;
      not_all_base     = false;
 
VAR
      index_count : integer;
      a41v        : tak40_show_glob;
 
BEGIN
WITH acv, viewscanpar DO
    BEGIN
    a41init_show_glob (a41v, a_cmd_packet_header.sp1h_mess_code);
    a41v.a4unique  := false;
    a41v.a4sh_kind := sh_index;
    a40init_table_scan (acv, a41v,
          no_temp, scan_private, scan_nonprivate,
          scan_public, no_synonyms, not_all_base);
    index_count    := 0;
    WHILE a40next_table (acv, a41v) AND (index_count <= 1) DO
        IF  (a41v.a4p_arr.pbasep^.sbase.bindexexist) AND
            (a41v.a4private OR
            (a41v.a4p_arr.pbasep^.sbase.bauthid <> a_curr_user_id))
        THEN
            IF  ak24indexname_exist (acv, viewscanpar, a41v.a4p_arr.pbasep)
            THEN
                index_count := index_count + 1;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDWHILE*) 
    IF  a_returncode = 0
    THEN
        IF  index_count > 1
        THEN
            a07_nb_put_error (acv, e_indexname_must_be_unique,
                  a_ap_tree^[ vsc_ti ].n_pos, vsc_indexname)
        ELSE
            IF  index_count = 0
            THEN
                a07_nb_put_error (acv, e_unknown_indexname,
                      a_ap_tree^[ vsc_ti ].n_pos, vsc_indexname);
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      ak24indexname_exist (
            VAR acv         : tak_all_command_glob;
            VAR viewscanpar : tak_viewscan_par;
            base_ptr        : tak_sysbufferaddress) : boolean;
 
VAR
      priv           : tak_privilege;
      index_scan_rec : tak_index_scan_record;
 
BEGIN
WITH acv, viewscanpar DO
    BEGIN
    ak24indexname_exist := false;
    a06_get_priv (acv, base_ptr, priv);
    IF  r_index in priv.priv_all_set
    THEN
        BEGIN
        a24find_indexname (acv, base_ptr^.syskey.stableid,
              vsc_indexname, index_scan_rec);
        IF  index_scan_rec.isr_buf <> NIL
        THEN
            BEGIN
            ak24indexname_exist := true;
            vsc_basetablen      := base_ptr^.sbase.btablen^;
            a06determine_username (acv,
                  base_ptr^.sbase.bauthid, vsc_baseauthname)
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24del_index_from_multbuf (
            VAR acv         : tak_all_command_glob;
            VAR viewscanpar : tak_viewscan_par;
            drop_buf        : tak_sysbufferaddress;
            drop_index      : integer;
            last_buf        : tak_sysbufferaddress;
            last_index      : integer);
 
CONST
      c_del_old = true;
      c_add_new = true;
 
VAR
      b_err : tgg00_BasisError;
      ptr   : tak_sysbufferaddress;
      sysk  : tgg00_SysInfoKey;
      oldk  : tgg00_SysInfoKey;
      newk  : tgg00_SysInfoKey;
 
BEGIN
&ifdef trace
t01int4 (ak_sem, 'drop_index  ', drop_index);
t01int4 (ak_sem, 'last_index  ', last_index);
&endif
WITH acv, viewscanpar DO
    IF  a_returncode = 0
    THEN
        WITH drop_buf^.smindex.indexdef [drop_index] DO
            BEGIN
            b_err := e_ok;
            IF  icomment
            THEN (* drop comment of index to be dropped *)
                a26drop_comment (acv, cm_index, a_ptr1^.syskey.stableid,
                      a_ptr1^.syskey.stableid, indexno);
            (*ENDIF*) 
            sysk             := drop_buf^.syskey;
            sysk.slinkage[1] := chr(drop_index);
            IF  isuffixlen >
                sizeof (icolstack) - icount * sizeof (icolstack[1])
            THEN
                BEGIN
                (* indexname suffix is stored in different record *)
                a10del_sysinfo (acv, sysk, b_err)
                END;
            (* substitute index to be dropped by last index *)
            (*ENDIF*) 
            IF  (last_buf^.smindex.indexdef[last_index].isuffixlen >
                sizeof (icolstack) -
                last_buf^.smindex.indexdef[last_index].icount *
                sizeof (icolstack[1]))
                AND
                (b_err = e_ok)
            THEN
                BEGIN
                oldk             := last_buf^.syskey;
                oldk.slinkage[1] := chr(last_index);
                IF  sysk.slinkage <> oldk.slinkage
                THEN
                    BEGIN
                    newk             := drop_buf^.syskey;
                    newk.slinkage[1] := chr(drop_index);
                    a10_copy_catalog_rec (acv, oldk,
                          c_del_old, newk, drop_buf^.smindex.isegmentid,
                          c_add_new, b_err)
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  b_err = e_ok
            THEN
                BEGIN
                drop_buf^.smindex.indexdef[drop_index] :=
                      last_buf^.smindex.indexdef[last_index];
                IF  drop_buf <> last_buf
                THEN
                    BEGIN
                    IF  (last_buf^.smindex.indexcount = 1) AND
                        (ord (drop_buf^.syskey.slinkage[2]) + 1 =
                        ord  (last_buf^.syskey.slinkage[2]))
                    THEN (* successor record will be deleted *)
                        drop_buf^.smindex.indexnext := false;
                    (*ENDIF*) 
                    a10repl_sysinfo (acv, drop_buf, b_err)
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  b_err = e_ok
            THEN
                WITH last_buf^.smindex DO
                    IF  indexcount > 1
                    THEN
                        BEGIN
                        indexcount     := indexcount - 1;
                        last_buf^.b_sl :=
                              last_buf^.b_sl - mxak_multindex;
                        a10repl_sysinfo (acv, last_buf, b_err);
                        a10_rel_sysinfo (acv, last_buf^.syskey);
                        END
                    ELSE
                        BEGIN
                        (* delete multbuf *)
                        IF  last_buf^.syskey.slinkage = cak_init_linkage
                        THEN (* last named index of table dropped *)
                            a_p_arr1.pbasep^.sbase.bindexexist := false
                        ELSE
                            IF  (ord (drop_buf^.syskey.slinkage[2])+1 <>
                                ord  (last_buf^.syskey.slinkage[2]))
                            THEN
                                BEGIN
                                sysk             := last_buf^.syskey;
                                sysk.slinkage[2] :=
                                      pred (sysk.slinkage[2]);
                                a10get_sysinfo (acv, sysk, d_release,
                                      ptr, b_err);
                                IF  b_err = e_ok
                                THEN
                                    BEGIN
                                    ptr^.smindex.indexnext := false;
                                    a10repl_sysinfo (acv, ptr, b_err)
                                    END;
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        IF  b_err = e_ok
                        THEN
                            a10del_sysinfo (acv,
                                  last_buf^.syskey, b_err);
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDWITH*) 
            (*ENDIF*) 
            IF  b_err <> e_ok
            THEN
                a07_b_put_error (acv, b_err, 1);
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24ObjectIndex (
            VAR acv            : tak_all_command_glob;
            VAR ClassSurrogate : tgg00_Surrogate;
            VAR ColDesc        : tgg00_ObjColDesc;
            VAR e              : tgg00_BasisError); (* PTS 1106736 *)
 
VAR
      IsFirst      : boolean;
      ix           : integer;
      StackListPtr : tgg00_StackListPtr;
      SysBuf       : tak_sysbufferaddress;
      SysKey       : tgg00_SysInfoKey;
      IndexName    : tsp00_KnlIdentifier;
 
BEGIN
SysKey           := a01defaultkey;
SysKey.stableid  := ClassSurrogate;
SysKey.sentrytyp := cak_emindex;
a10_fix_len_get_sysinfo (acv, SysKey, d_release (* PTS 1106736 *),
      sizeof (tak_mindexrecord), mxak_multindex, SysBuf, e);
IF  acv.a_returncode = 0
THEN
    WITH  SysBuf^, smindex DO
        BEGIN
        IF  e = e_sysinfo_not_found
        THEN (* mindex record created *)
            BEGIN
            IsFirst    := true;
            b_sl       := sizeof (tak_mindexrecord) - sizeof (indexdef) + sizeof(indexdef[1]);
            indexcount := 0;
            indexnext  := false;
            isegmentid := cak00_local_segment_id;
            END
        ELSE
            IsFirst := false;
        (*ENDIF*) 
        indexcount := indexcount + 1;
        WITH indexdef[indexcount] DO
            BEGIN
            a061assign_colname ('INDEX             ',  IndexName);
            g17int4to_line (indexcount, true, 3, 6, IndexName);
            IF  g01unicode
            THEN
                a01setl_identifier (IndexName, IndexName);
            (*ENDIF*) 
            s10mv (sizeof (IndexName), sizeof (indexn_prefix),
                  @IndexName, 1, @indexn_prefix, 1,
                  sizeof (indexn_prefix));
            isuffixlen := 0;
            indexno    := 0;
            IF  ColDesc.colHashCount_gg00 > 0
            THEN
                BEGIN
                StackListPtr := ColDesc.colHashList_gg00;
                icount       := ColDesc.colHashCount_gg00
                END
            ELSE
                BEGIN
                StackListPtr := ColDesc.colInvList_gg00;
                icount       := ColDesc.colInvCount_gg00
                END;
            (*ENDIF*) 
            FOR ix := 1 TO icount DO
                icolstack[ix] := StackListPtr^[ix];
            (*ENDFOR*) 
            a11put_date_time (idatecre, itimecre);
            FOR ix := 1 TO MAX_COL_SEQUENCE_GG00 DO
                icolseq [ix] := 0;
            (*ENDFOR*) 
            iunique             := false;
            ipages              := 0;
            icomment            := false;
            irows               := cak_initrows;
            iinvl               := cak_initinvlist;
            ipages              := 1
            END;
        (*ENDWITH*) 
        a10_add_repl_sysinfo (acv, SysBuf, IsFirst, e);
        END;
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24send_index_command_to_kb (
            VAR acv         : tak_all_command_glob;
            VAR viewscanpar : tak_viewscan_par;
            index_no        : integer;
            m_type          : tgg00_MessType;
            mm_type         : tgg00_MessType2);
 
VAR
      b_err          : tgg00_BasisError;
      j              : integer;
 
BEGIN
WITH acv, viewscanpar DO
    IF  a_returncode = 0
    THEN
        WITH a_mblock DO
            BEGIN
&           ifdef trace
            t01int4 (ak_sem, 'ignore_error', ord (vsc_ignore_error));
&           endif
            IF  mm_type <> mm_index
            THEN
                IF  ((a_ex_kind = only_parsing) AND
                    a_progusage_add)
                THEN
                    mm_type := mm_parse
                ELSE
                    mm_type := mm_nil;
                (*ENDIF*) 
            (*ENDIF*) 
            vsc_prim_cnt := 0;
            vsc_null_cnt := 0;
            a06a_mblock_init (acv,
                  m_type, mm_type, a_p_arr1.pbasep^.sbase.btreeid);
            mb_qual^.mtree.fileLeafNodes_gg00 := cgg_nil_leafnodes;
            WITH a_ptr1^.smindex.indexdef[ index_no ] DO
                BEGIN
&               ifdef TRACE
                ak24trace_index (
                      a_ptr1^.smindex.indexdef[index_no]);
&               endif
                mb_qual^.mmult_pos   := 1;
                mb_qual^.mmult_cnt   := icount;
                mb_qual^.mfirst_free := icount + 1;
                FOR j := 1 TO icount DO
                    mb_st^ [j] := icolstack[ j ];
                (*ENDFOR*) 
                END;
            (*ENDWITH*) 
            a06rsend_mess_buf (acv,
                  a_mblock, cak_return_req, b_err);
            IF  b_err = e_ok
            THEN
                IF  (m_type = m_create_index) AND
                    (mm_type <> mm_parse)
                THEN
                    WITH a_mblock.mb_data^.mbp_sample DO
                        BEGIN
&                       ifdef trace
                        t01int4 (ak_sem, 'leafnodes   ', leafnodes);
                        t01int4 (ak_sem, 'sec_key_cnt ', sec_key_cnt);
                        t01int4 (ak_sem, 'prim_key_cnt', prim_key_cnt);
                        t01int4 (ak_sem, 'null_val_cnt', null_value_cnt);
                        t01int4 (ak_sem, 'indexnodes  ', indexnodes);
&                       endif
                        vsc_prim_cnt := prim_key_cnt;
                        vsc_null_cnt := null_value_cnt
                        END
                    (*ENDWITH*) 
                ELSE
                    IF  m_type = m_drop
                    THEN
                        vsc_dropped_treeid := a_mblock.mb_qual^.mtree;
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
            IF  b_err <> e_ok
            THEN
                IF  (b_err <> e_file_not_found) OR NOT vsc_ignore_error
                THEN
                    a07_b_put_error (acv, b_err, 1);
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDWITH*) 
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24get_columnname  (
            VAR acv         : tak_all_command_glob;
            VAR viewscanpar : tak_viewscan_par;
            VAR errorpos    : integer);
 
VAR
      vsc_ti_lo_level : integer;
      column_name     : tsp00_KnlIdentifier;
 
BEGIN
WITH acv, viewscanpar DO
    IF  a_returncode = 0
    THEN
        BEGIN
        WITH a_ap_tree^[ vsc_ti ] DO
            BEGIN
            a05identifier_get (acv, vsc_ti,
                  sizeof(column_name), column_name);
            errorpos        := a_ap_tree^[ vsc_ti ].n_pos;
            vsc_ti_lo_level := n_lo_level;
            IF  NOT (a061exist_columnname (a_p_arr1.pbasep^.sbase,
                column_name, vsc_col_ptr))
            THEN
                a07_nb_put_error (acv, e_unknown_columnname,
                      errorpos, column_name)
            ELSE
                BEGIN
                WITH vsc_col_ptr^  DO
                    BEGIN
                    IF  cdatatyp in [ dstra, dstrb, dstruni,
                        dlonga, dlongb, dlonguni ]
                    THEN
                        a07_b_put_error (acv,
                              e_command_for_string_not_allow, errorpos);
                    (*ENDIF*) 
                    vsc_ti := n_sa_level;
                    IF  vsc_unique
                    THEN
                        vsc_op_order := op_unique
                    ELSE
                        vsc_op_order := op_order_asc;
                    (*ENDIF*) 
                    IF  vsc_ti_lo_level <> 0
                    THEN
                        IF  a_ap_tree^[ vsc_ti_lo_level ].n_symb = s_desc
                        THEN
                            IF  vsc_unique
                            THEN
                                vsc_op_order := op_unique_desc
                            ELSE
                                vsc_op_order := op_order_desc;
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24alter_index (
            VAR acv         : tak_all_command_glob;
            VAR viewscanpar : tak_viewscan_par;
            kw              : integer);
 
VAR
      index_file     : tgg00_FileId;
      index_scan_rec : tak_index_scan_record;
      b_err          : tgg00_BasisError;
      disable        : boolean;
 
BEGIN
IF  acv.a_p_arr1.pbasep^.sbase.bindexexist (* h.b. PTS 1106868 *)
THEN
    BEGIN
    a24find_indexname (acv, acv.a_p_arr1.pbasep^.sbase.bsurrogate,
          viewscanpar.vsc_indexname, index_scan_rec);
    IF  index_scan_rec.isr_buf = NIL
    THEN
        a07_nb_put_error (acv, e_unknown_indexname,
              1, viewscanpar.vsc_indexname)
    ELSE
        WITH index_scan_rec.isr_buf^.
             smindex.indexdef[index_scan_rec.isr_index] DO
            BEGIN
            CASE kw OF
                cak_i_bad :
                    BEGIN
                    g04index_tree_build(acv.a_p_arr1.pbasep^.sbase.btreeid,
                          index_file, indexno);
                    bd03SetToNotAccessible(acv.a_transinf.tri_trans, index_file);
                    END;
                cak_i_disable, cak_i_enable:
                    BEGIN
                    disable := kw = cak_i_disable;
                    IF  disable <> idisabled
                    THEN
                        BEGIN
                        idisabled := disable;
                        a10repl_sysinfo (acv,
                              index_scan_rec.isr_buf, b_err);
                        IF  b_err <> e_ok
                        THEN
                            a07_b_put_error (acv, b_err, 1);
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    END;
                cak_i_init:
                    BEGIN
                    g04index_tree_build(acv.a_p_arr1.pbasep^.sbase.btreeid,
                          index_file, indexno);
                    bd03ResetUsageInfo(acv.a_transinf.tri_trans, index_file);
                    END;
                END;
            (*ENDCASE*) 
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    END
ELSE
    a07_nb_put_error (acv, e_unknown_indexname,
          1, viewscanpar.vsc_indexname)
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24rename_index (
            VAR acv         : tak_all_command_glob;
            VAR viewscanpar : tak_viewscan_par);
 
VAR
      b_err          : tgg00_BasisError;
      index_scan_rec : tak_index_scan_record;
      new_name       : tsp00_KnlIdentifier;
 
BEGIN
(* ADIS change request 1000032 *)
a05identifier_get (acv,
      acv.a_ap_tree^[ acv.a_ap_tree^[ 0 ].n_lo_level ].n_sa_level,
      sizeof(new_name), new_name);
a24find_indexname (acv, acv.a_p_arr1.pbasep^.sbase.bsurrogate,
      new_name, index_scan_rec);
IF   index_scan_rec.isr_buf <> NIL
THEN
    a07_b_put_error (acv, e_duplicate_indexname, 1)
ELSE
    BEGIN
    a24find_indexname (acv, acv.a_p_arr1.pbasep^.sbase.bsurrogate,
          viewscanpar.vsc_indexname, index_scan_rec);
    IF  index_scan_rec.isr_buf = NIL
    THEN
        a07_nb_put_error (acv, e_unknown_indexname,
              1, viewscanpar.vsc_indexname)
    ELSE
        BEGIN
        ak24assign_indexname (acv, viewscanpar,
              index_scan_rec.isr_buf, index_scan_rec.isr_index, new_name);
        a10repl_sysinfo (acv,
              index_scan_rec.isr_buf, b_err);
        IF  b_err <> e_ok
        THEN
            a07_b_put_error (acv, b_err, 1);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak24replace_base_records (
            VAR acv         : tak_all_command_glob;
            VAR viewscanpar : tak_viewscan_par;
            view_scan       : boolean);
 
VAR
      b_err       : tgg00_BasisError;
 
BEGIN
WITH acv, viewscanpar DO
    BEGIN
    IF  a_returncode = 0
    THEN
        WITH a_p_arr1.pbasep^ DO
            BEGIN
            a10_version (acv, sbase, m_succ_file_version, view_scan);
            vsc_filevers := sbase.btreeid.fileVersion_gg00
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    IF  (a_returncode = 0) AND NOT view_scan
    THEN
        BEGIN
        vsc_col_dropped := false;
        a27view_scan (acv, vsc_base_tabid, viewscanpar)
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        a10repl_sysinfo (acv, a_p_arr1.pbasep, b_err);
        IF  b_err <> e_ok
        THEN
            a07_b_put_error (acv, b_err, 1);
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a24RecreateBadIndexes (VAR acv : tak_all_command_glob);
 
CONST
      c_with_zero = true;
 
VAR
      ok             : boolean;
      cntRecreated   : integer;
      fileId         : tgg00_FileId;
      index_scan_rec : tak_index_scan_record;
      msg            : tsp00_C40;
      pMsg           : ^tsp00_KnlIdentifier;
      viewscanpar    : tak_viewscan_par;
 
BEGIN
a27init_viewscanpar (acv, viewscanpar, v_index);
pMsg                := @msg;
cntRecreated        := 0;
fileId              := b01niltree_id;
fileId.fileTfn_gg00 := tfnMulti_egg00;
REPEAT
    b01get_bad_indexid (acv.a_transinf.tri_trans, fileId);
    IF  acv.a_transinf.tri_trans.trError_gg00 = e_ok
    THEN
        BEGIN
        a06_systable_get (acv, d_release, fileId.fileTabId_gg00,
              acv.a_p_arr1.pbasep, true, ok); (* PTS 1132772 M.Ki. *)
        IF  ok
        THEN
            BEGIN
            a24fnd_indexno (acv, fileId.fileTabId_gg00,
                  ord(fileId.fileTfnNo_gg00[1]), index_scan_rec);
            IF  index_scan_rec.isr_buf <> NIL
            THEN
                BEGIN
                acv.a_ptr1 := index_scan_rec.isr_buf;
                a24send_index_command_to_kb (acv, viewscanpar,
                      index_scan_rec.isr_index, m_drop, mm_index);
                IF  acv.a_returncode = 0
                THEN
                    a24send_index_command_to_kb (acv,
                          viewscanpar, index_scan_rec.isr_index, m_create_index, mm_nil);
                (*ENDIF*) 
                IF  acv.a_returncode = 0
                THEN
                    BEGIN
                    a52_ex_commit_rollback (acv, m_commit, false, false);
                    cntRecreated := cntRecreated + 1;
                    END
                ELSE
                    BEGIN
                    msg := 'recreate index failed :                 ';
                    g17int4to_line (acv.a_returncode, NOT c_with_zero, 10, 24, pMsg^);
                    g01optextmsg (sp3p_console, sp3m_error, csp3_a24_bad_index, csp3_n_badindex, msg);
                    a52_ex_commit_rollback (acv, m_rollback, false, false);
                    END;
                (*ENDIF*) 
                acv.a_returncode := 0;
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
UNTIL
    acv.a_transinf.tri_trans.trError_gg00 <> e_ok;
(*ENDREPEAT*) 
msg := 'bad indexes recreated :                 ';
g17int4to_line (cntRecreated, NOT c_with_zero, 10, 24, pMsg^);
g01optextmsg (sp3p_console, sp3m_info, csp3_a24_bad_index, csp3_n_badindex, msg);
IF  acv.a_transinf.tri_trans.trError_gg00 <> e_no_next_record
THEN
    a07_b_put_error (acv, acv.a_transinf.tri_trans.trError_gg00, 1)
(*ENDIF*) 
END;
 
&ifdef trace
(*------------------------------*) 
 
PROCEDURE
      ak24trace_index (VAR indexdef : tak_multindex);
 
VAR
      ix       : integer;
      ln_len   : integer;
      line     : tsp00_Line;
 
BEGIN
WITH indexdef DO
    BEGIN
    line   := a99blankline;
    ln_len := 0;
    t01c18  (ak_sem, indexn_prefix);
    t01int4 (ak_sem, 'indexno     ', indexno);
    t01bool (ak_sem, 'iunique     ', iunique);
    t01int4 (ak_sem, 'icount      ', icount);
    t01bool (ak_sem, 'icomment    ', icomment);
    t01bool (ak_sem, 'idisabled   ', idisabled);
    t01int4 (ak_sem, 'ipages      ', ipages);
    t01int4 (ak_sem, 'irows       ', irows);
    t01int4 (ak_sem, 'invlen      ', iinvl);
    g17sname_to_line( 'icolumns    ', ln_len, line );
    line[ 14 ] := ':';
    ln_len := 16;
    FOR ix := 1 TO icount DO
        BEGIN
        g17trimint4_to_line( icolseq[ ix ], ln_len, line );
        ln_len := succ( ln_len );
        IF  ( ln_len > 70 ) AND ( ix < MAX_COL_SEQUENCE_GG00 )
        THEN
            BEGIN
            t01line( ak_sem, line );
            line := a99blankline;
            ln_len := 16;
            END
        (*ENDIF*) 
        END;
    (*ENDFOR*) 
    t01line( ak_sem, line );
    FOR ix := 1 TO icount DO
        BEGIN
        t01stackentry (ak_sem, icolstack[ix], ix);
        END;
    (*ENDFOR*) 
    END;
(*ENDWITH*) 
END;
 
&endif
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
