diff options
Diffstat (limited to 'ndb/src/old_files/client/odbc/common/DataField.cpp')
-rw-r--r-- | ndb/src/old_files/client/odbc/common/DataField.cpp | 3023 |
1 files changed, 0 insertions, 3023 deletions
diff --git a/ndb/src/old_files/client/odbc/common/DataField.cpp b/ndb/src/old_files/client/odbc/common/DataField.cpp deleted file mode 100644 index 11aae7d893b..00000000000 --- a/ndb/src/old_files/client/odbc/common/DataField.cpp +++ /dev/null @@ -1,3023 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "DataField.hpp" - -#ifndef INT_MAX -#define INT_MAX (2147483647) -#endif - -#ifndef INT_MIN -#define INT_MIN (-INT_MAX - 1) -#endif - -#ifndef UINT_MAX -#define UINT_MAX 4294967295U -#endif - -#ifndef FLT_MAX -#define FLT_MAX (3.402823466E+38F) -#endif -#ifndef FLT_MIN -#define FLT_MIN (1.175494351E-38F) -#endif - -#ifdef NDB_WIN32 -#define FMT_I64 "%I64d" -#define FMT_U64 "%I64u" -#else -#define FMT_I64 "%lld" -#define FMT_U64 "%llu" -#endif - -#ifdef NDB_WIN32 -#define strtoll(str, endptr, base) strtoint64(str, endptr, base) -#define strtoull(str, endptr, base) strtouint64(str, endptr, base) - -static Int64 -strtoint64(const char *str, char **endptr, int base) -{ - Int64 x = 0; - while (*str == ' ') - str++; - const char* p = str; - while ('0' <= *p && *p <= '9') - x = 10 * x + *p++ - '0'; - if (p == str) { - *endptr = 0; - return 0; - } - *endptr = (char*)p; - return x; -} - -static Uint64 -strtouint64(const char *str, char **endptr, int base) -{ - Uint64 x = 0; - while (*str == ' ') - str++; - const char* p = str; - while ('0' <= *p && *p <= '9') - x = 10 * x + *p++ - '0'; - if (p == str) { - *endptr = 0; - return 0; - } - *endptr = (char*)p; - return x; -} -#endif - -// LexSpec - -void -LexSpec::convert(Ctx& ctx, const BaseString& value, SqlField& out) -{ - const SqlSpec& sqlSpec = out.sqlSpec(); - const SqlType& sqlType = sqlSpec.sqlType(); - out.alloc(); - if (sqlType.type() == SqlType::Char) { - const SqlChar* s = (const SqlChar*)value.c_str(); - out.sqlChar(s, SQL_NTS); - return; - } - if (sqlType.type() == SqlType::Bigint) { - char* endptr = 0; - SqlBigint n = static_cast<SqlBigint>(strtoll(value.c_str(), &endptr, 10)); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Error::Gen, "cannot convert '%s' to integer", value.c_str()); - return; - } - out.sqlBigint(n); - return; - } - if (sqlType.type() == SqlType::Double) { - char* endptr = 0; - SqlDouble x = static_cast<SqlDouble>(strtod(value.c_str(), &endptr)); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Error::Gen, "cannot convert '%s' to number", value.c_str()); - return; - } - out.sqlDouble(x); - return; - } - if (sqlType.type() == SqlType::Null) { - out.u_null.m_nullFlag = true; - return; - } - ctx_assert(false); -} - -// SqlField - -void -SqlField::alloc() -{ - ctx_assert(sqlSpec().store() == SqlSpec::Physical); - const SqlType& sqlType = sqlSpec().sqlType(); - if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varchar) - n += 2; - if (n > SqlField_CharSmall) { - u_data.m_sqlChar = new SqlChar[n]; - } - } - if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varbinary) - n += 2; - if (n > SqlField_CharSmall) { - u_data.m_sqlChar = new SqlChar[n]; - } - } -} - -void -SqlField::alloc(const SqlField& sqlField) -{ - alloc(); - const SqlType& sqlType = sqlSpec().sqlType(); - if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varchar) - n += 2; - if (n > SqlField_CharSmall) { - memcpy(u_data.m_sqlChar, sqlField.u_data.m_sqlChar, n); - } - } - if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varbinary) - n += 2; - if (n > SqlField_CharSmall) { - memcpy(u_data.m_sqlChar, sqlField.u_data.m_sqlChar, n); - } - } -} - -const void* -SqlField::addr() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->addr(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varchar) - n += 2; - if (n > SqlField_CharSmall) { - return static_cast<const void*>(u_data.m_sqlChar); - } - return static_cast<const void*>(u_data.m_sqlCharSmall); - } - if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varbinary) - n += 2; - if (n > SqlField_CharSmall) { - return static_cast<const void*>(u_data.m_sqlChar); - } - return static_cast<const void*>(u_data.m_sqlCharSmall); - } - if (sqlType.type() == SqlType::Smallint) { - return static_cast<const void*>(&u_data.m_sqlSmallint); - } - if (sqlType.type() == SqlType::Integer) { - return static_cast<const void*>(&u_data.m_sqlInteger); - } - if (sqlType.type() == SqlType::Bigint) { - return static_cast<const void*>(&u_data.m_sqlBigint); - } - if (sqlType.type() == SqlType::Real) { - return static_cast<const void*>(&u_data.m_sqlReal); - } - if (sqlType.type() == SqlType::Double) { - return static_cast<const void*>(&u_data.m_sqlDouble); - } - if (sqlType.type() == SqlType::Datetime) { - return static_cast<const void*>(&u_data.m_sqlDatetime); - } - ctx_assert(false); // SqlType::Null has no address - return 0; -} - -void* -SqlField::addr() -{ - const SqlType& sqlType = sqlSpec().sqlType(); - if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varchar) - n += 2; - if (n > SqlField_CharSmall) { - return static_cast<void*>(u_data.m_sqlChar); - } - return static_cast<void*>(u_data.m_sqlCharSmall); - } - if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varbinary) - n += 2; - if (n > SqlField_CharSmall) { - return static_cast<void*>(u_data.m_sqlChar); - } - return static_cast<void*>(u_data.m_sqlCharSmall); - } - if (sqlType.type() == SqlType::Smallint) { - return static_cast<void*>(&u_data.m_sqlSmallint); - } - if (sqlType.type() == SqlType::Integer) { - return static_cast<void*>(&u_data.m_sqlInteger); - } - if (sqlType.type() == SqlType::Bigint) { - return static_cast<void*>(&u_data.m_sqlBigint); - } - if (sqlType.type() == SqlType::Real) { - return static_cast<void*>(&u_data.m_sqlReal); - } - if (sqlType.type() == SqlType::Double) { - return static_cast<void*>(&u_data.m_sqlDouble); - } - if (sqlType.type() == SqlType::Datetime) { - return static_cast<void*>(&u_data.m_sqlDatetime); - } - ctx_assert(false); // SqlType::Null has no address - return 0; -} - -unsigned -SqlField::allocSize() const -{ - const SqlType& sqlType = sqlSpec().sqlType(); - unsigned n = sqlType.size(); - if (sqlType.type() == SqlType::Varchar || sqlType.type() == SqlType::Varbinary) { - n += 2; - } - return n; -} - -void -SqlField::free() -{ - ctx_assert(sqlSpec().store() == SqlSpec::Physical); - const SqlType& sqlType = sqlSpec().sqlType(); - if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varchar) - n += 2; - if (n > SqlField_CharSmall) { - delete[] u_data.m_sqlChar; - u_data.m_sqlChar = 0; // safety since dtor used explicitly - } - } - if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) { - unsigned n = sqlType.length(); - if (sqlType.type() == SqlType::Varbinary) - n += 2; - if (n > SqlField_CharSmall) { - delete[] u_data.m_sqlChar; - u_data.m_sqlChar = 0; // safety since dtor used explicitly - } - } -} - -// get - -const SqlChar* -SqlField::sqlChar() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlChar(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Char); - if (sqlType.length() > SqlField_CharSmall) - return u_data.m_sqlChar; - return u_data.m_sqlCharSmall; -} - -const SqlChar* -SqlField::sqlVarchar(unsigned* length) const -{ -#if NDB_VERSION_MAJOR >= 3 - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlVarchar(length); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Varchar); - const SqlChar* sqlChar; - unsigned n = sqlType.length(); - if (2 + n > SqlField_CharSmall) - sqlChar = u_data.m_sqlChar; - else - sqlChar = u_data.m_sqlCharSmall; - if (length != 0) - *length = (sqlChar[0] << 8) | sqlChar[1]; // big-endian - return sqlChar + 2; -#else - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlVarchar(length); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Varchar); - const SqlChar* sqlChar; - unsigned n = sqlType.length(); - if (n + 2 > SqlField_CharSmall) - sqlChar = u_data.m_sqlChar; - else - sqlChar = u_data.m_sqlCharSmall; - if (length != 0) - *length = (sqlChar[n + 0] << 8) | sqlChar[n + 1]; // big-endian - return sqlChar; -#endif -} - -const SqlChar* -SqlField::sqlBinary() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlChar(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Binary); - if (sqlType.length() > SqlField_CharSmall) - return u_data.m_sqlChar; - return u_data.m_sqlCharSmall; -} - -const SqlChar* -SqlField::sqlVarbinary(unsigned* length) const -{ -#if NDB_VERSION_MAJOR >= 3 - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlVarchar(length); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Varbinary); - const SqlChar* sqlChar; - unsigned n = sqlType.length(); - if (2 + n > SqlField_CharSmall) - sqlChar = u_data.m_sqlChar; - else - sqlChar = u_data.m_sqlCharSmall; - if (length != 0) - *length = (sqlChar[0] << 8) | sqlChar[1]; // big-endian - return sqlChar + 2; -#else - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlVarchar(length); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Varbinary); - const SqlChar* sqlChar; - unsigned n = sqlType.length(); - if (n + 2 > SqlField_CharSmall) - sqlChar = u_data.m_sqlChar; - else - sqlChar = u_data.m_sqlCharSmall; - if (length != 0) - *length = (sqlChar[n + 0] << 8) | sqlChar[n + 1]; // big-endian - return sqlChar; -#endif -} - -SqlSmallint -SqlField::sqlSmallint() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlSmallint(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Smallint); - return u_data.m_sqlSmallint; -} - -SqlInteger -SqlField::sqlInteger() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlInteger(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Integer); - return u_data.m_sqlInteger; -} - -SqlBigint -SqlField::sqlBigint() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlBigint(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Bigint); - return u_data.m_sqlBigint; -} - -SqlReal -SqlField::sqlReal() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlReal(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Real); - return u_data.m_sqlReal; -} - -SqlDouble -SqlField::sqlDouble() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlDouble(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Double); - return u_data.m_sqlDouble; -} - -SqlDatetime -SqlField::sqlDatetime() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlDatetime(); - } - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Datetime); - return u_data.m_sqlDatetime; -} - -// set - -void -SqlField::sqlChar(const SqlChar* value, int length) -{ - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Char); - unsigned n = sqlType.length(); - SqlChar* p = n > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall; - const SqlChar* q = value; - unsigned m = length == SQL_NTS ? strlen((const char*)q) : length; - ctx_assert(m <= n); - for (unsigned i = 0; i < m; i++) - *p++ = *q++; - for (unsigned i = m; i < n; i++) - *p++ = 0x20; // space - u_null.m_nullFlag = false; -} - -void -SqlField::sqlVarchar(const SqlChar* value, int length) -{ -#if NDB_VERSION_MAJOR >= 3 - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Varchar); - unsigned n = sqlType.length(); - SqlChar* p = 2 + n > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall; - const SqlChar* q = value; - unsigned m = length == SQL_NTS ? strlen((const char*)q) : length; - ctx_assert(m <= n); - *p++ = (m >> 8) & 0xff; // big-endian - *p++ = (m & 0xff); - for (unsigned i = 0; i < m; i++) - *p++ = *q++; - for (unsigned i = m; i < n; i++) - *p++ = 0x0; // null - u_null.m_nullFlag = false; -#else - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Varchar); - unsigned n = sqlType.length(); - SqlChar* p = n + 2 > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall; - const SqlChar* q = value; - unsigned m = length == SQL_NTS ? strlen((const char*)q) : length; - ctx_assert(m <= n); - for (unsigned i = 0; i < m; i++) - *p++ = *q++; - for (unsigned i = m; i < n; i++) - *p++ = 0x0; // null - *p++ = (m >> 8) & 0xff; // big-endian - *p++ = (m & 0xff); - u_null.m_nullFlag = false; -#endif -} - -void -SqlField::sqlBinary(const SqlChar* value, int length) -{ - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Binary); - unsigned n = sqlType.length(); - SqlChar* p = n > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall; - const SqlChar* q = value; - unsigned m = length; - ctx_assert(m <= n); - for (unsigned i = 0; i < m; i++) - *p++ = *q++; - for (unsigned i = m; i < n; i++) - *p++ = 0x0; // null - u_null.m_nullFlag = false; -} - -void -SqlField::sqlVarbinary(const SqlChar* value, int length) -{ -#if NDB_VERSION_MAJOR >= 3 - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Varbinary); - unsigned n = sqlType.length(); - SqlChar* p = 2 + n > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall; - const SqlChar* q = value; - unsigned m = length; - ctx_assert(m <= n); - *p++ = (m >> 8) & 0xff; // big-endian - *p++ = (m & 0xff); - for (unsigned i = 0; i < m; i++) - *p++ = *q++; - for (unsigned i = m; i < n; i++) - *p++ = 0x0; // null - u_null.m_nullFlag = false; -#else - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Varbinary); - unsigned n = sqlType.length(); - SqlChar* p = n + 2 > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall; - const SqlChar* q = value; - unsigned m = length; - ctx_assert(m <= n); - for (unsigned i = 0; i < m; i++) - *p++ = *q++; - for (unsigned i = m; i < n; i++) - *p++ = 0x0; // null - *p++ = (m >> 8) & 0xff; // big-endian - *p++ = (m & 0xff); - u_null.m_nullFlag = false; -#endif -} - -void -SqlField::sqlSmallint(SqlSmallint value) -{ - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Smallint); - u_data.m_sqlSmallint = value; - u_null.m_nullFlag = false; -} - -void -SqlField::sqlInteger(SqlInteger value) -{ - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Integer); - u_data.m_sqlInteger = value; - u_null.m_nullFlag = false; -} - -void -SqlField::sqlBigint(SqlBigint value) -{ - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Bigint); - u_data.m_sqlBigint = value; - u_null.m_nullFlag = false; -} - -void -SqlField::sqlReal(SqlReal value) -{ - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Real); - u_data.m_sqlReal = value; - u_null.m_nullFlag = false; -} - -void -SqlField::sqlDouble(SqlDouble value) -{ - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Double); - u_data.m_sqlDouble = value; - u_null.m_nullFlag = false; -} - -void -SqlField::sqlDatetime(SqlDatetime value) -{ - const SqlType& sqlType = sqlSpec().sqlType(); - ctx_assert(sqlType.type() == SqlType::Datetime); - u_data.m_sqlDatetime = value; - u_null.m_nullFlag = false; -} - -// get and and set null - -bool -SqlField::sqlNull() const -{ - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - return u_data.m_sqlField->sqlNull(); - } - return u_null.m_nullFlag; -} - -void -SqlField::sqlNull(bool value) -{ - u_null.m_nullFlag = value; -} - -unsigned -SqlField::trim() const -{ - const SqlType& sqlType = sqlSpec().sqlType(); - unsigned n = 0; - const SqlChar* s = 0; - if (sqlType.type() == SqlType::Char) { - n = sqlType.length(); - s = sqlChar(); - } else if (sqlType.type() == SqlType::Varchar) { - s = sqlVarchar(&n); - } else { - ctx_assert(false); - return 0; - } - while (n > 0 && s[n - 1] == 0x20) - n--; - return n; -} - -void -SqlField::copy(Ctx& ctx, SqlField& out) const -{ - const SqlField& f1 = *this; - SqlField& f2 = out; - const SqlType& t1 = f1.sqlSpec().sqlType(); - const SqlType& t2 = f2.sqlSpec().sqlType(); - ctx_assert(t1.type() == t2.type()); - if (f1.sqlNull()) { - f2.sqlNull(true); - return; - } - if (t1.type() == SqlType::Char) { - f2.sqlChar(f1.sqlChar(), t1.length()); - return; - } - if (t1.type() == SqlType::Varchar) { - unsigned length; - const SqlChar* s1 = f1.sqlVarchar(&length); - f2.sqlVarchar(s1, length); - return; - } - if (t1.type() == SqlType::Binary) { - f2.sqlBinary(f1.sqlBinary(), t1.length()); - return; - } - if (t1.type() == SqlType::Varbinary) { - unsigned length; - const SqlChar* s1 = f1.sqlVarbinary(&length); - f2.sqlVarbinary(s1, length); - return; - } - if (t1.type() == SqlType::Smallint) { - f2.sqlSmallint(f1.sqlSmallint()); - return; - } - if (t1.type() == SqlType::Integer) { - f2.sqlInteger(f1.sqlInteger()); - return; - } - if (t1.type() == SqlType::Bigint) { - f2.sqlBigint(f1.sqlBigint()); - return; - } - if (t1.type() == SqlType::Real) { - f2.sqlReal(f1.sqlReal()); - return; - } - if (t1.type() == SqlType::Double) { - f2.sqlDouble(f1.sqlDouble()); - return; - } - if (t1.type() == SqlType::Datetime) { - f2.sqlDatetime(f1.sqlDatetime()); - return; - } - ctx_assert(false); -} - -bool -SqlField::cast(Ctx& ctx, SqlField& out) const -{ - const SqlField& f1 = *this; - SqlField& f2 = out; - if (f1.sqlNull()) { - f2.sqlNull(true); - return true; - } - const SqlType& t1 = f1.sqlSpec().sqlType(); - const SqlType& t2 = f2.sqlSpec().sqlType(); - if (t1.type() == SqlType::Char) { - if (t2.type() == SqlType::Char) { - unsigned n1 = f1.trim(); - if (n1 > t2.length()) - return false; - f2.sqlChar(f1.sqlChar(), n1); - return true; - } - if (t2.type() == SqlType::Varchar) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlVarchar(f1.sqlChar(), n1); - return true; - } - if (t2.type() == SqlType::Binary) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlBinary(f1.sqlChar(), n1); - return true; - } - if (t2.type() == SqlType::Varbinary) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlVarbinary(f1.sqlChar(), n1); - return true; - } - ctx_assert(false); - return false; - } - if (t1.type() == SqlType::Varchar) { - if (t2.type() == SqlType::Char) { - unsigned n1 = f1.trim(); - if (n1 > t2.length()) - return false; - f2.sqlChar(f1.sqlVarchar(0), n1); - return true; - } - if (t2.type() == SqlType::Varchar) { - unsigned n1 = f1.trim(); - if (n1 > t2.length()) - return false; - f2.sqlVarchar(f1.sqlVarchar(0), n1); - return true; - } - if (t2.type() == SqlType::Binary) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlBinary(f1.sqlVarchar(0), n1); - return true; - } - if (t2.type() == SqlType::Varbinary) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlVarbinary(f1.sqlVarchar(0), n1); - return true; - } - ctx_assert(false); - return false; - } - if (t1.type() == SqlType::Binary) { - if (t2.type() == SqlType::Binary) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlBinary(f1.sqlBinary(), n1); - return true; - } - if (t2.type() == SqlType::Varbinary) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlVarbinary(f1.sqlBinary(), n1); - return true; - } - ctx_assert(false); - return false; - } - if (t1.type() == SqlType::Varbinary) { - if (t2.type() == SqlType::Binary) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlBinary(f1.sqlVarbinary(0), n1); - return true; - } - if (t2.type() == SqlType::Varbinary) { - unsigned n1 = t1.length(); - if (n1 > t2.length()) - return false; - f2.sqlVarbinary(f1.sqlVarbinary(0), n1); - return true; - } - ctx_assert(false); - return false; - } - if (t1.type() == SqlType::Smallint) { - if (! t2.unSigned()) { - SqlSmallint x1 = f1.sqlSmallint(); - if (t2.type() == SqlType::Smallint) { - f2.sqlSmallint(x1); - return true; - } - if (t2.type() == SqlType::Integer) { - SqlInteger x2 = static_cast<SqlInteger>(x1); - f2.sqlInteger(x2); - return true; - } - if (t2.type() == SqlType::Bigint) { - SqlBigint x2 = static_cast<SqlBigint>(x1); - f2.sqlBigint(x2); - return true; - } - if (t2.type() == SqlType::Real) { - SqlReal x2 = static_cast<SqlReal>(x1); - f2.sqlReal(x2); - return true; - } - if (t2.type() == SqlType::Double) { - SqlDouble x2 = static_cast<SqlDouble>(x1); - f2.sqlDouble(x2); - return true; - } - } else { - SqlUsmallint x1 = f1.sqlSmallint(); - if (t2.type() == SqlType::Smallint) { - f2.sqlSmallint(x1); - return true; - } - if (t2.type() == SqlType::Integer) { - SqlUinteger x2 = static_cast<SqlUinteger>(x1); - f2.sqlInteger(x2); - return true; - } - if (t2.type() == SqlType::Bigint) { - SqlUbigint x2 = static_cast<SqlUbigint>(x1); - f2.sqlBigint(x2); - return true; - } - } - ctx_assert(false); - return false; - } - if (t1.type() == SqlType::Integer) { - if (! t2.unSigned()) { - SqlInteger x1 = f1.sqlInteger(); - if (t2.type() == SqlType::Smallint) { - SqlSmallint x2 = static_cast<SqlSmallint>(x1); - if (x1 != static_cast<SqlInteger>(x2)) - return false; - f2.sqlSmallint(x2); - return true; - } - if (t2.type() == SqlType::Integer) { - f2.sqlInteger(x1); - return true; - } - if (t2.type() == SqlType::Bigint) { - SqlBigint x2 = static_cast<SqlBigint>(x1); - f2.sqlBigint(x2); - return true; - } - if (t2.type() == SqlType::Real) { - SqlReal x2 = static_cast<SqlReal>(x1); - f2.sqlReal(x2); - return true; - } - if (t2.type() == SqlType::Double) { - SqlDouble x2 = static_cast<SqlDouble>(x1); - f2.sqlDouble(x2); - return true; - } - } else { - SqlUinteger x1 = f1.sqlInteger(); - if (t2.type() == SqlType::Smallint) { - SqlUsmallint x2 = static_cast<SqlUsmallint>(x1); - if (x1 != static_cast<SqlUinteger>(x2)) - return false; - f2.sqlSmallint(x2); - return true; - } - if (t2.type() == SqlType::Integer) { - f2.sqlInteger(x1); - return true; - } - if (t2.type() == SqlType::Bigint) { - SqlUbigint x2 = static_cast<SqlUbigint>(x1); - f2.sqlBigint(x2); - return true; - } - } - ctx_assert(false); - return false; - } - if (t1.type() == SqlType::Bigint) { - if (! t2.unSigned()) { - SqlBigint x1 = f1.sqlBigint(); - if (t2.type() == SqlType::Smallint) { - SqlSmallint x2 = static_cast<SqlSmallint>(x1); - if (x1 != static_cast<SqlBigint>(x2)) - return false; - f2.sqlSmallint(x2); - return true; - } - if (t2.type() == SqlType::Integer) { - SqlInteger x2 = static_cast<SqlInteger>(x1); - if (x1 != static_cast<SqlBigint>(x2)) - return false; - f2.sqlInteger(x2); - return true; - } - if (t2.type() == SqlType::Bigint) { - f2.sqlBigint(x1); - return true; - } - if (t2.type() == SqlType::Real) { - SqlReal x2 = static_cast<SqlReal>(x1); - f2.sqlReal(x2); - return true; - } - if (t2.type() == SqlType::Double) { - SqlDouble x2 = static_cast<SqlDouble>(x1); - f2.sqlDouble(x2); - return true; - } - } else { - SqlUbigint x1 = f1.sqlBigint(); - if (t2.type() == SqlType::Smallint) { - SqlUsmallint x2 = static_cast<SqlUsmallint>(x1); - if (x1 != static_cast<SqlUbigint>(x2)) - return false; - f2.sqlSmallint(x2); - return true; - } - if (t2.type() == SqlType::Integer) { - SqlUinteger x2 = static_cast<SqlUinteger>(x1); - if (x1 != static_cast<SqlUbigint>(x2)) - return false; - f2.sqlInteger(x2); - return true; - } - if (t2.type() == SqlType::Bigint) { - f2.sqlBigint(x1); - return true; - } - } - ctx_assert(false); - return false; - } - if (t1.type() == SqlType::Real) { - SqlReal x1 = f1.sqlReal(); - int off = 0; - if (x1 > 0.0 && x1 - floor(x1) >= 0.5) - off = 1; - if (x1 < 0.0 && x1 - floor(x1) <= 0.5) - off = -1; - bool b = (x1 - floor(x1) < 0.5); - if (t2.type() == SqlType::Smallint) { - SqlSmallint x2 = static_cast<SqlSmallint>(x1) + off; - if (fabs(x1 - static_cast<SqlReal>(x2)) >= 1.0) - return false; - f2.sqlSmallint(x2); - return true; - } - if (t2.type() == SqlType::Integer) { - SqlInteger x2 = static_cast<SqlInteger>(x1) + off; - if (fabs(x1 - static_cast<SqlReal>(x2)) >= 1.0) - return false; - f2.sqlInteger(x2); - return true; - } - if (t2.type() == SqlType::Bigint) { - SqlBigint x2 = static_cast<SqlBigint>(x1) + off; - if (fabs(x1 - static_cast<SqlReal>(x2)) >= 1.0) - return false; - f2.sqlBigint(x2); - return true; - } - if (t2.type() == SqlType::Real) { - f2.sqlReal(x1); - return true; - } - if (t2.type() == SqlType::Double) { - SqlDouble x2 = static_cast<SqlDouble>(x1); - f2.sqlDouble(x2); - return true; - } - ctx_assert(false); - return false; - } - if (t1.type() == SqlType::Double) { - SqlDouble x1 = f1.sqlDouble(); - int off = 0; - if (x1 > 0.0 && x1 - floor(x1) >= 0.5) - off = 1; - if (x1 < 0.0 && x1 - floor(x1) <= 0.5) - off = -1; - bool b = (x1 - floor(x1) < 0.5); - if (t2.type() == SqlType::Smallint) { - SqlSmallint x2 = static_cast<SqlSmallint>(x1) + off; - if (fabs(x1 - static_cast<SqlDouble>(x2)) >= 1.0) - return false; - f2.sqlSmallint(x2); - return true; - } - if (t2.type() == SqlType::Integer) { - SqlInteger x2 = static_cast<SqlInteger>(x1) + off; - if (fabs(x1 - static_cast<SqlDouble>(x2)) >= 1.0) - return false; - f2.sqlInteger(x2); - return true; - } - if (t2.type() == SqlType::Bigint) { - SqlBigint x2 = static_cast<SqlBigint>(x1) + off; - if (fabs(x1 - static_cast<SqlDouble>(x2)) >= 1.0) - return false; - f2.sqlBigint(x2); - return true; - } - if (t2.type() == SqlType::Real) { - SqlReal x2 = static_cast<SqlReal>(x1); - if (fabs(x1 - static_cast<SqlDouble>(x2)) >= 1.0) // XXX - return false; - f2.sqlReal(x1); - return true; - } - if (t2.type() == SqlType::Double) { - f2.sqlDouble(x1); - return true; - } - ctx_assert(false); - return false; - } - ctx_assert(false); - return false; -} - -bool -SqlField::less(const SqlField& sqlField) const -{ - const SqlField& f1 = *this; - const SqlField& f2 = sqlField; - const SqlType& t1 = f1.sqlSpec().sqlType(); - const SqlType& t2 = f2.sqlSpec().sqlType(); - ctx_assert(t1.type() == t2.type()); - if (t1.type() == SqlType::Char) { - const SqlChar* s1 = f1.sqlChar(); - const SqlChar* s2 = f2.sqlChar(); - unsigned n1 = t1.length(); - unsigned n2 = t2.length(); - SqlChar c1 = 0; - SqlChar c2 = 0; - unsigned i = 0; - while (i < n1 || i < n2) { - c1 = i < n1 ? s1[i] : 0x20; - c2 = i < n2 ? s2[i] : 0x20; - if (c1 != c2) - break; - i++; - } - return (c1 < c2); - } - if (t1.type() == SqlType::Varchar) { - unsigned n1, n2; - const SqlChar* s1 = f1.sqlVarchar(&n1); - const SqlChar* s2 = f2.sqlVarchar(&n2); - SqlChar c1 = 0; - SqlChar c2 = 0; - unsigned i = 0; - while (i < n1 || i < n2) { - c1 = i < n1 ? s1[i] : 0x0; - c2 = i < n2 ? s2[i] : 0x0; - if (c1 != c2) - break; - i++; - } - return (c1 < c2); - } - if (t1.type() == SqlType::Smallint) { - ctx_assert(t1.unSigned() == t2.unSigned()); - if (! t1.unSigned()) { - SqlSmallint x1 = f1.sqlSmallint(); - SqlSmallint x2 = f2.sqlSmallint(); - return (x1 < x2); - } else { - SqlUsmallint x1 = f1.sqlSmallint(); - SqlUsmallint x2 = f2.sqlSmallint(); - return (x1 < x2); - } - } - if (t1.type() == SqlType::Integer) { - ctx_assert(t1.unSigned() == t2.unSigned()); - if (! t1.unSigned()) { - SqlInteger x1 = f1.sqlInteger(); - SqlInteger x2 = f2.sqlInteger(); - return (x1 < x2); - } else { - SqlUinteger x1 = f1.sqlInteger(); - SqlUinteger x2 = f2.sqlInteger(); - return (x1 < x2); - } - } - if (t1.type() == SqlType::Bigint) { - ctx_assert(t1.unSigned() == t2.unSigned()); - if (! t1.unSigned()) { - SqlBigint x1 = f1.sqlBigint(); - SqlBigint x2 = f2.sqlBigint(); - return (x1 < x2); - } else { - SqlUbigint x1 = f1.sqlBigint(); - SqlUbigint x2 = f2.sqlBigint(); - return (x1 < x2); - } - } - if (t1.type() == SqlType::Real) { - SqlReal x1 = f1.sqlReal(); - SqlReal x2 = f2.sqlReal(); - return (x1 < x2); - } - if (t1.type() == SqlType::Double) { - SqlDouble x1 = f1.sqlDouble(); - SqlDouble x2 = f2.sqlDouble(); - return (x1 < x2); - } - if (t1.type() == SqlType::Datetime) { - SqlDatetime x1 = f1.sqlDatetime(); - SqlDatetime x2 = f2.sqlDatetime(); - return x1.less(x2); - } - ctx_assert(false); -} - -// copy from external - -static bool -copyin_char_char(Ctx& ctx, char* value, unsigned n, const char* ptr, const SQLINTEGER* ind, int* off, SqlChar* addr, int fieldId) -{ - if (off != 0 && *off >= 0) { - if ((unsigned)*off > n) { - ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d truncated (%u > %u)", fieldId, (unsigned)*off, n); - return false; - } - value += *off; - n -= *off; - } - unsigned m; - if (ind == 0 || *ind == SQL_NTS) - m = strlen(ptr); - else - m = *ind; - if (m > n) { - ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d truncated (%u > %u)", fieldId, m, n); - return false; - } - for (unsigned i = 0; i < m; i++) - value[i] = ptr[i]; - if (off != 0 && *off >= 0) - *off += m; - for (unsigned i = m; i < n; i++) - value[i] = addr == 0 ? 0x20 : 0x0; - if (addr != 0) { - if (off != 0 && *off >= 0) - m = *off; - addr[0] = (m >> 8) & 0xff; - addr[1] = (m & 0xff); - } - return true; -} - -static bool -copyin_binary_binary(Ctx& ctx, char* value, unsigned n, const char* ptr, const SQLINTEGER* ind, int* off, SqlChar* addr, int fieldId) -{ - if (off != 0 && *off >= 0) { - if ((unsigned)*off > n) { - ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d truncated (%u > %u)", fieldId, (unsigned)*off, n); - return false; - } - value += *off; - n -= *off; - } - if (ind == 0) { - ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d missing length", fieldId); - return false; - } - if (*ind < 0) { - ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d invalid length %d", fieldId, (int)*ind); - return false; - } - unsigned m; - m = *ind; - if (m > n) { - ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d truncated (%u > %u)", fieldId, m, n); - return false; - } - for (unsigned i = 0; i < m; i++) - value[i] = ptr[i]; - if (off != 0 && *off >= 0) - *off += m; - for (unsigned i = m; i < n; i++) - value[i] = addr == 0 ? 0x0 : 0x0; // just null - if (addr != 0) { - if (off != 0 && *off >= 0) - m = *off; - addr[0] = (m >> 8) & 0xff; - addr[1] = (m & 0xff); - } - return true; -} - -static bool -copyin_signed_char(Ctx& ctx, SqlBigint* value, const char* ptr, int fieldId) -{ - errno = 0; - char* endptr = 0; - SqlBigint x = strtoll(ptr, &endptr, 10); - if (endptr == 0 || *endptr != 0) { - errno = 0; - endptr = 0; - double y = strtod(ptr, &endptr); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Sqlstate::_22005, Error::Gen, "input parameter %d value %s not numeric", fieldId, ptr); - return false; - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "input parameter %d value %s overflow", fieldId, ptr); - return false; - } - // XXX should handle 123.000 - ctx.pushStatus(Sqlstate::_01004, Error::Gen, "input parameter %d value %s truncated", fieldId, ptr); - x = static_cast<SqlBigint>(y); - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "input parameter %d value %s overflow", fieldId, ptr); - return false; - } - *value = x; - return true; -} - -static bool -copyin_double_char(Ctx& ctx, SqlDouble* value, const char* ptr, int fieldId) -{ - errno = 0; - char* endptr = 0; - double x = strtod(ptr, &endptr); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Sqlstate::_22005, Error::Gen, "input parameter %d value %s not numeric", fieldId, ptr); - return false; - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "input parameter %d value %s overflow", fieldId, ptr); - return false; - } - *value = x; - return true; -} - -void -SqlField::copyin(Ctx& ctx, ExtField& extField) -{ - ctx_assert(extField.extSpec().extType().type() != ExtType::Unbound); - ctx_assert(sqlSpec().store() == SqlSpec::Physical); - SQLINTEGER* indPtr = extField.m_indPtr; - const int fieldId = extField.fieldId(); - if (indPtr != 0 && *indPtr == SQL_NULL_DATA) { - sqlNull(true); - return; - } - const SqlType& sqlType = sqlSpec().sqlType(); - const ExtType& extType = extField.extSpec().extType(); - if (extField.m_pos > 0) { - if (sqlType.type() == SqlType::Char && extType.type() == ExtType::Char) - ; - else if (sqlType.type() == SqlType::Varchar && extType.type() == ExtType::Char) - ; - else { - char buf[40]; - sqlType.print(buf, sizeof(buf)); - ctx.pushStatus(Sqlstate::_HY019, Error::Gen, "cannot send %s data in pieces", buf); - return; - } - } - if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) { - unsigned length = 0; - char* value = 0; - SqlChar* laddr = 0; // Varchar length address - if (sqlType.type() == SqlType::Char) { - length = sqlType.length(); - if (length > SqlField_CharSmall) - value = reinterpret_cast<char *>(u_data.m_sqlChar); - else - value = reinterpret_cast<char *>(u_data.m_sqlCharSmall); - laddr = 0; - } else { -#if NDB_VERSION_MAJOR >= 3 - length = sqlType.length(); - if (2 + length > SqlField_CharSmall) - value = reinterpret_cast<char *>(u_data.m_sqlChar + 2); - else - value = reinterpret_cast<char *>(u_data.m_sqlCharSmall + 2); - laddr = (SqlChar*)value - 2; -#else - length = sqlType.length(); - if (length + 2 > SqlField_CharSmall) - value = reinterpret_cast<char *>(u_data.m_sqlChar); - else - value = reinterpret_cast<char *>(u_data.m_sqlCharSmall); - laddr = (SqlChar*)value + length; -#endif - } - if (extType.type() == ExtType::Char) { - const char* dataPtr = static_cast<char*>(extField.m_dataPtr); - int* off = 0; - if (extField.m_pos >= 0) - off = &extField.m_pos; - if (! copyin_char_char(ctx, value, length, dataPtr, indPtr, off, laddr, fieldId)) - return; - sqlNull(false); - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - const short* dataPtr = static_cast<short*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, "%hd", *dataPtr); - if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId)) - return; - sqlNull(false); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - const unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, "%hu", *dataPtr); - if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId)) - return; - sqlNull(false); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - const long* dataPtr = static_cast<long*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, "%ld", *dataPtr); - if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId)) - return; - sqlNull(false); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - const unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, "%lu", *dataPtr); - if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId)) - return; - sqlNull(false); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - const SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, FMT_I64, *dataPtr); - if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId)) - return; - sqlNull(false); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - const SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, FMT_U64, *dataPtr); - if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId)) - return; - sqlNull(false); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - const float* dataPtr = static_cast<float*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, "%.7f", (double)*dataPtr); - if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId)) - return; - sqlNull(false); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - const double* dataPtr = static_cast<double*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, "%.14f", *dataPtr); - if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId)) - return; - sqlNull(false); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) { - unsigned length = 0; - char* value = 0; - SqlChar* laddr = 0; // Varbinary length address - if (sqlType.type() == SqlType::Binary) { - length = sqlType.length(); - if (length > SqlField_CharSmall) - value = reinterpret_cast<char *>(u_data.m_sqlChar); - else - value = reinterpret_cast<char *>(u_data.m_sqlCharSmall); - laddr = 0; - } else { -#if NDB_VERSION_MAJOR >= 3 - length = sqlType.length(); - if (2 + length > SqlField_CharSmall) - value = reinterpret_cast<char *>(u_data.m_sqlChar + 2); - else - value = reinterpret_cast<char *>(u_data.m_sqlCharSmall + 2); - laddr = (SqlChar*)value - 2; -#else - length = sqlType.length(); - if (length + 2 > SqlField_CharSmall) - value = reinterpret_cast<char *>(u_data.m_sqlChar); - else - value = reinterpret_cast<char *>(u_data.m_sqlCharSmall); - laddr = (SqlChar*)value + length; -#endif - } - if (extType.type() == ExtType::Binary) { - const char* dataPtr = static_cast<char*>(extField.m_dataPtr); - int* off = 0; - if (extField.m_pos >= 0) - off = &extField.m_pos; - if (! copyin_binary_binary(ctx, value, length, dataPtr, indPtr, off, laddr, fieldId)) - return; - sqlNull(false); - return; - } - } - if (sqlType.type() == SqlType::Smallint) { - SqlSmallint value; - if (extType.type() == ExtType::Char) { - const char* dataPtr = static_cast<char*>(extField.m_dataPtr); - SqlBigint x; - if (! copyin_signed_char(ctx, &x, dataPtr, fieldId)) - return; - value = x; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - value = *dataPtr; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - value = *dataPtr; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - value = *dataPtr; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - value = *dataPtr; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - value = (SqlSmallint)*dataPtr; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - value = (SqlSmallint)*dataPtr; - sqlSmallint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Integer) { - SqlInteger value; - if (extType.type() == ExtType::Char) { - const char* dataPtr = static_cast<char*>(extField.m_dataPtr); - SqlBigint x; - if (! copyin_signed_char(ctx, &x, dataPtr, fieldId)) - return; - value = x; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - value = *dataPtr; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - value = *dataPtr; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - value = *dataPtr; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - value = *dataPtr; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - value = (SqlInteger)*dataPtr; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - value = (SqlInteger)*dataPtr; - sqlInteger(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Bigint) { - SqlBigint value; - if (extType.type() == ExtType::Char) { - const char* dataPtr = static_cast<char*>(extField.m_dataPtr); - SqlBigint x; - if (! copyin_signed_char(ctx, &x, dataPtr, fieldId)) - return; - value = x; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - value = *dataPtr; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - value = *dataPtr; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - value = *dataPtr; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - value = *dataPtr; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - value = (SqlBigint)*dataPtr; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - value = (SqlBigint)*dataPtr; - sqlBigint(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Real) { - SqlReal value; - if (extType.type() == ExtType::Char) { - const char* dataPtr = static_cast<char*>(extField.m_dataPtr); - SqlDouble x; - if (! copyin_double_char(ctx, &x, dataPtr, fieldId)) - return; - value = x; - sqlReal(x); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - value = *dataPtr; - sqlReal(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - value = *dataPtr; - sqlReal(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - value = *dataPtr; - sqlReal(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - value = *dataPtr; - sqlReal(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlReal(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlReal(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - value = *dataPtr; - sqlReal(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - value = *dataPtr; - sqlReal(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Double) { - SqlDouble value; - if (extType.type() == ExtType::Char) { - const char* dataPtr = static_cast<char*>(extField.m_dataPtr); - SqlDouble x; - if (! copyin_double_char(ctx, &x, dataPtr, fieldId)) - return; - value = x; - sqlDouble(x); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - value = *dataPtr; - sqlDouble(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - value = *dataPtr; - sqlDouble(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - value = *dataPtr; - sqlDouble(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - value = *dataPtr; - sqlDouble(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlDouble(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - value = *dataPtr; - sqlDouble(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - value = *dataPtr; - sqlDouble(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - value = *dataPtr; - sqlDouble(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Datetime) { - SqlDatetime value; - if (extType.type() == ExtType::Char) { - // XXX replace sscanf by manual scan or regex - const char* dataPtr = static_cast<char*>(extField.m_dataPtr); - int cc = 0; - unsigned yy = 0, mm = 0, dd = 0, HH = 0, MM = 0, SS = 0, ff = 0; - bool setdate = false; - char dummy[10]; - if (sscanf(dataPtr, "%2d%2u-%2u-%2u %2u:%2u:%2u.%4u%1s", &cc, &yy, &mm, &dd, &HH, &MM, &SS, &ff, dummy) == 8) { - ; - } else if (sscanf(dataPtr, "%2d%2u-%2u-%2u %2u:%2u:%2u%1s", &cc, &yy, &mm, &dd, &HH, &MM, &SS, dummy) == 7) { - ; - } else if (sscanf(dataPtr, "%2d%2u-%2u-%2u%1s", &cc, &yy, &mm, &dd, dummy) == 4) { - ; - } else if (sscanf(dataPtr, "%2u:%2u:%2u.%4u%1s", &HH, &MM, &SS, &ff, dummy) == 4) { - setdate = true; - } else if (sscanf(dataPtr, "%2u:%2u:%2u%1s", &HH, &MM, &SS, dummy) == 3) { - setdate = true; - } else { - ctx.pushStatus(Sqlstate::_22008, Error::Gen, "invalid timestamp format '%s'", dataPtr); - return; - } - if (setdate) { - time_t clock = time(0); - struct tm* t = localtime(&clock); - cc = (1900 + t->tm_year) / 100; - yy = (1900 + t->tm_year) % 100; - mm = 1 + t->tm_mon; - dd = t->tm_mday; - } - value.cc(cc); - value.yy(yy); - value.mm(mm); - value.dd(dd); - value.HH(HH); - value.MM(MM); - value.SS(SS); - value.ff(ff); - // XXX write date routines later - if (! value.valid()) { - ctx.pushStatus(Sqlstate::_22008, Error::Gen, "invalid timestamp values '%s'", dataPtr); - return; - } - sqlDatetime(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Timestamp) { - SQL_TIMESTAMP_STRUCT* dataPtr = static_cast<SQL_TIMESTAMP_STRUCT*>(extField.m_dataPtr); - // XXX assume same datatype - value.cc(dataPtr->year / 100); - value.yy(dataPtr->year / 100); - value.mm(dataPtr->month); - value.dd(dataPtr->day); - value.HH(dataPtr->hour); - value.MM(dataPtr->minute); - value.SS(dataPtr->second); - value.ff(dataPtr->fraction); - if (! value.valid()) { - ctx.pushStatus(Sqlstate::_22008, Error::Gen, "invalid timestamp struct"); - return; - } - sqlDatetime(value); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - ctx_assert(false); // SqlType::Null not applicable -} - -// copy to external - -static bool -copyout_char_char(Ctx& ctx, const char* value, unsigned n, char* ptr, unsigned len, SQLINTEGER* ind, int* off) -{ - unsigned n2 = n; - if (off != 0 && *off >= 0) { - ctx_assert((unsigned)*off <= n2); - value += *off; - n2 -= *off; - if (len < n2 + 1) { - ctx.pushStatus(Sqlstate::_01004, Error::Gen, "more data at offset %d, current fetch %u, available %u", *off, len, n2); - n2 = len - 1; - } - } else { - if (len < n + 1) { // room for null byte - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "char value '%.*s' overflow (%u < %u)", (int)n, value, (unsigned)len, (unsigned)(len + 1)); - return false; - } - } - memcpy(ptr, value, n2); - ptr[n2] = 0; - if (off != 0 && *off >= 0) { - if (ind != 0) - *ind = n - *off; - *off += n2; - } else { - if (ind != 0) - *ind = n; - } - return true; -} - -static bool -copyout_binary_binary(Ctx& ctx, const char* value, unsigned n, char* ptr, unsigned len, SQLINTEGER* ind, int* off) -{ - unsigned n2 = n; - if (off != 0 && *off >= 0) { - ctx_assert((unsigned)*off <= n2); - value += *off; - n2 -= *off; - if (len < n2 + 1) { - ctx.pushStatus(Sqlstate::_01004, Error::Gen, "more data at offset %d, current fetch %u, available %u", *off, len, n2); - n2 = len - 1; - } - } else { - if (len < n) { // no room for null byte - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "binary value '%.*s' overflow (%u < %u)", (int)n, value, (unsigned)len, (unsigned)n); - return false; - } - } - memcpy(ptr, value, n2); - ptr[n2] = 0; - if (off != 0 && *off >= 0) { - if (ind != 0) - *ind = n - *off; - *off += n2; - } else { - if (ind != 0) - *ind = n; - } - return true; -} - -static bool -copyout_char_signed(Ctx& ctx, const char* value, unsigned n, long* ptr) -{ - while (n > 0 && value[0] == 0x20) { - value++; - n--; - } - char buf[200]; - if (n >= 200) - n = 200 - 1; - memcpy(buf, value, n); - buf[n] = 0; - errno = 0; - char* endptr = 0; - long x = strtol(buf, &endptr, 10); - if (endptr == 0 || *endptr != 0) { - errno = 0; - endptr = 0; - double y = strtod(buf, &endptr); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", buf); - return false; - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - // XXX should handle 123.000 - ctx.pushStatus(Sqlstate::_01004, Error::Gen, "value %s truncated", buf); - x = static_cast<long>(y); - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - *ptr = x; - return true; -} - -static bool -copyout_char_bigsigned(Ctx& ctx, const char* value, unsigned n, SQLBIGINT* ptr) -{ - while (n > 0 && value[0] == 0x20) { - value++; - n--; - } - char buf[200]; - if (n >= 200) - n = 200 - 1; - memcpy(buf, value, n); - buf[n] = 0; - errno = 0; - char* endptr = 0; - SQLBIGINT x = strtoll(buf, &endptr, 10); - if (endptr == 0 || *endptr != 0) { - errno = 0; - endptr = 0; - double y = strtod(buf, &endptr); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", buf); - return false; - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - // XXX should handle 123.000 - ctx.pushStatus(Sqlstate::_01004, Error::Gen, "value %s truncated", buf); - x = static_cast<long>(y); - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - *ptr = x; - return true; -} - -static bool -copyout_char_unsigned(Ctx& ctx, const char* value, unsigned n, unsigned long* ptr) -{ - while (n > 0 && value[0] == 0x20) { - value++; - n--; - } - char buf[200]; - if (n >= 200) - n = 200 - 1; - memcpy(buf, value, n); - buf[n] = 0; - errno = 0; - char* endptr = 0; - unsigned long x = strtoul(buf, &endptr, 10); - if (endptr == 0 || *endptr != 0) { - errno = 0; - endptr = 0; - double y = strtod(buf, &endptr); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", buf); - return false; - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - // XXX should handle 123.000 - ctx.pushStatus(Sqlstate::_01004, Error::Gen, "value %s truncated", buf); - x = static_cast<unsigned long>(y); - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - *ptr = x; - return true; -} - -static bool -copyout_char_bigunsigned(Ctx& ctx, const char* value, unsigned n, SQLUBIGINT* ptr) -{ - while (n > 0 && value[0] == 0x20) { - value++; - n--; - } - char buf[200]; - if (n >= 200) - n = 200 - 1; - memcpy(buf, value, n); - buf[n] = 0; - errno = 0; - char* endptr = 0; - SQLUBIGINT x = strtoull(buf, &endptr, 10); - if (endptr == 0 || *endptr != 0) { - errno = 0; - endptr = 0; - double y = strtod(buf, &endptr); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", buf); - return false; - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - // XXX should handle 123.000 - ctx.pushStatus(Sqlstate::_01004, Error::Gen, "value %s truncated", buf); - x = static_cast<unsigned long>(y); - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - *ptr = x; - return true; -} - -static bool -copyout_char_double(Ctx& ctx, const char* value, unsigned n, double* ptr) -{ - while (n > 0 && value[0] == 0x20) { - value++; - n--; - } - char buf[200]; - if (n >= 200) - n = 200 - 1; - memcpy(buf, value, n); - buf[n] = 0; - errno = 0; - char* endptr = 0; - double x = strtod(value, &endptr); - if (endptr == 0 || *endptr != 0) { - ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", value); - return false; - } else if (errno != 0) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", value); - return false; - } - *ptr = x; - return true; -} - -static bool -copyout_signed_char(Ctx& ctx, Int64 value, char* ptr, int len, SQLINTEGER* ind) -{ - char buf[100]; - sprintf(buf, FMT_I64, value); - unsigned n = strlen(buf); - if (len <= 0) { - ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", len); - return false; - } - if ((unsigned)len < n + 1) { // room for null byte - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - strcpy(ptr, buf); - if (ind != 0) - *ind = n; - return true; -} - -static bool -copyout_unsigned_char(Ctx& ctx, Uint64 uvalue, char* ptr, int len, SQLINTEGER* ind) -{ - char buf[100]; - sprintf(buf, FMT_U64, uvalue); - unsigned n = strlen(buf); - if (len <= 0) { - ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", len); - return false; - } - if ((unsigned)len < n + 1) { // room for null byte - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - strcpy(ptr, buf); - if (ind != 0) - *ind = n; - return true; -} - -static bool -copyout_double_char(Ctx& ctx, double value, unsigned prec, char* ptr, int len, SQLINTEGER* ind) -{ - char buf[100]; - sprintf(buf, "%.*f", (int)prec, value); - char* p = buf + strlen(buf); - while (p > buf + prec) - *--p = 0; - while (p > buf && *(p - 1) == '0') - *--p = 0; - if (p > buf && *(p - 1) == '.') { - *p++ = '0'; - *p = 0; - } - unsigned n = strlen(buf); - if (len <= 0) { - ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", len); - return false; - } - if ((unsigned)len < n + 1) { // room for null byte - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf); - return false; - } - strcpy(ptr, buf); - if (ind != 0) - *ind = n; - return true; -} - -void -SqlField::copyout(Ctx& ctx, ExtField& extField) const -{ - if (extField.extSpec().extType().type() == ExtType::Unbound) { - return; // output buffer may be unbound - } - if (sqlSpec().store() == SqlSpec::Reference) { - ctx_assert(u_data.m_sqlField != 0); - u_data.m_sqlField->copyout(ctx, extField); - return; - } - SQLINTEGER* indPtr = extField.m_indPtr; - if (u_null.m_nullFlag) { - if (extField.m_pos > 0) { // second time from SQLGetData - ctx.setCode(SQL_NO_DATA); - return; - } - if (indPtr == 0) { - ctx.pushStatus(Sqlstate::_22002, Error::Gen, "indicator variable required"); - return; - } - *indPtr = SQL_NULL_DATA; - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - const SqlType& sqlType = sqlSpec().sqlType(); - const ExtType& extType = extField.extSpec().extType(); - if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) { - unsigned n = 0; - const char* value = 0; - if (sqlType.type() == SqlType::Char) { - n = sqlType.length(); - value = reinterpret_cast<const char*>(sqlChar()); - } else { - value = reinterpret_cast<const char*>(sqlVarchar(&n)); - } - if (extType.type() == ExtType::Char) { - char* dataPtr = static_cast<char*>(extField.m_dataPtr); - if (extField.m_dataLen <= 0) { - ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", (int)extField.m_dataLen); - return; - } - int* off = 0; - if (extField.m_pos >= 0) { - off = &extField.m_pos; - if ((unsigned)*off >= n) { - ctx.setCode(SQL_NO_DATA); - return; - } - } - if (! copyout_char_char(ctx, value, n, dataPtr, extField.m_dataLen, indPtr, off)) - return; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - long x; - if (! copyout_char_signed(ctx, value, n, &x)) - return; - if (x < SHRT_MIN || x > SHRT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", value); - return; - } - *dataPtr = static_cast<short>(x); - if (indPtr != 0) - *indPtr = sizeof(short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - unsigned long x; - if (! copyout_char_unsigned(ctx, value, n, &x)) - return; - if (x > USHRT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", value); - return; - } - *dataPtr = static_cast<unsigned short>(x); - if (indPtr != 0) - *indPtr = sizeof(unsigned short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - if (! copyout_char_signed(ctx, value, n, dataPtr)) - return; - if (indPtr != 0) - *indPtr = sizeof(long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - if (! copyout_char_unsigned(ctx, value, n, dataPtr)) - return; - if (indPtr != 0) - *indPtr = sizeof(unsigned long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - if (! copyout_char_bigsigned(ctx, value, n, dataPtr)) - return; - if (indPtr != 0) - *indPtr = sizeof(SQLBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - if (! copyout_char_bigunsigned(ctx, value, n, dataPtr)) - return; - if (indPtr != 0) - *indPtr = sizeof(SQLUBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - double x; - if (! copyout_char_double(ctx, value, n, &x)) - return; - if (fabs(x) < FLT_MIN || fabs(x) > FLT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", value); - return; - } - *dataPtr = static_cast<float>(x); - if (indPtr != 0) - *indPtr = sizeof(float); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - double x; - if (! copyout_char_double(ctx, value, n, &x)) - return; - *dataPtr = static_cast<double>(x); - if (indPtr != 0) - *indPtr = sizeof(double); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) { - unsigned n = 0; - const char* value = 0; - if (sqlType.type() == SqlType::Binary) { - n = sqlType.length(); - value = reinterpret_cast<const char*>(sqlBinary()); - } else { - value = reinterpret_cast<const char*>(sqlVarbinary(&n)); - } - if (extType.type() == ExtType::Binary) { - char* dataPtr = static_cast<char*>(extField.m_dataPtr); - if (extField.m_dataLen <= 0) { - ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", (int)extField.m_dataLen); - return; - } - int* off = 0; - if (extField.m_pos >= 0) { - off = &extField.m_pos; - if ((unsigned)*off >= n) { - ctx.setCode(SQL_NO_DATA); - return; - } - } - if (! copyout_binary_binary(ctx, value, n, dataPtr, extField.m_dataLen, indPtr, off)) - return; - return; - } - } - if (sqlType.type() == SqlType::Smallint) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - const SqlSmallint value = sqlSmallint(); - const SqlUsmallint uvalue = value; - if (extType.type() == ExtType::Char) { - char* dataPtr = static_cast<char*>(extField.m_dataPtr); - if (! sqlType.unSigned()) { - if (! copyout_signed_char(ctx, value, dataPtr, extField.m_dataLen, indPtr)) - return; - } else { - if (! copyout_unsigned_char(ctx, uvalue, dataPtr, extField.m_dataLen, indPtr)) - return; - } - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - *dataPtr = static_cast<short>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - *dataPtr = static_cast<unsigned short>(uvalue); - if (indPtr != 0) - *indPtr = sizeof(unsigned short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - *dataPtr = static_cast<long>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - *dataPtr = static_cast<unsigned long>(uvalue); - if (indPtr != 0) - *indPtr = sizeof(unsigned long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLBIGINT>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(SQLBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLUBIGINT>(uvalue); - if (indPtr != 0) - *indPtr = sizeof(SQLUBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - *dataPtr = static_cast<float>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(float); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - *dataPtr = static_cast<double>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(double); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Integer) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - const SqlInteger value = sqlInteger(); - const SqlUinteger uvalue = value; - if (extType.type() == ExtType::Char) { - char* dataPtr = static_cast<char*>(extField.m_dataPtr); - if (! sqlType.unSigned()) { - if (! copyout_signed_char(ctx, value, dataPtr, extField.m_dataLen, indPtr)) - return; - } else { - if (! copyout_unsigned_char(ctx, uvalue, dataPtr, extField.m_dataLen, indPtr)) - return; - } - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - if (value < SHRT_MIN || value > SHRT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %d overflow", (int)value); - return; - } - *dataPtr = static_cast<short>(value); - if (indPtr != 0) - *indPtr = sizeof(short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - if (uvalue > USHRT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %u overflow", uvalue); - return; - } - *dataPtr = static_cast<unsigned short>(value); - if (indPtr != 0) - *indPtr = sizeof(unsigned short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - *dataPtr = static_cast<long>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - *dataPtr = static_cast<unsigned long>(uvalue); - if (indPtr != 0) - *indPtr = sizeof(unsigned long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLBIGINT>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(SQLBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLUBIGINT>(uvalue); - if (indPtr != 0) - *indPtr = sizeof(SQLUBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - *dataPtr = static_cast<float>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(float); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - *dataPtr = static_cast<double>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(double); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Bigint) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - const SqlBigint value = sqlBigint(); - const SqlUbigint uvalue = value; - if (extType.type() == ExtType::Char) { - char* dataPtr = static_cast<char*>(extField.m_dataPtr); - if (! sqlType.unSigned()) { - if (! copyout_signed_char(ctx, value, dataPtr, extField.m_dataLen, indPtr)) - return; - } else { - if (! copyout_unsigned_char(ctx, uvalue, dataPtr, extField.m_dataLen, indPtr)) - return; - } - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - if (value < SHRT_MIN || value > SHRT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value " FMT_I64 " overflow", (Int64)value); - return; - } - *dataPtr = static_cast<short>(value); - if (indPtr != 0) - *indPtr = sizeof(short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - if (uvalue > USHRT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value " FMT_U64 " overflow", (Uint64)uvalue); - return; - } - *dataPtr = static_cast<short>(value); - if (indPtr != 0) - *indPtr = sizeof(unsigned short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - if (value < INT_MIN || value > INT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value " FMT_I64 " overflow", (Int64)value); - return; - } - *dataPtr = static_cast<long>(value); - if (indPtr != 0) - *indPtr = sizeof(long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - if (uvalue > UINT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value " FMT_U64 " overflow", (Uint64)uvalue); - return; - } - *dataPtr = static_cast<unsigned long>(uvalue); - if (indPtr != 0) - *indPtr = sizeof(unsigned long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLBIGINT>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(SQLBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLUBIGINT>(uvalue); - if (indPtr != 0) - *indPtr = sizeof(SQLUBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - *dataPtr = static_cast<float>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(float); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - *dataPtr = static_cast<double>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(double); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Real) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - const SqlReal value = sqlReal(); - if (extType.type() == ExtType::Char) { - char* dataPtr = static_cast<char*>(extField.m_dataPtr); - if (! copyout_double_char(ctx, value, 7, dataPtr, extField.m_dataLen, indPtr)) - return; - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - *dataPtr = static_cast<short>(value); // XXX todo - if (indPtr != 0) - *indPtr = sizeof(short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - if (value < 0 || value > USHRT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %g overflow", (double)value); - return; - } - *dataPtr = static_cast<short>(value); - if (indPtr != 0) - *indPtr = sizeof(unsigned short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - *dataPtr = static_cast<long>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - *dataPtr = static_cast<unsigned long>(value); // XXX todo - if (indPtr != 0) - *indPtr = sizeof(unsigned long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLBIGINT>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(SQLBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLUBIGINT>(value); - if (indPtr != 0) - *indPtr = sizeof(SQLUBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - *dataPtr = static_cast<float>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(float); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - *dataPtr = static_cast<double>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(double); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Double) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - SqlDouble value = sqlDouble(); - if (extType.type() == ExtType::Char) { - char* dataPtr = static_cast<char*>(extField.m_dataPtr); - if (! copyout_double_char(ctx, value, 14, dataPtr, extField.m_dataLen, indPtr)) - return; - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) { - short* dataPtr = static_cast<short*>(extField.m_dataPtr); - *dataPtr = static_cast<short>(value); // XXX todo - if (indPtr != 0) - *indPtr = sizeof(short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ushort) { - unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr); - if (value < 0 || value > USHRT_MAX) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %g overflow", (double)value); - return; - } - *dataPtr = static_cast<short>(value); - if (indPtr != 0) - *indPtr = sizeof(unsigned short); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) { - long* dataPtr = static_cast<long*>(extField.m_dataPtr); - *dataPtr = static_cast<long>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ulong) { - unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr); - *dataPtr = static_cast<unsigned long>(value); // XXX todo - if (indPtr != 0) - *indPtr = sizeof(unsigned long); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Sbigint) { - SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLBIGINT>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(SQLBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Ubigint) { - SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr); - *dataPtr = static_cast<SQLUBIGINT>(value); - if (indPtr != 0) - *indPtr = sizeof(SQLUBIGINT); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Float) { - float* dataPtr = static_cast<float*>(extField.m_dataPtr); - *dataPtr = static_cast<float>(value); // big enough - if (indPtr != 0) - *indPtr = sizeof(float); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Double) { - double* dataPtr = static_cast<double*>(extField.m_dataPtr); - *dataPtr = static_cast<double>(value); - if (indPtr != 0) - *indPtr = sizeof(double); - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - } - if (sqlType.type() == SqlType::Datetime) { - if (extField.m_pos > 0) { - ctx.setCode(SQL_NO_DATA); - return; - } - SqlDatetime value = sqlDatetime(); - if (extType.type() == ExtType::Char) { - char* dataPtr = static_cast<char*>(extField.m_dataPtr); - char buf[100]; - sprintf(buf, "%02d%02u-%02u-%02u\040%02u:%02u:%02u.%09u", value.cc(), value.yy(), value.mm(), value.dd(), value.HH(), value.MM(), value.SS(), value.ff()); - int n = strlen(buf); - if (extField.m_dataLen < 20) { - ctx.pushStatus(Sqlstate::_22003, Error::Gen, "buffer too small for timestamp %s", buf); - return; - } - if (extField.m_dataLen < n) { - ctx.pushStatus(Sqlstate::_01004, Error::Gen, "truncating fractional part of timestamp %s", buf); - n = extField.m_dataLen; - } - if (! copyout_char_char(ctx, buf, n, dataPtr, extField.m_dataLen, indPtr, 0)) - return; - if (extField.m_pos >= 0) - extField.m_pos = 1; - return; - } - if (extType.type() == ExtType::Timestamp) { - SQL_TIMESTAMP_STRUCT* dataPtr = static_cast<SQL_TIMESTAMP_STRUCT*>(extField.m_dataPtr); - // XXX assume same datatype - dataPtr->year = value.cc() * 100 + value.yy(); - dataPtr->month = value.mm(); - dataPtr->day = value.dd(); - dataPtr->hour = value.HH(); - dataPtr->minute = value.MM(); - dataPtr->second = value.SS(); - dataPtr->fraction = value.ff(); - return; - } - } - ctx_assert(false); // SqlType::Null not applicable -} - -void -SqlField::print(char* buf, unsigned size) const -{ - Ctx ctx; - unsigned n = sqlSpec().sqlType().displaySize(); - SQLINTEGER ind = 0; - ExtType extType(ExtType::Char); - ExtSpec extSpec(extType); - ExtField extField(extSpec, (SQLPOINTER)buf, size, &ind); - buf[0] = 0; - copyout(ctx, extField); - if (ind == SQL_NULL_DATA) - snprintf(buf, size, "NULL"); -} |