/*!
 * \file    SQL_Statement.cpp
 * \author  PeterG (GoertzP)
 * \brief   C++ SQL Class: Statement
 */

/*

    ========== licence begin  GPL
    Copyright (c) 2003-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



*/


/************************************************************************/
/* Includes                                                             */
/************************************************************************/

#include "geo00.h"

#ifndef __OMS_DEFINES_HPP
#include "Oms/OMS_Defines.h"
#endif

#ifndef SQL_HPP
#include "CppSQL/SQL_.hpp"
#endif

#ifndef SQL_STATEMENT_H
#include "CppSQL/SQL_Statement.hpp"
#endif

#ifndef SQL_SESSIONCONTEXT_HPP
#include "CppSQL/SQL_SessionContext.hpp"
#endif

#ifndef SQL_COLUMN_HPP
#include "CppSQL/SQL_Column.hpp"
#endif

#ifndef SQL_COLUMNDESC_HPP
#include "CppSQL/SQL_ColumnDesc.hpp"
#endif

/* PTS 1123241 */
#ifndef VSP001_H
#include "vsp001.h"
#endif


#ifndef HIN201_H
#include "PacketInterface/PIn_Part.h"
#endif

#include "hsp81.h"
#include "SAPDBCommon/SAPDB_MemCopyMove.hpp"

/* PTS 1119960 */
#ifndef HSP41_H
#include "hsp41.h"
#endif

/* PTS 1130628 */
#ifndef HSP77_H
#include "hsp77.h"
#endif


/************************************************************************/
/* Auto pointer                                                         */
/************************************************************************/

template<class S, class T> class auto_ptr 
{
    public:
        explicit auto_ptr(S *s, T *p = NULL)  {
            sessCtx = s;
            pointee = p; 
        };
        auto_ptr<S,T>& operator=(T *p) { 
            pointee = p; 
            return *this;
        };
        T* operator() (){
            return pointee;
        };
        T* release() 
        {
            T* p = pointee;
            sessCtx = NULL;
            pointee = NULL;
            return p;
        };
        ~auto_ptr() { 
            if (sessCtx)
              sessCtx->deallocate( pointee ); 
        };
    private:
        S* sessCtx;
        T* pointee;
};


/************************************************************************/
/* Helper functions                                                     */
/************************************************************************/

/* primitive token generator */

inline char * strntok ( char * s, const char c, int & n ) {
  char * pc = s;
  for ( ;*pc == c; pc++ );
  for ( n = 0; *(pc + n) != '\0'; n++ ) {
    if (*(pc + n) == c) break;
  }
  return pc;
}

inline tsp81_UCS2Char * strntok ( tsp81_UCS2Char * s,
                                  const tsp81_UCS2Char c,
                                  int & n) {
  tsp81_UCS2Char * pc = s;
  for ( ; pc->s == c.s; pc++ );
  for ( n = 0; (*(pc + n)).s != 0; n++ ) {
    if ((*(pc + n)).s == c.s) break;
  }
  return pc;
}

/* upper case conversion of a null terminated string s */

inline void strupper(char * s) {
  char * c = s;
  while (*c) {
    if (islower(*c)) {
      *c = toupper (*c);
    }
    c++;
  }
}

inline void strupper( tsp81_UCS2Char * s, int size, int swapped ) {
  if (swapped) {
    sp81UCS2SwappedStringToupper (s,size);
  }
  else {
    sp81UCS2StringToupper (s,size);
  }
}

/* compare a token s generated by strntok to a null terminated string t */

static int eqtok( const char * s, const char * t, int n ) {
  int i;
  const char * cs = s;
  const char * ct = t;
  
  for ( i = 0; (i < n) && (*cs != '\0'); i++) {
    if (*ct++ != *cs++) {
      i = n;
    }
  }

  return (i == n && !*ct);
}

static int eqtok( const tsp81_UCS2Char * s, const char * t,
                  int n, int swapped ) {
  int i;
  const tsp81_UCS2Char * cs = s;
  tsp81_UCS2Char         ct[64];
  unsigned int           converted;

  sp81ASCIItoUCS2( ct, sizeof(ct)/2 , swapped, &converted,
                   (const unsigned char*)t, (unsigned int)strlen(t) );

  for ( i = 0; (i < n) && (cs->s != 0); i++, cs++ ) {
    if (ct[i].s != cs->s) {
      i = n;
    }
  }

  return (i == n && ! ct[i].s);
}


/************************************************************************/
/* Implementation of class SQL_Statement                                */
/************************************************************************/

SQL_Statement::structSqlDA::structSqlDA() {
  inp_col_idx      = 0;
  sqlmax           = 0;
  sqln             = 0;
  sqlvar           = NULL;
  long_col_num     = 0;
  longDesc         = NULL;
  fix_buf_len      = 0;
  orig_fix_buf_len = 0;
  has_long_in_col  = 0;
  has_long_out_col = 0;
}

/*----------------------------------------------------------------------*/

SQL_Statement::SQL_Statement( SQL_SessionContext * sessContext,
                              const char * stmt ) :
  m_session_context(*sessContext)
, m_ref_count(1)
, m_prepared(false)
, m_stmt_type(ECO521_SQL)
, m_unicode(0)
, m_reset_parms(true) /* PTS 1109560 */
, m_mass_cmd(false)          /* PTS 1119960 */
, m_mass_fetch(false)        /* PTS 1119960 */
, m_fetch_count(0)           /* PTS 1119960 */
, m_max_fetch_count(0)       /* PTS 1119960 */
, m_data_ptr(NULL)           /* PTS 1119960 */
, m_multi_sing_exec(false)   /* PTS 1119960 */
, m_multi_sing_fetch(false)  /* PTS 1119960 */
, m_multi_sing_insert(false) /* PTS 1119960 */
, m_longdesc_ptr(NULL)     /* PTS 1123241 */
, m_longdata_notnull(NULL) /* PTS 1123241 */
, m_longdata_inplace(NULL) /* PTS 1123241 */
, m_longdesc_pos(0)        /* PTS 1123241 */
, m_longdesc_cnt(0)        /* PTS 1123241 */
, m_longdesc_cntr(0)       /* PTS 1123241 */
, m_longdata_ptr(NULL)     /* PTS 1123241 */
, m_longdata_buf(false)    /* PTS 1123241 */
{
  m_res_tabname[0] = '\0';
  tsp00_KnlIdentifierc  token;
  int i,n;

  if (stmt) {
    m_statement.c = REINTERPRET_CAST( char*, m_session_context.allocate(strlen(stmt) + 1));
    if (m_statement.c) {
      strcpy( m_statement.c, stmt );
      char * s = strntok( m_statement.c, ' ', n );
      strncpy( token, s, n);
      token[n] = '\0';
      strupper(token);
#     if !defined (EXT_CLIENT_SQL)
        if ( eqtok( token, (char*)"COMMIT", n ) ||
             eqtok( token, (char*)"ROLLBACK", n )) {
          s[0] = 'X';
        }
#     endif

      if (eqtok( token, (char*)"FETCH", n)) {
        static char * dir[5] = {(char*)"FIRST", (char*)"LAST",
                                (char*)"NEXT", (char*)"PREV", (char*)"SAME"},
                    * pos = (char*)"POS",
                    * into[3] = {(char*)"INTO", (char*)"USING", (char*)"DESCRIPTOR"};
        s = strntok( s + n, ' ', n );
        strncpy( token, s, n );
        token[n] = '\0';
        strupper(token);
        
        for ( i = 0; i < 5; i++ ) {
          if (eqtok( token, dir[i], n )) {
            i = 5;
          }
        }
        if (i > 5) {
          s = strntok( s + n, ' ', n );
          strncpy( token, s, n );
          token[n] = '\0';
          strupper(token);
        }
        else {
          if (eqtok( s, pos, n )) {
            s = strntok( s + n, ' ', n );
            if (*s == '(') {
              s = strntok( s, ')', n );
              if (*(s + n) == ')') {
                s++;
              }
              s = strntok( s + n, ' ', n );
              strncpy( m_res_tabname, s, n );
              m_res_tabname[n] = '\0';
              strncpy( token, s, n );
              token[n] = '\0';
              strupper(token);
            }
          }
        }

        if (!( eqtok( token, into[0], n ) ||
               eqtok( token, into[1], n ) )) {
          s = strntok( s + n, ' ', n );
          strncpy( m_res_tabname, s, n );
          m_res_tabname[n] = '\0';
          strncpy( token, s, n);
          token[n] = '\0';
          strupper(token);
        }

//#if defined(COMATABILITY)
        /* following code for compatability only                       */
        /* describe isn't supported anymore                            */

        if ( eqtok(token, into[0], n) ||
             eqtok(token, into[1], n) ) {
          if (eqtok( token, into[1], n )) {
            for ( i = 0; i < n; i++ ) {
              s[i] = ' ';
            }
          }
          s = strntok( s + n, ' ', n );
          strncpy( token, s, n );
          token[n] = '\0';
          strupper(token);
          if (eqtok( token, into[2], n )) {
            //m_stmt_type = ECO521_FETCH_DESCRIBE; only usefull if column names are needed
            for ( i = 0; i < n; i++ ) {
              s[i] = ' ';
            }
            s = strntok( s + n, ' ', n );
            strncpy( m_res_tabname, s, n );
            m_res_tabname[n] = '\0';
          }
        }

//#endif

      }
    }
  }
  else {
    m_statement.c = REINTERPRET_CAST( char *, m_session_context.allocate(1) );
    *m_statement.c = 0;
  }
}

/*----------------------------------------------------------------------*/

SQL_Statement::SQL_Statement( SQL_SessionContext * sessContext,
                              const DbpTypeUnicode * stmt) :
  m_session_context(*sessContext)
