Blame ma_bulk.c

Packit Service 17f749
/************************************************************************************
Packit Service 17f749
   Copyright (C) 2017,2018 MariaDB Corporation AB
Packit Service 17f749
   
Packit Service 17f749
   This library is free software; you can redistribute it and/or
Packit Service 17f749
   modify it under the terms of the GNU Library General Public
Packit Service 17f749
   License as published by the Free Software Foundation; either
Packit Service 17f749
   version 2.1 of the License, or (at your option) any later version.
Packit Service 17f749
   
Packit Service 17f749
   This library is distributed in the hope that it will be useful,
Packit Service 17f749
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 17f749
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 17f749
   Library General Public License for more details.
Packit Service 17f749
   
Packit Service 17f749
   You should have received a copy of the GNU Library General Public
Packit Service 17f749
   License along with this library; if not see <http://www.gnu.org/licenses>
Packit Service 17f749
   or write to the Free Software Foundation, Inc., 
Packit Service 17f749
   51 Franklin St., Fifth Floor, Boston, MA 02110, USA
Packit Service 17f749
*************************************************************************************/
Packit Service 17f749
Packit Service 17f749
/* Code allowing to deploy MariaDB bulk operation functionality.
Packit Service 17f749
 * i.e. adapting ODBC param arrays to MariaDB arrays */
