Blame ma_helper.c

Packit Service 17f749
/************************************************************************************
Packit Service 17f749
   Copyright (C) 2013, 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
#include <ma_odbc.h>
Packit Service 17f749
#include <stdint.h>
Packit Service 17f749
Packit Service 17f749
#define MADB_FIELD_IS_BINARY(_field) ((_field)->charsetnr == BINARY_CHARSETNR)
Packit Service 17f749
Packit Service 17f749
void CloseMultiStatements(MADB_Stmt *Stmt)
Packit Service 17f749
{
Packit Service 17f749
  unsigned int i;
Packit Service 17f749
Packit Service 17f749
  for (i=0; i < STMT_COUNT(Stmt->Query); ++i)
Packit Service 17f749
  {
Packit Service 17f749
    MDBUG_C_PRINT(Stmt->Connection, "-->closing %0x", Stmt->MultiStmts[i]);
Packit Service 17f749
    if (Stmt->MultiStmts[i] != NULL)
Packit Service 17f749
    {
Packit Service 17f749
      mysql_stmt_close(Stmt->MultiStmts[i]);
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  MADB_FREE(Stmt->MultiStmts);
Packit Service 17f749
  Stmt->stmt= NULL;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
MYSQL_STMT* MADB_NewStmtHandle(MADB_Stmt *Stmt)
Packit Service 17f749
{
Packit Service 17f749
  static const my_bool UpdateMaxLength= 1;
Packit Service 17f749
  MYSQL_STMT* stmt= mysql_stmt_init(Stmt->Connection->mariadb);
Packit Service 17f749
Packit Service 17f749
  if (stmt != NULL)
Packit Service 17f749
  {
Packit Service 17f749
    mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &UpdateMaxLength);
Packit Service 17f749
  }
Packit Service 17f749
  else
Packit Service 17f749
  {
Packit Service 17f749
    MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return stmt;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* Required, but not sufficient condition */