, m_ref_count(1), m_prepared(false)
, m_stmt_type(ECO521_SQL)
, m_unicode(1)
, m_reset_parms(true) /* PTS 1109560 */
, m_mass_cmd(false)          /* PTS 1119960 */
, m_mass_fetch(false)        /* PTS 1119960 */
, m_fetch_count(0)           /* PTS 1119960 */
, m_max_fetch_count(0)       /* PTS 1119960 */
, m_data_ptr(NULL)           /* PTS 1119960 */
, m_multi_sing_exec(false)   /* PTS 1119960 */
, m_multi_sing_fetch(false)  /* PTS 1119960 */
, m_multi_sing_insert(false) /* PTS 1119960 */
, m_longdesc_ptr(NULL)     /* PTS 1123241 */
, m_longdata_notnull(NULL) /* PTS 1123241 */
, m_longdata_inplace(NULL) /* PTS 1123241 */
, m_longdesc_pos(0)        /* PTS 1123241 */
, m_longdesc_cnt(0)        /* PTS 1123241 */
, m_longdesc_cntr(0)       /* PTS 1123241 */
, m_longdata_ptr(NULL)     /* PTS 1123241 */
, m_longdata_buf(false)    /* PTS 1123241 */
{
  m_res_tabname[0] = '\0';
  tsp81_UCS2Char uc_token[sizeof(tsp00_KnlIdentifierc)];
  int i,n;
  tsp81_UCS2Char UCS2Char;
  tsp81_UCS2Char UCS2Blank;
  int            UCS2Swap;
  UCS2Blank.s = 32;
  UCS2Swap =  ( UCS2Blank.c[0] ? 1 : 0 );

  if (stmt) {
    m_statement.uc = REINTERPRET_CAST( tsp81_UCS2Char*,
                                       m_session_context.allocate( (sp81UCS2strlen((tsp81_UCS2Char*)stmt) + 1) * 2));
    if (m_statement.uc) {
      sp81UCS2strcpy( m_statement.uc, (tsp81_UCS2Char*)stmt );
      tsp81_UCS2Char * s = strntok( m_statement.uc, UCS2Blank, n );
      sp81UCS2strncpy( uc_token, s, sizeof(uc_token)/sizeof(tsp81_UCS2Char) );
      uc_token[n].s = 0;
      strupper( uc_token, sizeof(uc_token)/2, UCS2Swap);
#     if !defined (EXT_CLIENT_SQL)
        if ( eqtok(uc_token, (char*)"COMMIT",   n, UCS2Swap) || 
             eqtok(uc_token, (char*)"ROLLBACK", n, UCS2Swap) ) {
          s->s = 'X';
        }
#     endif

      if (eqtok( (tsp81_UCS2Char*)uc_token, (char*)"FETCH", n, UCS2Swap )) {
        static char * dir[5] = {(char*)"FIRST", (char*)"LAST",
                                (char*)"NEXT", (char*)"PREV", (char*)"SAME"},
                    * pos = (char*)"POS",
                    * into[3] = {(char*)"INTO", (char*)"USING", (char*)"DESCRIPTOR"};
        s = strntok( s + n, UCS2Blank, n );
        sp81UCS2strncpy( uc_token, s, n );
        uc_token[n].s = 0;
        strupper( uc_token, sizeof(uc_token)/2, UCS2Swap );
        
        for ( i = 0; i < 5; i++ ) {
          if (eqtok( uc_token, dir[i], n, UCS2Swap) ) {
            i = 5;
          }
        }
        if (i > 5) {
          s = strntok( s + n, UCS2Blank, n );
          sp81UCS2strncpy( uc_token, s, n );
          uc_token[n].s = 0;
          strupper( uc_token, sizeof(uc_token)/2, UCS2Swap );
        }
        else {
          if (eqtok (s, pos, n,UCS2Swap)) {
            s = strntok (s + n, UCS2Blank, n);
            if (s->s == '(') {
              UCS2Char.s = ')';
              s = strntok (s, UCS2Char, n);
              if ((s + n)->s == ')') {
                s++;
              }
              s = strntok( s + n, UCS2Blank, n );
/***** TO DO TO DO            strncpy(m_res_tabname, s, n); */
/***** TO DO            m_res_tabname[n] = '\0';            */
              sp81UCS2strncpy( uc_token, s, n );
              uc_token[n].s = 0;
              strupper( uc_token, sizeof(uc_token)/2, UCS2Swap );
            }
          }
        }

        if (!( eqtok( uc_token, into[0], n, UCS2Swap ) ||
               eqtok( uc_token, into[1], n, UCS2Swap ) )) {
          s = strntok( s + n, UCS2Blank, n );
/*          strncpy(m_res_tabname, s, n);
          m_res_tabname[n] = '\0';   */
          sp81UCS2strncpy( uc_token, s, n );
          uc_token[n].s = 0;
          strupper( uc_token, sizeof(uc_token)/2, UCS2Swap );
        }
#       if defined (COMATABILITY)
          /* following code for compatability only                       */
          /* describe isn't supported anymore                            */
          if ( eqtok( token, into[0], n, UCS2Swap ) ||
               eqtok( token, into[1], n, UCS2Swap ) ) {
            for ( i = 0; i < n; i++ ) {
              s[i] = ' ';
            }
            s = strntok( s + n, UCS2Blank, n );
            strncpy( token, s, n );
            token[n] = '\0';
            strupper(token);
            if (eqtok( token, into[1], n, UCS2Swap )) {
              m_stmt_type = ECO521_FETCH_DESCRIBE;
              for ( i = 0; i < n; i++ ) {
                s[i] = ' ';
              }
              s = strntok( s + n, UCS2Blank, n );
              strncpy( m_res_tabname, s, n );
              m_res_tabname[n] = '\0';
            }
          }
#       endif

      }
    }
  }
  else {
    m_statement.uc = REINTERPRET_CAST( tsp81_UCS2Char *,
                                       m_session_context.allocate(2) );
    *m_statement.dc = 0;
  }
}

/*----------------------------------------------------------------------*/

#if defined (EXT_CLIENT_SQL)

int SQL_Statement::connect( const char * hostname, const char * dbname,
                            const char * user, const char * passwd,
                            const char * isolevel) {
  return m_session_context.connect( this, hostname, dbname, user,
                                    passwd, isolevel );
}

#endif

/*----- PTS 1119960 ----------------------------------------------------*/

int SQL_Statement::addResCntParm( PIn_Part * part, int swi, int cnt ) {
  int rc = 1; 

  //int swi = 0;
  if (swi == 0) {
    part->AddParameterArg( NULL, 1, 0, 7, ' ');
  }
  else if (swi == 1) {
    char buf[6];
    tsp00_NumError num_err;
    s41p4int( buf, 1, 32000, num_err); /* ??? */
    part->AddParameterArg( buf, 1, 7, 7, 0);
  }
  else if (swi == 2) {
    char buf[6];
    tsp00_NumError num_err;
    s41p4int( buf, 1, cnt, num_err);
    part->AddParameterArg( buf, 1, 7, 7, 0);
  }

  return rc;
}

/*----------------------------------------------------------------------*/

int SQL_Statement::addInputParms(PIn_Part * part) {
  int rc = 1;
  int i, prmNo;

  m_sqlda.fix_buf_len = 0;
  if (m_sqlda.has_long_in_col) {
    /* calculate "fixed column length" to get the first position
       to be used by long columns                                */
    for ( i = 0; (i < m_sqlda.sqln) && rc; i++ ) {
      SqlCol * var = m_sqlda.sqlvar + i;
      if (m_sqlda.fix_buf_len < var->m_desc->sfi.sp1i_bufpos +
                                var->m_desc->sfi.sp1i_in_out_len) {
        m_sqlda.fix_buf_len = var->m_desc->sfi.sp1i_bufpos +
                              var->m_desc->sfi.sp1i_in_out_len - 1;
      }
      switch (var->m_desc->sfi.sp1i_data_type) {
        case dstra :
        case dstrb :
        case dstruni :
        case dlonguni :
          (m_sqlda.longDesc + var->m_desc->long_idx)->varPos = 0;
          (m_sqlda.longDesc + var->m_desc->long_idx)->bufPos =
            var->m_desc->sfi.sp1i_bufpos;
          break;
        default :
          break;
      }
    }
  }

  /* PTS 1130628, writing extended error info in case of VCHAR_ASCII violation */
  for ( i = 0; (i < m_sqlda.sqln) && (rc > 0); i++ ) {
    prmNo = i + 1;
    SqlCol * var = m_sqlda.sqlvar + i;
    if ( var->sqlInOut() == sp1io_input ||
         var->sqlInOut() == sp1io_inout ) {
      rc = var->m_desc->addParmToBuffer( part, m_session_context,
                                         *this, prmNo );
    }
  }
# if !defined (EXT_CLIENT_SQL)
    if (rc < 0) {
      dumpBadAsciidataInfo( prmNo, 0, -rc );
      rc = 0;
    }
# endif

  return rc;
}

/*----- PTS 1119960 ----------------------------------------------------*/

int SQL_Statement::addInputParms( int offset, PIn_Part * part ) {
  int rc = 1; 
  int i;

  m_sqlda.fix_buf_len = 0;
  if (m_sqlda.has_long_in_col) {
    /* calculate "fixed column length" to get the first position
       to be used by long columns                                */
    for ( i = 0; (i < m_sqlda.sqln) && rc; i++ ) {
      SqlCol * var = m_sqlda.sqlvar + offset + i;
      if (m_sqlda.fix_buf_len < var->m_desc->sfi.sp1i_bufpos +
                                var->m_desc->sfi.sp1i_in_out_len) {
        m_sqlda.fix_buf_len = var->m_desc->sfi.sp1i_bufpos +
                              var->m_desc->sfi.sp1i_in_out_len - 1;
      }
      switch (var->m_desc->sfi.sp1i_data_type) {
        case dstra :
        case dstrb :
        case dstruni :
        case dlonguni :
          (m_sqlda.longDesc + var->m_desc->long_idx )->varPos = 0;
          (m_sqlda.longDesc + var->m_desc->long_idx )->bufPos =
            var->m_desc->sfi.sp1i_bufpos;
          break;
        default :
          break;
      }
    }
  }

  for ( i = 0; (i < m_sqlda.sqln) && rc; i++ ) {
    SqlCol * var = m_sqlda.sqlvar + offset + i;
    if ( var->sqlInOut() == sp1io_input ||
         var->sqlInOut() == sp1io_inout ) {
      rc = var->m_desc->addParmToBuffer( part, m_session_context,
                                         *this, i + 1 );
    }
  }
  return rc;
}

