.nf
 
 .nf

    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
.fo

 
.fo
*****************************************************
Copyright (c) 2000-2005 SAP AG
SAP Database Technology
 
Release :      Date : 2000-11-16
*****************************************************
modname : VAK57
changed : 2000-11-16
module  : AK_Update
 
Author  : ElkeZ
Created : 1987-09-22
*****************************************************
 
Purpose : Processes syntax and semantics of update
 
Define  :
 
        PROCEDURE
              a57_aupdate_statement (
                    VAR acv      : tak_all_command_glob;
                    VAR put_node : tsp00_Int2;
                    kw_index     : integer);
 
        PROCEDURE
              a57_range_not_null (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    VAR dfa  : tak_dfarr);
 
        PROCEDURE
              a57_b_update_string (
                    VAR acv      : tak_all_command_glob;
                    VAR dmli     : tak_dml_info;
                    VAR dfa      : tak_dfarr;
                    VAR isparr   : tak_syspointerarr;
                    start_node   : tsp00_Int2;
                    VAR sr_rec   : tak71_strat_rec;
                    VAR all_done : boolean;
                    new_parsinfo : boolean;
                    VAR linkbuf  : tak_sysbufferaddress);
 
        PROCEDURE
              a57_upd_del_rest (
                    VAR acv         : tak_all_command_glob;
                    VAR dmli        : tak_dml_info;
                    VAR dfa         : tak_dfarr;
                    VAR sr_rec      : tak71_strat_rec;
                    VAR icurr_n     : integer;
                    VAR upd_col_set : tak_columnset;
                    new_parsinfo    : boolean);
 
        PROCEDURE
              a57update_with_value_expr (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    VAR dfa  : tak_dfarr);
 
        PROCEDURE
              a57_set_clause (
                    VAR acv           : tak_all_command_glob;
                    VAR dmli          : tak_dml_info;
                    VAR dfa           : tak_dfarr;
                    start_node        : tsp00_Int2;
                    VAR upd_col_set   : tak_columnset;
                    VAR sel_upd_set   : tak_columnset;
                    named_values_done : boolean);
 
        PROCEDURE
              a57_update_statement (
                    VAR acv    : tak_all_command_glob;
                    start_node : tsp00_Int2);
 
.CM *-END-* define --------------------------------------
***********************************************************
 
