|
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 |
/* }}} */
|