/*----- PTS 1119960 ----------------------------------------------------*/

int SQL_Statement::addMassInputParms( PIn_Part * part,
                                      int start_row, int row_cnt ) {
  int rc = 1;
  int i = 0, len = 0, js = 0, end_row = 0;

  for ( int ix = 0; ix < m_sqlda.sqln; ix++) {
    len += m_sqlda.sqlvar[ix].m_desc->sfi.sp1i_in_out_len;
  }

  //m_sqlda.orig_fix_buf_len = m_sqlda.fix_buf_len;
  m_sqlda.fix_buf_len = 0;

  /* set short field info */
  if (start_row == 0) {
    js = 1;
    end_row = row_cnt - 1;
    for ( int j = js; j <= end_row; j++ ) {
      for ( int ix = 0; ix < m_sqlda.sqln; ix++ ) {
        int jx = j * m_sqlda.sqln;
        int jlen = j * len;
        setSqlDA_sfi( ix, jx , jlen, &(m_sqlda.sqlvar[ix].m_desc->sfi) );
      }
    }
  }
  else {
    js = start_row;
    end_row = start_row + row_cnt - 1;
    for ( int j = js; j <= end_row; j++ ) {
      for ( int ix = 0; ix < m_sqlda.sqln; ix++ ) {
        int jx = j * m_sqlda.sqln;
        int jlen = (j-start_row) * len;
        setSqlDA_sfi( ix, jx , jlen, &(m_sqlda.sqlvar[ix].m_desc->sfi) );
      }
    }
  }

//  for (int j = 1; j < rcnt; j++) {
//    for (int ix = 0; ix < m_sqlda.sqln; ix++) {
//      int jx = j * m_sqlda.sqln;
//      int jlen = j * len;
//      setSqlDA_sfi(ix, jx , jlen, &(m_sqlda.sqlvar[ix].m_desc->sfi));
//    }
//  }

  /* fill buffer */
  for ( i = start_row; (i < start_row + row_cnt) && rc; i++ ) {
    for ( int j = 0; j < m_sqlda.sqln; j++ ) {
      SqlCol * var = m_sqlda.sqlvar + (i*m_sqlda.sqln) + j;
      rc = var->m_desc->addParmToBuffer( part, m_session_context, *this,
                                         (i*m_sqlda.sqln) + j + 1 );
    }
  }

  return rc;

}

/*----------------------------------------------------------------------*/

int SQL_Statement::addOpenLongDataInput(PIn_Part * part) {
  int rc = 1; 
  for ( int i = 0; (i <= m_sqlda.long_col_num) && rc; i++) {
    SQL_LongDesc * longDescDestPtr = m_sqlda.longDesc + i;
    SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
    int byteLen;
    switch (var->sqlVarType()) {
      case SqlCol::VCHAR_UNICODE :
      case SqlCol::VSTRING_UNICODE :
        byteLen = var->m_desc->vfi.vlen * 2;
        break;
      default :
        byteLen = var->m_desc->vfi.vlen;
    }
    if ( (var->m_desc->vfi.ind == 0) &&
         (longDescDestPtr->varPos < byteLen) &&
         (var->sqlInOut() == sp1io_input ||
          var->sqlInOut() == sp1io_inout) ) {
      m_sqlda.fix_buf_len = part->Length() + sizeof(tsp00_LongDescriptor) + 1;
      longDescDestPtr->bufPos = part->Length() + 1;
      rc = var->m_desc->addOpenLongDataToBuffer( part, m_session_context, *this,
                                                 longDescDestPtr->colIdx + 1 );
    }
  }
  return rc;
}

/*----- PTS 1119960 ----------------------------------------------------*/

int SQL_Statement::addOpenLongDataInput( PIn_Part * part, int offset ) {
  int rc = 1;
  for ( int i = 0; (i <= m_sqlda.long_col_num) && rc; i++) {
    SQL_LongDesc * longDescDestPtr = m_sqlda.longDesc + i;
    SqlCol * var = m_sqlda.sqlvar + offset + longDescDestPtr->colIdx;
    int byteLen;
    switch (var->sqlVarType()) {
      case SqlCol::VCHAR_UNICODE :
      case SqlCol::VSTRING_UNICODE :
        byteLen = var->m_desc->vfi.vlen * 2;
        break;
      default :
        byteLen = var->m_desc->vfi.vlen;
    }
    if ( (var->m_desc->vfi.ind == 0) &&
         (longDescDestPtr->varPos < byteLen) &&
         (var->sqlInOut() == sp1io_input ||
          var->sqlInOut() == sp1io_inout) ) {
      m_sqlda.fix_buf_len = part->Length() + sizeof(tsp00_LongDescriptor) + 1;
      longDescDestPtr->bufPos = part->Length() + 1;
      rc = var->m_desc->addOpenLongDataToBuffer( part, m_session_context, *this,
                                                 longDescDestPtr->colIdx + 1 );
    }
  }
  return rc;
}

/*----------------------------------------------------------------------*/

int SQL_Statement::addOpenLongDataOutput(PIn_Part * part) {
  int rc = 1;
  for ( int i = 0; (i <= m_sqlda.long_col_num) && rc; i++ ) {
    SQL_LongDesc * longDescDestPtr = m_sqlda.longDesc + i;
    SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
    if ( (var->m_desc->vfi.ind >= 0) &&
         (!( vm_lastdata   == longDescDestPtr->dsc.ld_valmode() ||
             vm_alldata    == longDescDestPtr->dsc.ld_valmode() ||
             vm_data_trunc == longDescDestPtr->dsc.ld_valmode() )) &&
         ( var->sqlInOut() == sp1io_output ||
           var->sqlInOut() == sp1io_inout ) ) {
      m_sqlda.fix_buf_len = part->Length() + sizeof(tsp00_LongDescriptor) + 1;
      longDescDestPtr->bufPos = part->Length() + 1;
      rc = var->m_desc->addOpenLongDescriptor( part, m_session_context, *this,
                                               longDescDestPtr->colIdx + 1 );
    }
  }
  return rc;
}

/*----- PTS 1123241 ----------------------------------------------------*/

int SQL_Statement::addOpenLongDataOutputMass(PIn_Part * part) {

  int rc = 1, i, j;

  for ( j = 0; (j < m_sqlda.has_long_out_col) && rc; j++ ) {
    SQL_LongDesc * longDescDestPtr = m_longdesc_ptr +
                                     m_fetch_count*m_sqlda.has_long_out_col + j;
    SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
    bool notnull = *(m_longdata_notnull +
                     m_fetch_count*m_sqlda.has_long_out_col + j);
    if ( (var->m_desc->vfi.ind >= 0) &&
         (!( vm_lastdata   == longDescDestPtr->dsc.ld_valmode() ||
             vm_alldata    == longDescDestPtr->dsc.ld_valmode() ||
             vm_data_trunc == longDescDestPtr->dsc.ld_valmode() )) &&
         ( var->sqlInOut() == sp1io_output || 
           var->sqlInOut() == sp1io_inout ) &&
         notnull ) {
      m_sqlda.fix_buf_len = part->Length() + sizeof(tsp00_LongDescriptor) + 1;
      longDescDestPtr->bufPos = part->Length() + 1;
      rc = var->m_desc->addOpenLongDescriptor( part, m_session_context, *this,
                                               longDescDestPtr->colIdx + 1 );
    }
  }

  for ( i = m_fetch_count + 1; i < m_max_fetch_count; i++ ) {
    for ( j = 0; (j < m_sqlda.has_long_out_col) && rc; j++ ) {
      SQL_LongDesc * longDescDestPtr = m_longdesc_ptr +
                                       i*m_sqlda.has_long_out_col + j;
      SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
      bool notnull = *(m_longdata_notnull + i*m_sqlda.has_long_out_col + j);
      if ( ( var->sqlInOut() == sp1io_output || 
             var->sqlInOut() == sp1io_inout ) && notnull ) {
        m_sqlda.fix_buf_len = part->Length() + sizeof(tsp00_LongDescriptor) + 1;
        longDescDestPtr->bufPos = part->Length() + 1;
        rc = var->m_desc->addOpenLongDescriptorMass( part, m_session_context, *this,
                                                     i*m_sqlda.has_long_out_col + j );
      }
    }
  }

  return rc;

}

/*----------------------------------------------------------------------*/

int SQL_Statement::addInputFinishLongData(PIn_Part * part) {
  int rc = 1;
  SQL_LongDesc * longDescDestPtr = m_sqlda.longDesc;
  SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
  if ( (var->m_desc->vfi.ind == 0) &&
       ( var->sqlInOut() == sp1io_input ||
         var->sqlInOut() == sp1io_inout ) ) {
    m_sqlda.fix_buf_len = -1;
    longDescDestPtr->bufPos = part->Length() + 1;
    rc = var->m_desc->addOpenLongDataToBuffer( part, m_session_context, *this,
                                               longDescDestPtr->colIdx + 1 );
  }
  return rc;
}

/*----- PTS 1119960 ----------------------------------------------------*/

int SQL_Statement::addInputFinishLongData( PIn_Part * part, int offset ) {
  int rc = 1;
  SQL_LongDesc * longDescDestPtr = m_sqlda.longDesc;
  SqlCol * var = m_sqlda.sqlvar + offset + longDescDestPtr->colIdx;
  if ( (var->m_desc->vfi.ind == 0) &&
       ( var->sqlInOut() == sp1io_input ||
         var->sqlInOut() == sp1io_inout ) ) {
    m_sqlda.fix_buf_len = -1;
    longDescDestPtr->bufPos = part->Length() + 1;
    rc = var->m_desc->addOpenLongDataToBuffer( part, m_session_context, *this,
                                               longDescDestPtr->colIdx + 1 );
  }
  return rc;
}