Packit Service 17f749
Packit Service 17f749
#include <ma_odbc.h>
Packit Service 17f749
Packit Service 17f749
#define MAODBC_DATTIME_AS_PTR_ARR 1
Packit Service 17f749
Packit Service 17f749
static BOOL CanUseStructArrForDatetime(MADB_Stmt *Stmt)
Packit Service 17f749
{
Packit Service 17f749
#ifdef MAODBC_DATTIME_AS_PTR_ARR
Packit Service 17f749
  return FALSE;
Packit Service 17f749
#endif
Packit Service 17f749
  return TRUE;
Packit Service 17f749
}
Packit Service 17f749
char MADB_MapIndicatorValue(SQLLEN OdbcInd)
Packit Service 17f749
{
Packit Service 17f749
  switch (OdbcInd)
Packit Service 17f749
  {
Packit Service 17f749
  case SQL_NTS:           return STMT_INDICATOR_NTS;
Packit Service 17f749
  case SQL_COLUMN_IGNORE: return STMT_INDICATOR_IGNORE;
Packit Service 17f749
  case SQL_NULL_DATA:     return STMT_INDICATOR_NULL;
Packit Service 17f749
  case SQL_PARAM_IGNORE:  return STMT_INDICATOR_IGNORE_ROW;
Packit Service 17f749
    /*STMT_INDICATOR_DEFAULT*/
Packit Service 17f749
  }
Packit Service 17f749
  return '\0';
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
BOOL MADB_AppBufferCanBeUsed(SQLSMALLINT CType, SQLSMALLINT SqlType)
Packit Service 17f749
{
Packit Service 17f749
  switch (CType)
Packit Service 17f749
  {
Packit Service 17f749
  case CHAR_BINARY_TYPES:
Packit Service 17f749
    /*if (SqlType != SQL_BIT)
Packit Service 17f749
    {
Packit Service 17f749
      break;
Packit Service 17f749
    }*/
Packit Service 17f749
  case WCHAR_TYPES:
Packit Service 17f749
  case SQL_C_NUMERIC:
Packit Service 17f749
  case DATETIME_TYPES:
Packit Service 17f749
Packit Service 17f749
    return FALSE;
Packit Service 17f749
  }
Packit Service 17f749
  return TRUE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void MADB_CleanBulkOperData(MADB_Stmt *Stmt, unsigned int ParamOffset)
Packit Service 17f749
{
Packit Service 17f749
  if (MADB_DOING_BULK_OPER(Stmt))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_DescRecord *CRec;
Packit Service 17f749
    void            *DataPtr= NULL;
Packit Service 17f749
    MYSQL_BIND      *MaBind= NULL;
Packit Service 17f749
    int             i;
Packit Service 17f749
Packit Service 17f749
    for (i= ParamOffset; i < MADB_STMT_PARAM_COUNT(Stmt); ++i)
Packit Service 17f749
    {
Packit Service 17f749
      if ((CRec= MADB_DescGetInternalRecord(Stmt->Apd, i, MADB_DESC_READ)) != NULL)
Packit Service 17f749
      {
Packit Service 17f749
        MaBind= &Stmt->params[i - ParamOffset];
Packit Service 17f749
        DataPtr= GetBindOffset(Stmt->Apd, CRec, CRec->DataPtr, 0, CRec->OctetLength);
Packit Service 17f749
Packit Service 17f749
        if (MaBind->buffer != DataPtr)
Packit Service 17f749
        {
Packit Service 17f749
          switch (CRec->ConciseType)
Packit Service 17f749
          {
Packit Service 17f749
          case DATETIME_TYPES:
Packit Service 17f749
            if (CanUseStructArrForDatetime(Stmt) == FALSE)
Packit Service 17f749
            {
Packit Service 17f749
              MADB_FREE(MaBind->buffer);
Packit Service 17f749
              break;
Packit Service 17f749
            }
Packit Service 17f749
            /* Otherwise falling through and do the same as for others */
Packit Service 17f749
          case SQL_C_WCHAR:
Packit Service 17f749
          case SQL_C_NUMERIC:
Packit Service 17f749
          {
Packit Service 17f749
            unsigned int i;
Packit Service 17f749
            for (i= 0; i < Stmt->Bulk.ArraySize; ++i)
Packit Service 17f749
            {
Packit Service 17f749
              MADB_FREE(((char**)MaBind->buffer)[i]);
Packit Service 17f749
            }
Packit Service 17f749
          }
Packit Service 17f749
          /* falling through */
Packit Service 17f749
          default:
Packit Service 17f749
            MADB_FREE(MaBind->buffer);
Packit Service 17f749
          }
Packit Service 17f749
        }
Packit Service 17f749
Packit Service 17f749
        MADB_FREE(MaBind->length);
Packit Service 17f749
Packit Service 17f749
        MADB_FREE(MaBind->u.indicator);
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
    Stmt->Bulk.ArraySize= 0;
Packit Service 17f749
    Stmt->Bulk.HasRowsToSkip= 0;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
SQLRETURN MADB_InitIndicatorArray(MADB_Stmt *Stmt, MYSQL_BIND *MaBind, char InitValue)
Packit Service 17f749
{
Packit Service 17f749
  MaBind->u.indicator= MADB_ALLOC(Stmt->Bulk.ArraySize);
Packit Service 17f749
Packit Service 17f749
  if (MaBind->u.indicator == NULL)
Packit Service 17f749
  {
Packit Service 17f749
    return MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
  }
Packit Service 17f749
  memset(MaBind->u.indicator, InitValue, Stmt->Bulk.ArraySize);
Packit Service 17f749
Packit Service 17f749
  return SQL_SUCCESS;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
SQLRETURN MADB_SetBulkOperLengthArr(MADB_Stmt *Stmt, MADB_DescRecord *CRec, SQLLEN *OctetLengthPtr, SQLLEN *IndicatorPtr,
Packit Service 17f749
                                    void *DataPtr, MYSQL_BIND *MaBind, BOOL VariableLengthMadbType)
Packit Service 17f749
{
Packit Service 17f749
  /* Leaving it so far here commented, but it comlicates things w/out much gains */
Packit Service 17f749
  /*if (sizeof(SQLLEN) == sizeof(long) && MADB_AppBufferCanBeUsed())
Packit Service 17f749
  {
Packit Service 17f749
    if (OctetLengthPtr)
Packit Service 17f749
    {
Packit Service 17f749
      MaBind->length= OctetLengthPtr;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  else
Packit Service 17f749
  {*/
Packit Service 17f749
  unsigned int row;
Packit Service 17f749
Packit Service 17f749
  if (VariableLengthMadbType)
Packit Service 17f749
  {
Packit Service 17f749
    MaBind->length= MADB_REALLOC(MaBind->length, Stmt->Bulk.ArraySize*sizeof(long));
Packit Service 17f749
    if (MaBind->length == NULL)
Packit Service 17f749
    {
Packit Service 17f749
      return MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  for (row= 0; row < Stmt->Apd->Header.ArraySize; ++row, DataPtr= (char*)DataPtr + CRec->OctetLength)
Packit Service 17f749
  {
Packit Service 17f749
    if (Stmt->Apd->Header.ArrayStatusPtr != NULL && Stmt->Apd->Header.ArrayStatusPtr[row] == SQL_PARAM_IGNORE)
Packit Service 17f749
    {
Packit Service 17f749
      Stmt->Bulk.HasRowsToSkip= 1;
Packit Service 17f749
      continue;
Packit Service 17f749
    }
Packit Service 17f749
Packit Service 17f749
    if ((OctetLengthPtr != NULL && OctetLengthPtr[row] == SQL_NULL_DATA)
Packit Service 17f749
      || (IndicatorPtr != NULL && IndicatorPtr[row] != SQL_NULL_DATA))
Packit Service 17f749
    {
Packit Service 17f749
      RETURN_ERROR_OR_CONTINUE(MADB_SetIndicatorValue(Stmt, MaBind, row, SQL_NULL_DATA));
Packit Service 17f749
      continue;
Packit Service 17f749
    }
Packit Service 17f749
    if ((OctetLengthPtr != NULL && OctetLengthPtr[row] == SQL_COLUMN_IGNORE)
Packit Service 17f749
      || (IndicatorPtr != NULL && IndicatorPtr[row] != SQL_COLUMN_IGNORE))
Packit Service 17f749
    {
Packit Service 17f749
      RETURN_ERROR_OR_CONTINUE(MADB_SetIndicatorValue(Stmt, MaBind, row, SQL_COLUMN_IGNORE));
Packit Service 17f749
      continue;
Packit Service 17f749
    }
Packit Service 17f749
Packit Service 17f749
    if (VariableLengthMadbType)
Packit Service 17f749
    {
Packit Service 17f749
      MaBind->length[row]= (unsigned long)MADB_CalculateLength(Stmt, OctetLengthPtr != NULL ? &OctetLengthPtr[row] : NULL, CRec, DataPtr);
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return SQL_SUCCESS;
Packit Service 17f749
}
Packit Service 17f749
/* {{{ MADB_InitBulkOperBuffers */
Packit Service 17f749
/* Allocating data and length arrays, if needed, and initing them in certain cases.
Packit Service 17f749
   DataPtr should be ensured to be not NULL */
Packit Service 17f749
SQLRETURN MADB_InitBulkOperBuffers(MADB_Stmt *Stmt, MADB_DescRecord *CRec, void *DataPtr, SQLLEN *OctetLengthPtr,
Packit Service 17f749
                                   SQLLEN *IndicatorPtr, SQLSMALLINT SqlType, MYSQL_BIND *MaBind)
Packit Service 17f749
{
Packit Service 17f749
  BOOL VariableLengthMadbType= TRUE;
Packit Service 17f749
Packit Service 17f749
  MaBind->buffer_length= 0;
Packit Service 17f749
  MaBind->buffer_type= MADB_GetMaDBTypeAndLength(CRec->ConciseType, &MaBind->is_unsigned, &MaBind->buffer_length);
Packit Service 17f749
Packit Service 17f749
  /* For fixed length types MADB_GetMaDBTypeAndLength has set buffer_length */
Packit Service 17f749
  if (MaBind->buffer_length != 0)
Packit Service 17f749
  {
Packit Service 17f749
    VariableLengthMadbType= FALSE;
Packit Service 17f749
  }
Packit Service 17f749
  switch (CRec->ConciseType)
Packit Service 17f749
  {
Packit Service 17f749
  case CHAR_BINARY_TYPES:
Packit Service 17f749
    if (SqlType == SQL_BIT)
Packit Service 17f749
    {
Packit Service 17f749
      CRec->InternalBuffer= MADB_CALLOC(Stmt->Bulk.ArraySize);
Packit Service 17f749
      MaBind->buffer_length= 1;
Packit Service 17f749
      break;
Packit Service 17f749
    }
Packit Service 17f749
  case DATETIME_TYPES:
Packit Service 17f749
    if (CanUseStructArrForDatetime(Stmt) == TRUE)
Packit Service 17f749
    {
Packit Service 17f749
      CRec->InternalBuffer= MADB_ALLOC(Stmt->Bulk.ArraySize*sizeof(MYSQL_TIME));
Packit Service 17f749
      MaBind->buffer_length= sizeof(MYSQL_TIME);
Packit Service 17f749
      break;
Packit Service 17f749
    }
Packit Service 17f749
    /* Otherwise falling thru and allocating array of pointers */
Packit Service 17f749
  case WCHAR_TYPES:
Packit Service 17f749
  case SQL_C_NUMERIC:
Packit Service 17f749
    CRec->InternalBuffer= MADB_CALLOC(Stmt->Bulk.ArraySize*sizeof(char*));
Packit Service 17f749
    MaBind->buffer_length= sizeof(char*);
Packit Service 17f749
    break;
Packit Service 17f749
  default:
Packit Service 17f749
    MaBind->buffer= DataPtr;
Packit Service 17f749
    if (MaBind->buffer_length == 0)
Packit Service 17f749
    {
Packit Service 17f749
      MaBind->buffer_length= sizeof(char*);
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  if (MaBind->buffer != DataPtr)
Packit Service 17f749
  {
Packit Service 17f749
    MaBind->buffer= CRec->InternalBuffer;
Packit Service 17f749
    if (MaBind->buffer == NULL)
Packit Service 17f749
    {
Packit Service 17f749
      return MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
    }
Packit Service 17f749
    CRec->InternalBuffer= NULL; /* Need to reset this pointer, so the memory won't be freed (accidentally) */
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return MADB_SetBulkOperLengthArr(Stmt, CRec, OctetLengthPtr, IndicatorPtr, DataPtr, MaBind, VariableLengthMadbType);
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_SetIndicatorValue */
Packit Service 17f749
SQLRETURN MADB_SetIndicatorValue(MADB_Stmt *Stmt, MYSQL_BIND *MaBind, unsigned int row, SQLLEN OdbcIndicator)
Packit Service 17f749
{
Packit Service 17f749
  if (MaBind->u.indicator == NULL)
Packit Service 17f749
  {
Packit Service 17f749
    RETURN_ERROR_OR_CONTINUE(MADB_InitIndicatorArray(Stmt, MaBind, STMT_INDICATOR_NONE));
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  MaBind->u.indicator[row]= MADB_MapIndicatorValue(OdbcIndicator);
Packit Service 17f749
  return SQL_SUCCESS;
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_ExecuteBulk */
Packit Service 17f749
/* Assuming that bulk insert can't go with DAE(and that unlikely ever changes). And that it has been checked before this call,
Packit Service 17f749
and we can't have DAE here */
Packit Service 17f749
SQLRETURN MADB_ExecuteBulk(MADB_Stmt *Stmt, unsigned int ParamOffset)
Packit Service 17f749
{
Packit Service 17f749
  unsigned int  i, IndIdx= -1;
Packit Service 17f749
  unsigned long Dummy;
Packit Service 17f749
Packit Service 17f749
  for (i= ParamOffset; i < ParamOffset + MADB_STMT_PARAM_COUNT(Stmt); ++i)
Packit Service 17f749
  {
Packit Service 17f749
    MADB_DescRecord *CRec, *SqlRec;
Packit Service 17f749
    SQLLEN          *IndicatorPtr= NULL;
Packit Service 17f749
    SQLLEN          *OctetLengthPtr= NULL;
Packit Service 17f749
    void            *DataPtr= NULL;
Packit Service 17f749
    MYSQL_BIND      *MaBind= &Stmt->params[i - ParamOffset];
Packit Service 17f749
    SQLULEN         row, Start= Stmt->ArrayOffset;
Packit Service 17f749
Packit Service 17f749
    if ((CRec= MADB_DescGetInternalRecord(Stmt->Apd, i, MADB_DESC_READ)) &&
Packit Service 17f749
      (SqlRec= MADB_DescGetInternalRecord(Stmt->Ipd, i, MADB_DESC_READ)))
Packit Service 17f749
    {
Packit Service 17f749
      /* check if parameter was bound */
Packit Service 17f749
      if (!CRec->inUse)
Packit Service 17f749
      {
Packit Service 17f749
        return MADB_SetError(&Stmt->Error, MADB_ERR_07002, NULL, 0);
Packit Service 17f749
      }
Packit Service 17f749
Packit Service 17f749
      if (MADB_ConversionSupported(CRec, SqlRec) == FALSE)
Packit Service 17f749
      {
Packit Service 17f749
        return MADB_SetError(&Stmt->Error, MADB_ERR_07006, NULL, 0);
Packit Service 17f749
      }
Packit Service 17f749
Packit Service 17f749
      MaBind->length= NULL;
Packit Service 17f749
      IndicatorPtr=   (SQLLEN *)GetBindOffset(Stmt->Apd, CRec, CRec->IndicatorPtr, 0, sizeof(SQLLEN));
Packit Service 17f749
      OctetLengthPtr= (SQLLEN *)GetBindOffset(Stmt->Apd, CRec, CRec->OctetLengthPtr, 0, sizeof(SQLLEN));
Packit Service 17f749
      DataPtr=        GetBindOffset(Stmt->Apd, CRec, CRec->DataPtr, 0, CRec->OctetLength);
Packit Service 17f749
Packit Service 17f749
      /* If these are the same pointers, setting indicator to NULL to simplify things a bit */
Packit Service 17f749
      if (IndicatorPtr == OctetLengthPtr)
Packit Service 17f749
      {
Packit Service 17f749
        IndicatorPtr= NULL;
Packit Service 17f749
      }
Packit Service 17f749
      /* Well, specs kinda say, that both values and lenghts arrays should be set(in instruction to param array operations)
Packit Service 17f749
         But there is no error/sqlstate for the case if any of those pointers is not set. Thus we assume that is possible */
Packit Service 17f749
      if (DataPtr == NULL)
Packit Service 17f749
      {
Packit Service 17f749
        /* Special case - DataPtr is not set, we treat it as all values are NULL. Setting indicators and moving on next param */
Packit Service 17f749
        RETURN_ERROR_OR_CONTINUE(MADB_InitIndicatorArray(Stmt, MaBind, MADB_MapIndicatorValue(SQL_NULL_DATA)));
Packit Service 17f749
        continue;
Packit Service 17f749
      }
Packit Service 17f749
Packit Service 17f749
      /* Sets Stmt->Bulk.HasRowsToSkip if needed, since it traverses and checks status array anyway */
Packit Service 17f749
      RETURN_ERROR_OR_CONTINUE(MADB_InitBulkOperBuffers(Stmt, CRec, DataPtr, OctetLengthPtr, IndicatorPtr, SqlRec->ConciseType, MaBind));
Packit Service 17f749
Packit Service 17f749
      if (MaBind->u.indicator != NULL && IndIdx == (unsigned int)-1)
Packit Service 17f749
      {
Packit Service 17f749
        IndIdx= i - ParamOffset;
Packit Service 17f749
      }
Packit Service 17f749
Packit Service 17f749
      /* Doing it on last parameter - just to do do this once, and to use already allocated indicator array.
Packit Service 17f749
         Little stupid optimization. But it's actually even a bit simpler this way */
Packit Service 17f749
      if (i == ParamOffset + MADB_STMT_PARAM_COUNT(Stmt) - 1 && Stmt->Bulk.HasRowsToSkip)
Packit Service 17f749
      {
Packit Service 17f749
        if (IndIdx == (unsigned int)-1)
Packit Service 17f749
        {
Packit Service 17f749
          IndIdx= 0;
Packit Service 17f749
        }
Packit Service 17f749
Packit Service 17f749
        for (row= Start; row < Start + Stmt->Apd->Header.ArraySize; ++row)
Packit Service 17f749
        {
Packit Service 17f749
          if (Stmt->Apd->Header.ArrayStatusPtr[row] == SQL_PARAM_IGNORE)
Packit Service 17f749
          {
Packit Service 17f749
            MADB_SetIndicatorValue(Stmt, &Stmt->params[IndIdx], (unsigned int)row, SQL_PARAM_IGNORE);
Packit Service 17f749
          }
Packit Service 17f749
        }       
Packit Service 17f749
      }
Packit Service 17f749
Packit Service 17f749
      if (MADB_AppBufferCanBeUsed(CRec->ConciseType, SqlRec->ConciseType))
Packit Service 17f749
      {
Packit Service 17f749
        /* Everything has been done for such column already */
Packit Service 17f749
        continue;
Packit Service 17f749
      }
Packit Service 17f749
Packit Service 17f749
      /* We either have skipped rows or need to convert parameter values/convert array */
Packit Service 17f749
      for (row= Start; row < Start + Stmt->Apd->Header.ArraySize; ++row, DataPtr= (char*)DataPtr + CRec->OctetLength)
Packit Service 17f749
      {
Packit Service 17f749
        void *Buffer= (char*)MaBind->buffer + row*MaBind->buffer_length;
Packit Service 17f749
        void **BufferPtr= (void**)Buffer; /* For the case when Buffer points to the pointer already */
Packit Service 17f749
Packit Service 17f749
        if (Stmt->Apd->Header.ArrayStatusPtr != NULL && Stmt->Apd->Header.ArrayStatusPtr[row] == SQL_PARAM_IGNORE)
Packit Service 17f749
        {
Packit Service 17f749
          continue;
Packit Service 17f749
        }
Packit Service 17f749
        if (MaBind->u.indicator && MaBind->u.indicator[row] > STMT_INDICATOR_NONE)
Packit Service 17f749
        {
Packit Service 17f749
          continue;
Packit Service 17f749
        }
Packit Service 17f749
Packit Service 17f749
        switch (CRec->ConciseType)
Packit Service 17f749
        {
Packit Service 17f749
        case SQL_C_CHAR:
Packit Service 17f749
          if (SqlRec->ConciseType != SQL_BIT)
Packit Service 17f749
          {
Packit Service 17f749
            break;
Packit Service 17f749
          }
Packit Service 17f749
        case DATETIME_TYPES:
Packit Service 17f749
          if (CanUseStructArrForDatetime(Stmt))
Packit Service 17f749
          {
Packit Service 17f749
            BufferPtr= &Buffer;
Packit Service 17f749
          }
Packit Service 17f749
        }
Packit Service 17f749
Packit Service 17f749
        /* Need &Dummy here as a length ptr, since NULL is not good here.
Packit Service 17f749
           It would make MADB_ConvertC2Sql to use MaBind->buffer_length by default */
Packit Service 17f749
        if (!SQL_SUCCEEDED(MADB_ConvertC2Sql(Stmt, CRec, DataPtr, MaBind->length != NULL ? MaBind->length[row] : 0,
Packit Service 17f749
          SqlRec, MaBind, BufferPtr, MaBind->length != NULL ? MaBind->length + row : &Dummy)))
Packit Service 17f749
        {
Packit Service 17f749
          /* Perhaps it's better to move to Clean function */
Packit Service 17f749
          CRec->InternalBuffer= NULL;
Packit Service 17f749
          return Stmt->Error.ReturnValue;
Packit Service 17f749
        }
Packit Service 17f749
        CRec->InternalBuffer= NULL;
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return MADB_DoExecute(Stmt, FALSE);
Packit Service 17f749
}
Packit Service 17f749
/* }}} */