.ad 8
.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VAK641$
.tt 2 $$$
.TT 3 $ElkeZ$Execute_factor_col_function$2000-08-25$
***********************************************************
.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
.nf
.sp
MODULE  : Execute_factor_col_function
=========
.sp
Purpose : Processing of a column function, which is a
          a factor of a value expression
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              a641add_mapchar (
                    VAR acv            : tak_all_command_glob;
                    VAR dmli           : tak_dml_info;
                    VAR colin          : tak00_scolinf;
                    VAR setname        : tsp00_KnlIdentifier;
                    curr_n             : integer;
                    first_int          : integer);
 
        PROCEDURE
              a641check_datetime(
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    datatyp  : tsp00_DataType);
 
        PROCEDURE
              a641col_function (
                    VAR acv   : tak_all_command_glob;
                    VAR dmli  : tak_dml_info;
                    VAR frec  : tak_factorrec;
                    VAR colin : tak00_scolinf;
                    act_node  : integer);
 
        PROCEDURE
              a641get_mapcharset (
                    VAR acv            : tak_all_command_glob;
                    VAR mapcharsetname : tsp00_KnlIdentifier;
                    error_pos          : integer;
                    VAR max_maplen     : integer;
                    VAR sysbuf         : tak_sysbufferaddress);
 
        PROCEDURE
              a641s_literal_value (
                    VAR acv           : tak_all_command_glob;
                    act_node           : integer;
                    keep_datatype      : tsp00_DataType;
                    string_allowed     : boolean;
                    VAR string_found   : boolean;
                    VAR letter         : char;
                    VAR wrong_datatype : boolean);
 
        PROCEDURE
              a641string_set_operator (
                    VAR acv      : tak_all_command_glob;
                    operator     : tgg00_StackOpBuildIn;
                    destlength   : integer;
                    sourcelength : integer;
                    tab1         : char;
                    tab2         : char);
 
        PROCEDURE
              a641stack_for_op_b_chr (
                    VAR acv           : tak_all_command_glob;
                    VAR dmli           : tak_dml_info;
                    VAR colin          : tak00_scolinf;
                    first_int          : tsp00_Int2;
                    keep_datatype      : tsp00_DataType);
 
        PROCEDURE
              a641u_literal_value (
                    VAR acv            : tak_all_command_glob;
                    act_node           : integer;
                    VAR c2             : tsp00_C2;
                    VAR wrong_datatype : boolean);
 
        PROCEDURE
              a641charset_get (
                    VAR acv       : tak_all_command_glob;
                    node          : tsp00_Int2;
                    VAR setname   : tsp00_KnlIdentifier;
                    VAR messcode  : tsp00_CodeType;
                    VAR codewidth : tsp00_Uint1);
 
        PROCEDURE
              a641l_push_language (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a641f_push_format (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info);
 
        PROCEDURE
              a641_get_length (
                    VAR colin            : tak00_scolinf;
                    VAR output_length     : tsp00_Int2;
                    VAR wrong_datatype    : boolean);
 
        PROCEDURE
              a641_get_name (
                    VAR acv           : tak_all_command_glob;
                    part_ptr          : tsp1_part_ptr;
                    buf_pos           : tsp00_Int4;
                    buf_len           : tsp00_Int2;
                    get_schema        : boolean;
                    objecttype        : tsp00_Int2;
                    VAR returned_name : tsp00_KnlIdentifier);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              Scanner : VAK01;
 
        VAR
              a01defaultkey       : tgg00_SysInfoKey;
              a01char_size        : integer;
              a01_il_b_identifier : tsp00_KnlIdentifier;
 
        FUNCTION
              a01aligned_cmd_len (len : tsp00_Int4) : tsp00_Int4;
 
        PROCEDURE
              a01_put_node (
                    VAR acv    : tak_all_command_glob;
                    VAR curr_n : tsp00_Int2);
 
        PROCEDURE
              a01_next_symbol (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a01sets_identifier (
                    VAR id         : tsp00_KnlIdentifier;
                    set_identifier : tak_oldidentifier);
 
      ------------------------------ 
 
        FROM
              AK_syntax_tools : VAK02;
 
        PROCEDURE
              a02_put_identifier (
                    VAR acv       : tak_all_command_glob;
                    VAR put_node  : tsp00_Int2;
                    VAR last_node : tsp00_Int2);
 
      ------------------------------ 
 
        FROM
              AK_semantic_scanner_tools : VAK05;
 
        PROCEDURE
              a05_unsigned_int2_get (
                    VAR acv  : tak_all_command_glob;
                    pos      : integer;
                    l        : tsp00_Int2;
                    err_code : tsp00_Int4;
                    VAR int  : tsp00_Int2);
 
        PROCEDURE
              a05identifier_get (
                    VAR acv     : tak_all_command_glob;
                    tree_index  : integer;
                    obj_len     : integer;
                    VAR moveobj : tsp00_KnlIdentifier);
 
        PROCEDURE
              a05string_literal_get (
                    VAR acv     : tak_all_command_glob;
                    tree_index  : integer;
                    datatyp     : tsp00_DataType;
                    VAR moveobj : tsp00_MoveObj;
                    obj_pos     : integer;
                    obj_len     : integer);
 
      ------------------------------ 
 
        FROM
              AK_universal_semantic_tools : VAK06;
 
        PROCEDURE
              a06get_username (
                    VAR acv        : tak_all_command_glob;
                    VAR tree_index : integer;
                    VAR username   : tsp00_KnlIdentifier);
 
        FUNCTION
              a06_table_exist (
                    VAR acv      : tak_all_command_glob;
                    dstate       : tak_directory_state;
                    VAR authname : tsp00_KnlIdentifier;
                    VAR tablen   : tsp00_KnlIdentifier;
                    VAR sparr    : tak_syspointerarr;
                    get_all      : boolean) : boolean;
 
        PROCEDURE
              a06_get_priv  (
                    VAR acv  : tak_all_command_glob;
                    VAR brec : tak_sysbufferaddress;
                    VAR priv : tak_privilege);
 
      ------------------------------ 
 
        FROM
              AK_Identifier_Handling : VAK061;
 
        PROCEDURE
              a061assign_colname (
                    value       : tsp00_C18;
                    VAR colname : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK07;
 
        PROCEDURE
              a07_hex_uni_error (
                    VAR acv     : tak_all_command_glob;
                    uni_err     : tsp8_uni_error;
                    err_code    : tsp00_Int4;
                    to_unicode  : boolean;
                    bytestr     : tsp00_MoveObjPtr;
                    len         : tsp00_Int4 );
 
        PROCEDURE
              a07_b_put_error (
                    VAR acv : tak_all_command_glob;
                    b_err   : tgg00_BasisError;
                    err_code : tsp00_Int4);
 
        PROCEDURE
              a07_const_b_put_error (
                    VAR acv    : tak_all_command_glob;
                    b_err      : tgg00_BasisError;
                    err_code   : tsp00_Int4;
                    param_addr : tsp00_MoveObjPtr;
                    const_len  : integer);
 
        PROCEDURE
              a07_nb_put_error (
                    VAR acv  : tak_all_command_glob;
                    b_err    : tgg00_BasisError;
                    err_code : tsp00_Int4;
                    VAR n    : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK071;
 
        FUNCTION
              a071_return_code (
                    b_err   : tgg00_BasisError;
                    sqlmode : tsp00_SqlMode) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              Systeminfo_cache   : VAK10;
 
        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
              a10rel_sysinfo (syspointer : tak_sysbufferaddress);
 
      ------------------------------ 
 
        FROM
              AK_Domain : VAK12;
 
        FUNCTION
              a12dbfunc_exist (
                    VAR acv          : tak_all_command_glob;
                    VAR method_owner : tsp00_KnlIdentifier;
                    VAR method_name  : tsp00_KnlIdentifier;
                    dstate           : tak_directory_state;
                    VAR method_buf   : tak_sysbufferaddress) : boolean;
 
        PROCEDURE
              a12describe_param  (
                    VAR acv      : tak_all_command_glob;
                    method_buf   : tak_sysbufferaddress;
                    param_no     : integer;
                    VAR colinf   : tak00_scolinf);
 
        FUNCTION
              a12method_exist (
                    VAR acv         : tak_all_command_glob;
                    VAR type_id     : tgg00_Surrogate;
                    VAR method_name : tsp00_KnlIdentifier;
                    dstate          : tak_directory_state;
                    VAR method_buf  : tak_sysbufferaddress) : boolean;
 
        FUNCTION
              a12dbproc_exist (
                    VAR acv        : tak_all_command_glob;
                    VAR owner      : tsp00_KnlIdentifier;
                    VAR dbproc     : tsp00_KnlIdentifier;
                    dstate         : tak_directory_state;
                    VAR method_buf : tak_sysbufferaddress) : boolean;
 
        PROCEDURE
              a12output_parameter (
                    VAR acv        : tak_all_command_glob;
                    method_buf     : tak_sysbufferaddress;
                    VAR output_idx : integer;
                    VAR colinf     : tak00_scolinf);
 
        PROCEDURE
              a12get_domain (
                    VAR acv         : tak_all_command_glob;
                    VAR owner       : tsp00_KnlIdentifier;
                    VAR domain_name : tsp00_KnlIdentifier;
                    ti              : integer;
                    VAR domain_ref  : tak_sysbufferaddress;
                    VAR domain_def  : tak_sysbufferaddress);
 
      ------------------------------ 
 
        FROM
              AK_View_semantic : VAK16;
 
        PROCEDURE
              a16inc_vdesc_cnt (
                    VAR acv  : tak_all_command_glob;
                    VAR dmli : tak_dml_info;
                    VAR p    : tak_sysbufferaddress);
 
      ------------------------------ 
 
        FROM
              AK_Synonym : VAK23;
 
        FUNCTION
              a23exist_sequence (
                    VAR acv         : tak_all_command_glob;
                    tree_index      : integer;
                    inclusiveSerial : boolean;
                    VAR seq_buf     : tak_sysbufferaddress;
                    VAR seq_owner   : tsp00_KnlIdentifier;
                    VAR seq_name    : tsp00_KnlIdentifier) : boolean;
 
      ------------------------------ 
 
        FROM
              SQLManager : vak101;
 
        FUNCTION
              a101_StoreTableInfo (
                    VAR acv              : tak_all_command_glob;
                    VAR SchemaID         : tgg00_Surrogate;
                    VAR TableName        : tsp00_KnlIdentifier;
                    WithSpecifiedSchema  : boolean;
                    prepareHandle        : tgg00_VoidPtr) : boolean;
 
      ------------------------------ 
 
        FROM
              CatalogWrapper : VAK103;
 
        PROCEDURE
              a103GetSchemaId (
                    VAR acv        : tak_all_command_glob;
                    VAR schemaName : tsp00_KnlIdentifier (* ptocConst *);
                    errorPos       : integer;
                    VAR schemaId   : tgg00_Surrogate);
 
      ------------------------------ 
 
        FROM
              SequenceWrapper : VAK104;
 
        FUNCTION
              ak104_CreateIncrementalMemorySequence (
                    allocator    : tgg00_VoidPtr;
                    refMode      : tak104_refcountMode;
                    VAR sequence : tsp00_MoveObjPtr;
                    msglist      : tak104_MsgList) : boolean;
 
      ------------------------------ 
 
        FROM
              AK_Trigger : VAK262;
 
        PROCEDURE
              a262CalcOutputLen (
                    VAR acv         : tak_all_command_glob;
                    VAR methodRec   : tak_methodrecord;
                    pParamTable     : tak_sysbufferaddress;
                    VAR constParams : tak_colinteger;
                    VAR dataLength  : tsp00_Int2;
                    VAR ioLength    : tsp00_Int2;
                    VAR fraction    : tsp00_Int2);
 
        FUNCTION
              a262EvalOutputLenProlog (
                    VAR  acv        : tak_all_command_glob;
                    VAR  functionId : tgg00_Surrogate) : tak_sysbufferaddress;
 
        PROCEDURE
              a262SetParameterProperties (
                    VAR acv       : tak_all_command_glob;
                    pParamTable   : tak_sysbufferaddress;
                    paramNo       : integer;
                    paramDataType : tsp00_DataType;
                    dataLength    : integer;
                    inOutLength   : integer;
                    fraction      : integer);
 
      ------------------------------ 
 
        FROM
              Select_List : VAK61;
 
        PROCEDURE
              a61_set_jump (
                    VAR mess_block : tgg00_MessBlock;
                    stentrynr : integer;
                    operator  : tgg00_StackEntryType);
 
      ------------------------------ 
 
        FROM
              Execute_Factor : VAK640;
 
        PROCEDURE
              a640factor (
                    VAR acv      : tak_all_command_glob;
                    VAR dmli     : tak_dml_info;
                    VAR colin    : tak00_scolinf;
                    VAR act_node : integer);
 
        PROCEDURE
              a640not_first_factor (
                    VAR acv      : tak_all_command_glob;
                    VAR dmli     : tak_dml_info;
                    VAR colin    : tak00_scolinf;
                    VAR act_node : integer);
 
      ------------------------------ 
 
        FROM
              Execute_factor_constants : VAK642;
 
        VAR
              a642standard_colinfo : tak00_columninfo;
 
        PROCEDURE
              a642other_than_column (
                    VAR acv   : tak_all_command_glob;
                    VAR dmli  : tak_dml_info;
                    VAR frec  : tak_factorrec;
                    VAR colin : tak00_scolinf;
                    act_node  : integer);
 
      ------------------------------ 
 
        FROM
              Execute_Where_Part : VAK65;
 
        PROCEDURE
              a65_look_for_datatypes (
                    VAR acv    : tak_all_command_glob;
                    VAR dmli   : tak_dml_info;
                    first_node : integer);
 
        PROCEDURE
              a65ch_format (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    VAR startstack : integer;
                    VAR colin      : tak00_scolinf;
                    left_type      : tsp00_DataType;
                    d_type         : tsp00_DataType);
 
        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;
 
        PROCEDURE
              a65_search_condition (
                    VAR acv        : tak_all_command_glob;
                    VAR dmli       : tak_dml_info;
                    VAR first_node : integer);
 
      ------------------------------ 
 
        FROM
              Const_Expression : VAK651;
 
        PROCEDURE
              a651code_for_const_param_expr
                    (VAR acv : tak_all_command_glob;
                    VAR dmli    : tak_dml_info;
                    st_begin    : tsp00_Int2;
                    expr_st_cnt : tsp00_Int2);
 
        PROCEDURE
              a651value_calculate (
                    VAR acv  : tak_all_command_glob;
                    st_begin : integer;
                    st_end   : integer;
                    byte_str : boolean;
                    like     : boolean;
                    iolen    : tsp00_Int2;
                    err_pos  : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Join2_Select_help_routines : VAK685;
 
        PROCEDURE
              a685expand_joinarr(
                    VAR acv    : tak_all_command_glob;
                    VAR dmli   : tak_dml_info);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01code           : tgg04_CodeGlobals;
              g01unicode        : boolean;
 
      ------------------------------ 
 
        FROM
              Codetransformation_and_Coding : VGG02;
 
        VAR
              g02codetables : tgg04_CodeTables;
 
      ------------------------------ 
 
        FROM
              Select_Help_Procedures : VGG04;
 
        PROCEDURE
              g04value_locate (VAR stackentry : tgg00_StackEntry;
                    VAR mblock        : tgg00_MessBlock;
                    VAR operand_addr  : tsp00_MoveObjPtr;
                    VAR len           : integer);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill  (
                    mod_id         : tsp00_C6;
                    mod_intern_num : tsp00_Int4;
                    source_upb     : tsp00_Int4;
                    source         : tsp00_MoveObjPtr;
                    source_pos     : tsp00_Int4;
                    length         : tsp00_Int4;
                    fill_char      : char;
                    VAR e          : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id          : tsp00_C6;
                    mod_intern_num  : tsp00_Int4;
                    source_upb      : tsp00_Int4;
                    destin_upb      : tsp00_Int4;
                    source          : tsp00_MoveObjPtr;
                    source_pos      : tsp00_Int4;
                    destin          : tsp00_MoveObjPtr;
                    destin_pos      : tsp00_Int4;
                    length          : tsp00_Int4;
                    VAR e           : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              Unicode-Utilities: VGG20;
 
        PROCEDURE
              g20get_uni_key (
                    VAR setname   : tsp00_KnlIdentifier;
                    VAR messcode  : tsp00_CodeType;
                    VAR codewidth : tsp00_Uint1;
                    VAR rc        : tsp8_uni_error);
 
        PROCEDURE
              g20get_uni_set (
                    messcode      : tsp00_CodeType;
                    VAR codewidth : tsp00_Uint1;
                    VAR setname   : tsp00_KnlIdentifier);
 
      ------------------------------ 
 
        FROM
              KB_date_time : VKB79;
 
        FUNCTION
              k79n_dest_len_ora_number_format (
                    VAR format : tsp00_MoveObj;
                    fmt_pos : tsp00_Int4;
                    fmt_len : tsp00_Int4) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              date_time_formatting : VSP78;
 
        FUNCTION
              s78t_dest_len_date_format (
                    VAR format : tsp00_MoveObj;
                    fmt_pos : tsp00_Int4;
                    fmt_len : tsp00_Int4) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
        PROCEDURE
              s30map (
                    VAR code_t   : tsp00_Ctable;
                    VAR source   : tsp00_MoveObj;
                    spos         : tsp00_Int4;
                    VAR dest     : tsp00_MoveObj;
                    dpos         : tsp00_Int4;
                    length       : tsp00_Int4);
 
        FUNCTION
              s30lnr_defbyte (
                    str       : tsp00_KnlIdentifierPtr;
                    defbyte   : char;
                    start_pos : tsp00_Int4;
                    length    : tsp00_Int4) : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              GET-Conversions : VSP40;
 
        PROCEDURE
              s40gsint (
                    VAR buf  : tsp00_MoveObj;
                    pos      : tsp00_Int4;
                    len      : integer;
                    VAR dest : tsp00_Int2;
                    VAR res  : tsp00_NumError);
 
      ------------------------------ 
 
        FROM
              PUT-Conversions : VSP41;
 
        PROCEDURE
              s41pbyte (
                    VAR buf     : char;
                    pos         : tsp00_Int4;
                    VAR len     : integer;
                    VAR source  : tsp00_MoveObj;
                    spos        : tsp00_Int4;
                    slen        : integer;
                    VAR invalid : boolean);
 
        PROCEDURE
              s41p1byte (
                    VAR buf     : char;
                    pos         : tsp00_Int4;
                    VAR len     : integer;
                    VAR source  : tsp00_C2;
                    spos        : tsp00_Int4;
                    slen        : integer;
                    VAR invalid : boolean);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-80: VSP80;
 
        PROCEDURE
              s80uni_trans
                    (src_ptr        : tsp00_MoveObjPtr;
                    src_len         : tsp00_Int4;
                    src_codeset     : tsp00_Int2;
                    dest_ptr        : tsp00_MoveObjPtr;
                    VAR dest_len    : tsp00_Int4;
                    dest_codeset    : tsp00_Int2;
                    trans_options   : tsp8_uni_opt_set;
                    VAR rc          : tsp8_uni_error;
                    VAR err_char_no : tsp00_Int4);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01addr (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    bufaddr  : tsp00_MoveObjPtr);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01lidentifier (
                    debug      : tgg00_Debug;
                    identifier : tsp00_KnlIdentifier);
 
        PROCEDURE
              t01name (debug : tgg00_Debug; nam : tsp00_Name);
 
        PROCEDURE
              t01qual (debug : tgg00_Debug; VAR part1 : tgg00_QualBuf);
 
        PROCEDURE
              t01moveobj (
                    debug       : tgg00_Debug;
                    VAR moveobj : tsp00_MoveObj;
                    startpos    : tsp00_Int4;
                    endpos      : tsp00_Int4);
 
        PROCEDURE
              t01messblock (
                    debug         : tgg00_Debug;
                    nam           : tsp00_Sname;
                    VAR m         : tgg00_MessBlock);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              a05identifier_get;
 
              tsp00_MoveObj tsp00_KnlIdentifier
 
        FUNCTION
              ak104_CreateIncrementalMemorySequence;
 
              tak104_Allocator tgg00_VoidPtr
              tak104_IncrementalMemorySequence tsp00_MoveObjPtr
 
        FUNCTION
              s30lnr_defbyte;
 
              tsp00_MoveObjPtr tsp00_KnlIdentifierPtr
 
        PROCEDURE
              s41pbyte;
 
              tsp00_MoveObj char
 
        PROCEDURE
              s41p1byte;
 
              tsp00_MoveObj char
              tsp00_MoveObj tsp00_C2
 
        PROCEDURE
              t01addr;
 
              tsp00_BufAddr tsp00_MoveObjPTR
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : ElkeZ
.sp
.cp 3
Created : 1985-05-29
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-08-25
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
.sp 2
A64_CHECK_DATETIME
.sp
Creates a stackentry to check date, time or timestamp values which a
given as a string specification. The stackentry contains than in 'epos'
the information about the datatype to test ( 0 for date, 1 for time and
2 for timestamp ). In 'elen_var' the actuall date_time_format (
acv_dt_format ) is stored. In case of datatype dtimestamp only the two
formats 'NORMAL' and 'ISO' are supported. The operator 'eop' is set to
'op_check_format'.
.br;The procedur is always called if a function is processed that expects
a date ( time, timestamp ) value and the processing of the
argument returns with tdatatype
not equal ddate ( dtime, dtimestamp ).
.sp
INPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.sp
.of 12
dmli: especially dm_datatype
.sp
.of 12
datatype: datatype the string specification must represent.
.in -11
OUTPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.in -11
.sp 2
.cp 3
COL_FUNCTION
.sp
Processing of all functions contained in A01_FUNCTION_SYMBOLS.
.sp
INPUT :
.in +11
.of 12
acv: especially ap_tree
.sp
.of 12
dmli: especially dm_datatype
.sp
.of 12
frec: Temporary description of the factor and of the processing status
.sp
.of 12
act_node: Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv: especially mess_buf, part1
.sp
.of 12
dmli: especially dm_datatype, atcolbuf
.sp
.of 12
frec: Temporary description of the factor and of the processing status
.sp
.of 12
colin: Description of the factor processed
.sp
.in -11
First of all, 'atcolbuf' is set to NIL, because, in the case of a function,
column information contained in 'atcolbuf' can no longer be used (it is no
longer correct). This means that standard information must be accessed for an
analysis of the remaining expressions at this level. Information is not entered
in 'atcolbuf' again until another column is analyzed.
.br
The sequence of actions is the same for all functions. After various, so far
determined data types have been directly excluded, the arguments are
analyzed with A64_FACTOR and the information describing the entire factor is
formed accordingly:  'colin.sci_len', 'colin.sci_iolen', 'colin.sci_frac', 'colin.sci_typ',
'colin.sci_cprops' and possibly dm_datatype and is entered in the stack.
.sp
Since various functions allow only an unsigned integer as argument, this is
read directly from 'cmh_var_part' without calling A64_FACTOR.
.sp
For various functions there is a procedure that performs the steps described.
This is, however, only for the sake of clarity, which would otherwise be lost.
.sp
In the case of string functions, the operator and further already existing
information are entered in the stack with the procedure STRING_SET_OPERATOR.
.in -5
.sp 2
PROCSUBSTR
.sp
Processes the function 'SUBSTR'.
.sp
INPUT:
.in +11
.of 12
acv: especially ap_tree
.sp
.of 12
act_node: Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv: especially mess_buf, part1
.sp
.of 12
colin: Description of the factor processed
.sp
.in -11
See COL_FUNCTION for sequence of actions.
.sp 2
PROCEXPAND
.sp
Processes the function 'EXPAND'.
.sp
INPUT :
.in +11
.of 12
acv : especially ap_tree
.sp
.of 12
act_node : Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.sp
.of 12
colin : Description of the factor processed
.in -11
.sp
See COL_FUNCTION for sequence of actions.
.sp 2
PROCLRPAD
.sp
Processes the functions 'LPAD', 'RPAD', 'LFILL', 'RFILL'.
.sp
INPUT :
.in +11
.of 12
acv: especially ap_tree
.sp
.of 12
act_node: Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv: especially mess_buf, part1
.sp
.of 12
i_error: Identifies the existence of a data-type error.
.sp
.of 12
colin: Description of the factor processed
.in -11
.sp
See COL_FUNCTION for sequence of actions.
.sp 2
PROCMAPCHAR
.sp
Processes the function 'MAPCHAR'.
.sp
INPUT :
.in +11
.of 12
acv : especially ap_tree
.sp
.of 12
act_node : Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.sp
.of 12
i_error : Identifies the existence of a data-type error.
.sp
.of 12
colin : Description of the factor processed
.in -11
.sp
See COL_FUNCTION for sequence of actions.
.sp 2
PROCINDEX
.sp
Processes the function 'INDEX'.
.sp
INPUT :
.in +11
.of 12
acv: especially ap_tree
.sp
.of 12
act_node: Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv: especially mess_buf, part1
.sp
.of 12
i_error: Identifies the existence of a data-type error.
.sp
.of 12
colin: Description of the factor processed
.in -11
.sp
See COL_FUNCTION for sequence of actions.
.sp 2
PROCCHR
.sp
Processes the function 'CHR'.
.sp
INPUT :
.in +11
.of 12
acv : especially ap_tree
.sp
.of 12
act_node : Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.sp
.of 12
i_error : Identifies the existence of a data-type error.
.sp
.of 12
colin : Description of the factor processed
.in -11
.sp
See COL_FUNCTION for sequence of actions.
.sp 2
PROCCONVERSION
.sp
Processes the functions 'ASCII', 'UPPER', 'LOWER', 'INITCAP',
'TRIM', 'LTRIM', 'RTRIM'
.sp
INPUT :
.in +11
.of 12
acv : especially ap_tree
.sp
.of 12
act_node : Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.sp
.of 12
i_error : Identifies the existence of a data-type error.
.sp
.of 12
colin : Description of the factor processed
.in -11
.sp
See COL_FUNCTION for sequence of actions.
.sp 2
PROCDATETIME
.sp
Processes the functions 'YEAR', 'MONTH', 'DAY', 'HOUR', 'MINUTE',
'SECOND', 'MICROSECOND'.
.sp
INPUT :
.in +11
.of 12
acv : especially ap_tree
.sp
.of 12
act_node : Tree node at which the function begins
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.sp
.of 12
i_error : Identifies the existence of a data-type error.
.sp
.of 12
colin : Description of the factor processed
.in -11
.sp
See COL_FUNCTION for sequence of actions.
.sp 2
PROCTIMEDATE
.sp
Processes the functions 'DATE', 'TIME'.
.sp
INPUT :
.in +11
.of 12
acv : especially ap_tree
.sp
.of 12
act_node : Tree node at which the function begins
.sp
.of 12
frec: Temporary description of the factor and of the processing status
.sp;.in -11
OUTPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.sp
.of 12
i_error : Identifies the existence of a data-type error.
.sp
.of 12
colin : Description of the factor processed
.in -11
.sp
First of all it is tested whether a argument is present
(n_lo_level <> 0). If not
OTHER_THAN_COLUMN is called to process the corresponding function with
arity zero. If there is an argument see COL_FUNCTION for sequenze of
actions.
.sp 2
STRING_SET_OPERATOR
.sp
Creates a stack entry for string functions.
.sp
INPUT :
.in +11
.of 15
operator: Stack operator that is to be entered.
.sp
.of 15
destlength: Entry for elen_var.
.sp
.of 15
sourcelength: Entry for epos.
.sp
.of 15
tab1: Entry of ecol_tab[ 1 ].
.sp
.of 15
tab2: Entry of ecol_tab[ 2 ].
.in -11
.sp
.cp 3
The entry in the operator 'eop' is precisely determined by the function: the
entries in the other values are function-specific and depend, for example, on
the number of arguments and on their values. The special meanings are then
interpreted in VKB71.
.sp 2
CHECK_DATATYPE
.sp
Checks the data types of the two factors described by 'colin' and 'colin1'.
CHECK_DATATYPE is called if a function expects two factors with string types in
order to clarify the compatibility of their types. If there is incompatibility,
'i_error' is set to 'true'.
.sp
INPUT :
.in +11
.of 12
acv : especially mess_buf, part1
.sp
.of 12
colin: Description of the first factor.
.sp
.of 12
colin1: Description of the second factor.
.sp
.in -11
OUTPUT :
.in +11
.of 12
i_error: Identifies the existence of a data-type error.
.in -11
 
.sp 2
PUT_MAXLENGTH
.sp
PUT_MAXLENGTH is called by COL_FUNCTION if the function 'FIXED' is specified.
.sp
INPUT :
.in +11
.of 13
acv: especially cmh_var_part, ap_tree
.sp
.of 13
curr_n: Current tree node
.sp
.in -11
OUTPUT :
.in +11
.of 13
acv: especially mess_buf, part1
.sp
.of 13
first_int: Value of the first unsigned integer read
.sp
.of 13
second_int: Value of the second unsigned integer read
.sp
.in -11
The further arguments of 'FIXED' are read directly from 'cmh_var_part' and are
given to 'first_int' and 'second_int', if applicable (with
A05_UNSIGNED_INT2_GET). If not applicable then 'first)int' is set to
'maxfixedlength' and 'second_int' to '0'.
In addition, the stack entry is created into which the
values of 'first_int' and 'second_int' are directly inserted (in 'epos' and
'elen_var'). 'op_fixed' is entered as the stack operator.
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      c_get_all        = true (* 106_table_exist *);
      c_convert        = true (* a65_datatypes_ok  *);
      c_is_subquery    = true (* a65_datatypes_ok  *);
      c_trans_to_uni   = true (* a07_hex_uni_error *);
      c_string_allowed = true (* a641s_literal_value *);
      c_unicode_wid    = 2    (* a07_hex_uni_error *);
      c_undef_mcode    = csp_maxint1;
      c_maxcntstackno  = 256;
 
TYPE
      ak641stackentries = PACKED ARRAY [0..c_maxcntstackno] OF tsp00_Int2;
 
 
(*------------------------------*) 
 
PROCEDURE
      ak641addsubdate (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
      colin1 : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    curr_n := n_lo_level;
    IF  (a_ap_tree^[curr_n].n_proc = no_proc) AND
        (a_ap_tree^[curr_n].n_symb = s_now)
    THEN
        a640factor (acv, dmli, colin, curr_n)
    ELSE
        BEGIN
        ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, ddate, ddate);
        IF  a_returncode =
            a071_return_code (e_incompatible_datatypes, a_sqlmode)
        THEN
            BEGIN
            a_returncode := 0;
            ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, dtimestamp, dtimestamp);
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        colin1.sci_len := 0;
        d_datatype     := dnumber;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  a_returncode = 0
        THEN
            BEGIN
            IF  colin.sci_typ = dtimestamp
            THEN
                BEGIN
                d_datatype := dtimestamp;
                WITH colin DO
                    BEGIN
                    sci_len   := mxsp_timestamp;
                    sci_iolen := succ(sci_len);
                    sci_frac  := 0;
                    sci_typ   := dtimestamp
                    END;
                (*ENDWITH*) 
                END
            ELSE
                BEGIN
                d_datatype := ddate;
                WITH colin DO
                    BEGIN
                    sci_len   := mxsp_date;
                    sci_iolen := succ(sci_len);
                    sci_frac  := 0;
                    sci_typ   := ddate
                    END;
                (*ENDWITH*) 
                END;
            (*ENDIF*) 
            IF  (n_symb = s_adddate)
            THEN
                a65_set_operator (acv, op_adddate)
            ELSE
                a65_set_operator (acv, op_subdate)
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641addsubtime (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n        : integer;
      colin1        : tak00_scolinf;
      is_timestamp  :  boolean;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    curr_n       := n_lo_level;
    IF  (a_ap_tree^[curr_n].n_proc = no_proc) AND
        (a_ap_tree^[curr_n].n_symb = s_now)
    THEN
        a640factor (acv, dmli, colin, curr_n)
    ELSE
        BEGIN
        ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, dtime, dtime);
        IF  a_returncode =
            a071_return_code (e_incompatible_datatypes, a_sqlmode)
        THEN
            BEGIN
            a_returncode := 0;
            ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, dtimestamp, dtimestamp);
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    is_timestamp := colin.sci_typ = dtimestamp;
    IF  a_returncode = 0
    THEN
        BEGIN
        d_datatype     := dtime;
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        colin1.sci_len := 0;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  colin1.sci_typ = dtimestamp
        THEN
            wrong_datatype := true
        ELSE
            IF  a_returncode = 0
            THEN
                BEGIN
                IF  (colin1.sci_typ <> dtime)
                THEN
                    a641check_datetime(acv, dmli, dtime);
                (*ENDIF*) 
                IF  is_timestamp
                THEN
                    BEGIN
                    d_datatype := dtimestamp;
                    WITH colin DO
                        BEGIN
                        sci_len   := mxsp_timestamp;
                        sci_iolen := succ(sci_len);
                        sci_frac  := 0;
                        sci_typ   := dtimestamp;
                        END;
                    (*ENDWITH*) 
                    END
                ELSE
                    BEGIN
                    d_datatype := dtime;
                    WITH colin DO
                        BEGIN
                        sci_len   := mxsp_time;
                        sci_iolen := sci_len+1;
                        sci_frac  := 0;
                        sci_typ   := dtime;
                        END;
                    (*ENDWITH*) 
                    END;
                (*ENDIF*) 
                IF  n_symb = s_addtime
                THEN
                    a65_set_operator (acv, op_addtime)
                ELSE
                    a65_set_operator (acv, op_subtime)
                (*ENDIF*) 
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641ascii (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n        : integer;
 
BEGIN
(* This procedure describes the results of the build-in  *)
(* function ascii in oracle-mode and makes a stackentry. *)
WITH acv, a_ap_tree^[ act_node ], dmli, colin DO
    BEGIN
    d_datatype := dunknown;
    curr_n     := n_lo_level;
    sci_len    := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = cak_e_parameter
    THEN
        BEGIN
        a_returncode := 0;
        d_datatype  := dnonumber;
        a640factor (acv, dmli, colin, curr_n)
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        a641string_set_operator
              (acv, op_b_ascii_ora, 0, 0, chr(0), chr(0));
        WITH a_mblock, mb_qual^ DO
            mb_st^ [mfirst_free - 1].edatatype := sci_typ;
        (*ENDWITH*) 
        (* Because the highest decimal value for an ascii-symbol *)
        (* is 255 and the value must be an integer, lengthvalue  *)
        (* in 'colinf' can be given directly.                    *)
        sci_len    := 5;
        sci_frac   := 0;
        sci_iolen  := 5;
        sci_typ    := dfixed;
        sci_cprops := [ ctopt ];
        d_datatype := dnumber
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;   (*   end of procedure ak641ascii  *)
 
(*------------------------------*) 
 
PROCEDURE
      ak641_add_months (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      negativ   : boolean;
      curr_n    : integer;
      colin1    : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dtimestamp;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  (colin.sci_typ <> dtimestamp)
        THEN
            a641check_datetime (acv, dmli, dtimestamp);
        (*ENDIF*) 
        curr_n      := a_ap_tree^[ curr_n ].n_sa_level;
        IF  (n_symb = s_add_months)
        THEN
            BEGIN
            negativ     := (a_ap_tree^[ curr_n ].n_symb = s_minus);
            IF  negativ
            THEN
                curr_n  := a_ap_tree^[ curr_n ].n_lo_level;
            (*ENDIF*) 
            d_datatype  := dnumber;
            END
        ELSE
            d_datatype := dunknown;
        (*ENDIF*) 
        colin1.sci_len := 0;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  (n_symb = s_next_day) AND
            (a_returncode = cak_e_parameter)
        THEN
            BEGIN
            a_returncode := 0;
            d_datatype  := dnonumber;
            a640not_first_factor (acv, dmli, colin1, curr_n)
            END;
        (*ENDIF*) 
        IF  (a_returncode = 0)
        THEN
            IF  (d_datatype <> dnumber) AND
                (d_datatype <> dcha)    AND
                (d_datatype <> dunicode)
            THEN
                wrong_datatype := true
            ELSE
                BEGIN
                IF  d_datatype = dunicode
                THEN
                    a641string_set_operator (acv, op_b_uni_trans,
                          colin1.sci_len+1, 0, chr(csp_unicode),
                          chr(csp_ascii));
                (*ENDIF*) 
                d_datatype := dtimestamp;
                WITH colin DO
                    BEGIN
                    sci_len   := mxsp_exttimestamp;
                    sci_iolen := succ(sci_len);
                    sci_frac  := 0;
                    sci_typ   := dtimestamp;
                    END;
                (*ENDWITH*) 
                IF  (n_symb =  s_add_months)
                THEN
                    IF  negativ
                    THEN
                        a65_set_operator (acv, op_submonth)
                    ELSE
                        a65_set_operator (acv, op_addmonth)
                    (*ENDIF*) 
                ELSE
                    BEGIN
                    a641string_set_operator (acv, op_b_next_day,
                          0, 0, chr(0), chr(0));
                    WITH a_mblock, mb_qual^ DO
                        mb_st^ [mfirst_free-1].elanguage := a_ak_language;
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641new_time (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n    : integer;
      colin1    : tak00_scolinf;
      colin2    : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dtimestamp;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  (colin.sci_typ <> dtimestamp)
        THEN
            a641check_datetime (acv, dmli, dtimestamp);
        (*ENDIF*) 
        curr_n := a_ap_tree^[ curr_n ].n_sa_level;
        (* PTS 1121793 E.Z. *)
        d_datatype := dcha;
        colin1.sci_len := 0;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  (a_returncode = 0)
        THEN
            IF  (d_datatype <> dcha)
            THEN
                wrong_datatype := true
            ELSE
                BEGIN
                curr_n := a_ap_tree^[ curr_n ].n_sa_level;
                d_datatype := dcha;
                colin2.sci_len := 0;
                a640not_first_factor (acv, dmli, colin2, curr_n);
                IF  (a_returncode = 0)
                THEN
                    IF  (d_datatype <> dcha)
                    THEN
                        wrong_datatype := true
                    ELSE
                        BEGIN
                        d_datatype := dtimestamp;
                        WITH colin DO
                            BEGIN
                            sci_len   := mxsp_exttimestamp;
                            sci_iolen := succ(sci_len);
                            sci_frac  := 0;
                            sci_typ   := dtimestamp;
                            END;
                        (*ENDWITH*) 
                        a641string_set_operator (acv, op_b_new_time,
                              0, 0, chr(0), chr(0));
                        END
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641add_mapchar (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            VAR setname        : tsp00_KnlIdentifier;
            curr_n             : integer;
            first_int          : integer);
 
VAR
      charsize      : integer;
      max_maplen    : integer;
      curr_data_pos : tsp00_Int4;
      sbuf          : tak_sysbufferaddress;
 
      univ_ptr : RECORD
            CASE boolean OF
                true :
                    (mapsetptr : ^tak_map_set);
                false :
                    (moveobjptr : tsp00_MoveObjPtr);
                END;
            (*ENDCASE*) 
 
 
BEGIN
(* PTS 1120720 E.Z. *)
WITH acv, dmli DO
    BEGIN
    a641get_mapcharset (acv,
          setname, a_ap_tree^[curr_n].n_pos, max_maplen, sbuf);
    IF  a_returncode = 0
    THEN (* Build up the rules according to the mapchar_set in part2 *)
        WITH a_mblock, mb_data^, sbuf^, smapset DO
            IF  ((colin.sci_typ <> dunicode) AND (map_code  = csp_unicode)) OR
                ((colin.sci_typ  = dunicode) AND (map_code <> csp_unicode))
            THEN
                a07_b_put_error (acv, e_incompatible_datatypes,
                      a_ap_tree^[ curr_n ].n_pos)
            ELSE
                BEGIN
                IF  map_code = csp_unicode
                THEN
                    charsize := 2
                ELSE
                    charsize := 1;
                (*ENDIF*) 
                IF  (mb_data_len + 3 * charsize * map_count + 1) > mb_data_size
                THEN
                    a07_b_put_error (acv, e_too_many_mb_data,
                          a_ap_tree^[ curr_n ].n_pos)
                ELSE
                    BEGIN
                    mb_data_len := mb_data_len + csp_attr_byte;
                    curr_data_pos := mb_data_len;
                    IF  map_code = csp_ascii
                    THEN
                        mbp_buf[ curr_data_pos ] :=
                              csp_ascii_blank
                    ELSE
                        mbp_buf[ curr_data_pos ] :=
                              csp_unicode_def_byte;
                    (*ENDIF*) 
                    SAPDB_PascalMove ('VAK641',   1,    
                          sizeof(map_set),
                          mb_data_size, @map_set, 1,
                          @mbp_buf, curr_data_pos+1,
                          map_count * 3 * charsize,
                          a_returncode);
&                   ifdef TRACE
                    t01name (ak_sem, 'map_vorschrift    ');
                    t01moveobj (ak_sem, mbp_buf, curr_data_pos,
                          curr_data_pos + map_count * 3 * charsize);
&                   endif
                    IF  a_returncode = 0
                    THEN
                        BEGIN  (* fill stackentry *)
                        WITH mb_qual^ DO
                            IF  mfirst_free > mb_st_max
                            THEN
                                a07_b_put_error (acv,
                                      e_too_many_mb_stackentries, -mb_st_max)
                            ELSE
                                BEGIN
                                mqual_cnt := succ(mqual_cnt);
                                WITH mb_st^ [mfirst_free] DO
                                    BEGIN
                                    etype         := st_value;
                                    eop           := op_none;
                                    epos          := curr_data_pos;
                                    elen_var      := 3 * charsize * map_count + 1;
                                    ecol_tab[ 1 ] := chr(0);
                                    ecol_tab[ 2 ] := chr(0);
                                    END;
                                (*ENDWITH*) 
                                mfirst_free := succ(mfirst_free)
                                END;
                            (*ENDIF*) 
                        (*ENDWITH*) 
                        mb_data_len := mb_data_len + 3 * charsize * map_count;
                        IF  a_cmd_segment_header.sp1c_mess_type = sp1m_parse
                        THEN
                            d_movebefore := d_movebefore +
                                  csp_attr_byte + 3 * charsize * map_count;
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDWITH*) 
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  colin.sci_typ = dunicode
        THEN
            a65_set_operator (acv, op_dbyte_mapchar)
        ELSE
            a65_set_operator (acv, op_mapchar);
        (*ENDIF*) 
        IF  colin.sci_typ in [ dtime, ddate, dtimestamp ]
        THEN
            colin.sci_typ := dcha;
        (*ENDIF*) 
        colin.sci_len   := first_int;
        colin.sci_frac  := 0;
        colin.sci_iolen := succ(colin.sci_len * charsize);
        a641string_set_operator (acv, op_b_checklen,
              first_int * charsize, 0, chr(0), chr(0));
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641get_mapcharset (
            VAR acv            : tak_all_command_glob;
            VAR mapcharsetname : tsp00_KnlIdentifier;
            error_pos          : integer;
            VAR max_maplen     : integer;
            VAR sysbuf         : tak_sysbufferaddress);
 
VAR
      pos   : integer;
      cnt   : integer;
      b_err : tgg00_BasisError;
      sysk  : tgg00_SysInfoKey;
 
BEGIN
(*== get record from catalog ==========================*)
(* check of <mapchar set name> *)
sysk             := a01defaultkey;
sysk.sentrytyp   := cak_emapset;
sysk.sidentifier := mapcharsetname;
sysk.skeylen     := sizeof (sysk.stableid) +
      sizeof (sysk.sentrytyp) + sizeof (sysk.slinkage) +
      sizeof (sysk.sidentifier);
a10get_sysinfo (acv, sysk, d_release, sysbuf, b_err);
IF  b_err <> e_ok
THEN
    IF  b_err = e_sysinfo_not_found
    THEN
        a07_nb_put_error (acv, e_unknown_mapset,
              error_pos, mapcharsetname)
    ELSE
        a07_b_put_error (acv, b_err, 1)
    (*ENDIF*) 
ELSE
    BEGIN
    max_maplen := 1;
    pos        := 3;
    cnt        := sysbuf^.smapset.map_count;
    WHILE (cnt > 0) DO
        IF  sysbuf^.smapset.map_set[pos] <> bsp_c1
        THEN
            BEGIN
            max_maplen := 2;
            cnt        := 0
            END
        ELSE
            BEGIN
            cnt := cnt - 1;
            pos := pos + 3
            END;
        (*ENDIF*) 
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641mapchar (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n        : integer;
      charsize      : integer;
      first_int     : tsp00_Int2;
      keep_datatype : tsp00_DataType;
      setname       : tsp00_KnlIdentifier;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    keep_datatype := d_datatype;
    d_datatype    := dnonumber;
    d_ch_datatype := dunknown;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  (a_returncode = 0)
    THEN
        (* PTS 1120720 E.Z. *)
        IF  (colin.sci_typ = dchb)
        THEN
            wrong_datatype := true
        ELSE
            BEGIN
            first_int := colin.sci_len;
            (* calculation of length used for output *)
            IF  (a_ap_tree^[ curr_n ].n_sa_level <> 0) AND
                (a_ap_tree^[ a_ap_tree^[ curr_n ].n_sa_level ].n_symb =
                s_unsigned_integer)
            THEN
                BEGIN
                curr_n := a_ap_tree^[ curr_n ].n_sa_level;
                a05_unsigned_int2_get (acv, a_ap_tree^[ curr_n ].n_pos,
                      a_ap_tree^[ curr_n ].n_length, e_invalid_datalength, first_int);
                IF  ((first_int < 1) OR (first_int > cak_maxdeffieldlength))
                THEN
                    a07_b_put_error (acv, e_invalid_datalength,
                          a_ap_tree^[ curr_n ].n_pos)
                (*ENDIF*) 
                END
            ELSE
                (* PTS 1125461 E.Z. *)
                IF  first_int <= 10
                THEN
                    first_int := 2 * first_int
                ELSE
                    IF  first_int <= 100
                    THEN
                        first_int := first_int + 10
                    ELSE
                        IF  first_int <= 230
                        THEN
                            first_int := first_int + 20
                        ELSE
                            BEGIN
                            first_int := first_int + (first_int DIV 10);
                            (* PTS 1120720 E.Z. *)
                            IF  colin.sci_typ = dunicode
                            THEN
                                charsize := 2
                            ELSE
                                charsize := 1;
                            (*ENDIF*) 
                            IF  a_sqlmode = sqlm_oracle
                            THEN
                                BEGIN
                                IF  first_int > cak_maxorafieldlength DIV charsize
                                THEN
                                    first_int := cak_maxorafieldlength DIV charsize
                                (*ENDIF*) 
                                END
                            ELSE
                                IF  first_int > cak_maxdeffieldlength DIV charsize
                                THEN
                                    first_int := cak_maxdeffieldlength DIV charsize;
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
            (* Search for the mapchar set, which is to be used *)
            IF  (a_ap_tree^[ curr_n ].n_sa_level <> 0) AND
                (a_ap_tree^[ a_ap_tree^[ curr_n ].n_sa_level ].n_symb =
                s_identifier)
            THEN
                BEGIN
                curr_n  := a_ap_tree^[ curr_n ].n_sa_level;
                a05identifier_get (acv, curr_n,
                      sizeof (setname), setname)
                END
            ELSE
                a01sets_identifier (setname, cak00_default_mapchar_set);
            (*ENDIF*) 
            a641add_mapchar (acv,
                  dmli, colin, setname, curr_n, first_int);
            IF  (keep_datatype = dunicode) AND
                (d_datatype <> dunicode)
            THEN
                BEGIN
                colin.sci_typ   := dunicode;
                colin.sci_iolen := (2*colin.sci_len)+1;
                a641string_set_operator (acv, op_b_uni_trans, 0, 0,
                      chr(csp_ascii), chr(csp_unicode));
                d_datatype := dunicode
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641char (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n        : integer;
      keep_datatype : tsp00_DataType;
      dtyp          : tsp00_DataType;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    IF  NOT (d_datatype in [ dunknown, dnonumber, dcha,
        (* PTS 1109069 E.Z. *)
        dunicode,
        ddate, dtime, dtimestamp ])
    THEN
        wrong_datatype := true
    ELSE
        BEGIN
        keep_datatype := d_datatype;
        d_datatype    := dunknown;
        curr_n        := n_lo_level;
        colin.sci_len := 0;
        a640factor(acv, dmli, colin, curr_n);
        IF  (a_ap_tree^[ n_lo_level ].n_symb = s_null)
        THEN
            BEGIN
            d_datatype := ddate;
            colin.sci_typ := ddate;
            END;
        (*ENDIF*) 
        WITH a_ap_tree^[ n_lo_level ] DO
            IF  (n_proc = a67) AND (d_datatype = dcha) AND
                (n_datatype in [ ddate, dtime, dtimestamp ])
            THEN      (* the first function parameter was a corelated *)
                BEGIN (* column, with date/time/timestamp datatype.   *)
                a641check_datetime (acv, dmli, n_datatype);
                colin.sci_typ := n_datatype;
                CASE n_datatype OF
                    ddate:
                        colin.sci_len := mxsp_date;
                    dtime:
                        colin.sci_len := mxsp_time;
                    dtimestamp:
                        colin.sci_len := mxsp_timestamp
                    END;
                (*ENDCASE*) 
                d_datatype := n_datatype
                END;
&           ifdef TRACE
            (*ENDIF*) 
        (*ENDWITH*) 
        t01int4 (ak_sem, 'dattype     ', ord(d_datatype));
&       endif
        IF  (a_returncode = cak_e_parameter) AND
            (d_datatype <> dfixed)
        THEN
            (* PTS 1109261 E.Z. *)
            BEGIN
            a_returncode := 0;
            a07_b_put_error (acv, e_without_datatypes, n_pos)
            END
        ELSE
            IF  (a_returncode = 0)
            THEN
                IF  NOT (d_datatype in [ dfixed, dnumber, dtime, ddate,
                    dtimestamp ])
                THEN
                    wrong_datatype := true
                ELSE
                    IF  d_datatype in [  dfixed, dnumber ]
                    THEN
                        IF  (n_length <> ord(dtf_none)) OR
                            (a_sqlmode <> sqlm_db2)
                            OR (colin.sci_typ = dfloat)
                            OR (colin.sci_typ = dvfloat)
                        THEN
                            BEGIN
                            IF  (a_sqlmode <> sqlm_db2)
                                OR (colin.sci_typ = dfloat)
                                OR (colin.sci_typ = dvfloat)
                            THEN
                                a07_b_put_error (acv,
                                      e_incompatible_datatypes, n_pos)
                            ELSE
                                a07_b_put_error (acv, e_invalid_parameter,
                                      n_pos);
                            (*ENDIF*) 
                            END
                        ELSE
                            BEGIN
                            WITH colin DO
                                BEGIN
                                IF  sci_frac <> 0
                                THEN
                                    sci_iolen := sci_len + 2
                                ELSE
                                    sci_iolen := sci_len + 1;
                                (*ENDIF*) 
                                END;
                            (*ENDWITH*) 
                            a641stack_for_op_b_chr ( acv, dmli, colin, 0,
                                  keep_datatype);
                            END
                        (*ENDIF*) 
                    ELSE
                        BEGIN
                        WITH colin DO
                            BEGIN
                            IF  n_length = ord(dtf_none)
                            THEN
                                n_length := ord(a_dt_format);
                            (*ENDIF*) 
                            dtyp := d_datatype;
                            CASE d_datatype OF
                                ddate      :
                                    BEGIN
                                    IF  (n_length <> ord(dtf_normal))
                                    THEN
                                        sci_len  := mxsp_extdate;
                                    (*ENDIF*) 
                                    END;
                                dtime      :
                                    BEGIN
                                    IF  n_length <> ord(dtf_normal)
                                    THEN
                                        sci_len  := mxsp_exttime;
                                    (*ENDIF*) 
                                    END;
                                dtimestamp :
                                    BEGIN
                                    IF  n_length <> ord(dtf_normal)
                                    THEN
                                        IF  n_length <> ord(dtf_oracle_date)
                                        THEN
                                            BEGIN
                                            sci_len  := mxsp_exttimestamp;
                                            (* n_length := ord(dtf_iso) *)
                                            END;
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    END;
                                END;
                            (*ENDCASE*) 
                            d_datatype := dcha;
                            sci_iolen := sci_len + 1;
                            sci_frac  := 0;
                            sci_typ := d_datatype;
                            END;
                        (*ENDWITH*) 
                        WITH a_mblock, mb_qual^, mb_st^ [mfirst_free] DO
                            IF  mfirst_free >= mb_st_max
                            THEN
                                a07_b_put_error (acv,
                                      e_too_many_mb_stackentries, -mb_st_max)
                            ELSE
                                BEGIN
                                etype         := st_build_in_func;
                                eop_build_in  := op_b_format_change;
                                IF  a_ap_tree^[ act_node ].n_length =
                                    ord(dtf_normal)
                                THEN
                                    eformat := dtf_normal
                                ELSE
                                    IF  a_ap_tree^[ act_node ].n_length =
                                        ord(dtf_iso)
                                    THEN
                                        eformat := dtf_iso
                                    ELSE
                                        IF  a_ap_tree^[ act_node ].n_length =
                                            ord(dtf_usa)
                                        THEN
                                            eformat := dtf_usa
                                        ELSE
                                            IF  a_ap_tree^[ act_node ].n_length =
                                                ord(dtf_eur)
                                            THEN
                                                eformat := dtf_eur
                                            ELSE
                                                IF  a_ap_tree^[ act_node ].n_length =
                                                    ord(dtf_jis)
                                                THEN
                                                    eformat := dtf_jis
                                                ELSE
                                                    IF  a_ap_tree^[ act_node ].n_length =
                                                     ord(dtf_oracle_date)
                                                    THEN
                                                     eformat := dtf_oracle_date;
                                                    (* PTS 1112472 E.Z. *)
                                                    (*ENDIF*) 
                                                (*ENDIF*) 
                                            (*ENDIF*) 
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                (*ENDIF*) 
                                edatatype     := dtyp;
                                elanguage     := a_ak_language;
                                elength       := colin.sci_iolen;
                                mfirst_free   := succ(mfirst_free);
                                mqual_cnt     := succ(mqual_cnt)
                                END
                            (*ENDIF*) 
                        (*ENDWITH*) 
                        END
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641charset_get (
            VAR acv       : tak_all_command_glob;
            node          : tsp00_Int2;
            VAR setname   : tsp00_KnlIdentifier;
            VAR messcode  : tsp00_CodeType;
            VAR codewidth : tsp00_Uint1);
 
VAR
      setnamelength     : tsp00_Int4;
      uni_err           : tsp8_uni_error;
      err_char_no       : tsp00_Int4;
 
BEGIN
WITH acv, a_ap_tree^[ node ] DO
    BEGIN
    setnamelength := sizeof(setname);
    IF  g01unicode
    THEN
        BEGIN
        s80uni_trans (@a_cmd_part^.sp1p_buf[ n_pos ], n_length, csp_unicode,
              @setname, setnamelength,
              csp_ascii, [ ], uni_err, err_char_no);
        IF  uni_err <> uni_ok
        THEN
            a07_b_put_error (acv, e_unknown_multibyte_set, 1)
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        IF  n_length > setnamelength
        THEN
            a07_b_put_error (acv, e_unknown_multibyte_set, 1)
        ELSE
            BEGIN
            SAPDB_PascalMove ('VAK641',   2,    
                  a_cmd_part^.sp1p_buf_len, sizeof(setname),
                  @a_cmd_part^.sp1p_buf, n_pos, @setname, 1, n_length,
                  a_returncode);
            setnamelength := n_length;
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        SAPDB_PascalFill ('VAK641',   3,    
              sizeof(setname), @setname, setnamelength + 1,
              sizeof(setname) - setnamelength, csp_ascii_blank,
              a_returncode);
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        g20get_uni_key (setname, messcode, codewidth, uni_err);
        IF  (uni_err <> uni_ok)
        THEN
            a07_b_put_error (acv, e_unknown_multibyte_set, 1)
        ELSE
            IF  (messcode = csp_unicode) AND
                (a_cmd_packet_header.sp1h_mess_swap <> sw_normal)
            THEN
                messcode := csp_unicode_swap
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641mbcs (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer);
 
VAR
      curr_n        : integer;
      isostr        : tsp00_KnlIdentifier;
      messcode      : tsp00_CodeType;
      codewidth     : tsp00_Uint1;
      curr_leng     : integer;
      curr_data_pos : integer;
      ecoltab1      : char;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dunknown;
    colin.sci_len := 0;
    curr_n        := n_lo_level;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        IF  (a_ap_tree^[ curr_n ].n_sa_level <> 0)
        THEN
            BEGIN
            curr_n := a_ap_tree^[ curr_n ].n_sa_level;
            a641charset_get (acv, curr_n, isostr, messcode, codewidth);
            END
        ELSE
            BEGIN
            messcode  := a_out_packet^.sp1_header.sp1h_mess_code;
            g20get_uni_set (messcode, codewidth, isostr);
            END;
        (*ENDIF*) 
&   ifdef TRACE
    (*ENDIF*) 
    t01lidentifier (ak_sem, isostr);
    t01int4 (ak_sem, 'messcode    ', messcode);
    t01int4 (ak_sem, 'codewidth   ', codewidth);
&   endif
    IF  (acv.a_returncode = 0) AND
        (messcode > csp_unicode)
    THEN
        WITH acv, a_mblock, mb_qual^, mb_data^ DO
            BEGIN
            messcode := c_undef_mcode;
            curr_data_pos := a_mblock.mb_data_len + 1;
            curr_leng     := sizeof (isostr);
            IF  mfirst_free > mb_st_max
            THEN
                a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
            ELSE
                IF  mb_data_size < curr_data_pos + 1 + curr_leng
                THEN
                    a07_b_put_error (acv, e_too_many_mb_data, -mb_data_size);
                (*ENDIF*) 
            (*ENDIF*) 
            IF  a_returncode = 0
            THEN
                BEGIN
                mbp_buf [ curr_data_pos ] := bsp_c1;
                SAPDB_PascalMove ('VAK641',   4,    
                      sizeof (isostr), mb_data_size, @isostr, 1,
                      @mbp_buf, curr_data_pos + 1, sizeof(isostr),
                      a_returncode);
                IF  a_returncode = 0
                THEN
                    BEGIN
                    mb_data_len := mb_data_len + curr_leng + 1;
                    mqual_cnt := succ (mqual_cnt);
                    WITH mb_st^ [mfirst_free] DO
                        BEGIN
                        etype         := st_value;
                        eop           := op_none;
                        epos          := curr_data_pos;
                        elen_var      := curr_leng + 1;
                        ecol_tab[ 1 ] := chr(0);
                        ecol_tab[ 2 ] := chr(0);
                        END;
                    (*ENDWITH*) 
                    mfirst_free := succ (mfirst_free)
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        WITH colin DO
            BEGIN
            IF  sci_typ = dcha
            THEN
                ecoltab1 := chr (csp_ascii)
            ELSE
                ecoltab1 := chr (csp_unicode);
            (*ENDIF*) 
            sci_typ   := dchb;
            sci_len   := sci_len * codewidth;
            sci_iolen := sci_len + 1;
            a641string_set_operator (acv, op_b_uni_trans,
                  sci_iolen, 0, ecoltab1, chr(messcode));
            END;
        (*ENDWITH*) 
&   ifdef TRACE
    (*ENDIF*) 
    t01messblock (ak_sem, 'a641mbcs    ', acv.a_mblock);
&   endif
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641check_datatype (
            VAR acv            : tak_all_command_glob;
            VAR colin          : tak00_scolinf;
            VAR colin1         : tak00_scolinf;
            VAR wrong_datatype : boolean);
 
BEGIN
CASE colin.sci_typ OF
    dtime, ddate, dtimestamp :
        BEGIN
        IF  NOT (colin1.sci_typ in [ dcha, ddate, dtime, dtimestamp ])
        THEN
            wrong_datatype := true;
        (*ENDIF*) 
        colin.sci_typ := dcha
        END;
    dcha :
        IF  NOT (colin1.sci_typ in [ dcha,
            dtime, ddate, dtimestamp ])
        THEN
            IF  colin1.sci_typ = dunicode
            THEN
                BEGIN
                colin.sci_typ   := dunicode;
                colin.sci_iolen := succ(2*colin.sci_len);
                END
            ELSE
                wrong_datatype := true;
            (*ENDIF*) 
        (*ENDIF*) 
    dchb :
        IF  colin1.sci_typ <> colin.sci_typ
        THEN
            wrong_datatype := true;
        (*ENDIF*) 
    dunicode :
        IF  colin1.sci_typ <> colin.sci_typ
        THEN
            IF  colin1.sci_typ = dcha
            THEN
                BEGIN
                colin1.sci_typ   := dunicode;
                colin1.sci_iolen := succ(2*colin1.sci_len);
                a641string_set_operator (acv,
                      op_b_uni_trans, colin1.sci_iolen, 0,
                      chr(csp_ascii), chr(csp_unicode));
                END
            ELSE
                wrong_datatype := true;
            (*ENDIF*) 
        (*ENDIF*) 
    OTHERWISE
        wrong_datatype := true
    END
(*ENDCASE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641chr (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            act_node           : integer;
            VAR colin          : tak00_scolinf;
            VAR wrong_datatype : boolean);
 
VAR
      keep_datatype : tsp00_DataType;
      curr_n        : integer;
      first_int     : tsp00_Int2;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    keep_datatype := d_datatype;
    d_datatype    := dunknown;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = cak_e_parameter
    THEN
        BEGIN
        a_returncode := 0;
        d_datatype         := dnumber;
        a640factor (acv, dmli, colin, curr_n)
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        IF  (NOT (keep_datatype in [dunicode, dunknown, dnonumber]) AND
            (colin.sci_typ = dunicode))
            OR
            ((keep_datatype = dchb) AND (colin.sci_typ <> dchb))
            OR
            (NOT (keep_datatype in [dchb, dunknown, dnonumber]) AND
            (colin.sci_typ = dchb))
            OR
            ((a_sqlmode = sqlm_oracle) AND (d_datatype = dcha))
        THEN
            wrong_datatype := true
        ELSE
            BEGIN
            first_int := 0;
            IF  a_ap_tree^[ curr_n ].n_sa_level <> 0
            THEN
                BEGIN
                curr_n := a_ap_tree^[ curr_n ].n_sa_level;
                a05_unsigned_int2_get (acv, a_ap_tree^[ curr_n ].n_pos,
                      a_ap_tree^[ curr_n ].n_length, e_invalid_datalength, first_int);
                IF  (
                    (first_int < 1)                              OR
                    (first_int > cak_maxdeffieldlength)       OR
                    ((2*first_int > cak_maxdeffieldlength) AND
                    ( d_datatype = dunicode))
                    )
                THEN
                    a07_b_put_error (acv, e_invalid_datalength,
                          a_ap_tree^[ curr_n ].n_pos)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  a_returncode = 0
            THEN
                IF  d_datatype = dunicode
                THEN
                    WITH colin DO
                        BEGIN
                        IF  first_int > 0
                        THEN
                            BEGIN
                            sci_iolen := succ (2*first_int);
                            IF  (d_concat OR d_view)
                            THEN
                                a641string_set_operator (acv, op_b_expand,
                                      sci_iolen(*new*), sci_len(*old*),
                                      chr(0), chr(0));
                            (*ENDIF*) 
                            d_expand  := first_int;
                            sci_frac  := 0;
                            sci_len   := first_int;
                            a641string_set_operator (acv, op_b_checklen,
                                  pred(sci_iolen), 0, chr(0), chr(0));
                            END
                        (*ENDIF*) 
                        END
                    (*ENDWITH*) 
                ELSE
                    a641stack_for_op_b_chr ( acv, dmli, colin, first_int,
                          keep_datatype);
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641chr_ora (
            VAR acv  : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    colin.sci_len := 0;
    curr_n        := n_lo_level;
    d_datatype    := dnumber;
    a640factor(acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        WITH colin DO
            BEGIN
            sci_frac   := 0;
            sci_len    := 1;
            sci_iolen  := sci_len + 1;
            d_datatype := dcha;
            sci_typ    := d_datatype;
            a641string_set_operator (acv, op_b_chr_ora, sci_iolen, 0,
                  chr(g01code.ctype), chr(0));
            END
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641concat (
            VAR acv           : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
CONST
      c_max_recursive_loop = 50;
 
VAR
      curr_n        : integer;
      max_length    : integer;
      max_loop_cnt  : integer;
      colin1        : tak00_scolinf;
      keep_datatype : tsp00_DataType;
      h_datatype    : tsp00_DataType;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], a_mblock, mb_qual^, dmli DO
    BEGIN
    keep_datatype := d_datatype;
    IF  ((d_datatype = ddate) OR
        (d_datatype = dtime) OR
        (d_datatype = dtimestamp))
    THEN
        d_datatype := dcha
    ELSE
        IF  d_datatype = dunknown
        THEN
            d_datatype := dnonumber;
        (*ENDIF*) 
    (*ENDIF*) 
    d_concat      := true;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  (a_returncode = 0)
    THEN
        BEGIN
&       ifdef TRACE
        t01int4 (ak_sem, 'colin.typ co', ord(colin.sci_typ));
        t01int4 (ak_sem, 'd_datatype =', ord(d_datatype));
        t01int4 (ak_sem, 'd_change  co', ord(d_change_date_time));
&       endif
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        (* only because of ASCII || UNICODE we have to inspect *)
        (* the right side before working with it               *)
        IF  NOT(d_datatype in [ dchb, dunicode]) AND
            (keep_datatype in [ dunknown, dnonumber ])
        THEN
            BEGIN
            h_datatype := d_datatype;
            d_datatype := dunknown;
            a65_look_for_datatypes (acv, dmli, curr_n);
            IF  d_datatype = dunicode
            THEN
                BEGIN
                colin.sci_typ   := dunicode;
                colin.sci_iolen := (2*colin.sci_len)+1;
                IF  h_datatype = dcha
                THEN
                    a641string_set_operator (acv, op_b_uni_trans, 0, 0,
                          chr(csp_ascii), chr(csp_unicode))
                (*ENDIF*) 
                END
            ELSE
                d_datatype := h_datatype;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        colin1.sci_len := 0;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        d_concat := false;
        IF  (a_returncode = 0)
        THEN
            BEGIN
&           ifdef trace
            t01int4 (ak_sem,'atsubquery  ', ord(d_subquery));
            t01int4 (ak_sem,'dt_format   ', ord(a_dt_format));
            t01int4 (ak_sem,'colin1.sci_t', ord(colin1.sci_typ));
            t01int4 (ak_sem, 'd_change    ', ord(d_change_date_time));
&           endif
            IF  ((ctopt in colin.sci_cprops ) OR
                (ctopt in colin1.sci_cprops ))
            THEN
                colin.sci_cprops := [ ctopt ];
            (*ENDIF*) 
            IF  (keep_datatype in [ dunknown, dnonumber ])         AND
                (colin.sci_typ <> dunicode)                        AND
                (mb_st^[ mfirst_free-1 ].etype = st_build_in_func) AND
                (mb_st^[ mfirst_free-1 ].eop_build_in = op_b_uni_trans) AND
                (mb_st^[ mfirst_free-1 ].ecol_tab[ 2 ] <> chr(c_undef_mcode))
            THEN
                BEGIN
                (* left side <> unicode, right = unicode, *)
                (* we have to change to unicode           *)
                (* compare kb78concat                     *)
                mb_qual^.mfirst_free := mb_qual^.mfirst_free-1;
                mb_qual^.mqual_cnt   := mb_qual^.mqual_cnt-1;
                colin.sci_typ   := dunicode;
                colin.sci_iolen := (2*colin.sci_len)+1;
                colin1.sci_typ   := dunicode;
                colin1.sci_iolen := (2*colin1.sci_len)+1;
                END;
            (*ENDIF*) 
            ak641check_datatype (acv, colin, colin1, wrong_datatype);
            (* In case of a string_function it is      *)
            (* necessary to check the datatypes of the *)
            (* two factors about compatiblity          *)
            CASE a_sqlmode OF
                sqlm_db2 :
                    max_length := cak_maxdb2fieldlength;
                sqlm_oracle :
                    max_length := cak_maxorafieldlength;
                sqlm_internal :
                    max_length := cak_maxdeffieldlength;
                OTHERWISE
                    max_length := cak_maxfieldlength;
                END;
            (*ENDCASE*) 
            colin.sci_frac := 0;
&           ifdef trace
            t01int4 (ak_sem, 'c.typ       ', ord(colin.sci_typ));
            t01int4 (ak_sem, 'c1.typ      ', ord(colin1.sci_typ));
            t01int4 (ak_sem, 'c.sci_len   ', colin.sci_len);
            t01int4 (ak_sem, 'c1.sci_len  ', colin1.sci_len);
            t01int4 (ak_sem, 'c.sci_iolen ', colin.sci_iolen);
            t01int4 (ak_sem, 'c1.sci_iolen', colin1.sci_iolen);
&           endif
            (* Resulting length is sum of single lengths *)
            (* Outputlength is decremented because  *)
            (* both single outputlengths are soon   *)
            (* incremented                          *)
            IF  a_recursive_state = rs_check_select_list
            THEN
                BEGIN
                IF  dmli.d_inoutpos + max_length + KEY_MXSP00 >
                    MAX_RECLEN_GG00
                THEN
                    max_length := MAX_RECLEN_GG00
                          - dmli.d_inoutpos - KEY_MXSP00;
                (*ENDIF*) 
                IF  ((colin.sci_iolen +
                    c_max_recursive_loop * (colin1.sci_iolen - 1))
                    > (max_length+1))
                THEN
                    max_loop_cnt := (max_length + 1 - colin.sci_iolen) DIV
                          (colin1.sci_iolen - 1)
                ELSE
                    max_loop_cnt := c_max_recursive_loop;
                (*ENDIF*) 
                colin.sci_iolen := colin.sci_iolen +
                      max_loop_cnt * (colin1.sci_iolen - 1);
                colin.sci_len := colin.sci_len +
                      max_loop_cnt * colin1.sci_len;
                END
            ELSE
                IF  a_recursive_state = rs_no_recursive_select
                THEN
                    BEGIN
                    colin.sci_len := colin.sci_len + colin1.sci_len;
                    colin.sci_iolen := colin.sci_iolen + colin1.sci_iolen -1;
                    END;
&               ifdef trace
                (*ENDIF*) 
            (*ENDIF*) 
            t01int4 (ak_sem, 'cN.sci_len  ', colin.sci_len);
            t01int4 (ak_sem, 'cN.sci_iolen', colin.sci_iolen);
            t01int4 (ak_sem, 'a_is_ddl    ', ord(acv.a_is_ddl));
&           endif
            IF  (colin.sci_iolen > max_length+1) AND
                NOT (acv.a_is_ddl in [ddl_create_trigger, ddl_create_procedure])
            THEN
                a07_b_put_error (acv, e_one_output_field_too_long,
                      a_ap_tree^[ act_node ].n_pos)
            ELSE
                BEGIN
                IF  (colin.sci_typ = dunicode)
                THEN
                    a641string_set_operator (acv, op_b_dbyte_concat,
                          colin.sci_iolen, colin.sci_len, chr(2), chr(0))
                ELSE
                    a641string_set_operator (acv, op_b_concat,
                          colin.sci_iolen, colin.sci_len, chr(2), chr(0))
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  ((a_returncode = 0) AND
        ((keep_datatype = ddate) OR
        (keep_datatype = dtime) OR
        (keep_datatype = dtimestamp)))
    THEN
        d_datatype := keep_datatype;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641conversion (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_ch_datatype := dunknown;
    IF  (d_datatype = dunknown) OR (n_symb = s_ascii)
    THEN
        d_datatype := dnonumber;
    (*ENDIF*) 
    curr_n := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        CASE n_symb OF
            s_upper, s_lower, s_initcap:
                IF  colin.sci_typ = dcha
                    (* Characterfields must be there *)
                THEN
                    CASE n_symb OF
                        s_upper :
                            a65_set_operator (acv, op_upcase);
                        s_lower :
                            a65_set_operator (acv, op_lowcase);
                        s_initcap :
                            a65_set_operator (acv, op_initcap);
                        END
                    (*ENDCASE*) 
                ELSE
                    IF  colin.sci_typ = dunicode
                    THEN
                        CASE n_symb OF
                            s_upper :
                                a65_set_operator (acv, op_dbyte_upper);
                            s_lower :
                                a65_set_operator (acv, op_dbyte_lower);
                            s_initcap :
                                a65_set_operator (acv, op_dbyte_initcap);
                            END
                        (*ENDCASE*) 
                    ELSE
                        IF  colin.sci_typ in [ ddate, dtime, dtimestamp ]
                        THEN
                            BEGIN
                            (* In case of date - or timefields *)
                            (* no conversion need to be done   *)
                            colin.sci_typ := dcha;
                            d_datatype := colin.sci_typ
                            END
                        ELSE
                            wrong_datatype := true;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
            (* PTS 1122828 E.Z. *)
            s_ascii :
                BEGIN
                IF  NOT (colin.sci_typ in [ dcha, dunicode,
                    dchb, (* PTS 1130550 E.Z. *)
                    ddate, dtime, dtimestamp ])
                THEN
                    wrong_datatype := true
                ELSE
                    BEGIN
                    IF  colin.sci_typ = dunicode
                    THEN
                        BEGIN
                        colin.sci_iolen := colin.sci_len + 1;
                        a641string_set_operator (acv,
                              op_b_uni_trans, colin.sci_iolen, 0,
                              chr(csp_unicode), chr(csp_ascii));
                        END
                    ELSE
                        IF  colin.sci_typ = dchb
                        THEN
                            a65_set_operator (acv, op_ascii);
                        (*ENDIF*) 
                    (*ENDIF*) 
                    d_datatype := dcha;
                    colin.sci_typ := dcha
                    END
                (*ENDIF*) 
                END;
            s_unicode :
                BEGIN
                IF  NOT (colin.sci_typ in [ dcha, dunicode,
                    ddate, dtime, dtimestamp ])
                THEN
                    wrong_datatype := true
                ELSE
                    BEGIN
                    IF  colin.sci_typ <> dunicode
                    THEN
                        BEGIN
                        colin.sci_iolen := (2*colin.sci_len) + 1;
                        a641string_set_operator (acv,
                              op_b_uni_trans, colin.sci_iolen, 0,
                              chr(csp_ascii), chr(csp_unicode));
                        END;
                    (*ENDIF*) 
                    d_datatype    := dunicode;
                    colin.sci_typ := dunicode
                    END
                (*ENDIF*) 
                END;
            END;
        (*ENDCASE*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641datediff (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
      colin1 : tak00_scolinf;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    curr_n := a_ap_tree^[ act_node ].n_lo_level;
    ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, ddate, ddate);
    IF  a_returncode =
        a071_return_code (e_incompatible_datatypes, a_sqlmode)
    THEN
        BEGIN
        a_returncode := 0;
        ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, dtimestamp, dtimestamp);
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        curr_n := a_ap_tree^[ curr_n ].n_sa_level;
        ak641not_first_type_or_timestamp_parameter (acv, dmli,
              colin1, curr_n, ddate)
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        d_datatype := dnumber;
        WITH colin DO
            BEGIN
            sci_len   := 7;
            sci_iolen := (sci_len + 1) DIV 2 + 2;
            sci_frac  := 0;
            sci_typ   := dfixed
            END;
        (*ENDWITH*) 
        a65_set_operator (acv, op_datediff)
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641datetime (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n      : integer;
      pos         : integer;
      off_set     : integer;
      func        : integer;
      wanted_type : tsp00_DataType;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli,
     a_mblock, mb_qual^ DO
    IF  NOT (d_datatype in [ dunknown, dnumber ])
    THEN
        wrong_datatype := true
    ELSE
        BEGIN
        CASE n_symb OF
            s_day, s_month, s_year :
                wanted_type := ddate;
            s_hour, s_minute, s_second :
                wanted_type := dtime;
            s_microsecond :
                wanted_type := dtimestamp
            END;
        (*ENDCASE*) 
        IF  (a_ap_tree^[ n_lo_level ].n_symb = s_null)
        THEN
            d_datatype := wanted_type
        ELSE
            d_datatype := dunknown;
        (*ENDIF*) 
        curr_n := n_lo_level;
        colin.sci_len := 0;
        a640factor(acv, dmli, colin, curr_n);
        IF  a_returncode = cak_e_parameter
        THEN
            BEGIN
            a_returncode := 0;
            d_datatype := wanted_type;
            a640factor(acv, dmli, colin, curr_n)
            END;
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            BEGIN
            WITH colin DO
                BEGIN
&               ifdef trace
                t01int4 (ak_sem,'DM_DATATYPE ', ord(d_datatype));
&               endif
                IF  (colin.sci_typ = dcha) OR
                    (colin.sci_typ = dunicode)
                THEN
                    BEGIN
                    a641check_datetime(acv, dmli, wanted_type);
                    d_datatype := wanted_type
                    END;
                (*ENDIF*) 
                sci_len     := 0;
                pos     := 0;
                off_set := 0;
                func    := 0;
                CASE n_symb OF
                    s_day  :
                        IF  NOT ((d_datatype in [ dnumber, ddate,
                            dtimestamp ]) AND (a_sqlmode = sqlm_db2))
                            AND
                            (* PTS 1000313 E.Z. *)
                            (* PTS 1105820 E.Z. *)
                            NOT ((d_datatype in [ ddate, dtimestamp ])
                            AND (a_sqlmode = sqlm_internal))
                        THEN
                            wrong_datatype := true
                        ELSE
                            BEGIN
                            sci_len := 2;
                            pos := 7;
                            func := 2
                            END;
                        (*ENDIF*) 
                    s_hour   :
                        IF  NOT ((d_datatype in [ dnumber, dtime,
                            dtimestamp ]) AND (a_sqlmode = sqlm_db2))
                            AND
                            NOT ((d_datatype in [ dtime, dtimestamp ])
                            AND (a_sqlmode = sqlm_internal))
                        THEN
                            wrong_datatype := true
                        ELSE
                            BEGIN
                            pos  := 1;
                            func := 3;
                            IF  d_datatype = dtimestamp
                            THEN
                                BEGIN
                                sci_len := 2;
                                off_set := 8
                                END
                            ELSE
                                sci_len := 4
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                    s_minute :
                        IF  NOT ((d_datatype in [ dnumber, dtime,
                            dtimestamp ]) AND (a_sqlmode = sqlm_db2))
                            AND
                            NOT ((d_datatype in [ dtime, dtimestamp ])
                            AND (a_sqlmode = sqlm_internal))
                        THEN
                            wrong_datatype := true
                        ELSE
                            BEGIN
                            sci_len := 2;
                            pos := 5;
                            func := 4;
                            IF  d_datatype = dtimestamp
                            THEN
                                off_set := 6
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                    s_microsecond :
                        IF  d_datatype <> dtimestamp
                        THEN
                            wrong_datatype := true
                        ELSE
                            BEGIN
                            sci_len := 6;
                            pos := 15;
                            func := 6
                            END;
                        (*ENDIF*) 
                    s_month :
                        IF  NOT ((d_datatype in [ dnumber, ddate,
                            dtimestamp ]) AND (a_sqlmode = sqlm_db2))
                            AND
                            (* PTS 1000313 E.Z. *)
                            (* PTS 1105820 E.Z. *)
                            NOT ((d_datatype in [ ddate, dtimestamp ])
                            AND (a_sqlmode = sqlm_internal))
                        THEN
                            wrong_datatype := true
                        ELSE
                            BEGIN
                            sci_len := 2;
                            pos := 5;
                            func := 1
                            END;
                        (*ENDIF*) 
                    s_second :
                        IF  NOT ((d_datatype in [ dnumber, dtime,
                            dtimestamp ]) AND (a_sqlmode = sqlm_db2))
                            AND
                            NOT ((d_datatype in [ dtime, dtimestamp ])
                            AND (a_sqlmode = sqlm_internal))
                        THEN
                            wrong_datatype := true
                        ELSE
                            BEGIN
                            sci_len := 2;
                            pos := 7;
                            func := 5;
                            IF  d_datatype = dtimestamp
                            THEN
                                off_set := 6
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                    s_year :
                        IF  NOT ((d_datatype in [ dnumber, ddate,
                            dtimestamp ]) AND (a_sqlmode = sqlm_db2))
                            AND
                            (* PTS 1000313 E.Z. *)
                            (* PTS 1105820 E.Z. *)
                            NOT ((d_datatype in [ ddate, dtimestamp ])
                            AND (a_sqlmode = sqlm_internal))
                        THEN
                            wrong_datatype := true
                        ELSE
                            BEGIN
                            sci_len := 4;
                            pos := 1;
                            func := 0;
                            END
                        (*ENDIF*) 
                    END;
                (*ENDCASE*) 
                sci_frac := 0;
                IF  ( n_symb = s_year) OR
                    ((n_symb = s_hour) AND (d_datatype <> dtimestamp))
                THEN
                    sci_iolen := 4
                ELSE
                    IF  n_symb = s_microsecond
                    THEN
                        sci_iolen := 5
                    ELSE
                        sci_iolen := 3;
                    (*ENDIF*) 
                (*ENDIF*) 
                sci_typ := dfixed
                END;
            (*ENDWITH*) 
            IF  mfirst_free >= mb_st_max
            THEN
                a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
            ELSE
                WITH mb_st^ [mfirst_free] DO
                    BEGIN
                    etype         := st_build_in_func;
                    eop_build_in  := op_b_datetime;
                    elen_var      := colin.sci_len;
                    epos          := pos + off_set;
                    ecol_tab[ 1 ] := chr(func);
                    ecol_tab[ 2 ] := chr(0);
                    mfirst_free   := succ(mfirst_free);
                    mqual_cnt     := succ(mqual_cnt)
                    END
                (*ENDWITH*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        d_datatype := dnumber;
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641days (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
CONST
      maxdayslength = 7;
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype := dunknown;
    curr_n := n_lo_level;
    colin.sci_len := 0;
    a640factor(acv, dmli, colin, curr_n);
    IF  a_returncode = cak_e_parameter
    THEN
        (* PTS 1109261 E.Z. *)
        BEGIN
        a_returncode := 0;
        a07_b_put_error (acv, e_without_datatypes, n_pos)
        END
    ELSE
        IF  (a_returncode = 0)
        THEN
            IF  NOT (colin.sci_typ in [ ddate, dtimestamp,
                dcha, dunicode ] )
            THEN
                wrong_datatype := true
            ELSE
                BEGIN
                IF  d_datatype = dunicode
                THEN
                    BEGIN
                    colin.sci_typ   := dcha;
                    colin.sci_iolen := colin.sci_len+1;
                    a641string_set_operator (acv, op_b_uni_trans,
                          colin.sci_iolen, 0, chr(csp_unicode),
                          chr(csp_ascii));
                    END;
                (*ENDIF*) 
                IF  NOT (colin.sci_typ in [ ddate, dtimestamp ] )
                THEN
                    a641check_datetime(acv, dmli, ddate);
                (*ENDIF*) 
                WITH colin DO
                    BEGIN
                    sci_len         := maxdayslength;
                    d_datatype      := dnumber;
                    sci_frac        := 0;
                    sci_typ         := dfixed;
                    sci_iolen       := sci_len - 1;
                    a65_set_operator(acv, op_days)
                    END
                (*ENDWITH*) 
                END
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641digits (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype := dnumber;
    colin.sci_len  := 0;
    curr_n := n_lo_level;
    a640factor( acv, dmli, colin, curr_n );
    IF  a_returncode = 0
    THEN
        BEGIN
        colin.sci_typ := dcha;
        d_datatype    := dcha;
        WITH a_mblock, mb_qual^ DO
            IF  mfirst_free > mb_st_max
            THEN
                a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
            ELSE
                WITH mb_st^ [mfirst_free] DO
                    BEGIN
                    etype         := st_op;
                    eop           := op_digits;
                    epos          := 0;
                    elen_var      := colin.sci_len;
                    IF  colin.sci_frac >= 0
                    THEN
                        ecol_tab[ 1 ] := chr(colin.sci_frac)
                    ELSE
                        (* PTS 1123692 E.Z. *)
                        ecol_tab[ 1 ] := chr(255);
                    (*ENDIF*) 
                    ecol_tab[ 2 ] := chr(0);
                    mfirst_free   := succ(mfirst_free);
                    mqual_cnt     := succ(mqual_cnt)
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
        (*ENDWITH*) 
        (* PTS 1123692 E.Z. *)
        colin.sci_frac := 0;
        colin.sci_iolen := colin.sci_len + 1;
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641expand (
            VAR acv           : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      keep_datatype : tsp00_DataType;
      curr_n        : integer;
      first_int     : tsp00_Int2;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli, colin DO
    BEGIN
    IF  d_datatype = dunknown
    THEN
        d_datatype := dnonumber;
    (*ENDIF*) 
    curr_n  := n_lo_level;
    sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        keep_datatype := d_datatype;
        d_datatype    := dnumber;
        curr_n        := a_ap_tree^[ curr_n ].n_sa_level;
        IF  (a_ap_tree^[ curr_n ].n_symb <> s_null)
        THEN
            BEGIN
            a05_unsigned_int2_get (acv,
                  a_ap_tree^[ curr_n ].n_pos,
                  a_ap_tree^[ curr_n ].n_length, e_invalid_datalength, first_int);
            IF  first_int <= sci_len
            THEN
                a07_b_put_error (acv,
                      e_invalid_unsign_integer, n_pos)
            ELSE
                IF  (first_int > cak_maxdeffieldlength)
                    OR
                    ((2*first_int > cak_maxdeffieldlength) AND
                    (keep_datatype = dunicode))
                THEN
                    a07_b_put_error (acv,
                          e_invalid_datalength, n_pos);
                (*ENDIF*) 
            (*ENDIF*) 
            IF  a_returncode = 0
            THEN
                BEGIN
                IF  keep_datatype = dunicode
                THEN
                    sci_iolen := succ (2*first_int)
                ELSE
                    sci_iolen := succ (first_int);
                (*ENDIF*) 
                IF  (d_concat OR d_view)
                THEN
                    a641string_set_operator (acv, op_b_expand,
                          sci_iolen(*new*), sci_len(*old*),
                          chr(0), chr(0));
                (*ENDIF*) 
                d_expand  := first_int;
                sci_frac  := 0;
                sci_len   := first_int;
                END;
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            a641string_set_operator (acv, op_b_expand,
                  1, 0, csp_undef_byte, csp_undef_byte);
            d_expand  := cak_is_undefined;
            sci_frac  := 0;
            sci_len   := 0;
            sci_iolen := succ (sci_len);
            END;
        (*ENDIF*) 
        IF  keep_datatype in [ ddate, dtime, dtimestamp ]
        THEN
            BEGIN
            sci_typ := dcha;
            d_datatype := sci_typ
            END
        ELSE
            d_datatype := keep_datatype
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641space (
            VAR acv           : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n        : integer;
      first_int     : tsp00_Int2;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli, colin DO
    BEGIN
    curr_n := n_sa_level;
    a05_unsigned_int2_get (acv, a_ap_tree^[ curr_n ].n_pos,
          a_ap_tree^[ curr_n ].n_length, e_invalid_datalength, first_int);
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  NOT (d_datatype in [ dcha, dunicode, dunknown ])
        THEN
            wrong_datatype := true
        ELSE
            BEGIN
            IF  (first_int <= 0)
                OR
                (first_int > cak_maxdeffieldlength)
                OR
                ((2*first_int > cak_maxdeffieldlength) AND
                (d_datatype = dunicode))
            THEN
                a07_b_put_error (acv, e_invalid_datalength, n_pos);
            (*ENDIF*) 
            IF  a_returncode = 0
            THEN
                BEGIN
                IF  d_datatype in [dunknown, dnonumber]
                THEN
                    IF  g01unicode
                    THEN
                        d_datatype := dunicode
                    ELSE
                        d_datatype := dcha;
                    (*ENDIF*) 
                (*ENDIF*) 
                ak641push_blank (acv, d_datatype);
                sci_typ   := d_datatype;
                IF  sci_typ = dunicode
                THEN
                    sci_iolen := succ (2*first_int)
                ELSE
                    sci_iolen := succ (first_int);
                (*ENDIF*) 
                IF  (d_concat OR d_view)
                THEN
                    a641string_set_operator (acv, op_b_expand,
                          sci_iolen(*new*), 1,
                          chr(0), chr(0));
                (*ENDIF*) 
                sci_frac  := 0;
                sci_len   := first_int;
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641fixed_float (
            VAR acv  : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            symb      : tak_sc_symbol;
            act_node  : integer);
 
VAR
      curr_n     : integer;
      first_int  : tsp00_Int2;
      second_int : tsp00_Int2;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dnumber;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        ak641put_maxlength (acv, curr_n, symb, first_int, second_int);
        (*In procedure 'ak641put_maxlength' the two arguments   *)
        (*are directly analysed and put into the stackentry*)
        WITH colin DO
            BEGIN
            sci_len    := first_int;
            sci_frac   := second_int;
            sci_iolen  := (sci_len+1) DIV 2 + 2;
            IF  symb = s_fixed
            THEN
                sci_typ    := dfixed
            ELSE
                sci_typ    := dvfloat;
            (*ENDIF*) 
            sci_cprops := [ ctopt ]
            END
        (*ENDWITH*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641float (
            VAR acv  : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    colin.sci_len := 0;
    curr_n        := n_lo_level;
    d_datatype    := dnumber;
    a640factor(acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        WITH colin DO
            BEGIN
            sci_frac   := csp_float_frac;
            sci_typ    := dfloat;
            d_datatype := dnumber;
            END
        (*ENDWITH*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641_get_length (
            VAR colin            : tak00_scolinf;
            VAR output_length     : tsp00_Int2;
            VAR wrong_datatype    : boolean);
 
BEGIN
wrong_datatype := false;
WITH colin DO
    CASE sci_typ OF
        dcha, ddate, dtime, dtimestamp, dunicode:
            output_length := sci_len;
        dfloat, dvfloat:
            IF  (sci_len = 1)
            THEN
                output_length := 6
            ELSE
                output_length := sci_len + 6;
            (*ENDIF*) 
        dfixed:
            IF  (sci_len = sci_frac)
            THEN
                output_length := sci_len + 3
            ELSE
                IF  (sci_frac <> 0)
                THEN
                    output_length := sci_len + 2
                ELSE
                    output_length := succ (sci_len);
                (*ENDIF*) 
            (*ENDIF*) 
        OTHERWISE:
            BEGIN
            wrong_datatype := true;
            output_length  := 0;
            END;
        END;
    (*ENDCASE*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641_hextoraw (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dunknown;
    colin.sci_len := 0;
    curr_n        := n_lo_level;
    a640factor (acv, dmli, colin, curr_n);
    IF  (a_returncode = 0)
    THEN
        IF  NOT (d_datatype in [ dcha, dunicode ])
        THEN
            wrong_datatype := true
        ELSE
            BEGIN
            IF  d_datatype = dunicode
            THEN
                a641string_set_operator (acv,
                      op_b_uni_trans, colin.sci_iolen, 0,
                      chr(csp_unicode), chr(csp_ascii));
            (*ENDIF*) 
            colin.sci_len := (colin.sci_len + 1) DIV 2;
            a65_set_operator(acv, op_hextoraw);
            IF  a_returncode = 0
            THEN
                BEGIN
                d_datatype      := dchb;
                colin.sci_typ   := dchb;
                colin.sci_iolen := colin.sci_len + 1;
                colin.sci_frac  := 0;
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641hex (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n     : integer;
      max_length : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_hex         := true;
    d_datatype    := dunknown;
    colin.sci_len := 0;
    curr_n        := n_lo_level;
    a640factor( acv, dmli, colin, curr_n );
    IF  (a_sqlmode = sqlm_oracle) AND
        (d_datatype in [  ddate, dtime, dtimestamp ])
    THEN
        wrong_datatype := true;
    (*ENDIF*) 
    IF  a_returncode = cak_e_parameter
    THEN
        BEGIN
        a_returncode := 0;
        d_datatype  := dnonumber;
        a640factor (acv, dmli, colin, curr_n)
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        CASE a_sqlmode OF
            sqlm_db2 :
                max_length := cak_maxdb2fieldlength;
            sqlm_oracle :
                max_length := cak_maxorafieldlength;
            sqlm_internal :
                max_length := cak_maxdeffieldlength;
            OTHERWISE
                max_length := cak_maxfieldlength;
            END;
        (*ENDCASE*) 
        (* PTS 1000311 E.Z. *)
        IF  colin.sci_typ in [ dcha, dchb,
            ddate, dtime, dtimestamp ]
        THEN
            colin.sci_len := 2 * colin.sci_len
        ELSE
            colin.sci_len := 2 * (colin.sci_iolen-1);
        (*ENDIF*) 
        colin.sci_frac  := 0;
        colin.sci_iolen := colin.sci_len + 1;
        IF  colin.sci_iolen > max_length
        THEN
            a07_b_put_error (acv, e_one_output_field_too_long,
                  a_ap_tree^[ act_node ].n_pos);
        (*ENDIF*) 
        d_datatype    := dcha;
        colin.sci_typ := dcha;
        a65_set_operator(acv, op_hex)
        END;
    (*ENDIF*) 
    d_hex := false;
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641index (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      index_from_null : boolean;
      curr_n          : integer;
      index           : integer;
      param_cnt       : integer;
      old_n           : integer;
      start           : tsp00_Int2;
      n_err           : tsp00_NumError;
      colin1          : tak00_scolinf;
      colin2          : tak00_scolinf;
      vallen          : integer;
      valptr          : tsp00_MoveObjPtr;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    param_cnt     := 2;
    d_datatype    := dnonumber;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    index_from_null := (a_ap_tree^[ curr_n ].n_proc = no_proc) AND
          (a_ap_tree^[ curr_n ].n_symb = s_null);
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        colin1.sci_len := 0;
        IF  ((d_datatype = ddate) OR
            (d_datatype = dtime) OR
            (d_datatype = dtimestamp))
        THEN
            d_datatype := dcha;
        (*ENDIF*) 
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  a_returncode = 0
        THEN
            BEGIN
            ak641check_datatype (acv, colin, colin1,
                  wrong_datatype);
            IF  NOT wrong_datatype
            THEN
                BEGIN
                d_datatype := dnumber;
                curr_n     := a_ap_tree^[ curr_n ].n_sa_level;
                old_n      := curr_n;
                IF  curr_n <> 0
                THEN
                    BEGIN
                    param_cnt      := succ(param_cnt);
                    colin1.sci_len := 0;
                    a640not_first_factor (acv, dmli, colin1, curr_n);
                    IF  a_ap_tree^[ old_n ].n_symb = s_unsigned_integer
                    THEN
                        WITH a_mblock, mb_qual^ DO
                            BEGIN
                            index := mfirst_free - 1;
                            g04value_locate (mb_st^[index], a_mblock, valptr, vallen);
                            s40gsint (valptr^, 2, (vallen - 1 - csp_attr_byte) * 2,
                                  start, n_err);
                            IF  n_err = num_ok
                            THEN
                                IF  ((start < 1)
                                    OR
                                    ((start > colin.sci_len) AND
                                    NOT index_from_null))
                                THEN
                                    a07_b_put_error (acv,
                                          e_invalid_char_position,
                                          n_pos);
                                (*ENDIF*) 
                            (*ENDIF*) 
                            IF  a_returncode = 0
                            THEN
                                BEGIN
                                curr_n :=
                                      a_ap_tree^[ curr_n ].n_sa_level;
                                IF  curr_n <> 0
                                THEN
                                    BEGIN
                                    param_cnt      := succ(param_cnt);
                                    colin2.sci_len := 0;
                                    a640not_first_factor (acv, dmli, colin2,
                                          curr_n);
                                    END;
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                            END;
                        (*ENDWITH*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  a_returncode = 0
                THEN
                    BEGIN
                    CASE param_cnt OF
                        2:
                            a641string_set_operator (acv,
                                  op_b_index, 3, colin.sci_len,
                                  chr(2), chr(0));
                        3:
                            a641string_set_operator (acv,
                                  op_b_index, 3, colin.sci_len,
                                  chr(3), chr(0));
                        4:
                            a641string_set_operator (acv,
                                  op_b_index, 3, colin.sci_len,
                                  chr(4), chr(0));
                        END;
                    (*ENDCASE*) 
                    WITH colin DO
                        BEGIN
                        sci_len   := 3;
                        sci_frac  := 0;
                        sci_iolen := 4;
                        sci_typ   := dfixed
                        END
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641last_day (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dtimestamp;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  colin.sci_typ <> dtimestamp
        THEN
            a641check_datetime(acv, dmli, dtimestamp);
        (*ENDIF*) 
        d_datatype := dtimestamp;
        WITH colin DO
            BEGIN
            sci_len   := mxsp_exttimestamp;
            sci_iolen := succ(sci_len);
            sci_frac  := 0;
            sci_typ   := dtimestamp;
            END;
        (*ENDWITH*) 
        a65_set_operator (acv, op_last_day)
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641length_vsize (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            symbol             : tak_sc_symbol;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n         : integer;
      oldlen         : integer;
      reslen         : integer;
      res_len        : tsp00_Int2;
      curr_data_pos  : tsp00_Int4;
      h_long_allowed : boolean;
 
BEGIN
(* This procedure describes the results of the build-in *)
(* functions length and vsize both.                     *)
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    reslen := 4;
    d_datatype     := dunknown;
    curr_n         := n_lo_level;
    colin.sci_len  := 0;
    h_long_allowed      := d_type_long_allowed;
    d_type_long_allowed := true;
    a640factor (acv, dmli, colin, curr_n);
    IF  (a_returncode = cak_e_parameter)
    THEN
        BEGIN
        a_returncode := 0;
        d_datatype  := dnonumber;
        a640factor (acv, dmli, colin, curr_n)
        END;
    (*ENDIF*) 
    d_type_long_allowed := h_long_allowed;
    IF  (a_returncode = 0)
    THEN
        IF  (a_sqlmode <> sqlm_oracle) OR (symbol = s_vsize) OR
            NOT (d_datatype in [dnumber, dfixed, dfloat, dvfloat])
        THEN
            BEGIN
            IF  d_datatype in [dlonga, dlongb, dlonguni,
                dstra, dstrb, dstruni]
            THEN
                BEGIN
                WITH acv, a_mblock, mb_data^, mb_qual^ DO
                    IF  mfirst_free > mb_st_max - 1
                    THEN
                        a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
                    ELSE
                        IF  (colin.sci_len > SURROGATE_MXGG00)
                        THEN
                            ak641VirtualLongColumnNotImplemented (acv, n_pos)
                        ELSE
                            BEGIN
                            curr_data_pos := mb_data_len + 1;
                            WITH mb_st^[ mfirst_free ] DO
                                BEGIN
                                etype         := st_value;
                                eop           := op_none;
                                epos          := curr_data_pos;
                                elen_var      := sizeof (dmli.d_sparr.pbasep^.sbase.btreeid)+1;
                                ecol_tab[ 1 ] := chr (0);
                                ecol_tab[ 2 ] := chr (0)
                                END;
                            (*ENDWITH*) 
                            mbp_buf[ curr_data_pos ] := csp_defined_byte;
                            SAPDB_PascalMove ('VAK641',   5,    
                                  sizeof (dmli.d_sparr.pbasep^.sbase.btreeid), mb_data_size,
                                  @dmli.d_sparr.pbasep^.sbase.btreeid, 1, @mbp_buf, curr_data_pos+1,
                                  sizeof (dmli.d_sparr.pbasep^.sbase.btreeid),
                                  a_returncode);
                            mb_data_len := mb_data_len + sizeof (dmli.d_sparr.pbasep^.sbase.btreeid) + 1;
                            mfirst_free := succ (mfirst_free);
                            mqual_cnt   := mqual_cnt + 2;
                            WITH mb_st^ [mfirst_free] DO
                                BEGIN
                                etype         := st_op;
                                IF  (d_datatype in [dlonguni, dstruni]) AND
                                    (symbol <> s_vsize)
                                THEN
                                    eop       := op_dbyte_length
                                ELSE
                                    eop       := op_length;
                                (*ENDIF*) 
                                epos          := 0;
                                elen_var      := 0;
                                IF  d_datatype in [dlonga, dlongb, dlonguni]
                                THEN
                                    ecol_tab[ 1 ] := chr(ord(dlonga))
                                ELSE
                                    ecol_tab[ 1 ] := chr(ord(dstra));
                                (*ENDIF*) 
                                ecol_tab[ 2 ] := chr(1);
                                END;
                            (*ENDWITH*) 
                            mfirst_free := succ (mfirst_free);
                            reslen := 10;
                            END
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDWITH*) 
                END
            ELSE
                IF  (d_datatype = dunicode)
                    AND (symbol <> s_vsize)
                THEN
                    a65_set_operator (acv, op_dbyte_length)
                ELSE
                    a65_set_operator (acv, op_length)
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            oldlen := colin.sci_len;
            a641_get_length (colin, res_len, wrong_datatype);
            IF  NOT wrong_datatype
            THEN
                a641string_set_operator (acv, op_b_length_ora, 0,
                      oldlen, chr(0), chr(res_len));
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  NOT wrong_datatype
    THEN
        (* Because the maximal length of a charfield     *)
        (* is 255 and the length must be an integer,     *)
        (* lengthvalue in 'colinf' can be given directly *)
        WITH colin DO
            BEGIN
            sci_len    := reslen;
            sci_frac   := 0;
            sci_iolen  := (reslen + 1) DIV 2 + 2;
            sci_typ    := dfixed;
            sci_cprops := [ ctopt ];
            d_datatype := dnumber
            END
        (*ENDWITH*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641to_char (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer);
 
VAR
      curr_n          : integer;
      keep_datatype   : tsp00_DataType;
      colin2          : tak00_scolinf;
      max_length      : tsp00_Int2;
      to_char_variant : tsp00_Int2;
      vallen          : tsp00_Int4;
      value           : tsp00_MoveObjPtr;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    keep_datatype := d_datatype;
    d_datatype    := dunknown;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  (a_returncode = cak_e_parameter)
    THEN
        BEGIN
        a_returncode := 0;
        d_datatype  := dnonumber;
        a640factor (acv, dmli, colin, curr_n)
        END;
&   ifdef trace
    (*ENDIF*) 
    t01int4 (ak_sem, 'colin.scityp', ord (colin.sci_typ));
    t01int4 (ak_sem, 'd_datatype  ', ord (d_datatype));
&   endif
    curr_n := a_ap_tree^[ curr_n ].n_sa_level;
    IF  a_returncode = 0
    THEN
        IF  colin.sci_typ in [ dfixed, dfloat, dvfloat, dnumber ]
        THEN (* call of TO_CHAR with number. *)
            BEGIN
            IF  curr_n = 0
            THEN (* to_char_variant number to char conversion *)
                BEGIN
                to_char_variant := 3;
                IF  colin.sci_typ = dfixed
                THEN
                    (* '+/-' plus '.' *)
                    max_length  := 40
                ELSE
                    max_length  := 44
                (*ENDIF*) 
                END
            ELSE
                BEGIN (* TO_CHAR (<number>, 'format') *)
                to_char_variant := 2;
                IF  g01unicode
                THEN
                    d_datatype := dcha
                ELSE
                    d_datatype := dunknown;
                (*ENDIF*) 
                a640not_first_factor (acv, dmli, colin2, curr_n);
                IF  (a_returncode = cak_e_parameter)
                THEN
                    BEGIN
                    a_returncode := 0;
                    d_datatype  := dnonumber;
                    a640not_first_factor (acv, dmli, colin2, curr_n)
                    END;
                (*ENDIF*) 
                IF  colin2.sci_typ in [ dcha, dunknown ]
                THEN (* string column, string constant or null *)
                    WITH a_ap_tree^[ curr_n ] DO
                        IF  n_symb = s_string_literal
                        THEN
                            BEGIN
                            (* observe the given format string. *)
                            WITH a_mblock, mb_qual^ DO
                                g04value_locate (mb_st^[ mfirst_free-1 ],
                                      acv.a_mblock, value, vallen);
                            (*ENDWITH*) 
                            max_length := k79n_dest_len_ora_number_format (
                                  value^, 2, vallen-1)
                            END
                        ELSE (* reasonable maximum. *)
                            max_length := cgg04_oradate_max_to_char
                        (*ENDIF*) 
                    (*ENDWITH*) 
                ELSE
                    a07_b_put_error (acv, e_incompatible_datatypes,
                          a_ap_tree^[ curr_n ].n_pos)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END
        ELSE
            BEGIN (* TO_CHAR (<timestamp>, ...) *)
            IF  colin.sci_typ <> dtimestamp
            THEN
                a641check_datetime(acv, dmli, dtimestamp);
            (*ENDIF*) 
            IF  n_symb = s_to_24_char
            THEN (* it's the simple format YYYYMMDDHH24MISS. *)
                BEGIN
                max_length := cgg04_oradate_len_to_char;
                a641string_set_operator (acv, op_b_to_24_char,
                      max_length, colin.sci_len, chr(0), chr(0))
                END
            ELSE
                IF  curr_n = 0
                THEN
                    BEGIN
                    to_char_variant := 1;
                    max_length      := 9
                    END
                ELSE
                    BEGIN
                    to_char_variant := 0;
                    IF  g01unicode
                    THEN
                        d_datatype := dcha
                    ELSE
                        d_datatype := dunknown;
                    (*ENDIF*) 
                    a640not_first_factor (acv, dmli, colin2, curr_n);
                    IF  (a_returncode = cak_e_parameter)
                    THEN
                        BEGIN
                        a_returncode := 0;
                        d_datatype  := dnonumber;
                        a640not_first_factor (acv, dmli, colin2, curr_n)
                        END;
                    (*ENDIF*) 
                    IF  colin2.sci_typ in [ dcha, dunknown ]
                    THEN (* string column, string constant or null *)
                        WITH a_ap_tree^[ curr_n ] DO
                            IF  n_symb = s_string_literal
                            THEN
                                BEGIN
                                (* observe the given format string. *)
                                WITH a_mblock, mb_qual^ DO
                                    g04value_locate (mb_st^[ mfirst_free-1 ],
                                          acv.a_mblock, value, vallen);
                                (*ENDWITH*) 
                                max_length := s78t_dest_len_date_format (
                                      value^, 2, vallen-1)
                                END
                            ELSE (* reasonable maximum. *)
                                max_length := cgg04_oradate_max_to_char
                            (*ENDIF*) 
                        (*ENDWITH*) 
                    ELSE
                        a07_b_put_error (acv, e_incompatible_datatypes,
                              a_ap_tree^[ curr_n ].n_pos)
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  (a_returncode = 0) AND (n_symb <> s_to_24_char)
    THEN (* for the simple format we did this already. *)
        BEGIN
        IF  to_char_variant = 1 (* Default char conversion. *)
        THEN
            BEGIN (* Push a_nls_params.date_format onto stack. *)
            a641f_push_format (acv, dmli);
            max_length      := mxsp_exttimestamp;
            to_char_variant := 0
            END;
        (*ENDIF*) 
        IF  to_char_variant <= 1
        THEN
            a641l_push_language (acv, dmli); (* put a_ak_language on the stack. *)
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            WITH colin DO
                BEGIN
                a641string_set_operator (acv, op_b_to_char,
                      max_length+1, to_char_variant,
                      chr(sci_frac), chr(sci_len));
                (* PTS 1117130 E.Z. *)
                IF  to_char_variant = 3
                THEN
                    a641string_set_operator (acv, op_b_trim,
                          ord (a_sqlmode), (*  elen_var       *)
                          0,               (*  epos           *)
                          chr (1),         (*  ecol_tab[ 1 ]  *)
                          chr (sci_len));  (*  ecol_tab[ 2 ]  *)
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        WITH colin DO
            BEGIN
            sci_frac  := 0;
            sci_len   := max_length;
            sci_iolen := sci_len + 1;
            sci_typ   := dcha
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    d_datatype := dcha;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641toidentifier (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dunknown;
    colin.sci_len := 0;
    curr_n        := n_lo_level;
    a640factor( acv, dmli, colin, curr_n );
    IF  a_returncode = cak_e_parameter
    THEN
        BEGIN
        a_returncode := 0;
        d_datatype := dcha;
        d_expand    := cak_maxfieldlength DIV 2 - 2;
        a640factor (acv, dmli, colin, curr_n);
        END;
    (*ENDIF*) 
    d_expand := 0;
    IF  a_returncode = 0
    THEN
        BEGIN
        (* PTS 1000311 E.Z. *)
        (* 2* because identifier may consist of '"' *)
        IF  colin.sci_typ = dunicode
        THEN
            colin.sci_len := (2 * colin.sci_len + 2) * 2
        ELSE
            colin.sci_len :=  2 * colin.sci_len + 2;
        (*ENDIF*) 
        colin.sci_frac  := 0;
        colin.sci_iolen := colin.sci_len + 1;
        IF  colin.sci_iolen > cak_maxdeffieldlength
        THEN
            a07_b_put_error (acv, e_one_output_field_too_long,
                  a_ap_tree^[ act_node ].n_pos);
        (*ENDIF*) 
        WITH a_mblock, mb_qual^ DO
            IF  mfirst_free >= mb_st_max
            THEN
                a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
            ELSE
                WITH mb_st^ [mfirst_free] DO
                    BEGIN
                    etype         := st_build_in_func;
                    eop_build_in  := op_b_toidentifier;
                    elen_var      := 0;
                    epos          := 0;
                    ecol_tab[ 1 ] := chr(a_sqlmode);
                    ecol_tab[ 2 ] := chr(0);
                    mfirst_free   := succ(mfirst_free);
                    mqual_cnt     := succ(mqual_cnt)
                    END
                (*ENDWITH*) 
            (*ENDIF*) 
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641l_push_language (
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info);
 
VAR
      curr_data_pos : tsp00_Int4;
 
BEGIN (* put a_ak_language (or nls_date_language) onto the stack. *)
WITH acv, a_mblock, mb_data^, mb_qual^ DO
    IF  mfirst_free > mb_st_max
    THEN
        a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
    ELSE
        BEGIN
        curr_data_pos := mb_data_len + 1;
        WITH mb_st^[ mfirst_free ] DO
            BEGIN
            IF  dmli.d_view
            THEN
                etype     := st_language
            ELSE
                etype     := st_value;
            (*ENDIF*) 
            eop           := op_none;
            epos          := curr_data_pos;
            elen_var      := mxsp_c3+1;
            ecol_tab[ 1 ] := chr (0);
            ecol_tab[ 2 ] := chr (0)
            END;
        (*ENDWITH*) 
        IF  NOT dmli.d_view
        THEN
            BEGIN
            mbp_buf[ curr_data_pos ] := csp_ascii_blank;
            IF  a_sqlmode <> sqlm_oracle
            THEN
                SAPDB_PascalMove ('VAK641',   6,    
                      sizeof (a_ak_language), mb_data_size,
                      @a_ak_language, 1, @mbp_buf, curr_data_pos+1,
                      mxsp_c3, a_returncode)
            ELSE
                SAPDB_PascalMove ('VAK641',   7,    
                      sizeof (a_nls_params.date_language), mb_data_size,
                      @a_nls_params.date_language, 1,
                      @mbp_buf, curr_data_pos+1, mxsp_c3,
                      a_returncode)
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        mb_data_len := mb_data_len + mxsp_c3 + 1;
        mfirst_free := succ (mfirst_free);
        mqual_cnt   := succ (mqual_cnt)
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641s_push_string (
            VAR acv       : tak_all_command_glob;
            dtyp          : tsp00_DataType;
            tree_index    : integer;
            curr_data_len : tsp00_Int4);
 
VAR
      curr_data_pos : tsp00_Int4;
 
BEGIN
WITH acv, a_mblock, mb_data^, mb_qual^ DO
    BEGIN
    curr_data_pos := mb_data_len + 1;
    IF  mfirst_free > mb_st_max
    THEN
        a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
    ELSE
        IF  mb_data_size < curr_data_pos + 1 + curr_data_len
        THEN
            a07_b_put_error (acv, e_too_many_mb_data, -mb_data_size)
        ELSE
            BEGIN
            IF  dtyp = dunicode
            THEN
                mbp_buf[ curr_data_pos ] := csp_unicode_def_byte
            ELSE
                BEGIN
                mbp_buf[ curr_data_pos ] := csp_ascii_blank;
                IF  g01unicode
                THEN
                    curr_data_len := curr_data_len DIV 2
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            a05string_literal_get (acv, tree_index, dtyp,
                  mbp_buf, curr_data_pos + 1, curr_data_len);
            WITH mb_st^[ mfirst_free ] DO
                BEGIN
                etype         := st_value;
                eop           := op_none;
                epos          := curr_data_pos;
                elen_var      := curr_data_len + 1; (* incl. defined byte *)
                ecol_tab[ 1 ] := chr(0);
                ecol_tab[ 2 ] := chr(0);
                END;
            (*ENDWITH*) 
            mb_data_len := mb_data_len + 1 + curr_data_len;
            mfirst_free := succ (mfirst_free);
            mqual_cnt   := succ (mqual_cnt)
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641push_blank (
            VAR acv : tak_all_command_glob;
            dtyp  : tsp00_DataType );
 
VAR
      curr_data_pos : tsp00_Int4;
      curr_data_len : tsp00_Int4;
 
BEGIN
WITH acv, a_mblock, mb_data^, mb_qual^ DO
    BEGIN
    IF  dtyp = dunicode
    THEN
        curr_data_len := 3
    ELSE
        curr_data_len := 2;
    (*ENDIF*) 
    curr_data_pos := mb_data_len + 1;
    IF  mfirst_free > mb_st_max
    THEN
        a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
    ELSE
        IF  mb_data_size < curr_data_pos + curr_data_len
        THEN
            a07_b_put_error (acv, e_too_many_mb_data, -mb_data_size)
        ELSE
            BEGIN
            WITH mb_st^[ mfirst_free ] DO
                BEGIN
                etype         := st_value;
                eop           := op_none;
                epos          := curr_data_pos;
                elen_var      := curr_data_len;
                ecol_tab[ 1 ] := chr(0);
                ecol_tab[ 2 ] := chr(0);
                END;
            (*ENDWITH*) 
            IF  dtyp = dunicode
            THEN
                BEGIN
                mbp_buf [curr_data_pos]     := csp_unicode_def_byte;
                mbp_buf [curr_data_pos + 1] := csp_unicode_mark;
                mbp_buf [curr_data_pos + 2] := bsp_c1;
                END
            ELSE
                BEGIN
                mbp_buf [curr_data_pos]     := bsp_c1;
                mbp_buf [curr_data_pos + 1] := bsp_c1;
                END;
            (*ENDIF*) 
            mb_data_len := mb_data_len + curr_data_len;
            mfirst_free := succ (mfirst_free);
            mqual_cnt   := succ (mqual_cnt)
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641f_push_format (
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info);
 
VAR
      curr_data_pos : tsp00_Int4;
      curr_data_len : tsp00_Int4;
 
BEGIN (* now we put a_nls_params.date_format onto the stack. *)
WITH acv, a_mblock, mb_data^, mb_qual^ DO
    BEGIN
    curr_data_pos := mb_data_len + 1;
    IF  dmli.d_view
    THEN
        curr_data_len := mxsp_exttimestamp+1
    ELSE
        curr_data_len := a_nls_params.df_length;
    (*ENDIF*) 
    IF  mfirst_free > mb_st_max
    THEN
        a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
    ELSE
        IF  mb_data_size < curr_data_pos + curr_data_len
        THEN
            a07_b_put_error (acv, e_too_many_mb_data, -mb_data_size)
        ELSE
            BEGIN
            WITH mb_st^[ mfirst_free ] DO
                BEGIN
                IF  dmli.d_view
                THEN
                    etype     := st_format
                ELSE
                    etype     := st_value;
                (*ENDIF*) 
                eop           := op_none;
                epos          := curr_data_pos;
                elen_var      := curr_data_len;
                ecol_tab[ 1 ] := chr(0);
                ecol_tab[ 2 ] := chr(0);
                END;
            (*ENDWITH*) 
            IF  NOT dmli.d_view
            THEN
                BEGIN
                SAPDB_PascalMove ('VAK641',   8,    
                      sizeof (a_nls_params.date_format), mb_data_size,
                      @a_nls_params.date_format, 1, @mbp_buf, curr_data_pos,
                      acv.a_nls_params.df_length,
                      a_returncode);
                END;
            (*ENDIF*) 
            mb_data_len := mb_data_len + curr_data_len;
            mfirst_free := succ (mfirst_free);
            mqual_cnt   := succ (mqual_cnt)
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641d_push_date (
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info);
 
VAR
      put_node      : tsp00_Int2;
      date_n        : integer;
      colin         : tak00_scolinf;
      keep_datatype : tsp00_DataType;
      keep_change   : boolean;
      msglist       : tak104_MsgList;
 
BEGIN (* now we put the current date on the stack.             *)
(* after a lot of different tries we considerd it as most easy *)
(* to tie a dummy node and let a640factor do all the work.     *)
WITH acv, dmli DO
    BEGIN
    a_scv.sc_symb      := s_date;
    a01_put_node (acv, put_node);
    IF  a_variable_input                AND
        (a_init_ddl = no_ddl)           AND
        (a_count_literals = 1)          AND
        NOT (a_mblock.mb_type in [ m_nil, m_fetch, m_get, m_insert_select ])
        (* m_get : i.e. vak56, foreign key *)
    THEN
        BEGIN
        msglist := NIL;
        IF  NOT ak104_CreateIncrementalMemorySequence ( a_transinf.tri_trans.trAllocator_gg00,
            sessionCount_eak104, a_mblock.mb_fieldlists[cgg_idx_literal_valuefieldlist], msglist)
        THEN
            a07_b_put_error (acv, e_no_more_memory, 1);
&       ifdef TRACE
        (*ENDIF*) 
        t01addr (ak_sem, 'newfieldlist',
              a_mblock.mb_fieldlists[cgg_idx_literal_valuefieldlist]);
&       endif
        END;
    (*ENDIF*) 
    keep_change        := d_change_date_time;
    keep_datatype      := d_datatype;
    d_change_date_time := false;
    d_datatype         := ddate;
    date_n             := put_node;
    colin.sci_len      := 0;
    a640factor (acv, dmli, colin, date_n);
    d_datatype         := keep_datatype;
    d_change_date_time := keep_change;
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641time_date_to_char_datatype
            (VAR erg_datatype  : tsp00_DataType;
            VAR keep_datatype : tsp00_DataType);
 
BEGIN
IF  keep_datatype in
    [ ddate, dtime, dtimestamp ]
THEN
    erg_datatype := dcha
ELSE
    erg_datatype := keep_datatype;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641s_literal_value (
            VAR acv           : tak_all_command_glob;
            act_node           : integer;
            keep_datatype      : tsp00_DataType;
            string_allowed     : boolean;
            VAR string_found   : boolean;
            VAR letter         : char;
            VAR wrong_datatype : boolean);
 
VAR
      invalid     : boolean;
      bytestr_len : integer;
      c2          : tsp00_C2;
      uni_len     : tsp00_Int4;
      err_char_no : tsp00_Int4;
      uni_err     : tsp8_uni_error;
 
BEGIN
string_found := false;
WITH acv, a_ap_tree^[ act_node ] DO
    IF  ((n_symb = s_string_literal) AND
        (keep_datatype <> dchb))
    THEN
        BEGIN
        IF  n_length = 0
        THEN
            a07_b_put_error (acv,
                  e_missing_string_literal, n_pos)
        ELSE
            IF  g01unicode
            THEN
                IF  (a_cmd_part^.sp1p_buf[ n_pos ] = csp_unicode_mark)
                    AND (n_length = 2)
                THEN
                    letter := a_cmd_part^.sp1p_buf[ n_pos+1 ]
                ELSE
                    IF  string_allowed AND (n_length >= 2)
                    THEN
                        BEGIN
                        ak641s_push_string (acv,
                              keep_datatype, act_node, n_length);
                        letter       := csp_defined_byte;
                        string_found := true
                        END
                    ELSE
                        wrong_datatype := true
                    (*ENDIF*) 
                (*ENDIF*) 
            ELSE (* no unicode *)
                IF  n_length = 1
                THEN
                    letter := a_cmd_part^.sp1p_buf[ n_pos ]
                ELSE
                    IF  string_allowed AND (n_length > 1)
                    THEN
                        BEGIN
                        ak641s_push_string (acv,
                              keep_datatype, act_node, n_length);
                        letter       := csp_defined_byte;
                        string_found := true
                        END
                    ELSE
                        wrong_datatype := true
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        END
    ELSE
        IF  (n_symb = s_null)
        THEN
            a07_b_put_error (acv,
                  e_const_incompatible_with_typ, n_pos)
        ELSE
            IF  n_symb = s_byte_string
            THEN
                BEGIN
                invalid := false;
                IF  (n_length = 4) AND
                    g01unicode
                THEN
                    BEGIN
                    uni_len := 2;
                    s80uni_trans (@(a_cmd_part^.sp1p_buf[n_pos]), n_length, csp_unicode,
                          @c2, uni_len, csp_ascii, [ ], uni_err,
                          err_char_no);
                    IF  uni_err = uni_ok
                    THEN
                        s41p1byte (letter, 1, bytestr_len, c2, 1,
                              uni_len, invalid)
                    ELSE
                        a07_hex_uni_error (acv, uni_err,
                              n_pos - 1 + err_char_no, NOT c_trans_to_uni,
                              @(a_cmd_part^.sp1p_buf[n_pos+err_char_no-1]),
                              c_unicode_wid);
                    (*ENDIF*) 
                    END
                ELSE
                    IF  (n_length = 2) AND
                        NOT g01unicode
                    THEN
                        s41pbyte (letter, 1, bytestr_len,
                              a_cmd_part^.sp1p_buf, n_pos, n_length, invalid)
                    ELSE
                        invalid := true;
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  invalid
                THEN
                    a07_b_put_error (acv,
                          e_const_incompatible_with_typ, n_pos)
                (*ENDIF*) 
                END
            ELSE
                wrong_datatype := true;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641u_literal_value (
            VAR acv            : tak_all_command_glob;
            act_node           : integer;
            VAR c2             : tsp00_C2;
            VAR wrong_datatype : boolean);
 
BEGIN
WITH acv, a_ap_tree^[ act_node ] DO
    IF  ((n_symb = s_string_literal) AND
        (n_length = 2))
    THEN
        BEGIN
        c2[ 1 ] := a_cmd_part^.sp1p_buf[ n_pos   ];
        c2[ 2 ] := a_cmd_part^.sp1p_buf[ n_pos+1 ]
        END
    ELSE
        IF  (n_symb = s_null)
        THEN
            a07_b_put_error (acv,
                  e_const_incompatible_with_typ, n_pos)
        ELSE
            wrong_datatype := true;
        (*ENDIF*) 
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641lrpad (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      char_field_found : boolean;
      c                : char;
      c2               : tsp00_C2;
      keep_datatype    : tsp00_DataType;
      curr_n           : integer;
      old_n            : integer;
      max_length       : integer;
      l                : tsp00_Int2;
      colin1           : tak00_scolinf;
      string_pushed    : boolean;
      operator         : tgg00_StackOpBuildIn;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    string_pushed := false;
    d_ch_datatype := dunknown;
    IF  d_datatype = dunknown
    THEN
        d_datatype := dnonumber;
    (*ENDIF*) 
    curr_n           := n_lo_level;
    colin.sci_len    := 0;
    char_field_found :=  a_ap_tree^[ curr_n ].n_symb IN
          [ s_authid, s_tablename, s_columnname, s_columnid, s_null ];
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  d_datatype = dnonumber
        THEN
            d_datatype := dcha;
        (*ENDIF*) 
        keep_datatype := d_datatype;
        IF  (NOT (d_datatype in [ dcha, dchb, dunicode ])) OR
            (d_ch_datatype <> dunknown)
        THEN
            char_field_found := false;
        (*ENDIF*) 
        curr_n := a_ap_tree^[ curr_n ].n_sa_level;
        IF  n_symb in [ s_lpad, s_rpad ]
        THEN
            BEGIN
            (* is not the ORACLE lpad/rpad *)
            d_datatype     := dnumber;
            colin1.sci_len := 0;
            a640not_first_factor (acv, dmli, colin1, curr_n);
            curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
            END;
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            BEGIN
            WITH a_ap_tree^[ curr_n ] DO
                IF  (n_sa_level = 0) AND
                    (a_sqlmode = sqlm_oracle)
                THEN
                    IF  (n_symb = s_null)
                    THEN
                        a07_b_put_error (acv,
                              e_const_incompatible_with_typ, n_pos)
                    ELSE
                        (*   n_symb = s_unsigned_integer   *)
                        CASE keep_datatype OF
                            ddate, dtime, dtimestamp,
                            dcha:
                                c := bsp_c1;
                            dchb:
                                c := csp_defined_byte;
                            dunicode :
                                BEGIN
                                c       := csp_undef_byte;
                                c2[ 1 ] := csp_unicode_mark;
                                c2[ 2 ] := bsp_c1
                                END;
                            OTHERWISE
                                BEGIN
                                END;
                            END
                        (*ENDCASE*) 
                    (*ENDIF*) 
                ELSE
                    BEGIN
                    a641s_literal_value (acv, curr_n, keep_datatype,
                          c_string_allowed, string_pushed,
                          c, wrong_datatype);
                    IF  (NOT wrong_datatype) AND
                        (keep_datatype = dunicode)
                    THEN
                        BEGIN
                        c2    := csp_unicode_blank;
                        c2[2] := c
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDWITH*) 
            IF  NOT wrong_datatype
            THEN
                BEGIN
                WITH a_ap_tree^[ curr_n ] DO
                    IF  (NOT (n_symb IN [ s_unsigned_integer, s_null ])) OR
                        (a_sqlmode <> sqlm_oracle)
                    THEN
                        BEGIN
                        old_n  := curr_n;
                        curr_n := n_sa_level;
                        END;
                    (*ENDIF*) 
                (*ENDWITH*) 
                IF  curr_n <> 0
                THEN
                    WITH a_ap_tree^[ curr_n ] DO
                        BEGIN
                        IF  (n_symb <> s_null)
                        THEN
                            a05_unsigned_int2_get (acv,
                                  n_pos, n_length, e_invalid_datalength, l)
                        ELSE
                            BEGIN
                            l := 2;
                            c := csp_undef_byte;
                            c2[ 1 ] := csp_undef_byte;
                            c2[ 2 ] := csp_undef_byte;
                            END;
                        (*ENDIF*) 
                        CASE a_sqlmode OF
                            sqlm_db2 :
                                max_length := cak_maxdb2fieldlength;
                            sqlm_oracle :
                                max_length := cak_maxorafieldlength;
                            sqlm_internal :
                                max_length := cak_maxdeffieldlength;
                            OTHERWISE
                                max_length := cak_maxfieldlength;
                            END;
                        (*ENDCASE*) 
                        IF  ((l < 1) OR (l > max_length))
                            OR
                            ((keep_datatype = dunicode) AND (l*2 > max_length))
                        THEN
                            a07_b_put_error (acv,
                                  e_invalid_datalength, n_pos)
                        (*ENDIF*) 
                        END
                    (*ENDWITH*) 
                ELSE
                    IF  char_field_found
                    THEN
                        l := colin.sci_len
                    ELSE
                        BEGIN
                        l := 1;
&                       ifdef TRACE
                        t01int4 (ak_sem, 'char_field**', l);
&                       endif
                        a07_b_put_error (acv,
                              e_invalid_unsign_integer,
                              a_ap_tree^[ old_n ].n_pos+
                              a_ap_tree^[ old_n ].n_length);
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                ak641time_date_to_char_datatype (d_datatype,
                      keep_datatype);
                WITH colin DO
                    BEGIN
                    sci_typ   := d_datatype;
                    sci_frac  := 0;
                    sci_len   := l;
                    IF  d_datatype = dunicode
                    THEN
                        sci_iolen := succ(2*sci_len)
                    ELSE
                        sci_iolen := succ (sci_len);
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
                IF  a_returncode = 0
                THEN
                    IF  d_datatype = dunicode
                    THEN
                        BEGIN
                        CASE n_symb OF
                            s_lpad :
                                operator := op_b_dbyte_lpad;
                            s_rpad :
                                operator := op_b_dbyte_rpad;
                            s_lfill :
                                operator := op_b_dbyte_lfill;
                            s_rfill :
                                operator := op_b_dbyte_rfill;
                            END;
                        (*ENDCASE*) 
                        ak641dbyte_string_set_operator (acv,
                              operator, colin.sci_iolen,
                              ord (string_pushed), c2)
                        END
                    ELSE
                        BEGIN
                        CASE n_symb OF
                            s_lpad :
                                operator := op_b_lpad;
                            s_rpad :
                                operator := op_b_rpad;
                            s_lfill :
                                operator := op_b_lfill;
                            s_rfill :
                                operator := op_b_rfill;
                            END;
                        (*ENDCASE*) 
                        a641string_set_operator (acv,
                              operator, colin.sci_iolen,
                              ord (string_pushed), c, chr(0))
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641to_date (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      keep_datatype   : tsp00_DataType;
      curr_n          : integer;
      to_date_variant : integer;
      colin2          : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    keep_datatype    := d_datatype;
    d_datatype       := dunknown;
    curr_n           := n_lo_level;
&   ifdef trace
    t01int4 (ak_sem, 'act_node    ', act_node);
    t01int4 (ak_sem, 'curr_n      ', curr_n);
&   endif
    colin.sci_len    := 0;
    a640factor (acv, dmli, colin, curr_n);
&   ifdef trace
    t01name (ak_sem, 'to_date 1         ');
    t01int4 (ak_sem, 'curr_n      ', curr_n);
&   endif
    IF  (a_returncode = cak_e_parameter)
    THEN
        BEGIN
        a_returncode := 0;
        d_datatype  := dnonumber;
        a640factor (acv, dmli, colin, curr_n)
        END;
&   ifdef trace
    (*ENDIF*) 
    t01int4 (ak_sem, 'colin.scityp', ord (colin.sci_typ));
    t01int4 (ak_sem, 'd_datatype  ', ord (d_datatype));
&   endif
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  colin.sci_typ in [ dfixed, dfloat, dvfloat, dnumber ]
        THEN (* call of TO_DATE with number, which must be converted. *)
            a641stack_for_op_b_chr (acv, dmli, colin, 0, dcha);
        (*ENDIF*) 
        IF  colin.sci_typ = dunicode
        THEN
            BEGIN
            a641string_set_operator (acv,
                  op_b_uni_trans, colin.sci_len+1, 0,
                  chr(csp_unicode), chr(csp_ascii));
            colin.sci_typ   := dcha;
            colin.sci_iolen := colin.sci_len + 1;
            END;
        (*ENDIF*) 
        curr_n := a_ap_tree^[ curr_n ].n_sa_level;
&       ifdef trace
        t01int4 (ak_sem, 'curr_n      ', curr_n);
&       endif
        IF  curr_n <> 0
        THEN
            BEGIN
            to_date_variant := 0;
            IF  g01unicode
            THEN
                d_datatype := dcha
            ELSE
                d_datatype := dunknown;
            (*ENDIF*) 
            colin2.sci_len := 0;
            a640not_first_factor (acv, dmli, colin2, curr_n);
            IF  (a_returncode = cak_e_parameter)
            THEN
                BEGIN
                a_returncode := 0;
                d_datatype  := dnonumber;
                a640not_first_factor (acv, dmli, colin2, curr_n)
                END;
            (*ENDIF*) 
            IF  NOT (colin.sci_typ in [ dcha, dunknown ])
            THEN (* string column, string constant or null *)
                a07_b_put_error (acv, e_incompatible_datatypes,
                      a_ap_tree^[ curr_n ].n_pos)
            (*ENDIF*) 
            END
        ELSE
            to_date_variant := 1;
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            BEGIN
            IF  to_date_variant = 1
            THEN (* Push a_nls_params.date_format onto stack. *)
                BEGIN
                a641f_push_format (acv, dmli);
                to_date_variant := 0
                END;
            (*ENDIF*) 
            ak641d_push_date     (acv, dmli); (* Push current date and   *)
            a641l_push_language (acv, dmli); (* a_ak_language on stack. *)
            WITH colin DO
                BEGIN
                a641string_set_operator (acv, op_b_to_date,
                      mxsp_timestamp+1, to_date_variant, chr (0), chr(0));
                sci_frac  := 0;
                sci_len   := mxsp_timestamp;
                sci_iolen := sci_len + 1;
                sci_typ   := dtimestamp
                END
            (*ENDWITH*) 
            END;
        (*ENDIF*) 
        d_datatype := dtimestamp
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641replace_translate (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      second_param     : boolean;
      keep_datatype    : tsp00_DataType;
      curr_n           : integer;
      max_length       : integer;
      colin1           : tak00_scolinf;
      colin2           : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    keep_datatype := d_datatype;
    IF  ((d_datatype = ddate) OR
        (d_datatype = dtime) OR
        (d_datatype = dtimestamp))
    THEN
        d_datatype := dcha
    ELSE
        IF  d_datatype = dunknown
        THEN
            d_datatype := dnonumber;
        (*ENDIF*) 
    (*ENDIF*) 
    d_ch_datatype := dunknown;
    curr_n           := n_lo_level;
    colin.sci_len    := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        colin1.sci_len := 0;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  colin1.sci_len <= 0
        THEN
            a07_b_put_error (acv, e_missing_string_literal,
                  a_ap_tree^[ curr_n ].n_pos)
        ELSE
            BEGIN
            curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
            colin2.sci_len := 0;
            IF  (curr_n <> 0)
            THEN
                BEGIN
                a640not_first_factor (acv, dmli, colin2, curr_n);
                IF  (colin2.sci_len > colin1.sci_len) AND
                    (n_symb = s_replace)
                THEN
                    colin.sci_len := (colin.sci_len DIV colin1.sci_len)
                          * colin2.sci_len;
                (*ENDIF*) 
                second_param := true;
                CASE a_sqlmode OF
                    sqlm_db2 :
                        max_length := cak_maxdb2fieldlength;
                    sqlm_oracle :
                        max_length := cak_maxorafieldlength;
                    sqlm_internal :
                        max_length := cak_maxdeffieldlength;
                    OTHERWISE
                        max_length := cak_maxfieldlength;
                    END;
                (*ENDCASE*) 
                IF  colin.sci_typ = dunicode
                THEN
                    max_length := max_length DIV 2;
                (*ENDIF*) 
                IF  colin.sci_len > max_length
                THEN
                    colin.sci_len := max_length;
                (*ENDIF*) 
                END
            ELSE
                second_param := false;
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    colin.sci_frac  := 0;
    colin.sci_typ   := d_datatype;
    IF  colin.sci_typ = dunicode
    THEN
        BEGIN
        colin.sci_iolen := (2 * colin.sci_len) + 1;
        IF  a_returncode = 0
        THEN
            IF  n_symb = s_replace
            THEN
                BEGIN
                IF  second_param
                THEN
                    a65_set_operator (acv, op_dbyte_replace)
                ELSE
                    a65_set_operator (acv, op_dbyte_remove);
                (*ENDIF*) 
                END
            ELSE
                a65_set_operator (acv, op_dbyte_translate);
            (*ENDIF*) 
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        colin.sci_iolen := colin.sci_len+1;
        IF  a_returncode = 0
        THEN
            IF  n_symb = s_replace
            THEN
                BEGIN
                IF  second_param
                THEN
                    a65_set_operator (acv, op_replace)
                ELSE
                    a65_set_operator (acv, op_remove);
                (*ENDIF*) 
                END
            ELSE
                a65_set_operator (acv, op_translate);
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641trim (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      colin1           : tak00_scolinf;
      curr_n           : integer;
      para_count       : integer;
      build_in_func    : tgg00_StackOpBuildIn;
      res_len          : tsp00_Int2;
      old_sci_len      : tsp00_Int2;
      keep_datatype    : tsp00_DataType;
 
BEGIN
(* zur Zeit werden noch Parameter vom Typ dchb abgewiesen *)
WITH acv, a_ap_tree^[ act_node ], dmli, colin DO
    BEGIN
    para_count := 1;
    keep_datatype := d_datatype;
    d_datatype := dunknown;
    curr_n     := n_lo_level;
    sci_len    := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  (a_returncode = cak_e_parameter)
    THEN
        BEGIN
        a_returncode := 0;
        (* PTS 1118316 E.Z. *)
        IF  keep_datatype <> dunknown
        THEN
            d_datatype := keep_datatype
        ELSE
            d_datatype  := dnonumber;
        (*ENDIF*) 
        a640factor (acv, dmli, colin, curr_n)
        END;
    (*ENDIF*) 
    IF  (a_returncode = 0)
    THEN
        IF  (d_datatype = dchb)
        THEN
            wrong_datatype := true
        ELSE
            BEGIN
            curr_n := a_ap_tree^[ curr_n ].n_sa_level;
            IF  (curr_n <> 0)
            THEN
                BEGIN
                colin1.sci_len := 0;
                IF  d_datatype <> dunicode
                THEN
                    d_datatype := dcha;
                (*ENDIF*) 
                a640not_first_factor (acv, dmli, colin1, curr_n);
                IF  (a_returncode = 0)
                THEN
                    IF  ((colin.sci_typ <> dunicode) AND
                        (colin1.sci_typ = dcha))
                        OR
                        ((colin.sci_typ = dunicode) AND
                        (colin1.sci_typ = dunicode))
                    THEN
                        para_count := 2
                    ELSE
                        wrong_datatype := true;
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  ((a_returncode = 0) AND NOT wrong_datatype)
            THEN
                BEGIN
                IF  sci_typ in [ dfixed, dfloat, dvfloat, dnumber ]
                THEN
                    old_sci_len := sci_len
                ELSE
                    (* otherwise may be longer than 255 *)
                    (* ==> chr(old_sci_len) results in funny values *)
                    old_sci_len := 0;
                (*ENDIF*) 
                IF  (colin.sci_typ IN [ dcha, dunicode ])
                THEN
                    d_datatype := sci_typ
                ELSE
                    d_datatype := dcha;
                (*ENDIF*) 
                a641_get_length (colin, res_len, wrong_datatype);
                IF  NOT wrong_datatype
                THEN
                    BEGIN
                    sci_typ   := d_datatype;
                    sci_len   := res_len;
                    IF  d_datatype = dunicode
                    THEN
                        BEGIN
                        sci_iolen := 2 * sci_len + 1;
                        CASE n_symb OF
                            s_trim :
                                build_in_func := op_b_dbyte_trim;
                            s_ltrim :
                                build_in_func := op_b_dbyte_ltrim;
                            s_rtrim :
                                build_in_func := op_b_dbyte_rtrim;
                            END;
                        (*ENDCASE*) 
                        END
                    ELSE
                        BEGIN
                        sci_iolen := 1 + sci_len;
                        CASE n_symb OF
                            s_trim :
                                build_in_func := op_b_trim;
                            s_ltrim :
                                build_in_func := op_b_ltrim;
                            s_rtrim :
                                build_in_func := op_b_rtrim;
                            END;
                        (*ENDCASE*) 
                        END;
                    (*ENDIF*) 
                    a641string_set_operator (acv, build_in_func,
                          ord (a_sqlmode),    (*  elen_var       *)
                          sci_frac,           (*  epos           *)
                          chr (para_count),   (*  ecol_tab[ 1 ]  *)
                          chr (old_sci_len)); (*  ecol_tab[ 2 ]  *)
                    sci_frac  := 0;  (* h.b. 1995-05-10 *)
                    END;
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641makedate (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
      colin1 : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dnumber;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor ( acv, dmli, colin, curr_n );
    IF  a_returncode = 0
    THEN
        BEGIN
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        colin1.sci_len := 0;
        a640not_first_factor( acv, dmli, colin1, curr_n);
        IF  a_returncode = 0
        THEN
            BEGIN
            d_datatype := ddate;
            WITH colin DO
                BEGIN
                sci_len   := mxsp_date;
                sci_iolen := sci_len + 1;
                sci_frac  := 0;
                sci_typ   := ddate
                END;
            (*ENDWITH*) 
            a65_set_operator ( acv, op_makedate)
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641maketime (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
      colin1 : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dnumber;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        colin1.sci_len := 0;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  a_returncode = 0
        THEN
            BEGIN
            curr_n := a_ap_tree^[ curr_n ].n_sa_level;
            colin1.sci_len := 0;
            a640not_first_factor (acv, dmli, colin1, curr_n);
            IF  a_returncode = 0
            THEN
                BEGIN
                d_datatype := dtime;
                WITH colin DO
                    BEGIN
                    sci_len   := mxsp_time;
                    sci_iolen := sci_len+1;
                    sci_frac  := 0;
                    sci_typ   := dtime
                    END;
                (*ENDWITH*) 
                a65_set_operator (acv, op_maketime)
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641months_between (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer);
 
VAR
      curr_n    : integer;
      colin1    : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype     := dtimestamp;
    curr_n         := n_lo_level;
    colin.sci_len  := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  colin.sci_typ <> dtimestamp
        THEN
            a641check_datetime(acv, dmli, dtimestamp);
        (*ENDIF*) 
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        colin1.sci_len := 0;
        d_datatype     := dtimestamp;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  a_returncode = 0
        THEN
            BEGIN
            IF  colin.sci_typ <> dtimestamp
            THEN
                a641check_datetime(acv, dmli, dtimestamp);
            (*ENDIF*) 
            d_datatype := dnumber;
            WITH colin DO
                BEGIN
                sci_len   := csp_fixed;
                sci_frac  := csp_float_frac;
                sci_typ   := dfloat;
                sci_iolen := (sci_len + 1) DIV 2 + 2;
                END;
            (*ENDWITH*) 
            a65_set_operator (acv, op_months_between)
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641noround (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype         := dnumber;
    d_const_value_expr := false;
    colin.sci_len      := 0;
    curr_n             := n_lo_level;
    a640factor( acv, dmli, colin, curr_n );
    IF  a_returncode = 0
    THEN
        WITH a_mblock, mb_qual^ DO
            IF  mfirst_free > mb_st_max
            THEN
                a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
            ELSE
                WITH mb_st^ [mfirst_free] DO
                    BEGIN
                    etype    := st_noround;
                    eop      := op_none;
                    epos     := colin.sci_len;
                    elen_var := colin.sci_frac;
                    ecol_tab[ 1 ] := chr(0);
                    ecol_tab[ 2 ] := chr(0);
                    mfirst_free := succ(mfirst_free);
                    mqual_cnt := succ(mqual_cnt)
                    END
                (*ENDWITH*) 
            (*ENDIF*) 
        (*ENDWITH*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641num (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n     : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype    := dunknown;
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = cak_e_parameter
    THEN
        BEGIN
        (* 'a_returncode' ='par_error' is true, if a      *)
        (* parameter is there and is tried to analyse    *)
        (* with datatype 'dunknown'. In this case the  *)
        (* datatype is set to 'dnonumber' and a new    *)
        (* parse is done. Now the datatype is set        *)
        (* to the code_type of the machine               *)
        a_returncode := 0;
        d_datatype := dnonumber;
        a640factor (acv, dmli, colin, curr_n)
        END;
    (*ENDIF*) 
    IF  (a_returncode = 0)
    THEN
        IF  ((n_symb = s_to_number) AND
            (d_datatype <> dcha) AND
            (d_datatype <> dunicode))
        THEN
            wrong_datatype := true
        ELSE
            IF  (n_symb = s_num) AND
                (d_datatype = dchb)
            THEN
                WITH colin DO
                    BEGIN
                    a641string_set_operator
                          (acv, op_b_ascii_ora, 0, 0, chr(0), chr(0));
                    WITH a_mblock, mb_qual^ DO
                        mb_st^ [mfirst_free - 1].edatatype := sci_typ;
                    (*ENDWITH*) 
                    sci_len    := 5;
                    sci_frac   := 0;
                    sci_iolen  := 5;
                    sci_typ    := dfixed;
                    sci_cprops := [ ctopt ];
                    d_datatype := dnumber
                    END
                (*ENDWITH*) 
            ELSE
                IF  d_datatype = dnumber
                THEN
                    d_const_value_expr := false
                ELSE
                    BEGIN
                    (* In case of a conversion from string to num- *)
                    (* ber the procedure in KB expects that the    *)
                    (* stringnotation is the same as the default   *)
                    (* code of the underlying machine. To make     *)
                    (* this sure the codetype and the datatype are *)
                    (* compared and in case of differences a con-  *)
                    (* version takes place                         *)
                    IF  d_datatype = dunicode
                    THEN
                        a641string_set_operator (acv,
                              op_b_uni_trans, colin.sci_len+1, 0,
                              chr(csp_unicode), chr(csp_ascii));
                    (*ENDIF*) 
                    d_datatype := dnumber;
                    a65_set_operator (acv, op_num);
                    WITH colin DO
                        BEGIN
                        sci_len   := csp_fixed;
                        sci_frac  := csp_float_frac;
                        sci_iolen := (sci_len+1) DIV 2 + 2;
                        sci_typ   := dvfloat
                        END
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641name (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer);
 
CONST
      max_length = 12;
 
VAR
      curr_n        : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    curr_n := n_lo_level;
    ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, ddate, ddate);
    IF  a_returncode =
        a071_return_code (e_incompatible_datatypes, a_sqlmode)
    THEN
        BEGIN
        a_returncode := 0;
        ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, dtimestamp, dtimestamp);
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        a641l_push_language (acv, dmli);
        IF  a_returncode = 0
        THEN
            WITH colin DO
                BEGIN
                sci_frac   := 0;
                sci_len    := max_length;
                sci_iolen  := sci_len + 1;
                sci_typ    := dcha;
                d_datatype := dcha;
                IF  n_symb = s_monthname
                THEN
                    a641string_set_operator (acv, op_b_namefromdate,
                          sci_iolen, 0, chr(0), chr(0))
                ELSE
                    a641string_set_operator (acv, op_b_namefromdate,
                          sci_iolen, 0, chr(1), chr(0));
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641of (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    curr_n := n_lo_level;
    ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, ddate, ddate);
    IF  a_returncode =
        a071_return_code (e_incompatible_datatypes, a_sqlmode)
    THEN
        BEGIN
        a_returncode := 0;
        ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, dtimestamp, dtimestamp);
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        d_datatype := dnumber;
        WITH colin DO
            BEGIN
            CASE n_symb OF
                s_dayofweek :
                    BEGIN
                    (* Result <= 7, so Length = 1 *)
                    sci_len := 1;
                    a65_set_operator (acv, op_dayofweek)
                    END;
                s_weekofyear :
                    BEGIN
                    (* Result <= 52, so Length = 2 *)
                    sci_len := 2;
                    a65_set_operator (acv, op_weekofyear)
                    END;
                s_dayofyear :
                    BEGIN
                    (* Result <= 365, so Length = 3 *)
                    sci_len := 3;
                    a65_set_operator (acv, op_dayofyear)
                    END;
                s_dayofmonth :
                    BEGIN
                    (* Result <= 31, so Length = 2 *)
                    sci_len := 2;
                    a641string_set_operator (acv, op_b_dayofmonth,
                          0, 0, chr (0), chr (0));
                    END;
                END;
            (*ENDCASE*) 
            sci_iolen := (sci_len+1) DIV 2 + 2;
            sci_frac  := 0;
            sci_typ   := dfixed
            END;
        (*ENDWITH*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641put_maxlength (
            VAR acv        : tak_all_command_glob;
            VAR curr_n     : integer;
            symb           : tak_sc_symbol;
            VAR first_int  : tsp00_Int2;
            VAR second_int : tsp00_Int2);
 
VAR
      undef : boolean;
 
BEGIN
undef := false;
WITH acv DO
    BEGIN
    IF  a_ap_tree^[ curr_n ].n_sa_level <> 0
    THEN
        BEGIN
        curr_n := a_ap_tree^[ curr_n ].n_sa_level;
        IF  (a_ap_tree^[ curr_n ].n_symb = s_unsigned_integer)
        THEN
            BEGIN
            a05_unsigned_int2_get (acv, a_ap_tree^[ curr_n ].n_pos,
                  a_ap_tree^[ curr_n ].n_length, e_invalid_datalength, first_int);
            IF  ((first_int < 1) OR (first_int > csp_fixed))
            THEN
                a07_b_put_error (acv, e_invalid_datalength,
                      a_ap_tree^[ curr_n ].n_pos)
            ELSE
                IF  a_ap_tree^[ curr_n ].n_sa_level <> 0
                THEN
                    BEGIN
                    curr_n := a_ap_tree^[ curr_n ].n_sa_level;
                    WITH a_ap_tree^[ curr_n ] DO
                        IF  n_symb = s_unsigned_integer
                        THEN
                            BEGIN
                            a05_unsigned_int2_get (acv, n_pos,
                                  n_length, e_invalid_datalength, second_int);
                            IF  ((second_int < 0) OR
                                (second_int > first_int))
                            THEN
                                a07_b_put_error (acv,
                                      e_invalid_datalength, n_pos)
                            (*ENDIF*) 
                            END
                        ELSE
                            IF  (n_symb = s_null)
                            THEN
                                undef := true
                            ELSE
                                second_int := 0
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDWITH*) 
                    END
                ELSE
                    second_int := 0
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE
            (*   a_ap_tree^[ curr_n ].n_symb = s_null   *)
            undef := true;
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        first_int  := csp_fixed;
        second_int := 0
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        WITH 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
                WITH mb_st^ [mfirst_free] DO
                    BEGIN
                    IF  symb = s_fixed
                    THEN
                        BEGIN
                        etype := st_op;
                        eop   := op_fixed
                        END
                    ELSE
                        BEGIN
                        etype        := st_build_in_func;
                        eop_build_in := op_b_float;
                        second_int := csp_float_frac
                        END;
                    (*ENDIF*) 
                    IF  undef
                    THEN
                        IF  symb = s_fixed
                        THEN
                            BEGIN
                            epos          := 0;
                            elen_var      := 0;
                            ecol_tab[ 1 ] := csp_undef_byte;
                            ecol_tab[ 2 ] := csp_undef_byte;
                            first_int     := csp_fixed;
                            second_int    := 0
                            END
                        ELSE
                            a07_b_put_error (acv,
                                  e_num_invalid, a_ap_tree^[ curr_n ].n_pos)
                        (*ENDIF*) 
                    ELSE
                        BEGIN
                        epos          := first_int;
                        elen_var      := second_int;
                        ecol_tab[ 1 ] := chr(0);
                        ecol_tab[ 2 ] := chr(0)
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
                mqual_cnt   := succ (mqual_cnt);
                mfirst_free := succ (mfirst_free);
                END;
            (*ENDIF*) 
            END
        (*ENDWITH*) 
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641put_roundlength (
            VAR acv        : tak_all_command_glob;
            VAR curr_n     : integer;
            VAR colin      : tak00_scolinf);
 
VAR
      old_frac   : integer;
      second_int : tsp00_Int2;
      next_n     : integer;
 
BEGIN
WITH acv DO
    BEGIN
    second_int := colin.sci_frac;
    IF  second_int = csp_float_frac
    THEN
        second_int := colin.sci_len;
    (*ENDIF*) 
    next_n := a_ap_tree^ [ curr_n ].n_lo_level;
    IF  ((a_ap_tree^ [ curr_n ].n_symb = s_unsigned_integer) AND
        (a_ap_tree^[ curr_n ].n_sa_level = 0) AND
        (a_ap_tree^[ curr_n ].n_lo_level = 0)) OR
        ((a_ap_tree^[ curr_n ].n_symb = s_plus) AND
        (a_ap_tree^[ next_n ].n_symb = s_unsigned_integer) AND
        (a_ap_tree^[ next_n ].n_sa_level = 0) AND
        (a_ap_tree^[ next_n ].n_lo_level = 0))
    THEN
        BEGIN
        IF  a_ap_tree^ [ curr_n ].n_symb = s_plus
        THEN
            curr_n := next_n;
        (*ENDIF*) 
        old_frac := second_int;
        a05_unsigned_int2_get (acv, a_ap_tree^[ curr_n ].n_pos,
              a_ap_tree^[ curr_n ].n_length, e_invalid_datalength, second_int);
        IF  (second_int < 0)
        THEN
            a07_b_put_error (acv, e_invalid_datalength,
                  a_ap_tree^[ curr_n ].n_pos)
        ELSE
            IF  (second_int > old_frac)
            THEN
                second_int := old_frac;
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (colin.sci_frac <> csp_float_frac)
    THEN
        WITH colin DO
            BEGIN
            IF  second_int <> 0
            THEN
                BEGIN
                sci_len  := sci_len - sci_frac + second_int;
                sci_iolen := (sci_len + 1) DIV 2 + 2;
                END;
            (*ENDIF*) 
            sci_frac := second_int;
            END;
        (*ENDWITH*) 
&   ifdef TRACE
    (*ENDIF*) 
    WITH colin DO
        BEGIN
        t01int4 (ak_sem, 'sci_len     ', sci_len);
        t01int4 (ak_sem, 'sci_iolen   ', sci_iolen);
        t01int4 (ak_sem, 'sci_frac    ', sci_frac);
        END;
    (*ENDWITH*) 
&   endif
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641soundex (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
CONST
      soundex_len = 4;
 
VAR
      curr_n        : integer;
      keep_datatype : tsp00_DataType;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    curr_n        := n_lo_level;
    keep_datatype := d_datatype;
    d_ch_datatype := dunknown;
    IF  (d_datatype in [dunknown, dnonumber, dunicode])
    THEN
        d_datatype := dcha;
    (*ENDIF*) 
    colin.sci_len := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        IF  (colin.sci_typ = dcha) AND
            (d_ch_datatype = dunknown)
            (* Characterfields must be given     *)
        THEN
            BEGIN
            a65_set_operator (acv, op_soundex);
            colin.sci_len    := soundex_len;
            IF  keep_datatype = dunicode
            THEN
                BEGIN
                colin.sci_iolen  := succ(2*soundex_len);
                a641string_set_operator (acv,
                      op_b_uni_trans, colin.sci_iolen, 0,
                      chr(csp_ascii), chr(csp_unicode));
                d_datatype := dunicode;
                END
            ELSE
                colin.sci_iolen  := succ(soundex_len);
            (*ENDIF*) 
            colin.sci_frac   := 0;
            colin.sci_typ    := d_datatype;
            colin.sci_cprops := [ ctopt ];
            END
        ELSE
            wrong_datatype   := true
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641substr (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      substr_from_null : boolean;
      h_long_allowed   : boolean;
      keep_datatype    : tsp00_DataType;
      keep1_datatype   : tsp00_DataType;
      param1Datatype   : tsp00_DataType;
      curr_n           : integer;
      index            : integer;
      max_length       : integer;
      old_n            : integer;
      operand_count    : integer;
      datatype_info    : integer;
      first_int        : tsp00_Int2;
      second_int       : tsp00_Int2;
      curr_data_pos    : tsp00_Int4;
      n_err            : tsp00_NumError;
      op               : tgg00_StackOpBuildIn;
      colin1           : tak00_scolinf;
      vallen           : integer;
      valptr           : tsp00_MoveObjPtr;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    param1Datatype := dunknown;
    keep1_datatype := dunknown;
    IF  ((d_datatype = ddate) OR
        (d_datatype = dtime) OR
        (d_datatype = dtimestamp))
    THEN
        d_datatype := dcha
    ELSE
        IF  d_datatype = dunknown
        THEN
            d_datatype := dnonumber;
        (*ENDIF*) 
    (*ENDIF*) 
    datatype_info := 0;
    curr_n := n_lo_level;
    colin.sci_len := 0;
    h_long_allowed      := d_type_long_allowed;
    d_type_long_allowed := true; (* acv.a_is_ddl <> ddl_create_trigger; *)
    substr_from_null := (a_ap_tree^[ curr_n ].n_proc = no_proc) AND
          (a_ap_tree^[ curr_n ].n_symb = s_null);
    a640factor (acv, dmli, colin, curr_n);
    d_type_long_allowed := h_long_allowed;
    IF  a_returncode = 0
    THEN
        BEGIN
        param1Datatype := colin.sci_typ;
&       ifdef trace
        t01int4 (ak_sem, 'param1Dtype ', ord(param1Datatype));
        t01int4 (ak_sem, 'd_datatype  ', ord(d_datatype));
&       endif
        IF  (param1Datatype in [dlonga, dlongb, dlonguni,
            dstra, dstrb, dstruni]) AND
            (colin.sci_len > SURROGATE_MXGG00)
        THEN
            ak641VirtualLongColumnNotImplemented (acv, n_pos)
        ELSE
            BEGIN
            keep_datatype  := d_datatype;
            d_datatype     := dnumber;
            colin1.sci_len := 0;
            curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
            operand_count  := 3;
            old_n          := curr_n;
            a640not_first_factor (acv, dmli, colin1, curr_n);
            IF  a_ap_tree^[ old_n ].n_symb = s_unsigned_integer
            THEN
                WITH a_mblock, mb_qual^ DO
                    BEGIN
                    index := mfirst_free-1;
                    g04value_locate (mb_st^[index], a_mblock, valptr, vallen);
                    s40gsint (valptr^, 2, (vallen - 1 - csp_attr_byte) * 2,
                          first_int, n_err);
&                   ifdef TRACE
                    t01int4 (ak_sem, 'index       ', index);
                    t01int4 (ak_sem, 'first_int   ', first_int);
                    t01int4 (ak_sem, 'colin.sci_le', colin.sci_len);
&                   endif
                    IF  n_err = num_ok
                    THEN
                        IF  (first_int < 1)
                            OR
                            ((first_int > colin.sci_len) AND
                            NOT
                            (param1Datatype in [dlonga, dlongb, dlonguni,
                            dstra, dstrb, dstruni]))
                        THEN
                            IF  substr_from_null
                            THEN
                                first_int := 1
                            ELSE
                                a07_b_put_error (acv,
                                      e_invalid_char_position, n_pos);
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                (*ENDWITH*) 
            ELSE
                first_int := 1;
            (*ENDIF*) 
            IF  a_returncode = 0
            THEN
                BEGIN
                curr_n := a_ap_tree^[ curr_n ].n_sa_level;
                old_n  := curr_n;
                IF  curr_n <> 0
                THEN
                    BEGIN
                    colin1.sci_len := 0;
                    a640not_first_factor (acv, dmli, colin1, curr_n);
                    IF  a_ap_tree^[ old_n ].n_symb = s_unsigned_integer
                    THEN
                        WITH a_mblock, mb_qual^ DO
                            BEGIN
                            CASE a_sqlmode OF
                                sqlm_db2 :
                                    max_length := cak_maxdb2fieldlength;
                                sqlm_oracle :
                                    max_length := cak_maxorafieldlength;
                                sqlm_internal :
                                    max_length := cak_maxdeffieldlength;
                                OTHERWISE
                                    max_length := cak_maxfieldlength;
                                END;
                            (*ENDCASE*) 
                            index := mfirst_free-1;
                            g04value_locate (mb_st^[index], a_mblock, valptr, vallen);
                            s40gsint (valptr^, 2, (vallen - 1 - csp_attr_byte) * 2,
                                  second_int, n_err);
                            IF  n_err = num_ok
                            THEN
                                IF  (second_int <= 0)
                                    OR
                                    (second_int > max_length)
                                    OR
                                    ((param1Datatype in [dunicode, dstruni, dlonguni]) AND
                                    (2 * second_int > max_length))
                                THEN
                                    a07_b_put_error (acv,
                                          e_invalid_char_position, n_pos);
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END
                        (*ENDWITH*) 
                    ELSE
                        second_int := 0
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    second_int := 0;
                    operand_count := 2;
                    END;
                (*ENDIF*) 
                IF  a_returncode = 0
                THEN
                    BEGIN
                    IF  param1Datatype in [dlonga, dlongb, dlonguni,
                        dstra, dstrb, dstruni]
                    THEN
                        IF  second_int = 0
                        THEN
                            a07_b_put_error (acv, e_missing_value_spec,
                                  a_ap_tree^[ a_ap_tree^[ act_node ].n_lo_level ].n_pos)
                        ELSE
                            BEGIN
                            WITH a_mblock, mb_data^, mb_qual^ DO
                                IF  mfirst_free > mb_st_max - 1
                                THEN
                                    a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
                                ELSE
                                    BEGIN
                                    curr_data_pos := mb_data_len + 1;
                                    WITH mb_st^[ mfirst_free ] DO
                                        BEGIN
                                        etype         := st_value;
                                        eop           := op_none;
                                        epos          := curr_data_pos;
                                        elen_var      := sizeof (dmli.d_sparr.pbasep^.sbase.btreeid)+1;
                                        ecol_tab[ 1 ] := chr (0);
                                        ecol_tab[ 2 ] := chr (0)
                                        END;
                                    (*ENDWITH*) 
                                    mbp_buf[ curr_data_pos ] := csp_defined_byte;
                                    SAPDB_PascalMove ('VAK641',   9,    
                                          sizeof (mtree), mb_data_size,
                                          @dmli.d_sparr.pbasep^.sbase.btreeid, 1,
                                          @mbp_buf, curr_data_pos+1,
                                          sizeof (dmli.d_sparr.pbasep^.sbase.btreeid),
                                          a_returncode);
                                    mb_data_len := mb_data_len + sizeof (dmli.d_sparr.pbasep^.sbase.btreeid) + 1;
                                    mfirst_free := succ (mfirst_free);
                                    mqual_cnt   := succ (mqual_cnt);
                                    operand_count := 4;
                                    END;
                                (*ENDIF*) 
                            (*ENDWITH*) 
                            op := op_b_long_substr;
                            IF  param1Datatype in [dstruni, dlonguni]
                            THEN
                                second_int := 2 * second_int;
                            (*ENDIF*) 
                            datatype_info := ord(param1Datatype);
                            END
                        (*ENDIF*) 
                    ELSE
                        IF  keep_datatype = dunicode
                        THEN
                            BEGIN
                            op := op_b_dbyte_substr;
                            IF  second_int = 0
                            THEN
                                second_int := colin.sci_iolen-(2*first_int-1)
                            ELSE
                                second_int := 2*second_int;
                            (*ENDIF*) 
                            colin.sci_len := 2 * colin.sci_len;
                            END
                        ELSE
                            BEGIN
                            op := op_b_substr;
                            IF  second_int = 0
                            THEN
                                second_int := colin.sci_len+1-first_int;
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    IF  a_returncode = 0
                    THEN
                        BEGIN
                        a641string_set_operator (acv, op,
                              second_int, colin.sci_len, chr(operand_count),
                              chr(datatype_info));
                        IF  (op = op_b_substr)
                            OR
                            ((op = op_b_long_substr) AND
                            NOT (keep_datatype in [dstruni, dlonguni]))
                        THEN
                            BEGIN
                            colin.sci_len   := second_int;
                            colin.sci_iolen := colin.sci_len + 1;
                            END
                        ELSE
                            BEGIN
                            colin.sci_len   := second_int DIV 2;
                            colin.sci_iolen := second_int+1;
                            END;
                        (*ENDIF*) 
                        colin.sci_frac := 0;
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            CASE keep_datatype OF
                ddate, dtime, dtimestamp, dstra, dlonga :
                    BEGIN
                    d_datatype := dcha;
                    colin.sci_typ := d_datatype;
                    END;
                dstruni, dlonguni :
                    BEGIN
                    d_datatype := dunicode;
                    colin.sci_typ := d_datatype;
                    END;
                dstrb, dlongb :
                    BEGIN
                    d_datatype := dchb;
                    colin.sci_typ := d_datatype;
                    END;
                OTHERWISE
                    d_datatype := keep_datatype;
                END;
            (*ENDCASE*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  ((a_returncode = 0) AND
        ((keep1_datatype = ddate) OR
        (keep1_datatype = dtime) OR
        (keep1_datatype = dtimestamp)))
    THEN
        d_datatype := keep1_datatype;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641leftright (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer;
            symbol    : tak_sc_symbol);
 
VAR
      substr_from_null : boolean;
      keep_datatype    : tsp00_DataType;
      keep1_datatype   : tsp00_DataType;
      curr_n           : integer;
      old_n            : integer;
      index            : integer;
      first_int        : tsp00_Int2;
      n_err            : tsp00_NumError;
      op               : tgg00_StackOpBuildIn;
      colin1           : tak00_scolinf;
      vallen           : integer;
      valptr           : tsp00_MoveObjPtr;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    IF  symbol = s_left
    THEN
        op := op_b_left
    ELSE
        op := op_b_right;
    (*ENDIF*) 
    keep1_datatype := d_datatype;
    IF  ((d_datatype = ddate) OR
        (d_datatype = dtime) OR
        (d_datatype = dtimestamp))
    THEN
        d_datatype := dcha
    ELSE
        IF  d_datatype = dunknown
        THEN
            d_datatype := dnonumber;
        (*ENDIF*) 
    (*ENDIF*) 
    curr_n := n_lo_level;
    colin.sci_len := 0;
    substr_from_null := (a_ap_tree^[ curr_n ].n_proc = no_proc) AND
          (a_ap_tree^[ curr_n ].n_symb = s_null);
    a640factor (acv, dmli, colin, curr_n);
    IF  a_returncode = 0
    THEN
        BEGIN
        keep_datatype  := d_datatype;
        d_datatype     := dnumber;
        colin1.sci_len := 0;
        curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
        old_n          := curr_n;
        a640not_first_factor (acv, dmli, colin1, curr_n);
        IF  a_ap_tree^[ old_n ].n_symb = s_unsigned_integer
        THEN
            WITH a_mblock, mb_qual^ DO
                BEGIN
                index := mfirst_free-1;
                g04value_locate (mb_st^[index], a_mblock, valptr, vallen);
                s40gsint (valptr^, 2, (vallen - 1 - csp_attr_byte) * 2,
                      first_int, n_err);
                IF  n_err = num_ok
                THEN
                    IF  (first_int < 0) OR
                        (first_int > cak_maxdeffieldlength)
                    THEN
                        a07_b_put_error (acv,
                              e_invalid_char_position, n_pos)
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            (*ENDWITH*) 
        ELSE
            first_int := colin.sci_len + 1;
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            BEGIN
            IF  keep_datatype = dunicode
            THEN
                BEGIN
                first_int := 2*first_int;
                colin.sci_len := 2*colin.sci_len;
                a641string_set_operator (acv, op,
                      first_int, colin.sci_len, chr(2), chr(0));
                colin.sci_len   := first_int DIV 2;
                colin.sci_iolen := first_int+1;
                END
            ELSE
                BEGIN
                a641string_set_operator (acv, op,
                      first_int, colin.sci_len, chr(1), chr(0));
                colin.sci_len   := first_int;
                colin.sci_iolen := colin.sci_len + 1;
                END;
            (*ENDIF*) 
            colin.sci_frac := 0;
            END;
        (*ENDIF*) 
        IF  keep_datatype in [ ddate, dtime, dtimestamp ]
        THEN
            BEGIN
            d_datatype := dcha;
            colin.sci_typ := d_datatype;
            END
        ELSE
            d_datatype := keep_datatype;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  ((a_returncode = 0) AND
        ((keep1_datatype = ddate) OR
        (keep1_datatype = dtime) OR
        (keep1_datatype = dtimestamp)))
    THEN
        d_datatype := keep1_datatype;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641timedate (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      curr_n : integer;
      op_set : boolean;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli,
     a_mblock.mb_qual^ DO
    BEGIN
    op_set     := false;
    d_datatype := dunknown;
    curr_n     := n_lo_level;
    IF  (a_ap_tree^[ curr_n ].n_symb = s_string_literal)
        AND (a_is_ddl = ddl_create_view)
    THEN
        BEGIN
        a16inc_vdesc_cnt (acv, dmli, a_ptr10);
        IF  a_returncode = 0
        THEN
            WITH a_ptr10^.sviewdesc, vdescription[ vdesc_cnt ] DO
                BEGIN
                vfromtabno    := a_ap_tree^[ curr_n ].n_length;
                vfromextcolno := 0;
                vn_pos        := a_ap_tree^[ curr_n ].n_pos;
                vextcolno     := 0;
                IF  n_symb = s_func_date
                THEN
                    vdatatype := ddate
                ELSE
                    vdatatype := dtime
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    colin.sci_len := 0;
    a640factor(acv, dmli, colin, curr_n);
    IF  a_returncode = cak_e_parameter
    THEN
        (* PTS 1109261 E.Z. *)
        BEGIN
        a_returncode := 0;
        IF  n_symb = s_func_date
        THEN
            d_datatype := ddate
        ELSE
            d_datatype := dtime;
        (*ENDIF*) 
        colin.sci_len := 0;
        a640factor (acv, dmli, colin, curr_n);
        END;
    (*ENDIF*) 
    IF  (a_returncode = 0)
    THEN
        WITH colin DO
            IF  sci_typ = dchb
            THEN
                wrong_datatype := true
            ELSE
                IF  n_symb = s_func_date
                THEN
                    IF  sci_typ = dtime
                    THEN
                        wrong_datatype := true
                    ELSE
                        BEGIN
                        IF  sci_typ in [ dcha, dunicode ]
                        THEN
                            a641check_datetime(acv, dmli, ddate)
                        ELSE
                            IF  sci_typ = dtimestamp
                            THEN
                                a65_set_operator (acv,
                                      op_date_from_timestamp)
                            ELSE
                                IF  sci_typ in [ dfixed, dfloat, dvfloat ]
                                THEN
                                    op_set := true;
                                (*ENDIF*) 
                            (*ENDIF*) 
                        (*ENDIF*) 
                        sci_len    := mxsp_date;
                        d_datatype := ddate;
                        sci_frac   := 0;
                        sci_typ    := ddate;
                        sci_iolen  := sci_len + 1;
                        IF  op_set
                        THEN
                            a65_set_operator(acv, op_date)
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                ELSE
                    BEGIN
                    IF  sci_typ in [ dfixed, dfloat, dvfloat, ddate ]
                    THEN
                        wrong_datatype := true
                    ELSE
                        BEGIN
                        IF  sci_typ in [ dcha, dunicode ]
                        THEN
                            a641check_datetime(acv, dmli, dtime)
                        ELSE
                            IF  sci_typ = dtimestamp
                            THEN
                                op_set := true;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        sci_len    := mxsp_time;
                        d_datatype := dtime;
                        sci_frac   := 0;
                        sci_typ    := dtime;
                        sci_iolen  := sci_len + 1;
                        IF  op_set
                        THEN
                            a65_set_operator(acv, op_time)
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDWITH*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641timediff (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
      colin1 : tak00_scolinf;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    curr_n := a_ap_tree^[ act_node ].n_lo_level;
    ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, dtime, dtime);
    IF  a_returncode =
        a071_return_code (e_incompatible_datatypes, a_sqlmode)
    THEN
        BEGIN
        a_returncode := 0;
        ak641type_or_timestamp_parameter (acv, dmli, colin, curr_n, dtimestamp, dtimestamp);
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        curr_n := a_ap_tree^[ curr_n ].n_sa_level;
        ak641not_first_type_or_timestamp_parameter (acv, dmli,
              colin1, curr_n, colin.sci_typ)
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        IF  colin.sci_typ <> colin.sci_typ
        THEN
            a07_b_put_error (acv, e_incompatible_datatypes,
                  a_ap_tree^[ act_node ].n_lo_level)
        ELSE
            BEGIN
            d_datatype := dtime;
            WITH colin DO
                BEGIN
                sci_len   := mxsp_time;
                sci_iolen := sci_len+1;
                sci_frac  := 0;
                sci_typ   := dtime
                END;
            (*ENDWITH*) 
            a65_set_operator (acv, op_timediff)
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641not_first_type_or_timestamp_parameter
            (VAR acv : tak_all_command_glob;
            VAR dmli     : tak_dml_info;
            VAR colin    : tak00_scolinf;
            VAR act_node : integer;
            wanted_type  : tsp00_DataType);
 
VAR
      st_begin : integer;
      st_index : integer;
 
BEGIN
st_begin := dmli.d_param_st_begin;
st_index := dmli.d_param_st_index;
dmli.d_param_st_begin := 0;
dmli.d_param_st_index := 0;
ak641type_or_timestamp_parameter (acv, dmli, colin,
      act_node, wanted_type, dtimestamp);
dmli.d_param_st_begin := st_begin;
IF  dmli.d_param_st_index = 0
THEN
    dmli.d_param_st_index := st_index;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641type_or_timestamp_parameter (
            VAR acv      : tak_all_command_glob;
            VAR dmli     : tak_dml_info;
            VAR colin    : tak00_scolinf;
            VAR act_node : integer;
            wanted_type  : tsp00_DataType;
            param_type   : tsp00_DataType);
 
VAR
      top_node : integer;
 
BEGIN
(* PTS 1112963 E.Z. *)
WITH acv, dmli DO
    BEGIN
    d_datatype    := dunknown;
    colin.sci_len := 0;
    top_node      := act_node;
    a640factor (acv, dmli, colin, act_node);
    IF  (a_returncode = cak_e_parameter)
    THEN
        BEGIN
        a_returncode := 0;
        d_datatype := param_type;
        act_node   := top_node;
        a640factor (acv, dmli, colin, act_node)
        END;
&   ifdef trace
    (*ENDIF*) 
    t01int4 (ak_sem, '>>wanted_typ', ord (wanted_type));
    t01int4 (ak_sem, '>>d_datatype', ord (d_datatype));
    t01int4 (ak_sem, '>>colin.typ ', ord (colin.sci_typ));
&   endif
    IF  a_returncode = 0
    THEN
        IF  (colin.sci_typ = wanted_type) OR
            (colin.sci_typ = dtimestamp)
        THEN
            d_datatype := colin.sci_typ
        ELSE
            IF  a_ap_tree^[ top_node ].n_symb = s_null
            THEN
                d_datatype := wanted_type
            ELSE
                IF  colin.sci_typ in [ dcha, dunicode ]
                THEN
                    WITH a_ap_tree^[top_node] DO
                        IF  (n_symb = s_string_literal)
                            AND
                            (
                            (
                            (wanted_type = ddate) AND
                            (n_length > EXT_DATE_MXSP00 * a01char_size)
                            )
                            OR
                            (
                            (wanted_type = dtime) AND
                            (n_length > EXT_TIME_MXSP00 * a01char_size)
                            )
                            )
                        THEN
                            BEGIN
                            a641check_datetime (acv, dmli, dtimestamp);
                            d_datatype    := dtimestamp;
                            colin.sci_typ := dtimestamp;
                            END
                        ELSE
                            BEGIN
                            a641check_datetime (acv, dmli, wanted_type);
                            d_datatype    := wanted_type;
                            colin.sci_typ := wanted_type;
                            END
                        (*ENDIF*) 
                    (*ENDWITH*) 
                ELSE
                    a07_b_put_error (acv, e_incompatible_datatypes,
                          a_ap_tree^[ top_node ].n_pos)
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641timestamp (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR frec  : tak_factorrec;
            VAR colin : tak00_scolinf;
            act_node  : integer;
            VAR wrong_datatype : boolean);
 
VAR
      date_n    : integer;
      time_n    : integer;
      value_cnt : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    IF  n_lo_level = 0
    THEN
        a642other_than_column( acv, dmli, frec, colin, act_node)
    ELSE
        BEGIN
        value_cnt := 2;
        date_n    := n_lo_level;
        (* Now we look for the optional second parameter. *)
        time_n := date_n;
        IF  a_ap_tree^[ time_n ].n_symb = s_authid
        THEN
            time_n := a_ap_tree^[ time_n ].n_sa_level;
        (*ENDIF*) 
        IF  a_ap_tree^[ time_n ].n_symb = s_tablename
        THEN
            time_n := a_ap_tree^[ time_n ].n_sa_level;
        (*ENDIF*) 
        time_n := a_ap_tree^[ time_n ].n_sa_level;
        IF  time_n <> 0
        THEN (* Call of TIMESTAMP (<date>, <time>) *)
            BEGIN
            d_datatype    := ddate;
            colin.sci_len := 0;
            a640factor(acv, dmli, colin, date_n);
            IF  (colin.sci_typ = dtimestamp)
            THEN
                wrong_datatype := true
            ELSE
                IF  a_returncode = 0
                THEN
                    BEGIN
                    IF  colin.sci_typ <> ddate
                    THEN
                        a641check_datetime(acv, dmli, ddate);
                    (*ENDIF*) 
                    d_datatype    := dtime;
                    colin.sci_len := 0;
                    a640not_first_factor(acv, dmli, colin, time_n);
                    IF  (colin.sci_typ = dtimestamp)
                    THEN
                        wrong_datatype := true
                    ELSE
                        IF  a_returncode = 0
                        THEN
                            IF  colin.sci_typ <> dtime
                            THEN
                                a641check_datetime(acv, dmli, dtime);
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE
            BEGIN (* Call with only one parameter. *)
            value_cnt     := 1;
            d_datatype    := dtimestamp;
            colin.sci_len := 0;
            a640factor(acv, dmli, colin, date_n);
            IF  a_returncode = 0
            THEN
                IF  colin.sci_typ <> dtimestamp
                THEN
                    a641check_datetime(acv, dmli, dtimestamp);
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            WITH colin DO
                BEGIN
                sci_len    := mxsp_timestamp;
                sci_iolen  := sci_len + 1;
                d_datatype := dtimestamp;
                sci_typ    := dtimestamp;
                sci_frac   := 0;
                IF  value_cnt = 2
                THEN
                    a65_set_operator(acv, op_timestamp);
                (*ENDIF*) 
                END
            (*ENDWITH*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641truncround (
            VAR acv            : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            act_node           : integer;
            VAR wrong_datatype : boolean);
 
VAR
      negativ_trunc : boolean;
      curr_n        : integer;
      next_n        : integer;
      colin1        : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    curr_n        := n_lo_level;
    colin.sci_len := 0;
    IF  a_sqlmode <> sqlm_oracle
    THEN
        d_datatype := dnumber
    ELSE
        BEGIN
        a65_look_for_datatypes (acv, dmli, curr_n);
        IF  d_datatype <> dtimestamp
        THEN
            d_datatype := dnumber;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    a640factor (acv, dmli, colin, curr_n);
    IF  (a_returncode = 0)
    THEN
        IF  d_datatype = dtimestamp
        THEN
            BEGIN (* oracle like timestamp trunc or round. *)
            curr_n          := a_ap_tree^[ curr_n ].n_sa_level;
            IF  curr_n <> 0
            THEN
                BEGIN
                colin1.sci_len  := 0;
                colin1.sci_frac := 0;
                d_datatype      := dcha;
                a640not_first_factor (acv, dmli, colin1, curr_n);
                IF  (d_datatype <> dcha)
                THEN
                    wrong_datatype := true
                ELSE
                    BEGIN
                    IF  n_symb = s_trunc
                    THEN
                        a641string_set_operator (acv, op_b_ts_trunc,
                              0, 0, chr(0), chr(0))
                    ELSE
                        a641string_set_operator (acv, op_b_ts_round,
                              0, 0, chr(0), chr(0));
                    (*ENDIF*) 
                    d_datatype := dtimestamp
                    END
                (*ENDIF*) 
                END
            ELSE
                IF  n_symb = s_trunc
                THEN
                    a641string_set_operator (acv, op_b_ts_trunc,
                          0, 1, chr(0), chr(0))
                ELSE
                    a641string_set_operator (acv, op_b_ts_round,
                          0, 1, chr(0), chr(0));
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE
            IF  (a_ap_tree^[ curr_n ].n_sa_level <> 0)
            THEN
                BEGIN
                curr_n          := a_ap_tree^[ curr_n ].n_sa_level;
                colin1.sci_len  := 0;
                colin1.sci_frac := 0;
                next_n          := a_ap_tree^ [ curr_n ].n_lo_level;
                negativ_trunc   := (a_ap_tree^[ curr_n ].n_symb = s_minus) AND
                      (a_ap_tree^[ next_n ].n_symb = s_unsigned_integer) AND
                      (a_ap_tree^[ next_n ].n_sa_level = 0) AND
                      (a_ap_tree^[ next_n ].n_lo_level = 0);
                a640not_first_factor (acv, dmli, colin1, curr_n);
                IF  n_symb = s_trunc
                THEN
                    a65_set_operator (acv, op_fractrunc)
                ELSE
                    a65_set_operator (acv, op_fracround);
                (*ENDIF*) 
                IF  NOT negativ_trunc
                THEN
                    ak641put_roundlength (acv, curr_n, colin)
                ELSE
                    IF  colin.sci_frac > 0
                    THEN
                        WITH colin DO
                            BEGIN
                            sci_len   := sci_len - sci_frac;
                            IF  sci_len = 0
                            THEN
                                sci_len := 1;
                            (*ENDIF*) 
                            sci_frac  := 0;
                            sci_iolen := (sci_len + 1) DIV 2 + 2;
                            END;
                        (*ENDWITH*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                IF  colin.sci_frac > 0
                THEN
                    colin.sci_frac := 0;
                (*ENDIF*) 
                IF  n_symb = s_trunc
                THEN
                    a65_set_operator (acv, op_trunc)
                ELSE
                    a65_set_operator (acv, op_round);
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDIF*) 
&   ifdef trace
    (*ENDIF*) 
    t01int4 (ak_sem,'tr: datatype', ord (d_datatype));
&   endif
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641mod_power (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n          : integer;
      exponent_curr_n : integer;
      second_int      : tsp00_Int2;
      colin1          : tak00_scolinf;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype      := dnumber;
    curr_n          := n_lo_level;
    colin.sci_len   := 0;
    a640factor (acv, dmli, colin, curr_n);
    curr_n          := a_ap_tree^[ curr_n ].n_sa_level;
    colin1.sci_len  := 0;
    exponent_curr_n := curr_n;
    a640not_first_factor (acv, dmli, colin1, curr_n);
    IF  (a_returncode = 0)
    THEN
        CASE  n_symb OF
            s_mod_func:
                IF  (colin1.sci_frac <> 0)
                THEN
                    a07_b_put_error (acv, e_incompatible_datatypes,
                          a_ap_tree^[ curr_n ].n_pos)
                ELSE
                    a65_set_operator (acv, op_mod_func);
                (*ENDIF*) 
            s_atan2:
                WITH colin DO
                    BEGIN
                    a641string_set_operator (acv, op_b_atan2,
                          0, 0, chr (0), chr (0));
                    sci_len   := csp_fixed;
                    sci_frac  := csp_float_frac;
                    sci_typ   := dfloat;
                    sci_iolen := NUMBER_MXGG04;
                    END;
                (*ENDWITH*) 
            s_log:
                WITH colin DO
                    BEGIN
                    a641string_set_operator (acv, op_b_log,
                          0, 0, chr (0), chr (0));
                    sci_len   := csp_fixed;
                    sci_frac  := csp_float_frac;
                    sci_typ   := dfloat;
                    sci_iolen := NUMBER_MXGG04;
                    END;
                (*ENDWITH*) 
            s_power:
                IF  (colin1.sci_frac <> 0)
                THEN
                    a07_b_put_error (acv, e_incompatible_datatypes,
                          a_ap_tree^[ curr_n ].n_pos)
                ELSE
                    WITH a_ap_tree^[ exponent_curr_n ], colin DO
                        BEGIN
                        a65_set_operator (acv, op_power);
                        second_int := csp_fixed;
                        IF  (n_symb = s_unsigned_integer)
                        THEN
                            BEGIN
                            a05_unsigned_int2_get (acv,
                                  n_pos, n_length, e_invalid_unsign_integer, second_int);
                            IF  (second_int < 2)
                            THEN
                                second_int := 2;
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        IF  ((sci_len * second_int) < csp_fixed) AND
                            (sci_typ = dfixed)
                        THEN
                            BEGIN
                            sci_len   := sci_len * second_int;
                            sci_frac  := sci_frac * second_int;
                            sci_iolen := (sci_len + 1) DIV 2 + 2;
                            END
                        ELSE
                            BEGIN
                            sci_len   := csp_fixed;
                            sci_frac  := csp_float_frac;
                            sci_typ   := dfloat;
                            sci_iolen := NUMBER_MXGG04;
                            END;
                        (*ENDIF*) 
                        END;
                    (*ENDWITH*) 
                (*ENDIF*) 
            END;
        (*ENDCASE*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641integer (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_datatype     := dnumber;
    curr_n         := n_lo_level;
    colin.sci_len  := 0;
    colin.sci_frac := 0;
    a640factor (acv, dmli, colin, curr_n);
    IF  (a_returncode = 0)
    THEN
        IF  (n_symb <> s_abs)
        THEN
            BEGIN
            CASE n_symb OF
                s_ceil:
                    a65_set_operator (acv, op_ceil);
                s_cos:
                    a641string_set_operator (acv, op_b_cos,
                          0, 0, chr (0), chr (0));
                s_cosh:
                    a641string_set_operator (acv, op_b_cosh,
                          0, 0, chr (0), chr (0));
                s_acos:
                    a641string_set_operator (acv, op_b_acos,
                          0, 0, chr (0), chr (0));
                s_exp:
                    a641string_set_operator (acv, op_b_exp,
                          0, 0, chr (0), chr (0));
                s_floor:
                    a65_set_operator (acv, op_floor);
                s_integer:
                    a65_set_operator (acv, op_trunc);
                s_ln:
                    a641string_set_operator (acv, op_b_ln,
                          0, 0, chr (0), chr (0));
                s_log10:
                    a641string_set_operator (acv, op_b_log10,
                          0, 0, chr (0), chr (0));
                s_sign:
                    a65_set_operator (acv, op_sign);
                s_sin:
                    a641string_set_operator (acv, op_b_sin,
                          0, 0, chr (0), chr (0));
                s_sinh:
                    a641string_set_operator (acv, op_b_sinh,
                          0, 0, chr (0), chr (0));
                s_asin:
                    a641string_set_operator (acv, op_b_asin,
                          0, 0, chr (0), chr (0));
                s_sqrt:
                    a65_set_operator (acv, op_sqrt);
                s_tan:
                    a641string_set_operator (acv, op_b_tan,
                          0, 0, chr (0), chr (0));
                s_tanh:
                    a641string_set_operator (acv, op_b_tanh,
                          0, 0, chr (0), chr (0));
                s_atan:
                    a641string_set_operator (acv, op_b_atan,
                          0, 0, chr (0), chr (0));
                s_cot:
                    a641string_set_operator (acv, op_b_cot,
                          0, 0, chr (0), chr (0));
                s_degrees:
                    a641string_set_operator (acv, op_b_degrees,
                          0, 0, chr (0), chr (0));
                s_radians:
                    a641string_set_operator (acv, op_b_radians,
                          0, 0, chr (0), chr (0));
                END;
            (*ENDCASE*) 
            CASE n_symb OF
                s_integer,
                s_floor,
                s_ceil:
                    WITH colin DO
                        BEGIN
                        IF  sci_typ <> dfixed
                        THEN
                            BEGIN
                            sci_typ   := dfixed;
                            sci_len   := csp_fixed;
                            sci_iolen := NUMBER_MXGG04;
                            END;
                        (*ENDIF*) 
                        sci_frac := 0;
                        END;
                    (*ENDWITH*) 
                s_sign :
                    WITH colin DO
                        BEGIN
                        sci_len   := 1;
                        sci_frac  := 0;
                        sci_typ   := dfixed;
                        sci_iolen := (sci_len+1) DIV 2 + 2;
                        END;
                    (*ENDWITH*) 
                OTHERWISE :
                    (* cos, cosh, exp, ln, sin, sinh, sqrt, tan, tanh *)
                    WITH colin DO
                        BEGIN
                        sci_len   := csp_fixed;
                        sci_frac  := csp_float_frac;
                        sci_typ   := dfloat;
                        sci_iolen := NUMBER_MXGG04;
                        END;
                    (*ENDWITH*) 
                END;
            (*ENDCASE*) 
            END
        ELSE
            a65_set_operator (acv, op_abs);
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641newcolin(
            VAR colin  : tak00_scolinf;
            VAR colin1 : tak00_scolinf);
 
BEGIN (* PTS 1113810 *)
&ifdef trace
t01int4 (ak_sem, 'colin  typ  ', ord(colin.sci_typ));
t01int4 (ak_sem, 'colin  len  ', colin.sci_len);
t01int4 (ak_sem, 'colin  frac ', colin.sci_frac);
t01int4 (ak_sem, 'colin  ilen ', colin.sci_iolen);
t01int4 (ak_sem, 'colin1 typ  ', ord(colin1.sci_typ));
t01int4 (ak_sem, 'colin1 len  ', colin1.sci_len);
t01int4 (ak_sem, 'colin1 frac ', colin1.sci_frac);
t01int4 (ak_sem, 'colin1 ilen ', colin1.sci_iolen);
&endif
(* PTS 1123805 E.Z. *)
IF  (colin.sci_frac <> csp_float_frac) AND
    (colin1.sci_frac <> csp_float_frac)
THEN
    IF  (colin.sci_frac < colin1.sci_frac)
    THEN
        BEGIN
        IF  colin.sci_len < colin1.sci_len
        THEN
            colin.sci_len   := colin1.sci_len
        ELSE
            colin.sci_len   := colin.sci_len +
                  colin1.sci_frac - colin.sci_frac;
        (*ENDIF*) 
        IF  colin.sci_iolen < colin1.sci_iolen
        THEN
            colin.sci_iolen   := colin1.sci_iolen
        ELSE
            colin.sci_iolen   := colin.sci_iolen +
                  colin1.sci_frac - colin.sci_frac;
        (*ENDIF*) 
        colin.sci_frac := colin1.sci_frac;
        END
    ELSE
        BEGIN
        IF  colin.sci_len < colin1.sci_len
        THEN
            colin.sci_len := colin1.sci_len;
        (*ENDIF*) 
        IF  colin.sci_iolen < colin1.sci_iolen
        THEN
            colin.sci_iolen := colin1.sci_iolen
        (*ENDIF*) 
        END
    (*ENDIF*) 
ELSE
    BEGIN
    IF  colin.sci_len < colin1.sci_len
    THEN
        BEGIN
        colin.sci_len   := colin1.sci_len;
        colin.sci_iolen := colin1.sci_iolen
        END;
    (*ENDIF*) 
    colin.sci_frac := csp_float_frac;
    (* PTS 1123805 E.Z. *)
    colin.sci_typ  := dfloat;
    END;
(*ENDIF*) 
IF  (colin.sci_typ = dunknown) AND (colin1.sci_typ <> dunknown)
THEN
    colin.sci_typ := colin1.sci_typ;
&ifdef trace
(*ENDIF*) 
t01int4 (ak_sem, 'colin  typ  ', ord(colin.sci_typ));
t01int4 (ak_sem, 'colin  len  ', colin.sci_len);
t01int4 (ak_sem, 'colin  frac ', colin.sci_frac);
t01int4 (ak_sem, 'colin  ilen ', colin.sci_iolen);
&endif
END;
 
(* PTS 1113088 E.Z. *)
(*------------------------------*) 
 
FUNCTION
      ak641is_trans_ascii_to_uni (VAR st : tgg00_StackEntry) : boolean;
 
BEGIN
WITH st DO
    ak641is_trans_ascii_to_uni :=
          (etype        = st_build_in_func)     AND
          (eop_build_in = op_b_uni_trans)         AND
          (ecol_tab[1]  = chr(csp_ascii)) AND
          (ecol_tab[2]  = chr(csp_unicode))
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      ak641is_trans_uni_to_ascii (VAR st : tgg00_StackEntry) : boolean;
 
BEGIN
WITH st DO
    ak641is_trans_uni_to_ascii :=
          (etype        = st_build_in_func)       AND
          (eop_build_in = op_b_uni_trans)           AND
          (ecol_tab[1]  = chr(csp_unicode)) AND
          (ecol_tab[2]  = chr(csp_ascii))
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      ak641unicode_conv_destroyed (
            mb_st            : tgg00_StackListPtr;
            VAR stackentries : ak641stackentries;
            pair_cnt         : tsp00_Int2) : boolean;
 
VAR
      ind             : integer;
      conv_to_uni     : boolean;
 
BEGIN
ind := 0;
conv_to_uni := true;
WHILE (ind <= pair_cnt) AND conv_to_uni DO
    BEGIN
    IF  stackentries[ind] > 1
    THEN
        IF  ak641is_trans_ascii_to_uni (mb_st^ [stackentries[ind]])
        THEN
            BEGIN
            IF  ak641is_trans_uni_to_ascii (mb_st^ [stackentries[ind]-1])
            THEN
                BEGIN
                conv_to_uni := false;
                mb_st^ [stackentries[ind]  ].etype := st_dummy;
                mb_st^ [stackentries[ind]  ].eop   := op_none;
                mb_st^ [stackentries[ind]-1].etype := st_dummy;
                mb_st^ [stackentries[ind]-1].eop   := op_none;
                END;
            (*ENDIF*) 
            END
        ELSE
            conv_to_uni := false;
        (*ENDIF*) 
    (*ENDIF*) 
    ind := succ(ind);
    END;
(*ENDWHILE*) 
IF  conv_to_uni
THEN
    BEGIN
    ind := 0;
    WHILE ind <= pair_cnt DO
        BEGIN
        IF  stackentries[ind] > 1
        THEN
            BEGIN
            mb_st^ [stackentries[ind]  ].etype := st_dummy;
            mb_st^ [stackentries[ind]  ].eop   := op_none;
            END;
        (*ENDIF*) 
        ind := succ(ind);
        END
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
ak641unicode_conv_destroyed := conv_to_uni
END;
 
(*------------------------------*) 
 
FUNCTION
      ak641destroy_dummy_entries (
            mb_st    : tgg00_StackListPtr;
            start_st : tsp00_Int2;
            stop_st  : tsp00_Int2) : integer;
 
VAR
      ind     : integer;
      diff    : integer;
 
BEGIN
diff := 0;
ind := start_st - 1;
WHILE ind <= stop_st DO
    BEGIN
    IF  mb_st^ [ind].etype = st_dummy
    THEN
        diff := succ(diff)
    ELSE
        mb_st^ [ind - diff] := mb_st^ [ind];
    (*ENDIF*) 
    ind := succ(ind)
    END;
(*ENDWHILE*) 
ak641destroy_dummy_entries := diff;
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641decode_func (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n          : integer;
      check_n         : integer;
      value_cnt       : integer;
      colin1          : tak00_scolinf;
      search_datatype : tsp00_DataType;
      result_datatype : tsp00_DataType;
      ch_type         : tsp00_DataType;
      ch1_type        : tsp00_DataType;
      comp_st         : ak641stackentries;
      res_st          : ak641stackentries;
      pair_cnt        : tsp00_Int2;
      ind             : integer;
      diff            : integer;
      dummy_found     : boolean;
      h_long_allowed  : boolean;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli, a_mblock, mb_qual^ DO
    BEGIN
    (* PTS 1111393 E.Z. *)
    result_datatype := d_datatype;
    d_datatype      := dunknown;
    curr_n          := n_lo_level;
    colin1.sci_len  := 0;
    d_ch_datatype   := dunknown;
    a640factor ( acv, dmli, colin1, curr_n );
    IF  a_returncode = cak_e_parameter
    THEN
        BEGIN
        comp_st[0]      := mfirst_free - 1;
        check_n         := a_ap_tree^[ curr_n ].n_sa_level;
        colin.sci_len   := 0;
        d_datatype      := dunknown;
        d_ch_datatype   := dunknown;
        h_long_allowed      := d_type_long_allowed;
        d_type_long_allowed := true;
        a_returncode := 0;
        a640not_first_factor( acv, dmli, colin, check_n);
        IF  a_returncode = cak_e_parameter
        THEN
            a07_b_put_error (acv, e_parameter_not_allowed, a_ap_tree^[curr_n].n_pos)
        ELSE
            BEGIN
            search_datatype := d_datatype;
            d_type_long_allowed := h_long_allowed;
            mqual_cnt   := mqual_cnt - (mfirst_free - comp_st[0] - 1);
            mfirst_free := mfirst_free - comp_st[0] - 1;
            colin1.sci_len  := 0;
            a_returncode := 0;
            a640factor( acv, dmli, colin1, curr_n);
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (g01unicode AND
        (d_datatype = dcha))
    THEN
        BEGIN
        (*d_datatype := dunicode;*)
        (* do not change d_datatype, otherwise string literals will *)
        (* be converted to unicde and no b_uni_trans will be found  *)
        a641string_set_operator (acv, op_b_uni_trans,
              (2*colin1.sci_len)+1, 0, chr(csp_ascii),
              chr(csp_unicode));
        END;
    (*ENDIF*) 
    comp_st[0] := mfirst_free - 1;
    pair_cnt   := 1;
    res_st[0]  := 0;
    search_datatype := d_datatype;
    ch_type         := d_ch_datatype;
    curr_n          := a_ap_tree^[ curr_n ].n_sa_level;
    colin1.sci_len  := 0;
    d_ch_datatype   := dunknown;
    a640not_first_factor( acv, dmli, colin1, curr_n);
    IF  d_ch_datatype <> dunknown
    THEN
        IF  ch_type <> d_ch_datatype
        THEN
            IF  ch_type <> dunknown
            THEN
                a07_b_put_error (acv, e_incompatible_datatypes,
                      a_ap_tree^[ curr_n ].n_pos)
            ELSE
                ch_type := d_ch_datatype;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    IF  (g01unicode AND
        (d_datatype = dcha))
    THEN
        BEGIN
        a641string_set_operator (acv, op_b_uni_trans,
              (2*colin1.sci_len)+1, 0, chr(csp_ascii),
              chr(csp_unicode));
        END;
    (*ENDIF*) 
    comp_st[pair_cnt] := mfirst_free - 1;
    curr_n          := a_ap_tree^[ curr_n ].n_sa_level;
    colin.sci_len   := 0;
    d_datatype      := dunknown;
    d_ch_datatype   := dunknown;
    h_long_allowed      := d_type_long_allowed;
    d_type_long_allowed := true;
    a640not_first_factor( acv, dmli, colin, curr_n);
    IF  a_returncode = cak_e_parameter
    THEN
        BEGIN
        (* PTS 1111393 E.Z. *)
        IF  result_datatype <> dunknown
        THEN
            d_datatype := result_datatype
        ELSE
            d_datatype := search_datatype;
        (*ENDIF*) 
        a_returncode := 0;
        a640not_first_factor( acv, dmli, colin, curr_n);
        END;
    (*ENDIF*) 
    d_type_long_allowed := h_long_allowed;
    IF  (g01unicode AND
        (d_datatype = dcha))
    THEN
        BEGIN
        a641string_set_operator (acv, op_b_uni_trans,
              (2*colin.sci_len)+1, 0, chr(csp_ascii),
              chr(csp_unicode));
        colin.sci_typ := dunicode;
        colin.sci_iolen := (2*colin.sci_len)+1;
        END;
    (*ENDIF*) 
    res_st[pair_cnt]:= mfirst_free - 1;
    result_datatype := d_datatype;
    ch1_type        := d_ch_datatype;
    value_cnt       := 3;
&   ifdef TRACE
    t01int4 (ak_sem, 'result_dtyp ', ord(result_datatype));
    t01int4 (ak_sem, 'search_dtyp ', ord(search_datatype));
    t01int4 (ak_sem, 'colin_dtyp  ', ord(colin.sci_typ));
&   endif
    IF  a_returncode = 0
    THEN
        BEGIN
        d_datatype := search_datatype;
        WHILE ( a_ap_tree^[ curr_n ].n_sa_level <> 0 )
              AND ( a_returncode = 0 ) DO
            BEGIN
            check_n := a_ap_tree^[ curr_n ].n_sa_level;
            IF  a_ap_tree^[ check_n ].n_symb = s_authid
            THEN
                check_n := a_ap_tree^[ check_n ].n_sa_level;
            (*ENDIF*) 
            IF  a_ap_tree^[ check_n ].n_symb = s_tablename
            THEN
                check_n := a_ap_tree^[ check_n ].n_sa_level;
            (*ENDIF*) 
            IF  (a_ap_tree^[ check_n ].n_sa_level = 0 )
            THEN (* default expression *)
                BEGIN
                value_cnt      := succ(value_cnt);
                curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
                colin1.sci_len := 0;
                d_ch_datatype  := dunknown;
                d_datatype     := result_datatype;
                h_long_allowed      := d_type_long_allowed;
                d_type_long_allowed := true;
                a640not_first_factor( acv, dmli, colin1, curr_n);
                IF  a_returncode = cak_e_parameter
                THEN
                    BEGIN
                    d_datatype := search_datatype;
                    a_returncode := 0;
                    a640not_first_factor( acv, dmli, colin1, curr_n);
                    END;
                (*ENDIF*) 
                d_type_long_allowed := h_long_allowed;
                IF  d_ch_datatype <> dunknown
                THEN
                    IF  ch1_type <> d_ch_datatype
                    THEN
                        IF  ch1_type <> dunknown
                        THEN
                            a07_b_put_error (acv,
                                  e_incompatible_datatypes,
                                  a_ap_tree^[ curr_n ].n_pos)
                        ELSE
                            ch1_type := d_ch_datatype;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  (g01unicode AND
                    (d_datatype = dcha))
                THEN
                    BEGIN
                    a641string_set_operator (acv, op_b_uni_trans,
                          (2*colin1.sci_len)+1, 0, chr(csp_ascii),
                          chr(csp_unicode));
                    colin1.sci_typ := dunicode;
                    colin1.sci_iolen := (2*colin1.sci_len)+1;
                    END;
                (*ENDIF*) 
                IF  res_st[pair_cnt] = 0
                THEN
                    (* it is last result, not the default-result *)
                    res_st[pair_cnt] := mfirst_free - 1
                ELSE
                    res_st[0] := mfirst_free - 1;
                (*ENDIF*) 
                IF  (result_datatype in [dunknown, dnonumber]) AND
                    NOT (d_datatype in [dunknown, dnonumber])
                THEN
                    result_datatype := d_datatype;
                (*ENDIF*) 
                ak641newcolin(colin,colin1);
                END
            ELSE (* search and result spec list *)
                BEGIN
                curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
                colin1.sci_len := 0;
                d_ch_datatype  := dunknown;
                h_long_allowed := d_type_long_allowed;
                IF  (value_cnt MOD 2 = 0)
                THEN (* result expression*)
                    d_type_long_allowed := true;
                (*ENDIF*) 
                a640not_first_factor( acv, dmli, colin1, curr_n);
                d_type_long_allowed := h_long_allowed;
                IF  (g01unicode AND
                    (d_datatype = dcha))
                THEN
                    BEGIN
                    a641string_set_operator (acv, op_b_uni_trans,
                          (2*colin1.sci_len)+1, 0, chr(csp_ascii),
                          chr(csp_unicode));
                    colin1.sci_typ := dunicode;
                    colin1.sci_iolen := (2*colin1.sci_len)+1;
                    END;
                (*ENDIF*) 
                IF  (value_cnt MOD 2 = 0)
                THEN (* result expression*)
                    BEGIN
                    IF  d_ch_datatype <> dunknown
                    THEN
                        IF  ch1_type <> d_ch_datatype
                        THEN
                            IF  ch1_type <> dunknown
                            THEN
                                a07_b_put_error (acv,
                                      e_incompatible_datatypes,
                                      a_ap_tree^[ curr_n ].n_pos)
                            ELSE
                                ch1_type := d_ch_datatype;
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    res_st[pair_cnt] := mfirst_free - 1;
                    IF  (result_datatype in [dunknown, dnonumber]) AND
                        NOT (d_datatype  in [dunknown, dnonumber])
                    THEN
                        result_datatype := d_datatype;
                    (*ENDIF*) 
                    ak641newcolin(colin,colin1);
                    d_datatype := search_datatype;
                    END
                ELSE (* search expression *)
                    (* PTS 1120298 E.Z. *)
                    IF  pair_cnt = c_maxcntstackno
                    THEN
                        a07_b_put_error (acv, e_stack_overflow, -(c_maxcntstackno+1))
                    ELSE
                        BEGIN
                        pair_cnt := succ(pair_cnt);
                        IF  ch_type <> d_ch_datatype
                        THEN
                            IF  ch_type <> dunknown
                            THEN
                                a07_b_put_error (acv,
                                      e_incompatible_datatypes,
                                      a_ap_tree^[ curr_n ].n_pos)
                            ELSE
                                ch_type := d_ch_datatype;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        comp_st[pair_cnt] := mfirst_free - 1;
                        res_st[pair_cnt]  := 0;
                        d_datatype     := result_datatype;
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                value_cnt := succ(value_cnt);
                END
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        d_datatype := result_datatype;
&       ifdef TRACE
        t01messblock (ak_sem, 'a641decode  ', acv.a_mblock);
        t01int4 (ak_sem, 'search_st   ', comp_st[0]);
        FOR ind := 1 TO pair_cnt DO
            BEGIN
            t01int4 (ak_sem, 'ind         ', ind);
            t01int4 (ak_sem, 'comp_st     ', comp_st[ind]);
            t01int4 (ak_sem, ' res_st     ', res_st[ind]);
            END;
        (*ENDFOR*) 
        t01int4 (ak_sem, 'def_st      ', res_st[0]);
        t01int4 (ak_sem, 'result_dtyp ', ord(result_datatype));
        t01int4 (ak_sem, 'search_dtyp ', ord(search_datatype));
        t01int4 (ak_sem, 'colin_dtyp  ', ord(colin.sci_typ));
&       endif
        (* PTS 1120298 E.Z. *)
        IF  (a_returncode = 0) AND
            g01unicode
        THEN
            BEGIN
            dummy_found := ak641unicode_conv_destroyed (mb_st, comp_st, pair_cnt);
            IF  ak641unicode_conv_destroyed (mb_st, res_st, pair_cnt)
            THEN
                BEGIN
                colin.sci_typ := dcha;
                colin.sci_iolen := succ(colin.sci_len);
                dummy_found := true;
                END;
            (*ENDIF*) 
            IF  dummy_found
            THEN
                BEGIN
                diff := ak641destroy_dummy_entries (mb_st, comp_st[0], mfirst_free-1);
                mfirst_free := mfirst_free - diff;
                mqual_cnt   := mqual_cnt - diff;
                END;
            (* PTS 1118415 E.Z. *)
            (*ENDIF*) 
            IF  (colin.sci_typ = dunicode) AND
                (d_datatype = dcha)
            THEN
                d_datatype := dunicode;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  a_returncode = 0
        THEN
            IF  mfirst_free > mb_st_max
            THEN
                a07_b_put_error (acv,
                      e_too_many_mb_stackentries, -mb_st_max)
            ELSE
                BEGIN
                (* PTS 1121505 E.Z. *)
                WITH mb_st^ [mfirst_free] DO
                    BEGIN
                    etype         := st_build_in_func;
                    eop_build_in  := op_b_decode;
                    epos          := 0;
                    elen_var      := value_cnt;
                    ecol_tab[ 1 ] := chr(0);
                    ecol_tab[ 2 ] := chr(0)
                    END;
                (*ENDWITH*) 
                mfirst_free := succ(mfirst_free);
                mqual_cnt := succ(mqual_cnt)
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(* END OF PTS 1113088 E.Z. *)
(* PTS 1117523 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      ak641case_func (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      m_in_case_function : boolean;
      m_joincnt          : integer;
      m_jo_partno        : integer;
      curr_n             : integer;
      next_n             : integer;
      colin1             : tak00_scolinf;
      result_datatype    : tsp00_DataType;
      ch_type            : tsp00_DataType;
      res_st             : ak641stackentries;
      pair_cnt           : tsp00_Int2;
      ind                : integer;
      first_tabno        : integer;
      jumpstackentry1    : integer;
      startstackentry    : integer;
 
BEGIN
(*     a07_b_put_error (acv, e_not_implemented, acv.a_ap_tree^[ act_node ].n_pos);   *)
WITH acv, a_ap_tree^[ act_node ], dmli, a_mblock, mb_qual^ DO
    BEGIN
    m_in_case_function := d_in_case_function;
    d_in_case_function := true;
    IF  d_join
    THEN
        BEGIN
        m_joincnt      := d_joins.jrc_cnt;
        m_jo_partno    := d_joins.jrc_joinarr^[ d_joins.jrc_cnt ].jo_partno;
        END;
    (*ENDIF*) 
    result_datatype := d_datatype;
    d_datatype      := dunknown;
&   ifdef TRACE
    t01int4 (ak_sem, 'result_type ', ord(result_datatype));
&   endif
    curr_n          := n_lo_level;
    IF  curr_n > 0
    THEN
        next_n := a_ap_tree^[ curr_n ].n_sa_level
    ELSE
        next_n := 0;
    (*ENDIF*) 
    pair_cnt        := 1;
    res_st[0]       := 0;
    colin1.sci_len  := 0;
    d_ch_datatype   := dunknown;
    ch_type         := dunknown;
    IF  a_returncode = 0
    THEN
        IF  mfirst_free > mb_st_max
        THEN
            a07_b_put_error (acv,
                  e_too_many_mb_stackentries, -mb_st_max)
        ELSE
            BEGIN
            startstackentry := mfirst_free;
            mfirst_free := succ(mfirst_free);
            mqual_cnt := succ(mqual_cnt);
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        WHILE (curr_n > 0)  AND
              (next_n <> 0) AND
              (a_returncode = 0) DO
            BEGIN
            d_colptr := NIL;
            IF  d_join
            THEN
                BEGIN
                (**************************************************)
                (* in case of a                                   *)
                (* WHERE tab1.col = CASE ... tab2.col ....        *)
                (* it has to be assured, that tab2.col will not be*)
                (* in the same joinrec-entry as tab1.col          *)
                (* --> start a new joinrec-entry, which will be   *)
                (* destroyed when returning from case function    *)
                (**************************************************)
                dmli.d_joins.jrc_cnt := succ(dmli.d_joins.jrc_cnt);
                IF  ( dmli.d_joins.jrc_cnt > dmli.d_joins.jrc_capacity - 1 )
                THEN
                    a685expand_joinarr( acv, dmli );
                (*ENDIF*) 
                WITH d_joins, jrc_joinarr^[ jrc_cnt ] DO
                    BEGIN
                    jo_no_join             := false;
                    jo_partno              := 1;
                    jo_recs[ 1 ].jop_tableno    := 0;
                    jo_recs[ 2 ].jop_tableno    := 0;
                    jo_recs[ 1 ].jop_outer_join := false;
                    jo_recs[ 2 ].jop_outer_join := false;
                    END
                (*ENDWITH*) 
                END;
            (*ENDIF*) 
            a65_search_condition (acv, dmli, curr_n );
            IF  ( a_returncode = 0 )
            THEN
                BEGIN
                IF  pair_cnt > 1
                THEN
                    a65_set_operator (acv, op_or);
                (*ENDIF*) 
                a65_set_operator (acv, op_undef_to_false);
                jumpstackentry1 := acv.a_mblock.mb_qual^.mfirst_free;
                mfirst_free := succ(mfirst_free);
                mqual_cnt := succ(mqual_cnt);
                curr_n         := a_ap_tree^[ curr_n ].n_sa_level;
                colin1.sci_len := 0;
                d_ch_datatype  := dunknown;
                d_datatype     := result_datatype;
                d_colptr := NIL;
                a640not_first_factor( acv, dmli, colin1, curr_n);
                IF  a_returncode = cak_e_parameter
                THEN
                    BEGIN
                    IF  result_datatype <> dunknown
                    THEN
                        BEGIN
                        d_datatype := result_datatype;
                        a_returncode := 0;
                        a640not_first_factor( acv, dmli, colin, curr_n);
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  ( a_returncode = 0 )
            THEN
                BEGIN
                IF  (g01unicode AND
                    (d_datatype = dcha))
                THEN
                    BEGIN
                    a641string_set_operator (acv, op_b_uni_trans,
                          (2*colin1.sci_len)+1, 0, chr(csp_ascii),
                          chr(csp_unicode));
                    colin1.sci_typ := dunicode;
                    colin1.sci_iolen := (2*colin1.sci_len)+1;
                    END;
                (*ENDIF*) 
                IF  d_ch_datatype <> dunknown
                THEN
                    IF  ch_type <> d_ch_datatype
                    THEN
                        IF  ch_type <> dunknown
                        THEN
                            a07_b_put_error (acv,
                                  e_incompatible_datatypes,
                                  a_ap_tree^[ curr_n ].n_pos)
                        ELSE
                            ch_type := d_ch_datatype;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  mfirst_free > mb_st_max
                THEN
                    a07_b_put_error (acv,
                          e_too_many_mb_stackentries, -mb_st_max)
                ELSE
                    BEGIN
                    res_st[pair_cnt] := mfirst_free - 1;
                    mfirst_free := succ(mfirst_free);
                    mqual_cnt := succ(mqual_cnt);
                    IF  (result_datatype in [dunknown, dnonumber]) AND
                        NOT (d_datatype  in [dunknown, dnonumber])
                    THEN
                        result_datatype := d_datatype;
                    (*ENDIF*) 
                    IF  pair_cnt = 1
                    THEN
                        colin := colin1
                    ELSE
                        ak641newcolin(colin,colin1);
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  ( a_returncode = 0 )
            THEN
                (* PTS 1120298 E.Z. *)
                IF  pair_cnt = c_maxcntstackno
                THEN
                    a07_b_put_error (acv, e_stack_overflow, -(c_maxcntstackno+1))
                ELSE
                    BEGIN
                    pair_cnt := succ(pair_cnt);
                    curr_n   := a_ap_tree^[ curr_n ].n_sa_level;
                    next_n   := curr_n;
                    IF  next_n > 0
                    THEN
                        BEGIN
                        IF  a_ap_tree^[next_n].n_symb = s_authid
                        THEN
                            next_n := a_ap_tree^[next_n].n_sa_level;
                        (*ENDIF*) 
                        IF  a_ap_tree^[next_n].n_symb = s_tablename
                        THEN
                            next_n := a_ap_tree^[next_n].n_sa_level;
                        (*ENDIF*) 
                        next_n := a_ap_tree^[next_n].n_sa_level;
                        END;
                    (*ENDIF*) 
                    a61_set_jump (acv.a_mblock, jumpstackentry1, st_jump_false);
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDWHILE*) 
        END;
    (* ELSE / DEFAULT NULL *)
    (*ENDIF*) 
    IF  ( a_returncode = 0 )
    THEN
        BEGIN
        d_datatype := result_datatype;
        IF  mfirst_free > mb_st_max
        THEN
            a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
        ELSE
            BEGIN
            WITH mb_st^ [mfirst_free] DO
                BEGIN
                etype := st_truth;
                eop   := op_none;
                epos  := cgg04_is_false;
                elen_var      := 0;
                ecol_tab[ 1 ] := chr(0);
                ecol_tab[ 2 ] := chr(0)
                END;
            (*ENDWITH*) 
            mfirst_free := succ(mfirst_free);
            mqual_cnt := succ(mqual_cnt);
            END;
        (*ENDIF*) 
        IF  (curr_n <> 0 )
        THEN
            BEGIN
            colin1.sci_len := 0;
            d_ch_datatype  := dunknown;
            a640not_first_factor( acv, dmli, colin1, curr_n);
            IF  a_returncode = cak_e_parameter
            THEN
                BEGIN
                IF  result_datatype <> dunknown
                THEN
                    BEGIN
                    d_datatype := result_datatype;
                    a_returncode := 0;
                    a640not_first_factor( acv, dmli, colin, curr_n);
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  ( a_returncode = 0 )
            THEN
                BEGIN
                IF  (g01unicode AND
                    (d_datatype = dcha))
                THEN
                    BEGIN
                    a641string_set_operator (acv, op_b_uni_trans,
                          (2*colin1.sci_len)+1, 0, chr(csp_ascii),
                          chr(csp_unicode));
                    colin1.sci_typ := dunicode;
                    colin1.sci_iolen := (2*colin1.sci_len)+1;
                    END;
                (*ENDIF*) 
                IF  d_ch_datatype <> dunknown
                THEN
                    IF  ch_type <> d_ch_datatype
                    THEN
                        IF  ch_type <> dunknown
                        THEN
                            a07_b_put_error (acv,
                                  e_incompatible_datatypes,
                                  a_ap_tree^[ curr_n ].n_pos)
                        ELSE
                            ch_type := d_ch_datatype;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                res_st[0] := mfirst_free - 1;
                IF  (result_datatype in [dunknown, dnonumber]) AND
                    NOT (d_datatype  in [dunknown, dnonumber])
                THEN
                    result_datatype := d_datatype;
                (*ENDIF*) 
                ak641newcolin(colin,colin1);
                END
            (*ENDIF*) 
            END
        ELSE
            IF  mfirst_free > 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, -mb_data_size)
                ELSE
                    BEGIN
                    WITH mb_st^[mfirst_free] DO
                        BEGIN
                        etype       := st_value;
                        eop         := op_none;
                        epos        := a_mblock.mb_data_len + 1;
                        elen_var    := 1;
                        ecol_tab[1] := chr(0);
                        ecol_tab[2] := chr(0);
                        END;
                    (*ENDWITH*) 
                    WITH mb_data^ DO
                        BEGIN
                        mbp_buf[mb_data_len+1] := csp_undef_byte;
                        mb_data_len := mb_data_len + 1
                        END;
                    (*ENDWITH*) 
                    mqual_cnt   := succ(mqual_cnt);
                    mfirst_free := succ(mfirst_free);
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    d_datatype := result_datatype;
    IF  ( a_returncode = 0 )
    THEN
        FOR ind := 1 TO pair_cnt DO
            BEGIN
            res_st[pair_cnt] := mfirst_free - 1;
            WITH mb_st^[ res_st[ind] + 1] DO
                BEGIN
                etype         := st_jump_absolute;
                eop           := op_none;
                epos          := mfirst_free - 1 - (res_st[ind] + 1) ;
                elen_var      := 0;
                ecol_tab[ 1 ] := chr(0);
                ecol_tab[ 2 ] := chr(0);
                END;
            (*ENDWITH*) 
            END;
        (*ENDFOR*) 
&   ifdef TRACE
    (*ENDIF*) 
    t01messblock (ak_sem, 'a641decode  ', acv.a_mblock);
    FOR ind := 1 TO pair_cnt DO
        BEGIN
        t01int4 (ak_sem, 'ind         ', ind);
        t01int4 (ak_sem, ' res_st     ', res_st[ind]);
        END;
    (*ENDFOR*) 
    t01int4 (ak_sem, 'def_st      ', res_st[0]);
    t01int4 (ak_sem, 'result_dtyp ', ord(result_datatype));
    t01int4 (ak_sem, 'colin_dtyp  ', ord(colin.sci_typ));
&   endif
    IF  ( a_returncode = 0 )
    THEN
        IF  g01unicode
        THEN
            IF  ak641unicode_conv_destroyed (mb_st, res_st, pair_cnt)
            THEN
                BEGIN
                colin.sci_typ := dcha;
                colin.sci_iolen := succ(colin.sci_len);
                END;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        IF  mfirst_free >= mb_st_max
        THEN
            a07_b_put_error (acv,
                  e_too_many_mb_stackentries, -mb_st_max)
        ELSE
            BEGIN
            (* PTS 1121505 E.Z. *)
            WITH mb_st^ [startstackentry] DO
                BEGIN
                etype         := st_build_in_func;
                eop_build_in  := op_b_case_start;
                epos          := mfirst_free - startstackentry;
                elen_var      := 0;
                ecol_tab[ 1 ] := chr(0);
                ecol_tab[ 2 ] := chr(0)
                END;
            (*ENDWITH*) 
            WITH mb_st^ [mfirst_free] DO
                BEGIN
                etype         := st_build_in_func;
                eop_build_in  := op_b_case_stop;
                epos          := 0;
                elen_var      := pair_cnt;
                ecol_tab[ 1 ] := chr(0);
                ecol_tab[ 2 ] := chr(0)
                END;
            (*ENDWITH*) 
            mfirst_free := succ(mfirst_free);
            mqual_cnt := succ(mqual_cnt);
            IF  d_join
            THEN
                BEGIN
                first_tabno := 0;
                FOR ind := succ(startstackentry) TO pred(mfirst_free) DO
                    IF  mb_st^ [ind].etype in [ st_fixkey, st_varkey,
                        st_fixcol, st_varcol,
                        st_varlongchar ]
                    THEN
                        IF  first_tabno = 0
                        THEN
                            first_tabno := ord(mb_st^ [ind].ecol_tab[2])
                        ELSE
                            IF  first_tabno <> ord(mb_st^ [ind].ecol_tab[2])
                            THEN
                                d_arith_where := true;
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDFOR*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    d_in_case_function := m_in_case_function;
    d_const_value_expr := false;
    IF  d_join
    THEN
        BEGIN
        d_joins.jrc_cnt    := m_joincnt;
        d_joins.jrc_joinarr^[ d_joins.jrc_cnt ].jo_partno := m_jo_partno;
        END;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(* END OF PTS 1117523 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      ak641special_colin (
            VAR colin     : tak00_scolinf;
            max_integer   : tsp00_Int2;
            max_sci_frac  : tsp00_Int2);
 
BEGIN
WITH colin DO
    BEGIN
    sci_len   := max_integer + max_sci_frac;
    sci_iolen := (sci_len + 1) DIV 2 + 2;
    sci_frac  := max_sci_frac;
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641special_func (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      no_more_fixed : boolean;
      curr_n        : integer;
      value_cnt     : integer;
      colin1        : tak00_scolinf;
      op            : tgg00_StackOpBuildIn;
      ch_type       : tsp00_DataType;
      d_type        : tsp00_DataType;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    curr_n         := n_lo_level;
    colin.sci_len  := 0;
    colin.sci_frac := 0;
    d_ch_datatype := dunknown;
    (*d_datatype    := dunknown;*)
    a640factor ( acv, dmli, colin, curr_n );
    no_more_fixed  := (colin.sci_frac = csp_float_frac);
    ch_type := d_ch_datatype;
    d_type  := d_datatype;
    value_cnt := 1;
    IF  a_returncode = 0
    THEN
        BEGIN
        WHILE ( a_ap_tree^[ curr_n ].n_sa_level <> 0 )
              AND ( a_returncode = 0 ) DO
            BEGIN
            curr_n := a_ap_tree^[ curr_n ].n_sa_level;
            colin1.sci_len  := 0;
            colin1.sci_frac := 0;
            d_ch_datatype   := dunknown;
            a640not_first_factor( acv, dmli, colin1, curr_n);
&           ifdef TRACE
            t01int4 (ak_sem, 'colsci-typ V', ord(colin.sci_typ));
            t01int4 (ak_sem, 'co1sci-typ V', ord(colin1.sci_typ));
            t01int4 (ak_sem, 'n_pos      V', a_ap_tree^[ curr_n ].n_pos);
            t01int4 (ak_sem, 'colsci-len V', colin.sci_len);
            t01int4 (ak_sem, 'co1sci-len V', colin1.sci_len);
            t01int4 (ak_sem, 'colsci-fra V', colin.sci_frac);
            t01int4 (ak_sem, 'co1sci-fra V', colin1.sci_frac);
&           endif
            IF  d_ch_datatype <> dunknown
            THEN
                IF  ch_type <> d_ch_datatype
                THEN
                    IF  ch_type <> dunknown
                    THEN
                        a07_b_put_error (acv, e_incompatible_datatypes,
                              a_ap_tree^[ curr_n ].n_pos)
                    ELSE
                        ch_type := d_ch_datatype;
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
            IF  (d_type         in [dunknown, dnonumber]) AND
                NOT (d_datatype in [dunknown, dnonumber])
            THEN
                BEGIN
                colin := colin1;
                d_type := d_datatype;
                END;
            (*ENDIF*) 
            IF  (colin1.sci_typ = dfixed) AND NOT (no_more_fixed)
            THEN
                BEGIN
                IF  (colin.sci_frac < colin1.sci_frac)
                THEN
                    BEGIN
                    IF  (colin.sci_len - colin.sci_frac) <
                        (colin1.sci_len - colin1.sci_frac)
                    THEN
                        WITH colin1 DO
                            ak641special_colin ( colin,
                                  sci_len - sci_frac, sci_frac)
                        (*ENDWITH*) 
                    ELSE
                        WITH colin DO
                            ak641special_colin ( colin,
                                  sci_len - sci_frac, colin1.sci_frac);
                        (*ENDWITH*) 
                    (*ENDIF*) 
                    END
                ELSE
                    IF  (colin.sci_len - colin.sci_frac) <
                        (colin1.sci_len - colin1.sci_frac )
                    THEN
                        WITH colin1 DO
                            ak641special_colin ( colin,
                                  sci_len - sci_frac, colin.sci_frac)
                        (*ENDWITH*) 
                    ELSE
                        WITH colin DO
                            ak641special_colin ( colin,
                                  sci_len - sci_frac, sci_frac);
                        (*ENDWITH*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  colin.sci_len > csp_fixed
                THEN
                    WITH colin DO
                        BEGIN
                        sci_len   := csp_fixed;
                        sci_frac  := csp_float_frac;
                        sci_typ   := dfloat;
                        sci_iolen := (sci_len + 1) DIV 2 + 2;
                        no_more_fixed := true;
                        END
                    (*ENDWITH*) 
                (*ENDIF*) 
                END
            ELSE
                IF  (colin1.sci_typ in [ ddate, dtime, dtimestamp ]) AND
                    (d_datatype     in [ ddate, dtime, dtimestamp ]) AND
                    (d_datatype <> colin1.sci_typ)
                THEN
                    a07_b_put_error (acv, e_incompatible_datatypes,
                          a_ap_tree^[ curr_n ].n_pos)
                ELSE
                    BEGIN
                    IF  (colin.sci_len < colin1.sci_len)
                    THEN
                        BEGIN
                        colin.sci_len   := colin1.sci_len;
                        colin.sci_iolen := colin1.sci_iolen;
                        END;
                    (*ENDIF*) 
                    IF  colin1.sci_typ in [ dfloat, dvfloat ]
                    THEN
                        BEGIN
                        colin.sci_typ   := dvfloat;
                        colin.sci_frac  := csp_float_frac;
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            value_cnt := value_cnt + 1
            END;
        (*ENDWHILE*) 
        WITH a_mblock, mb_qual^ DO
            IF  a_returncode = 0
            THEN
                IF  mfirst_free > mb_st_max
                THEN
                    a07_b_put_error (acv,
                          e_too_many_mb_stackentries, -mb_st_max)
                ELSE
                    BEGIN
                    (* This is commented out by krischan at 27.9.94.   *)
                    (* I think, you can't set the result type to char  *)
                    (* without changing the value from internal format *)
                    (* to an external one. But since I'm not sure, I   *)
                    (* just changed it into a comment.                 *)
                    (* IF  d_datatype in [ ddate, dtime, dtimestamp ]  *)
                    (*    THEN                                         *)
                    (*    BEGIN                                        *)
                    (*    d_datatype := dcha;                          *)
                    (*    colin.sci_typ := d_datatype;                 *)
                    (*    END;                                         *)
                    CASE n_symb OF
                        s_greatest :
                            op := op_b_greatest;
                        s_least :
                            op := op_b_least;
                        s_value :
                            op := op_b_value;
                        END;
                    (*ENDCASE*) 
                    WITH mb_st^ [mfirst_free] DO
                        BEGIN
                        etype         := st_build_in_func;
                        eop_build_in  := op;
                        epos          := 0;
                        elen_var      := value_cnt;
                        ecol_tab[ 1 ] := chr(0);
                        ecol_tab[ 2 ] := chr(0)
                        END;
                    (*ENDWITH*) 
                    mfirst_free := succ(mfirst_free);
                    mqual_cnt := succ(mqual_cnt)
                    END
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDWITH*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
&ifdef TRACE
t01int4 (ak_sem, 'erg col_len ', colin.sci_len);
t01int4 (ak_sem, 'erg col_iole', colin.sci_iolen);
t01int4 (ak_sem, 'erg col_frac', colin.sci_frac);
t01int4 (ak_sem, 'erg col_typ ', ord(colin.sci_typ));
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641check_datetime(
            VAR acv  : tak_all_command_glob;
            VAR dmli : tak_dml_info;
            datatyp  : tsp00_DataType);
 
BEGIN
&ifdef trace
t01int4 (ak_sem, 'datatyp     ', ord (datatyp));
&endif
WITH acv, dmli, a_mblock, mb_qual^, mb_st^ [mfirst_free] DO
    IF  mfirst_free > mb_st_max
    THEN
        a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
    ELSE
        BEGIN
        a_date_time_used := true;
        etype            := st_build_in_func;
        eop_build_in     := op_b_check_format;
        (* PTS 1118400 E.Z. *)
        eformat := a_dt_format;
        edatatype := datatyp;
        elanguage := a_ak_language;
        elength   := 0;
        mfirst_free   := succ(mfirst_free);
        mqual_cnt     := succ(mqual_cnt)
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(* PTS 1111577 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      a641_get_name (
            VAR acv           : tak_all_command_glob;
            part_ptr          : tsp1_part_ptr;
            buf_pos           : tsp00_Int4;
            buf_len           : tsp00_Int2;
            get_schema        : boolean;
            objecttype        : tsp00_Int2;
            VAR returned_name : tsp00_KnlIdentifier);
 
CONST
      c_inclusiveSerial = true;
 
VAR
      ok               : boolean;
      kl_gr            : boolean;
      one_c            : char;
      i                : tsp00_Int4;
      start            : tsp00_Int4;
      put_node         : tsp00_Int2;
      last_node        : tsp00_Int2;
      err_char_no      : tsp00_Int4;
      temp_cmd_len     : tsp00_Int4;
      i_buf_len        : tsp00_Int4;
      auth_node        : integer;
      uni_err          : tsp8_uni_error;
      temp_cmd_ptr     : tsp1_part_ptr;
      scvh             : tak_scanner_glob;
      authid           : tsp00_KnlIdentifier;
      object_ident     : tsp00_KnlIdentifier;
      sparr            : tak_syspointerarr;
      sys_buf          : tak_sysbufferaddress;
      domain_ref       : tak_sysbufferaddress;
      domain_def       : tak_sysbufferaddress;
      priv             : tak_privilege;
 
BEGIN
WITH acv DO
    BEGIN
    returned_name := a01_il_b_identifier;
    i_buf_len := buf_len;
    IF  g01unicode
    THEN
        BEGIN
        s80uni_trans (@part_ptr^.sp1p_buf[ buf_pos ], i_buf_len, csp_unicode,
              @part_ptr^.sp1p_buf[ buf_pos ], i_buf_len, csp_unicode,
              [ uni_change_to_upper ], uni_err, err_char_no);
        IF  uni_err <> uni_ok
        THEN
            a07_b_put_error (acv, e_unknown_multibyte_set, 1)
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        i     := buf_pos;
        kl_gr := true;
        WHILE i < buf_pos + buf_len DO
            BEGIN
            start := i;
            IF  kl_gr
            THEN
                BEGIN
                WHILE (i < buf_pos + buf_len) AND
                      (part_ptr^.sp1p_buf[ i ] <> csp_ascii_double_quote) DO
                    i := succ (i);
                (*ENDWHILE*) 
                one_c := part_ptr^.sp1p_buf[ i ]
                END
            ELSE
                WHILE (i < buf_pos + buf_len) AND
                      (part_ptr^.sp1p_buf[ i ] <> one_c) DO
                    i := succ (i);
                (*ENDWHILE*) 
            (*ENDIF*) 
            IF  i >= buf_pos + buf_len
            THEN
                i := buf_pos + buf_len;
            (*ENDIF*) 
            IF  kl_gr
            THEN
                s30map (g02codetables.tables[ cgg04_up_ascii ],
                      part_ptr^.sp1p_buf, start,
                      part_ptr^.sp1p_buf, start, i - start+1);
            (*ENDIF*) 
            kl_gr := NOT kl_gr;
            i     := succ(i)
            END;
        (*ENDWHILE*) 
        END;
    (*ENDIF*) 
    temp_cmd_ptr := a_cmd_part;
    temp_cmd_len := a_cmd_part^.sp1p_buf_len;
    scvh := a_scv;
    IF  a_returncode = 0
    THEN
        BEGIN
        (* to be able to use a01_next_symbol : *)
        a_cmd_part               := part_ptr;
        a_cmd_part^.sp1p_buf_len := buf_pos + i_buf_len - 1;
        WITH a_scv DO
            BEGIN
            sc_symb             := s_unknown;
            sc_newpos           := buf_pos;
            sc_sypos            := buf_pos;
            sc_states           := [ scs_pack ];
            sc_double_quote     := 0;
            END;
        (*ENDWITH*) 
        ok := false;
        authid := a01_il_b_identifier;
        object_ident := a01_il_b_identifier;
        a01_next_symbol (acv);
        IF  a_scv.sc_symb = s_identifier
        THEN
            BEGIN
            a02_put_identifier (acv, put_node, put_node);
            IF  a_returncode = 0
            THEN
                BEGIN
                IF  (a_scv.sc_symb = s_point) AND
                    (acv.a_scv.sc_newpos < buf_pos + i_buf_len - 1)
                THEN
                    BEGIN
                    a01_next_symbol (acv);
                    IF  a_scv.sc_symb = s_identifier
                    THEN
                        BEGIN
                        a_ap_tree^[put_node].n_symb := s_authid;
                        a02_put_identifier (acv, a_ap_tree^[put_node].n_sa_level,
                              last_node);
                        IF  a_returncode = 0
                        THEN
                            BEGIN
                            auth_node := put_node;
                            a06get_username (acv, auth_node, authid);
                            a05identifier_get (acv, last_node, a_ap_tree^[last_node].n_length,
                                  object_ident);
                            END
                        (*ENDIF*) 
                        END
                    ELSE
                        a07_b_put_error (acv, e_missing_identifier, buf_pos);
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    a05identifier_get (acv, put_node, a_ap_tree^[put_node].n_length,
                          object_ident);
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END
        ELSE
            a07_b_put_error (acv, e_missing_identifier, buf_pos);
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  a_returncode = 0
    THEN
        BEGIN
        (* compare vak63 *)
&       ifdef TRACE
        t01int4 (ak_sem, 'objecttype  ', objecttype);
        t01int4 (ak_sem, 'cak_ctable  ', ord(cak_ctable));
&       endif
        CASE chr(objecttype) OF
            cak_cprivproc :
                BEGIN
                IF  authid = a01_il_b_identifier
                THEN
                    authid := a_curr_user_name;
                (*ENDIF*) 
                IF  a12dbproc_exist (acv, authid, object_ident, d_release, sys_buf)
                THEN
                    ok := true
                (*ENDIF*) 
                END;
            cak_cdomain :
                BEGIN
                a12get_domain (acv, authid, object_ident, put_node,
                      domain_ref, domain_def);
                IF  a_returncode = 0
                THEN
                    ok := true
                ELSE
                    IF  a_returncode =
                        a071_return_code (e_unknown_domainname, a_sqlmode)
                    THEN
                        BEGIN
                        a_returncode := 0;
                        a_errorpos   := 0;
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            cak_csequence :
                BEGIN
                IF  a23exist_sequence (acv, put_node, NOT c_inclusiveSerial,
                    sys_buf, authid, object_ident)
                THEN
                    ok := true
                ELSE
                    IF  a_returncode =
                        a071_return_code (e_unknown_sequencename, a_sqlmode)
                    THEN
                        BEGIN
                        a_returncode := 0;
                        a_errorpos   := 0;
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            cak_cusage :
                BEGIN
                (* Synonym *)
                IF  a06_table_exist (acv, d_release, authid, object_ident,
                    sparr, NOT c_get_all)
                THEN
                    IF  sparr.psynfound
                    THEN
                        ok := true
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            cak_cviewdesc, cak_ctable:
                BEGIN
                IF  a06_table_exist (acv, d_release, authid, object_ident,
                    sparr, NOT c_get_all)
                THEN
                    IF  (
                        (chr(objecttype) = cak_cviewdesc) AND
                        (NOT sparr.psynfound)             AND
                        (sparr.pbasep^.sbase.btablekind in [ tonebase,
                        tview, tcomplexview, tshow_view ])
                        )
                        OR
                        (
                        (chr(objecttype) = cak_ctable) AND
                        (NOT sparr.psynfound)          AND
                        (sparr.pbasep^.sbase.btablekind in [twithkey,
                        twithoutkey, tcatalog_table ])
                        )
                    THEN
                        BEGIN
                        a06_get_priv (acv, sparr.pbasep, priv);
                        IF  NOT (
                            (priv.priv_all_set   = [  ]) AND
                            (priv.priv_col_exist = [  ]))
                        THEN
                            ok := true
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            END;
        (*ENDCASE*) 
        IF  ok
        THEN
            IF  get_schema
            THEN
                returned_name := authid
            ELSE
                returned_name := object_ident;
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    a_cmd_part               := temp_cmd_ptr;
    a_cmd_part^.sp1p_buf_len := temp_cmd_len;
    a_scv := scvh;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641get_name (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      curr_n           : integer;
      curr_name_len    : tsp00_Int4;
      returned_name    : tsp00_KnlIdentifier;
      colinf           : tak00_columninfo;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    IF  g01unicode
    THEN
        d_datatype := dunicode
    ELSE
        d_datatype := dcha;
    (*ENDIF*) 
    curr_n := n_lo_level;
    colin.sci_len   := sizeof (tsp00_KnlIdentifier) DIV 2;
    colin.sci_frac  := 0;
    colin.sci_typ   := d_datatype;
    colin.sci_iolen := (colin.sci_len * a01char_size) + 1;
    IF  a_ap_tree^[curr_n].n_symb = s_string_literal
    THEN
        BEGIN
        a641_get_name (acv, a_cmd_part,
              a_ap_tree^[curr_n].n_pos, a_ap_tree^[curr_n].n_length,
              (n_symb = s_get_schema), n_subproc, returned_name);
        IF  a_returncode = 0
        THEN
            WITH a_mblock, mb_qual^, mb_data^ DO
                BEGIN
                IF  mfirst_free > mb_st_max
                THEN
                    a07_b_put_error (acv,
                          e_too_many_mb_stackentries, -mb_st_max)
                ELSE
                    BEGIN
                    WITH mb_st^ [mfirst_free] DO
                        BEGIN
                        etype         := st_value;
                        eop           := op_none;
                        epos          := mb_data_len+1;
                        elen_var      := 0;
                        ecol_tab[ 1 ] := chr(0);
                        ecol_tab[ 2 ] := chr(0);
                        END;
                    (*ENDWITH*) 
                    IF  returned_name = a01_il_b_identifier
                    THEN
                        BEGIN
                        mbp_buf[mb_data_len+1] := csp_undef_byte;
                        mb_st^ [mfirst_free].elen_var := 1;
                        END
                    ELSE
                        BEGIN
                        IF  d_datatype = dunicode
                        THEN
                            mbp_buf[mb_data_len+1] := csp_unicode_def_byte
                        ELSE
                            mbp_buf[mb_data_len+1] := csp_ascii_blank;
                        (*ENDIF*) 
                        curr_name_len := s30lnr_defbyte (@returned_name,
                              mbp_buf[mb_data_len+1], 1, sizeof(returned_name));
                        mb_st^ [mfirst_free].elen_var := curr_name_len + 1;
                        SAPDB_PascalMove ('VAK641',  10,    
                              sizeof(returned_name), mb_data_size, @returned_name, 1,
                              @mbp_buf, mb_data_len+2, curr_name_len,
                              a_returncode);
                        END;
                    (*ENDIF*) 
                    mb_data_len := mb_data_len + mb_st^ [mfirst_free].elen_var;
                    mfirst_free := succ (mfirst_free);
                    mqual_cnt   := succ (mqual_cnt)
                    END;
                (*ENDIF*) 
&               ifdef TRACE
                t01moveobj (ak_sem, mbp_buf, 1, mb_data_len);
&               endif
                END
            (*ENDWITH*) 
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        colinf := a642standard_colinfo;
        WITH colinf DO
            BEGIN
            cdatatyp := d_datatype;
            (* two identifier each with '"' and '.' in between  *)
            (* "ident1"."ident2"  + some room for '"' somewhere in the middle *)
            cdatalen := sizeof(tsp00_KnlIdentifier) + 10;
            cinoutlen := succ(cdatalen * a01char_size);
            END;
        (*ENDWITH*) 
        d_colptr := @colinf;
        a640factor (acv, dmli, colin, curr_n);
        d_colptr := NIL;
        IF  a_returncode = 0
        THEN
            BEGIN
            WITH d_sparr.pparsp^.sparsinfo,
                 p_pars_infos[ p_cnt_infos ] DO
                BEGIN
                fp_kind          := fp_get_name_value;
                fp_sc_symbol     := n_symb;
                fp_objecttype[1] := chr(n_subproc);
                END;
            (*ENDWITH*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641col_function (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR frec  : tak_factorrec;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      rem_change_date_time : boolean;
      startstack           : integer;
      const_value_expr     : boolean;
      st_begin             : tsp00_Int2;
      st_end               : tsp00_Int2;
      st_index             : tsp00_Int2;
      expr_st_cnt          : tsp00_Int2;
 
BEGIN
&ifdef TRACE
t01int4 (ak_sem, 'act_node    ', act_node);
&endif
WITH acv, a_ap_tree^[ act_node ], dmli, frec DO
    BEGIN
    IF  a_allow_functions = tf_no_func
    THEN
        a_allow_functions := tf_func;
    (*ENDIF*) 
    const_value_expr   := d_const_value_expr;
    d_const_value_expr := true;
    st_begin           := a_mblock.mb_qual^.mfirst_free;
    st_index           := d_param_st_index;
    CASE n_symb OF
        s_greatest, s_least, s_value,
        s_upper, s_lower, s_initcap,
        (* PTS 1122828 E.Z. *)
        s_translate :
            BEGIN
            END;
        s_ascii:
            IF  (a_sqlmode = sqlm_oracle)
            THEN
                d_colptr := NIL;
            (*ENDIF*) 
        OTHERWISE
            d_colptr := NIL;
        END;
    (*ENDCASE*) 
    rem_change_date_time := d_change_date_time;
    CASE n_symb OF
        s_adddate, s_subdate, s_next_day,
        s_addtime, s_subtime,
        s_datediff, s_timediff,
        s_makedate, s_maketime,
        s_dayofweek, s_dayofyear,
        s_weekofyear, s_dayofmonth,
        s_monthname, s_dayname,
        s_year, s_month, s_day,
        s_hour, s_minute, s_second, s_microsecond,
        s_days,
        s_add_months, s_last_day, s_months_between,
        s_hex, s_trunc, s_round,
        s_length, s_vsize,
        s_num, s_to_number, s_mbcs,
        (* PTS 1105409 E.Z. *)                s_new_time,
        s_value,
        s_decode,
        s_greatest, s_least,
        (* PTS 1117523 E.Z. *)
        s_case :
            BEGIN
            (* before we thaught this:     *)
            (* for all these we do nothing *)
            (* with d_change_date_time.    *)
            (* but in case 'chr(func(datecol))' *)
            (* this will result in wrong results*)
            (* or error -8006                   *)
            d_change_date_time := false;
            END;
        s_func_date, s_func_time, s_func_timestamp,
        s_func_char, s_to_char, s_to_24_char, s_user_func, s_method_call :
            d_change_date_time := false;
        OTHERWISE
            d_change_date_time := true;
        END;
    (*ENDCASE*) 
&   ifdef TRACE
    t01int4 (ak_sem, 'd_change_dat', ord(d_change_date_time));
&   endif
    CASE n_symb OF
        s_func_char :
            ak641char(acv, dmli, colin, act_node, fr_error);
        s_chr :
            IF  d_datatype = dnumber
            THEN
                fr_error := true
            ELSE
                ak641chr (acv, dmli, act_node, colin, fr_error);
            (*ENDIF*) 
        s_chr_ora:
            IF  d_datatype = dnumber
            THEN
                fr_error := true
            ELSE
                ak641chr_ora (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_concat :
            IF  d_datatype = dnumber
            THEN
                fr_error := true
            ELSE
                ak641concat ( acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_datediff :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641datediff (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_days :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641days (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_digits :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641digits (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_expand :
            IF  d_datatype = dnumber
            THEN
                fr_error := true
            ELSE
                ak641expand ( acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_space :
            IF  d_datatype = dnumber
            THEN
                fr_error := true
            ELSE
                ak641space ( acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_fixed :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641fixed_float (acv, dmli, colin, n_symb, act_node);
            (*ENDIF*) 
        s_float :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                IF  a_sqlmode = sqlm_internal
                THEN
                    ak641fixed_float (acv, dmli, colin, n_symb, act_node)
                ELSE
                    ak641float (acv, dmli, colin, act_node);
                (*ENDIF*) 
            (*ENDIF*) 
        s_func_date ,
        s_func_time ,
        s_func_timestamp :
            IF  (d_datatype in [ dunknown, dnonumber, dcha ]) OR
                ((n_symb = s_func_date) AND (d_datatype = ddate)) OR
                ((n_symb = s_func_time) AND (d_datatype = dtime)) OR
                ((n_symb = s_func_timestamp) AND
                (d_datatype = dtimestamp))
            THEN
                BEGIN
                IF  n_symb in [ s_func_date, s_func_time ]
                THEN
                    ak641timedate(acv, dmli, colin, act_node, fr_error)
                ELSE
                    ak641timestamp (acv, dmli, frec, colin,
                          act_node, fr_error);
                (*ENDIF*) 
                IF  (d_datatype in [ ddate, dtime, dtimestamp ]) AND
                    d_change_date_time
                THEN
                    BEGIN
                    startstack := a_mblock.mb_qual^.mfirst_free;
&                   ifdef TRACE
                    t01int4 (ak_sem, 'sci.len colf', colin.sci_len);
&                   endif
                    a65ch_format (acv, dmli, startstack,
                          colin, d_datatype, d_datatype);
&                   ifdef TRACE
                    t01int4 (ak_sem, 'sci.len   2 ', colin.sci_len);
&                   endif
                    colin.sci_iolen := colin.sci_len+1;
                    END;
                (*ENDIF*) 
                END
            ELSE
                fr_error := true;
            (*ENDIF*) 
        s_hex :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641hex (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_hextoraw :
            IF  NOT (d_datatype in [dchb, dunknown, dnonumber])
            THEN
                fr_error := true
            ELSE
                ak641_hextoraw (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_index :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641index (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_length,
        s_vsize :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641length_vsize (acv, dmli, colin, act_node,
                      n_symb, fr_error);
            (*ENDIF*) 
        s_makedate :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = dtime) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641makedate (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_maketime :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = ddate) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641maketime (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_mapchar :
            IF  d_datatype = dnumber
            THEN
                fr_error := true
            ELSE
                ak641mapchar (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_mbcs :
            IF  NOT (d_datatype in [dchb, dunknown, dnonumber])
            THEN
                fr_error := true
            ELSE
                ak641mbcs (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_noround :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641noround (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_num, s_to_number :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641num (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_soundex :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641soundex (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_substr :
            IF  d_datatype = dnumber
            THEN
                fr_error := true
            ELSE
                ak641substr (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_left, s_right :
            IF  d_datatype = dnumber
            THEN
                fr_error := true
            ELSE
                ak641leftright (acv, dmli, colin, act_node, n_symb);
            (*ENDIF*) 
        s_timediff :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = ddate) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641timediff (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_greatest, s_least, s_value :
            ak641special_func (acv, dmli, colin, act_node);
        s_decode :
            ak641decode_func (acv, dmli, colin, act_node);
        s_adddate, s_subdate :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = dtime) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641addsubdate (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_addtime, s_subtime :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = ddate) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641addsubtime (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_ascii :
            IF  (a_sqlmode = sqlm_internal)
            THEN
                IF  (d_datatype = dnumber) OR
                    (d_datatype = dchb)
                THEN
                    fr_error := true
                ELSE
                    ak641conversion (acv, dmli, colin, act_node, fr_error)
                (*ENDIF*) 
            ELSE
                ak641ascii (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        (* PTS 1122828 E.Z. *)
        s_upper, s_lower, s_initcap, s_unicode:
            IF  (d_datatype = dnumber) OR
                (d_datatype = dchb)
            THEN
                fr_error := true
            ELSE
                ak641conversion (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_day, s_hour, s_minute, s_microsecond,
        s_month, s_second, s_year :
            ak641datetime(acv, dmli, colin, act_node, fr_error);
        s_lpad, s_rpad,
        s_lfill, s_rfill:
            IF  (d_datatype = dnumber)
            THEN
                fr_error := true
            ELSE
                ak641lrpad (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_to_date:
            IF  (d_datatype = dnumber)
            THEN
                fr_error := true
            ELSE
                ak641to_date (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_to_char, s_to_24_char :
            IF  (d_datatype = dnumber) OR
                (d_datatype = dtimestamp)
            THEN
                fr_error := true
            ELSE
                ak641to_char (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_trim , s_ltrim, s_rtrim:
            ak641trim (acv, dmli, colin, act_node, fr_error);
        s_replace, s_translate:
            IF  (d_datatype = dnumber)
            THEN
                fr_error := true
            ELSE
                ak641replace_translate (acv, dmli, colin,
                      act_node, fr_error);
            (*ENDIF*) 
        s_dayofweek, s_dayofyear, s_weekofyear, s_dayofmonth :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641of (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_monthname, s_dayname :
            IF  ((d_datatype <> dnonumber) AND
                ( d_datatype <> dunknown)  AND
                ( d_datatype <> dcha)      AND
                ( d_datatype <> dunicode))
            THEN
                fr_error := true
            ELSE
                ak641name (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_integer, s_abs, s_ceil, s_floor, s_sign, s_sqrt,
        s_exp, s_ln, s_sin, s_sinh, s_cos, s_cosh, s_tan, s_tanh,
        s_cot, s_acos, s_asin, s_atan, s_log10, s_degrees, s_radians :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                BEGIN
                ak641integer (acv, dmli, colin, act_node);
                END;
            (*ENDIF*) 
        s_mod_func , s_power, s_log, s_atan2:
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641mod_power (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_trunc, s_round :
            IF  (d_datatype <> dnumber) AND (d_datatype <> dunknown)
                AND
                (((d_datatype <> dtimestamp) AND (d_datatype <> dnonumber)) OR
                (a_sqlmode <> sqlm_oracle))
            THEN
                fr_error := true
            ELSE
                ak641truncround (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_add_months, s_next_day :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = ddate) OR
                (d_datatype = dtime) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641_add_months (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_new_time :
            IF  (d_datatype <> dtimestamp) AND
                (d_datatype <> dnonumber) AND
                (d_datatype <> dunknown)
            THEN
                fr_error := true
            ELSE
                ak641new_time (acv, dmli, colin, act_node, fr_error);
            (*ENDIF*) 
        s_last_day :
            IF  ((d_datatype = dnumber) OR
                (d_datatype = ddate) OR
                (d_datatype = dtime) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641last_day (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_months_between :
            IF  ((d_datatype <> dnumber) AND (d_datatype <> dunknown))
            THEN
                fr_error := true
            ELSE
                ak641months_between (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_toidentifier :
            IF  ((d_datatype = dnumber)   OR
                (d_datatype = ddate)      OR
                (d_datatype = dtime)      OR
                (d_datatype = dtimestamp) OR
                (d_datatype = dchb))
            THEN
                fr_error := true
            ELSE
                ak641toidentifier (acv, dmli, colin, act_node);
            (*ENDIF*) 
        s_user_func, s_method_call :
            BEGIN
            ak641user_defined_func (acv, dmli, colin, act_node);
            dmli.d_colptr := NIL;
            END;
        (* PTS 1111577 E.Z. *)
        s_get_schema, s_get_name :
            ak641get_name (acv, dmli, colin, act_node);
        (* PTS 1117523 E.Z. *)
        s_case :
            ak641case_func (acv, dmli, colin, act_node);
        (* PTS 1127075 *)
        s_updated :
            ak641isupdatedcolumn (acv, dmli, colin, act_node);
        OTHERWISE
            BEGIN
&           ifdef TRACE
            t01int4 (ak_sem, 'act_node    ', act_node);
            t01int4 (ak_sem, 'n_proc      ', ord(n_proc));
            t01int4 (ak_sem, 'n_symb      ', ord(n_symb));
            t01int4 (ak_sem, 'n_length    ', n_length);
&           endif
            END
        END;
    (*ENDCASE*) 
    CASE n_symb OF
        s_mapchar, s_func_char, s_concat, s_expand, s_space,
        s_length, s_substr, s_left, s_right,
        (* PTS 1122828 E.Z. *)
        s_ascii, s_upper, s_lower, s_initcap, s_trim, s_rtrim,
        s_replace, s_to_24_char, s_vsize,
        s_ltrim, s_translate, s_lpad, s_rpad, s_lfill, s_rfill :
            d_ch_datatype := dunknown;
        OTHERWISE
            BEGIN
            END
        END;
    (*ENDCASE*) 
&   ifdef trace
    t01int4 (ak_sem, 'node       C', act_node);
    t01int4 (ak_sem, 'colin.typ  C', ord(colin.sci_typ));
    t01int4 (ak_sem, 'change_d   C', ord (d_change_date_time));
&   endif
    d_change_date_time := rem_change_date_time;
&   ifdef TRACE
    t01int4 (ak_sem, 'dm_datatype ', ord(d_datatype));
&   endif
    IF  (a_returncode = cak_e_parameter)
    THEN
        (* PTS 1118316 E.Z. *)
        BEGIN
        a_returncode := 0;
        a07_b_put_error (acv, e_without_datatypes,
              a_ap_tree^[ n_lo_level ].n_pos)
        END
    ELSE
        IF  fr_error
        THEN
            a07_b_put_error (acv, e_incompatible_datatypes,
                  a_ap_tree^[ n_lo_level ].n_pos)
        ELSE
            IF  a_returncode = 0
            THEN
                WITH a_mblock, mb_qual^ DO
                    IF  d_const_value_expr
                    THEN
                        BEGIN
                        IF  (mb_st^ [mfirst_free - 1].eop <> op_none) OR
                            (n_symb = s_cast)
                        THEN
                            IF  d_param_st_index > st_index
                            THEN
                                BEGIN
                                expr_st_cnt := a_mblock.mb_qual^.mfirst_free
                                      - st_begin;
                                IF  (expr_st_cnt <= 255) AND
                                    (
                                    (a_variable_input AND
                                    (a_init_ddl = no_ddl)) OR
                                    (mb_data_len -
                                    mb_st^ [st_begin].epos + 1 >= colin.sci_iolen)
                                    )
                                THEN
                                    a651code_for_const_param_expr (acv, dmli,
                                          st_begin, expr_st_cnt);
                                (*ENDIF*) 
                                END
                            ELSE
                                BEGIN
                                st_end := mfirst_free - 1;
                                a651value_calculate ( acv, st_begin, st_end,
                                      colin.sci_typ = dchb, d_like,
                                      colin.sci_iolen,
                                      a_ap_tree^[ act_node ].n_pos);
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        d_const_value_expr := const_value_expr
                        END;
                    (*ENDIF*) 
                (*ENDWITH*) 
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641stack_for_op_b_chr (
            VAR acv           : tak_all_command_glob;
            VAR dmli           : tak_dml_info;
            VAR colin          : tak00_scolinf;
            first_int          : tsp00_Int2;
            keep_datatype      : tsp00_DataType);
 
VAR
      oldlen   : integer;
      newlen   : integer;
      res_len  : tsp00_Int2;
      dummy    : boolean;
 
BEGIN
WITH acv, dmli, colin DO
    BEGIN
&   ifdef TRACE
    t01int4 (ak_sem, 'keep_datatyp', ord(keep_datatype));
&   endif
    oldlen := sci_len;
    IF  first_int = 0
    THEN
        CASE sci_typ OF
            dfixed,
            dfloat,
            dvfloat :
                BEGIN
                a641_get_length (colin, res_len, dummy);
                sci_len := res_len;
                END;
            OTHERWISE
            END
        (*ENDCASE*) 
    ELSE
        sci_len := first_int;
    (*ENDIF*) 
    newlen := sci_len;
    sci_iolen := succ(sci_len);
    IF  ((acv.a_returncode = 0) AND
        (colin.sci_typ in [ dfixed, dfloat, dvfloat, dboolean ]))
    THEN
        BEGIN
        IF  colin.sci_typ = dboolean
        THEN
            BEGIN
            IF  sci_len > 255
            THEN
                newlen := 1;
            (*ENDIF*) 
            a641string_set_operator (acv, op_b_chr, colin.sci_frac,
                  oldlen, chr(3), chr(newlen))
            END
        ELSE
            BEGIN
            IF  sci_len > 255
            THEN
                newlen := oldlen + 6;
            (*ENDIF*) 
            a641string_set_operator (acv, op_b_chr, colin.sci_frac,
                  oldlen, chr(2), chr(newlen))
            END;
        (*ENDIF*) 
        IF  ((acv.a_returncode = 0) AND
            (sci_len <> newlen))
        THEN
            a641string_set_operator (acv, op_b_expand, first_int+1,
                  newlen, chr(0), chr(0))
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  keep_datatype = dcha
    THEN
        BEGIN
        keep_datatype := dcha;
        colin.sci_typ := dcha;
        END
    ELSE
        IF  keep_datatype = dunicode
        THEN
            BEGIN
            a641string_set_operator (acv, op_b_uni_trans, 0, 0,
                  chr(csp_ascii), chr(csp_unicode));
            colin.sci_typ := dunicode;
            sci_iolen := 2 * sci_len + 1
            END
        ELSE
            IF  keep_datatype in [ dunknown, dnonumber ]
            THEN
                IF  colin.sci_typ = dchb
                THEN
                    keep_datatype := dchb
                ELSE
                    IF  g01code.ctype = csp_ascii
                    THEN
                        BEGIN
                        colin.sci_typ := dcha;
                        keep_datatype := dcha
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    d_datatype := keep_datatype;
    sci_frac := 0;
    IF  colin.sci_typ in [ dfixed, dfloat, dvfloat ]
    THEN
        sci_typ := dcha
    ELSE
        IF  first_int <> 0
        THEN
            a641string_set_operator (acv, op_b_checklen,
                  pred(sci_iolen), 0, chr(0), chr(0));
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a641string_set_operator (
            VAR acv      : tak_all_command_glob;
            operator     : tgg00_StackOpBuildIn;
            destlength   : integer;
            sourcelength : integer;
            tab1         : char;
            tab2         : char);
 
BEGIN
IF  acv.a_returncode = 0
THEN
    WITH acv.a_mblock, mb_qual^ DO
        IF  mfirst_free > mb_st_max
        THEN
            a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
        ELSE
            BEGIN
            mqual_cnt := succ (mqual_cnt);
            WITH mb_st^ [mfirst_free] DO
                BEGIN
                etype         := st_build_in_func;
                eop_build_in  := operator;
                epos          := sourcelength;
                elen_var      := destlength;
                ecol_tab[ 1 ] := tab1;
                ecol_tab[ 2 ] := tab2
                END;
            (*ENDWITH*) 
            mfirst_free := succ (mfirst_free)
            END
        (*ENDIF*) 
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641dbyte_string_set_operator (
            VAR acv      : tak_all_command_glob;
            operator     : tgg00_StackOpBuildIn;
            destlength   : integer;
            sourcelength : integer;
            c2           : tsp00_C2);
 
BEGIN
IF  acv.a_returncode = 0
THEN
    WITH acv.a_mblock, mb_qual^ DO
        IF  mfirst_free > mb_st_max
        THEN
            a07_b_put_error (acv, e_too_many_mb_stackentries, -mb_st_max)
        ELSE
            BEGIN
            mqual_cnt := succ (mqual_cnt);
            WITH mb_st^ [mfirst_free] DO
                BEGIN
                etype         := st_build_in_func;
                eop_build_in  := operator;
                epos          := sourcelength;
                elen_var      := destlength;
                ecol_tab      := c2;
                END;
            (*ENDWITH*) 
            mfirst_free := succ (mfirst_free)
            END
        (*ENDIF*) 
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641isupdatedcolumn (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      changeDateTime : boolean;
      currSt         : integer;
      curr_n         : integer;
 
BEGIN
WITH acv, a_ap_tree^[ act_node ], dmli DO
    BEGIN
    d_ch_datatype       := dunknown;
    curr_n              := n_lo_level;
    colin.sci_len       := 0;
    d_type_long_allowed := true;
    changeDateTime      := d_change_date_time;
    d_change_date_time  := false;
    a640factor (acv, dmli, colin, curr_n);
    d_change_date_time  := changeDateTime;
    d_type_long_allowed := false;
    IF  acv.a_returncode = 0
    THEN
        BEGIN
        currSt := acv.a_mblock.mb_qual^.mfirst_free-1;
        acv.a_mblock.mb_st^[currSt].eop := op_eq; (* force new stack entry for st_op *)
        a65_set_operator (acv, op_updated);
        acv.a_mblock.mb_st^[currSt].eop := op_none;
        acv.a_mblock.mb_st^ [acv.a_mblock.mb_qual^.mfirst_free-1].ecol_pos :=
              dmli.d_colbuf^.creccolno;
        WITH colin DO
            BEGIN
            sci_len    := 1;
            sci_frac   := 0;
            sci_iolen  := 2;
            sci_typ    := dboolean;
            sci_cprops := [ ctopt ];
            d_datatype := dboolean;
            END;
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641user_defined_func (
            VAR acv   : tak_all_command_glob;
            VAR dmli  : tak_dml_info;
            VAR colin : tak00_scolinf;
            act_node  : integer);
 
VAR
      inMethodParam   : boolean;
      schemaGiven     : boolean;
      is_in_out       : integer;
      curr_n          : integer;
      proc_no         : integer;
      value_cnt       : integer;
      init_qual_cnt   : integer;
      init_first_free : integer;
      init_part2_len  : integer;
      io_len          : integer;
      first_free      : integer;
      ix              : integer;
      ownerNode       : integer;
      dummy_iolen     : tsp00_Int2;
      curr_data_pos   : tsp00_Int4;
      param_cnt       : tsp00_Int4;
      pEvalDataLength : tak_sysbufferaddress;
      pSurrogate      : ^tgg00_Surrogate;
      schemaId        : tgg00_Surrogate;
      proc_colin      : tak00_scolinf;
      param_colin     : tak00_scolinf;
      param_colinfo   : tak00_columninfo;
      keep_datatype   : tsp00_DataType;
      convert_t       : tak_convert_type;
      schema          : tsp00_KnlIdentifier;
      func_name       : tsp00_KnlIdentifier;
      proc_ptr        : tak_sysbufferaddress;
      proc_buf        : tak_sysbufferaddress;
      constParams     : tak_colinteger;
 
BEGIN
WITH acv, dmli DO
    BEGIN
    a05identifier_get (acv, act_node, sizeof (func_name), func_name);
    curr_n      := acv.a_ap_tree^[act_node].n_lo_level;
    schemaGiven := acv.a_ap_tree^[curr_n].n_proc = a262;
    IF  schemaGiven
    THEN
        BEGIN
        act_node  := curr_n;
        ownerNode := acv.a_ap_tree^[curr_n].n_sa_level;
        a06get_username   (acv, ownerNode, schema);
        END
    ELSE
        schema := a01_il_b_identifier;
    (*ENDIF*) 
    proc_no           := 1;
    proc_buf          := NIL;
    is_in_out         := 0;
    inMethodParam     := d_in_method_param;
    d_in_method_param := true;
    IF  NOT a12dbfunc_exist (acv, schema, func_name, d_fix, proc_buf)
    THEN
        a07_b_put_error (acv, e_unknown_functionname,
              a_ap_tree^[ act_node ].n_pos)
    ELSE
        BEGIN
        IF  NOT (dmli.d_view)                      AND
            (acv.a_parsingForSharedSql)            AND
            (acv.a_prepareHandle <> NIL)           AND
            (acv.a_queryrewrite_done = No_Rewrite)
        THEN
            BEGIN
            IF  schemaGiven
            THEN
                a103GetSchemaId (acv, schema, 1, schemaId)
            ELSE
                schemaId := cgg_zero_id;
            (*ENDIF*) 
            IF  NOT a101_StoreTableInfo (acv, schemaId, func_name, schemaGiven, acv.a_prepareHandle)
            THEN
                acv.a_parsingForSharedSql := false; (* a07ak_system_error (acv, 660, 2) *)
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  NOT proc_buf^.smethod.me_deterministic
        THEN
            d_const_value_expr := false;
        (*ENDIF*) 
        param_cnt := proc_buf^.smethod.me_param_cnt;
        keep_datatype := d_datatype;
        WITH a_mblock, mb_qual^ DO
            BEGIN
            init_qual_cnt   := mqual_cnt;
            init_first_free := mfirst_free;
            init_part2_len  := mb_data_len
            END;
        (*ENDWITH*) 
        value_cnt   := 0;
        curr_n      := a_ap_tree^[act_node].n_lo_level;
        ak641describe_output_param (acv, dmli, proc_buf, colin, is_in_out, param_colinfo);
        IF  colin.sci_len <= 0
        THEN
            BEGIN
            FOR ix := 1 TO param_cnt DO
                constParams[ix] := cak_is_undefined;
            (*ENDFOR*) 
            pEvalDataLength := a262EvalOutputLenProlog (acv, proc_buf^.smethod.me_surrogate)
            END
        ELSE
            pEvalDataLength := NIL;
        (*ENDIF*) 
        IF  is_in_out > 0
        THEN (* virtual last output parameter *)
            param_cnt := param_cnt + 1;
        (*ENDIF*) 
        dummy_iolen := 0;
        IF  a65_datatypes_ok (acv, dmli, keep_datatype, dummy_iolen,
            colin.sci_typ, NOT c_is_subquery,
            1, 1, NOT c_convert, convert_t)
        THEN
            BEGIN
            (* analyze input parameters *)
            WHILE (curr_n <> 0 ) AND
                  (a_returncode = 0) DO
                BEGIN
&               ifdef trace
                t01int4 (ak_sem, 'curr_n      ', curr_n);
&               endif
                value_cnt          := value_cnt + 1;
                ak641describe_param (acv, dmli,
                      proc_buf, value_cnt, proc_colin, param_colinfo);
                first_free          := acv.a_mblock.mb_qual^.mfirst_free;
                param_colin.sci_len := 0;
                a640not_first_factor (acv, dmli, param_colin, curr_n);
                param_colin.sci_com_type := proc_colin.sci_com_type;
                IF  (param_colin.sci_typ <> proc_colin.sci_typ) AND
                    (proc_colin.sci_typ  in [ddate, dtime, dtimestamp])
                THEN
                    IF  param_colin.sci_typ = dcha
                    THEN
                        a641check_datetime (acv, dmli,
                              proc_colin.sci_typ)
                    ELSE
                        a07_b_put_error (acv, e_incompatible_datatypes,
                              a_ap_tree^[curr_n].n_pos);
                    (*ENDIF*) 
                (*ENDIF*) 
                dmli.d_colptr := NIL;
&               ifdef trace
                t01int4 (ak_sem, 'func dtype  ',
                      ord (proc_colin.sci_typ));
                t01int4 (ak_sem, 'found dtype ',
                      ord (param_colin.sci_typ));
                t01int4 (ak_sem, 'func len    ',
                      ord (proc_colin.sci_len));
                t01int4 (ak_sem, 'found len   ',
                      ord (param_colin.sci_len));
&               endif
                IF  a_returncode = 0
                THEN
                    BEGIN
                    IF  pEvalDataLength <> NIL
                    THEN
                        BEGIN
                        IF  (acv.a_mblock.mb_qual^.mfirst_free = first_free + 1) AND
                            (acv.a_mblock.mb_st^[first_free].etype = st_value)
                        THEN
                            constParams[value_cnt] := first_free;
                        (*ENDIF*) 
                        a262SetParameterProperties (acv, pEvalDataLength, value_cnt,
                              param_colin.sci_typ, param_colin.sci_len, param_colin.sci_iolen, param_colin.sci_frac);
                        END;
&                   ifdef cppFunc
                    (*ENDIF*) 
                    ak641emit_param (acv, dmli, proc_buf,
                          value_cnt = is_in_out, proc_colin, first_free);
&                   else
                    ak641emit_param (acv, proc_colin);
&                   endif
                    END;
                (*ENDIF*) 
                curr_n := a_ap_tree^[curr_n].n_sa_level;
                END;
            (*ENDWHILE*) 
            END;
&       ifdef trace
        (*ENDIF*) 
        t01int4 (ak_sem, 'value_cnt   ', value_cnt);
&       endif
        WHILE ((value_cnt < param_cnt - 1)
              OR (value_cnt = 0))
              AND
              (a_returncode = 0) DO
            BEGIN
            (* missing parameters are substituted by NULL values *)
            value_cnt := value_cnt + 1;
            IF  param_cnt > 1
            THEN
                ak641describe_param
                      (acv, dmli, proc_buf, value_cnt, proc_colin, param_colinfo)
            ELSE
                BEGIN
                proc_colin.sci_len := 2;
                proc_colin.sci_frac:= 0;
                proc_colin.sci_typ := dunknown;
                END;
            (*ENDIF*) 
            WITH acv.a_mblock, mb_qual^ DO
                BEGIN
                IF  mfirst_free + 1 > 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, -mb_data_size);
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  a_returncode = 0
                THEN
                    BEGIN
                    WITH mb_st^[mfirst_free] DO
                        BEGIN
                        etype       := st_value;
                        eop         := op_none;
                        epos        := a_mblock.mb_data_len + 1;
                        elen_var    := 1;
                        ecol_tab[1] := chr(0);
                        ecol_tab[2] := chr(0);
                        END;
                    (*ENDWITH*) 
                    WITH mb_st^[mfirst_free+1] DO
                        BEGIN
                        etype       := st_result;
                        eop         := op_ascii;
                        epos        := proc_colin.sci_len;
                        elen_var    := proc_colin.sci_frac;
                        ecol_tab[1] :=
                              chr (ord (proc_colin.sci_typ));
                        ecol_tab[2] := chr(0)
                        END;
                    (*ENDWITH*) 
                    IF  (value_cnt = param_cnt - 1) OR
                        (param_cnt = 1            )
                    THEN
                        WITH mb_data^ DO
                            BEGIN
                            curr_data_pos := mb_data_len;
                            mbp_buf[curr_data_pos+1] := csp_undef_byte;
                            mb_data_len := mb_data_len + 1
                            END;
                        (*ENDWITH*) 
                    (*ENDIF*) 
                    mqual_cnt   := mqual_cnt   + 2;
                    mfirst_free := mfirst_free + 2;
                    END
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            END;
        (*ENDWHILE*) 
        IF  a_returncode = 0
        THEN
            BEGIN
            IF  param_cnt = 1
            THEN (* describe output parameter *)
                ak641describe_param (acv, dmli, proc_buf, 1, colin, param_colinfo);
            (*ENDIF*) 
            WITH a_mblock, mb_qual^ DO
                BEGIN
                IF  mfirst_free + 2 >= mb_st_max
                THEN
                    a07_b_put_error (acv,
                          e_too_many_mb_stackentries, -mb_st_max);
                (*ENDIF*) 
                IF  a_returncode = 0
                THEN
                    BEGIN
                    IF  colin.sci_typ = dunknown
                    THEN
                        a07_b_put_error (acv, e_not_implemented, 1)
                    ELSE
                        IF  colin.sci_typ in [dnumber, dfixed, dfloat, dsmallint, dinteger]
                        THEN
                            d_datatype := dnumber
                        ELSE
                            d_datatype := colin.sci_typ;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    d_udt_datatype                 := colin.sci_udt_id;
                    mb_st^[mfirst_free].esurrogate := proc_buf^.smethod.me_surrogate;
                    mqual_cnt                      := mqual_cnt + 2;
                    (* reserve one entry for st_build_in_func entry *)
                    mfirst_free                    := mfirst_free + 2;
                    IF  pEvalDataLength <> NIL
                    THEN
                        BEGIN
                        a262CalcOutputLen (acv, proc_buf^.smethod, pEvalDataLength, constParams,
                              colin.sci_len, colin.sci_iolen, colin.sci_frac);
                        IF  colin.sci_len  <= 0
                        THEN
                            a07_b_put_error (acv, e_not_implemented, 1)
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  proc_buf^.smethod.me_sql
                    THEN
                        mstack_state := mstack_state + [ssCopyRow_egg00];
                    (*ENDIF*) 
                    WITH mb_st^ [mfirst_free-1] DO
                        BEGIN
                        etype         := st_build_in_func;
                        eop_build_in  := op_b_user_def_func;
                        epos          := value_cnt;
                        elen_var      := colin.sci_len;
                        ecol_tab[ 1 ] := chr(0);
                        ecol_tab[ 2 ] := chr(ord(proc_buf^.smethod.me_sql))
                        END;
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    d_in_method_param := inMethodParam;
    a10rel_sysinfo (proc_buf);
&   ifdef trace
    ;
    t01qual (ak_sem, a_mblock.mb_qual^)
&         endif
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641describe_output_param (
            VAR acv       : tak_all_command_glob;
            VAR dmli      : tak_dml_info;
            proc_buf      : tak_sysbufferaddress;
            VAR scolinf   : tak00_scolinf;
            VAR is_in_out : integer;
            VAR colinfo   : tak00_columninfo);
 
BEGIN
a12output_parameter (acv, proc_buf, is_in_out, scolinf);
IF  acv.a_returncode = 0
THEN
    BEGIN
    IF  scolinf.sci_typ in [dsmallint, dinteger]
    THEN
        scolinf.sci_typ := dfixed;
    (* PTS 1000985/1001162 E.Z. *)
    (*ENDIF*) 
    colinfo                    := a642standard_colinfo;
    colinfo.cdatatyp           := scolinf.sci_typ;
    colinfo.cdatalen           := scolinf.sci_len;
    colinfo.cinoutlen          := scolinf.sci_iolen;
    colinfo.cdatafrac          := scolinf.sci_frac;
    colinfo.ccolstack.elen_var := scolinf.sci_iolen;
    IF  colinfo.cdatalen  <= 0
    THEN
        dmli.d_colptr := NIL
    ELSE
        dmli.d_colptr := @colinfo
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641describe_param  (
            VAR acv       : tak_all_command_glob;
            VAR dmli      : tak_dml_info;
            proc_buf      : tak_sysbufferaddress;
            param_no      : integer;
            VAR scolinf   : tak00_scolinf;
            VAR colinfo   : tak00_columninfo);
 
BEGIN
scolinf.sci_len := 0;
a12describe_param  (acv, proc_buf, param_no, scolinf);
IF  acv.a_returncode = 0
THEN
    BEGIN
    colinfo                    := a642standard_colinfo;
    colinfo.cdatatyp           := scolinf.sci_typ;
    colinfo.cdatalen           := scolinf.sci_len;
    colinfo.cinoutlen          := scolinf.sci_iolen;
    colinfo.cdatafrac          := scolinf.sci_frac;
    colinfo.ccolstack.elen_var := scolinf.sci_iolen;
    IF  colinfo.cdatalen  <= 0
    THEN
        dmli.d_colptr := NIL
    ELSE
        dmli.d_colptr := @colinfo;
    (*ENDIF*) 
    CASE scolinf.sci_typ OF
        dsmallint, dinteger :
            BEGIN
            scolinf.sci_typ := dfixed;
            dmli.d_datatype := dnumber
            END;
        dfixed, dfloat :
            dmli.d_datatype := dnumber;
        OTHERWISE
            BEGIN
            dmli.d_datatype     := scolinf.sci_typ;
            dmli.d_udt_datatype := scolinf.sci_udt_id;
            IF  dmli.d_datatype in [dcha, dunicode]
            THEN
                dmli.d_expand := scolinf.sci_len
            (*ENDIF*) 
            END;
        END;
    (*ENDCASE*) 
    dmli.d_ch_datatype := dunknown;
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641emit_param (
            VAR acv            : tak_all_command_glob;
            VAR proc_colin     : tak00_scolinf);
 
BEGIN
WITH acv.a_mblock, mb_qual^ DO
    IF  mfirst_free > mb_st_max
    THEN
        a07_b_put_error (acv,
              e_too_many_mb_stackentries, -mb_st_max)
    ELSE
        BEGIN
        mqual_cnt := succ(mqual_cnt);
        WITH mb_st^[mfirst_free] DO
            BEGIN
            etype    := st_result;
            IF  (proc_colin.sci_typ in [dfixed, dfloat]) AND (proc_colin.sci_len > 0)
            THEN
                BEGIN
                eop      := op_fixed; (* force complete length on interpreter stack *)
                epos     := proc_colin.sci_len;
                elen_var := proc_colin.sci_frac;
                END
            ELSE
                BEGIN
                eop      := op_copy;
                epos     := 0;
                elen_var := 0;
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        mfirst_free := mfirst_free + 1;
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak641VirtualLongColumnNotImplemented (
            VAR acv  : tak_all_command_glob;
            errorPos : integer);
 
VAR
      msg : tsp00_C20;
 
BEGIN
msg := 'virtual long column ';
a07_const_b_put_error (acv, e_not_implemented, errorPos,
      @msg, sizeof(msg));
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