/*----------------------------------------------------------------------*/

void SQL_Statement::reallocColDescs(int new_max) {
  int ix; /* PTS 1119960, short before */
  auto_ptr<SQL_SessionContext,SqlCol> var(&m_session_context);

  var = REINTERPRET_CAST( SqlCol *,
                          m_session_context.allocate(new_max * sizeof(SqlCol)) );

  /* initialize SqlCol Array to avoid ~SqlCol() to use undefined memory */
  for ( ix = 0; ix < new_max; ix++ ) {
    (*(var() + ix)).m_desc = NULL;
  }
  for ( ix = m_sqlda.sqlmax; ix < new_max; ix++ ) {
    (*(var() + ix)).sqlColInit();
  }
  for ( ix = 0; ix < m_sqlda.sqlmax; ix++ ) {
    (*(var() + ix)).m_desc = (*(m_sqlda.sqlvar + ix)).m_desc; /* PTS 1112897 */
  }
  m_session_context.deallocate(m_sqlda.sqlvar);
  m_sqlda.sqlmax = new_max; /* PTS 1115380 FF 2002-04-17 because of execption safety */
  m_sqlda.sqlvar = var.release();
}

/*----------------------------------------------------------------------*/

boolean SQL_Statement::hasInputParms() {
  for ( int i = 0; i < m_sqlda.sqln; i++ ) {
    SqlCol * var = m_sqlda.sqlvar + i;
    if ( var->sqlInOut() == sp1io_input ||
         var->sqlInOut() == sp1io_inout ) {
      return true;
    }
  }
  return false;
}

/*----------------------------------------------------------------------*/

void SQL_Statement::appendNewColDesc(const SqlCol & p) {
  if (m_reset_parms) {       /* PTS 1109560 */
    m_sqlda.inp_col_idx = 0; /* PTS 1109560 */
    m_reset_parms = false;   /* PTS 1109560 */
  }                          /* PTS 1109560 */
  m_sqlda.inp_col_idx++;
  if (m_sqlda.inp_col_idx > m_sqlda.sqlmax) {
    reallocColDescs(m_sqlda.sqlmax + 100);
  }
  SqlCol * var = m_sqlda.sqlvar + (m_sqlda.inp_col_idx - 1);
  var->m_desc->assignVar(*p.m_desc);
}

/*----------------------------------------------------------------------*/

int SQL_Statement::createLongDescriptors() {
  int rc = 1;

  short lcolCnt = m_sqlda.long_col_num + 1;
  if (lcolCnt > 0) {
    SQL_LongDesc * longDescPtr = NULL;
//    // BEGIN: MassCmd3
///*    if (m_multi_sing_exec) {
//      int norecs = m_sqlda.inp_col_idx / m_sqlda.sqln;
//      if (m_sqlda.longDesc) m_session_context.deallocate(m_sqlda.longDesc);
//      m_sqlda.longDesc = REINTERPRET_CAST(SQL_LongDesc*,
//        m_session_context.allocate( norecs * i * sizeof(SQL_LongDesc) ));
//      if ( m_sqlda.longDesc ) {
//        int nolongs = (m_sqlda.long_col_num + 1) * norecs;
//        for ( i = 0; i <= nolongs; i++ ) {
//          longDescPtr = m_sqlda.longDesc + i;
//          memset(longDescPtr,'\0',sizeof(*longDescPtr));
//        }
//      }
//      else {
//        rc = 0;
//        return rc;
//      }
//    }
//    else {  */
//    // END: MassCmd3
    m_sqlda.longDesc = 
      REINTERPRET_CAST( SQL_LongDesc *,
                        m_session_context.allocate(lcolCnt * sizeof(SQL_LongDesc)) );
    if (m_sqlda.longDesc) {
      for ( int i = 0; i <= m_sqlda.long_col_num; i++ ) {
        longDescPtr = m_sqlda.longDesc + i;
        memset( longDescPtr, '\0', sizeof(*longDescPtr) );
      }
    }
    else {
      rc = 0;
      return rc;
    }
//    //}  // gehört zu MassCmd3

    for ( int i = 0; i < m_sqlda.sqln; i++ ) {
      SqlCol * var = m_sqlda.sqlvar + i;
      if (var->m_desc) {
        switch (var->m_desc->sfi.sp1i_data_type) {
          case dstra :
          case dstrb :
          case dstruni :
          case dlonguni :
            if (var->sqlInOut() == sp1io_output) {
              m_sqlda.has_long_out_col++;
            }
            else if (var->sqlInOut() == sp1io_inout) {
              m_sqlda.has_long_in_col++;
              m_sqlda.has_long_out_col++;
            }
            else if (var->sqlInOut() == sp1io_input) {
              m_sqlda.has_long_in_col++;
            }
            (m_sqlda.longDesc + var->m_desc->long_idx)->dsc.ld_used_in_ak()[0] =
              (unsigned char)var->m_desc->long_idx;
            (m_sqlda.longDesc + var->m_desc->long_idx)->colIdx = i;
            break;
          default :
            break;
        }
      }
    }
  }
  else {
    m_sqlda.has_long_in_col  = 0;
    m_sqlda.has_long_out_col = 0;
  }
  return rc;
}

/*----- PTS 1119960 ------------------------------------------------------------*/

int SQL_Statement::createLongDescriptors(int offset) {
  int rc = 1;

  m_sqlda.has_long_in_col  = 0;
  m_sqlda.has_long_out_col = 0;

  /* int shift = m_sqlda.sqln * rowno; */
  for ( int i = 0; i < m_sqlda.sqln; i++ ) {
    SqlCol * var = m_sqlda.sqlvar + offset + i;
    if (var->m_desc) {
      switch (var->m_desc->sfi.sp1i_data_type) {
        case dstra :
        case dstrb :
        case dstruni :
        case dlonguni :
          if (var->sqlInOut() == sp1io_output) {
            m_sqlda.has_long_out_col++;
          }
          else if (var->sqlInOut() == sp1io_inout) {
            m_sqlda.has_long_in_col++;
            m_sqlda.has_long_out_col++;
          }
          else if (var->sqlInOut() == sp1io_input){
            m_sqlda.has_long_in_col++;
          }
          (m_sqlda.longDesc + var->m_desc->long_idx)->dsc.ld_used_in_ak()[0] =
            (unsigned char)var->m_desc->long_idx;
          (m_sqlda.longDesc + var->m_desc->long_idx)->colIdx = i;
          break;
        default :
          break;
      }
    }
  }

  return rc;
}

/*----------------------------------------------------------------------*/

int SQL_Statement::dropLongDescriptors() {
  m_sqlda.long_col_num = -1;
  m_session_context.deallocate(m_sqlda.longDesc);
  m_sqlda.longDesc = NULL;
  return 1;
}

/*----------------------------------------------------------------------*/

int  SQL_Statement::execute() {
  return m_session_context.executeSqlStmt(this);
}

/*----- PTS 1119960, 1123241 -------------------------------------------*/

// BEGIN: MassLong
//int  SQL_Statement::executeMass() {
//  //if ( (this->m_multi_sing_exec) && (this->m_sqlda.has_long_out_col > 0) )
//  //  return m_session_context.executeSqlStmt(this);
//  if (this->multSingFetch())
//    return m_session_context.executeSqlStmt(this);
//  else if (m_mass_fetch && m_fetch_count > 0 && m_fetch_count < m_max_fetch_count) {
//    for (int i = 0; i < m_sqlda.sqln; i++)
//      m_sqlda.sqlvar[i].m_desc->sfi.sp1i_bufpos = 
//        m_sqlda.sqlvar[i].m_desc->sfi.sp1i_bufpos + m_sqlda.fix_buf_len;
//    getNextOutputParms( m_data_ptr );
//    ++m_fetch_count;
//    if (m_fetch_count == m_max_fetch_count) { // 
//      for (int i = 0; i < m_sqlda.sqln; i++)
//        m_sqlda.sqlvar[i].m_desc->sfi.sp1i_bufpos = 
//          m_sqlda.sqlvar[i].m_desc->sfi.sp1i_bufpos -
//          (m_fetch_count - 1) * m_sqlda.fix_buf_len;
//      //free(m_data_ptr);                        // hier
//      m_session_context.deallocate(m_data_ptr);
//      m_data_ptr = NULL;                       // nur 
//      m_fetch_count = 0;                      // zum
//      m_max_fetch_count = 0;                  // Test 
//    }                                         //
//    return 1;
//  }
//  else if (m_mass_fetch && m_fetch_count > 0 && m_fetch_count == m_max_fetch_count) {
//    //free(m_data_ptr);
//    m_session_context.deallocate(m_data_ptr);
//    m_data_ptr = NULL;
//    m_fetch_count = 0;
//    m_max_fetch_count = 0;
//    return 0; 
//  }
//  //else if ( (this->m_multi_sing_exec) && (this->m_sqlda.has_long_in_col > 0) ) {
//  //  this->setMassCmdFlag();
//  //  return m_session_context.executeSqlStmt(this);
//  //}
//  else if (this->m_multi_sing_insert) 
//    return m_session_context.executeSqlStmt(this);
//  else
//    return m_session_context.executeMassSqlStmt(this);
//};