Use     :
 
        FROM
              Scanner : VAK01;
 
        VAR
              a01kw               : tak_keywordtab;
              a01fullset          : tak_columnset;
              a01sysnullkey       : tgg00_SysInfoKey;
              a01_i_temp          : tsp00_KnlIdentifier;
 
        PROCEDURE
              a01_force_symbol (
                    VAR acv         : tak_all_command_glob;
                    expected_symbol : tak_sc_symbol;
                    VAR node1       : tsp00_Int2;
                    VAR node2       : tsp00_Int2);
 
        PROCEDURE
              a01_get_keyword (
                    VAR acv   : tak_all_command_glob;
                    VAR index : integer;
                    VAR reserved : boolean);
 
        PROCEDURE
              a01_next_symbol (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a01_is_end_symbol (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a01_call_put (
                    VAR acv    : tak_all_command_glob;
                    proc       : tak_procs;
                    subproc    : tsp00_Int2;
                    VAR curr_n : tsp00_Int2);
 
        PROCEDURE
              a01_put_node (
                    VAR acv    : tak_all_command_glob;
                    VAR curr_n : tsp00_Int2);
 
        PROCEDURE
              a01_dt_put_datatype_node (
                    VAR acv    : tak_all_command_glob;
                    VAR curr_n : tsp00_Int2;
                    data_type  : tsp00_DataType;
                    datalen    : tsp00_Int2;
                    datafrac   : tsp00_Int2;
                    inoutlen   : integer);
 
        FUNCTION
              a01_eqkey (
                    VAR a      : tak_keyword;
                    sqlmode    : tsp00_SqlMode;
                    VAR b      : tsp00_MoveObj;
                    VAR scv    : tak_scanner_glob) : boolean;
 
        FUNCTION
              a01mandatory_keyword (
                    VAR acv          : tak_all_command_glob;
                    required_keyword : integer) : boolean;
 
      ------------------------------ 
 
        FROM
              AK_syntax_tools : VAK02;
 
        PROCEDURE
              a02atableid (
                    VAR acv       : tak_all_command_glob;
                    VAR put_node  : tsp00_Int2;
                    VAR last_node : tsp00_Int2);
 
        PROCEDURE
              a02_atablename (
                    VAR acv       : tak_all_command_glob;
                    VAR put_node  : tsp00_Int2;
                    VAR last_node : tsp00_Int2);
 
        PROCEDURE
              a02_acolumnspec (
                    VAR acv        : tak_all_command_glob;
                    table_required : boolean;
                    VAR put_node   : tsp00_Int2;
                    VAR last_node  : tsp00_Int2);
 
        PROCEDURE
              a02_l_acolumn_list (
                    VAR acv       : tak_all_command_glob;
                    VAR put_node  : tsp00_Int2;
                    VAR last_node : tsp00_Int2);
 
        PROCEDURE
              a02_s_atable_spec (
                    VAR acv       : tak_all_command_glob;
                    VAR put_node  : tsp00_Int2;
                    VAR last_node : tsp00_Int2);
 
        PROCEDURE
              a02_n_acolumnname  (
                    VAR acv       : tak_all_command_glob;
                    VAR put_node  : tsp00_Int2;
                    VAR last_node : tsp00_Int2);
 
      ------------------------------ 
 
        FROM
              AK_syntax_values_tools : VAK03;
 
        PROCEDURE
              a03_aunsigned_integer (
                    VAR acv            : tak_all_command_glob;
                    VAR put_node       : tsp00_Int2;
                    VAR last_node      : tsp00_Int2);
 
        PROCEDURE
              a03_ln_aexpression_list (
                    VAR acv         : tak_all_command_glob;
                    VAR put_node    : tsp00_Int2;
                    VAR last_node   : tsp00_Int2);
 
      ------------------------------ 
 
        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);
 
      ------------------------------ 
 
        FROM
              AK_Identifier_Handling : VAK061;
 
        PROCEDURE
              a061get_colname (
                    VAR col_info : tak00_columninfo;
                    VAR colname  : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK07;
 
        PROCEDURE
              a07_error (
                    VAR acv   : tak_all_command_glob;
                    errorcode : tgg00_BasisError;
                    VAR nod1  : tsp00_Int2;
                    VAR nod2  : tsp00_Int2);
 
        PROCEDURE
              a07_b_put_error (
                    VAR acv : tak_all_command_glob;
                    b_err   : tgg00_BasisError;
                    err_code : tsp00_Int4);
 
        PROCEDURE
              a07_nb_put_error (
                    VAR acv : tak_all_command_glob;
                    b_err   : tgg00_BasisError;
                    err_code : tsp00_Int4;
                    VAR n    : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK071;
 
        FUNCTION
              a07_return_code (
                    b_err   : tgg00_BasisError;
                    sqlmode : tsp00_SqlMode) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              Systeminfo_cache : VAK10;
 
        PROCEDURE
              a10cmd_rollback (VAR acv : tak_all_command_glob);
 
        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
              a10new (
                    VAR acv  : tak_all_command_glob;
                    obj_size : tsp00_Int4;
                    VAR p    : tak_eop_arr_ptr);
 
        PROCEDURE
              a10dispose (
                    VAR acv : tak_all_command_glob;
                    VAR p : tak_eop_arr_ptr);
 
        PROCEDURE
              a10del_sysinfo (
                    VAR acv     : tak_all_command_glob;
                    VAR syskey  : tgg00_SysInfoKey;
                    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
              a10add_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              AK_Trigger : VAK262;
 
        PROCEDURE
              a262add_trigger_info (
                    VAR acv           : tak_all_command_glob;
                    VAR dmli          : tak_dml_info;
                    ignoreUserTrigger : boolean);
 
      ------------------------------ 
 
        FROM
              DML_Help_Procedures : VAK54;
 
        PROCEDURE
              a54add_next_temp_lock (
                    VAR acv           : tak_all_command_glob;
                    VAR tabid         : tgg00_Surrogate;
                    globstate         : tgg00_HandlingSet);
 
        PROCEDURE
              a54_loc_temp_locks (
                    VAR acv   : tak_all_command_glob;
                    globstate : tgg00_HandlingSet;
                    VAR sparr : tak_syspointerarr);
 
        PROCEDURE
              a54set_complex_entry (
                    VAR acv     : tak_all_command_glob;
                    call_reason : tak_complex_call_reason);
 
        PROCEDURE
              a54_dml_init (
                    VAR dmli : tak_dml_info;
                    in_union : boolean);
 
        PROCEDURE
              a54_internal_function (
                    VAR acv : tak_all_command_glob;
                    VAR m : tgg00_MessBlock;
                    st_no : integer);
 
        PROCEDURE
              a54_last_part (
                    VAR acv        : tak_all_command_glob;
                    VAR sparr      : tak_syspointerarr;
                    last_pars_part : boolean);
 
        PROCEDURE
              a54_put_indices_in_mess_buf (
                    VAR acv     : tak_all_command_glob;
                    VAR basebuf : tak_baserecord;
                    VAR dfa     : tak_dfarr;
                    all_indices : boolean);
 
        PROCEDURE
              a54_get_pparsp_pinfop (
                    VAR acv   : tak_all_command_glob;
                    VAR sparr : tak_syspointerarr;
                    mtype     : tgg00_MessType);
 
        PROCEDURE
              a54_view_put_into (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a54_fixedpos (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a54_subquery (
                    VAR acv          : tak_all_command_glob;
                    VAR isparr       : tak_syspointerarr;
                    start_node       : tsp00_Int2;
                    mtype            : tgg00_MessType;
                    VAR is_join_view : boolean);
 
        PROCEDURE
              a54datetime_parsinfo (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    stackpos : integer);
 
        PROCEDURE
              a54init_lock_parsinfo (
                    VAR acv      : tak_all_command_glob;
                    tempinfo_buf : tak_sysbufferaddress);
 
        PROCEDURE
              a54trunc_complex_record (
                    VAR acv      : tak_all_command_glob;
                    comp_cnt_old : integer);
 
        FUNCTION
              a54get_complex_cnt (VAR acv : tak_all_command_glob) : integer;
 
      ------------------------------ 
 
        FROM
              DML_Parts : VAK55;
 
        PROCEDURE
              a55_asearch_clause (
                    VAR acv       : tak_all_command_glob;
                    VAR put_node  : tsp00_Int2;
                    VAR last_node : tsp00_Int2);
 
        PROCEDURE
              a55_named_values (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    VAR dfa  : tak_dfarr;
                    curr_n   : integer);
 
        PROCEDURE
              a55_build_key (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    VAR dfa  : tak_dfarr;
                    keynode  : integer);
 
        PROCEDURE
              a55_found_one_value (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    VAR dfa  : tak_dfarr);
 
      ------------------------------ 
 
        FROM
              AK_Insert : VAK56;
 
        PROCEDURE
              a56alloc_linkpos_info (
                    VAR acv        : tak_all_command_glob;
                    VAR p_arr      : tak_syspointerarr;
                    mess_type      : tgg00_MessType;
                    VAR linkposbuf : tak_sysbufferaddress);
 
        PROCEDURE
              a56insert_upd_with_link (
                    VAR acv        : tak_all_command_glob;
                    VAR linkbuf     : tak_sysbufferaddress);
 
        PROCEDURE
              a56put_link_info (
                    VAR acv            : tak_all_command_glob;
                    base_ptr           : tak_sysbufferaddress;
                    not_used_links     : tak_charset;
                    viewqualbuf        : tak_sysbufferaddress;
                    VAR linkbuf        : tak_sysbufferaddress);
 
        PROCEDURE
              a56_aenumerated_values (
                    VAR acv        : tak_all_command_glob;
                    select_allowed : boolean;
                    VAR put_node   : tsp00_Int2;
                    VAR last_node  : tsp00_Int2);
 
        PROCEDURE
              a56_enumerated_values (
                    VAR acv    : tak_all_command_glob;
                    VAR dmli   : tak_dml_info;
                    VAR dfa    : tak_dfarr;
                    VAR curr_n : integer);
 
        PROCEDURE
              a56one_default_value (
                    VAR acv     : tak_all_command_glob;
                    VAR dmli    : tak_dml_info;
                    VAR colinfo : tak00_columninfo;
                    with_length : tak_fp_kind_type);
 
      ------------------------------ 
 
        FROM
              AK_Delete : VAK58;
 
        PROCEDURE
              a58_mass_update_delete (VAR dmli : tak_dml_info);
 
        PROCEDURE
              a58_current_of (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    curr_n   : integer);
 
        PROCEDURE
              a58execute_link_cmd (VAR acv : tak_all_command_glob);
 
      ------------------------------ 
 
        FROM
              DML-Join-View-Procedures : VAK59;
 
        PROCEDURE
              a59_join_view (
                    VAR acv     : tak_all_command_glob;
                    VAR dmli    : tak_dml_info;
                    VAR viewdfa : tak_dfarr;
                    start_node  : integer;
                    mtype       : tgg00_MessType);
 
      ------------------------------ 
 
        FROM
              Select_Syntax : VAK60;
 
        PROCEDURE
              a60_asub_query (
                    VAR acv         : tak_all_command_glob;
                    VAR put_node    : tsp00_Int2;
                    list_cnt        : integer;
                    one_valsubquery : boolean);
 
        PROCEDURE
              a60rescount (
                    VAR acv  : tak_all_command_glob;
                    rescount : tsp00_Int4);
 
        PROCEDURE
              a60resnum (
                    VAR acv     : tak_all_command_glob;
                    VAR moveobj : tsp00_Buf;
                    startpos    : integer);
 
      ------------------------------ 
 
        FROM
              Select_List : VAK61;
 
        PROCEDURE
              a61_set_jump (
                    VAR mblock : tgg00_MessBlock;
                    stentrynr : integer;
                    operator  : tgg00_StackEntryType);
 
      ------------------------------ 
 
        FROM
              Where_Part : VAK63;
 
        PROCEDURE
              a63_avalue_expression (
                    VAR acv       : tak_all_command_glob;
                    VAR put_node  : tsp00_Int2;
                    VAR last_node : tsp00_Int2);
 
        FUNCTION
              a63pure_subquery (VAR acv : tak_all_command_glob) : boolean;
 
      ------------------------------ 
 
        FROM
              Execute_factor_col_function : VAK641;
 
        PROCEDURE
              a641check_datetime(
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    datatyp  : tsp00_DataType);
 
      ------------------------------ 
 
        FROM
              Execute_Where_Part : VAK65;
 
        PROCEDURE
              a65_search_condition (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    VAR first_node : integer);
 
        PROCEDURE
              a65_val_expr (
                    VAR acv    : tak_all_command_glob;
                    VAR dmli   : tak_dml_info;
                    VAR colin  : tak00_scolinf;
                    first_node : integer);
 
        PROCEDURE
              a65_set_operator (
                    VAR acv  : tak_all_command_glob;
                    operator : tgg00_StackOpType);
 
        FUNCTION
              a65_datatypes_ok (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    VAR dm_type    : tsp00_DataType;
                    VAR dm_iolen   : tsp00_Int2;
                    ctype          : tsp00_DataType;
                    is_subquery    : boolean;
                    first_node     : integer;
                    error_pos      : tsp00_Int4;
                    convert        : boolean;
                    VAR convert_t  : tak_convert_type) : boolean;
 
      ------------------------------ 
 
        FROM
              Execute_Select_Expression : VAK660;
 
        PROCEDURE
              a660_search_one_table (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    table_node     : integer;
                    all            : boolean;
                    check_teresult : boolean;
                    lock_spec      : tak_lockenum;
                    wanted_priv    : tak00_PrivR);
 
        PROCEDURE
              a660_new_pparsp (
                    VAR acv        : tak_all_command_glob;
                    VAR sparr      : tak_syspointerarr;
                    first_parsinfo : boolean;
                    complicate     : boolean);
 
        PROCEDURE
              a660_prefix_delete (VAR acv : tak_all_command_glob;
                    VAR parsk     : tak_parskey;
                    VAR del_cnt   : integer;
                    prefix_length : integer);
 
        PROCEDURE
              a660set_subq_info (VAR acv : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
      ------------------------------ 
 
        FROM
              Part2_Select_Expression : VAK67;
 
        PROCEDURE
              a67_first_corr (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a67_corr_search (
                    VAR acv         : tak_all_command_glob;
                    VAR dmli        : tak_dml_info;
                    only_having_columns_get : boolean;
                    VAR starttabno  : integer;
                    only_split      : boolean;
                    predefined_pno  : integer;
                    VAR old_infolen : integer;
                    VAR rtree       : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              Build_Strategy : VAK70;
 
        PROCEDURE
              a70_strategy_search (
                    VAR acv    : tak_all_command_glob;
                    VAR dmli   : tak_dml_info;
                    VAR rtree  : tgg00_FileId;
                    VAR sr_rec : tak71_strat_rec);
 
      ------------------------------ 
 
        FROM
              Hint_Handling : VAK80;
 
        PROCEDURE
              a80_ahint_statement (
                    VAR acv : tak_all_command_glob;
                    subproc : tsp00_Int2;
                    putnode : tsp00_Int2);
 
        PROCEDURE
              a80store_cmd_hint_info(
                    VAR acv     : tak_all_command_glob;
                    VAR dmli    : tak_dml_info;
                    select_node : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01glob          : tgg00_KernelGlobals;
 
      ------------------------------ 
 
        FROM
              Select_Help_Procedures : VGG04;
 
        PROCEDURE
              g04build_temp_tree_id (
                    VAR curr : tgg00_FileId;
                    VAR t : tgg00_TransContext);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    obj_upb     : tsp00_Int4;
                    obj         : tsp00_MoveObjPtr;
                    obj_pos     : tsp00_Int4;
                    length      : tsp00_Int4;
                    fillchar    : char;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_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);
&       ifdef trace
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01bool (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    curr_bool: boolean);
 
        PROCEDURE
              t01moveobj (
                    debug    : tgg00_Debug;
                    VAR buf  : tsp00_MoveObj;
                    startpos : tsp00_Int4;
                    endpos   : tsp00_Int4);
 
        PROCEDURE
              t01stackentry (
                    layer       : tgg00_Debug;
                    VAR st      : tgg00_StackEntry;
                    entry_index : integer);
 
        PROCEDURE
              t01messblock (
                    debug         : tgg00_Debug;
                    nam           : tsp00_Sname;
                    VAR m         : tgg00_MessBlock);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
***********************************************************
Synonym :
 
        PROCEDURE
              a10new;
 
              tak_sysbufferaddress tak_eop_arr_ptr
 
        PROCEDURE
              a10dispose;
 
              tak_sysbufferaddress tak_eop_arr_ptr
 
        PROCEDURE
              a60resnum;
 
              tsp00_MoveObj tsp00_Buf
 
.CM *-END-* synonym -------------------------------------
***********************************************************
 
Specification:
.SP 2;.NF
A57_AUPDATE_STATEMENT : Update syntax
.br
A57_CALL_SEMANTIC     : Semantics of update, begin-modify,
                        end-modify, modify
.br
A57_RANGE_NOT_NULL    : Entering of stack entries and values
                        that return the NOT NULL and range
                        conditions of the table definition
.fo
.CM *-END-* specification -------------------------------
***********************************************************
 
Description:
.sp 2
Node assignment:
  a57, 1  : update
  a57, 2  : set part of update
  a57, 3  : a string <columnname> = <value_expression>
 used:
  a55, 2  : key specification
  a63,..  : value_expression, a simple value_spec
.sp 2
A57_AUPDATE_STATEMENT
.sp
This procedure
analyzes the syntax of an update command
For analyzing the set_clause AUPDSET_CLAUSE is called in a loop.
.br
If 'WHERE' or 'KEY' is specified, A55_ASEARCH_CLAUSE is called.
There the following syntax is analyzed :
  (WHERE <search_condition> or
   WHERE CURRENT OF <result-table_name> or
   KEY <key_spec> or
   KEY <key_spec> WHERE <search_condition>)
.sp 2
AUPDSET_CLAUSE
.sp
It is called by A57_AUPDATE_STATEMENT.
It analyzes one sequence of :
 <column_name> = <value_expression>
.br;For the right hand side A63_AVALUE_EXPRESSION is called.
.sp 2
A57_UPDATE_STATEMENT
.sp
If the update contains no subquery that is indicated
by an assigned n_sa_level in the first node of the tree the
mess buffer is build by calling
BUILD_UPDATE_STRING.
.br;A54_LAST_PART either calls KB05 or stores the edited information
(mess_buffer, information on variables) and, if necessary, transfers
information on variables to the SQL_PACKET.
.br;The number of records modified is entered in the SQL_PACKET
as a number even if only 1 record is modified
(KEY or CURRENT OF entry).
.br;The link definitions are checked after the modifications and, if
appropriate, cause the changes to be reversed.
.br
If the update contains subqueries, A54_SUBQUERY is called which, among
other things, executes the subqueries and the update with the HELP
of A57_B_UPDATE_STRING.
.sp 2
BUILD_UPDATE_STRING
.sp
It is called by A57_UPDATE_STATEMENT.
.br;This procedure is called in order to limit the size of the stack
when executing in A57_UPDATE_STATEMENT.
.br
A57_B_UPDATE_STRING creates the update-information records.
.sp 2
A57_B_UPDATE_STRING
.sp
It is internally called by BUILD_UPDATE_STRING.
The following actions are done by this procedure :
.in +2;.un 2
.un 2;- checks the table name and privileges via A54_TABLE_PRIV.
.un 2;- creates link-information records via A56PUT_LINK_INFO
.un 2;- dicurr_n is moved to the beginning of the set clause
.un 2;- icurr_n is moved to the beginning of the where condition or
key condition
.un 2;- a key spec is processed via A55_BUILD_KEY; the complete key is moved
to the beginning of mess_buf.part2.
.un 2;- A58_CURRENT_OF moves the key of the last record which was
fetched of the
result set to the beginning of mess_buf.part2.
.un 2;- With A57_SET_CLAUSE, the set_clause is processed; the stack entries
of the fields to be modified and the stack entries of multiple inversions
that contain fields to be modified are entered in part1 of the mess
buffer.  Associated values are written to part2 after the key, if it
is present.
.un 2;- A57_UPD_DEL_REST is called where that parts of processing are
in which are the same for update and delete commands.
.in -2
.sp 2
A57_SET_CLAUSE
.sp
It is called by A57_B_UPDATE_STRING.
.br;Via A55_NAMED_VALUES, DM_NODE is set to the first associated value
node in DFA for each field that is to be modified.
DM_BUF and DM_INDEX are assigned in such a way that rapid reaccess to
the field information is possible.
.br;Via A54_PUT_INDICES_IN_MESS_BUF, the stack entries of all multiple
inversions of this table containing fields to be modified are entered
in the mess buffer.
.br;In a loop, the associated stack entries for all fields to be
modified are entered in mess_buf.part1 and the values are entered in
part2.  First the fields to be modified for which a value_spec but
no other field is specified are processed and then the other fields.
.br;For the fields with value_expression, an entry is made in DM_FOUNDSET;
for the other fields, the stack entry is written and the value is moved
via A55_FOUND_ONE_VALUE to the mess_buf.part2.
.br;For the fields listed in dm_foundset, stack enteries are entered;
op_..expr_upd indicates that their values are not located directly in
part2 but are identified via stack entries and values in the
qualification (which, together, specify the value_expression) and
also by op_output_var.
.br;The value_expressions of all corresponding fields are processed via
UPDATE_WITH_VALUE_EXPRESSION.
.br;All loops include the key fields although these fields actually
must not be changed.  The key information was allowed for the sake of
a simpler process via application programs.  An error does not occur unless
the new key value does not correspond to the one that is already
present.
.sp 2
UPDATE_WITH_VALUE_EXPRESSION
.sp
This procedure is called by A57_SET_CLAUSE.
.br;For all fields from DM_FOUNDSET, A65_VAL_EXPR is called after
the necessary initializations, e.g. of the only valid data type.
This procedure forms stack entries that describe the
value_expression and enters the values in the mess buffer.
.br;For numbers, a stack entry is formed that is necessary for a check
of the number formed in the value_expression.  The result of the
value_expression must fit in the data type specified for the
field to be modified.
.br;Date and time checks (e.g no 13th month) are forced via simple
operators.
.br;A stack entry with op_output_var indicates that the value_expression
is terminated and belongs to the next appropriately identified stack
entry of the fields to be modified.
.br;Range_conditions for these fields can be carried out only in KB.
DM_NODE <> 0 or another identifier in
DM_FOUNDSET leads to corresponding entries when
A57_RANGE_NOT_NULL is called in A57_B_UPDATE_STRING.
.sp 2
A57_UPD_DEL_REST
.sp
This procedure is called by A57_B_UPDATE_STRING and by VAK58 (delete).
.br
A58_MASS_UPDATE_DELETE contains some initializations of global
variables in dmli, that are required in order to continue the operation.
.br;If a where clause is present, the stack entries and the values that
form conditions are entered in the mess buffer via A65_SEARCH_CONDITION.
.br;If the specified table name is a view (oview) that is also to be
checked in the case of modifications (oviewcheck) and contains a
view qualification (oviewqual), this view qualification is transferred
to the mess buffer.
.br;In the case of an update
the NOT NULL or range conditions specified for a create table
are normally checked in A57_SET_CLAUSE for the fields to be modified.
If the new value is specified as a value_expression (not value_spec),
the check can first occur in KB.  For this reason, the conditions are
also passed in the mess buffer via A57_RANGE_NOT_NULL.
.br;If it is a set command (no entry of KEY or CURRENT OF; 0-n records
can be modified), an attempt is made via A67_STRATEGY-SEARCH to find
a way of rapidly identifying the records to be modified, i.e. to
identify a condition contained in the search_condition that
speeds up the search.  Appropriate facts are entered in the
mess buffer.
.sp 2
A57_RANGE_NOT_NULL
.sp
It is called internally by UPDATE_WITH_VALUE_EXPRESSION.
.br;For all fields, a check is run to determine whether a NOT-NULL or
range check must be performed.  Range conditions are indicated via
DM_NODE <> 0; NOT NULL is indicated via an entry in DM_FOUNDSET.
.br;The range conditions are transferred from the values record to
the mess buffer or a NOT NULL condition consisting of two stack
entries is incorporated there.
.CM *-END-* description ---------------------------------
***********************************************************
.CM -lll-
Code    :
 
 
CONST
      c_table_required  = true (* a02_acolumnspec *);
      c_in_union        = true (* a54_dml_init *);
      c_last_pars_part  = true (* a54_last_part *);
      c_select_allowed  = true (* a56_aenumerated_values *);
      c_new_parsinfo    = true (* a57_b_update_string *);
      c_initialize      = true (* ak57set1_clause *);
      c_table_constraint= true (* ak57constraint_not_null_check *);
      c_one_valsubquery = true (* a60_asub_query *);
      c_convert         = true (* a65_datatypes_ok *);
      c_is_subquery     = true (* a65_datatypes_ok *);
      c_all             = true (* a660_search_one_table *);
      c_check_teresult  = true (* a660_search_one_table *);
      c_complicate      = true (* a660_new_pparsp *);
      c_first_parsinfo  = true (* a660_new_pparsp *);
      c_only_having_columns_get = true (* a67_corr_search *);
      c_only_split      = true (* a67_corr_search *);
      c_named_values_done      = true (* ak57set1_clause *);
      c_use_only_varlongchar   = true (* ak57one_upd_col *);
      c_predefined_pno   = 0 (* a67_corr_search *);
 
 
(*------------------------------*) 
 
PROCEDURE
      ak57aupdset_clause (
            VAR acv       : tak_all_command_glob;
            VAR put_node  : tsp00_Int2;
            VAR last_node : tsp00_Int2);
 
VAR
      query  : boolean;
      curr_n : tsp00_Int2;
      last_n : tsp00_Int2;
      scvh   : tak_scanner_glob;
 
BEGIN
WITH acv, a_scv DO
    IF  a_returncode = 0
    THEN
        BEGIN
        a01_call_put (acv, a57, cak_x_one_update_col, curr_n);
        put_node := curr_n;
        last_node := curr_n;
        a02_n_acolumnname (acv, a_ap_tree^[ curr_n ].n_lo_level,
              last_n);
        a01_force_symbol (acv, s_equal, put_node, last_node);
        IF  a_returncode = 0
        THEN
            BEGIN
            a_rowno_allowed := false;
            a_rowno_found := false;
            query := false;
            scvh := a_scv;
            (* a_cpart_type is for corr subquery *)
            a_cpart_type := cpt_in_where_clause;
            IF  sc_symb = s_leftpar
            THEN
                BEGIN
                a01_next_symbol (acv);
                IF  (((a_sqlmode = sqlm_oracle) OR
                    (  a_sqlmode = sqlm_internal)) AND
                    (a01_eqkey (a01kw[cak_i_select], a_sqlmode,
                    a_cmd_part^.sp1p_buf, a_scv)))
                THEN
                    BEGIN
                    a_scv := scvh;
                    query := a63pure_subquery (acv);
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  query
            THEN
                BEGIN
                a60_asub_query (acv,
                      a_ap_tree^[ last_n ].n_sa_level, 1,
                      c_one_valsubquery);
                curr_n := a_ap_tree^[ last_n ].n_sa_level;
                END
            ELSE
                BEGIN
                a_scv := scvh;
                IF  a01_eqkey (a01kw[ cak_i_null ], a_sqlmode,
                    a_cmd_part^.sp1p_buf, a_scv)
                THEN
                    BEGIN
                    sc_symb := s_null;
                    a01_put_node (acv, curr_n);
                    a_ap_tree^[ last_n ].n_sa_level := curr_n;
                    a01_next_symbol (acv)
                    END
                ELSE
                    IF  ((a01_eqkey (a01kw[cak_i_stamp], a_sqlmode,
                        a_cmd_part^.sp1p_buf, a_scv)) AND
                        (a_sqlmode = sqlm_internal))
                    THEN
                        BEGIN
                        sc_symb := s_stamp;
                        a01_put_node (acv, curr_n);
                        a_ap_tree^[ last_n ].n_sa_level := curr_n;
                        a01_next_symbol (acv)
                        END
                    ELSE
                        (* PTS 1115778 E.Z. *)
                        IF  ((a01_eqkey (a01kw[ cak_i_default ],
                            a_sqlmode, a_cmd_part^.sp1p_buf, a_scv))
                            AND
                            (
                            (a_sqlmode = sqlm_internal) OR
                            (a_cmd_segment_header.sp1c_producer = sp1pr_kernel)
                            ))
                        THEN
                            BEGIN
                            sc_symb := s_default;
                            a01_put_node (acv, curr_n);
                            a_ap_tree^[ last_n ].n_sa_level := curr_n;
                            a01_next_symbol (acv)
                            END
                        ELSE
                            (* PTS 1116169 E.Z. *)
                            BEGIN
                            a_oneval_subq_allowed := true;
                            a63_avalue_expression (acv,
                                  a_ap_tree^[ last_n ].n_sa_level, last_n);
                            a_oneval_subq_allowed := false;
                            END;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak57aupd_stat_stmt (
            VAR acv      : tak_all_command_glob;
            VAR kw_index : integer;
            VAR put_node : tsp00_Int2);
 
VAR
      found      : boolean;
      dummy      : boolean;
      ora_syntax : boolean;
      curr_n     : tsp00_Int2;
      last_n     : tsp00_Int2;
      sa_level   : tsp00_Int2;
      scvh       : tak_scanner_glob;
 
BEGIN
WITH acv, a_scv DO
    BEGIN
    found      := false;
    a_is_ddl   := ddl_update_statistics;
    ora_syntax := (kw_index = cak_i_analyze) OR
          ((kw_index <> cak_i_analyze) AND
          NOT g01glob.db_is_for_sapr3  AND
          (a_sqlmode = sqlm_oracle));
    IF  ora_syntax
    THEN
        BEGIN
        IF  NOT a01mandatory_keyword (acv, cak_i_table)
        THEN
            put_node := 0;
        (*ENDIF*) 
        END
    ELSE
        a01_next_symbol (acv);
    (*ENDIF*) 
    (* PTS 1000252 E.Z. *)
    IF  (a01_eqkey (a01kw[ cak_i_column ], a_sqlmode,
        a_cmd_part^.sp1p_buf, a_scv))                   AND
        ((a_sqlmode  = sqlm_internal)         OR
        (g01glob.db_is_for_sapr3     AND
        (a_sqlmode = sqlm_oracle)))
    THEN
        BEGIN
        found := true;
        a01_call_put (acv, a28, cak_x_upd_stat_col, put_node);
        a01_next_symbol (acv);
        IF  sc_symb = s_leftpar
        THEN
            BEGIN
            a01_next_symbol (acv);
            curr_n := put_node;
            IF  sc_symb <> s_asterisk
            THEN
                a02_l_acolumn_list (acv, sa_level, last_n)
            ELSE
                BEGIN
                a01_put_node (acv, sa_level);
                a01_next_symbol (acv)
                END;
            (*ENDIF*) 
            a01_force_symbol (acv, s_rightpar, put_node, last_n);
            IF  a_returncode = 0
            THEN
                BEGIN
                IF  a01mandatory_keyword (acv, cak_i_for)
                THEN
                    BEGIN
                    a02atableid  (acv,
                          a_ap_tree^[ curr_n ].n_lo_level, last_n);
                    a_ap_tree^[last_n].n_sa_level := sa_level
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        ELSE
            a02_acolumnspec (acv, c_table_required,
                  a_ap_tree^[put_node].n_lo_level, last_n);
        (*ENDIF*) 
        END
    ELSE
        IF  (a01_eqkey (a01kw[ cak_i_as ], a_sqlmode,
            a_cmd_part^.sp1p_buf, a_scv))                   AND
            ((a_sqlmode  = sqlm_internal)         OR
            (g01glob.db_is_for_sapr3     AND
            (a_sqlmode = sqlm_oracle)))
        THEN
            BEGIN
            scvh := a_scv;
            a01_next_symbol (acv);
            IF  a01_eqkey (a01kw[ cak_i_per ], a_sqlmode,
                a_cmd_part^.sp1p_buf, a_scv)
            THEN
                BEGIN
                found := true;
                a01_next_symbol (acv);
                IF  a01mandatory_keyword (acv, cak_i_system)
                THEN
                    IF  a01mandatory_keyword (acv, cak_i_table)
                    THEN
                        a01_call_put (acv, a28, cak_x_upd_stat_system_table, put_node);
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            ELSE
                a_scv := scvh;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  NOT found
    THEN
        BEGIN
        a01_call_put (acv, a28, cak_x_upd_statistics, put_node);
        IF  ora_syntax
        THEN
            a02_atablename (acv,
                  a_ap_tree^[put_node].n_lo_level, last_n)
        ELSE
            a02atableid  (acv,
                  a_ap_tree^[put_node].n_lo_level, last_n)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    a_ap_tree^[put_node].n_length := cak_i_compute;
    IF  sc_symb <> s_eof
    THEN
        IF  a01_eqkey (a01kw[cak_i_estimate], a_sqlmode,
            a_cmd_part^.sp1p_buf, a_scv)
        THEN
            BEGIN
            a_ap_tree^[put_node].n_length := cak_i_estimate;
            a01_next_symbol (acv);
            IF  sc_symb <> s_eof
            THEN
                IF  a01mandatory_keyword (acv, cak_i_sample)
                THEN
                    BEGIN
                    a03_aunsigned_integer (acv,
                          a_ap_tree^[put_node].n_sa_level, last_n);
                    a01_get_keyword (acv, kw_index, dummy);
                    CASE kw_index OF
                        cak_i_rows, cak_i_percent :
                            BEGIN
                            a01_call_put (acv, a28, kw_index,
                                  a_ap_tree^[last_n].n_sa_level);
                            a01_next_symbol (acv)
                            END;
                        OTHERWISE
                            a07_error (acv, e_wanted_keyword,
                                  put_node, last_n)
                        END;
                    (*ENDCASE*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE
            IF  ora_syntax
            THEN
                IF  a01_eqkey (a01kw[cak_i_compute], a_sqlmode,
                    a_cmd_part^.sp1p_buf, a_scv)
                THEN
                    a01_next_symbol (acv);
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    IF  ora_syntax
    THEN
        IF  a01mandatory_keyword (acv, cak_i_statistics)
        THEN
            BEGIN
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    a01_is_end_symbol (acv)
    END;
(*ENDWITH*) 
END;
 
(* PTS 1113924 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      ak57build_update_string (VAR acv : tak_all_command_glob;
            VAR isparr   : tak_syspointerarr;
            start_node   : tsp00_Int2;
            VAR all_done : boolean;
            VAR linkbuf  : tak_sysbufferaddress);
 
VAR
      del_cnt      : integer;
      comp_cnt_old : integer;
      parsk        : tak_parskey;
      b_err        : tgg00_BasisError;
      sr_rec       : tak71_strat_rec;
      dfa          : tak_dfarr;
      dmli         : tak_dml_info;
 
BEGIN
sr_rec.sr_reverse_access := false;
REPEAT
    a54_dml_init (dmli, NOT c_in_union);
    IF  start_node <> acv.a_ap_tree^[ 0 ].n_lo_level
    THEN
        comp_cnt_old := a54get_complex_cnt (acv);
    (*ENDIF*) 
    a57_b_update_string (acv, dmli, dfa, isparr, start_node,
          sr_rec, all_done, c_new_parsinfo, linkbuf);
    IF  linkbuf <> NIL
    THEN
        BEGIN
        IF  (acv.a_isolation_info <> temp_lock_rec_get) AND
            (linkbuf^.slinkposinfo.lunique_cnt > 0)
        THEN
            BEGIN
            (* key update or unique update in the primary *)
            (* table of a referntial constraint, repeat   *)
            (* update execution because temp locks are    *)
            (* required                                   *)
            acv.a_isolation_info := temp_lock_rec_needed;
            acv.a_input_data_pos := 1;
            IF  start_node <> acv.a_ap_tree^[ 0 ].n_lo_level
            THEN
                BEGIN
                a10del_sysinfo (acv, linkbuf^.syskey, b_err);
                a54trunc_complex_record (acv, comp_cnt_old);
                parsk           := acv.a_pars_last_key;
                (* parsk.p_id[ 1 ] := acv.a_first_parskey;*)
                parsk.p_kind    := m_complex;
                parsk.p_no      := 0;
                a660_prefix_delete (acv, parsk, del_cnt, cak_intern_prefix);
                IF  parsk.p_id[1] > chr(4)
                THEN
                    a07_b_put_error (acv, e_no_more_memory, 1);
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                acv.a_shortinfo_key := cgg_zero_id;
                a10cmd_rollback (acv)
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END
    ELSE
        IF  (acv.a_returncode <> 0) AND
            (start_node <> acv.a_ap_tree^[ 0 ].n_lo_level)
        THEN
            BEGIN
            acv.a_shortinfo_key := cgg_zero_id;
            a10cmd_rollback (acv)
            END;
        (*ENDIF*) 
    (*ENDIF*) 
UNTIL
    (acv.a_isolation_info <> temp_lock_rec_needed)
    OR
    (acv.a_returncode <> 0);
(*ENDREPEAT*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak57constraint_not_null_check (
            VAR acv          : tak_all_command_glob;
            VAR dmli         : tak_dml_info;
            VAR dfa          : tak_dfarr;
            max_loop         : integer;
            table_constraint : boolean);
 
VAR
      null_qual  : boolean;
      int_qual   : boolean;
      put_dummy  : boolean;
      e          : tgg00_BasisError;
      first      : boolean;
      and_count  : integer;
      aux_len    : integer;
      fieldno    : integer;
      first_pos  : integer;
      first_epos : integer;
      i          : integer;
      j          : integer;
      m_qual2    : integer;
      move_len   : integer;
      stcount    : integer;
      first_free : integer;
      constraint_no : integer;
      valp       : tak_sysbufferaddress;
      ke         : tgg00_SysInfoKey;
      and_arr    : tak_eop_arr_ptr;
 
BEGIN
WITH acv.a_mblock, mb_qual^, mb_data^ DO
    BEGIN
&   ifdef TRACE
    t01messblock( ak_sem, 'a57constr 1 ', acv.a_mblock );
&   endif
    (* dm_foundset  => NOT NULL Column   *)
    (* dm_node <> 0 => Constraint Column *)
    (* PTS 1115407 E.Z. *)
    and_arr  := NIL;
    first    := true;
    int_qual := false;
    j := mfirst_free - 1;
    WHILE mb_st^[ j ].eop in [ op_and, op_upd_view_and ] DO
        j := pred(j);
    (*ENDWHILE*) 
    IF  NOT table_constraint
    THEN
        (* integer + NOT NULL-check possible for one column *)
        a10new (acv, (mfirst_free - 1 - j + (max_loop * 2)) *
              sizeof(tgg00_StackOpType), and_arr)
    ELSE
        a10new (acv, (mfirst_free - 1 - j + max_loop) *
              sizeof(tgg00_StackOpType), and_arr);
    (*ENDIF*) 
    IF  and_arr = NIL
    THEN
        a07_b_put_error (acv, e_no_more_memory, 1);
    (*ENDIF*) 
    put_dummy := mupd_pos = 0;
    IF  put_dummy
    THEN
        BEGIN
        mb_st^[mfirst_free].etype := st_dummy;
        mfirst_free := mfirst_free + 1;
        mupd_pos    := mfirst_free;
        END;
    (* END PTS 1115407 E.Z. *)
    (*ENDIF*) 
    dmli.d_colbuf := dmli.d_sparr.pbasep^.sbase.bcolumn[
          dmli.d_sparr.pbasep^.sbase.bfirstcolind];
    fieldno := 1;
&   ifdef trace
    t01int4( ak_sem, 'max_loop    ', max_loop );
&   endif
    WHILE ((fieldno <= max_loop) AND
          (acv.a_returncode = 0)) DO
        BEGIN
        and_count     := 0;
        m_qual2       := mupd_cnt;
        dmli.d_fieldno     := dmli.d_colbuf^.creccolno;
        constraint_no := 0;
        IF  (dfa[ fieldno ].dml_node <> 0) AND
            table_constraint
        THEN
            BEGIN (* get constraint catalog record *)
            WITH ke, dmli.d_tabarr[ dmli.d_acttabindex ] DO
                BEGIN
&               ifdef trace
                t01int4 (ak_sem, 'check range ', fieldno);
&               endif
                IF  ouser = a01_i_temp
                THEN
                    BEGIN
                    ke := dmli.d_sparr.pbasep^.syskey;
                    sentrytyp := cak_etempconstraint
                    END
                ELSE
                    BEGIN
                    stableid  := otreeid.fileTabId_gg00;
                    sentrytyp := cak_econstraint;
                    END;
                (*ENDIF*) 
                slinkage[1] := chr(fieldno DIV 256);
                slinkage[2] := chr(fieldno MOD 256);
                skeylen   := mxak_standard_sysk;
                a10get_sysinfo (acv, ke, d_release, valp, e);
                END;
            (*ENDWITH*) 
            IF  e <> e_ok
            THEN
                a07_b_put_error (acv, e, 1)
            ELSE
                WITH valp^.sconstraint DO
                    BEGIN
&                   ifdef trace
                    FOR i := 1 TO MAX_COL_PER_TAB_GG00 DO
                        BEGIN
                        IF  i in dmli.d_upd_set
                        THEN
                            t01int4 (ak_sem, 'update colum', i);
                        (*ENDIF*) 
                        IF  i in ccolset
                        THEN
                            t01int4 (ak_sem, 'in constrain', i);
                        (*ENDIF*) 
                        END;
                    (*ENDFOR*) 
&                   endif
                    IF  NOT cfunction
                    THEN
                        IF  dmli.d_upd_set * ccolset = [  ]
                        THEN
                            (* constraint does not contain any updated *)
                            (* column ==> don't has to be checked      *)
                            dfa[ fieldno ].dml_node := 0;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
            END;
&       ifdef TRACE
        (*ENDIF*) 
        t01int4 (ak_sem, 'd_fieldno   ', dmli.d_fieldno);
        t01bool (ak_sem, 'd_fieldno se', dmli.d_fieldno in dmli.d_foundset);
&       endif
        IF  (dmli.d_fieldno in dmli.d_foundset) AND
            NOT table_constraint
        THEN
            BEGIN
            WITH dmli.d_colbuf^ DO
                BEGIN
                null_qual := NOT (ctkey in ccolpropset) AND
                      NOT (ctopt in ccolpropset)        AND
                      NOT int_qual;
                int_qual  :=  (cdatatyp = dfixed) AND cbinary;
&               ifdef TRACE
                t01bool (ak_sem, 'null_qual   ', null_qual);
                t01bool (ak_sem, 'ctkey in set', ctkey in ccolpropset);
                t01bool (ak_sem, 'ctopt in set', ctopt in ccolpropset);
                t01bool (ak_sem, 'int _qual   ', int_qual);
&               endif
                END;
            (*ENDWITH*) 
            END
        ELSE
            BEGIN
            null_qual := false;
            int_qual  := false
            END;
        (*ENDIF*) 
        IF  (dfa[ fieldno ].dml_node <> 0) OR null_qual OR int_qual
        THEN
            BEGIN
            IF  ( first AND ( acv.a_ex_kind = only_parsing ))
            THEN
                BEGIN
                first := false;
                a54_fixedpos( acv, dmli );
                END;
            (*ENDIF*) 
            IF  ( m_qual2 > 0 )
            THEN
                BEGIN
                WHILE (mb_st^ [mfirst_free - 1].eop = op_and) OR
                      (mb_st^ [mfirst_free - 1].eop = op_upd_view_and) DO
                    BEGIN
                    mupd_cnt    := mupd_cnt - 1;
                    mfirst_free := mfirst_free - 1;
                    and_count   := and_count + 1;
                    and_arr^[ and_count ] := mb_st^ [mfirst_free].eop
                    END;
                (*ENDWHILE*) 
                first_free := mfirst_free;
                IF  first_free + and_count < mb_st_max
                THEN
                    BEGIN
                    mfirst_free := succ(mfirst_free);
                    mupd_cnt    := succ(mupd_cnt)
                    END
                ELSE
                    a07_b_put_error (acv,
                          e_too_many_mb_stackentries, -mb_st_max);
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  (dfa[ fieldno ].dml_node <> 0) AND
            table_constraint AND
            (acv.a_returncode = 0)
        THEN
            BEGIN (* constraint stack entries into mess_buffer *)
            i := mfirst_free - 1;
            IF  i + valp^.sconstraint.cstack_cnt + 1 > mb_st_max
            THEN
                a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
            ELSE
                IF  mb_data_len  + valp^.b_sl -
                    valp^.sconstraint.cvalue_pos > mb_data_size
                THEN
                    a07_b_put_error (acv, e_too_many_mb_data, 1)
                ELSE
                    BEGIN
                    constraint_no := ord(valp^.syskey.slinkage[1]) * 256 +
                          ord(valp^.syskey.slinkage[2]);
                    i             := succ(i);
                    WITH valp^.sconstraint DO
                        g10mv ('VAK57 ',   1,    
                              sizeof (cstack), mb_st_size,
                              @cstack[cstackstart], 1, @mb_st^ [i],
                              1, cstack_cnt * STACK_ENTRY_MXGG00,
                              acv.a_returncode);
                    (*ENDWITH*) 
                    IF  acv.a_returncode = 0
                    THEN
                        BEGIN
&                       ifdef trace
                        t01int4 (ak_sem, 'moved st    ', 1);
                        FOR j := i TO
                              i + valp^.sconstraint.cstack_cnt - 1 DO
                            t01stackentry (ak_sem, mb_st^ [j], j);
                        (*ENDFOR*) 
&                       endif
                        mupd_cnt    := mupd_cnt    +
                              valp^.sconstraint.cstack_cnt;
                        mfirst_free := mfirst_free +
                              valp^.sconstraint.cstack_cnt;
                        IF  valp^.sconstraint.coldrange OR
                            (acv.a_sqlmode = sqlm_ansi)
                        THEN
                            WITH mb_st^ [mfirst_free] DO
                                BEGIN
                                etype       := st_truth;
                                eop         := op_none;
                                epos        := cgg04_is_not_false;
                                mupd_cnt    := mupd_cnt + 1;
                                mfirst_free := mfirst_free + 1
                                END;
                            (*ENDWITH*) 
                        (*ENDIF*) 
                        first_epos := 0;
                        FOR j := i TO
                              i + valp^.sconstraint.cstack_cnt - 1 DO
                            WITH mb_st^ [j] DO
                                IF  etype in [ st_value,
                                    st_language, st_format,
                                    st_date, st_time, st_timestamp,
                                    (* PTS 1116175 E.Z. *)
                                    st_utcdate,
                                    (* PTS 1109925 E.Z. *)
                                    st_utcdiff,
                                    st_user, st_usergroup, st_uid,
                                    st_sysdba, st_localsysdba,
                                    st_transaction,
                                    st_timezone (* PTS 1122262 E.Z. *)
                                    ]
                                THEN
                                    IF  first_epos = 0
                                    THEN
                                        first_epos := epos
                                    ELSE
                                        IF  etype = st_jump_false
                                        THEN
                                            ecol_tab[1] := chr(0);
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                (*ENDIF*) 
                            (*ENDWITH*) 
                        (*ENDFOR*) 
                        first_pos := valp^.sconstraint.cvalue_pos +
                              first_epos - cgg_rec_key_offset - 1;
                        move_len := valp^.b_sl - first_pos + 1;
                        g10mv ('VAK57 ',   2,    
                              sizeof(valp^), mb_data_size, @valp^,
                              first_pos, @mbp_buf, mb_data_len+1,
                              move_len,
                              acv.a_returncode);
                        IF  acv.a_returncode = 0
                        THEN
                            BEGIN
&                           ifdef trace
                            t01moveobj (ak_sem, mbp_buf, mb_data_len+1,
                                  mb_data_len + move_len);
&                           endif
                            FOR j := i TO
                                  i + valp^.sconstraint.cstack_cnt - 1 DO
                                WITH mb_st^ [j] DO
                                    IF  etype in [ st_value,
                                        st_language, st_format,
                                        st_date, st_time, st_timestamp,
                                        (* PTS 1116175 E.Z. *)
                                        st_utcdate,
                                        (* PTS 1109925 E.Z. *)
                                        st_utcdiff,
                                        st_user, st_usergroup, st_uid,
                                        st_sysdba, st_localsysdba,
                                        st_transaction,
                                        st_timezone (* PTS 1122262 E.Z. *)
                                        ]
                                    THEN
                                        BEGIN
                                        epos := epos - first_epos +
                                              mb_data_len + 1;
                                        IF  ((acv.a_ex_kind = only_parsing) AND
                                            (
                                            (* PTS 1122262 E.Z. *)
                                            ( etype = st_date )       OR
                                            ( etype = st_time )       OR
                                            ( etype = st_timestamp)   OR
                                            ( etype = st_utcdate )    OR
                                            ( etype = st_utcdiff )    OR
                                            ( etype = st_transaction) OR
                                            ( etype = st_timezone)
                                            ))
                                        THEN
                                            BEGIN
                                            aux_len     := mb_data_len;
                                            mb_data_len := epos - 1;
                                            a54_fixedpos (acv, dmli);
                                            mb_data_len := aux_len;
                                            a54datetime_parsinfo (acv, dmli, j)
                                            END
                                        ELSE
                                            IF  etype <> st_value
                                            THEN
                                                a54_internal_function (acv,
                                                      acv.a_mblock, j);
                                            (*ENDIF*) 
                                        (*ENDIF*) 
                                        END;
&                                   ifdef trace
                                    (*ENDIF*) 
                                (*ENDWITH*) 
                            (*ENDFOR*) 
                            t01moveobj (ak_sem, mbp_buf, mb_data_len+1,
                                  mb_data_len + 40);
&                           endif
                            mb_data_len := mb_data_len + move_len;
&                           ifdef trace
                            t01moveobj (ak_sem, mbp_buf, 1, mb_data_len);
                            t01int4 (ak_sem, 'final st    ', 2);
                            FOR j := i TO
                                  i + valp^.sconstraint.cstack_cnt - 1 DO
                                t01stackentry (ak_sem, mb_st^ [j], j);
                            (*ENDFOR*) 
&                           endif
                            stcount := valp^.sconstraint.cstack_cnt
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE (* not null into mess buffer *)
            IF  null_qual
            THEN
                BEGIN
                i := mfirst_free-1;
                IF  i+3 > mb_st_max
                THEN
                    a07_b_put_error (acv,
                          e_too_many_mb_stackentries, -mb_st_max)
                ELSE
                    IF  mb_data_len + 1 > mb_data_size
                    THEN
                        a07_b_put_error (acv, e_too_many_mb_data, 1)
                    ELSE
                        BEGIN
                        i := succ(i);
                        mupd_cnt := mupd_cnt+2;
                        mfirst_free := mfirst_free+2;
                        stcount := 1;
                        WITH dfa[ dmli.d_fieldno ] DO
                            mb_st^[ i ] := dml_col_ptr^.ccolstack;
                        (*ENDWITH*) 
                        WITH mb_st^ [i+1] DO
                            BEGIN
                            etype := st_value;
                            eop := op_not_null;
                            epos := mb_data_len+1;
                            elen_var := 1;
                            ecol_pos := 0;
                            mb_data_len := succ(mb_data_len);
                            mbp_buf [mb_data_len] := csp_undef_byte
                            END;
                        (*ENDWITH*) 
                        END
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            ELSE
                IF  int_qual
                THEN
                    BEGIN
                    int_qual    := false;
                    IF  mfirst_free + 1 > mb_st_max
                    THEN
                        a07_b_put_error (acv,
                              e_too_many_mb_stackentries, -mb_st_max)
                    ELSE
                        BEGIN
                        WITH dfa[ dmli.d_fieldno ] DO
                            BEGIN
                            mb_st^ [mfirst_free] :=
                                  dml_col_ptr^.ccolstack;
                            mb_st^ [mfirst_free].eop := op_is_integer;
                            END;
                        (*ENDWITH*) 
                        stcount             := 0;
                        mupd_cnt            := mupd_cnt + 1;
                        mfirst_free         := mfirst_free + 1
                        END;
                    (*ENDIF*) 
                    END
                ELSE
                    m_qual2 := 0;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        IF  m_qual2 = 0
        THEN
            BEGIN
            mb_st^[mupd_pos-1].ecol_tab[1] := chr(constraint_no DIV 256);
            mb_st^[mupd_pos-1].ecol_tab[2] := chr(constraint_no MOD 256);
            END
        ELSE
            BEGIN
            a65_set_operator (acv, op_and);
            a61_set_jump (acv.a_mblock, first_free, st_jump_false);
            WITH mb_st^ [first_free] DO
                BEGIN
                epos        := epos + mupd_cnt + 1;
                ecol_tab[1] := chr(constraint_no DIV 256);
                ecol_tab[2] := chr(constraint_no MOD 256);
                END;
            (*ENDWITH*) 
            IF  and_count > 0
            THEN
                BEGIN
                FOR j := and_count DOWNTO 1 DO
                    a65_set_operator(acv, and_arr^[ j ]);
                (*ENDFOR*) 
                FOR j := 1 TO first_free - 1 DO
                    IF  mb_st^ [j].etype = st_jump_false
                    THEN
                        IF  ( ( j + mb_st^ [j].epos ) > first_free )
                        THEN
                            WITH mb_st^ [j] DO
                                epos := epos + stcount+3
                            (*ENDWITH*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDFOR*) 
                END;
            (*ENDIF*) 
            ;
&           ifdef TRACE
            t01messblock (ak_sem, 'a57constr 2 ', acv.a_mblock);
&           endif
            END;
        (*ENDIF*) 
        IF  NOT int_qual
        THEN
            BEGIN
            fieldno := succ(fieldno);
            IF  dmli.d_colbuf^.cnextind > 0
            THEN
                dmli.d_colbuf := dmli.d_sparr.pbasep^.sbase.bcolumn[dmli.d_colbuf^.cnextind];
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  put_dummy
    THEN
        IF  mupd_cnt > 0
        THEN
            BEGIN
            mupd_pos := mupd_pos - 1;
            mupd_cnt := mupd_cnt + 1
            END
        ELSE
            BEGIN
            mupd_pos    := 0;
            mfirst_free := mfirst_free - 1
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  and_arr <> NIL
    THEN
        a10dispose (acv, and_arr)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak57late_unique_check_analyze (VAR mess_b : tgg00_MessBlock);
 
VAR
      found       : boolean;
      index_scan  : boolean;
      i           : integer;
      j           : integer;
      k           : integer;
      l           : integer;
      first_i_pos : integer;
      last_i_pos  : integer;
      qual_pos    : integer;
 
BEGIN
WITH mess_b, mb_qual^ DO
    BEGIN
&   ifdef TRACE
    t01messblock (ak_sem, 'late_unique ', mess_b);
&   endif
    qual_pos := mqual_pos;
    FOR i := mcol_pos TO mcol_pos + mcol_cnt - 1 DO
        IF  (mb_st^ [i].eop = op_expr_upd            ) OR
            (mb_st^ [i].eop = op_desc_expr_upd       ) OR
            (mb_st^ [i].eop = op_unique_expr_upd     ) OR
            (mb_st^ [i].eop = op_desc_unique_expr_upd)
        THEN
            BEGIN (* expression update found *)
            j     := qual_pos;
            found := false;
            WHILE NOT found DO
                IF  j = mqual_pos + mqual_cnt - 1
                THEN
                    found := true
                ELSE
                    IF  (mb_st^ [j].etype   = st_output      )
                        AND
                        ((mb_st^ [j].eop_out = op_o_output_var) OR
                        ( mb_st^ [j].eop_out = op_o_output_longvar))
                    THEN
                        found := true
                    ELSE
                        j := j + 1;
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDWHILE*) 
            (* corresponding expression is described from *)
            (* mb_st^ [qual_pos] to mb_st^ [j]            *)
            IF  mmult_cnt > 0
            THEN
                BEGIN
                (* check, if any unique multiple index *)
                (* requires late unique check          *)
                first_i_pos := mmult_pos;
                WHILE first_i_pos < mmult_pos + mmult_cnt DO
                    BEGIN
                    last_i_pos := first_i_pos;
                    found      := false;
                    index_scan := true;
                    WHILE index_scan DO
                        BEGIN
                        WITH mb_st^ [last_i_pos] DO
                            IF  (etype    = mb_st^ [i].etype   ) AND
                                (epos     = mb_st^ [i].epos    ) AND
                                (elen_var = mb_st^ [i].elen_var)
                            THEN
                                found := true;
                            (*ENDIF*) 
                        (*ENDWITH*) 
                        IF  last_i_pos = mmult_pos + mmult_cnt - 1
                        THEN
                            index_scan := false
                        ELSE
                            IF  mb_st^ [last_i_pos+1].ecol_tab[ 1 ] =
                                mb_st^ [first_i_pos].ecol_tab[ 1 ]
                            THEN
                                last_i_pos := last_i_pos + 1
                            ELSE
                                index_scan := false;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END;
                    (*ENDWHILE*) 
                    WITH mb_st^ [first_i_pos] DO
                        found := found AND
                              ((eop=op_unique) OR (eop=op_unique_desc));
                    (*ENDWITH*) 
&                   ifdef trace
                    t01int4 (ak_sem, 'index found ', ord (found));
                    FOR l := first_i_pos TO last_i_pos DO
                        t01stackentry (ak_sem, mb_st^ [l], l);
                    (*ENDFOR*) 
&                   endif
                    IF  found
                    THEN
                        BEGIN
                        (* current expression update column is   *)
                        (* part of the multiple index described  *)
                        (* from first_i_pos to last_i_pos, check *)
                        (* if any column of the index is part of *)
                        (* the expression                        *)
                        k := first_i_pos;
                        WHILE k <= last_i_pos DO
                            BEGIN
                            l := qual_pos;
                            WHILE l < j DO
                                BEGIN
                                IF  (mb_st^ [k].etype = mb_st^ [l].etype) AND
                                    (mb_st^ [k].epos  = mb_st^ [l].epos ) AND
                                    (mb_st^ [k].elen_var = mb_st^ [l].elen_var)
                                THEN
                                    BEGIN
&                                   ifdef trace
                                    t01stackentry (ak_sem, mb_st^ [first_i_pos],
                                          first_i_pos);
&                                   endif
                                    IF  mb_st^ [first_i_pos].eop = op_unique
                                    THEN
                                        mb_st^ [first_i_pos].eop :=
                                              op_late_asc_unique_check
                                    ELSE
                                        mb_st^ [first_i_pos].eop :=
                                              op_late_desc_unique_check;
                                    (*ENDIF*) 
                                    k := last_i_pos + 1;
                                    l := j
                                    END
                                ELSE
                                    l := l + 1
                                (*ENDIF*) 
                                END;
                            (*ENDWHILE*) 
                            k := k + 1
                            END;
                        (*ENDWHILE*) 
                        END;
                    (*ENDIF*) 
                    first_i_pos := last_i_pos + 1
                    END;
                (*ENDWHILE*) 
                END;
            (*ENDIF*) 
            IF  (mb_st^ [i].eop = op_unique_expr_upd) OR
                (mb_st^ [i].eop = op_desc_unique_expr_upd)
            THEN
                WITH mb_st^[ i ] DO
                    (* check, if single index requires *)
                    (* late unique check, true, if     *)
                    (* the column to be updated is     *)
                    (* part of the expression          *)
                    WHILE qual_pos < j DO
                        IF  (mb_st^ [qual_pos].etype = etype) AND
                            (mb_st^ [qual_pos].epos  = epos ) AND
                            (mb_st^ [qual_pos].elen_var = elen_var)
                        THEN
                            BEGIN
                            IF  eop = op_unique_expr_upd
                            THEN
                                eop := op_late_asc_unique_check
                            ELSE
                                eop := op_late_desc_unique_check;
                            (*ENDIF*) 
                            qual_pos := j
                            END
                        ELSE
                            qual_pos := qual_pos + 1;
                        (*ENDIF*) 
                    (*ENDWHILE*) 
                (*ENDWITH*) 
            (*ENDIF*) 
            qual_pos := j + 1
            END;
        (*ENDIF*) 
    (*ENDFOR*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak57one_upd_col (
            VAR acv              : tak_all_command_glob;
            VAR dmli             : tak_dml_info;
            VAR dfa              : tak_dfarr;
            VAR upd_col_set      : tak_columnset;
            use_only_varlongchar : boolean);
 
VAR
      n       : tsp00_KnlIdentifier;
 
BEGIN
WITH acv, dmli, a_mblock, mb_data^ DO
    BEGIN
    d_fieldno  := 1;
    WHILE ((d_fieldno <= d_sparr.pbasep^.sbase.bmaxcol) AND
          (a_returncode = 0)) DO
        WITH dfa[ d_fieldno ] DO
            BEGIN
&           ifdef trace
            t01int4 (ak_sem, 'dm_fieldno  ', d_fieldno);
            t01int4 (ak_sem, 'dm_node     ', dml_node);
            t01int4 (ak_sem, 'colno_subque', dml_colno_in_subquery);
            t01int4 (ak_sem, 'dm_res_index', dml_res_index);
            t01int4 (ak_sem, 'btablekind  ',
                  ord(d_sparr.pbasep^.sbase.btablekind));
            t01int4 (ak_sem, 'dm_join_dml ', ord(d_join_dml));
&           endif
            IF  dml_node <> 0
            THEN
                IF  (dml_col_ptr^.ccolstack.etype = st_varlongchar)
                    = use_only_varlongchar
                THEN
                    BEGIN (* update column *)
                    WITH a_ap_tree^[ dml_node ] DO
                        BEGIN
                        d_upd_set := d_upd_set + [
                              dml_col_ptr^.creccolno ];
                        IF  ((n_proc = a64) OR
                            (n_proc = a641) OR
                            (n_proc = a63query_spec) OR
                            ((n_proc = a63) AND (n_subproc = cak_x_start_union)) OR
                            ( n_symb in [
                            s_authid, s_tablename, s_columnname,
                            s_minus, s_plus,
                            s_stamp
                            ]) OR
                            (((n_symb = s_nextval) OR (n_symb = s_currval)) AND
                            (a_mblock.mb_type2 = mm_qual)) OR
                            (dml_col_ptr^.cdatatyp in
                            [dlonga, dlongb, dlonguni,
                            dstra, dstrb, dstruni]))
                            AND
                            NOT (d_join_dml AND
                            (d_sparr.pbasep^.sbase.btablekind <> tview))
                        THEN (* expression update *)
                            BEGIN
                            upd_col_set := upd_col_set + [ d_fieldno ];
                            d_foundset := d_foundset + [ d_fieldno ]
                            END
                        ELSE
                            IF  d_sparr.pbasep^.sbase.btablekind <> tview
                            THEN
                                BEGIN
                                IF  d_linkbuf <> NIL
                                THEN
                                    WITH d_linkbuf^.slinkposinfo DO
                                        lupd_col_info := lupd_col_info +
                                              [ dml_col_ptr^.creccolno];
                                    (*ENDWITH*) 
                                (*ENDIF*) 
                                WITH mb_qual^, dml_col_ptr^ DO
                                    BEGIN
                                    mcol_cnt := succ(mcol_cnt);
                                    mb_st^ [mfirst_free] := ccolstack;
                                    mfirst_free := mfirst_free + 1
                                    END;
                                (*ENDWITH*) 
                                IF  n_symb = s_default
                                THEN
                                    IF  ctdefault in dml_col_ptr^.ccolpropset
                                    THEN
                                        BEGIN
                                        a56one_default_value (acv, dmli,
                                              dml_col_ptr^, fp_val_all_with_len);
                                        IF  a_returncode =
                                            a07_return_code (
                                            e_default_spec_not_allowed, a_sqlmode)
                                        THEN
                                            BEGIN
                                            a_returncode := 0;
                                            a_errorpos   := 0;
                                            n_symb := s_stamp;
                                            IF  dml_col_ptr^.
                                                ccolstack.etype = st_varlongchar
                                            THEN
                                                a07_b_put_error (acv,
                                                      e_varchar_not_allowed, n_pos)
                                            ELSE
                                                BEGIN
                                                WITH mb_qual^, dml_col_ptr^ DO
                                                    BEGIN
                                                    mcol_cnt    := pred(mcol_cnt);
                                                    mfirst_free := pred(mfirst_free)
                                                    END;
                                                (*ENDWITH*) 
                                                upd_col_set := upd_col_set + [ d_fieldno ];
                                                d_foundset := d_foundset + [ d_fieldno ]
                                                END
                                            (*ENDIF*) 
                                            END
                                        ELSE
                                            dml_node := 0;
                                        (*ENDIF*) 
                                        END
                                    ELSE
                                        BEGIN
                                        a061get_colname (dml_col_ptr^, n);
                                        a07_nb_put_error (acv,
                                              e_default_spec_not_allowed,
                                              n_pos, n)
                                        END
                                    (*ENDIF*) 
                                ELSE
                                    BEGIN
                                    a55_found_one_value (acv, dmli, dfa);
                                    dml_node := 0
                                    END;
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END;
                    (*ENDWITH*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            d_fieldno := succ(d_fieldno);
            END
        (*ENDWITH*) 
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak57subquery (
            VAR acv           : tak_all_command_glob;
            VAR dmli          : tak_dml_info;
            first_node        : tsp00_Int2;
            colno_in_subquery : tsp00_Int2;
            VAR colinfo       : tak00_columninfo);
 
VAR
      finished       : boolean;
      subquery_count : integer;
      i              : integer;
      lengths_before : integer;
      datatype_node  : tsp00_Int2;
      dummy_iolen    : tsp00_Int2;
      convert_t      : tak_convert_type;
      itree          : tgg00_FileId;
      colname        : tsp00_KnlIdentifier;
 
BEGIN
WITH acv, a_mblock, mb_qual^ DO
    BEGIN
    IF  mfirst_free > mb_st_max
    THEN
        a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
    ELSE
        BEGIN
        datatype_node := a_ap_tree^[ first_node ].n_sa_level;
        lengths_before := 0;
        i := -1;
        IF  datatype_node > 0
        THEN
            BEGIN
            (* PTS 1122102 E.Z. *)
            i := 1;
            finished := false;
            WHILE (i < colno_in_subquery) AND NOT finished DO
                BEGIN
                lengths_before := lengths_before +
                      a_ap_tree^[ datatype_node ].n_length;
                IF  a_ap_tree^ [ datatype_node ].n_sa_level > 0
                THEN
                    BEGIN
                    datatype_node := a_ap_tree^ [ datatype_node ].n_sa_level;
                    i := succ(i);
                    END
                ELSE
                    finished := true
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            END;
&       ifdef TRACE
        (*ENDIF*) 
        t01int4 (ak_sem, 'datatype_nod', datatype_node);
        t01int4 (ak_sem, 'i           ', i);
&       endif
        subquery_count := acv.a_ap_tree^[ first_node ].n_length;
        msubquery := true;
        WITH mb_st^ [mfirst_free] DO
            BEGIN
            mqual_cnt := succ(mqual_cnt);
            etype := st_get_subquery;
            eop := op_none;
            WITH mb_data^ DO
                BEGIN
                g04build_temp_tree_id (itree, a_transinf.tri_trans);
                itree.fileTfnTemp_gg00 := ttfnSubquery_egg00;
                itree.fileLevel_gg00[ 1 ] := chr(subquery_count DIV 100);
                itree.fileLevel_gg00[ 2 ] := chr(subquery_count MOD 100);
                itree.fileResultSite_gg00   := cgg04_nil_site;
&               ifdef trace
                t01int4 (ak_sem, 'first_node  ', first_node);
&               endif
                IF  mb_data_len + FILE_ID_MXGG00 <= mb_data_size
                THEN
                    BEGIN
                    epos := mb_data_len + 1;
                    g10mv ('VAK57 ',   3,    
                          sizeof(itree), mb_data_size, @itree, 1,
                          @mbp_buf, epos, FILE_ID_MXGG00,
                          a_returncode);
                    mb_data_len := mb_data_len + FILE_ID_MXGG00;
                    END
                ELSE
                    a07_b_put_error (acv, e_too_many_mb_data, 1)
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            elen_var := lengths_before + 1;
            (* PTS 1116323 E.Z. *)
            IF  i = colno_in_subquery
            THEN
                ecol_pos := a_ap_tree^[ datatype_node ].n_length
            ELSE
                ecol_pos := colinfo.cinoutlen;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        mfirst_free := succ(mfirst_free);
        IF  ((a_ap_tree^[ first_node ].n_proc = a63query_spec)
            AND
            (a_dt_format <> dtf_normal)
            AND
            ((dmli.d_datatype = ddate) OR
            ( dmli.d_datatype = dtime) OR
            ( dmli.d_datatype = dtimestamp)))
        THEN
            a641check_datetime(acv, dmli, dmli.d_datatype);
        (*ENDIF*) 
        IF  i = colno_in_subquery
        THEN
            BEGIN
            dummy_iolen := 0;
            (* PTS 1000985/1001162 E.Z. *)
            IF  NOT a65_datatypes_ok (acv, dmli, dmli.d_datatype, dummy_iolen,
                a_ap_tree^[ datatype_node ].n_datatype,
                NOT c_is_subquery (* although it is one !!! *)
                , first_node,
                a_ap_tree^[ first_node ].n_pos, c_convert, convert_t)
            THEN
                BEGIN
                a_returncode := 0;
                a061get_colname  (colinfo, colname);
                a07_nb_put_error (acv, e_incompatible_datatypes,
                      a_ap_tree^[ first_node ].n_pos, colname)
                END
            (*ENDIF*) 
            END
        ELSE
            IF  dmli.d_corr = no_correlation
            THEN
                BEGIN
                a_returncode := 0;
                a061get_colname (colinfo, colname);
                a07_nb_put_error (acv, e_incompatible_datatypes, 1, colname)
                END
            ELSE
                IF  datatype_node > 0
                THEN
                    a01_dt_put_datatype_node (acv,
                          a_ap_tree^[ datatype_node ].n_sa_level,
                          dmli.d_datatype, colinfo.cdatalen,
                          colinfo.cdatafrac, colinfo.cinoutlen)
                ELSE
                    a01_dt_put_datatype_node (acv,
                          a_ap_tree^[ first_node ].n_sa_level,
                          dmli.d_datatype, colinfo.cdatalen,
                          colinfo.cdatafrac, colinfo.cinoutlen);
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
&       ifdef TRACE
        t01int4 (ak_sem, 'd_corr      ', ord(dmli.d_corr));
        t01int4 (ak_sem, 'return_code ',
              a_returncode);
&       endif
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a57update_with_value_expr (
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info;
            VAR dfa  : tak_dfarr);
      (*==========================================================*)
      (* i in d_foundset ==> expression update column             *)
      (*                                                          *)
      (* returns d_foundset : all not null columns without        *)
      (*                      constraints                   or    *)
      (*                      INTEGER, SMALLINT has to be checked *)
      (*         dfa        : dml_node <> 0 ==> simple Constraint *)
      (*                      defined for column                  *)
      (*==========================================================*)
 
VAR
      expr_update : boolean;
      m_datatype  : tsp00_DataType;
      upd_col_cnt : integer;
      colin       : tak00_scolinf;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    d_wherepart := true;
    d_pars_kind := fp_val_all_without_l;
    d_fieldno   := 1;
    upd_col_cnt := 0;
    expr_update := false;
    WHILE ((d_fieldno <= d_sparr.pbasep^.sbase.bmaxcol) AND
          (a_returncode = 0)) DO
        BEGIN
        IF  d_fieldno in d_foundset
        THEN
            BEGIN
            upd_col_cnt := succ(upd_col_cnt);
            WITH dfa[ d_fieldno ], a_mblock, mb_qual^ DO
                BEGIN
                WITH  dml_col_ptr^ DO
                    BEGIN
                    IF  ((cdatatyp = dfixed) OR (cdatatyp = dfloat) OR
                        (cdatatyp = dvfloat))
                    THEN
                        d_datatype := dnumber
                    ELSE
                        d_datatype := cdatatyp;
                    (*ENDIF*) 
                    d_udt_datatype := cudtdatatype;
                    IF  cdatatyp in [ dlonga, dlongb,
                        dlonguni, dstra, dstrb, dstruni ]
                    THEN
                        IF  mfirst_free+1 > mb_st_max
                        THEN
                            a07_b_put_error (acv, e_too_many_mb_stackentries,
                                  -mb_st_max)
                        ELSE
                            BEGIN
                            mqual_cnt := succ(mqual_cnt);
                            mfirst_free := succ(mfirst_free);
                            mb_st^ [mfirst_free-1] := ccolstack;
                            END
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
                m_datatype         := d_datatype;
                d_colbuf           := dml_col_ptr;
                d_colptr           := dml_col_ptr;
                colin.sci_len      := 0;
                d_first_tab        := 0;
                d_allowed          := may_more_tabs;
                d_change_date_time := false;
                d_const_value_expr := ( a_is_ddl = no_ddl);
                d_param_st_begin   := 0;
                d_param_st_index   := 0;
                IF  ((a_ap_tree^[ dml_node ].n_proc = a63query_spec) OR
                    ((a_ap_tree^[ dml_node ].n_proc = a63) AND
                    ( a_ap_tree^[ dml_node ].n_subproc  = cak_x_start_union)))
                THEN
                    IF  d_sparr.pbasep^.sbase.btablekind = tview
                    THEN
                        a07_b_put_error (acv, e_not_implemented,
                              a_ap_tree^[ dml_node ].n_pos)
                    ELSE
                        ak57subquery (acv, dmli, dml_node,
                              dml_colno_in_subquery, dml_col_ptr^)
                    (*ENDIF*) 
                ELSE
                    BEGIN
                    expr_update := true;
                    IF  ((a_ap_tree^[ dml_node ].n_proc = a64) AND
                        ( a_ap_tree^[ dml_node ].n_subproc  = cak_x_value_expression))
                    THEN
                        a65_val_expr (acv, dmli, colin,
                              a_ap_tree^[ dml_node ].n_lo_level)
                    ELSE
                        a65_val_expr (acv, dmli, colin, dml_node);
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                d_change_date_time := true;
                IF  a_returncode = 0
                THEN
                    BEGIN
                    WITH  dml_col_ptr^ DO
                        IF  cdatatyp in [ dlonga, dlongb, dlonguni ]
                        THEN
                            mb_st^ [mfirst_free-1].eop := op_longcol_update
                        ELSE
                            IF  cdatatyp in [ dstra, dstrb, dstruni ]
                            THEN
                                mb_st^ [mfirst_free-1].eop := op_scol_upd;
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDWITH*) 
                    IF  d_datatype = dnumber
                    THEN
                        BEGIN
                        IF  mb_st^ [mfirst_free-1].etype <> st_noround
                        THEN
                            IF  mfirst_free+1 > mb_st_max
                            THEN
                                a07_b_put_error (acv,
                                      e_too_many_mb_stackentries,
                                      -mb_st_max)
                            ELSE
                                BEGIN
                                mqual_cnt   := succ(mqual_cnt);
                                mfirst_free := succ(mfirst_free);
                                WITH mb_st^ [mfirst_free-1] DO
                                    BEGIN
                                    etype    := st_result;
                                    eop      := op_none;
                                    ecol_tab[ 1 ] := chr(0);
                                    ecol_tab[ 2 ] := chr(0)
                                    END;
                                (*ENDWITH*) 
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        WITH  dml_col_ptr^,
                             mb_st^ [mfirst_free-1] DO
                            BEGIN
                            epos     := cdatalen;
                            elen_var := cdatafrac - cak_frac_offset;
                            END
                        (*ENDWITH*) 
                        END
                    ELSE
                        BEGIN
                        IF  m_datatype in
                            [ ddate, dtime, dtimestamp ]
                        THEN
                            BEGIN
                            IF  mfirst_free+1 > mb_st_max
                            THEN
                                a07_b_put_error (acv,
                                      e_too_many_mb_stackentries,
                                      -mb_st_max);
                            (*ENDIF*) 
                            IF  a_returncode = 0
                            THEN
                                WITH mb_st^ [mfirst_free] DO
                                    BEGIN
                                    etype        := st_build_in_func;
                                    eop_build_in := op_b_check_format;
                                    eformat := dtf_normal;
                                    edatatype := m_datatype;
                                    elanguage := a_ak_language;
                                    elength   := 0;
                                    END;
                                (*ENDWITH*) 
                            (*ENDIF*) 
                            mfirst_free := succ(mfirst_free);
                            mqual_cnt   := succ(mqual_cnt)
                            END;
                        (*ENDIF*) 
                        IF  mfirst_free+1 > mb_st_max
                        THEN
                            a07_b_put_error (acv, e_too_many_mb_stackentries,
                                  -mb_st_max);
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  a_returncode = 0
                    THEN
                        BEGIN
                        mqual_cnt := succ(mqual_cnt);
                        WITH  dml_col_ptr^,
                             mb_st^ [mfirst_free] DO
                            BEGIN
                            etype    := st_output;
                            IF  (ccolstack.etype = st_varlongchar)
                                OR
                                (* st_fixkey, st_varkey *)
                                (cinoutlen > cak_maxvarcoliolen)
                            THEN
                                eop_out  := op_o_output_longvar
                            ELSE
                                eop_out  := op_o_output_var;
                            (*ENDIF*) 
                            epos     := 0;
                            elen_var := cinoutlen;
                            ecol_pos := 0;
                            END;
                        (*ENDWITH*) 
                        mfirst_free := succ(mfirst_free);
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            WITH dfa[ d_fieldno ], dml_col_ptr^ DO
                BEGIN
                IF  (ctopt in ccolpropset) AND
                    ((cdatatyp <> dfixed) OR NOT cbinary)
                THEN
                    d_foundset := d_foundset - [ d_fieldno ];
                (*ENDIF*) 
                IF  d_sparr.pbasep^.sbase.btablekind = tview
                THEN
                    dml_res_index := upd_col_cnt
                ELSE
                    dml_node := 0
                (*ENDIF*) 
                END
            (*ENDWITH*) 
            END;
        (*ENDIF*) 
        d_fieldno := succ(d_fieldno)
        END;
    (*ENDWHILE*) 
    IF  (expr_update AND (a_returncode = 0))
    THEN
        ak57late_unique_check_analyze (a_mblock)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a57_aupdate_statement (
            VAR acv      : tak_all_command_glob;
            VAR put_node : tsp00_Int2;
            kw_index     : integer);
 
VAR
      column_list : boolean;
      query_upd   : boolean;
      curr_n      : tsp00_Int2;
      last_n      : tsp00_Int2;
      upd_col_n   : tsp00_Int2;
      list_cnt    : integer;
      scvh        : tak_scanner_glob;
 
BEGIN
WITH acv, a_scv DO
    BEGIN
    a_scv.sc_states := a_scv.sc_states + [ scs_hint_allowed ];
    a01_next_symbol (acv);
    IF  ((kw_index = cak_i_update)             AND
        (a01_eqkey (a01kw[ cak_i_statistics ], a_sqlmode,
        a_cmd_part^.sp1p_buf, a_scv) OR
        a01_eqkey (a01kw[ cak_i_stat ], a_sqlmode,
        a_cmd_part^.sp1p_buf, a_scv)))
        OR
        (kw_index = cak_i_analyze)
    THEN
        ak57aupd_stat_stmt (acv, kw_index, put_node)
    ELSE
        BEGIN
        a_return_segm^.sp1r_function_code := csp1_update_fc;
        IF  kw_index = cak_i_update
        THEN
            IF  NOT a_cmd_segment_header.sp1c_mass_cmd
            THEN
                a01_call_put (acv, a57, cak_x_update, put_node)
            ELSE
                BEGIN
                acv.a_return_segm^.sp1r_function_code :=
                      acv.a_return_segm^.sp1r_function_code + csp1_masscmd_fc_offset;
                a_precomp_info_byte := csp1_p_mass_command;
                a01_call_put (acv, a57, cak_x_mupdate, put_node)
                END
            (*ENDIF*) 
        ELSE
            a01_call_put (acv, a57, cak_x_append, put_node);
        (*ENDIF*) 
        a_ap_tree^[put_node].n_length := 0;
        curr_n                       := put_node;
        a_select_node                := put_node;
        IF  acv.a_scv.sc_symb = s_hint
        THEN
            a80_ahint_statement(acv, cak_x_update_hint, put_node);
        (*ENDIF*) 
        a_scv.sc_states := a_scv.sc_states - [ scs_hint_allowed ];
        IF  ((a01_eqkey (a01kw[ cak_i_of ], a_sqlmode,
            a_cmd_part^.sp1p_buf, a_scv)) AND
            (a_sqlmode = sqlm_internal))
        THEN
            a01_next_symbol (acv);
        (*ENDIF*) 
        a02_s_atable_spec (acv, a_ap_tree^[ curr_n ].n_lo_level, last_n);
        IF  a01_eqkey (a01kw[ cak_i_set ], a_sqlmode,
            a_cmd_part^.sp1p_buf, a_scv)
        THEN
            BEGIN
            upd_col_n := last_n;
            REPEAT
                a01_next_symbol (acv); (* SET / ',' *)
                scvh := a_scv;
                column_list := false;
                query_upd := false;
                IF  ((sc_symb = s_identifier) AND
                    ((a_sqlmode = sqlm_oracle) OR
                    ( a_sqlmode = sqlm_internal)))
                THEN
                    BEGIN
                    a01_next_symbol (acv);
                    IF  sc_symb = s_comma
                    THEN
                        column_list := true;
                    (*ENDIF*) 
                    a_scv := scvh
                    END
                ELSE
                    IF  ((sc_symb = s_leftpar) AND
                        ((a_sqlmode = sqlm_oracle) OR
                        ( a_sqlmode = sqlm_internal)))
                    THEN
                        BEGIN
                        column_list := true;
                        query_upd := true;
                        a01_next_symbol (acv);
                        END
                    ELSE
                        (* h.b. PTS 1001683 *)
                        IF  (a_sqlmode = sqlm_oracle) OR
                            (a_sqlmode = sqlm_internal)
                        THEN
                            a07_error (acv, e_missing_identifier,
                                  curr_n, last_n);
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  a_returncode = 0
                THEN
                    IF  column_list
                    THEN
                        BEGIN
                        (* SET col1, col2 = (val expr1, val expr2) *)
                        a01_call_put (acv, a56, cak_x_enum_values, curr_n);
                        a_ap_tree^[ upd_col_n ].n_sa_level := curr_n;
                        last_n := curr_n;
                        upd_col_n := curr_n;
                        a01_call_put (acv, a56, cak_x_column_list, curr_n);
                        a_ap_tree^[ last_n ].n_lo_level := curr_n;
                        a02_l_acolumn_list (acv, a_ap_tree^[ curr_n ].n_lo_level,
                              last_n);
                        last_n := curr_n;
                        IF  query_upd
                        THEN
                            a01_force_symbol (acv, s_rightpar,
                                  put_node, last_n);
                        (*ENDIF*) 
                        IF  a_returncode = 0
                        THEN
                            BEGIN
                            curr_n := a_ap_tree^[ curr_n ].n_lo_level;
                            list_cnt := 1;
                            WHILE a_ap_tree^[ curr_n ].n_sa_level <> 0 DO
                                BEGIN
                                list_cnt := succ(list_cnt);
                                curr_n := a_ap_tree^[ curr_n ].n_sa_level
                                END;
                            (*ENDWHILE*) 
                            a_ap_tree^[ last_n ].n_length := list_cnt;
                            a01_force_symbol (acv,
                                  s_equal, put_node, last_n);
                            END;
                        (*ENDIF*) 
                        IF  a_returncode = 0
                        THEN
                            BEGIN
                            scvh := a_scv;
                            a01_force_symbol (acv,
                                  s_leftpar, put_node, last_n);
                            IF  a_returncode = 0
                            THEN
                                BEGIN
                                IF  ((a01_eqkey (a01kw[ cak_i_select ],
                                    a_sqlmode,
                                    a_cmd_part^.sp1p_buf, a_scv)) AND
                                    query_upd)
                                THEN
                                    BEGIN
                                    a_cpart_type := cpt_in_where_clause;
                                    (* a_cpart_type is for corr subquery *)
                                    a_scv := scvh;
                                    a60_asub_query (acv,
                                          a_ap_tree^[ last_n ].n_sa_level,
                                          list_cnt, (
                                          c_one_valsubquery AND (list_cnt = 1)));
                                    last_n := a_ap_tree^[ last_n ].n_sa_level;
                                    END
                                ELSE
                                    BEGIN
                                    a01_call_put (acv, a56, cak_x_value_list, curr_n);
                                    a_ap_tree^[ last_n ].n_sa_level := curr_n;
                                    a03_ln_aexpression_list (acv,
                                          a_ap_tree^[ curr_n ].n_lo_level, last_n);
                                    a01_force_symbol (acv,
                                          s_rightpar, put_node, last_n)
                                    END
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        curr_n := upd_col_n;
                        END
                    ELSE
                        BEGIN
                        (* SET col =  value expr      , col =  value            ... *)
                        (* SET col = (value expr/query), col = (value expr/query)... *)
                        a_allow_functions := tf_no_func;
                        a01_call_put (acv, a57, cak_x_update_set,
                              a_ap_tree^[ upd_col_n ].n_sa_level);
                        curr_n := a_ap_tree^[ upd_col_n ].n_sa_level;
                        upd_col_n := curr_n;
                        last_n := curr_n;
                        ak57aupdset_clause (acv,
                              a_ap_tree^[ curr_n ].n_lo_level, last_n);
                        WHILE ((sc_symb = s_comma) AND
                              (a_returncode = 0)) DO
                            BEGIN
                            scvh := a_scv;
                            a01_next_symbol (acv);
                            ak57aupdset_clause (acv,
                                  a_ap_tree^[ last_n ].n_sa_level, last_n);
                            END;
                        (*ENDWHILE*) 
                        IF  ((a_returncode <> 0) AND
                            ( sc_symb = s_comma) AND
                            ((a_sqlmode = sqlm_oracle) OR
                            ( a_sqlmode = sqlm_internal)))
                        THEN
                            BEGIN
                            (* a column list began *)
                            a_returncode := 0;
                            a_scv       := scvh;
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                (*ENDIF*) 
            UNTIL
                ((sc_symb <> s_comma) OR
                ( a_returncode <> 0))
            (*ENDREPEAT*) 
            END
        ELSE
            IF  ((sc_symb = s_leftpar) AND
                (a_sqlmode = sqlm_internal))
            THEN
                BEGIN
                a56_aenumerated_values (acv, NOT c_select_allowed,
                      a_ap_tree^[ last_n ].n_sa_level, curr_n);
                curr_n := a_ap_tree^[ last_n ].n_sa_level
                END
            ELSE
                a07_error (acv, e_wanted_keyword, curr_n, last_n);
            (*ENDIF*) 
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            BEGIN
            IF  ((a01_eqkey (a01kw[ cak_i_where ], a_sqlmode,
                a_cmd_part^.sp1p_buf, a_scv))
                OR (a01_eqkey (a01kw[ cak_i_key ], a_sqlmode,
                a_cmd_part^.sp1p_buf, a_scv)))
            THEN
                BEGIN
                a55_asearch_clause (acv, a_ap_tree^[ curr_n ].n_sa_level,
                      last_n);
                curr_n := a_ap_tree^[ curr_n ].n_sa_level
                END
            ELSE
                WITH a_transinf.tri_trans DO
                    trWarning_gg00 := trWarning_gg00 + [ warn0_exist,
                          warn4_nullwhere ];
                (*ENDWITH*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  (a_returncode = 0)                   AND
            (sc_symb <> s_eof) (* PTS 1106990 *)
            AND
            (
            (a_proc_compile in [pct_insert_trigger,
            pct_update_trigger,
            pct_delete_trigger,
            pct_multi_trigger])  OR
            (a_trigger_level > 0)
            )
        THEN
            IF  a01_eqkey (a01kw[ cak_i_ignore ], a_sqlmode,
                a_cmd_part^.sp1p_buf, a_scv)
            THEN
                BEGIN
                a01_next_symbol (acv);
                IF  a01mandatory_keyword (acv, cak_i_trigger)
                THEN
                    BEGIN
                    acv.a_ap_tree^[ put_node ].n_length := cak_i_ignore;
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        a01_is_end_symbol (acv);
        END;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a57_b_update_string (
            VAR acv      : tak_all_command_glob;
            VAR dmli     : tak_dml_info;
            VAR dfa      : tak_dfarr;
            VAR isparr   : tak_syspointerarr;
            start_node   : tsp00_Int2;
            VAR sr_rec   : tak71_strat_rec;
            VAR all_done : boolean;
            new_parsinfo : boolean;
            VAR linkbuf  : tak_sysbufferaddress);
 
VAR
      key_found    : boolean;
      found        : boolean;
      b_err        : tgg00_BasisError;
      act_node     : integer;
      icurr_n      : integer;
      tab_node     : integer;
      upd_n        : tsp00_Int2;
      sel_upd_set  : tak_columnset;
      upd_col_set  : tak_columnset;
      not_used     : tak_charset;
      parsk        : tak_parskey;
      sysk         : tgg00_SysInfoKey;
      tempinfo_buf : tak_sysbufferaddress;
 
BEGIN
act_node           := acv.a_ap_tree^[ start_node ].n_lo_level;
dmli.d_acttabindex := 1;
dmli.d_cntfromtab  := 1;
tab_node := acv.a_ap_tree^[ act_node ].n_lo_level;
a660_search_one_table (acv, dmli, tab_node, c_all,
      c_check_teresult, no_lock, r_upd);
IF  acv.a_returncode = 0
THEN
    WITH acv, dmli, d_sparr.pbasep^.sbase DO
        IF  btablekind = tview
        THEN
            BEGIN
            all_done := true;
            a59_join_view (acv, dmli, dfa, start_node, m_update);
            isparr := d_sparr
            END
        ELSE
            (* PTS 1122050 E.Z. *)
            IF  ftsArchive_egg00 in d_tabarr[ 1 ].otreeid.fileType_gg00
            THEN
                a07_b_put_error (acv, e_invalid_tabletype,
                      acv.a_ap_tree^[tab_node].n_pos)
            ELSE
                BEGIN
                a06a_mblock_init (acv, m_update, mm_qual,
                      d_tabarr[ 1 ].otreeid);
                (* PTS 1113190 E.Z. *)
                IF  ((is_secondary_table in blinkexist) OR
                    (is_primary_table   in blinkexist))
                    AND
                    NOT acv.a_isReplicationSession
                THEN
                    BEGIN
                    not_used := [  ];
                    a56alloc_linkpos_info (acv,
                          d_sparr, m_update, d_linkbuf)
                    END;
                (*ENDIF*) 
                IF  ((bsegmentid = cak00_public_segment_id) OR
                    ( a_isolation_info = temp_lock_rec_needed))
                    AND
                    (a_isolation_info <> temp_lock_rec_get)
                THEN
                    BEGIN
                    a_ex_kind        := only_parsing;
                    a_isolation_info := temp_lock_rec_needed;
                    IF  acv.a_command_kind = single_command
                    THEN
                        acv.a_command_kind := link_command
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  ((a_ex_kind = only_parsing) AND new_parsinfo)
                THEN
                    BEGIN
                    IF  start_node <> a_ap_tree^[ 0 ].n_lo_level
                    THEN
                        BEGIN
                        a_pars_last_key.p_kind := m_update;
                        a660_new_pparsp (acv, dmli.d_sparr,
                              NOT c_first_parsinfo, c_complicate);
                        IF  acv.a_returncode = 0
                        THEN
                            BEGIN
                            a54set_complex_entry (acv, c_set_last_pars);
                            sysk := a01sysnullkey;
                            WITH sysk, parsk DO
                                BEGIN
                                sauthid[ 1 ] := cak_tempinfo_byte;
                                p_count   := acv.a_pars_last_key.p_count;
                                p_id[ 1 ] := acv.a_first_parsid;
                                p_kind    := m_fetch;
                                p_no      := 0;
                                sentrytyp := cak_eshortinfo;
                                s10mv (sizeof(parsk), sizeof(sauthid),
                                      @parsk, 1, @sauthid, 2, mxak_parskey);
                                END;
                            (*ENDWITH*) 
                            a10get_sysinfo (acv, sysk, d_fix,
                                  d_sparr.pinfop, b_err);
                            IF  b_err <> e_ok
                            THEN
                                a07_b_put_error (acv, b_err, 1);
                            (*ENDIF*) 
                            END;
                        (* PTS 1113924 E.Z. *)
                        (*ENDIF*) 
                        IF  ( acv.a_isolation_info = temp_lock_rec_needed )
                            AND
                            ( acv.a_returncode = 0 )
                        THEN
                            BEGIN
                            WITH sysk DO
                                BEGIN
                                sauthid   := cgg_zero_id;
                                sentrytyp := cak_eparsinfo;
                                slinkage  := cak_temp_info_linkage;
                                END;
                            (*ENDWITH*) 
                            a10_nil_get_sysinfo( acv, sysk, d_release,
                                  cak_sysbufferoffset + mxak_pars_header + 8, tempinfo_buf, b_err);
                            IF  b_err = e_ok
                            THEN
                                BEGIN
                                a54init_lock_parsinfo( acv, tempinfo_buf );
                                a10add_sysinfo( acv, tempinfo_buf, b_err);
                                END;
                            (*ENDIF*) 
                            IF  b_err <> e_ok
                            THEN
                                a07_b_put_error( acv, b_err, a_cmd_part^.sp1p_buf_len )
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        a54_get_pparsp_pinfop (acv, d_sparr, m_update);
                        IF  acv.a_command_kind = link_command
                        THEN
                            a54set_complex_entry (acv, c_set_last_pars);
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  (bsegmentid = cak00_public_segment_id) AND
                        (btreeid.fileTfn_gg00 <> tfnTemp_egg00)
                    THEN
                        a54add_next_temp_lock (acv, btreeid.fileTabId_gg00,
                              [ hsTempLock_egg00 ]);
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                d_movebefore := cgg_rec_key_offset;
                d_maxlen     := 0;
                upd_col_set  := [  ];
                sel_upd_set  := d_tabarr[ 1 ].oprivset;
                IF  a_returncode = 0
                THEN
                    BEGIN
                    IF  a_ex_kind = only_parsing
                    THEN
                        WITH d_sparr.pparsp^.sparsinfo DO
                            BEGIN
                            p_tabid := d_sparr.pbasep^.syskey.stableid;
                            p_mtyp  := m_update;
                            IF  a_ap_tree^[ start_node ].n_subproc = cak_x_append
                            THEN
                                p_mtyp2 := mm_expand
                            ELSE
                                p_mtyp2 := mm_nil;
                            (*ENDIF*) 
                            END;
                        (*ENDWITH*) 
                    (*ENDIF*) 
                    key_found := false;
                    act_node := a_ap_tree^[ act_node ].n_sa_level;
                    icurr_n := a_ap_tree^[ act_node ].n_sa_level;
                    found := false;
                    WHILE ((NOT found) AND (icurr_n <> 0)) DO
                        WITH a_ap_tree^[ icurr_n ] DO
                            IF  ((n_proc = a55) AND
                                (n_subproc = cak_x_search_clause))
                            THEN
                                found := true
                            ELSE
                                icurr_n := a_ap_tree^[ icurr_n ].n_sa_level;
                            (*ENDIF*) 
                        (*ENDWITH*) 
                    (*ENDWHILE*) 
                    IF  found
                    THEN
                        BEGIN
                        icurr_n := a_ap_tree^[ icurr_n ].n_lo_level;
                        WITH a_ap_tree^[ icurr_n ] DO
                            IF  ((n_proc = a55) AND
                                (n_subproc = cak_x_keyspec_list))
                            THEN
                                BEGIN
                                (*Key_Spec*)
                                d_tabarr[ 1 ].oprivset := a01fullset;
                                d_pars_kind := fp_val_varcol_with_len;
                                a55_build_key (acv, dmli, dfa, icurr_n);
                                key_found := true;
                                icurr_n := n_sa_level;
                                WITH a_mblock, mb_data^ DO
                                    mbp_keylen := mb_data_len - cgg_rec_key_offset;
                                (*ENDWITH*) 
                                IF  a_check_lock
                                THEN
                                    a_mblock.mb_type2 := mm_test
                                ELSE
                                    a_mblock.mb_type2 := mm_nil;
                                (*ENDIF*) 
                                END
                            ELSE
                                IF  ((n_proc = a55) AND
                                    ((n_subproc = cak_x_current_of) OR
                                    ( n_subproc = cak_x_pos_of)))
                                THEN
                                    BEGIN
                                    a58_current_of (acv, dmli, icurr_n);
                                    IF  a_check_lock
                                    THEN
                                        a_mblock.mb_type2 := mm_test
                                    ELSE
                                        a_mblock.mb_type2 := mm_nil;
                                    (*ENDIF*) 
                                    icurr_n := n_sa_level;
                                    END;
                                (*ENDIF*) 
                            (*ENDIF*) 
                        (*ENDWITH*) 
                        END;
                    (*ENDIF*) 
                    END;
&               ifdef TRACE
                (*ENDIF*) 
                t01messblock (ak_sem, 'b_update_str', a_mblock);
&               endif
                IF  a_returncode = 0
                THEN
                    BEGIN
                    d_tabarr[ 1 ].oprivset := d_upd_set;
                    d_upd_set           := [  ];
                    upd_n := a_ap_tree^[ start_node].n_lo_level;
                    upd_n := a_ap_tree^[ upd_n ].n_sa_level;
                    ak57set1_clause (acv, dmli, dfa, c_initialize,
                          upd_n, NOT c_named_values_done);
                    upd_n := a_ap_tree^[ upd_n ].n_sa_level;
                    WHILE ((upd_n > 0) AND (a_returncode = 0)) DO
                        WITH a_ap_tree^[ upd_n ] DO
                            IF  (((n_proc = a56) AND (n_subproc = cak_x_enum_values)) OR
                                ( (n_proc = a57) AND (n_subproc = cak_x_update_set)))
                            THEN
                                BEGIN
                                ak57set1_clause (acv, dmli, dfa, NOT c_initialize,
                                      upd_n, NOT c_named_values_done);
                                upd_n := a_ap_tree^[ upd_n ].n_sa_level;
                                END
                            ELSE
                                upd_n := 0;
                            (*ENDIF*) 
                        (*ENDWITH*) 
                    (*ENDWHILE*) 
                    ak57set2_clause (acv, dmli, dfa, upd_col_set,
                          sel_upd_set);
                    IF  a_sqlmode = sqlm_ansi
                    THEN
                        BEGIN
                        d_tabarr[ 1 ].oprivset   := sel_upd_set;
                        d_tabarr[ 1 ].osetallpriv := sel_upd_set;
                        END
                    ELSE
                        BEGIN
                        d_tabarr[ 1 ].oprivset   := a01fullset;
                        d_tabarr[ 1 ].osetallpriv := a01fullset;
                        END;
                    (*ENDIF*) 
                    a57_upd_del_rest (acv, dmli, dfa, sr_rec, icurr_n,
                          upd_col_set, new_parsinfo)
                    END;
                (*ENDIF*) 
                IF  d_linkbuf <> NIL
                THEN
                    BEGIN
                    WITH d_tabarr[ 1 ] DO
                        a56put_link_info (acv,
                              d_sparr.pbasep, not_used, NIL, d_linkbuf);
                    (*ENDWITH*) 
                    linkbuf := d_linkbuf
                    END;
                (*ENDIF*) 
                a262add_trigger_info (acv, dmli, a_ap_tree^[start_node].n_length = cak_i_ignore);
                isparr := d_sparr
                END
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a57_range_not_null (
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info;
            VAR dfa  : tak_dfarr);
 
VAR
      i : integer;
 
BEGIN
(* one column constraints and not null fields first *)
ak57constraint_not_null_check (acv, dmli, dfa,
      dmli.d_sparr.pbasep^.sbase.bmaxcol, NOT c_table_constraint);
IF  ( dmli.d_sparr.pbasep^.sbase.bnamed_constr > 0 )
THEN
    BEGIN
    (* table contains named constraints *)
    FOR i := 1 TO dmli.d_sparr.pbasep^.sbase.bnamed_constr DO
        dfa[ i ].dml_node := 1;
    (*ENDFOR*) 
    dmli.d_foundset := [  ];
    ak57constraint_not_null_check( acv, dmli, dfa,
          dmli.d_sparr.pbasep^.sbase.bnamed_constr, c_table_constraint )
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a57_set_clause (
            VAR acv           : tak_all_command_glob;
            VAR dmli          : tak_dml_info;
            VAR dfa           : tak_dfarr;
            start_node        : tsp00_Int2;
            VAR upd_col_set   : tak_columnset;
            VAR sel_upd_set   : tak_columnset;
            named_values_done : boolean);
 
VAR
      curr_n : tsp00_Int2;
 
BEGIN
curr_n := acv.a_ap_tree^[ start_node ].n_lo_level;
curr_n := acv.a_ap_tree^[ curr_n ].n_sa_level;
ak57set1_clause (acv, dmli, dfa, c_initialize,
      curr_n, named_values_done);
ak57set2_clause (acv, dmli, dfa, upd_col_set, sel_upd_set)
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak57set1_clause (
            VAR acv           : tak_all_command_glob;
            VAR dmli          : tak_dml_info;
            VAR dfa           : tak_dfarr;
            initialize        : boolean;
            curr_n            : tsp00_Int2;
            named_values_done : boolean);
 
VAR
      fno              : integer;
      act_node         : integer;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    d_range := true;
    d_foundset := [  ];
    d_nullkey := false;
    d_pars_kind := fp_val_all_with_len;
    IF  ((a_returncode = 0) AND (NOT named_values_done))
    THEN
        BEGIN
        IF  initialize
        THEN
            BEGIN
            d_key := false;
            FOR fno := 1 TO d_sparr.pbasep^.sbase.bmaxcol DO
                WITH dfa[ fno ] DO
                    BEGIN
                    dml_node      := 0;
                    dml_res_index := 0
                    END;
                (*ENDWITH*) 
            (*ENDFOR*) 
            END;
        (*ENDIF*) 
        act_node := curr_n;
        IF  a_ap_tree^[ act_node ].n_proc = a56
        THEN
            a56_enumerated_values (acv, dmli, dfa, act_node)
        ELSE
            a55_named_values (acv, dmli, dfa, act_node);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak57set2_clause (
            VAR acv           : tak_all_command_glob;
            VAR dmli          : tak_dml_info;
            VAR dfa           : tak_dfarr;
            VAR upd_col_set   : tak_columnset;
            VAR sel_upd_set   : tak_columnset);
 
VAR
      keyupdate        : boolean;
      i                : integer;
      jumpstackentry   : integer;
      m_qual_desc      : integer;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    keyupdate := false;
    IF  a_returncode = 0
    THEN
        BEGIN
        i := 1;
        WHILE i <= d_sparr.pbasep^.sbase.bmaxcol DO
            BEGIN
            WITH dfa[ i ] DO
                IF  dml_node <> 0
                THEN
                    IF  dml_col_ptr^.
                        ccolstack.etype in [ st_fixkey, st_varkey ]
                    THEN
                        keyupdate := true;
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDWITH*) 
            i := succ(i);
            END;
        (*ENDWHILE*) 
&       ifdef TRACE
        t01int4 (ak_sem, 'keyupdate   ', ord(keyupdate));
        t01int4 (ak_sem, 'mfirst_free ', a_mblock.mb_qual^.mfirst_free);
&       endif
        IF  d_sparr.pbasep^.sbase.bindexexist AND
            (d_sparr.pbasep^.sbase.btablekind <> tview)
        THEN
            a54_put_indices_in_mess_buf (acv,
                  d_sparr.pbasep^.sbase, dfa, keyupdate);
&       ifdef TRACE
        (*ENDIF*) 
        t01int4 (ak_sem, 'mfirst_free ', a_mblock.mb_qual^.mfirst_free);
&       endif
        WITH a_mblock.mb_qual^ DO
            mcol_pos := mfirst_free;
        (*ENDWITH*) 
        d_foundset       := [  ];
        END;
    (*ENDIF*) 
    ak57one_upd_col (acv, dmli, dfa, upd_col_set,
          c_use_only_varlongchar);
    ak57one_upd_col (acv, dmli, dfa, upd_col_set,
          NOT c_use_only_varlongchar);
    IF  a_returncode = 0
    THEN
        BEGIN
        d_fieldno := 1;
        IF  d_foundset <> [  ]
        THEN
            WHILE d_fieldno <= d_sparr.pbasep^.sbase.bmaxcol DO
                BEGIN
                IF  d_fieldno in d_foundset
                THEN
                    WITH a_mblock, mb_qual^, dfa[ d_fieldno ] DO
                        BEGIN
                        mcol_cnt := succ(mcol_cnt);
                        mb_st^ [mfirst_free] :=
                              dml_col_ptr^.ccolstack;
                        IF  d_linkbuf <> NIL
                        THEN
                            BEGIN
                            WITH d_linkbuf^.slinkposinfo DO
                                lupd_col_info := lupd_col_info +
                                      [ dml_col_ptr^.creccolno ];
                            (*ENDWITH*) 
                            END;
                        (*ENDIF*) 
                        WITH mb_st^ [mfirst_free] DO
                            BEGIN
                            CASE eop OF
                                op_order_desc :
                                    eop := op_desc_expr_upd;
                                op_unique :
                                    eop := op_unique_expr_upd;
                                op_unique_desc :
                                    eop := op_desc_unique_expr_upd;
                                OTHERWISE
                                    IF  dml_col_ptr^.cdatatyp in
                                        [ dstra, dstrb, dstruni ]
                                    THEN
                                        BEGIN
                                        ecol_tab[ 1 ] := chr(0);
                                        eop := op_scol_upd
                                        END
                                    ELSE
                                        IF  dml_col_ptr^.cdatatyp in
                                            [ dlonga, dlongb, dlonguni ]
                                        THEN
                                            BEGIN
                                            ecol_tab[ 1 ] := chr(0);
                                            eop := op_longcol_update
                                            END
                                        ELSE
                                            eop := op_expr_upd
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                END;
                            (*ENDCASE*) 
                            END;
                        (*ENDWITH*) 
                        mfirst_free := succ(mfirst_free);
                        END;
                    (*ENDWITH*) 
                (*ENDIF*) 
                d_fieldno := succ(d_fieldno)
                END;
            (*ENDWHILE*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        WITH a_mblock.mb_qual^ DO
            BEGIN
            mqual_pos := mfirst_free;
            mqual_cnt := succ(mqual_cnt);
            m_qual_desc := mqual_cnt;
            jumpstackentry := mfirst_free;
            mfirst_free := succ(mfirst_free);
            END;
        (*ENDWITH*) 
        d_range := false;
        d_nullkey := true;
        d_join := false;
        d_joins.jrc_cnt := 0;
        IF  a_ex_kind = only_parsing
        THEN
            a54_fixedpos (acv, dmli);
        (*ENDIF*) 
        d_tabarr[ 1 ].oprivset := sel_upd_set;
        a57update_with_value_expr (acv, dmli, dfa);
        a61_set_jump (a_mblock, jumpstackentry, st_jump_output);
        WITH a_mblock.mb_st^ [jumpstackentry] DO
            epos := epos+m_qual_desc;
        (*ENDWITH*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a57_upd_del_rest (
            VAR acv         : tak_all_command_glob;
            VAR dmli        : tak_dml_info;
            VAR dfa         : tak_dfarr;
            VAR sr_rec      : tak71_strat_rec;
            VAR icurr_n     : integer;
            VAR upd_col_set : tak_columnset;
            new_parsinfo    : boolean);
 
VAR
      ins_temp_lock: boolean;
      h_cpt        : tak_cmd_part_type;
      h_first_free : integer;
      dummy_tabno  : integer;
      dummy_infolen: integer;
      aux_upd_set  : tak_columnset;
      rtree        : tgg00_FileId;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    IF  ((a_returncode = 0) AND
        (a_mblock.mb_type2 = mm_qual))
    THEN
        a58_mass_update_delete (dmli)
    ELSE
        IF  NOT new_parsinfo (*subquery*)
        THEN
            a_mblock.mb_qual^.msubquery := true;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  ((icurr_n <> 0) AND (a_returncode = 0))
    THEN
        BEGIN
        IF  a_ex_kind = only_parsing
        THEN
            a54_fixedpos (acv, dmli);
        (*ENDIF*) 
        a_rowno_allowed := true;
        IF  ( acv.a_first_hint_node <> csp_minint2 )
        THEN
            BEGIN
            a80store_cmd_hint_info( acv, dmli, acv.a_select_node );
            END;
        (*ENDIF*) 
        a65_search_condition (acv, dmli, icurr_n);
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        WITH d_tabarr[ d_acttabindex ] DO
            IF  oview AND oviewqual
            THEN
                BEGIN
                IF  a_ex_kind = only_parsing
                THEN
                    a54_fixedpos (acv, dmli);
                (*ENDIF*) 
                a54_view_put_into (acv, dmli);
                IF  NOT oviewcheck
                THEN
                    BEGIN
                    a_mblock.mb_qual^.mview_pos := 0;
                    a_mblock.mb_qual^.mview_cnt := 0
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDWITH*) 
    (*ENDIF*) 
    rtree       := a_into_tree;
    aux_upd_set := d_upd_set;
    d_having := false;
    IF  d_corr = first_correlation
    THEN
        a67_first_corr (acv, dmli);
    (*ENDIF*) 
    IF  ((d_corr = first_correlation) AND
        (a_returncode = 0) AND
        (NOT d_only_sem_check))
    THEN
        BEGIN
        (* PTS 1117747 E.Z. *)
        a660set_subq_info (acv, dmli);
        h_cpt := a_cpart_type;
        a_cpart_type := cpt_in_where_clause;
        a67_corr_search (acv, dmli, NOT c_only_having_columns_get,
              dummy_tabno, NOT c_only_split, c_predefined_pno,
              dummy_infolen, rtree);
        a_cpart_type := h_cpt;
        END;
    (*ENDIF*) 
    d_upd_set := aux_upd_set;
    IF  ((a_returncode = 0) AND
        (a_mblock.mb_type = m_update))
    THEN
        BEGIN
        h_first_free := a_mblock.mb_qual^.mfirst_free;
        (* use temp-table-lock during update without qualification *)
        ins_temp_lock := false;
        IF  a_mblock.mb_type2 = mm_qual
        THEN
            WITH a_mblock, mb_qual^ DO
                BEGIN
                IF  mqual_cnt = 0
                THEN
                    ins_temp_lock := true
                ELSE
                    IF  mqual_cnt > 0
                    THEN
                        IF  mb_st^ [mqual_pos].etype = st_jump_output
                        THEN
                            IF  mqual_cnt <= mb_st^ [mqual_pos].epos
                            THEN
                                ins_temp_lock := true;
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  ins_temp_lock
                THEN
                    BEGIN
                    WITH mtree DO
                        BEGIN
                        IF  NOT (hsPermLock_egg00 in fileHandling_gg00)
                        THEN
                            fileHandling_gg00 := fileHandling_gg00 +
                                  [ hsTempLock_egg00 ];
                        (*ENDIF*) 
                        END;
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        IF  ((a_returncode = 0) AND
            (NOT d_only_sem_check))
        THEN
            a57_range_not_null (acv, dmli, dfa);
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  ((a_returncode = 0) AND
        (a_mblock.mb_type2 = mm_qual))
    THEN
        BEGIN
        d_distinct := no_distinct;
        d_use_order := false;
        d_order_or_group_cols := @d_order_cols;
        d_order_cols.ocntord  := 0;
        d_keylen := 4;
        d_foundset := upd_col_set;
        IF  a_ex_kind = only_parsing
        THEN
            a54_fixedpos (acv, dmli);
        (*ENDIF*) 
        WITH sr_rec DO
            BEGIN
            sr_must_result    := true;
            sr_use_rowno      := false;
            sr_distinct_bytes := true;
            sr_invkeylen      := csp_maxint2;
            END;
        (*ENDWITH*) 
        IF  NOT d_only_sem_check
        THEN
            a70_strategy_search (acv, dmli, rtree, sr_rec)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a57_update_statement (
            VAR acv    : tak_all_command_glob;
            start_node : tsp00_Int2);
 
VAR
      b_upd_string : boolean;
      all_done     : boolean;
      massupdate   : boolean;
      glob_state   : tgg00_HandlingSet;
      linkbuf      : tak_sysbufferaddress;
      isparr       : tak_syspointerarr;
 
BEGIN
b_upd_string := false;
linkbuf      := NIL;
all_done     := false;
WITH acv.a_ap_tree^[ start_node ] DO
    BEGIN
    IF  n_sa_level <> 0
    THEN
        a54_subquery (acv, isparr, start_node,
              m_update, b_upd_string)
    ELSE
        b_upd_string := true;
    (*ENDIF*) 
    IF  b_upd_string
    THEN
        BEGIN
        ak57build_update_string (acv, isparr, start_node,
              all_done, linkbuf);
        WITH acv, a_mblock, mb_data^ DO
            IF  a_returncode = 0
            THEN
                BEGIN
                IF  NOT all_done
                THEN
                    BEGIN
                    massupdate := (mb_type = m_update) AND
                          (mb_type2 = mm_qual);
                    a54_last_part (acv, isparr, c_last_pars_part)
                    END
                ELSE
                    massupdate := false;
                (*ENDIF*) 
                IF  ((a_returncode = 0) AND
                    (a_ex_kind <> only_parsing)           AND
                    (a_qualified_jv_upd = no_jv_upd))
                THEN
                    IF  massupdate
                    THEN
                        IF  mb_qual^.mr_resnum = csp_rescnt_zero
                        THEN
                            BEGIN
                            a07_b_put_error (acv, e_row_not_found, 1)
                            END
                        ELSE
                            a60resnum (acv, mb_qual^.buf, MB_PART1_HEAD_MXGG00+1)
                        (*ENDIF*) 
                    ELSE
                        a60rescount (acv, 1);
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDWITH*) 
        IF  (linkbuf <> NIL) AND (NOT all_done)
        THEN
            a56insert_upd_with_link (acv, linkbuf);
        (*ENDIF*) 
        IF  (acv.a_isolation_info = temp_lock_rec_get) AND
            NOT all_done                           AND
            (acv.a_returncode = 0)
        THEN
            BEGIN
            glob_state := acv.a_transinf.tri_global_state;
            IF  NOT (hsTempLock_egg00 in glob_state) AND
                NOT (hsPermLock_egg00 in glob_state)
            THEN
                glob_state := glob_state + [ hsTempLock_egg00 ];
            (*ENDIF*) 
            a54_loc_temp_locks (acv, glob_state, acv.a_p_arr2);
            END;
        (*ENDIF*) 
        IF  (acv.a_init_ex_kind <> acv.a_ex_kind) AND
            NOT all_done                    AND
            (acv.a_returncode = 0)
        THEN
            BEGIN
            acv.a_ex_kind := acv.a_init_ex_kind;
            IF  acv.a_init_ex_kind <> only_parsing
            THEN
                a58execute_link_cmd (acv)
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