Packit Service 17f749
BOOL QueryIsPossiblyMultistmt(MADB_QUERY *Query)
Packit Service 17f749
{
Packit Service 17f749
  return Query->QueryType != MADB_QUERY_CREATE_PROC && Query->QueryType != MADB_QUERY_CREATE_FUNC &&
Packit Service 17f749
         Query->QueryType != MADB_QUERY_CREATE_DEFINER && Query->QueryType != MADB_NOT_ATOMIC_BLOCK;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/* Trims spaces and/or ';' at the end of query */
Packit Service 17f749
int SqlRtrim(char *StmtStr, int Length)
Packit Service 17f749
{
Packit Service 17f749
  if (Length > 0)
Packit Service 17f749
  {
Packit Service 17f749
    char *end= StmtStr + Length - 1;
Packit Service 17f749
    while (end > StmtStr && (isspace(0x000000ff & *end) || *end == ';'))
Packit Service 17f749
    {
Packit Service 17f749
      *end= '\0';
Packit Service 17f749
      --end;
Packit Service 17f749
      --Length;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return Length;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* Function assumes that the query is multistatement. And, e.g. STMT_COUNT(Stmt->Query) > 1 */
Packit Service 17f749
unsigned int GetMultiStatements(MADB_Stmt *Stmt, BOOL ExecDirect)
Packit Service 17f749
{
Packit Service 17f749
  int          i= 0;
Packit Service 17f749
  unsigned int MaxParams= 0;
Packit Service 17f749
  char        *p= Stmt->Query.RefinedText;
Packit Service 17f749
Packit Service 17f749
  Stmt->MultiStmtNr= 0;
Packit Service 17f749
  Stmt->MultiStmts= (MYSQL_STMT **)MADB_CALLOC(sizeof(MYSQL_STMT) * STMT_COUNT(Stmt->Query));
Packit Service 17f749
Packit Service 17f749
  while (p < Stmt->Query.RefinedText + Stmt->Query.RefinedLength)
Packit Service 17f749
  {
Packit Service 17f749
    Stmt->MultiStmts[i]= i == 0 ? Stmt->stmt : MADB_NewStmtHandle(Stmt);
Packit Service 17f749
    MDBUG_C_PRINT(Stmt->Connection, "-->inited&preparing %0x(%d,%s)", Stmt->MultiStmts[i], i, p);
Packit Service 17f749
Packit Service 17f749
    if (mysql_stmt_prepare(Stmt->MultiStmts[i], p, (unsigned long)strlen(p)))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetNativeError(&Stmt->Error, SQL_HANDLE_STMT, Stmt->MultiStmts[i]);
Packit Service 17f749
      CloseMultiStatements(Stmt);
Packit Service 17f749
Packit Service 17f749
      /* Last paranoid attempt make sure that we did not have a parsing error.
Packit Service 17f749
         More to preserve "backward-compatibility" - we did this before, but before trying to
Packit Service 17f749
         prepare "multi-statement". */
Packit Service 17f749
      if (i == 0 && Stmt->Error.NativeError !=1295 /*ER_UNSUPPORTED_PS*/)
Packit Service 17f749
      {
Packit Service 17f749
        Stmt->stmt= MADB_NewStmtHandle(Stmt);
Packit Service 17f749
        if (mysql_stmt_prepare(Stmt->stmt, STMT_STRING(Stmt), (unsigned long)strlen(STMT_STRING(Stmt))))
Packit Service 17f749
        {
Packit Service 17f749
          MADB_STMT_CLOSE_STMT(Stmt);
Packit Service 17f749
        }
Packit Service 17f749
        else
Packit Service 17f749
        {
Packit Service 17f749
          MADB_DeleteSubqueries(&Stmt->Query);
Packit Service 17f749
          return 0;
Packit Service 17f749
        }
Packit Service 17f749
      }
Packit Service 17f749
      return 1;
Packit Service 17f749
    }
Packit Service 17f749
    if (mysql_stmt_param_count(Stmt->MultiStmts[i]) > MaxParams)
Packit Service 17f749
    {
Packit Service 17f749
      MaxParams= mysql_stmt_param_count(Stmt->MultiStmts[i]);
Packit Service 17f749
    }
Packit Service 17f749
    p+= strlen(p) + 1;
Packit Service 17f749
    ++i;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  if (MaxParams)
Packit Service 17f749
  {
Packit Service 17f749
    Stmt->params= (MYSQL_BIND *)MADB_CALLOC(sizeof(MYSQL_BIND) * MaxParams);
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return 0;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
my_bool MADB_CheckPtrLength(SQLINTEGER MaxLength, char *Ptr, SQLINTEGER NameLen)
Packit Service 17f749
{
Packit Service 17f749
  if(!Ptr)
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  if ((NameLen == SQL_NTS && strlen(Ptr) >(size_t) MaxLength) || NameLen > MaxLength)
Packit Service 17f749
    return FALSE;
Packit Service 17f749
  return TRUE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
int  MADB_GetWCharType(int Type)
Packit Service 17f749
{
Packit Service 17f749
  switch (Type) {
Packit Service 17f749
  case SQL_CHAR:
Packit Service 17f749
    return SQL_WCHAR;
Packit Service 17f749
  case SQL_VARCHAR:
Packit Service 17f749
    return SQL_WVARCHAR;
Packit Service 17f749
  case SQL_LONGVARCHAR:
Packit Service 17f749
    return SQL_WLONGVARCHAR;
Packit Service 17f749
  default:
Packit Service 17f749
    return Type;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
int MADB_KeyTypeCount(MADB_Dbc *Connection, char *TableName, int KeyFlag)
Packit Service 17f749
{
Packit Service 17f749
  int          Count= 0;
Packit Service 17f749
  unsigned int i;
Packit Service 17f749
  char         StmtStr[1024];
Packit Service 17f749
  char         *p= StmtStr;
Packit Service 17f749
  char         Database[65]= {'\0'};
Packit Service 17f749
  MADB_Stmt    *Stmt= NULL;
Packit Service 17f749
  MYSQL_FIELD  *Field;
Packit Service 17f749
  
Packit Service 17f749
  Connection->Methods->GetAttr(Connection, SQL_ATTR_CURRENT_CATALOG, Database, 65, NULL, FALSE);
Packit Service 17f749
  p+= _snprintf(p, 1024, "SELECT * FROM ");
Packit Service 17f749
  if (Database[0] != '\0')
Packit Service 17f749
  {
Packit Service 17f749
    p+= _snprintf(p, sizeof(StmtStr) - strlen(p), "`%s`.", Database);
Packit Service 17f749
  }
Packit Service 17f749
  p+= _snprintf(p, sizeof(StmtStr) - strlen(p), "%s LIMIT 0", TableName);
Packit Service 17f749
  if (MA_SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE)Connection, (SQLHANDLE*)&Stmt) == SQL_ERROR ||
Packit Service 17f749
    Stmt->Methods->ExecDirect(Stmt, (char *)StmtStr, SQL_NTS) == SQL_ERROR ||
Packit Service 17f749
    Stmt->Methods->Fetch(Stmt) == SQL_ERROR)
Packit Service 17f749
  {
Packit Service 17f749
    goto end;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    Field= mysql_fetch_field_direct(Stmt->metadata, i);
Packit Service 17f749
    if (Field->flags & KeyFlag)
Packit Service 17f749
    {
Packit Service 17f749
      ++Count;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
end:
Packit Service 17f749
  if (Stmt)
Packit Service 17f749
  {
Packit Service 17f749
    Stmt->Methods->StmtFree(Stmt, SQL_DROP);
Packit Service 17f749
  }
Packit Service 17f749
  return Count;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_CheckODBCType */
Packit Service 17f749
BOOL MADB_CheckODBCType(SQLSMALLINT Type)
Packit Service 17f749
{
Packit Service 17f749
  switch(Type)
Packit Service 17f749
  {
Packit Service 17f749
  case SQL_C_CHAR:
Packit Service 17f749
  case SQL_C_WCHAR:
Packit Service 17f749
  case SQL_C_SSHORT:
Packit Service 17f749
  case SQL_C_SHORT:
Packit Service 17f749
  case SQL_C_USHORT:
Packit Service 17f749
  case SQL_C_SLONG:
Packit Service 17f749
  case SQL_C_LONG:
Packit Service 17f749
  case SQL_C_ULONG:
Packit Service 17f749
  case SQL_C_FLOAT:
Packit Service 17f749
  case SQL_C_DOUBLE:
Packit Service 17f749
  case SQL_C_BIT:
Packit Service 17f749
  case SQL_C_STINYINT:
Packit Service 17f749
  case SQL_C_TINYINT:
Packit Service 17f749
  case SQL_C_UTINYINT:
Packit Service 17f749
  case SQL_C_SBIGINT:
Packit Service 17f749
  case SQL_C_UBIGINT:
Packit Service 17f749
  case SQL_C_BINARY:
Packit Service 17f749
  case SQL_C_TYPE_DATE:
Packit Service 17f749
  case SQL_C_TYPE_TIME:
Packit Service 17f749
  case SQL_C_TYPE_TIMESTAMP:
Packit Service 17f749
  case SQL_C_NUMERIC:
Packit Service 17f749
#if (ODBCVER>=0x0350)
Packit Service 17f749
  case SQL_C_GUID:
Packit Service 17f749
#endif
Packit Service 17f749
  case SQL_C_DEFAULT:
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  default:
Packit Service 17f749
    return FALSE;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_GetTypeFromConciseType */
Packit Service 17f749
SQLSMALLINT MADB_GetTypeFromConciseType(SQLSMALLINT ConciseType)
Packit Service 17f749
{
Packit Service 17f749
  switch (ConciseType)
Packit Service 17f749
  {
Packit Service 17f749
    /* todo: support for interval. currently we map only date/time types */
Packit Service 17f749
  case SQL_C_DATE:
Packit Service 17f749
  case SQL_C_TIME:
Packit Service 17f749
  case SQL_C_TIMESTAMP:
Packit Service 17f749
  case SQL_TYPE_DATE:
Packit Service 17f749
  case SQL_TYPE_TIME:
Packit Service 17f749
  case SQL_TYPE_TIMESTAMP:
Packit Service 17f749
    return SQL_DATETIME;
Packit Service 17f749
  case SQL_C_INTERVAL_YEAR:
Packit Service 17f749
  case SQL_C_INTERVAL_YEAR_TO_MONTH:
Packit Service 17f749
  case SQL_C_INTERVAL_MONTH:
Packit Service 17f749
  case SQL_C_INTERVAL_DAY:
Packit Service 17f749
  case SQL_C_INTERVAL_DAY_TO_HOUR:
Packit Service 17f749
  case SQL_C_INTERVAL_DAY_TO_MINUTE:
Packit Service 17f749
  case SQL_C_INTERVAL_DAY_TO_SECOND:
Packit Service 17f749
  case SQL_C_INTERVAL_HOUR:
Packit Service 17f749
  case SQL_C_INTERVAL_HOUR_TO_MINUTE:
Packit Service 17f749
  case SQL_C_INTERVAL_HOUR_TO_SECOND:
Packit Service 17f749
  case SQL_C_INTERVAL_MINUTE:
Packit Service 17f749
  case SQL_C_INTERVAL_MINUTE_TO_SECOND:
Packit Service 17f749
  case SQL_C_INTERVAL_SECOND:
Packit Service 17f749
      return SQL_INTERVAL;
Packit Service 17f749
  default:
Packit Service 17f749
    return ConciseType;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_GetTypeName */
Packit Service 17f749
char *MADB_GetTypeName(MYSQL_FIELD *Field)
Packit Service 17f749
{
Packit Service 17f749
  switch(Field->type) {
Packit Service 17f749
  case MYSQL_TYPE_DECIMAL:
Packit Service 17f749
  case MYSQL_TYPE_NEWDECIMAL:
Packit Service 17f749
    return "decimal";
Packit Service 17f749
  case MYSQL_TYPE_NULL:
Packit Service 17f749
    return "null";
Packit Service 17f749
  case MYSQL_TYPE_TINY:
Packit Service 17f749
    return (Field->flags & NUM_FLAG) ? "tinyint" : "char";
Packit Service 17f749
  case MYSQL_TYPE_SHORT:
Packit Service 17f749
    return "smallint";
Packit Service 17f749
  case MYSQL_TYPE_LONG:
Packit Service 17f749
    return "integer";
Packit Service 17f749
  case MYSQL_TYPE_FLOAT:
Packit Service 17f749
    return "float";
Packit Service 17f749
  case MYSQL_TYPE_DOUBLE:
Packit Service 17f749
    return "double";
Packit Service 17f749
  case MYSQL_TYPE_TIMESTAMP:
Packit Service 17f749
    return "timestamp";
Packit Service 17f749
  case MYSQL_TYPE_LONGLONG:
Packit Service 17f749
    return "bigint";
Packit Service 17f749
  case MYSQL_TYPE_INT24:
Packit Service 17f749
    return "mediumint";
Packit Service 17f749
  case MYSQL_TYPE_DATE:
Packit Service 17f749
    return "date";
Packit Service 17f749
  case MYSQL_TYPE_TIME:
Packit Service 17f749
    return "time";
Packit Service 17f749
  case MYSQL_TYPE_DATETIME:
Packit Service 17f749
    return "datetime";
Packit Service 17f749
  case MYSQL_TYPE_YEAR:
Packit Service 17f749
    return "year";
Packit Service 17f749
  case MYSQL_TYPE_NEWDATE:
Packit Service 17f749
    return "date";
Packit Service 17f749
  case MYSQL_TYPE_VARCHAR:
Packit Service 17f749
  case MYSQL_TYPE_VAR_STRING:
Packit Service 17f749
    return MADB_FIELD_IS_BINARY(Field) ? "varbinary" : "varchar";
Packit Service 17f749
  case MYSQL_TYPE_BIT:
Packit Service 17f749
    return "bit";
Packit Service 17f749
  case MYSQL_TYPE_ENUM:
Packit Service 17f749
    return "enum";
Packit Service 17f749
  case MYSQL_TYPE_SET:
Packit Service 17f749
    return "set";
Packit Service 17f749
  case MYSQL_TYPE_TINY_BLOB:
Packit Service 17f749
    return MADB_FIELD_IS_BINARY(Field) ? "tinyblob" : "tinytext";
Packit Service 17f749
  case MYSQL_TYPE_MEDIUM_BLOB:
Packit Service 17f749
    return MADB_FIELD_IS_BINARY(Field) ? "mediumblob" : "mediumtext";
Packit Service 17f749
  case MYSQL_TYPE_LONG_BLOB:
Packit Service 17f749
    return MADB_FIELD_IS_BINARY(Field) ? "longblob" : "longtext";
Packit Service 17f749
  case MYSQL_TYPE_BLOB:
Packit Service 17f749
    return MADB_FIELD_IS_BINARY(Field) ? "blob" : "text";
Packit Service 17f749
  case MYSQL_TYPE_STRING:
Packit Service 17f749
    return MADB_FIELD_IS_BINARY(Field) ? "binary" : "char";
Packit Service 17f749
  case MYSQL_TYPE_GEOMETRY:
Packit Service 17f749
    return "geometry";
Packit Service 17f749
  default:
Packit Service 17f749
    return "";
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
MYSQL_RES *MADB_GetDefaultColumnValues(MADB_Stmt *Stmt, MYSQL_FIELD *fields)
Packit Service 17f749
{
Packit Service 17f749
  MADB_DynString DynStr;
Packit Service 17f749
  unsigned int i;
Packit Service 17f749
  MYSQL_RES *result= NULL;
Packit Service 17f749
  
Packit Service 17f749
  MADB_InitDynamicString(&DynStr, "SELECT COLUMN_NAME, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='", 512, 512);
Packit Service 17f749
  if (MADB_DynstrAppend(&DynStr, fields[0].db) ||
Packit Service 17f749
      MADB_DynstrAppend(&DynStr, "' AND TABLE_NAME='") ||
Packit Service 17f749
      MADB_DynstrAppend(&DynStr, fields[0].org_table) ||
Packit Service 17f749
      MADB_DynstrAppend(&DynStr, "' AND COLUMN_NAME IN ("))
Packit Service 17f749
    goto error;
Packit Service 17f749
Packit Service 17f749
  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    MADB_DescRecord *Rec= MADB_DescGetInternalRecord(Stmt->Ard, i, MADB_DESC_READ);
Packit Service 17f749
Packit Service 17f749
    if (!Rec->inUse || MADB_ColumnIgnoredInAllRows(Stmt->Ard, Rec) == TRUE)
Packit Service 17f749
    {
Packit Service 17f749
      continue;
Packit Service 17f749
    }
Packit Service 17f749
    if (MADB_DynstrAppend(&DynStr, i > 0 ? ",'" : "'") ||
Packit Service 17f749
      MADB_DynstrAppend(&DynStr, fields[i].org_name) ||
Packit Service 17f749
      MADB_DynstrAppend(&DynStr, "'"))
Packit Service 17f749
    {
Packit Service 17f749
      goto error;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  if (MADB_DynstrAppend(&DynStr, ") AND COLUMN_DEFAULT IS NOT NULL"))
Packit Service 17f749
    goto error;
Packit Service 17f749
Packit Service 17f749
  LOCK_MARIADB(Stmt->Connection);
Packit Service 17f749
  if (mysql_query(Stmt->Connection->mariadb, DynStr.str))
Packit Service 17f749
    goto error;
Packit Service 17f749
  result= mysql_store_result(Stmt->Connection->mariadb);
Packit Service 17f749
  
Packit Service 17f749
error:
Packit Service 17f749
    UNLOCK_MARIADB(Stmt->Connection);
Packit Service 17f749
    MADB_DynstrFree(&DynStr);
Packit Service 17f749
    return result;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
char *MADB_GetDefaultColumnValue(MYSQL_RES *res, const char *Column)
Packit Service 17f749
{
Packit Service 17f749
  MYSQL_ROW row;
Packit Service 17f749
Packit Service 17f749
  if (res == NULL || !res->row_count)
Packit Service 17f749
    return NULL;
Packit Service 17f749
  mysql_data_seek(res, 0);
Packit Service 17f749
  while ((row= mysql_fetch_row(res)))
Packit Service 17f749
  {
Packit Service 17f749
    if (_stricmp(row[0], Column) == 0)
Packit Service 17f749
     return _strdup(row[1]);
Packit Service 17f749
  }
Packit Service 17f749
  return NULL;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
SQLLEN MADB_GetDataSize(SQLSMALLINT SqlType, SQLLEN OctetLength, BOOL Unsigned,
Packit Service 17f749
                        SQLSMALLINT Precision, SQLSMALLINT Scale, unsigned int CharMaxLen)
Packit Service 17f749
{
Packit Service 17f749
  switch(SqlType)
Packit Service 17f749
  {
Packit Service 17f749
  case SQL_BIT:
Packit Service 17f749
    return 1;
Packit Service 17f749
  case SQL_TINYINT:
Packit Service 17f749
    return 3;
Packit Service 17f749
  case SQL_SMALLINT:
Packit Service 17f749
    return 5;
Packit Service 17f749
  case SQL_INTEGER:
Packit Service 17f749
    return 10;
Packit Service 17f749
  case SQL_BIGINT:
Packit Service 17f749
    return 20 - test(Unsigned != FALSE);
Packit Service 17f749
  case SQL_REAL:
Packit Service 17f749
    return 7;
Packit Service 17f749
  case SQL_DOUBLE:
Packit Service 17f749
  case SQL_FLOAT:
Packit Service 17f749
    return 15;
Packit Service 17f749
  case SQL_DECIMAL:
Packit Service 17f749
  case SQL_NUMERIC:
Packit Service 17f749
    return Precision;
Packit Service 17f749
  case SQL_TYPE_DATE:
Packit Service 17f749
    return SQL_DATE_LEN;
Packit Service 17f749
  case SQL_TYPE_TIME:
Packit Service 17f749
    return SQL_TIME_LEN + MADB_FRACTIONAL_PART(Scale);
Packit Service 17f749
  case SQL_TYPE_TIMESTAMP:
Packit Service 17f749
    return SQL_TIMESTAMP_LEN + MADB_FRACTIONAL_PART(Scale);
Packit Service 17f749
  case SQL_BINARY:
Packit Service 17f749
  case SQL_VARBINARY:
Packit Service 17f749
  case SQL_LONGVARBINARY:
Packit Service 17f749
    return OctetLength;
Packit Service 17f749
  case SQL_GUID:
Packit Service 17f749
    return 36;;
Packit Service 17f749
  default:
Packit Service 17f749
    {
Packit Service 17f749
      if (CharMaxLen < 2/*i.e.0||1*/)
Packit Service 17f749
      {
Packit Service 17f749
        return OctetLength;
Packit Service 17f749
      }
Packit Service 17f749
      else
Packit Service 17f749
      {
Packit Service 17f749
        return OctetLength/CharMaxLen;
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_GetDisplaySize */
Packit Service 17f749
size_t MADB_GetDisplaySize(MYSQL_FIELD *Field, MARIADB_CHARSET_INFO *charset)
Packit Service 17f749
{
Packit Service 17f749
  /* Todo: check these values with output from mysql --with-columntype-info */
Packit Service 17f749
  switch (Field->type) {
Packit Service 17f749
  case MYSQL_TYPE_NULL:
Packit Service 17f749
    return 1;
Packit Service 17f749
  case MYSQL_TYPE_BIT:
Packit Service 17f749
    return (Field->length == 1) ? 1 : (Field->length + 7) / 8 * 2;
Packit Service 17f749
  case MYSQL_TYPE_TINY:
Packit Service 17f749
    return 4 - test(Field->flags & UNSIGNED_FLAG);
Packit Service 17f749
  case MYSQL_TYPE_SHORT:
Packit Service 17f749
  case MYSQL_TYPE_YEAR:
Packit Service 17f749
    return 6 - test(Field->flags & UNSIGNED_FLAG);
Packit Service 17f749
  case MYSQL_TYPE_INT24:
Packit Service 17f749
    return 9 - test(Field->flags & UNSIGNED_FLAG);
Packit Service 17f749
  case MYSQL_TYPE_LONG:
Packit Service 17f749
    return 11 - test(Field->flags & UNSIGNED_FLAG);
Packit Service 17f749
  case MYSQL_TYPE_LONGLONG:
Packit Service 17f749
    return 20;
Packit Service 17f749
  case MYSQL_TYPE_DOUBLE:
Packit Service 17f749
    return 15;
Packit Service 17f749
  case MYSQL_TYPE_FLOAT:
Packit Service 17f749
    return 7;
Packit Service 17f749
  case MYSQL_TYPE_DECIMAL:
Packit Service 17f749
  case MYSQL_TYPE_NEWDECIMAL:
Packit Service 17f749
  {
Packit Service 17f749
    /* The edge case like decimal(1,1)*/
Packit Service 17f749
    size_t Precision= Field->length - test((Field->flags & UNSIGNED_FLAG) == 0) - test(Field->decimals != 0);
Packit Service 17f749
    return Field->length + test(Precision == Field->decimals);
Packit Service 17f749
  }
Packit Service 17f749
  case MYSQL_TYPE_DATE:
Packit Service 17f749
    return SQL_DATE_LEN; /* YYYY-MM-DD */
Packit Service 17f749
  case MYSQL_TYPE_TIME:
Packit Service 17f749
    return SQL_TIME_LEN + MADB_FRACTIONAL_PART(Field->decimals); /* HH:MM:SS.ffffff */
Packit Service 17f749
  case MYSQL_TYPE_NEWDATE:
Packit Service 17f749
  case MYSQL_TYPE_TIMESTAMP:
Packit Service 17f749
  case MYSQL_TYPE_DATETIME:
Packit Service 17f749
    return SQL_TIMESTAMP_LEN + MADB_FRACTIONAL_PART(Field->decimals);
Packit Service 17f749
  case MYSQL_TYPE_BLOB:
Packit Service 17f749
  case MYSQL_TYPE_ENUM:
Packit Service 17f749
  case MYSQL_TYPE_GEOMETRY:
Packit Service 17f749
  case MYSQL_TYPE_LONG_BLOB:
Packit Service 17f749
  case MYSQL_TYPE_MEDIUM_BLOB:
Packit Service 17f749
  case MYSQL_TYPE_SET:
Packit Service 17f749
  case MYSQL_TYPE_STRING:
Packit Service 17f749
  case MYSQL_TYPE_TINY_BLOB:
Packit Service 17f749
  case MYSQL_TYPE_VARCHAR:
Packit Service 17f749
  case MYSQL_TYPE_VAR_STRING:
Packit Service 17f749
  {
Packit Service 17f749
    if (MADB_FIELD_IS_BINARY(Field))
Packit Service 17f749
    {
Packit Service 17f749
      return Field->length*2; /* ODBC specs says we should give 2 characters per byte to display binaray data in hex form */
Packit Service 17f749
    }
Packit Service 17f749
    else if (charset == NULL || charset->char_maxlen < 2/*i.e.0||1*/)
Packit Service 17f749
    {
Packit Service 17f749
      return Field->length;
Packit Service 17f749
    }
Packit Service 17f749
    else
Packit Service 17f749
    {
Packit Service 17f749
      return Field->length/charset->char_maxlen;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  default:
Packit Service 17f749
    return SQL_NO_TOTAL;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_GetOctetLength */
Packit Service 17f749
size_t MADB_GetOctetLength(MYSQL_FIELD *Field, unsigned short MaxCharLen)
Packit Service 17f749
{
Packit Service 17f749
  size_t Length= MIN(MADB_INT_MAX32, Field->length);
Packit Service 17f749
Packit Service 17f749
  switch (Field->type) {
Packit Service 17f749
  case MYSQL_TYPE_NULL:
Packit Service 17f749
    return 1;
Packit Service 17f749
  case MYSQL_TYPE_BIT:
Packit Service 17f749
    return (Field->length + 7) / 8;
Packit Service 17f749
  case MYSQL_TYPE_TINY:
Packit Service 17f749
    return 1;
Packit Service 17f749
  case MYSQL_TYPE_YEAR:
Packit Service 17f749
  case MYSQL_TYPE_SHORT:
Packit Service 17f749
    return 2;
Packit Service 17f749
  case MYSQL_TYPE_INT24:
Packit Service 17f749
  case MYSQL_TYPE_LONG:
Packit Service 17f749
    return 4;
Packit Service 17f749
  case MYSQL_TYPE_LONGLONG:
Packit Service 17f749
    return 8;
Packit Service 17f749
  case MYSQL_TYPE_DOUBLE:
Packit Service 17f749
    return 8;
Packit Service 17f749
  case MYSQL_TYPE_FLOAT:
Packit Service 17f749
    return 4;
Packit Service 17f749
  case MYSQL_TYPE_DECIMAL:
Packit Service 17f749
  case MYSQL_TYPE_NEWDECIMAL:
Packit Service 17f749
  {
Packit Service 17f749
    /* The edge case like decimal(1,1)*/
Packit Service 17f749
    size_t Precision= Field->length - test((Field->flags & UNSIGNED_FLAG) == 0) - test(Field->decimals != 0);
Packit Service 17f749
    return Field->length + test(Precision == Field->decimals);
Packit Service 17f749
  }
Packit Service 17f749
  case MYSQL_TYPE_DATE:
Packit Service 17f749
    return sizeof(SQL_DATE_STRUCT);
Packit Service 17f749
  case MYSQL_TYPE_TIME:
Packit Service 17f749
    return sizeof(SQL_TIME_STRUCT);
Packit Service 17f749
   case MYSQL_TYPE_NEWDATE:
Packit Service 17f749
  case MYSQL_TYPE_TIMESTAMP:
Packit Service 17f749
  case MYSQL_TYPE_DATETIME:
Packit Service 17f749
    return sizeof(SQL_TIMESTAMP_STRUCT);
Packit Service 17f749
  case MYSQL_TYPE_BLOB:
Packit Service 17f749
  case MYSQL_TYPE_ENUM:
Packit Service 17f749
  case MYSQL_TYPE_GEOMETRY:
Packit Service 17f749
  case MYSQL_TYPE_LONG_BLOB:
Packit Service 17f749
  case MYSQL_TYPE_MEDIUM_BLOB:
Packit Service 17f749
  case MYSQL_TYPE_TINY_BLOB:
Packit Service 17f749
    return Length;
Packit Service 17f749
  case MYSQL_TYPE_SET:
Packit Service 17f749
  case MYSQL_TYPE_STRING:
Packit Service 17f749
  case MYSQL_TYPE_VARCHAR:
Packit Service 17f749
  case MYSQL_TYPE_VAR_STRING:
Packit Service 17f749
    return Length; /* Field->length is calculated using current charset */
Packit Service 17f749
  default:
Packit Service 17f749
    return SQL_NO_TOTAL;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_GetDefaultType */
Packit Service 17f749
int MADB_GetDefaultType(int SQLDataType)
Packit Service 17f749
{
Packit Service 17f749
  switch(SQLDataType)
Packit Service 17f749
  {
Packit Service 17f749
  case SQL_BIGINT:
Packit Service 17f749
    return SQL_C_SBIGINT;
Packit Service 17f749
  case SQL_BINARY:
Packit Service 17f749
    return SQL_C_BINARY;
Packit Service 17f749
  case SQL_BIT:
Packit Service 17f749
    return SQL_C_BIT;
Packit Service 17f749
  case SQL_CHAR:
Packit Service 17f749
    return SQL_C_CHAR;
Packit Service 17f749
  case SQL_DATE:
Packit Service 17f749
  case SQL_TYPE_DATE:
Packit Service 17f749
    return SQL_C_DATE;
Packit Service 17f749
  case SQL_DECIMAL:
Packit Service 17f749
    return SQL_C_CHAR;
Packit Service 17f749
  case SQL_DOUBLE:
Packit Service 17f749
    return SQL_C_DOUBLE; 
Packit Service 17f749
  case SQL_FLOAT:
Packit Service 17f749
    return SQL_C_FLOAT;
Packit Service 17f749
  case SQL_INTEGER:
Packit Service 17f749
    return SQL_C_LONG;
Packit Service 17f749
  case SQL_LONGVARBINARY:
Packit Service 17f749
    return SQL_C_BINARY;
Packit Service 17f749
  case SQL_LONGVARCHAR:
Packit Service 17f749
    return SQL_C_CHAR;
Packit Service 17f749
  case SQL_NUMERIC:
Packit Service 17f749
    return SQL_C_CHAR;
Packit Service 17f749
  case SQL_REAL:
Packit Service 17f749
    return SQL_C_FLOAT;
Packit Service 17f749
  case SQL_SMALLINT:
Packit Service 17f749
    return SQL_C_SHORT;
Packit Service 17f749
  case SQL_TIME:
Packit Service 17f749
  case SQL_TYPE_TIME:
Packit Service 17f749
    return SQL_C_TIME;
Packit Service 17f749
  case SQL_TIMESTAMP:
Packit Service 17f749
  case SQL_TYPE_TIMESTAMP:
Packit Service 17f749
    return SQL_C_TIMESTAMP;
Packit Service 17f749
  case SQL_TINYINT:
Packit Service 17f749
    return SQL_C_TINYINT;
Packit Service 17f749
  case SQL_VARBINARY:
Packit Service 17f749
    return SQL_C_BINARY;
Packit Service 17f749
  case SQL_VARCHAR:
Packit Service 17f749
    return SQL_C_CHAR;
Packit Service 17f749
  default:
Packit Service 17f749
    return SQL_C_CHAR;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
/* {{{ MapMariadDbToOdbcType */
Packit Service 17f749
       /* It's not quite right to mix here C and SQL types, even though constants are sort of equal */
Packit Service 17f749
SQLSMALLINT MapMariadDbToOdbcType(MYSQL_FIELD *field)
Packit Service 17f749
{
Packit Service 17f749
  switch (field->type) {
Packit Service 17f749
    case MYSQL_TYPE_BIT:
Packit Service 17f749
      if (field->length > 1)
Packit Service 17f749
        return SQL_BINARY;
Packit Service 17f749
      return SQL_BIT;
Packit Service 17f749
    case MYSQL_TYPE_NULL:
Packit Service 17f749
      return SQL_VARCHAR;
Packit Service 17f749
    case MYSQL_TYPE_TINY:
Packit Service 17f749
      return field->flags & NUM_FLAG ? SQL_TINYINT : SQL_CHAR;
Packit Service 17f749
    case MYSQL_TYPE_YEAR:
Packit Service 17f749
    case MYSQL_TYPE_SHORT:
Packit Service 17f749
      return SQL_SMALLINT;
Packit Service 17f749
    case MYSQL_TYPE_INT24:
Packit Service 17f749
    case MYSQL_TYPE_LONG:
Packit Service 17f749
      return SQL_INTEGER;
Packit Service 17f749
    case MYSQL_TYPE_FLOAT:
Packit Service 17f749
      return SQL_REAL;
Packit Service 17f749
    case MYSQL_TYPE_DOUBLE:
Packit Service 17f749
      return SQL_DOUBLE;
Packit Service 17f749
    case MYSQL_TYPE_TIMESTAMP:
Packit Service 17f749
    case MYSQL_TYPE_DATETIME:
Packit Service 17f749
      return SQL_TYPE_TIMESTAMP;
Packit Service 17f749
    case MYSQL_TYPE_NEWDATE:
Packit Service 17f749
    case MYSQL_TYPE_DATE:
Packit Service 17f749
      return SQL_TYPE_DATE;
Packit Service 17f749
    case MYSQL_TYPE_TIME:
Packit Service 17f749
       return SQL_TYPE_TIME;
Packit Service 17f749
    case MYSQL_TYPE_TINY_BLOB:
Packit Service 17f749
    case MYSQL_TYPE_BLOB:
Packit Service 17f749
    case MYSQL_TYPE_MEDIUM_BLOB:
Packit Service 17f749
    case MYSQL_TYPE_LONG_BLOB:
Packit Service 17f749
      return MADB_FIELD_IS_BINARY(field) ? SQL_LONGVARBINARY : SQL_LONGVARCHAR;
Packit Service 17f749
    case MYSQL_TYPE_LONGLONG:
Packit Service 17f749
      return SQL_BIGINT;
Packit Service 17f749
    case MYSQL_TYPE_STRING:
Packit Service 17f749
      return MADB_FIELD_IS_BINARY(field) ? SQL_BINARY : SQL_CHAR;
Packit Service 17f749
    case MYSQL_TYPE_VAR_STRING:
Packit Service 17f749
      return MADB_FIELD_IS_BINARY(field) ? SQL_VARBINARY : SQL_VARCHAR;
Packit Service 17f749
    case MYSQL_TYPE_SET:
Packit Service 17f749
    case MYSQL_TYPE_ENUM:
Packit Service 17f749
      return SQL_CHAR;
Packit Service 17f749
    case MYSQL_TYPE_GEOMETRY:
Packit Service 17f749
      return SQL_LONGVARBINARY;
Packit Service 17f749
    case MYSQL_TYPE_DECIMAL:
Packit Service 17f749
    case MYSQL_TYPE_NEWDECIMAL:
Packit Service 17f749
      return SQL_DECIMAL;
Packit Service 17f749
    default:
Packit Service 17f749
      return SQL_UNKNOWN_TYPE;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* }}} */
Packit Service 17f749
/* {{{ MADB_GetTypeLength */
Packit Service 17f749
size_t MADB_GetTypeLength(SQLINTEGER SqlDataType, size_t Length)
Packit Service 17f749
{
Packit Service 17f749
  switch(SqlDataType)
Packit Service 17f749
  {
Packit Service 17f749
  case SQL_C_BIT:
Packit Service 17f749
  case SQL_C_TINYINT:
Packit Service 17f749
  case SQL_C_STINYINT:
Packit Service 17f749
  case SQL_C_UTINYINT:
Packit Service 17f749
    return 1;
Packit Service 17f749
  case SQL_C_SHORT:
Packit Service 17f749
  case SQL_C_SSHORT:
Packit Service 17f749
  case SQL_C_USHORT:
Packit Service 17f749
    return 2;
Packit Service 17f749
  case SQL_C_LONG:
Packit Service 17f749
  case SQL_C_SLONG:
Packit Service 17f749
  case SQL_C_ULONG:
Packit Service 17f749
    return sizeof(SQLINTEGER);
Packit Service 17f749
  case SQL_C_UBIGINT:
Packit Service 17f749
  case SQL_C_SBIGINT:
Packit Service 17f749
    return sizeof(long long);
Packit Service 17f749
  case SQL_C_DOUBLE:
Packit Service 17f749
    return sizeof(SQLDOUBLE);
Packit Service 17f749
  case SQL_C_FLOAT:
Packit Service 17f749
    return sizeof(SQLFLOAT);
Packit Service 17f749
  case SQL_C_NUMERIC:
Packit Service 17f749
    return sizeof(SQL_NUMERIC_STRUCT);
Packit Service 17f749
  case SQL_C_TYPE_TIME:
Packit Service 17f749
  case SQL_C_TIME:
Packit Service 17f749
    return sizeof(SQL_TIME_STRUCT);
Packit Service 17f749
  case SQL_C_TYPE_DATE:
Packit Service 17f749
  case SQL_C_DATE:
Packit Service 17f749
    return sizeof(SQL_DATE_STRUCT);
Packit Service 17f749
  case SQL_C_TYPE_TIMESTAMP:
Packit Service 17f749
  case SQL_C_TIMESTAMP:
Packit Service 17f749
    return sizeof(SQL_TIMESTAMP_STRUCT);
Packit Service 17f749
  default:
Packit Service 17f749
    return Length;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_GetMaDBTypeAndLength */
Packit Service 17f749
int MADB_GetMaDBTypeAndLength(SQLINTEGER SqlDataType, my_bool *Unsigned, unsigned long *Length)
Packit Service 17f749
{
Packit Service 17f749
  *Unsigned= 0;
Packit Service 17f749
  switch(SqlDataType)
Packit Service 17f749
  {
Packit Service 17f749
  case SQL_C_BIT:
Packit Service 17f749
  case SQL_C_TINYINT:
Packit Service 17f749
  case SQL_C_STINYINT:
Packit Service 17f749
  case SQL_C_UTINYINT:
Packit Service 17f749
    *Length= 1;
Packit Service 17f749
    *Unsigned= (SqlDataType == SQL_C_UTINYINT);
Packit Service 17f749
Packit Service 17f749
    return MYSQL_TYPE_TINY;
Packit Service 17f749
Packit Service 17f749
  case SQL_C_SHORT:
Packit Service 17f749
  case SQL_C_SSHORT:
Packit Service 17f749
  case SQL_C_USHORT:
Packit Service 17f749
    *Length= 2;
Packit Service 17f749
    *Unsigned= (SqlDataType == SQL_C_USHORT);
Packit Service 17f749
Packit Service 17f749
    return MYSQL_TYPE_SHORT;
Packit Service 17f749
 
Packit Service 17f749
  case SQL_C_LONG:
Packit Service 17f749
  case SQL_C_SLONG:
Packit Service 17f749
  case SQL_C_ULONG:
Packit Service 17f749
    *Length= sizeof(SQLINTEGER);
Packit Service 17f749
    *Unsigned= (SqlDataType == SQL_C_ULONG);
Packit Service 17f749
    return MYSQL_TYPE_LONG;
Packit Service 17f749
  case SQL_C_UBIGINT:
Packit Service 17f749
  case SQL_C_SBIGINT:
Packit Service 17f749
    *Length= sizeof(long long);
Packit Service 17f749
    *Unsigned= (SqlDataType == SQL_C_UBIGINT);
Packit Service 17f749
    return MYSQL_TYPE_LONGLONG;
Packit Service 17f749
  case SQL_C_DOUBLE:
Packit Service 17f749
    *Length= sizeof(SQLDOUBLE);
Packit Service 17f749
    return MYSQL_TYPE_DOUBLE;
Packit Service 17f749
  case SQL_C_FLOAT:
Packit Service 17f749
    *Length =sizeof(SQLFLOAT);
Packit Service 17f749
    return MYSQL_TYPE_FLOAT;
Packit Service 17f749
  case SQL_C_NUMERIC:
Packit Service 17f749
    /**Length= sizeof(SQL_NUMERIC_STRUCT);*/
Packit Service 17f749
    return MYSQL_TYPE_DECIMAL;
Packit Service 17f749
  case SQL_C_TYPE_TIME:
Packit Service 17f749
  case SQL_C_TIME:
Packit Service 17f749
    *Length= sizeof(SQL_TIME_STRUCT);
Packit Service 17f749
    return MYSQL_TYPE_TIME;
Packit Service 17f749
  case SQL_C_TYPE_DATE:
Packit Service 17f749
  case SQL_C_DATE:
Packit Service 17f749
    *Length= sizeof(SQL_DATE_STRUCT);
Packit Service 17f749
    return MYSQL_TYPE_DATE;
Packit Service 17f749
  case SQL_C_TYPE_TIMESTAMP:
Packit Service 17f749
  case SQL_C_TIMESTAMP:
Packit Service 17f749
    *Length= sizeof(SQL_TIMESTAMP_STRUCT);
Packit Service 17f749
    return MYSQL_TYPE_TIMESTAMP;
Packit Service 17f749
  case SQL_C_INTERVAL_HOUR_TO_MINUTE:
Packit Service 17f749
  case SQL_C_INTERVAL_HOUR_TO_SECOND:
Packit Service 17f749
    *Length= sizeof(SQL_INTERVAL_STRUCT);
Packit Service 17f749
    return MYSQL_TYPE_TIME;
Packit Service 17f749
  case SQL_C_CHAR:
Packit Service 17f749
    return MYSQL_TYPE_STRING;
Packit Service 17f749
  default:
Packit Service 17f749
    return MYSQL_TYPE_BLOB;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
/* }}} */
Packit Service 17f749
Packit Service 17f749
void MADB_CopyOdbcTsToMadbTime(SQL_TIMESTAMP_STRUCT *Src, MYSQL_TIME *Dst)
Packit Service 17f749
{
Packit Service 17f749
  Dst->year=        Src->year;
Packit Service 17f749
  Dst->month=       Src->month;
Packit Service 17f749
  Dst->day=         Src->day;
Packit Service 17f749
  Dst->hour=        Src->hour;
Packit Service 17f749
  Dst->minute=      Src->minute;
Packit Service 17f749
  Dst->second=      Src->second;
Packit Service 17f749
  Dst->second_part= Src->fraction / 1000;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
void MADB_CopyMadbTimeToOdbcTs(MYSQL_TIME *Src, SQL_TIMESTAMP_STRUCT *Dst)
Packit Service 17f749
{
Packit Service 17f749
  Dst->year=        Src->year;
Packit Service 17f749
  Dst->month=       Src->month;
Packit Service 17f749
  Dst->day=         Src->day;
Packit Service 17f749
  Dst->hour=        Src->hour;
Packit Service 17f749
  Dst->minute=      Src->minute;
Packit Service 17f749
  Dst->second=      Src->second;
Packit Service 17f749
  Dst->fraction=    Src->second_part*1000;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
SQLRETURN MADB_CopyMadbTimestamp(MADB_Stmt *Stmt, MYSQL_TIME *tm, SQLPOINTER DataPtr, SQLLEN *Length, SQLLEN *Ind,
Packit Service 17f749
                                 SQLSMALLINT CType, SQLSMALLINT SqlType)
Packit Service 17f749
{
Packit Service 17f749
  SQLLEN Dummy;
Packit Service 17f749
Packit Service 17f749
  Length= Length == NULL ? &Dummy : Length;
Packit Service 17f749
Packit Service 17f749
  switch(CType)
Packit Service 17f749
  {
Packit Service 17f749
    case SQL_C_TIMESTAMP:
Packit Service 17f749
    case SQL_C_TYPE_TIMESTAMP:
Packit Service 17f749
    {
Packit Service 17f749
      SQL_TIMESTAMP_STRUCT *ts= (SQL_TIMESTAMP_STRUCT *)DataPtr;
Packit Service 17f749
Packit Service 17f749
      if (ts != NULL)
Packit Service 17f749
      {
Packit Service 17f749
        /* If time converted to timestamp - fraction is set to 0, date is set to current date */
Packit Service 17f749
        if (SqlType == SQL_TIME || SqlType == SQL_TYPE_TIME)
Packit Service 17f749
        {
Packit Service 17f749
          time_t sec_time;
Packit Service 17f749
          struct tm * cur_tm;
Packit Service 17f749
Packit Service 17f749
          sec_time= time(NULL);
Packit Service 17f749
          cur_tm= localtime(&sec_time);
Packit Service 17f749
Packit Service 17f749
          ts->year= 1900 + cur_tm->tm_year;
Packit Service 17f749
          ts->month= cur_tm->tm_mon + 1;
Packit Service 17f749
          ts->day= cur_tm->tm_mday;
Packit Service 17f749
          ts->fraction= 0;
Packit Service 17f749
        }
Packit Service 17f749
        else
Packit Service 17f749
        {
Packit Service 17f749
          ts->year= tm->year;
Packit Service 17f749
          ts->month= tm->month;
Packit Service 17f749
          ts->day= tm->day;
Packit Service 17f749
          ts->fraction= tm->second_part * 1000;
Packit Service 17f749
        }
Packit Service 17f749
        ts->hour= tm->hour;
Packit Service 17f749
        ts->minute= tm->minute;
Packit Service 17f749
        ts->second= tm->second;
Packit Service 17f749
Packit Service 17f749
        if (ts->year + ts->month + ts->day + ts->hour + ts->minute + ts->fraction + ts->second == 0)
Packit Service 17f749
        {
Packit Service 17f749
          if (Ind != NULL)
Packit Service 17f749
          {
Packit Service 17f749
            *Ind= SQL_NULL_DATA;
Packit Service 17f749
          }
Packit Service 17f749
          else
Packit Service 17f749
          {
Packit Service 17f749
            return MADB_SetError(&Stmt->Error, MADB_ERR_22002, NULL, 0);
Packit Service 17f749
          }
Packit Service 17f749
          break;
Packit Service 17f749
        }
Packit Service 17f749
      }
Packit Service 17f749
      *Length= sizeof(SQL_TIMESTAMP_STRUCT);
Packit Service 17f749
    }
Packit Service 17f749
    break;
Packit Service 17f749
    case SQL_C_TIME:
Packit Service 17f749
    case SQL_C_TYPE_TIME:
Packit Service 17f749
    {
Packit Service 17f749
      SQL_TIME_STRUCT *ts= (SQL_TIME_STRUCT *)DataPtr;
Packit Service 17f749
Packit Service 17f749
      if (ts != NULL)
Packit Service 17f749
      {
Packit Service 17f749
        /* tm(buffer from MYSQL_BIND) can be NULL. And that happens if ts(app's buffer) is null */
Packit Service 17f749
        if (!VALID_TIME(tm))
Packit Service 17f749
        {
Packit Service 17f749
          return MADB_SetError(&Stmt->Error, MADB_ERR_22007, NULL, 0);
Packit Service 17f749
        }
Packit Service 17f749
Packit Service 17f749
        ts->hour= tm->hour;
Packit Service 17f749
        ts->minute= tm->minute;
Packit Service 17f749
        ts->second= tm->second;
Packit Service 17f749
Packit Service 17f749
        *Length= sizeof(SQL_TIME_STRUCT);
Packit Service 17f749
Packit Service 17f749
        if (tm->second_part)
Packit Service 17f749
        {
Packit Service 17f749
          return MADB_SetError(&Stmt->Error, MADB_ERR_01S07, NULL, 0);
Packit Service 17f749
        }
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
    break;
Packit Service 17f749
    case SQL_C_DATE:
Packit Service 17f749
    case SQL_TYPE_DATE:
Packit Service 17f749
    {
Packit Service 17f749
      SQL_DATE_STRUCT *ts= (SQL_DATE_STRUCT *)DataPtr;
Packit Service 17f749
Packit Service 17f749
      if (ts != NULL)
Packit Service 17f749
      {
Packit Service 17f749
        ts->year= tm->year;
Packit Service 17f749
        ts->month= tm->month;
Packit Service 17f749
        ts->day= tm->day;
Packit Service 17f749
        if (ts->year + ts->month + ts->day == 0)
Packit Service 17f749
        {
Packit Service 17f749
          if (Ind != NULL)
Packit Service 17f749
          {
Packit Service 17f749
            *Ind= SQL_NULL_DATA;
Packit Service 17f749
          }
Packit Service 17f749
          else
Packit Service 17f749
          {
Packit Service 17f749
            return MADB_SetError(&Stmt->Error, MADB_ERR_22002, NULL, 0);
Packit Service 17f749
          }
Packit Service 17f749
          break;
Packit Service 17f749
        }
Packit Service 17f749
      }
Packit Service 17f749
      *Length= sizeof(SQL_DATE_STRUCT);
Packit Service 17f749
    }
Packit Service 17f749
    break;
Packit Service 17f749
  }
Packit Service 17f749
    
Packit Service 17f749
  return SQL_SUCCESS;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void *GetBindOffset(MADB_Desc *Desc, MADB_DescRecord *Record, void *Ptr, SQLULEN RowNumber, size_t PtrSize)
Packit Service 17f749
{
Packit Service 17f749
  size_t BindOffset= 0;
Packit Service 17f749
Packit Service 17f749
  /* This is not quite clear - I'd imagine, that if BindOffset is set, then Ptr can be NULL.
Packit Service 17f749
     Makes perfect sense in case of row-based binding - setting pointers to offset in structure, and BindOffset to the begin of array.
Packit Service 17f749
     One of members would have 0 offset then. But specs are rather against that, and other drivers also don't support such interpretation */
Packit Service 17f749
  if (Ptr == NULL)
Packit Service 17f749
  {
Packit Service 17f749
    return NULL;
Packit Service 17f749
  }
Packit Service 17f749
  if (Desc->Header.BindOffsetPtr != NULL)
Packit Service 17f749
  {
Packit Service 17f749
    BindOffset= (size_t)*Desc->Header.BindOffsetPtr;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  /* row wise binding */
Packit Service 17f749
  if (Desc->Header.BindType == SQL_BIND_BY_COLUMN ||
Packit Service 17f749
    Desc->Header.BindType == SQL_PARAM_BIND_BY_COLUMN)
Packit Service 17f749
  {
Packit Service 17f749
    BindOffset+= PtrSize * RowNumber;
Packit Service 17f749
  }
Packit Service 17f749
  else
Packit Service 17f749
  {
Packit Service 17f749
    BindOffset+= Desc->Header.BindType * RowNumber;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return (char *)Ptr + BindOffset;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* Checking if column ignored in all bound rows. Should hel*/
Packit Service 17f749
BOOL MADB_ColumnIgnoredInAllRows(MADB_Desc *Desc, MADB_DescRecord *Rec)
Packit Service 17f749
{
Packit Service 17f749
  SQLULEN row;
Packit Service 17f749
  SQLLEN *IndicatorPtr;
Packit Service 17f749
Packit Service 17f749
  for (row= 0; row < Desc->Header.ArraySize; ++row)
Packit Service 17f749
  {
Packit Service 17f749
    IndicatorPtr= (SQLLEN *)GetBindOffset(Desc, Rec, Rec->IndicatorPtr, row, sizeof(SQLLEN));
Packit Service 17f749
Packit Service 17f749
    if (IndicatorPtr == NULL || *IndicatorPtr != SQL_COLUMN_IGNORE)
Packit Service 17f749
    {
Packit Service 17f749
      return FALSE;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return TRUE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void MADB_NumericInit(SQL_NUMERIC_STRUCT *number, MADB_DescRecord *Ard)
Packit Service 17f749
{
Packit Service 17f749
  if (!number)
Packit Service 17f749
    return;
Packit Service 17f749
  number->precision= (SQLCHAR)Ard->Precision;
Packit Service 17f749
  number->scale= (SQLCHAR)Ard->Scale;
Packit Service 17f749
  memset(number->val, 0, sizeof(number->val));
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_CharToSQLNumeric */
Packit Service 17f749
int MADB_CharToSQLNumeric(char *buffer, MADB_Desc *Ard, MADB_DescRecord *ArdRecord, SQL_NUMERIC_STRUCT *dst_buffer, unsigned long RowNumber)
Packit Service 17f749
{
Packit Service 17f749
  char *p;
Packit Service 17f749
  SQL_NUMERIC_STRUCT *number= dst_buffer != NULL ? dst_buffer :
Packit Service 17f749
    (SQL_NUMERIC_STRUCT *)GetBindOffset(Ard, ArdRecord, ArdRecord->DataPtr, RowNumber, ArdRecord->OctetLength);
Packit Service 17f749
  int ret= 0;
Packit Service 17f749
Packit Service 17f749
  if (!buffer || !number)
Packit Bot ff6dbd
  {
Packit Service 17f749
    return ret;
Packit Bot ff6dbd
  }
Packit Service 17f749
Packit Service 17f749
  p= trim(buffer);
Packit Service 17f749
  MADB_NumericInit(number, ArdRecord);
Packit Service 17f749
Packit Bot ff6dbd
  /* Determining the sign of the number. From now on we dean with unsigned number */
Packit Bot ff6dbd
  if (!(number->sign = (*p == '-') ? 0 : 1))
Packit Bot ff6dbd
  {
Packit Service 17f749
    p++;
Packit Bot ff6dbd
  }
Packit Bot ff6dbd
  /* Empty string - nothing to do*/
Packit Service 17f749
  if (!*p)
Packit Bot ff6dbd
  {
Packit Bot ff6dbd
    return ret;
Packit Bot ff6dbd
  }
Packit Service 17f749
Packit Service 17f749
  if (number->precision == 0)
Packit Service 17f749
  {
Packit Service 17f749
    number->precision= MADB_DEFAULT_PRECISION;
Packit Service 17f749
  }
Packit Service 17f749
Packit Bot ff6dbd
  /* Skipping leading zeroes */
Packit Bot ff6dbd
  while (*p == '0')
Packit Service 17f749
  {
Packit Bot ff6dbd
    ++p;
Packit Service 17f749
  }
Packit Service 17f749
  if (*p)
Packit Service 17f749
  {
Packit Service 17f749
    int i;
Packit Bot ff6dbd
    unsigned int bit, hval, tv, dig, sta, olen;
Packit Service 17f749
    int leading_zeros= 0;
Packit Service 17f749
    char *dot= strchr(p, '.');
Packit Service 17f749
    char digits[100];
Packit Bot ff6dbd
    unsigned short digits_count= 0; /* integer part digits count*/
Packit Bot ff6dbd
Packit Bot ff6dbd
    if (dot == NULL)
Packit Bot ff6dbd
    {
Packit Bot ff6dbd
      char* end= p;
Packit Bot ff6dbd
      while (*end && isdigit(0x000000ff & *end))
Packit Bot ff6dbd
        ++end;
Packit Service 17f749
Packit Bot ff6dbd
      digits_count= (unsigned short)(end - p);
Packit Bot ff6dbd
    }
Packit Bot ff6dbd
    else
Packit Bot ff6dbd
    {
Packit Bot ff6dbd
      digits_count= (unsigned short)(dot - p);
Packit Bot ff6dbd
    }
Packit Bot ff6dbd
    /* Overflow checks */
Packit Bot ff6dbd
    if (digits_count > MADB_DEFAULT_PRECISION + 1 ) /* 16 bytes of FF make up 39 digits number */
Packit Bot ff6dbd
    {
Packit Service 17f749
      return MADB_ERR_22003;
Packit Bot ff6dbd
    }
Packit Bot ff6dbd
    if (number->precision > 0 &&  digits_count > number->precision)
Packit Bot ff6dbd
    {
Packit Bot ff6dbd
      /* if scale is negative, and we have just enough zeroes at the end - we are fine, there is no overflow */
Packit Bot ff6dbd
      if (number->scale < 0 && (number->precision - number->scale) >= digits_count)
Packit Bot ff6dbd
      {
Packit Bot ff6dbd
        /* Checking that all digits past presision are '0'. Otherwise - overflow */
Packit Bot ff6dbd
        for (i = digits_count - number->precision; i > 0; --i)
Packit Bot ff6dbd
        {
Packit Bot ff6dbd
          if (*(p + digits_count - i) != '0')
Packit Bot ff6dbd
          {
Packit Bot ff6dbd
            return MADB_ERR_22003;
Packit Bot ff6dbd
          }
Packit Bot ff6dbd
        }
Packit Bot ff6dbd
      }
Packit Bot ff6dbd
      else
Packit Bot ff6dbd
      {
Packit Bot ff6dbd
        return MADB_ERR_22003;
Packit Bot ff6dbd
      }
Packit Bot ff6dbd
    }
Packit Bot ff6dbd
Packit Bot ff6dbd
    memcpy(digits, p, digits_count);
Packit Bot ff6dbd
Packit Service 17f749
    if (dot && number->scale > 0)
Packit Service 17f749
    {
Packit Bot ff6dbd
      short digits_total= 0,       /* fractional part total digits */
Packit Bot ff6dbd
            digits_significant= 0; /* fractional part significant digits(not counting 0 at the end) */
Packit Bot ff6dbd
Packit Service 17f749
      p= dot + 1;
Packit Service 17f749
      while (*p)
Packit Service 17f749
      {
Packit Service 17f749
        /* ignore non numbers */
Packit Service 17f749
        if (!isdigit(0x000000ff & *p))
Packit Service 17f749
          break;
Packit Bot ff6dbd
        ++digits_total;
Packit Service 17f749
        /* ignore trailing zeros */
Packit Service 17f749
        if (*p != '0')
Packit Service 17f749
        {
Packit Service 17f749
          digits_significant= digits_total;
Packit Service 17f749
        }
Packit Bot ff6dbd
        ++p;
Packit Service 17f749
      }
Packit Service 17f749
Packit Bot ff6dbd
      /* Kinda tricky. let's say precision is 5.2. 1234.5 is fine, 1234.56 is overflow, 123.456 fractional overflow with rounding and warning */
Packit Bot ff6dbd
      if (digits_count + digits_significant > number->precision && digits_significant <= number->scale)
Packit Service 17f749
      {
Packit Bot ff6dbd
        return MADB_ERR_22003;
Packit Service 17f749
        /* if digits are zero there is no overflow */
Packit Bot ff6dbd
        /*for (p= dot + 1; p <= dot + digits_significant; ++p)
Packit Service 17f749
        {
Packit Service 17f749
          if (*p != '0')
Packit Bot ff6dbd
            
Packit Bot ff6dbd
        }*/
Packit Service 17f749
      }
Packit Service 17f749
      
Packit Bot ff6dbd
      if (digits_significant > number->scale)
Packit Bot ff6dbd
      {
Packit Bot ff6dbd
        ret= MADB_ERR_01S07;
Packit Bot ff6dbd
        memcpy(digits + digits_count, dot + 1, number->scale);
Packit Bot ff6dbd
      }
Packit Bot ff6dbd
      else
Packit Service 17f749
      {
Packit Bot ff6dbd
        memcpy(digits + digits_count, dot + 1, digits_significant);
Packit Bot ff6dbd
      
Packit Bot ff6dbd
        for (i= digits_count + digits_significant; i < digits_count + number->scale; ++i)
Packit Service 17f749
        {
Packit Service 17f749
          digits[i]= '0';
Packit Service 17f749
        }
Packit Service 17f749
      }
Packit Bot ff6dbd
      digits_count+= number->scale;
Packit Service 17f749
    }
Packit Service 17f749
Packit Service 17f749
    /* Rounding */
Packit Service 17f749
    if (number->scale < 0)
Packit Service 17f749
    {
Packit Service 17f749
      int64_t OldVal, Val;
Packit Service 17f749
      int64_t RoundNumber= (int64_t)pow(10.0, -number->scale);
Packit Service 17f749
Packit Bot ff6dbd
      //if (digits_count <= number->precision)
Packit Bot ff6dbd
      {
Packit Bot ff6dbd
        digits[digits_count/*number->precision*/]= 0;
Packit Bot ff6dbd
      }
Packit Service 17f749
      Val= _atoi64(digits);
Packit Service 17f749
Packit Service 17f749
      OldVal= Val;
Packit Service 17f749
      Val= (Val + RoundNumber / 2) / RoundNumber * RoundNumber;
Packit Service 17f749
      if (OldVal != Val)
Packit Bot ff6dbd
      {
Packit Service 17f749
        return MADB_ERR_22003;
Packit Bot ff6dbd
      }
Packit Bot ff6dbd
      _snprintf(digits, sizeof(digits), "%lld", Val/RoundNumber);
Packit Service 17f749
      digits_count= (short)strlen(digits);
Packit Service 17f749
      if (digits_count > number->precision)
Packit Service 17f749
        return MADB_ERR_22003;
Packit Service 17f749
    }
Packit Service 17f749
Packit Bot ff6dbd
    digits_count= MIN(digits_count, MADB_DEFAULT_PRECISION + 1);
Packit Service 17f749
    for (hval = 0, bit = 1L, sta = 0, olen = 0; sta < digits_count;)
Packit Service 17f749
    {
Packit Service 17f749
      for (dig = 0, i = sta; i < digits_count; i++)
Packit Service 17f749
      {
Packit Service 17f749
        tv = dig * 10 + digits[i] - '0';
Packit Service 17f749
        dig = tv % 2;
Packit Service 17f749
        digits[i] = tv / 2 + '0';
Packit Service 17f749
        if (i == sta && tv < 2)
Packit Service 17f749
          sta++;
Packit Service 17f749
      }
Packit Service 17f749
      if (dig > 0)
Packit Service 17f749
        hval |= bit;
Packit Service 17f749
      bit <<= 1;
Packit Service 17f749
      if (bit >= (1L << 8))
Packit Service 17f749
      {
Packit Bot ff6dbd
        if (olen >= SQL_MAX_NUMERIC_LEN)
Packit Service 17f749
        {
Packit Service 17f749
          //number->scale = sta - number->precision;
Packit Bot ff6dbd
          ret= MADB_ERR_22003;
Packit Service 17f749
          break;
Packit Service 17f749
        }
Packit Bot ff6dbd
        number->val[olen++] = hval;
Packit Bot ff6dbd
        hval = 0;
Packit Bot ff6dbd
        bit = 1L;
Packit Bot ff6dbd
Packit Service 17f749
      } 
Packit Service 17f749
    }
Packit Bot ff6dbd
    if (hval != 0)
Packit Service 17f749
    {
Packit Bot ff6dbd
      if (olen < SQL_MAX_NUMERIC_LEN)
Packit Bot ff6dbd
      {
Packit Bot ff6dbd
        number->val[olen++] = hval;
Packit Bot ff6dbd
      }
Packit Bot ff6dbd
      else
Packit Bot ff6dbd
      {
Packit Bot ff6dbd
        ret= MADB_ERR_22003;
Packit Bot ff6dbd
      }
Packit Service 17f749
    }
Packit Service 17f749
  } 
Packit Service 17f749
  return ret;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* {{{ MADB_GetHexString */
Packit Service 17f749
size_t MADB_GetHexString(char *BinaryBuffer, size_t BinaryLength,
Packit Service 17f749
                          char *HexBuffer, size_t HexLength)
Packit Service 17f749
{
Packit Service 17f749
  const char HexDigits[]= "0123456789ABCDEF";
Packit Service 17f749
  char *Start= HexBuffer;
Packit Service 17f749
  size_t CurrentLength= HexLength;
Packit Service 17f749
Packit Service 17f749
  if (!HexBuffer || !BinaryBuffer)
Packit Service 17f749
    return 0;
Packit Service 17f749
   
Packit Service 17f749
  while (BinaryLength-- && CurrentLength > 2)
Packit Service 17f749
  {
Packit Service 17f749
    *HexBuffer++=HexDigits[*BinaryBuffer >> 4];
Packit Service 17f749
    *HexBuffer++=HexDigits[*BinaryBuffer & 0x0F];
Packit Service 17f749
    BinaryBuffer++;
Packit Service 17f749
    CurrentLength-= 2;
Packit Service 17f749
  }
Packit Service 17f749
  *HexBuffer= 0;
Packit Service 17f749
  return (HexBuffer - Start);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
SQLRETURN MADB_DaeStmt(MADB_Stmt *Stmt, SQLUSMALLINT Operation)
Packit Service 17f749
{
Packit Service 17f749
  char          *TableName=   MADB_GetTableName(Stmt);
Packit Service 17f749
  char          *CatalogName= MADB_GetCatalogName(Stmt);
Packit Service 17f749
  MADB_DynString DynStmt;
Packit Service 17f749
Packit Service 17f749
  MADB_CLEAR_ERROR(&Stmt->Error);
Packit Service 17f749
  memset(&DynStmt, 0, sizeof(MADB_DynString));
Packit Service 17f749
Packit Service 17f749
  if (Stmt->DaeStmt)
Packit Service 17f749
    Stmt->Methods->StmtFree(Stmt->DaeStmt, SQL_DROP);
Packit Service 17f749
  Stmt->DaeStmt= NULL;
Packit Service 17f749
Packit Service 17f749
  if (!SQL_SUCCEEDED(MA_SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE)Stmt->Connection, (SQLHANDLE *)&Stmt->DaeStmt)))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_CopyError(&Stmt->Error, &Stmt->Connection->Error);
Packit Service 17f749
    goto end;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  switch(Operation)
Packit Service 17f749
  {
Packit Service 17f749
  case SQL_ADD:
Packit Service 17f749
    if (MADB_InitDynamicString(&DynStmt, "INSERT INTO ", 1024, 1024) ||
Packit Service 17f749
        MADB_DynStrAppendQuoted(&DynStmt, CatalogName) ||
Packit Service 17f749
        MADB_DynstrAppend(&DynStmt, ".") ||
Packit Service 17f749
        MADB_DynStrAppendQuoted(&DynStmt, TableName)||
Packit Service 17f749
        MADB_DynStrUpdateSet(Stmt, &DynStmt))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_DynstrFree(&DynStmt);
Packit Service 17f749
      return Stmt->Error.ReturnValue;
Packit Service 17f749
    }
Packit Service 17f749
    Stmt->DataExecutionType= MADB_DAE_ADD;
Packit Service 17f749
    break;
Packit Service 17f749
  case SQL_DELETE:
Packit Service 17f749
    if (MADB_InitDynamicString(&DynStmt, "DELETE FROM ", 1024, 1024) ||
Packit Service 17f749
        MADB_DynStrAppendQuoted(&DynStmt, CatalogName) ||
Packit Service 17f749
        MADB_DynstrAppend(&DynStmt, ".") ||
Packit Service 17f749
        MADB_DynStrAppendQuoted(&DynStmt, TableName) ||
Packit Service 17f749
        MADB_DynStrGetWhere(Stmt, &DynStmt, TableName, FALSE))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_DynstrFree(&DynStmt);
Packit Service 17f749
      return Stmt->Error.ReturnValue;
Packit Service 17f749
    }
Packit Service 17f749
    Stmt->DataExecutionType= MADB_DAE_DELETE;
Packit Service 17f749
    break;
Packit Service 17f749
  case SQL_UPDATE:
Packit Service 17f749
    if (MADB_InitDynamicString(&DynStmt, "UPDATE ", 1024, 1024) ||
Packit Service 17f749
        MADB_DynStrAppendQuoted(&DynStmt, CatalogName) ||
Packit Service 17f749
        MADB_DynstrAppend(&DynStmt, ".") ||
Packit Service 17f749
        MADB_DynStrAppendQuoted(&DynStmt, TableName)||
Packit Service 17f749
        MADB_DynStrUpdateSet(Stmt, &DynStmt)||
Packit Service 17f749
        MADB_DynStrGetWhere(Stmt, &DynStmt, TableName, FALSE))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_DynstrFree(&DynStmt);
Packit Service 17f749
      return Stmt->Error.ReturnValue;
Packit Service 17f749
    }
Packit Service 17f749
    Stmt->DataExecutionType= MADB_DAE_UPDATE;
Packit Service 17f749
    break;
Packit Service 17f749
  }
Packit Service 17f749
  
Packit Service 17f749
  if (!SQL_SUCCEEDED(Stmt->DaeStmt->Methods->Prepare(Stmt->DaeStmt, DynStmt.str, SQL_NTS, FALSE)))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_CopyError(&Stmt->Error, &Stmt->DaeStmt->Error);
Packit Service 17f749
    Stmt->Methods->StmtFree(Stmt->DaeStmt, SQL_DROP);
Packit Service 17f749
  }
Packit Service 17f749
   
Packit Service 17f749
end:
Packit Service 17f749
  MADB_DynstrFree(&DynStmt);
Packit Service 17f749
  return Stmt->Error.ReturnValue;
Packit Service 17f749
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
int MADB_FindNextDaeParam(MADB_Desc *Desc, int InitialParam, SQLSMALLINT RowNumber)
Packit Service 17f749
{
Packit Service 17f749
  int             i;
Packit Service 17f749
  MADB_DescRecord *Record;
Packit Service 17f749
Packit Service 17f749
  for (i= InitialParam > -1 ? InitialParam + 1 : 0; i < Desc->Header.Count; i++)
Packit Service 17f749
  {
Packit Service 17f749
    if ((Record= MADB_DescGetInternalRecord(Desc, i, MADB_DESC_READ)))
Packit Service 17f749
    {
Packit Service 17f749
      if (Record->OctetLengthPtr)
Packit Service 17f749
      {
Packit Service 17f749
        /* Stmt->DaeRowNumber is 1 based */
Packit Service 17f749
        SQLLEN *OctetLength = (SQLLEN *)GetBindOffset(Desc, Record, Record->OctetLengthPtr, RowNumber > 1 ? RowNumber - 1 : 0, sizeof(SQLLEN));
Packit Service 17f749
        if (PARAM_IS_DAE(OctetLength))
Packit Service 17f749
        {
Packit Service 17f749
          return i;
Packit Service 17f749
        }
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return MADB_NOPARAM;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
BOOL MADB_IsNumericType(SQLSMALLINT ConciseType)
Packit Service 17f749
{
Packit Service 17f749
  switch (ConciseType)
Packit Service 17f749
  {
Packit Service 17f749
    case SQL_C_DOUBLE:
Packit Service 17f749
    case SQL_C_FLOAT:
Packit Service 17f749
    case SQL_DECIMAL:
Packit Service 17f749
      return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return MADB_IsIntType(ConciseType);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
BOOL MADB_IsIntType(SQLSMALLINT ConciseType)
Packit Service 17f749
{
Packit Service 17f749
  switch (ConciseType)
Packit Service 17f749
  {
Packit Service 17f749
  case SQL_C_TINYINT:
Packit Service 17f749
  case SQL_C_STINYINT:
Packit Service 17f749
  case SQL_C_UTINYINT:
Packit Service 17f749
  case SQL_C_SHORT:
Packit Service 17f749
  case SQL_C_SSHORT:
Packit Service 17f749
  case SQL_C_USHORT:
Packit Service 17f749
  case SQL_C_LONG:
Packit Service 17f749
  case SQL_C_SLONG:
Packit Service 17f749
  case SQL_C_ULONG:
Packit Service 17f749
  case SQL_C_UBIGINT:
Packit Service 17f749
  case SQL_C_SBIGINT:
Packit Service 17f749
  case SQL_BIGINT:
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
  return FALSE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* Now it's more like installing result */
Packit Service 17f749
void MADB_InstallStmt(MADB_Stmt *Stmt, MYSQL_STMT *stmt)
Packit Service 17f749
{
Packit Service 17f749
  Stmt->stmt= stmt;
Packit Service 17f749
Packit Service 17f749
  if (mysql_stmt_field_count(Stmt->stmt) == 0)
Packit Service 17f749
  {
Packit Service 17f749
    MADB_DescFree(Stmt->Ird, TRUE);
Packit Service 17f749
    Stmt->AffectedRows= mysql_stmt_affected_rows(Stmt->stmt);
Packit Service 17f749
  }
Packit Service 17f749
  else
Packit Service 17f749
  {
Packit Service 17f749
    Stmt->AffectedRows= 0;
Packit Service 17f749
    MADB_StmtResetResultStructures(Stmt);
Packit Service 17f749
    MADB_DescSetIrdMetadata(Stmt, mysql_fetch_fields(FetchMetadata(Stmt)), mysql_stmt_field_count(Stmt->stmt));
Packit Service 17f749
  }
Packit Service 17f749
}