int SQL_Statement::executeMass() {

  if (m_multi_sing_fetch) {
    return m_session_context.executeSqlStmt(this);
  }

  else if ( m_mass_fetch && 
            m_fetch_count > 0 && m_fetch_count < m_max_fetch_count ) {
    for ( int i = 0; i < m_sqlda.sqln; i++ ) {
      m_sqlda.sqlvar[i].m_desc->sfi.sp1i_bufpos += m_sqlda.orig_fix_buf_len;

      m_sqlda.sqlvar[i].m_desc->vfi.ind = 0;

    }
    getNextOutputParmsMass(); //(m_data_ptr);
    if (hasLongOutputMass()) {
      getNextLongOutputParmsMass();
    }
    ++m_fetch_count;
    if (m_fetch_count == m_max_fetch_count) {
      for ( int i = 0; i < m_sqlda.sqln; i++ ) {
        m_sqlda.sqlvar[i].m_desc->sfi.sp1i_bufpos -= (m_fetch_count-1) * m_sqlda.orig_fix_buf_len;
      }
//      m_session_context.deallocate(m_data_ptr);
//      m_data_ptr = NULL;
      m_fetch_count = 0;
      m_max_fetch_count = 0;
      m_session_context.deallocate(m_longdesc_ptr);
      m_longdesc_ptr = NULL;
      m_session_context.deallocate(m_longdata_notnull);
      m_longdata_notnull = NULL;
      m_session_context.deallocate(m_longdata_inplace);
      m_longdata_inplace = NULL;
    }
    return 1;
  }

  else if ( m_mass_fetch && 
            m_fetch_count > 0 && m_fetch_count == m_max_fetch_count) {
    m_session_context.deallocate(m_data_ptr);
    m_data_ptr = NULL;
    m_fetch_count = 0;
    m_max_fetch_count = 0;
    m_session_context.deallocate(m_longdesc_ptr);
    m_longdesc_ptr = NULL;
    m_session_context.deallocate(m_longdata_notnull);
    m_longdata_notnull = NULL;
    m_session_context.deallocate(m_longdata_inplace);
    m_longdata_inplace = NULL;
    m_session_context.deallocate(m_longdata_ptr);
    m_longdata_ptr = NULL;
    return 0; 
  }

  else if (m_multi_sing_insert) {
    return m_session_context.executeSqlStmt(this);
  }

  else {
    int rc = m_session_context.executeMassSqlStmt(this);
    if (0 == rc) {
      m_session_context.deallocate(m_data_ptr);
      m_data_ptr = NULL;
      m_fetch_count = 0;
      m_max_fetch_count = 0;
      m_session_context.deallocate(m_longdesc_ptr);
      m_longdesc_ptr = NULL;
      m_session_context.deallocate(m_longdata_notnull);
      m_longdata_notnull = NULL;
      m_session_context.deallocate(m_longdata_inplace);
      m_longdata_inplace = NULL;
      m_session_context.deallocate(m_longdata_ptr);
      m_longdata_ptr = NULL;
    }
    else {
      if (m_mass_fetch) {
        ++m_fetch_count;
      }
    }
    return rc;
  }

}

// END: MassLong

//unsigned char SQL_Statement::getParseFlag1() {
//  //return tsp00_Array<unsigned char,12,12>m_parseid.data_IV[10];
//  return m_parseid.asCharp()[10];
//};
//
//unsigned char SQL_Statement::getParseFlag2() {
//  //return tsp00_Array<unsigned char,12,12>m_parseid_of_select.data_IV[10];
//    return m_parseid_of_select.asCharp()[10];
//};
//
//unsigned char SQL_Statement::getParseInfo(parseid_type id, int bytenr) {
//  if (id == parseid)
//    return m_parseid.asCharp()[bytenr];
//  //if (id == parseid_of_select)
//  else
//    return m_parseid_of_select.asCharp()[bytenr];
//};

/*----------------------------------------------------------------------*/

int SQL_Statement::getOutputParms( int argCount,
                                   int dataLen,
                                   const teo00_Byte * dataPtr ) {
  int rc = 1;
  SQL_LongDesc * longDescPtr = NULL;
  int i, prmNo;

// BEGIN: MassLong
//  // PTS 1119960
//  if (m_mass_cmd || 
//      m_parseid_of_select.asCharp()[10] == 114 || m_parseid.asCharp()[10] == 43) {
//    m_mass_fetch = true;
//    m_fetch_count = 1;
//    m_max_fetch_count = argCount;
//    m_data_ptr = (teo00_Byte*)m_session_context.allocate(dataLen);  //malloc(dataLen);
//    SAPDB_MemCopyNoCheck( m_data_ptr, dataPtr, dataLen );
//  }
// END: MassLong
  /* PTS 1130628, writing extended error info in case of VCHAR_ASCII violation */
  for ( i = 0; (i < m_sqlda.sqln) && (rc > 0); i++) {
    prmNo = i + 1;
    SqlCol * var = m_sqlda.sqlvar + i;
    switch (var->m_desc->sfi.sp1i_data_type) {
      case dstra :
      case dstrb :
      case dstruni :
      case dlonguni :
        longDescPtr = m_sqlda.longDesc + var->m_desc->long_idx;
        longDescPtr->bufPos = var->m_desc->sfi.sp1i_bufpos;
        longDescPtr->dsc.ld_valpos() = 0;
        longDescPtr->varPos = 0;
        break;
      default :
        break;
    }
    if ( var->sqlInOut() == sp1io_output ||
         var->sqlInOut() == sp1io_inout ) {
      rc = var->m_desc->getParmFromBuffer( dataPtr, m_session_context,
                                           *this, prmNo );
    }
  }
# if !defined (EXT_CLIENT_SQL)
    if (rc < 0) {
      dumpBadAsciidataInfo( prmNo, 0, -rc );
      rc = 0;
    }
# endif

  return rc;
}

/*----- PTS 1123241 ----------------------------------------------------*/

int SQL_Statement::getOutputParmsMass( int argCount, int dataLen,
                                       const teo00_Byte * dataPtr ) {
  int rc = 1, i, j, offset;
  SQL_LongDesc * longDescPtr = NULL;

  m_mass_fetch = true;
  m_max_fetch_count = argCount;
  if (NULL == m_data_ptr) {
    m_data_ptr = (teo00_Byte*)m_session_context.allocate(m_session_context.getRequestPacketSize());
  }
  SAPDB_MemCopyNoCheck( m_data_ptr, dataPtr, dataLen );

  if (m_sqlda.has_long_out_col) { // (hasLongOutput()) {
    m_longdesc_ptr = 
      REINTERPRET_CAST( SQL_LongDesc *,
                        m_session_context.allocate(argCount*
                                                   m_sqlda.has_long_out_col*
                                                   sizeof(SQL_LongDesc)) );
    m_longdata_notnull = 
      REINTERPRET_CAST( bool *,
                        m_session_context.allocate(argCount*
                                                   m_sqlda.has_long_out_col*
                                                   sizeof(bool)) );
    m_longdata_inplace = 
      REINTERPRET_CAST( bool *,
                        m_session_context.allocate(argCount*
                                                   m_sqlda.has_long_out_col*
                                                   sizeof(bool)) );
    int * longDescPos =
      REINTERPRET_CAST( int *,
                        m_session_context.allocate(m_sqlda.has_long_out_col*
                                                   sizeof(int)) );
    int * longColCIdx =
      REINTERPRET_CAST( int *,
                        m_session_context.allocate(m_sqlda.has_long_out_col*
                                                   sizeof(int)) );
    j = 0;
    for ( i = 0; i < m_sqlda.sqln; i++ ) {
      if ((m_sqlda.sqlvar+i)->m_desc->long_idx >= 0) {
        *(longDescPos+j) = (m_sqlda.sqlvar+i)->m_desc->sfi.sp1i_bufpos;
        *(longColCIdx+j) = i;
        j++;
      }
    }
    for ( i = 0; i < argCount; i++ ) {
      for ( j = 0; j < m_sqlda.has_long_out_col; j++ ) {
        offset = i*m_sqlda.has_long_out_col + j;
        longDescPtr = m_longdesc_ptr + offset;
        SAPDB_MemCopyNoCheck( &(longDescPtr->dsc),
                m_data_ptr + *(longDescPos + j) + i*m_sqlda.orig_fix_buf_len,
                sizeof(tsp00_LongDescriptor) );
        if ((char)csp_undef_byte == 
            *((char*)m_data_ptr + *(longDescPos + j) + i*m_sqlda.orig_fix_buf_len - 1)) {
          *(m_longdata_notnull + offset) = false;
        }
        else {
          *(m_longdata_notnull + offset) = true;
        }
        longDescPtr->varPos = 0;
        longDescPtr->bufPos = 0;
        longDescPtr->colIdx = *(longColCIdx + j);
        longDescPtr->dsc.ld_valind() = offset;
        if (longDescPtr->dsc.ld_valpos() > 0) {
          *(m_longdata_inplace + offset) = true;
        }
        else {
          *(m_longdata_inplace + offset) = false;
        }
      }
    }
    longDescPtr = NULL;
    m_session_context.deallocate(longDescPos);
    longDescPos = NULL;
    m_session_context.deallocate(longColCIdx);
    longColCIdx = NULL;
  }

  for ( i = 0; (i < m_sqlda.sqln) && rc; i++ ) {
    SqlCol * var = m_sqlda.sqlvar + i;
    SQL_ColumnDesc * descPtr = var->m_desc;
    switch (descPtr->sfi.sp1i_data_type) {
      case dstra :
      case dstrb :
      case dstruni :
      case dlonguni :
        longDescPtr = m_longdesc_ptr + var->m_desc->long_idx;
        longDescPtr->dsc.ld_valpos() = 0;
        longDescPtr->bufPos = var->m_desc->sfi.sp1i_bufpos;
        longDescPtr->varPos = 0;
        break;
      default :
        break;
    }
    if ( descPtr->getIOType() == sp1io_output ||
         descPtr->getIOType() == sp1io_inout ) {
      rc = descPtr->getParmFromBuffer( dataPtr, m_session_context,
                                       *this, i + 1 );
    }
  }

  if (m_sqlda.has_long_out_col) { // (hasLongOutput()) {
    for ( j = 0; j < m_sqlda.has_long_out_col; j++ ) {
      (m_longdesc_ptr + j)->dsc.ld_valind() = j;
    }
  }

  return rc;

}

/*----- PTS 1119960 ------------------------------------------------------------*/

int SQL_Statement::getNextOutputParms ( const teo00_Byte * dataPtr ) {
  int rc = 1; 
  SQL_LongDesc * longDescPtr = NULL;
  for (int i = 0; ( i < m_sqlda.sqln ) && rc; i++) {
    SqlCol *var = m_sqlda.sqlvar + i;
    switch ( var->m_desc->sfi.sp1i_data_type ) {
      case dstra:
      case dstrb:
     	case dstruni:
      case dlonguni:
        longDescPtr = m_sqlda.longDesc + var->m_desc->long_idx;
        longDescPtr->bufPos = var->m_desc->sfi.sp1i_bufpos;
        longDescPtr->dsc.ld_valpos() = 0;
        longDescPtr->varPos = 0;
        break;
      default:
        break;
    }
    if (var->sqlInOut () == sp1io_output ||
      var->sqlInOut() == sp1io_inout) {	
      rc = var->m_desc->getParmFromBuffer( dataPtr, m_session_context, 
        *this, i + 1 );
    }
  }
  return rc;
};

/*----- PTS 1123241 ------------------------------------------------------------*/

int SQL_Statement::getNextOutputParmsMass() { //(const teo00_Byte * dataPtr) {
  int rc = 1, lrc, valind;
  SQL_LongDesc * longDescPtr = NULL;

  for ( int i = 0; (i < m_sqlda.sqln) && rc; i++ ) {
    SqlCol * var = m_sqlda.sqlvar + i;
    lrc = 1;
    switch (var->m_desc->sfi.sp1i_data_type) {
      case dstra :
      case dstrb :
      case dstruni :
      case dlonguni :
        if (!(*(m_longdata_notnull + m_fetch_count*m_sqlda.has_long_out_col
                                    + var->m_desc->long_idx))) {
          lrc = -1;
          var->m_desc->vfi.ind = -1;
        }
        else if (!(*(m_longdata_inplace + m_fetch_count*m_sqlda.has_long_out_col
                                        + var->m_desc->long_idx))) {
          lrc = 0;
        }
        else {
          lrc = 2;
          longDescPtr = m_longdesc_ptr + m_fetch_count*m_sqlda.has_long_out_col
                                       + var->m_desc->long_idx;
          valind = longDescPtr->dsc.ld_valind();
//        }
          longDescPtr->bufPos = var->m_desc->sfi.sp1i_bufpos;
          longDescPtr->dsc.ld_valpos() = 0;
          longDescPtr->varPos = 0;
        }
        break;
      default :
        break;
    }
    if ( (var->sqlInOut() == sp1io_output ||
          var->sqlInOut() == sp1io_inout)  && (lrc > 0) ) {
      rc = var->m_desc->getParmFromBuffer( m_data_ptr /*dataPtr*/, m_session_context,
                                           *this, i + 1 );
      if (lrc == 2) {
        longDescPtr->dsc.ld_valind() = valind;
      }
    }
  }

  return rc;
}

/*----- PTS 1123241 ------------------------------------------------------------*/

int SQL_Statement::getNextLongOutputParmsMass() {
  tsp00_LongDescriptor * longDescSrcPtr  = NULL;
  SQL_LongDesc         * longDescDestPtr = NULL;
  int rc = 1, cntr, descPos;

  if (m_longdata_buf) {

    cntr = m_longdesc_cntr;
    descPos = m_longdesc_pos;
    while (cntr < m_longdesc_cnt) {
      longDescSrcPtr = (tsp00_LongDescriptor*)(m_longdata_ptr + descPos);
      if (longDescSrcPtr->ld_valind() < (m_fetch_count+1) * m_sqlda.has_long_out_col) {
        longDescDestPtr = m_longdesc_ptr + longDescSrcPtr->ld_valind();
        SAPDB_MemCopyNoCheck( &longDescDestPtr->dsc, longDescSrcPtr, sizeof(tsp00_LongDescriptor) );
        SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
        if ( (vm_datapart == longDescDestPtr->dsc.ld_valmode()) ||
             (vm_alldata  == longDescDestPtr->dsc.ld_valmode()) ||
             (vm_lastdata == longDescDestPtr->dsc.ld_valmode()) ) {
          descPos = longDescDestPtr->dsc.ld_valpos() + longDescDestPtr->dsc.ld_vallen();
          rc = var->m_desc->getOpenLongDataFromBuffer( m_longdata_ptr, m_session_context,
                                                       *this, longDescDestPtr->colIdx + 1 );
        }
        else {
          descPos = descPos + sizeof(tsp00_LongDescriptor) + 1;
        }
      }
      else {
        break;
      }
      ++cntr;
    }
  
//    m_sqlda.fix_buf_len = cntr * (1 + sizeof(tsp00_LongDescriptor));

    if (cntr < m_longdesc_cnt) { /* buffer isn't completely read */
      m_longdesc_pos = descPos;
      m_longdesc_cntr = cntr;
      return rc;
    }
    else { /* buffer is now completely read */
      m_longdata_buf = false;
      if ( hasLongOutputMass() && rc ) {
        return m_session_context.executeNextLongOutput(this);
      }
      else {
        return rc;
      } 
    }

  }
  else {
    return m_session_context.executeNextLongOutput(this);
  }

}

/*----------------------------------------------------------------------*/

/* PTS 1112690 parsingAgain added */
int SQL_Statement::prepare(const pasbool parsingAgain) {
  m_res_tabname[0] = '0';
  int rc = m_session_context.prepareSqlStmt( this, parsingAgain );
  // PTS 1119960
// BEGIN: MassLong
//  if(isMassCmd() && hasLongOutput()) {
//    removeMassCmdFlag();
//    //setMultiSingExecFlag();
//    setMultiSingFetchFlag();
//    rc = m_session_context.prepareSqlStmt(this, parsingAgain);
//  }
// END: MassLong
  if (rc) {
    m_prepared = true;
  }
  return rc;
}

/*----------------------------------------------------------------------*/

void SQL_Statement::setParsid( int len, const tin02_ParseId * data ) {
  SAPDB_MemCopyNoCheck( &m_parseid[0], data, sizeof(m_parseid) );
  m_parseid_len = len;
}

/*----------------------------------------------------------------------*/

void SQL_Statement::setParsidOfSelect( int len, const tin02_ParseId * data ) {
  SAPDB_MemCopyNoCheck( &m_parseid_of_select[0], data, sizeof(m_parseid_of_select) );
  m_parseid_len = len;
}

/*----------------------------------------------------------------------*/

void SQL_Statement::setResultTablename( int len, const char * data ) {
  SAPDB_MemCopyNoCheck( &m_res_tabname[0], data, len );
  m_res_tabname[len] = '\0';
}

/*----------------------------------------------------------------------*/

void SQL_Statement::setSqlDA_sqln(int argCount) {
  if (m_sqlda.sqlmax < argCount) {
    reallocColDescs(argCount);
  }
  m_sqlda.sqln = argCount;
}

/*----------------------------------------------------------------------*/

void SQL_Statement::setSqlDA_sfi( int i, const tsp1_param_info * sfi ) {
  SqlCol * var = m_sqlda.sqlvar + i;
  if (var->m_desc) {
    SAPDB_MemCopyNoCheck( &var->m_desc->sfi, sfi, sizeof(*sfi) );
    switch (var->m_desc->sfi.sp1i_data_type) {
      case dstra :
      case dstrb :
      case dstruni :
      case dlonguni :
        m_sqlda.long_col_num++;
        var->m_desc->long_idx = m_sqlda.long_col_num;
        break;
      default :
        break;
    }
  }
  if (m_sqlda.fix_buf_len < (var->m_desc->sfi.sp1i_bufpos +
                             var->m_desc->sfi.sp1i_in_out_len)) {
    m_sqlda.fix_buf_len = var->m_desc->sfi.sp1i_bufpos +
                          var->m_desc->sfi.sp1i_in_out_len - 1;
  }
}

/*----- PTS 1119960 ----------------------------------------------------*/

short SQL_Statement::getSqlDA_inp_col_idx() {
  return m_sqlda.inp_col_idx;
}

/*-----  PTS 1119960 ---------------------------------------------------*/

void SQL_Statement::setSqlDA_sfi( short i, int jx, int jlen,
                                  const tsp1_param_info * sfi ) {
  SqlCol * var = m_sqlda.sqlvar + jx + i;
    if (var->m_desc) {
      SAPDB_MemCopyNoCheck( &(var->m_desc->sfi), sfi, sizeof(*sfi) );
      var->m_desc->sfi.sp1i_bufpos += jlen;
      switch (var->m_desc->sfi.sp1i_data_type) {
        case dstra :
        case dstrb :
        case dstruni :
        case dlonguni :
          m_sqlda.long_col_num++;
          var->m_desc->long_idx = m_sqlda.long_col_num;
          break;
        default :
          break;
      }
    }
  if (m_sqlda.fix_buf_len < (var->m_desc->sfi.sp1i_bufpos +
                             var->m_desc->sfi.sp1i_in_out_len)) {
    m_sqlda.fix_buf_len = var->m_desc->sfi.sp1i_bufpos +
                          var->m_desc->sfi.sp1i_in_out_len - 1;
  }
}

/*-----  PTS 1119960 ---------------------------------------------------*/

void SQL_Statement::shiftSqlCols( int offset, int nr ) {
  if (nr == 0) {
    m_sqlda.long_col_num = -1;
  }
  setSqlDA_sfi (offset + nr, &(m_sqlda.sqlvar[nr].m_desc->sfi) );
}

/*----------------------------------------------------------------------*/

void SQL_Statement::setResetParms() { /* PTS 1109560 */
  m_reset_parms = true;
}

/*----- PTS 1119960 ----------------------------------------------------*/

void SQL_Statement::setMassCmdFlag() {
  m_mass_cmd = true;
}

/*----- PTS 1119960 ----------------------------------------------------*/

void SQL_Statement::removeMassCmdFlag() {
  m_mass_cmd = false;
}

/*----- PTS 1119960 ----------------------------------------------------*/

void SQL_Statement::setMultiSingExecFlag() {
  m_multi_sing_exec = true;
}

/*----- PTS 1119960 ----------------------------------------------------*/

void SQL_Statement::removeMultiSingExecFlag() {
  m_multi_sing_exec = false;
}

/*----- PTS 1119960 ----------------------------------------------------*/

boolean SQL_Statement::multSingExec() {
  return m_multi_sing_exec;
}

/*----- PTS 1119960 ----------------------------------------------------*/

void SQL_Statement::setMultiSingFetchFlag() {
  m_multi_sing_fetch = true;
}

/*----------------------------------------------------------------------*/

boolean SQL_Statement::multSingFetch() {
  return m_multi_sing_fetch;
}

/*----- PTS 1119960 ----------------------------------------------------*/

void SQL_Statement::setMultiSingInsertFlag() {
  m_multi_sing_insert = true;
}

/*----- PTS 1119960 ----------------------------------------------------*/

boolean SQL_Statement::multSingInsert() {
  return m_multi_sing_insert;
}

/*----- PTS 1119960 ----------------------------------------------------*/

boolean SQL_Statement::isMassCmd() {
  return m_mass_cmd;
}

/*----- PTS 1119960 ----------------------------------------------------*/

short SQL_Statement::getSqln() {
  return m_sqlda.sqln;
}

/*----------------------------------------------------------------------*/

int SQL_Statement::getFixBufLength() const {
  return m_sqlda.fix_buf_len;
}

/*----- PTS 1119960 ----------------------------------------------------*/

void SQL_Statement::setOrigFixBufLength(int fix_buf_len) {
  m_sqlda.orig_fix_buf_len = fix_buf_len;
}

/*----- PTS 1119960 ----------------------------------------------------*/

int SQL_Statement::getOrigFixBufLength() const {
  return m_sqlda.orig_fix_buf_len;
}

/*----------------------------------------------------------------------*/

short SQL_Statement::getNumCols() const {
  return m_sqlda.sqln;
}

/*----------------------------------------------------------------------*/

short SQL_Statement::getNumVars() const{
  return m_sqlda.inp_col_idx;
}

/*----------------------------------------------------------------------*/

short SQL_Statement::getLongColNum () const {
  return m_sqlda.long_col_num;
}

/*----------------------------------------------------------------------*/

short SQL_Statement::getNumOutCols() const {
  short numOutCols = 0;
  for ( int i = 0; i < m_sqlda.sqln; i++ ) {
    SqlCol * var = m_sqlda.sqlvar + i;
    if ( var->sqlInOut() == sp1io_output ||
         var->sqlInOut() == sp1io_inout) {
      numOutCols++;
    }
  }
  return numOutCols;
}

/*----------------------------------------------------------------------*/

#define OFFSET(T,M) (((char*) &((T*) 0)->M) - (char*) 0) /* 1113808 FF 30-JAN-2002 */

int SQL_Statement::getLongDesc( int argCount, int dataLen,
                                const tsp00_Byte * dataPtr) {
  unsigned char * longDescSrcPtr  = NULL; /* 1113808 FF 30-JAN-2002 */
  SQL_LongDesc  * longDescDestPtr = NULL;  
  for (int i = 0; i < argCount; i++ ) {
    longDescSrcPtr = (unsigned char *)(dataPtr + i*(sizeof(tsp00_LongDescriptor)+1) + 1);
    longDescDestPtr = m_sqlda.longDesc + *(longDescSrcPtr +
                                           OFFSET(tsp00_LongDescriptor,ld_used_in_ak()));
    SAPDB_MemCopyNoCheck( &(longDescDestPtr->dsc), longDescSrcPtr, sizeof(tsp00_LongDescriptor) );
  }
  m_sqlda.fix_buf_len = argCount * (1 + sizeof(tsp00_LongDescriptor));
  return 1;
}

/*----- PTS 1123241 ----------------------------------------------------*/

// BEGIN: MassLong
int SQL_Statement::getLongDescMass( int argCount, int dataLen,
                                    const tsp00_Byte * dataPtr) {

  unsigned char * longDescSrcPtr  = NULL;	// 1113808 FF 30-JAN-2002 
  SQL_LongDesc  * longDescDestPtr = NULL;  

  for (int i = 0; i < argCount; i++) {
    longDescSrcPtr = (unsigned char *)(dataPtr + i * (sizeof(tsp00_LongDescriptor) + 1) + 1);
    longDescDestPtr = m_sqlda.longDesc + *( longDescSrcPtr +  OFFSET(tsp00_LongDescriptor,ld_used_in_ak()) );
    SAPDB_MemCopyNoCheck( &longDescDestPtr->dsc, longDescSrcPtr, sizeof(tsp00_LongDescriptor) );
  }
  m_sqlda.fix_buf_len = argCount * (1 + sizeof(tsp00_LongDescriptor));

  return 1;
};
// END: MassLong

/*----------------------------------------------------------------------*/

int SQL_Statement::getLongDescAndValue( int argCount, int dataLen,
                                        const tsp00_Byte * dataPtr ) {
  unsigned char * longDescSrcPtr  = NULL; /* 1113808 FF 30-JAN-2002 */
  SQL_LongDesc  * longDescDestPtr = NULL;
  int descPos = 1;
  int rc = 1;

  for ( int i = 0; i < argCount; i++ ) {
    longDescSrcPtr  = (unsigned char *)(dataPtr + descPos);
    longDescDestPtr = m_sqlda.longDesc +
                      *(longDescSrcPtr + OFFSET(tsp00_LongDescriptor,ld_used_in_ak()));
    SAPDB_MemCopyNoCheck( &(longDescDestPtr->dsc), longDescSrcPtr, sizeof(tsp00_LongDescriptor) );
    SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
    if ( (vm_datapart == longDescDestPtr->dsc.ld_valmode()) ||
         (vm_alldata  == longDescDestPtr->dsc.ld_valmode()) ||
         (vm_lastdata == longDescDestPtr->dsc.ld_valmode()) ) {
      descPos = longDescDestPtr->dsc.ld_valpos() +
                longDescDestPtr->dsc.ld_vallen();
      rc = var->m_desc->getOpenLongDataFromBuffer( dataPtr, m_session_context, *this,
                                                   longDescDestPtr->colIdx + 1 );
    }
    else {
      descPos = descPos + sizeof(tsp00_LongDescriptor) + 1;
    }
  }
  m_sqlda.fix_buf_len = argCount * (1 + sizeof(tsp00_LongDescriptor));

  return rc;
}

/*----------------------------------------------------------------------*/

int SQL_Statement::getLongDescAndValueMass( int argCount, int dataLen,
                                            const tsp00_Byte * dataPtr) {
  tsp00_LongDescriptor * longDescSrcPtr  = NULL;
  SQL_LongDesc         * longDescDestPtr = NULL;
  int descPos = 1;
  int rc = 1;
  int cntr = 0;

  while (cntr < argCount) {
    longDescSrcPtr = (tsp00_LongDescriptor*)(dataPtr + descPos);
    if (longDescSrcPtr->ld_valind() < (m_fetch_count+1) * m_sqlda.has_long_out_col) {
      longDescDestPtr = m_longdesc_ptr + longDescSrcPtr->ld_valind();
      SAPDB_MemCopyNoCheck( &(longDescDestPtr->dsc), longDescSrcPtr, sizeof(tsp00_LongDescriptor) );
      SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
      if ( (vm_datapart == longDescDestPtr->dsc.ld_valmode()) ||
           (vm_alldata  == longDescDestPtr->dsc.ld_valmode()) ||
           (vm_lastdata == longDescDestPtr->dsc.ld_valmode()) ) {
        descPos = longDescDestPtr->dsc.ld_valpos() + longDescDestPtr->dsc.ld_vallen();
        rc = var->m_desc->getOpenLongDataFromBuffer( dataPtr, m_session_context, *this,
                                                     longDescDestPtr->colIdx + 1 );
      }
      else {
        descPos = descPos + sizeof(tsp00_LongDescriptor) + 1;
      }
    }
    else {
      break;
    }
    ++cntr;
  }

//  m_sqlda.fix_buf_len = cntr * (1 + sizeof(tsp00_LongDescriptor)); /* ??? */

  if (cntr < argCount) { /* buffer isn't completely read */
    if (NULL == m_longdata_ptr) {
      m_longdata_ptr = (teo00_Byte*)m_session_context.allocate(m_session_context.getRequestPacketSize());
    }
    SAPDB_MemCopyNoCheck( m_longdata_ptr, dataPtr, dataLen );
    m_longdata_buf  = true;
    m_longdesc_pos  = descPos;
    m_longdesc_cnt  = argCount;
    m_longdesc_cntr = cntr;
  }

  return rc;
}
// END: MassCmd

/*----------------------------------------------------------------------*/

int SQL_Statement::getParsid(const tin02_ParseId ** data) const {
  *data = &m_parseid;
  return m_parseid_len;
}

/*----------------------------------------------------------------------*/

SQL_LongDesc * SQL_Statement::getLongDescPtr(short idx) {
  if ( m_mass_cmd && m_mass_fetch ) {
    return (m_longdesc_ptr +
//              m_fetch_count*m_sqlda.has_long_out_col + idx)->longDsc);
                             m_fetch_count*m_sqlda.has_long_out_col + idx);
  }
  else {
    return(m_sqlda.longDesc + idx);
  }
}

/*----- PTS 1123241 ----------------------------------------------------*/

SQL_LongDesc * SQL_Statement::getLongDescPtrMass(short idx) {
  return m_longdesc_ptr + idx;
}

/*----------------------------------------------------------------------*/

boolean SQL_Statement::getPreparedFlag() const {
  return m_prepared;
}

/*----------------------------------------------------------------------*/

const char* SQL_Statement::getStatement() const {
  return m_statement.c;
}

/*----------------------------------------------------------------------*/

const tsp81_UCS2Char* SQL_Statement::getUniStatement() const {
  return m_statement.uc;
}

/*----------------------------------------------------------------------*/

eco521_stmt_type SQL_Statement::getStmtType() const {
  return m_stmt_type;
}

/*----------------------------------------------------------------------*/

int SQL_Statement::isUnicode() const {
  return m_unicode;
}

/*----------------------------------------------------------------------*/

short SQL_Statement::hasLongInput() {
  if (m_sqlda.has_long_in_col) {
    for ( int i = 0; i <= m_sqlda.long_col_num; i++ ) {
      SQL_LongDesc * longDescDestPtr = m_sqlda.longDesc + i;
      SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
      if ( (var->m_desc->vfi.ind == 0) &&
           (var->sqlInOut() == sp1io_input || 
            var->sqlInOut() == sp1io_inout) ) {
        int byteLen;
        switch (var->sqlVarType()) {
          case SqlCol::VCHAR_UNICODE :
          case SqlCol::VSTRING_UNICODE :
            byteLen = var->m_desc->vfi.vlen * 2;
            break;
          default :
            byteLen = var->m_desc->vfi.vlen;
        } 
        if (longDescDestPtr->varPos < byteLen) {
          return 1;
        }
      }
    }
  }
  return 0;
}

/*----- PTS 1119960 ----------------------------------------------------*/

short SQL_Statement::hasLongInput(int offset) {
  if (m_sqlda.has_long_in_col) {
    for ( int i = 0; i <= m_sqlda.long_col_num; i++ ) {
      SQL_LongDesc * longDescDestPtr = m_sqlda.longDesc + i;
      SqlCol * var = m_sqlda.sqlvar + offset + longDescDestPtr->colIdx;
      if ( (var->m_desc->vfi.ind == 0) &&
           (var->sqlInOut() == sp1io_input ||
            var->sqlInOut() == sp1io_inout) ) {
        int byteLen;
        switch (var->sqlVarType()) {
          case SqlCol::VCHAR_UNICODE :
          case SqlCol::VSTRING_UNICODE :
            byteLen = var->m_desc->vfi.vlen * 2;
            break;
          default :
            byteLen = var->m_desc->vfi.vlen;
        }
        if (longDescDestPtr->varPos < byteLen) {
          return 1;
        }
      }
    }
  }
  return 0;
}

/*----------------------------------------------------------------------*/

short SQL_Statement::hasLongOutput() {
  if (m_sqlda.has_long_out_col) {
    for ( int i = 0; i <= m_sqlda.long_col_num; i++ ) {
      SQL_LongDesc * longDescDestPtr = m_sqlda.longDesc + i;
      SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
      if ( (var->m_desc->vfi.ind == 0) &&
           (var->sqlInOut() == sp1io_output ||
            var->sqlInOut() == sp1io_inout) ) {
        if ( !( vm_alldata    == longDescDestPtr->dsc.ld_valmode() ||
                vm_data_trunc == longDescDestPtr->dsc.ld_valmode() ||
                vm_lastdata   == longDescDestPtr->dsc.ld_valmode() ) ) {
          return 1;
        }
      }
    }
  }
  return 0;
}

/*----- PTS 1123241 ----------------------------------------------------*/

short SQL_Statement::hasLongOutputMass() {
  if (m_sqlda.has_long_out_col) {
    for ( int i = m_fetch_count*m_sqlda.has_long_out_col;
              i < (m_fetch_count+1)*m_sqlda.has_long_out_col; i++ ) {
      SQL_LongDesc * longDescDestPtr = m_longdesc_ptr + i;
      SqlCol * var = m_sqlda.sqlvar + longDescDestPtr->colIdx;
      if ( (var->m_desc->vfi.ind == 0) &&
           (var->sqlInOut() == sp1io_output ||
            var->sqlInOut() == sp1io_inout) ) {
        if ( !( vm_alldata    == longDescDestPtr->dsc.ld_valmode() ||
                vm_data_trunc == longDescDestPtr->dsc.ld_valmode() ||
                vm_lastdata   == longDescDestPtr->dsc.ld_valmode() ) ) {
          return 1;
        }
      }
    }
  }
  return 0;
}

/*----------------------------------------------------------------------*/

int SQL_Statement::addRef() {
  ++m_ref_count;
  return m_ref_count;
}

/*----------------------------------------------------------------------*/

int SQL_Statement::release() {
  --m_ref_count;
  if (0 == m_ref_count) {
    m_session_context.deallocate(m_statement.c);
    m_statement.c = NULL;
    for ( int i = 0; i < m_sqlda.sqlmax; i++ ) {
      (*(m_sqlda.sqlvar + i)).~SqlCol();
    }
    m_session_context.deallocate(m_sqlda.sqlvar);
    m_sqlda.sqlvar = NULL;
    m_sqlda.long_col_num = 0;
    m_session_context.deallocate(m_sqlda.longDesc);
    m_sqlda.longDesc = NULL;
    m_session_context.deallocate(m_data_ptr); /* PTS 1119960 */
    m_data_ptr = NULL;                        /* PTS 1119960 */
    m_session_context.deallocate(m_longdesc_ptr);     /* PTS 1123241 */
    m_longdesc_ptr = NULL;                            /* PTS 1123241 */
    m_session_context.deallocate(m_longdata_notnull); /* PTS 1123241 */
    m_longdata_notnull = NULL;                        /* PTS 1123241 */
    m_session_context.deallocate(m_longdata_inplace); /* PTS 1123241 */
    m_longdata_inplace = NULL;                        /* PTS 1123241 */
    m_session_context.deallocate(m_longdata_ptr);     /* PTS 1123241 */
    m_longdata_ptr = NULL;                            /* PTS 1123241 */
    m_session_context.dropSqlStmt(this);
    return 0;
  }
  else {
    return m_ref_count;
  }
}

/*----- PTS 1130628 ----------------------------------------------------*/

# if !defined (EXT_CLIENT_SQL)

void SQL_Statement::dumpBadAsciidataInfo( int prmNo, int offset, int pos ) {
  const char * stmtText = NULL;
  int stmtLen      = 0;
  int remLen       = 0;
  const int outLen = 29;
  char name[32];
  int nameLen = sizeof(name);
  char buffer[256];
  int bufLen = sizeof(buffer);

  if (m_unicode) {
    return;
  }
  if (!(m_session_context.getSqlHandle())) {
    return;
  }
  if (!(m_session_context.getSqlHandle()->getSinkPtr())) {
    return;
  }

  memset( buffer, '\0', sizeof(buffer) );
  sp77sprintf( buffer, bufLen, "DbpError %d", m_session_context.sqlCode() );
  m_session_context.getSqlHandle()->dbpOpError(buffer);

  memset( buffer, '\0', sizeof(buffer) );
  strcpy( buffer, "-- " );
  strcat( buffer, m_session_context.getErrorDesc(e_nonascii_char) );
  strcat( buffer, " --" );
  m_session_context.getSqlHandle()->dbpOpError(buffer);

  memset( buffer, '\0', sizeof(buffer) );
  memset( name, '\0', nameLen );
  m_session_context.getCurrMethodAscii( name, nameLen );
  strcat( buffer, "in " );
  strncat( buffer, name, nameLen );
  m_session_context.getSqlHandle()->dbpOpError(buffer);

  if ( getParsidInfo1() == 42 || getParsidInfo1() == 43 ) {
    const tin02_ParseId * parseId;
    getParsid(&parseId);
    const SQL_Statement * selStmt = m_session_context.getSqlStmtFromDirectory(parseId);
    stmtText = selStmt->m_statement.c;
  }
  else {
    stmtText = m_statement.c;
  }
  stmtLen = strlen(stmtText);
  memset( buffer, '\0', sizeof(buffer) );
  strcat( buffer, "Statement: " );
  if ( stmtLen < outLen  ) {
    strncat( buffer, stmtText, stmtLen );
    m_session_context.getSqlHandle()->dbpOpError(buffer);
  }
  else {
    strncat( buffer, stmtText, outLen );
    m_session_context.getSqlHandle()->dbpOpError(buffer);
    remLen = stmtLen - outLen;
    while ( remLen > 0 ) {
      memset( buffer, '\0', sizeof(buffer) );
      strcat( buffer, "           " );
      if ( remLen < outLen ) {
        strncat( buffer, stmtText+(stmtLen-remLen), remLen );
      }
      else {
        strncat( buffer, stmtText+(stmtLen-remLen), outLen );
      }
      m_session_context.getSqlHandle()->dbpOpError(buffer);
      remLen = remLen - outLen;
    }
  }

  memset( buffer, '\0', sizeof(buffer) );
  sp77sprintf( buffer, bufLen, "Parameter: %d", prmNo );
  m_session_context.getSqlHandle()->dbpOpError(buffer);

  memset( buffer, '\0', sizeof(buffer) );
  sp77sprintf( buffer, bufLen, "Position : %d", pos );
  m_session_context.getSqlHandle()->dbpOpError(buffer);

  memset( buffer, '\0', sizeof(buffer) );
  unsigned char c = *((char*)((m_sqlda.sqlvar + offset + prmNo - 1)->m_desc->vfi.vaddr) + pos - 1);
  sp77sprintf( buffer, bufLen, "Value (x): %x", c );
  m_session_context.getSqlHandle()->dbpOpError(buffer);
}

# endif

/*----------------------------------------------------------------------*/

SqlCol & SQL_Statement::operator[] (int i) {
  if ( (i >= 0) && (i < m_sqlda.sqlmax) ) {
      return *(m_sqlda.sqlvar + i);
  }
  else {
    return *new(SqlCol);
  }
}

/*----------------------------------------------------------------------*/

void * SQL_Statement::operator new (size_t sz) {
# if defined (EXT_CLIENT_SQL)
    void * p = malloc(sz);
    if (!p) {
      throw DbpError(e_new_failed,"new failed");
    }
    return p;
# else
#   if defined (OMSTST)
      co10_GetKernelInterface()->TestBadAlloc();
#   endif
    SAPDBMem_IRawAllocator * m_alloc;
    co10_GetLcSink()->GetSqlClsAllocator(m_alloc);
    return m_alloc->Allocate(sz);
# endif
}

/*----------------------------------------------------------------------*/

void SQL_Statement::operator delete (void * p) {
# if defined (EXT_CLIENT_SQL)
    free(p);
# else
    SAPDBMem_IRawAllocator * m_alloc;
    co10_GetLcSink()->GetSqlClsAllocator(m_alloc);
    m_alloc->Deallocate(p);
# endif
}

