DataField.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:84k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include "DataField.hpp"
  14. #ifndef INT_MAX
  15. #define INT_MAX (2147483647)
  16. #endif
  17. #ifndef INT_MIN
  18. #define INT_MIN (-INT_MAX - 1)
  19. #endif
  20. #ifndef UINT_MAX
  21. #define UINT_MAX 4294967295U
  22. #endif
  23. #ifndef FLT_MAX
  24. #define FLT_MAX (3.402823466E+38F)
  25. #endif
  26. #ifndef FLT_MIN
  27. #define FLT_MIN (1.175494351E-38F)
  28. #endif
  29. #ifdef NDB_WIN32
  30. #define FMT_I64 "%I64d"
  31. #define FMT_U64 "%I64u"
  32. #else
  33. #define FMT_I64 "%lld"
  34. #define FMT_U64 "%llu"
  35. #endif
  36. #ifdef NDB_WIN32
  37. #define strtoll(str, endptr, base) strtoint64(str, endptr, base)
  38. #define strtoull(str, endptr, base) strtouint64(str, endptr, base)
  39. static Int64
  40. strtoint64(const char *str, char **endptr, int base)
  41. {
  42.     Int64 x = 0;
  43.     while (*str == ' ')
  44. str++;
  45.     const char* p = str;
  46.     while ('0' <= *p && *p <= '9')
  47. x = 10 * x + *p++ - '0';
  48.     if (p == str) {
  49. *endptr = 0;
  50. return 0;
  51.     }
  52.     *endptr = (char*)p;
  53.     return x;
  54. }
  55. static Uint64
  56. strtouint64(const char *str, char **endptr, int base)
  57. {
  58.     Uint64 x = 0;
  59.     while (*str == ' ')
  60. str++;
  61.     const char* p = str;
  62.     while ('0' <= *p && *p <= '9')
  63. x = 10 * x + *p++ - '0';
  64.     if (p == str) {
  65. *endptr = 0;
  66. return 0;
  67.     }
  68.     *endptr = (char*)p;
  69.     return x;
  70. }
  71. #endif
  72. // LexSpec
  73. void
  74. LexSpec::convert(Ctx& ctx, const BaseString& value, SqlField& out)
  75. {
  76.     const SqlSpec& sqlSpec = out.sqlSpec();
  77.     const SqlType& sqlType = sqlSpec.sqlType();
  78.     out.alloc();
  79.     if (sqlType.type() == SqlType::Char) {
  80. const SqlChar* s = (const SqlChar*)value.c_str();
  81. out.sqlChar(s, SQL_NTS);
  82. return;
  83.     }
  84.     if (sqlType.type() == SqlType::Bigint) {
  85. char* endptr = 0;
  86. SqlBigint n = static_cast<SqlBigint>(strtoll(value.c_str(), &endptr, 10));
  87. if (endptr == 0 || *endptr != 0) {
  88.     ctx.pushStatus(Error::Gen, "cannot convert '%s' to integer", value.c_str());
  89.     return;
  90. }
  91. out.sqlBigint(n);
  92. return;
  93.     }
  94.     if (sqlType.type() == SqlType::Double) {
  95. char* endptr = 0;
  96. SqlDouble x = static_cast<SqlDouble>(strtod(value.c_str(), &endptr));
  97. if (endptr == 0 || *endptr != 0) {
  98.     ctx.pushStatus(Error::Gen, "cannot convert '%s' to number", value.c_str());
  99.     return;
  100. }
  101. out.sqlDouble(x);
  102. return;
  103.     }
  104.     if (sqlType.type() == SqlType::Null) {
  105. out.u_null.m_nullFlag = true;
  106. return;
  107.     }
  108.     ctx_assert(false);
  109. }
  110. // SqlField
  111. void
  112. SqlField::alloc()
  113. {
  114.     ctx_assert(sqlSpec().store() == SqlSpec::Physical);
  115.     const SqlType& sqlType = sqlSpec().sqlType();
  116.     if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) {
  117. unsigned n = sqlType.length();
  118. if (sqlType.type() == SqlType::Varchar)
  119.     n += 2;
  120. if (n > SqlField_CharSmall) {
  121.     u_data.m_sqlChar = new SqlChar[n];
  122. }
  123.     }
  124.     if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) {
  125. unsigned n = sqlType.length();
  126. if (sqlType.type() == SqlType::Varbinary)
  127.     n += 2;
  128. if (n > SqlField_CharSmall) {
  129.     u_data.m_sqlChar = new SqlChar[n];
  130. }
  131.     }
  132. }
  133. void
  134. SqlField::alloc(const SqlField& sqlField)
  135. {
  136.     alloc();
  137.     const SqlType& sqlType = sqlSpec().sqlType();
  138.     if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) {
  139. unsigned n = sqlType.length();
  140. if (sqlType.type() == SqlType::Varchar)
  141.     n += 2;
  142. if (n > SqlField_CharSmall) {
  143.     memcpy(u_data.m_sqlChar, sqlField.u_data.m_sqlChar, n);
  144. }
  145.     }
  146.     if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) {
  147. unsigned n = sqlType.length();
  148. if (sqlType.type() == SqlType::Varbinary)
  149.     n += 2;
  150. if (n > SqlField_CharSmall) {
  151.     memcpy(u_data.m_sqlChar, sqlField.u_data.m_sqlChar, n);
  152. }
  153.     }
  154. }
  155. const void*
  156. SqlField::addr() const
  157. {
  158.     if (sqlSpec().store() == SqlSpec::Reference) {
  159. ctx_assert(u_data.m_sqlField != 0);
  160. return u_data.m_sqlField->addr();
  161.     }
  162.     const SqlType& sqlType = sqlSpec().sqlType();
  163.     if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) {
  164. unsigned n = sqlType.length();
  165. if (sqlType.type() == SqlType::Varchar)
  166.     n += 2;
  167. if (n > SqlField_CharSmall) {
  168.     return static_cast<const void*>(u_data.m_sqlChar);
  169. }
  170. return static_cast<const void*>(u_data.m_sqlCharSmall);
  171.     }
  172.     if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) {
  173. unsigned n = sqlType.length();
  174. if (sqlType.type() == SqlType::Varbinary)
  175.     n += 2;
  176. if (n > SqlField_CharSmall) {
  177.     return static_cast<const void*>(u_data.m_sqlChar);
  178. }
  179. return static_cast<const void*>(u_data.m_sqlCharSmall);
  180.     }
  181.     if (sqlType.type() == SqlType::Smallint) {
  182. return static_cast<const void*>(&u_data.m_sqlSmallint);
  183.     }
  184.     if (sqlType.type() == SqlType::Integer) {
  185. return static_cast<const void*>(&u_data.m_sqlInteger);
  186.     }
  187.     if (sqlType.type() == SqlType::Bigint) {
  188. return static_cast<const void*>(&u_data.m_sqlBigint);
  189.     }
  190.     if (sqlType.type() == SqlType::Real) {
  191. return static_cast<const void*>(&u_data.m_sqlReal);
  192.     }
  193.     if (sqlType.type() == SqlType::Double) {
  194. return static_cast<const void*>(&u_data.m_sqlDouble);
  195.     }
  196.     if (sqlType.type() == SqlType::Datetime) {
  197. return static_cast<const void*>(&u_data.m_sqlDatetime);
  198.     }
  199.     ctx_assert(false); // SqlType::Null has no address
  200.     return 0;
  201. }
  202. void*
  203. SqlField::addr()
  204. {
  205.     const SqlType& sqlType = sqlSpec().sqlType();
  206.     if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) {
  207. unsigned n = sqlType.length();
  208. if (sqlType.type() == SqlType::Varchar)
  209.     n += 2;
  210. if (n > SqlField_CharSmall) {
  211.     return static_cast<void*>(u_data.m_sqlChar);
  212. }
  213. return static_cast<void*>(u_data.m_sqlCharSmall);
  214.     }
  215.     if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) {
  216. unsigned n = sqlType.length();
  217. if (sqlType.type() == SqlType::Varbinary)
  218.     n += 2;
  219. if (n > SqlField_CharSmall) {
  220.     return static_cast<void*>(u_data.m_sqlChar);
  221. }
  222. return static_cast<void*>(u_data.m_sqlCharSmall);
  223.     }
  224.     if (sqlType.type() == SqlType::Smallint) {
  225. return static_cast<void*>(&u_data.m_sqlSmallint);
  226.     }
  227.     if (sqlType.type() == SqlType::Integer) {
  228. return static_cast<void*>(&u_data.m_sqlInteger);
  229.     }
  230.     if (sqlType.type() == SqlType::Bigint) {
  231. return static_cast<void*>(&u_data.m_sqlBigint);
  232.     }
  233.     if (sqlType.type() == SqlType::Real) {
  234. return static_cast<void*>(&u_data.m_sqlReal);
  235.     }
  236.     if (sqlType.type() == SqlType::Double) {
  237. return static_cast<void*>(&u_data.m_sqlDouble);
  238.     }
  239.     if (sqlType.type() == SqlType::Datetime) {
  240. return static_cast<void*>(&u_data.m_sqlDatetime);
  241.     }
  242.     ctx_assert(false); // SqlType::Null has no address
  243.     return 0;
  244. }
  245. unsigned
  246. SqlField::allocSize() const
  247. {
  248.     const SqlType& sqlType = sqlSpec().sqlType();
  249.     unsigned n = sqlType.size();
  250.     if (sqlType.type() == SqlType::Varchar || sqlType.type() == SqlType::Varbinary) {
  251. n += 2;
  252.     }
  253.     return n;
  254. }
  255. void
  256. SqlField::free()
  257. {
  258.     ctx_assert(sqlSpec().store() == SqlSpec::Physical);
  259.     const SqlType& sqlType = sqlSpec().sqlType();
  260.     if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) {
  261. unsigned n = sqlType.length();
  262. if (sqlType.type() == SqlType::Varchar)
  263.     n += 2;
  264. if (n > SqlField_CharSmall) {
  265.     delete[] u_data.m_sqlChar;
  266.     u_data.m_sqlChar = 0; // safety since dtor used explicitly
  267. }
  268.     }
  269.     if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) {
  270. unsigned n = sqlType.length();
  271. if (sqlType.type() == SqlType::Varbinary)
  272.     n += 2;
  273. if (n > SqlField_CharSmall) {
  274.     delete[] u_data.m_sqlChar;
  275.     u_data.m_sqlChar = 0; // safety since dtor used explicitly
  276. }
  277.     }
  278. }
  279. // get
  280. const SqlChar*
  281. SqlField::sqlChar() const
  282. {
  283.     if (sqlSpec().store() == SqlSpec::Reference) {
  284. ctx_assert(u_data.m_sqlField != 0);
  285. return u_data.m_sqlField->sqlChar();
  286.     }
  287.     const SqlType& sqlType = sqlSpec().sqlType();
  288.     ctx_assert(sqlType.type() == SqlType::Char);
  289.     if (sqlType.length() > SqlField_CharSmall)
  290. return u_data.m_sqlChar;
  291.     return u_data.m_sqlCharSmall;
  292. }
  293. const SqlChar*
  294. SqlField::sqlVarchar(unsigned* length) const
  295. {
  296. #if NDB_VERSION_MAJOR >= 3
  297.     if (sqlSpec().store() == SqlSpec::Reference) {
  298. ctx_assert(u_data.m_sqlField != 0);
  299. return u_data.m_sqlField->sqlVarchar(length);
  300.     }
  301.     const SqlType& sqlType = sqlSpec().sqlType();
  302.     ctx_assert(sqlType.type() == SqlType::Varchar);
  303.     const SqlChar* sqlChar;
  304.     unsigned n = sqlType.length();
  305.     if (2 + n > SqlField_CharSmall)
  306. sqlChar = u_data.m_sqlChar;
  307.     else
  308. sqlChar = u_data.m_sqlCharSmall;
  309.     if (length != 0)
  310. *length = (sqlChar[0] << 8) | sqlChar[1]; // big-endian
  311.     return sqlChar + 2;
  312. #else
  313.     if (sqlSpec().store() == SqlSpec::Reference) {
  314. ctx_assert(u_data.m_sqlField != 0);
  315. return u_data.m_sqlField->sqlVarchar(length);
  316.     }
  317.     const SqlType& sqlType = sqlSpec().sqlType();
  318.     ctx_assert(sqlType.type() == SqlType::Varchar);
  319.     const SqlChar* sqlChar;
  320.     unsigned n = sqlType.length();
  321.     if (n + 2 > SqlField_CharSmall)
  322. sqlChar = u_data.m_sqlChar;
  323.     else
  324. sqlChar = u_data.m_sqlCharSmall;
  325.     if (length != 0)
  326. *length = (sqlChar[n + 0] << 8) | sqlChar[n + 1]; // big-endian
  327.     return sqlChar;
  328. #endif
  329. }
  330. const SqlChar*
  331. SqlField::sqlBinary() const
  332. {
  333.     if (sqlSpec().store() == SqlSpec::Reference) {
  334. ctx_assert(u_data.m_sqlField != 0);
  335. return u_data.m_sqlField->sqlChar();
  336.     }
  337.     const SqlType& sqlType = sqlSpec().sqlType();
  338.     ctx_assert(sqlType.type() == SqlType::Binary);
  339.     if (sqlType.length() > SqlField_CharSmall)
  340. return u_data.m_sqlChar;
  341.     return u_data.m_sqlCharSmall;
  342. }
  343. const SqlChar*
  344. SqlField::sqlVarbinary(unsigned* length) const
  345. {
  346. #if NDB_VERSION_MAJOR >= 3
  347.     if (sqlSpec().store() == SqlSpec::Reference) {
  348. ctx_assert(u_data.m_sqlField != 0);
  349. return u_data.m_sqlField->sqlVarchar(length);
  350.     }
  351.     const SqlType& sqlType = sqlSpec().sqlType();
  352.     ctx_assert(sqlType.type() == SqlType::Varbinary);
  353.     const SqlChar* sqlChar;
  354.     unsigned n = sqlType.length();
  355.     if (2 + n > SqlField_CharSmall)
  356. sqlChar = u_data.m_sqlChar;
  357.     else
  358. sqlChar = u_data.m_sqlCharSmall;
  359.     if (length != 0)
  360. *length = (sqlChar[0] << 8) | sqlChar[1]; // big-endian
  361.     return sqlChar + 2;
  362. #else
  363.     if (sqlSpec().store() == SqlSpec::Reference) {
  364. ctx_assert(u_data.m_sqlField != 0);
  365. return u_data.m_sqlField->sqlVarchar(length);
  366.     }
  367.     const SqlType& sqlType = sqlSpec().sqlType();
  368.     ctx_assert(sqlType.type() == SqlType::Varbinary);
  369.     const SqlChar* sqlChar;
  370.     unsigned n = sqlType.length();
  371.     if (n + 2 > SqlField_CharSmall)
  372. sqlChar = u_data.m_sqlChar;
  373.     else
  374. sqlChar = u_data.m_sqlCharSmall;
  375.     if (length != 0)
  376. *length = (sqlChar[n + 0] << 8) | sqlChar[n + 1]; // big-endian
  377.     return sqlChar;
  378. #endif
  379. }
  380. SqlSmallint
  381. SqlField::sqlSmallint() const
  382. {
  383.     if (sqlSpec().store() == SqlSpec::Reference) {
  384. ctx_assert(u_data.m_sqlField != 0);
  385. return u_data.m_sqlField->sqlSmallint();
  386.     }
  387.     const SqlType& sqlType = sqlSpec().sqlType();
  388.     ctx_assert(sqlType.type() == SqlType::Smallint);
  389.     return u_data.m_sqlSmallint;
  390. }
  391. SqlInteger
  392. SqlField::sqlInteger() const
  393. {
  394.     if (sqlSpec().store() == SqlSpec::Reference) {
  395. ctx_assert(u_data.m_sqlField != 0);
  396. return u_data.m_sqlField->sqlInteger();
  397.     }
  398.     const SqlType& sqlType = sqlSpec().sqlType();
  399.     ctx_assert(sqlType.type() == SqlType::Integer);
  400.     return u_data.m_sqlInteger;
  401. }
  402. SqlBigint
  403. SqlField::sqlBigint() const
  404. {
  405.     if (sqlSpec().store() == SqlSpec::Reference) {
  406. ctx_assert(u_data.m_sqlField != 0);
  407. return u_data.m_sqlField->sqlBigint();
  408.     }
  409.     const SqlType& sqlType = sqlSpec().sqlType();
  410.     ctx_assert(sqlType.type() == SqlType::Bigint);
  411.     return u_data.m_sqlBigint;
  412. }
  413. SqlReal
  414. SqlField::sqlReal() const
  415. {
  416.     if (sqlSpec().store() == SqlSpec::Reference) {
  417. ctx_assert(u_data.m_sqlField != 0);
  418. return u_data.m_sqlField->sqlReal();
  419.     }
  420.     const SqlType& sqlType = sqlSpec().sqlType();
  421.     ctx_assert(sqlType.type() == SqlType::Real);
  422.     return u_data.m_sqlReal;
  423. }
  424. SqlDouble
  425. SqlField::sqlDouble() const
  426. {
  427.     if (sqlSpec().store() == SqlSpec::Reference) {
  428. ctx_assert(u_data.m_sqlField != 0);
  429. return u_data.m_sqlField->sqlDouble();
  430.     }
  431.     const SqlType& sqlType = sqlSpec().sqlType();
  432.     ctx_assert(sqlType.type() == SqlType::Double);
  433.     return u_data.m_sqlDouble;
  434. }
  435. SqlDatetime
  436. SqlField::sqlDatetime() const
  437. {
  438.     if (sqlSpec().store() == SqlSpec::Reference) {
  439. ctx_assert(u_data.m_sqlField != 0);
  440. return u_data.m_sqlField->sqlDatetime();
  441.     }
  442.     const SqlType& sqlType = sqlSpec().sqlType();
  443.     ctx_assert(sqlType.type() == SqlType::Datetime);
  444.     return u_data.m_sqlDatetime;
  445. }
  446. // set
  447. void
  448. SqlField::sqlChar(const SqlChar* value, int length)
  449. {
  450.     const SqlType& sqlType = sqlSpec().sqlType();
  451.     ctx_assert(sqlType.type() == SqlType::Char);
  452.     unsigned n = sqlType.length();
  453.     SqlChar* p = n > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall;
  454.     const SqlChar* q = value;
  455.     unsigned m = length == SQL_NTS ? strlen((const char*)q) : length;
  456.     ctx_assert(m <= n);
  457.     for (unsigned i = 0; i < m; i++)
  458. *p++ = *q++;
  459.     for (unsigned i = m; i < n; i++)
  460. *p++ = 0x20; // space
  461.     u_null.m_nullFlag = false;
  462. }
  463. void
  464. SqlField::sqlVarchar(const SqlChar* value, int length)
  465. {
  466. #if NDB_VERSION_MAJOR >= 3
  467.     const SqlType& sqlType = sqlSpec().sqlType();
  468.     ctx_assert(sqlType.type() == SqlType::Varchar);
  469.     unsigned n = sqlType.length();
  470.     SqlChar* p = 2 + n > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall;
  471.     const SqlChar* q = value;
  472.     unsigned m = length == SQL_NTS ? strlen((const char*)q) : length;
  473.     ctx_assert(m <= n);
  474.     *p++ = (m >> 8) & 0xff; // big-endian
  475.     *p++ = (m & 0xff);
  476.     for (unsigned i = 0; i < m; i++)
  477. *p++ = *q++;
  478.     for (unsigned i = m; i < n; i++)
  479. *p++ = 0x0; // null
  480.     u_null.m_nullFlag = false;
  481. #else
  482.     const SqlType& sqlType = sqlSpec().sqlType();
  483.     ctx_assert(sqlType.type() == SqlType::Varchar);
  484.     unsigned n = sqlType.length();
  485.     SqlChar* p = n + 2 > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall;
  486.     const SqlChar* q = value;
  487.     unsigned m = length == SQL_NTS ? strlen((const char*)q) : length;
  488.     ctx_assert(m <= n);
  489.     for (unsigned i = 0; i < m; i++)
  490. *p++ = *q++;
  491.     for (unsigned i = m; i < n; i++)
  492. *p++ = 0x0; // null
  493.     *p++ = (m >> 8) & 0xff; // big-endian
  494.     *p++ = (m & 0xff);
  495.     u_null.m_nullFlag = false;
  496. #endif
  497. }
  498. void
  499. SqlField::sqlBinary(const SqlChar* value, int length)
  500. {
  501.     const SqlType& sqlType = sqlSpec().sqlType();
  502.     ctx_assert(sqlType.type() == SqlType::Binary);
  503.     unsigned n = sqlType.length();
  504.     SqlChar* p = n > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall;
  505.     const SqlChar* q = value;
  506.     unsigned m = length;
  507.     ctx_assert(m <= n);
  508.     for (unsigned i = 0; i < m; i++)
  509. *p++ = *q++;
  510.     for (unsigned i = m; i < n; i++)
  511. *p++ = 0x0; // null
  512.     u_null.m_nullFlag = false;
  513. }
  514. void
  515. SqlField::sqlVarbinary(const SqlChar* value, int length)
  516. {
  517. #if NDB_VERSION_MAJOR >= 3
  518.     const SqlType& sqlType = sqlSpec().sqlType();
  519.     ctx_assert(sqlType.type() == SqlType::Varbinary);
  520.     unsigned n = sqlType.length();
  521.     SqlChar* p = 2 + n > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall;
  522.     const SqlChar* q = value;
  523.     unsigned m = length;
  524.     ctx_assert(m <= n);
  525.     *p++ = (m >> 8) & 0xff; // big-endian
  526.     *p++ = (m & 0xff);
  527.     for (unsigned i = 0; i < m; i++)
  528. *p++ = *q++;
  529.     for (unsigned i = m; i < n; i++)
  530. *p++ = 0x0; // null
  531.     u_null.m_nullFlag = false;
  532. #else
  533.     const SqlType& sqlType = sqlSpec().sqlType();
  534.     ctx_assert(sqlType.type() == SqlType::Varbinary);
  535.     unsigned n = sqlType.length();
  536.     SqlChar* p = n + 2 > SqlField_CharSmall ? u_data.m_sqlChar : u_data.m_sqlCharSmall;
  537.     const SqlChar* q = value;
  538.     unsigned m = length;
  539.     ctx_assert(m <= n);
  540.     for (unsigned i = 0; i < m; i++)
  541. *p++ = *q++;
  542.     for (unsigned i = m; i < n; i++)
  543. *p++ = 0x0; // null
  544.     *p++ = (m >> 8) & 0xff; // big-endian
  545.     *p++ = (m & 0xff);
  546.     u_null.m_nullFlag = false;
  547. #endif
  548. }
  549. void
  550. SqlField::sqlSmallint(SqlSmallint value)
  551. {
  552.     const SqlType& sqlType = sqlSpec().sqlType();
  553.     ctx_assert(sqlType.type() == SqlType::Smallint);
  554.     u_data.m_sqlSmallint = value;
  555.     u_null.m_nullFlag = false;
  556. }
  557. void
  558. SqlField::sqlInteger(SqlInteger value)
  559. {
  560.     const SqlType& sqlType = sqlSpec().sqlType();
  561.     ctx_assert(sqlType.type() == SqlType::Integer);
  562.     u_data.m_sqlInteger = value;
  563.     u_null.m_nullFlag = false;
  564. }
  565. void
  566. SqlField::sqlBigint(SqlBigint value)
  567. {
  568.     const SqlType& sqlType = sqlSpec().sqlType();
  569.     ctx_assert(sqlType.type() == SqlType::Bigint);
  570.     u_data.m_sqlBigint = value;
  571.     u_null.m_nullFlag = false;
  572. }
  573. void
  574. SqlField::sqlReal(SqlReal value)
  575. {
  576.     const SqlType& sqlType = sqlSpec().sqlType();
  577.     ctx_assert(sqlType.type() == SqlType::Real);
  578.     u_data.m_sqlReal = value;
  579.     u_null.m_nullFlag = false;
  580. }
  581. void
  582. SqlField::sqlDouble(SqlDouble value)
  583. {
  584.     const SqlType& sqlType = sqlSpec().sqlType();
  585.     ctx_assert(sqlType.type() == SqlType::Double);
  586.     u_data.m_sqlDouble = value;
  587.     u_null.m_nullFlag = false;
  588. }
  589. void
  590. SqlField::sqlDatetime(SqlDatetime value)
  591. {
  592.     const SqlType& sqlType = sqlSpec().sqlType();
  593.     ctx_assert(sqlType.type() == SqlType::Datetime);
  594.     u_data.m_sqlDatetime = value;
  595.     u_null.m_nullFlag = false;
  596. }
  597. // get and and set null
  598. bool
  599. SqlField::sqlNull() const
  600. {
  601.     if (sqlSpec().store() == SqlSpec::Reference) {
  602. ctx_assert(u_data.m_sqlField != 0);
  603. return u_data.m_sqlField->sqlNull();
  604.     }
  605.     return u_null.m_nullFlag;
  606. }
  607. void
  608. SqlField::sqlNull(bool value)
  609. {
  610.     u_null.m_nullFlag = value;
  611. }
  612. unsigned
  613. SqlField::trim() const
  614. {
  615.     const SqlType& sqlType = sqlSpec().sqlType();
  616.     unsigned n = 0;
  617.     const SqlChar* s = 0;
  618.     if (sqlType.type() == SqlType::Char) {
  619. n = sqlType.length();
  620. s = sqlChar();
  621.     } else if (sqlType.type() == SqlType::Varchar) {
  622. s = sqlVarchar(&n);
  623.     } else {
  624. ctx_assert(false);
  625. return 0;
  626.     }
  627.     while (n > 0 && s[n - 1] == 0x20)
  628. n--;
  629.     return n;
  630. }
  631. void
  632. SqlField::copy(Ctx& ctx, SqlField& out) const
  633. {
  634.     const SqlField& f1 = *this;
  635.     SqlField& f2 = out;
  636.     const SqlType& t1 = f1.sqlSpec().sqlType();
  637.     const SqlType& t2 = f2.sqlSpec().sqlType();
  638.     ctx_assert(t1.type() == t2.type());
  639.     if (f1.sqlNull()) {
  640. f2.sqlNull(true);
  641. return;
  642.     }
  643.     if (t1.type() == SqlType::Char) {
  644. f2.sqlChar(f1.sqlChar(), t1.length());
  645. return;
  646.     }
  647.     if (t1.type() == SqlType::Varchar) {
  648. unsigned length;
  649. const SqlChar* s1 = f1.sqlVarchar(&length);
  650. f2.sqlVarchar(s1, length);
  651. return;
  652.     }
  653.     if (t1.type() == SqlType::Binary) {
  654. f2.sqlBinary(f1.sqlBinary(), t1.length());
  655. return;
  656.     }
  657.     if (t1.type() == SqlType::Varbinary) {
  658. unsigned length;
  659. const SqlChar* s1 = f1.sqlVarbinary(&length);
  660. f2.sqlVarbinary(s1, length);
  661. return;
  662.     }
  663.     if (t1.type() == SqlType::Smallint) {
  664. f2.sqlSmallint(f1.sqlSmallint());
  665. return;
  666.     }
  667.     if (t1.type() == SqlType::Integer) {
  668. f2.sqlInteger(f1.sqlInteger());
  669. return;
  670.     }
  671.     if (t1.type() == SqlType::Bigint) {
  672. f2.sqlBigint(f1.sqlBigint());
  673. return;
  674.     }
  675.     if (t1.type() == SqlType::Real) {
  676. f2.sqlReal(f1.sqlReal());
  677. return;
  678.     }
  679.     if (t1.type() == SqlType::Double) {
  680. f2.sqlDouble(f1.sqlDouble());
  681. return;
  682.     }
  683.     if (t1.type() == SqlType::Datetime) {
  684. f2.sqlDatetime(f1.sqlDatetime());
  685. return;
  686.     }
  687.     ctx_assert(false);
  688. }
  689. bool
  690. SqlField::cast(Ctx& ctx, SqlField& out) const
  691. {
  692.     const SqlField& f1 = *this;
  693.     SqlField& f2 = out;
  694.     if (f1.sqlNull()) {
  695. f2.sqlNull(true);
  696. return true;
  697.     }
  698.     const SqlType& t1 = f1.sqlSpec().sqlType();
  699.     const SqlType& t2 = f2.sqlSpec().sqlType();
  700.     if (t1.type() == SqlType::Char) {
  701. if (t2.type() == SqlType::Char) {
  702.     unsigned n1 = f1.trim();
  703.     if (n1 > t2.length())
  704. return false;
  705.     f2.sqlChar(f1.sqlChar(), n1);
  706.     return true;
  707. }
  708. if (t2.type() == SqlType::Varchar) {
  709.     unsigned n1 = t1.length();
  710.     if (n1 > t2.length())
  711. return false;
  712.     f2.sqlVarchar(f1.sqlChar(), n1);
  713.     return true;
  714. }
  715. if (t2.type() == SqlType::Binary) {
  716.     unsigned n1 = t1.length();
  717.     if (n1 > t2.length())
  718. return false;
  719.     f2.sqlBinary(f1.sqlChar(), n1);
  720.     return true;
  721. }
  722. if (t2.type() == SqlType::Varbinary) {
  723.     unsigned n1 = t1.length();
  724.     if (n1 > t2.length())
  725. return false;
  726.     f2.sqlVarbinary(f1.sqlChar(), n1);
  727.     return true;
  728. }
  729. ctx_assert(false);
  730. return false;
  731.     }
  732.     if (t1.type() == SqlType::Varchar) {
  733. if (t2.type() == SqlType::Char) {
  734.     unsigned n1 = f1.trim();
  735.     if (n1 > t2.length())
  736. return false;
  737.     f2.sqlChar(f1.sqlVarchar(0), n1);
  738.     return true;
  739. }
  740. if (t2.type() == SqlType::Varchar) {
  741.     unsigned n1 = f1.trim();
  742.     if (n1 > t2.length())
  743. return false;
  744.     f2.sqlVarchar(f1.sqlVarchar(0), n1);
  745.     return true;
  746. }
  747. if (t2.type() == SqlType::Binary) {
  748.     unsigned n1 = t1.length();
  749.     if (n1 > t2.length())
  750. return false;
  751.     f2.sqlBinary(f1.sqlVarchar(0), n1);
  752.     return true;
  753. }
  754. if (t2.type() == SqlType::Varbinary) {
  755.     unsigned n1 = t1.length();
  756.     if (n1 > t2.length())
  757. return false;
  758.     f2.sqlVarbinary(f1.sqlVarchar(0), n1);
  759.     return true;
  760. }
  761. ctx_assert(false);
  762. return false;
  763.     }
  764.     if (t1.type() == SqlType::Binary) {
  765. if (t2.type() == SqlType::Binary) {
  766.     unsigned n1 = t1.length();
  767.     if (n1 > t2.length())
  768. return false;
  769.     f2.sqlBinary(f1.sqlBinary(), n1);
  770.     return true;
  771. }
  772. if (t2.type() == SqlType::Varbinary) {
  773.     unsigned n1 = t1.length();
  774.     if (n1 > t2.length())
  775. return false;
  776.     f2.sqlVarbinary(f1.sqlBinary(), n1);
  777.     return true;
  778. }
  779. ctx_assert(false);
  780. return false;
  781.     }
  782.     if (t1.type() == SqlType::Varbinary) {
  783. if (t2.type() == SqlType::Binary) {
  784.     unsigned n1 = t1.length();
  785.     if (n1 > t2.length())
  786. return false;
  787.     f2.sqlBinary(f1.sqlVarbinary(0), n1);
  788.     return true;
  789. }
  790. if (t2.type() == SqlType::Varbinary) {
  791.     unsigned n1 = t1.length();
  792.     if (n1 > t2.length())
  793. return false;
  794.     f2.sqlVarbinary(f1.sqlVarbinary(0), n1);
  795.     return true;
  796. }
  797. ctx_assert(false);
  798. return false;
  799.     }
  800.     if (t1.type() == SqlType::Smallint) {
  801. if (! t2.unSigned()) {
  802.     SqlSmallint x1 = f1.sqlSmallint();
  803.     if (t2.type() == SqlType::Smallint) {
  804. f2.sqlSmallint(x1);
  805. return true;
  806.     }
  807.     if (t2.type() == SqlType::Integer) {
  808. SqlInteger x2 = static_cast<SqlInteger>(x1);
  809. f2.sqlInteger(x2);
  810. return true;
  811.     }
  812.     if (t2.type() == SqlType::Bigint) {
  813. SqlBigint x2 = static_cast<SqlBigint>(x1);
  814. f2.sqlBigint(x2);
  815. return true;
  816.     }
  817.     if (t2.type() == SqlType::Real) {
  818. SqlReal x2 = static_cast<SqlReal>(x1);
  819. f2.sqlReal(x2);
  820. return true;
  821.     }
  822.     if (t2.type() == SqlType::Double) {
  823. SqlDouble x2 = static_cast<SqlDouble>(x1);
  824. f2.sqlDouble(x2);
  825. return true;
  826.     }
  827. } else {
  828.     SqlUsmallint x1 = f1.sqlSmallint();
  829.     if (t2.type() == SqlType::Smallint) {
  830. f2.sqlSmallint(x1);
  831. return true;
  832.     }
  833.     if (t2.type() == SqlType::Integer) {
  834. SqlUinteger x2 = static_cast<SqlUinteger>(x1);
  835. f2.sqlInteger(x2);
  836. return true;
  837.     }
  838.     if (t2.type() == SqlType::Bigint) {
  839. SqlUbigint x2 = static_cast<SqlUbigint>(x1);
  840. f2.sqlBigint(x2);
  841. return true;
  842.     }
  843. }
  844. ctx_assert(false);
  845. return false;
  846.     }
  847.     if (t1.type() == SqlType::Integer) {
  848. if (! t2.unSigned()) {
  849.     SqlInteger x1 = f1.sqlInteger();
  850.     if (t2.type() == SqlType::Smallint) {
  851. SqlSmallint x2 = static_cast<SqlSmallint>(x1);
  852. if (x1 != static_cast<SqlInteger>(x2))
  853.     return false;
  854. f2.sqlSmallint(x2);
  855. return true;
  856.     }
  857.     if (t2.type() == SqlType::Integer) {
  858. f2.sqlInteger(x1);
  859. return true;
  860.     }
  861.     if (t2.type() == SqlType::Bigint) {
  862. SqlBigint x2 = static_cast<SqlBigint>(x1);
  863. f2.sqlBigint(x2);
  864. return true;
  865.     }
  866.     if (t2.type() == SqlType::Real) {
  867. SqlReal x2 = static_cast<SqlReal>(x1);
  868. f2.sqlReal(x2);
  869. return true;
  870.     }
  871.     if (t2.type() == SqlType::Double) {
  872. SqlDouble x2 = static_cast<SqlDouble>(x1);
  873. f2.sqlDouble(x2);
  874. return true;
  875.     }
  876. } else {
  877.     SqlUinteger x1 = f1.sqlInteger();
  878.     if (t2.type() == SqlType::Smallint) {
  879. SqlUsmallint x2 = static_cast<SqlUsmallint>(x1);
  880. if (x1 != static_cast<SqlUinteger>(x2))
  881.     return false;
  882. f2.sqlSmallint(x2);
  883. return true;
  884.     }
  885.     if (t2.type() == SqlType::Integer) {
  886. f2.sqlInteger(x1);
  887. return true;
  888.     }
  889.     if (t2.type() == SqlType::Bigint) {
  890. SqlUbigint x2 = static_cast<SqlUbigint>(x1);
  891. f2.sqlBigint(x2);
  892. return true;
  893.     }
  894. }
  895. ctx_assert(false);
  896. return false;
  897.     }
  898.     if (t1.type() == SqlType::Bigint) {
  899. if (! t2.unSigned()) {
  900.     SqlBigint x1 = f1.sqlBigint();
  901.     if (t2.type() == SqlType::Smallint) {
  902. SqlSmallint x2 = static_cast<SqlSmallint>(x1);
  903. if (x1 != static_cast<SqlBigint>(x2))
  904.     return false;
  905. f2.sqlSmallint(x2);
  906. return true;
  907.     }
  908.     if (t2.type() == SqlType::Integer) {
  909. SqlInteger x2 = static_cast<SqlInteger>(x1);
  910. if (x1 != static_cast<SqlBigint>(x2))
  911.     return false;
  912. f2.sqlInteger(x2);
  913. return true;
  914.     }
  915.     if (t2.type() == SqlType::Bigint) {
  916. f2.sqlBigint(x1);
  917. return true;
  918.     }
  919.     if (t2.type() == SqlType::Real) {
  920. SqlReal x2 = static_cast<SqlReal>(x1);
  921. f2.sqlReal(x2);
  922. return true;
  923.     }
  924.     if (t2.type() == SqlType::Double) {
  925. SqlDouble x2 = static_cast<SqlDouble>(x1);
  926. f2.sqlDouble(x2);
  927. return true;
  928.     }
  929. } else {
  930.     SqlUbigint x1 = f1.sqlBigint();
  931.     if (t2.type() == SqlType::Smallint) {
  932. SqlUsmallint x2 = static_cast<SqlUsmallint>(x1);
  933. if (x1 != static_cast<SqlUbigint>(x2))
  934.     return false;
  935. f2.sqlSmallint(x2);
  936. return true;
  937.     }
  938.     if (t2.type() == SqlType::Integer) {
  939. SqlUinteger x2 = static_cast<SqlUinteger>(x1);
  940. if (x1 != static_cast<SqlUbigint>(x2))
  941.     return false;
  942. f2.sqlInteger(x2);
  943. return true;
  944.     }
  945.     if (t2.type() == SqlType::Bigint) {
  946. f2.sqlBigint(x1);
  947. return true;
  948.     }
  949. }
  950. ctx_assert(false);
  951. return false;
  952.     }
  953.     if (t1.type() == SqlType::Real) {
  954. SqlReal x1 = f1.sqlReal();
  955. int off = 0;
  956. if (x1 > 0.0 && x1 - floor(x1) >= 0.5)
  957.     off = 1;
  958. if (x1 < 0.0 && x1 - floor(x1) <= 0.5)
  959.     off = -1;
  960. bool b = (x1 - floor(x1) < 0.5);
  961. if (t2.type() == SqlType::Smallint) {
  962.     SqlSmallint x2 = static_cast<SqlSmallint>(x1) + off;
  963.     if (fabs(x1 - static_cast<SqlReal>(x2)) >= 1.0)
  964. return false;
  965.     f2.sqlSmallint(x2);
  966.     return true;
  967. }
  968. if (t2.type() == SqlType::Integer) {
  969.     SqlInteger x2 = static_cast<SqlInteger>(x1) + off;
  970.     if (fabs(x1 - static_cast<SqlReal>(x2)) >= 1.0)
  971. return false;
  972.     f2.sqlInteger(x2);
  973.     return true;
  974. }
  975. if (t2.type() == SqlType::Bigint) {
  976.     SqlBigint x2 = static_cast<SqlBigint>(x1) + off;
  977.     if (fabs(x1 - static_cast<SqlReal>(x2)) >= 1.0)
  978. return false;
  979.     f2.sqlBigint(x2);
  980.     return true;
  981. }
  982. if (t2.type() == SqlType::Real) {
  983.     f2.sqlReal(x1);
  984.     return true;
  985. }
  986. if (t2.type() == SqlType::Double) {
  987.     SqlDouble x2 = static_cast<SqlDouble>(x1);
  988.     f2.sqlDouble(x2);
  989.     return true;
  990. }
  991. ctx_assert(false);
  992. return false;
  993.     }
  994.     if (t1.type() == SqlType::Double) {
  995. SqlDouble x1 = f1.sqlDouble();
  996. int off = 0;
  997. if (x1 > 0.0 && x1 - floor(x1) >= 0.5)
  998.     off = 1;
  999. if (x1 < 0.0 && x1 - floor(x1) <= 0.5)
  1000.     off = -1;
  1001. bool b = (x1 - floor(x1) < 0.5);
  1002. if (t2.type() == SqlType::Smallint) {
  1003.     SqlSmallint x2 = static_cast<SqlSmallint>(x1) + off;
  1004.     if (fabs(x1 - static_cast<SqlDouble>(x2)) >= 1.0)
  1005. return false;
  1006.     f2.sqlSmallint(x2);
  1007.     return true;
  1008. }
  1009. if (t2.type() == SqlType::Integer) {
  1010.     SqlInteger x2 = static_cast<SqlInteger>(x1) + off;
  1011.     if (fabs(x1 - static_cast<SqlDouble>(x2)) >= 1.0)
  1012. return false;
  1013.     f2.sqlInteger(x2);
  1014.     return true;
  1015. }
  1016. if (t2.type() == SqlType::Bigint) {
  1017.     SqlBigint x2 = static_cast<SqlBigint>(x1) + off;
  1018.     if (fabs(x1 - static_cast<SqlDouble>(x2)) >= 1.0)
  1019. return false;
  1020.     f2.sqlBigint(x2);
  1021.     return true;
  1022. }
  1023. if (t2.type() == SqlType::Real) {
  1024.     SqlReal x2 = static_cast<SqlReal>(x1);
  1025.     if (fabs(x1 - static_cast<SqlDouble>(x2)) >= 1.0) // XXX
  1026. return false;
  1027.     f2.sqlReal(x1);
  1028.     return true;
  1029. }
  1030. if (t2.type() == SqlType::Double) {
  1031.     f2.sqlDouble(x1);
  1032.     return true;
  1033. }
  1034. ctx_assert(false);
  1035. return false;
  1036.     }
  1037.     ctx_assert(false);
  1038.     return false;
  1039. }
  1040. bool
  1041. SqlField::less(const SqlField& sqlField) const
  1042. {
  1043.     const SqlField& f1 = *this;
  1044.     const SqlField& f2 = sqlField;
  1045.     const SqlType& t1 = f1.sqlSpec().sqlType();
  1046.     const SqlType& t2 = f2.sqlSpec().sqlType();
  1047.     ctx_assert(t1.type() == t2.type());
  1048.     if (t1.type() == SqlType::Char) {
  1049. const SqlChar* s1 = f1.sqlChar();
  1050. const SqlChar* s2 = f2.sqlChar();
  1051. unsigned n1 = t1.length();
  1052. unsigned n2 = t2.length();
  1053. SqlChar c1 = 0;
  1054. SqlChar c2 = 0;
  1055. unsigned i = 0;
  1056. while (i < n1 || i < n2) {
  1057.     c1 = i < n1 ? s1[i] : 0x20;
  1058.     c2 = i < n2 ? s2[i] : 0x20;
  1059.     if (c1 != c2)
  1060. break;
  1061.     i++;
  1062. }
  1063. return (c1 < c2);
  1064.     }
  1065.     if (t1.type() == SqlType::Varchar) {
  1066. unsigned n1, n2;
  1067. const SqlChar* s1 = f1.sqlVarchar(&n1);
  1068. const SqlChar* s2 = f2.sqlVarchar(&n2);
  1069. SqlChar c1 = 0;
  1070. SqlChar c2 = 0;
  1071. unsigned i = 0;
  1072. while (i < n1 || i < n2) {
  1073.     c1 = i < n1 ? s1[i] : 0x0;
  1074.     c2 = i < n2 ? s2[i] : 0x0;
  1075.     if (c1 != c2)
  1076. break;
  1077.     i++;
  1078. }
  1079. return (c1 < c2);
  1080.     }
  1081.     if (t1.type() == SqlType::Smallint) {
  1082. ctx_assert(t1.unSigned() == t2.unSigned());
  1083. if (! t1.unSigned()) {
  1084.     SqlSmallint x1 = f1.sqlSmallint();
  1085.     SqlSmallint x2 = f2.sqlSmallint();
  1086.     return (x1 < x2);
  1087. } else {
  1088.     SqlUsmallint x1 = f1.sqlSmallint();
  1089.     SqlUsmallint x2 = f2.sqlSmallint();
  1090.     return (x1 < x2);
  1091. }
  1092.     }
  1093.     if (t1.type() == SqlType::Integer) {
  1094. ctx_assert(t1.unSigned() == t2.unSigned());
  1095. if (! t1.unSigned()) {
  1096.     SqlInteger x1 = f1.sqlInteger();
  1097.     SqlInteger x2 = f2.sqlInteger();
  1098.     return (x1 < x2);
  1099. } else {
  1100.     SqlUinteger x1 = f1.sqlInteger();
  1101.     SqlUinteger x2 = f2.sqlInteger();
  1102.     return (x1 < x2);
  1103. }
  1104.     }
  1105.     if (t1.type() == SqlType::Bigint) {
  1106. ctx_assert(t1.unSigned() == t2.unSigned());
  1107. if (! t1.unSigned()) {
  1108.     SqlBigint x1 = f1.sqlBigint();
  1109.     SqlBigint x2 = f2.sqlBigint();
  1110.     return (x1 < x2);
  1111. } else {
  1112.     SqlUbigint x1 = f1.sqlBigint();
  1113.     SqlUbigint x2 = f2.sqlBigint();
  1114.     return (x1 < x2);
  1115. }
  1116.     }
  1117.     if (t1.type() == SqlType::Real) {
  1118. SqlReal x1 = f1.sqlReal();
  1119. SqlReal x2 = f2.sqlReal();
  1120. return (x1 < x2);
  1121.     }
  1122.     if (t1.type() == SqlType::Double) {
  1123. SqlDouble x1 = f1.sqlDouble();
  1124. SqlDouble x2 = f2.sqlDouble();
  1125. return (x1 < x2);
  1126.     }
  1127.     if (t1.type() == SqlType::Datetime) {
  1128. SqlDatetime x1 = f1.sqlDatetime();
  1129. SqlDatetime x2 = f2.sqlDatetime();
  1130. return x1.less(x2);
  1131.     }
  1132.     ctx_assert(false);
  1133. }
  1134. // copy from external
  1135. static bool
  1136. copyin_char_char(Ctx& ctx, char* value, unsigned n, const char* ptr, const SQLINTEGER* ind, int* off, SqlChar* addr, int fieldId)
  1137. {
  1138.     if (off != 0 && *off >= 0) {
  1139. if ((unsigned)*off > n) {
  1140.     ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d truncated (%u > %u)", fieldId, (unsigned)*off, n);
  1141.     return false;
  1142. }
  1143. value += *off;
  1144. n -= *off;
  1145.     }
  1146.     unsigned m;
  1147.     if (ind == 0 || *ind == SQL_NTS)
  1148. m = strlen(ptr);
  1149.     else
  1150. m = *ind;
  1151.     if (m > n) {
  1152. ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d truncated (%u > %u)", fieldId, m, n);
  1153. return false;
  1154.     }
  1155.     for (unsigned i = 0; i < m; i++)
  1156. value[i] = ptr[i];
  1157.     if (off != 0 && *off >= 0)
  1158. *off += m;
  1159.     for (unsigned i = m; i < n; i++)
  1160. value[i] = addr == 0 ? 0x20 : 0x0;
  1161.     if (addr != 0) {
  1162. if (off != 0 && *off >= 0)
  1163.     m = *off;
  1164. addr[0] = (m >> 8) & 0xff;
  1165. addr[1] = (m & 0xff);
  1166.     }
  1167.     return true;
  1168. }
  1169. static bool
  1170. copyin_binary_binary(Ctx& ctx, char* value, unsigned n, const char* ptr, const SQLINTEGER* ind, int* off, SqlChar* addr, int fieldId)
  1171. {
  1172.     if (off != 0 && *off >= 0) {
  1173. if ((unsigned)*off > n) {
  1174.     ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d truncated (%u > %u)", fieldId, (unsigned)*off, n);
  1175.     return false;
  1176. }
  1177. value += *off;
  1178. n -= *off;
  1179.     }
  1180.     if (ind == 0) {
  1181. ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d missing length", fieldId);
  1182. return false;
  1183.     }
  1184.     if (*ind < 0) {
  1185. ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d invalid length %d", fieldId, (int)*ind);
  1186. return false;
  1187.     }
  1188.     unsigned m;
  1189.     m = *ind;
  1190.     if (m > n) {
  1191. ctx.pushStatus(Sqlstate::_22001, Error::Gen, "input parameter %d truncated (%u > %u)", fieldId, m, n);
  1192. return false;
  1193.     }
  1194.     for (unsigned i = 0; i < m; i++)
  1195. value[i] = ptr[i];
  1196.     if (off != 0 && *off >= 0)
  1197. *off += m;
  1198.     for (unsigned i = m; i < n; i++)
  1199. value[i] = addr == 0 ? 0x0 : 0x0; // just null
  1200.     if (addr != 0) {
  1201. if (off != 0 && *off >= 0)
  1202.     m = *off;
  1203. addr[0] = (m >> 8) & 0xff;
  1204. addr[1] = (m & 0xff);
  1205.     }
  1206.     return true;
  1207. }
  1208. static bool
  1209. copyin_signed_char(Ctx& ctx, SqlBigint* value, const char* ptr, int fieldId)
  1210. {
  1211.     errno = 0;
  1212.     char* endptr = 0;
  1213.     SqlBigint x = strtoll(ptr, &endptr, 10);
  1214.     if (endptr == 0 || *endptr != 0) {
  1215.         errno = 0;
  1216.         endptr = 0;
  1217.         double y = strtod(ptr, &endptr);
  1218.         if (endptr == 0 || *endptr != 0) {
  1219.             ctx.pushStatus(Sqlstate::_22005, Error::Gen, "input parameter %d value %s not numeric", fieldId, ptr);
  1220.             return false;
  1221.         } else if (errno != 0) {
  1222.             ctx.pushStatus(Sqlstate::_22003, Error::Gen, "input parameter %d value %s overflow", fieldId, ptr);
  1223.             return false;
  1224.         }
  1225.         // XXX should handle 123.000
  1226.         ctx.pushStatus(Sqlstate::_01004, Error::Gen, "input parameter %d value %s truncated", fieldId, ptr);
  1227.         x = static_cast<SqlBigint>(y);
  1228.     } else if (errno != 0) {
  1229.         ctx.pushStatus(Sqlstate::_22003, Error::Gen, "input parameter %d value %s overflow", fieldId, ptr);
  1230.         return false;
  1231.     }
  1232.     *value = x;
  1233.     return true;
  1234. }
  1235. static bool
  1236. copyin_double_char(Ctx& ctx, SqlDouble* value, const char* ptr, int fieldId)
  1237. {
  1238.     errno = 0;
  1239.     char* endptr = 0;
  1240.     double x = strtod(ptr, &endptr);
  1241.     if (endptr == 0 || *endptr != 0) {
  1242.         ctx.pushStatus(Sqlstate::_22005, Error::Gen, "input parameter %d value %s not numeric", fieldId, ptr);
  1243.         return false;
  1244.     } else if (errno != 0) {
  1245.         ctx.pushStatus(Sqlstate::_22003, Error::Gen, "input parameter %d value %s overflow", fieldId, ptr);
  1246.         return false;
  1247.     }
  1248.     *value = x;
  1249.     return true;
  1250. }
  1251. void
  1252. SqlField::copyin(Ctx& ctx, ExtField& extField)
  1253. {
  1254.     ctx_assert(extField.extSpec().extType().type() != ExtType::Unbound);
  1255.     ctx_assert(sqlSpec().store() == SqlSpec::Physical);
  1256.     SQLINTEGER* indPtr = extField.m_indPtr;
  1257.     const int fieldId = extField.fieldId();
  1258.     if (indPtr != 0 && *indPtr == SQL_NULL_DATA) {
  1259. sqlNull(true);
  1260. return;
  1261.     }
  1262.     const SqlType& sqlType = sqlSpec().sqlType();
  1263.     const ExtType& extType = extField.extSpec().extType();
  1264.     if (extField.m_pos > 0) {
  1265. if (sqlType.type() == SqlType::Char && extType.type() == ExtType::Char)
  1266.     ;
  1267. else if (sqlType.type() == SqlType::Varchar && extType.type() == ExtType::Char)
  1268.     ;
  1269. else {
  1270.     char buf[40];
  1271.     sqlType.print(buf, sizeof(buf));
  1272.     ctx.pushStatus(Sqlstate::_HY019, Error::Gen, "cannot send %s data in pieces", buf);
  1273.     return;
  1274. }
  1275.     }
  1276.     if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) {
  1277. unsigned length = 0;
  1278. char* value = 0;
  1279. SqlChar* laddr = 0; // Varchar length address
  1280. if (sqlType.type() == SqlType::Char) {
  1281.     length = sqlType.length();
  1282.     if (length > SqlField_CharSmall)
  1283. value = reinterpret_cast<char *>(u_data.m_sqlChar);
  1284.     else
  1285. value = reinterpret_cast<char *>(u_data.m_sqlCharSmall);
  1286.     laddr = 0;
  1287. } else {
  1288. #if NDB_VERSION_MAJOR >= 3
  1289.     length = sqlType.length();
  1290.     if (2 + length > SqlField_CharSmall)
  1291. value = reinterpret_cast<char *>(u_data.m_sqlChar + 2);
  1292.     else
  1293. value = reinterpret_cast<char *>(u_data.m_sqlCharSmall + 2);
  1294.     laddr = (SqlChar*)value - 2;
  1295. #else
  1296.     length = sqlType.length();
  1297.     if (length + 2 > SqlField_CharSmall)
  1298. value = reinterpret_cast<char *>(u_data.m_sqlChar);
  1299.     else
  1300. value = reinterpret_cast<char *>(u_data.m_sqlCharSmall);
  1301.     laddr = (SqlChar*)value + length;
  1302. #endif
  1303. }
  1304. if (extType.type() == ExtType::Char) {
  1305.     const char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  1306.     int* off = 0;
  1307.     if (extField.m_pos >= 0)
  1308. off = &extField.m_pos;
  1309.     if (! copyin_char_char(ctx, value, length, dataPtr, indPtr, off, laddr, fieldId))
  1310. return;
  1311.     sqlNull(false);
  1312.     return;
  1313. }
  1314. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  1315.     const short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  1316.     char buf[100];
  1317.     sprintf(buf, "%hd", *dataPtr);
  1318.     if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId))
  1319. return;
  1320.     sqlNull(false);
  1321.     if (extField.m_pos >= 0)
  1322. extField.m_pos = 1;
  1323.     return;
  1324. }
  1325. if (extType.type() == ExtType::Ushort) {
  1326.     const unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  1327.     char buf[100];
  1328.     sprintf(buf, "%hu", *dataPtr);
  1329.     if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId))
  1330. return;
  1331.     sqlNull(false);
  1332.     if (extField.m_pos >= 0)
  1333. extField.m_pos = 1;
  1334.     return;
  1335. }
  1336. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  1337.     const long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  1338.     char buf[100];
  1339.     sprintf(buf, "%ld", *dataPtr);
  1340.     if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId))
  1341. return;
  1342.     sqlNull(false);
  1343.     if (extField.m_pos >= 0)
  1344. extField.m_pos = 1;
  1345.     return;
  1346. }
  1347. if (extType.type() == ExtType::Ulong) {
  1348.     const unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  1349.     char buf[100];
  1350.     sprintf(buf, "%lu", *dataPtr);
  1351.     if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId))
  1352. return;
  1353.     sqlNull(false);
  1354.     if (extField.m_pos >= 0)
  1355. extField.m_pos = 1;
  1356.     return;
  1357. }
  1358. if (extType.type() == ExtType::Sbigint) {
  1359.     const SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  1360.     char buf[100];
  1361.     sprintf(buf, FMT_I64, *dataPtr);
  1362.     if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId))
  1363. return;
  1364.     sqlNull(false);
  1365.     if (extField.m_pos >= 0)
  1366. extField.m_pos = 1;
  1367.     return;
  1368. }
  1369. if (extType.type() == ExtType::Ubigint) {
  1370.     const SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  1371.     char buf[100];
  1372.     sprintf(buf, FMT_U64, *dataPtr);
  1373.     if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId))
  1374. return;
  1375.     sqlNull(false);
  1376.     if (extField.m_pos >= 0)
  1377. extField.m_pos = 1;
  1378.     return;
  1379. }
  1380. if (extType.type() == ExtType::Float) {
  1381.     const float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  1382.     char buf[100];
  1383.     sprintf(buf, "%.7f", (double)*dataPtr);
  1384.     if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId))
  1385. return;
  1386.     sqlNull(false);
  1387.     if (extField.m_pos >= 0)
  1388. extField.m_pos = 1;
  1389.     return;
  1390. }
  1391. if (extType.type() == ExtType::Double) {
  1392.     const double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  1393.     char buf[100];
  1394.     sprintf(buf, "%.14f", *dataPtr);
  1395.     if (! copyin_char_char(ctx, value, length, buf, indPtr, 0, laddr, fieldId))
  1396. return;
  1397.     sqlNull(false);
  1398.     if (extField.m_pos >= 0)
  1399. extField.m_pos = 1;
  1400.     return;
  1401. }
  1402.     }
  1403.     if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) {
  1404. unsigned length = 0;
  1405. char* value = 0;
  1406. SqlChar* laddr = 0; // Varbinary length address
  1407. if (sqlType.type() == SqlType::Binary) {
  1408.     length = sqlType.length();
  1409.     if (length > SqlField_CharSmall)
  1410. value = reinterpret_cast<char *>(u_data.m_sqlChar);
  1411.     else
  1412. value = reinterpret_cast<char *>(u_data.m_sqlCharSmall);
  1413.     laddr = 0;
  1414. } else {
  1415. #if NDB_VERSION_MAJOR >= 3
  1416.     length = sqlType.length();
  1417.     if (2 + length > SqlField_CharSmall)
  1418. value = reinterpret_cast<char *>(u_data.m_sqlChar + 2);
  1419.     else
  1420. value = reinterpret_cast<char *>(u_data.m_sqlCharSmall + 2);
  1421.     laddr = (SqlChar*)value - 2;
  1422. #else
  1423.     length = sqlType.length();
  1424.     if (length + 2 > SqlField_CharSmall)
  1425. value = reinterpret_cast<char *>(u_data.m_sqlChar);
  1426.     else
  1427. value = reinterpret_cast<char *>(u_data.m_sqlCharSmall);
  1428.     laddr = (SqlChar*)value + length;
  1429. #endif
  1430. }
  1431. if (extType.type() == ExtType::Binary) {
  1432.     const char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  1433.     int* off = 0;
  1434.     if (extField.m_pos >= 0)
  1435. off = &extField.m_pos;
  1436.     if (! copyin_binary_binary(ctx, value, length, dataPtr, indPtr, off, laddr, fieldId))
  1437. return;
  1438.     sqlNull(false);
  1439.     return;
  1440. }
  1441.     }
  1442.     if (sqlType.type() == SqlType::Smallint) {
  1443. SqlSmallint value;
  1444. if (extType.type() == ExtType::Char) {
  1445.     const char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  1446.     SqlBigint x;
  1447.     if (! copyin_signed_char(ctx, &x, dataPtr, fieldId))
  1448. return;
  1449.     value = x;
  1450.     sqlSmallint(value);
  1451.     if (extField.m_pos >= 0)
  1452. extField.m_pos = 1;
  1453.     return;
  1454. }
  1455. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  1456.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  1457.     value = *dataPtr;
  1458.     sqlSmallint(value);
  1459.     if (extField.m_pos >= 0)
  1460. extField.m_pos = 1;
  1461.     return;
  1462. }
  1463. if (extType.type() == ExtType::Ushort) {
  1464.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  1465.     value = *dataPtr;
  1466.     sqlSmallint(value);
  1467.     if (extField.m_pos >= 0)
  1468. extField.m_pos = 1;
  1469.     return;
  1470. }
  1471. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  1472.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  1473.     value = *dataPtr;
  1474.     sqlSmallint(value);
  1475.     if (extField.m_pos >= 0)
  1476. extField.m_pos = 1;
  1477.     return;
  1478. }
  1479. if (extType.type() == ExtType::Ulong) {
  1480.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  1481.     value = *dataPtr;
  1482.     sqlSmallint(value);
  1483.     if (extField.m_pos >= 0)
  1484. extField.m_pos = 1;
  1485.     return;
  1486. }
  1487. if (extType.type() == ExtType::Sbigint) {
  1488.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  1489.     value = *dataPtr;
  1490.     sqlSmallint(value);
  1491.     if (extField.m_pos >= 0)
  1492. extField.m_pos = 1;
  1493.     return;
  1494. }
  1495. if (extType.type() == ExtType::Ubigint) {
  1496.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  1497.     value = *dataPtr;
  1498.     sqlSmallint(value);
  1499.     if (extField.m_pos >= 0)
  1500. extField.m_pos = 1;
  1501.     return;
  1502. }
  1503. if (extType.type() == ExtType::Float) {
  1504.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  1505.     value = (SqlSmallint)*dataPtr;
  1506.     sqlSmallint(value);
  1507.     if (extField.m_pos >= 0)
  1508. extField.m_pos = 1;
  1509.     return;
  1510. }
  1511. if (extType.type() == ExtType::Double) {
  1512.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  1513.     value = (SqlSmallint)*dataPtr;
  1514.     sqlSmallint(value);
  1515.     if (extField.m_pos >= 0)
  1516. extField.m_pos = 1;
  1517.     return;
  1518. }
  1519.     }
  1520.     if (sqlType.type() == SqlType::Integer) {
  1521. SqlInteger value;
  1522. if (extType.type() == ExtType::Char) {
  1523.     const char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  1524.     SqlBigint x;
  1525.     if (! copyin_signed_char(ctx, &x, dataPtr, fieldId))
  1526. return;
  1527.     value = x;
  1528.     sqlInteger(value);
  1529.     if (extField.m_pos >= 0)
  1530. extField.m_pos = 1;
  1531.     return;
  1532. }
  1533. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  1534.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  1535.     value = *dataPtr;
  1536.     sqlInteger(value);
  1537.     if (extField.m_pos >= 0)
  1538. extField.m_pos = 1;
  1539.     return;
  1540. }
  1541. if (extType.type() == ExtType::Ushort) {
  1542.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  1543.     value = *dataPtr;
  1544.     sqlInteger(value);
  1545.     if (extField.m_pos >= 0)
  1546. extField.m_pos = 1;
  1547.     return;
  1548. }
  1549. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  1550.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  1551.     value = *dataPtr;
  1552.     sqlInteger(value);
  1553.     if (extField.m_pos >= 0)
  1554. extField.m_pos = 1;
  1555.     return;
  1556. }
  1557. if (extType.type() == ExtType::Ulong) {
  1558.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  1559.     value = *dataPtr;
  1560.     sqlInteger(value);
  1561.     if (extField.m_pos >= 0)
  1562. extField.m_pos = 1;
  1563.     return;
  1564. }
  1565. if (extType.type() == ExtType::Sbigint) {
  1566.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  1567.     value = *dataPtr;
  1568.     sqlInteger(value);
  1569.     if (extField.m_pos >= 0)
  1570. extField.m_pos = 1;
  1571.     return;
  1572. }
  1573. if (extType.type() == ExtType::Ubigint) {
  1574.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  1575.     value = *dataPtr;
  1576.     sqlInteger(value);
  1577.     if (extField.m_pos >= 0)
  1578. extField.m_pos = 1;
  1579.     return;
  1580. }
  1581. if (extType.type() == ExtType::Float) {
  1582.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  1583.     value = (SqlInteger)*dataPtr;
  1584.     sqlInteger(value);
  1585.     if (extField.m_pos >= 0)
  1586. extField.m_pos = 1;
  1587.     return;
  1588. }
  1589. if (extType.type() == ExtType::Double) {
  1590.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  1591.     value = (SqlInteger)*dataPtr;
  1592.     sqlInteger(value);
  1593.     if (extField.m_pos >= 0)
  1594. extField.m_pos = 1;
  1595.     return;
  1596. }
  1597.     }
  1598.     if (sqlType.type() == SqlType::Bigint) {
  1599. SqlBigint value;
  1600. if (extType.type() == ExtType::Char) {
  1601.     const char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  1602.     SqlBigint x;
  1603.     if (! copyin_signed_char(ctx, &x, dataPtr, fieldId))
  1604. return;
  1605.     value = x;
  1606.     sqlBigint(value);
  1607.     if (extField.m_pos >= 0)
  1608. extField.m_pos = 1;
  1609.     return;
  1610. }
  1611. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  1612.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  1613.     value = *dataPtr;
  1614.     sqlBigint(value);
  1615.     if (extField.m_pos >= 0)
  1616. extField.m_pos = 1;
  1617.     return;
  1618. }
  1619. if (extType.type() == ExtType::Ushort) {
  1620.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  1621.     value = *dataPtr;
  1622.     sqlBigint(value);
  1623.     if (extField.m_pos >= 0)
  1624. extField.m_pos = 1;
  1625.     return;
  1626. }
  1627. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  1628.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  1629.     value = *dataPtr;
  1630.     sqlBigint(value);
  1631.     if (extField.m_pos >= 0)
  1632. extField.m_pos = 1;
  1633.     return;
  1634. }
  1635. if (extType.type() == ExtType::Ulong) {
  1636.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  1637.     value = *dataPtr;
  1638.     sqlBigint(value);
  1639.     if (extField.m_pos >= 0)
  1640. extField.m_pos = 1;
  1641.     return;
  1642. }
  1643. if (extType.type() == ExtType::Sbigint) {
  1644.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  1645.     value = *dataPtr;
  1646.     sqlBigint(value);
  1647.     if (extField.m_pos >= 0)
  1648. extField.m_pos = 1;
  1649.     return;
  1650. }
  1651. if (extType.type() == ExtType::Ubigint) {
  1652.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  1653.     value = *dataPtr;
  1654.     sqlBigint(value);
  1655.     if (extField.m_pos >= 0)
  1656. extField.m_pos = 1;
  1657.     return;
  1658. }
  1659. if (extType.type() == ExtType::Float) {
  1660.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  1661.     value = (SqlBigint)*dataPtr;
  1662.     sqlBigint(value);
  1663.     if (extField.m_pos >= 0)
  1664. extField.m_pos = 1;
  1665.     return;
  1666. }
  1667. if (extType.type() == ExtType::Double) {
  1668.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  1669.     value = (SqlBigint)*dataPtr;
  1670.     sqlBigint(value);
  1671.     if (extField.m_pos >= 0)
  1672. extField.m_pos = 1;
  1673.     return;
  1674. }
  1675.     }
  1676.     if (sqlType.type() == SqlType::Real) {
  1677. SqlReal value;
  1678. if (extType.type() == ExtType::Char) {
  1679.     const char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  1680.     SqlDouble x;
  1681.     if (! copyin_double_char(ctx, &x, dataPtr, fieldId))
  1682. return;
  1683.     value = x;
  1684.     sqlReal(x);
  1685.     if (extField.m_pos >= 0)
  1686. extField.m_pos = 1;
  1687.     return;
  1688. }
  1689. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  1690.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  1691.     value = *dataPtr;
  1692.     sqlReal(value);
  1693.     if (extField.m_pos >= 0)
  1694. extField.m_pos = 1;
  1695.     return;
  1696. }
  1697. if (extType.type() == ExtType::Ushort) {
  1698.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  1699.     value = *dataPtr;
  1700.     sqlReal(value);
  1701.     if (extField.m_pos >= 0)
  1702. extField.m_pos = 1;
  1703.     return;
  1704. }
  1705. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  1706.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  1707.     value = *dataPtr;
  1708.     sqlReal(value);
  1709.     if (extField.m_pos >= 0)
  1710. extField.m_pos = 1;
  1711.     return;
  1712. }
  1713. if (extType.type() == ExtType::Ulong) {
  1714.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  1715.     value = *dataPtr;
  1716.     sqlReal(value);
  1717.     if (extField.m_pos >= 0)
  1718. extField.m_pos = 1;
  1719.     return;
  1720. }
  1721. if (extType.type() == ExtType::Sbigint) {
  1722.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  1723.     value = *dataPtr;
  1724.     sqlReal(value);
  1725.     if (extField.m_pos >= 0)
  1726. extField.m_pos = 1;
  1727.     return;
  1728. }
  1729. if (extType.type() == ExtType::Ubigint) {
  1730.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  1731.     value = *dataPtr;
  1732.     sqlReal(value);
  1733.     if (extField.m_pos >= 0)
  1734. extField.m_pos = 1;
  1735.     return;
  1736. }
  1737. if (extType.type() == ExtType::Float) {
  1738.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  1739.     value = *dataPtr;
  1740.     sqlReal(value);
  1741.     if (extField.m_pos >= 0)
  1742. extField.m_pos = 1;
  1743.     return;
  1744. }
  1745. if (extType.type() == ExtType::Double) {
  1746.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  1747.     value = *dataPtr;
  1748.     sqlReal(value);
  1749.     if (extField.m_pos >= 0)
  1750. extField.m_pos = 1;
  1751.     return;
  1752. }
  1753.     }
  1754.     if (sqlType.type() == SqlType::Double) {
  1755. SqlDouble value;
  1756. if (extType.type() == ExtType::Char) {
  1757.     const char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  1758.     SqlDouble x;
  1759.     if (! copyin_double_char(ctx, &x, dataPtr, fieldId))
  1760. return;
  1761.     value = x;
  1762.     sqlDouble(x);
  1763.     if (extField.m_pos >= 0)
  1764. extField.m_pos = 1;
  1765.     return;
  1766. }
  1767. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  1768.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  1769.     value = *dataPtr;
  1770.     sqlDouble(value);
  1771.     if (extField.m_pos >= 0)
  1772. extField.m_pos = 1;
  1773.     return;
  1774. }
  1775. if (extType.type() == ExtType::Ushort) {
  1776.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  1777.     value = *dataPtr;
  1778.     sqlDouble(value);
  1779.     if (extField.m_pos >= 0)
  1780. extField.m_pos = 1;
  1781.     return;
  1782. }
  1783. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  1784.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  1785.     value = *dataPtr;
  1786.     sqlDouble(value);
  1787.     if (extField.m_pos >= 0)
  1788. extField.m_pos = 1;
  1789.     return;
  1790. }
  1791. if (extType.type() == ExtType::Ulong) {
  1792.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  1793.     value = *dataPtr;
  1794.     sqlDouble(value);
  1795.     if (extField.m_pos >= 0)
  1796. extField.m_pos = 1;
  1797.     return;
  1798. }
  1799. if (extType.type() == ExtType::Sbigint) {
  1800.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  1801.     value = *dataPtr;
  1802.     sqlDouble(value);
  1803.     if (extField.m_pos >= 0)
  1804. extField.m_pos = 1;
  1805.     return;
  1806. }
  1807. if (extType.type() == ExtType::Ubigint) {
  1808.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  1809.     value = *dataPtr;
  1810.     sqlDouble(value);
  1811.     if (extField.m_pos >= 0)
  1812. extField.m_pos = 1;
  1813.     return;
  1814. }
  1815. if (extType.type() == ExtType::Float) {
  1816.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  1817.     value = *dataPtr;
  1818.     sqlDouble(value);
  1819.     if (extField.m_pos >= 0)
  1820. extField.m_pos = 1;
  1821.     return;
  1822. }
  1823. if (extType.type() == ExtType::Double) {
  1824.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  1825.     value = *dataPtr;
  1826.     sqlDouble(value);
  1827.     if (extField.m_pos >= 0)
  1828. extField.m_pos = 1;
  1829.     return;
  1830. }
  1831.     }
  1832.     if (sqlType.type() == SqlType::Datetime) {
  1833. SqlDatetime value;
  1834. if (extType.type() == ExtType::Char) {
  1835.     // XXX replace sscanf by manual scan or regex
  1836.     const char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  1837.     int cc = 0;
  1838.     unsigned yy = 0, mm = 0, dd = 0, HH = 0, MM = 0, SS = 0, ff = 0;
  1839.     bool setdate = false;
  1840.     char dummy[10];
  1841.     if (sscanf(dataPtr, "%2d%2u-%2u-%2u %2u:%2u:%2u.%4u%1s", &cc, &yy, &mm, &dd, &HH, &MM, &SS, &ff, dummy) == 8) {
  1842. ;
  1843.     } else if (sscanf(dataPtr, "%2d%2u-%2u-%2u %2u:%2u:%2u%1s", &cc, &yy, &mm, &dd, &HH, &MM, &SS, dummy) == 7) {
  1844. ;
  1845.     } else if (sscanf(dataPtr, "%2d%2u-%2u-%2u%1s", &cc, &yy, &mm, &dd, dummy) == 4) {
  1846. ;
  1847.     } else if (sscanf(dataPtr, "%2u:%2u:%2u.%4u%1s", &HH, &MM, &SS, &ff, dummy) == 4) {
  1848. setdate = true;
  1849.     } else if (sscanf(dataPtr, "%2u:%2u:%2u%1s", &HH, &MM, &SS, dummy) == 3) {
  1850. setdate = true;
  1851.     } else {
  1852. ctx.pushStatus(Sqlstate::_22008, Error::Gen, "invalid timestamp format '%s'", dataPtr);
  1853. return;
  1854.     }
  1855.     if (setdate) {
  1856. time_t clock = time(0);
  1857. struct tm* t = localtime(&clock);
  1858. cc = (1900 + t->tm_year) / 100;
  1859. yy = (1900 + t->tm_year) % 100;
  1860. mm = 1 + t->tm_mon;
  1861. dd = t->tm_mday;
  1862.     }
  1863.     value.cc(cc);
  1864.     value.yy(yy);
  1865.     value.mm(mm);
  1866.     value.dd(dd);
  1867.     value.HH(HH);
  1868.     value.MM(MM);
  1869.     value.SS(SS);
  1870.     value.ff(ff);
  1871.     // XXX write date routines later
  1872.     if (! value.valid()) {
  1873. ctx.pushStatus(Sqlstate::_22008, Error::Gen, "invalid timestamp values '%s'", dataPtr);
  1874. return;
  1875.     }
  1876.     sqlDatetime(value);
  1877.     if (extField.m_pos >= 0)
  1878. extField.m_pos = 1;
  1879.     return;
  1880. }
  1881. if (extType.type() == ExtType::Timestamp) {
  1882.     SQL_TIMESTAMP_STRUCT* dataPtr = static_cast<SQL_TIMESTAMP_STRUCT*>(extField.m_dataPtr);
  1883.     // XXX assume same datatype
  1884.     value.cc(dataPtr->year / 100);
  1885.     value.yy(dataPtr->year / 100);
  1886.     value.mm(dataPtr->month);
  1887.     value.dd(dataPtr->day);
  1888.     value.HH(dataPtr->hour);
  1889.     value.MM(dataPtr->minute);
  1890.     value.SS(dataPtr->second);
  1891.     value.ff(dataPtr->fraction);
  1892.     if (! value.valid()) {
  1893. ctx.pushStatus(Sqlstate::_22008, Error::Gen, "invalid timestamp struct");
  1894. return;
  1895.     }
  1896.     sqlDatetime(value);
  1897.     if (extField.m_pos >= 0)
  1898. extField.m_pos = 1;
  1899.     return;
  1900. }
  1901.     }
  1902.     ctx_assert(false); // SqlType::Null not applicable
  1903. }
  1904. // copy to external
  1905. static bool
  1906. copyout_char_char(Ctx& ctx, const char* value, unsigned n, char* ptr, unsigned len, SQLINTEGER* ind, int* off)
  1907. {
  1908.     unsigned n2 = n;
  1909.     if (off != 0 && *off >= 0) {
  1910. ctx_assert((unsigned)*off <= n2);
  1911. value += *off;
  1912. n2 -= *off;
  1913. if (len < n2 + 1) {
  1914.     ctx.pushStatus(Sqlstate::_01004, Error::Gen, "more data at offset %d, current fetch %u, available %u", *off, len, n2);
  1915.     n2 = len - 1;
  1916. }
  1917.     } else {
  1918. if (len < n + 1) { // room for null byte
  1919.     ctx.pushStatus(Sqlstate::_22003, Error::Gen, "char value '%.*s' overflow (%u < %u)", (int)n, value, (unsigned)len, (unsigned)(len + 1));
  1920.     return false;
  1921. }
  1922.     }
  1923.     memcpy(ptr, value, n2);
  1924.     ptr[n2] = 0;
  1925.     if (off != 0 && *off >= 0) {
  1926. if (ind != 0)
  1927.     *ind = n - *off;
  1928. *off += n2;
  1929.     } else {
  1930. if (ind != 0)
  1931.     *ind = n;
  1932.     }
  1933.     return true;
  1934. }
  1935. static bool
  1936. copyout_binary_binary(Ctx& ctx, const char* value, unsigned n, char* ptr, unsigned len, SQLINTEGER* ind, int* off)
  1937. {
  1938.     unsigned n2 = n;
  1939.     if (off != 0 && *off >= 0) {
  1940. ctx_assert((unsigned)*off <= n2);
  1941. value += *off;
  1942. n2 -= *off;
  1943. if (len < n2 + 1) {
  1944.     ctx.pushStatus(Sqlstate::_01004, Error::Gen, "more data at offset %d, current fetch %u, available %u", *off, len, n2);
  1945.     n2 = len - 1;
  1946. }
  1947.     } else {
  1948. if (len < n) { // no room for null byte
  1949.     ctx.pushStatus(Sqlstate::_22003, Error::Gen, "binary value '%.*s' overflow (%u < %u)", (int)n, value, (unsigned)len, (unsigned)n);
  1950.     return false;
  1951. }
  1952.     }
  1953.     memcpy(ptr, value, n2);
  1954.     ptr[n2] = 0;
  1955.     if (off != 0 && *off >= 0) {
  1956. if (ind != 0)
  1957.     *ind = n - *off;
  1958. *off += n2;
  1959.     } else {
  1960. if (ind != 0)
  1961.     *ind = n;
  1962.     }
  1963.     return true;
  1964. }
  1965. static bool
  1966. copyout_char_signed(Ctx& ctx, const char* value, unsigned n, long* ptr)
  1967. {
  1968.     while (n > 0 && value[0] == 0x20) {
  1969. value++;
  1970. n--;
  1971.     }
  1972.     char buf[200];
  1973.     if (n >= 200)
  1974. n = 200 - 1;
  1975.     memcpy(buf, value, n);
  1976.     buf[n] = 0;
  1977.     errno = 0;
  1978.     char* endptr = 0;
  1979.     long x = strtol(buf, &endptr, 10);
  1980.     if (endptr == 0 || *endptr != 0) {
  1981. errno = 0;
  1982. endptr = 0;
  1983. double y = strtod(buf, &endptr);
  1984. if (endptr == 0 || *endptr != 0) {
  1985.     ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", buf);
  1986.     return false;
  1987. } else if (errno != 0) {
  1988.     ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  1989.     return false;
  1990. }
  1991. // XXX should handle 123.000
  1992. ctx.pushStatus(Sqlstate::_01004, Error::Gen, "value %s truncated", buf);
  1993. x = static_cast<long>(y);
  1994.     } else if (errno != 0) {
  1995. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  1996. return false;
  1997.     }
  1998.     *ptr = x;
  1999.     return true;
  2000. }
  2001. static bool
  2002. copyout_char_bigsigned(Ctx& ctx, const char* value, unsigned n, SQLBIGINT* ptr)
  2003. {
  2004.     while (n > 0 && value[0] == 0x20) {
  2005. value++;
  2006. n--;
  2007.     }
  2008.     char buf[200];
  2009.     if (n >= 200)
  2010. n = 200 - 1;
  2011.     memcpy(buf, value, n);
  2012.     buf[n] = 0;
  2013.     errno = 0;
  2014.     char* endptr = 0;
  2015.     SQLBIGINT x = strtoll(buf, &endptr, 10);
  2016.     if (endptr == 0 || *endptr != 0) {
  2017. errno = 0;
  2018. endptr = 0;
  2019. double y = strtod(buf, &endptr);
  2020. if (endptr == 0 || *endptr != 0) {
  2021.     ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", buf);
  2022.     return false;
  2023. } else if (errno != 0) {
  2024.     ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2025.     return false;
  2026. }
  2027. // XXX should handle 123.000
  2028. ctx.pushStatus(Sqlstate::_01004, Error::Gen, "value %s truncated", buf);
  2029. x = static_cast<long>(y);
  2030.     } else if (errno != 0) {
  2031. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2032. return false;
  2033.     }
  2034.     *ptr = x;
  2035.     return true;
  2036. }
  2037. static bool
  2038. copyout_char_unsigned(Ctx& ctx, const char* value, unsigned n, unsigned long* ptr)
  2039. {
  2040.     while (n > 0 && value[0] == 0x20) {
  2041. value++;
  2042. n--;
  2043.     }
  2044.     char buf[200];
  2045.     if (n >= 200)
  2046. n = 200 - 1;
  2047.     memcpy(buf, value, n);
  2048.     buf[n] = 0;
  2049.     errno = 0;
  2050.     char* endptr = 0;
  2051.     unsigned long x = strtoul(buf, &endptr, 10);
  2052.     if (endptr == 0 || *endptr != 0) {
  2053. errno = 0;
  2054. endptr = 0;
  2055. double y = strtod(buf, &endptr);
  2056. if (endptr == 0 || *endptr != 0) {
  2057.     ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", buf);
  2058.     return false;
  2059. } else if (errno != 0) {
  2060.     ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2061.     return false;
  2062. }
  2063. // XXX should handle 123.000
  2064. ctx.pushStatus(Sqlstate::_01004, Error::Gen, "value %s truncated", buf);
  2065. x = static_cast<unsigned long>(y);
  2066.     } else if (errno != 0) {
  2067. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2068. return false;
  2069.     }
  2070.     *ptr = x;
  2071.     return true;
  2072. }
  2073. static bool
  2074. copyout_char_bigunsigned(Ctx& ctx, const char* value, unsigned n, SQLUBIGINT* ptr)
  2075. {
  2076.     while (n > 0 && value[0] == 0x20) {
  2077. value++;
  2078. n--;
  2079.     }
  2080.     char buf[200];
  2081.     if (n >= 200)
  2082. n = 200 - 1;
  2083.     memcpy(buf, value, n);
  2084.     buf[n] = 0;
  2085.     errno = 0;
  2086.     char* endptr = 0;
  2087.     SQLUBIGINT x = strtoull(buf, &endptr, 10);
  2088.     if (endptr == 0 || *endptr != 0) {
  2089. errno = 0;
  2090. endptr = 0;
  2091. double y = strtod(buf, &endptr);
  2092. if (endptr == 0 || *endptr != 0) {
  2093.     ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", buf);
  2094.     return false;
  2095. } else if (errno != 0) {
  2096.     ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2097.     return false;
  2098. }
  2099. // XXX should handle 123.000
  2100. ctx.pushStatus(Sqlstate::_01004, Error::Gen, "value %s truncated", buf);
  2101. x = static_cast<unsigned long>(y);
  2102.     } else if (errno != 0) {
  2103. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2104. return false;
  2105.     }
  2106.     *ptr = x;
  2107.     return true;
  2108. }
  2109. static bool
  2110. copyout_char_double(Ctx& ctx, const char* value, unsigned n, double* ptr)
  2111. {
  2112.     while (n > 0 && value[0] == 0x20) {
  2113. value++;
  2114. n--;
  2115.     }
  2116.     char buf[200];
  2117.     if (n >= 200)
  2118. n = 200 - 1;
  2119.     memcpy(buf, value, n);
  2120.     buf[n] = 0;
  2121.     errno = 0;
  2122.     char* endptr = 0;
  2123.     double x = strtod(value, &endptr);
  2124.     if (endptr == 0 || *endptr != 0) {
  2125. ctx.pushStatus(Sqlstate::_22005, Error::Gen, "value %s not numeric", value);
  2126. return false;
  2127.     } else if (errno != 0) {
  2128. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", value);
  2129. return false;
  2130.     }
  2131.     *ptr = x;
  2132.     return true;
  2133. }
  2134. static bool
  2135. copyout_signed_char(Ctx& ctx, Int64 value, char* ptr, int len, SQLINTEGER* ind)
  2136. {
  2137.     char buf[100];
  2138.     sprintf(buf, FMT_I64, value);
  2139.     unsigned n = strlen(buf);
  2140.     if (len <= 0) {
  2141. ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", len);
  2142. return false;
  2143.     }
  2144.     if ((unsigned)len < n + 1) { // room for null byte
  2145. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2146. return false;
  2147.     }
  2148.     strcpy(ptr, buf);
  2149.     if (ind != 0)
  2150. *ind = n;
  2151.     return true;
  2152. }
  2153. static bool
  2154. copyout_unsigned_char(Ctx& ctx, Uint64 uvalue, char* ptr, int len, SQLINTEGER* ind)
  2155. {
  2156.     char buf[100];
  2157.     sprintf(buf, FMT_U64, uvalue);
  2158.     unsigned n = strlen(buf);
  2159.     if (len <= 0) {
  2160. ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", len);
  2161. return false;
  2162.     }
  2163.     if ((unsigned)len < n + 1) { // room for null byte
  2164. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2165. return false;
  2166.     }
  2167.     strcpy(ptr, buf);
  2168.     if (ind != 0)
  2169. *ind = n;
  2170.     return true;
  2171. }
  2172. static bool
  2173. copyout_double_char(Ctx& ctx, double value, unsigned prec, char* ptr, int len, SQLINTEGER* ind)
  2174. {
  2175.     char buf[100];
  2176.     sprintf(buf, "%.*f", (int)prec, value);
  2177.     char* p = buf + strlen(buf);
  2178.     while (p > buf + prec)
  2179. *--p = 0;
  2180.     while (p > buf && *(p - 1) == '0')
  2181. *--p = 0;
  2182.     if (p > buf && *(p - 1) == '.') {
  2183. *p++ = '0';
  2184. *p = 0;
  2185.     }
  2186.     unsigned n = strlen(buf);
  2187.     if (len <= 0) {
  2188. ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", len);
  2189. return false;
  2190.     }
  2191.     if ((unsigned)len  < n + 1) { // room for null byte
  2192. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", buf);
  2193. return false;
  2194.     }
  2195.     strcpy(ptr, buf);
  2196.     if (ind != 0)
  2197. *ind = n;
  2198.     return true;
  2199. }
  2200. void
  2201. SqlField::copyout(Ctx& ctx, ExtField& extField) const
  2202. {
  2203.     if (extField.extSpec().extType().type() == ExtType::Unbound) {
  2204. return; // output buffer may be unbound
  2205.     }
  2206.     if (sqlSpec().store() == SqlSpec::Reference) {
  2207. ctx_assert(u_data.m_sqlField != 0);
  2208. u_data.m_sqlField->copyout(ctx, extField);
  2209. return;
  2210.     }
  2211.     SQLINTEGER* indPtr = extField.m_indPtr;
  2212.     if (u_null.m_nullFlag) {
  2213. if (extField.m_pos > 0) { // second time from SQLGetData
  2214.     ctx.setCode(SQL_NO_DATA);
  2215.     return;
  2216. }
  2217. if (indPtr == 0) {
  2218.     ctx.pushStatus(Sqlstate::_22002, Error::Gen, "indicator variable required");
  2219.     return;
  2220. }
  2221. *indPtr = SQL_NULL_DATA;
  2222. if (extField.m_pos >= 0)
  2223.     extField.m_pos = 1;
  2224. return;
  2225.     }
  2226.     const SqlType& sqlType = sqlSpec().sqlType();
  2227.     const ExtType& extType = extField.extSpec().extType();
  2228.     if (sqlType.type() == SqlType::Char || sqlType.type() == SqlType::Varchar) {
  2229. unsigned n = 0;
  2230. const char* value = 0;
  2231. if (sqlType.type() == SqlType::Char) {
  2232.     n = sqlType.length();
  2233.     value = reinterpret_cast<const char*>(sqlChar());
  2234. } else {
  2235.     value = reinterpret_cast<const char*>(sqlVarchar(&n));
  2236. }
  2237. if (extType.type() == ExtType::Char) {
  2238.     char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  2239.     if (extField.m_dataLen <= 0) {
  2240. ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", (int)extField.m_dataLen);
  2241. return;
  2242.     }
  2243.     int* off = 0;
  2244.     if (extField.m_pos >= 0) {
  2245. off = &extField.m_pos;
  2246. if ((unsigned)*off >= n) {
  2247.     ctx.setCode(SQL_NO_DATA);
  2248.     return;
  2249. }
  2250.     }
  2251.     if (! copyout_char_char(ctx, value, n, dataPtr, extField.m_dataLen, indPtr, off))
  2252. return;
  2253.     return;
  2254. }
  2255. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  2256.     if (extField.m_pos > 0) {
  2257. ctx.setCode(SQL_NO_DATA);
  2258. return;
  2259.     }
  2260.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  2261.     long x;
  2262.     if (! copyout_char_signed(ctx, value, n, &x))
  2263. return;
  2264.     if (x < SHRT_MIN || x > SHRT_MAX) {
  2265. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", value);
  2266. return;
  2267.     }
  2268.     *dataPtr = static_cast<short>(x);
  2269.     if (indPtr != 0)
  2270. *indPtr = sizeof(short);
  2271.     if (extField.m_pos >= 0)
  2272. extField.m_pos = 1;
  2273.     return;
  2274. }
  2275. if (extType.type() == ExtType::Ushort) {
  2276.     if (extField.m_pos > 0) {
  2277. ctx.setCode(SQL_NO_DATA);
  2278. return;
  2279.     }
  2280.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  2281.     unsigned long x;
  2282.     if (! copyout_char_unsigned(ctx, value, n, &x))
  2283. return;
  2284.     if (x > USHRT_MAX) {
  2285. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", value);
  2286. return;
  2287.     }
  2288.     *dataPtr = static_cast<unsigned short>(x);
  2289.     if (indPtr != 0)
  2290. *indPtr = sizeof(unsigned short);
  2291.     if (extField.m_pos >= 0)
  2292. extField.m_pos = 1;
  2293.     return;
  2294. }
  2295. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  2296.     if (extField.m_pos > 0) {
  2297. ctx.setCode(SQL_NO_DATA);
  2298. return;
  2299.     }
  2300.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  2301.     if (! copyout_char_signed(ctx, value, n, dataPtr))
  2302. return;
  2303.     if (indPtr != 0)
  2304. *indPtr = sizeof(long);
  2305.     if (extField.m_pos >= 0)
  2306. extField.m_pos = 1;
  2307.     return;
  2308. }
  2309. if (extType.type() == ExtType::Ulong) {
  2310.     if (extField.m_pos > 0) {
  2311. ctx.setCode(SQL_NO_DATA);
  2312. return;
  2313.     }
  2314.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  2315.     if (! copyout_char_unsigned(ctx, value, n, dataPtr))
  2316. return;
  2317.     if (indPtr != 0)
  2318. *indPtr = sizeof(unsigned long);
  2319.     if (extField.m_pos >= 0)
  2320. extField.m_pos = 1;
  2321.     return;
  2322. }
  2323. if (extType.type() == ExtType::Sbigint) {
  2324.     if (extField.m_pos > 0) {
  2325. ctx.setCode(SQL_NO_DATA);
  2326. return;
  2327.     }
  2328.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  2329.     if (! copyout_char_bigsigned(ctx, value, n, dataPtr))
  2330. return;
  2331.     if (indPtr != 0)
  2332. *indPtr = sizeof(SQLBIGINT);
  2333.     if (extField.m_pos >= 0)
  2334. extField.m_pos = 1;
  2335.     return;
  2336. }
  2337. if (extType.type() == ExtType::Ubigint) {
  2338.     if (extField.m_pos > 0) {
  2339. ctx.setCode(SQL_NO_DATA);
  2340. return;
  2341.     }
  2342.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  2343.     if (! copyout_char_bigunsigned(ctx, value, n, dataPtr))
  2344. return;
  2345.     if (indPtr != 0)
  2346. *indPtr = sizeof(SQLUBIGINT);
  2347.     if (extField.m_pos >= 0)
  2348. extField.m_pos = 1;
  2349.     return;
  2350. }
  2351. if (extType.type() == ExtType::Float) {
  2352.     if (extField.m_pos > 0) {
  2353. ctx.setCode(SQL_NO_DATA);
  2354. return;
  2355.     }
  2356.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  2357.     double x;
  2358.     if (! copyout_char_double(ctx, value, n, &x))
  2359. return;
  2360.     if (fabs(x) < FLT_MIN || fabs(x) > FLT_MAX) {
  2361. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %s overflow", value);
  2362. return;
  2363.     }
  2364.     *dataPtr = static_cast<float>(x);
  2365.     if (indPtr != 0)
  2366. *indPtr = sizeof(float);
  2367.     if (extField.m_pos >= 0)
  2368. extField.m_pos = 1;
  2369.     return;
  2370. }
  2371. if (extType.type() == ExtType::Double) {
  2372.     if (extField.m_pos > 0) {
  2373. ctx.setCode(SQL_NO_DATA);
  2374. return;
  2375.     }
  2376.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  2377.     double x;
  2378.     if (! copyout_char_double(ctx, value, n, &x))
  2379. return;
  2380.     *dataPtr = static_cast<double>(x);
  2381.     if (indPtr != 0)
  2382. *indPtr = sizeof(double);
  2383.     if (extField.m_pos >= 0)
  2384. extField.m_pos = 1;
  2385.     return;
  2386. }
  2387.     }
  2388.     if (sqlType.type() == SqlType::Binary || sqlType.type() == SqlType::Varbinary) {
  2389. unsigned n = 0;
  2390. const char* value = 0;
  2391. if (sqlType.type() == SqlType::Binary) {
  2392.     n = sqlType.length();
  2393.     value = reinterpret_cast<const char*>(sqlBinary());
  2394. } else {
  2395.     value = reinterpret_cast<const char*>(sqlVarbinary(&n));
  2396. }
  2397. if (extType.type() == ExtType::Binary) {
  2398.     char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  2399.     if (extField.m_dataLen <= 0) {
  2400. ctx.pushStatus(Sqlstate::_HY090, Error::Gen, "invalid output buffer length %d", (int)extField.m_dataLen);
  2401. return;
  2402.     }
  2403.     int* off = 0;
  2404.     if (extField.m_pos >= 0) {
  2405. off = &extField.m_pos;
  2406. if ((unsigned)*off >= n) {
  2407.     ctx.setCode(SQL_NO_DATA);
  2408.     return;
  2409. }
  2410.     }
  2411.     if (! copyout_binary_binary(ctx, value, n, dataPtr, extField.m_dataLen, indPtr, off))
  2412. return;
  2413.     return;
  2414. }
  2415.     }
  2416.     if (sqlType.type() == SqlType::Smallint) {
  2417. if (extField.m_pos > 0) {
  2418.     ctx.setCode(SQL_NO_DATA);
  2419.     return;
  2420. }
  2421. const SqlSmallint value = sqlSmallint();
  2422. const SqlUsmallint uvalue = value;
  2423. if (extType.type() == ExtType::Char) {
  2424.     char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  2425.     if (! sqlType.unSigned()) {
  2426. if (! copyout_signed_char(ctx, value, dataPtr, extField.m_dataLen, indPtr))
  2427.     return;
  2428.     } else {
  2429. if (! copyout_unsigned_char(ctx, uvalue, dataPtr, extField.m_dataLen, indPtr))
  2430.     return;
  2431.     }
  2432.     if (extField.m_pos >= 0)
  2433. extField.m_pos = 1;
  2434.     return;
  2435. }
  2436. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  2437.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  2438.     *dataPtr = static_cast<short>(value); // big enough
  2439.     if (indPtr != 0)
  2440. *indPtr = sizeof(short);
  2441.     if (extField.m_pos >= 0)
  2442. extField.m_pos = 1;
  2443.     return;
  2444. }
  2445. if (extType.type() == ExtType::Ushort) {
  2446.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  2447.     *dataPtr = static_cast<unsigned short>(uvalue);
  2448.     if (indPtr != 0)
  2449. *indPtr = sizeof(unsigned short);
  2450.     if (extField.m_pos >= 0)
  2451. extField.m_pos = 1;
  2452.     return;
  2453. }
  2454. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  2455.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  2456.     *dataPtr = static_cast<long>(value); // big enough
  2457.     if (indPtr != 0)
  2458. *indPtr = sizeof(long);
  2459.     if (extField.m_pos >= 0)
  2460. extField.m_pos = 1;
  2461.     return;
  2462. }
  2463. if (extType.type() == ExtType::Ulong) {
  2464.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  2465.     *dataPtr = static_cast<unsigned long>(uvalue);
  2466.     if (indPtr != 0)
  2467. *indPtr = sizeof(unsigned long);
  2468.     if (extField.m_pos >= 0)
  2469. extField.m_pos = 1;
  2470.     return;
  2471. }
  2472. if (extType.type() == ExtType::Sbigint) {
  2473.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  2474.     *dataPtr = static_cast<SQLBIGINT>(value); // big enough
  2475.     if (indPtr != 0)
  2476. *indPtr = sizeof(SQLBIGINT);
  2477.     if (extField.m_pos >= 0)
  2478. extField.m_pos = 1;
  2479.     return;
  2480. }
  2481. if (extType.type() == ExtType::Ubigint) {
  2482.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  2483.     *dataPtr = static_cast<SQLUBIGINT>(uvalue);
  2484.     if (indPtr != 0)
  2485. *indPtr = sizeof(SQLUBIGINT);
  2486.     if (extField.m_pos >= 0)
  2487. extField.m_pos = 1;
  2488.     return;
  2489. }
  2490. if (extType.type() == ExtType::Float) {
  2491.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  2492.     *dataPtr = static_cast<float>(value); // big enough
  2493.     if (indPtr != 0)
  2494. *indPtr = sizeof(float);
  2495.     if (extField.m_pos >= 0)
  2496. extField.m_pos = 1;
  2497.     return;
  2498. }
  2499. if (extType.type() == ExtType::Double) {
  2500.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  2501.     *dataPtr = static_cast<double>(value); // big enough
  2502.     if (indPtr != 0)
  2503. *indPtr = sizeof(double);
  2504.     if (extField.m_pos >= 0)
  2505. extField.m_pos = 1;
  2506.     return;
  2507. }
  2508.     }
  2509.     if (sqlType.type() == SqlType::Integer) {
  2510. if (extField.m_pos > 0) {
  2511.     ctx.setCode(SQL_NO_DATA);
  2512.     return;
  2513. }
  2514. const SqlInteger value = sqlInteger();
  2515. const SqlUinteger uvalue = value;
  2516. if (extType.type() == ExtType::Char) {
  2517.     char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  2518.     if (! sqlType.unSigned()) {
  2519. if (! copyout_signed_char(ctx, value, dataPtr, extField.m_dataLen, indPtr))
  2520.     return;
  2521.     } else {
  2522. if (! copyout_unsigned_char(ctx, uvalue, dataPtr, extField.m_dataLen, indPtr))
  2523.     return;
  2524.     }
  2525.     if (extField.m_pos >= 0)
  2526. extField.m_pos = 1;
  2527.     return;
  2528. }
  2529. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  2530.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  2531.     if (value < SHRT_MIN || value > SHRT_MAX) {
  2532. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %d overflow", (int)value);
  2533. return;
  2534.     }
  2535.     *dataPtr = static_cast<short>(value);
  2536.     if (indPtr != 0)
  2537. *indPtr = sizeof(short);
  2538.     if (extField.m_pos >= 0)
  2539. extField.m_pos = 1;
  2540.     return;
  2541. }
  2542. if (extType.type() == ExtType::Ushort) {
  2543.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  2544.     if (uvalue > USHRT_MAX) {
  2545. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %u overflow", uvalue);
  2546. return;
  2547.     }
  2548.     *dataPtr = static_cast<unsigned short>(value);
  2549.     if (indPtr != 0)
  2550. *indPtr = sizeof(unsigned short);
  2551.     if (extField.m_pos >= 0)
  2552. extField.m_pos = 1;
  2553.     return;
  2554. }
  2555. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  2556.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  2557.     *dataPtr = static_cast<long>(value); // big enough
  2558.     if (indPtr != 0)
  2559. *indPtr = sizeof(long);
  2560.     if (extField.m_pos >= 0)
  2561. extField.m_pos = 1;
  2562.     return;
  2563. }
  2564. if (extType.type() == ExtType::Ulong) {
  2565.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  2566.     *dataPtr = static_cast<unsigned long>(uvalue);
  2567.     if (indPtr != 0)
  2568. *indPtr = sizeof(unsigned long);
  2569.     if (extField.m_pos >= 0)
  2570. extField.m_pos = 1;
  2571.     return;
  2572. }
  2573. if (extType.type() == ExtType::Sbigint) {
  2574.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  2575.     *dataPtr = static_cast<SQLBIGINT>(value); // big enough
  2576.     if (indPtr != 0)
  2577. *indPtr = sizeof(SQLBIGINT);
  2578.     if (extField.m_pos >= 0)
  2579. extField.m_pos = 1;
  2580.     return;
  2581. }
  2582. if (extType.type() == ExtType::Ubigint) {
  2583.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  2584.     *dataPtr = static_cast<SQLUBIGINT>(uvalue);
  2585.     if (indPtr != 0)
  2586. *indPtr = sizeof(SQLUBIGINT);
  2587.     if (extField.m_pos >= 0)
  2588. extField.m_pos = 1;
  2589.     return;
  2590. }
  2591. if (extType.type() == ExtType::Float) {
  2592.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  2593.     *dataPtr = static_cast<float>(value); // big enough
  2594.     if (indPtr != 0)
  2595. *indPtr = sizeof(float);
  2596.     if (extField.m_pos >= 0)
  2597. extField.m_pos = 1;
  2598.     return;
  2599. }
  2600. if (extType.type() == ExtType::Double) {
  2601.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  2602.     *dataPtr = static_cast<double>(value); // big enough
  2603.     if (indPtr != 0)
  2604. *indPtr = sizeof(double);
  2605.     if (extField.m_pos >= 0)
  2606. extField.m_pos = 1;
  2607.     return;
  2608. }
  2609.     }
  2610.     if (sqlType.type() == SqlType::Bigint) {
  2611. if (extField.m_pos > 0) {
  2612.     ctx.setCode(SQL_NO_DATA);
  2613.     return;
  2614. }
  2615. const SqlBigint value = sqlBigint();
  2616. const SqlUbigint uvalue = value;
  2617. if (extType.type() == ExtType::Char) {
  2618.     char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  2619.     if (! sqlType.unSigned()) {
  2620. if (! copyout_signed_char(ctx, value, dataPtr, extField.m_dataLen, indPtr))
  2621.     return;
  2622.     } else {
  2623. if (! copyout_unsigned_char(ctx, uvalue, dataPtr, extField.m_dataLen, indPtr))
  2624.     return;
  2625.     }
  2626.     if (extField.m_pos >= 0)
  2627. extField.m_pos = 1;
  2628.     return;
  2629. }
  2630. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  2631.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  2632.     if (value < SHRT_MIN || value > SHRT_MAX) {
  2633. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value " FMT_I64 " overflow", (Int64)value);
  2634. return;
  2635.     }
  2636.     *dataPtr = static_cast<short>(value);
  2637.     if (indPtr != 0)
  2638. *indPtr = sizeof(short);
  2639.     if (extField.m_pos >= 0)
  2640. extField.m_pos = 1;
  2641.     return;
  2642. }
  2643. if (extType.type() == ExtType::Ushort) {
  2644.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  2645.     if (uvalue > USHRT_MAX) {
  2646. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value " FMT_U64 " overflow", (Uint64)uvalue);
  2647. return;
  2648.     }
  2649.     *dataPtr = static_cast<short>(value);
  2650.     if (indPtr != 0)
  2651. *indPtr = sizeof(unsigned short);
  2652.     if (extField.m_pos >= 0)
  2653. extField.m_pos = 1;
  2654.     return;
  2655. }
  2656. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  2657.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  2658.     if (value < INT_MIN || value > INT_MAX) {
  2659. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value " FMT_I64 " overflow", (Int64)value);
  2660. return;
  2661.     }
  2662.     *dataPtr = static_cast<long>(value);
  2663.     if (indPtr != 0)
  2664. *indPtr = sizeof(long);
  2665.     if (extField.m_pos >= 0)
  2666. extField.m_pos = 1;
  2667.     return;
  2668. }
  2669. if (extType.type() == ExtType::Ulong) {
  2670.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  2671.     if (uvalue > UINT_MAX) {
  2672. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value " FMT_U64 " overflow", (Uint64)uvalue);
  2673. return;
  2674.     }
  2675.     *dataPtr = static_cast<unsigned long>(uvalue);
  2676.     if (indPtr != 0)
  2677. *indPtr = sizeof(unsigned long);
  2678.     if (extField.m_pos >= 0)
  2679. extField.m_pos = 1;
  2680.     return;
  2681. }
  2682. if (extType.type() == ExtType::Sbigint) {
  2683.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  2684.     *dataPtr = static_cast<SQLBIGINT>(value); // big enough
  2685.     if (indPtr != 0)
  2686. *indPtr = sizeof(SQLBIGINT);
  2687.     if (extField.m_pos >= 0)
  2688. extField.m_pos = 1;
  2689.     return;
  2690. }
  2691. if (extType.type() == ExtType::Ubigint) {
  2692.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  2693.     *dataPtr = static_cast<SQLUBIGINT>(uvalue);
  2694.     if (indPtr != 0)
  2695. *indPtr = sizeof(SQLUBIGINT);
  2696.     if (extField.m_pos >= 0)
  2697. extField.m_pos = 1;
  2698.     return;
  2699. }
  2700. if (extType.type() == ExtType::Float) {
  2701.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  2702.     *dataPtr = static_cast<float>(value); // big enough
  2703.     if (indPtr != 0)
  2704. *indPtr = sizeof(float);
  2705.     if (extField.m_pos >= 0)
  2706. extField.m_pos = 1;
  2707.     return;
  2708. }
  2709. if (extType.type() == ExtType::Double) {
  2710.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  2711.     *dataPtr = static_cast<double>(value); // big enough
  2712.     if (indPtr != 0)
  2713. *indPtr = sizeof(double);
  2714.     if (extField.m_pos >= 0)
  2715. extField.m_pos = 1;
  2716.     return;
  2717. }
  2718.     }
  2719.     if (sqlType.type() == SqlType::Real) {
  2720. if (extField.m_pos > 0) {
  2721.     ctx.setCode(SQL_NO_DATA);
  2722.     return;
  2723. }
  2724. const SqlReal value = sqlReal();
  2725. if (extType.type() == ExtType::Char) {
  2726.     char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  2727.     if (! copyout_double_char(ctx, value, 7, dataPtr, extField.m_dataLen, indPtr))
  2728. return;
  2729.     if (extField.m_pos >= 0)
  2730. extField.m_pos = 1;
  2731.     return;
  2732. }
  2733. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  2734.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  2735.     *dataPtr = static_cast<short>(value); // XXX todo
  2736.     if (indPtr != 0)
  2737. *indPtr = sizeof(short);
  2738.     if (extField.m_pos >= 0)
  2739. extField.m_pos = 1;
  2740.     return;
  2741. }
  2742. if (extType.type() == ExtType::Ushort) {
  2743.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  2744.     if (value < 0 || value > USHRT_MAX) {
  2745. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %g overflow", (double)value);
  2746. return;
  2747.     }
  2748.     *dataPtr = static_cast<short>(value);
  2749.     if (indPtr != 0)
  2750. *indPtr = sizeof(unsigned short);
  2751.     if (extField.m_pos >= 0)
  2752. extField.m_pos = 1;
  2753.     return;
  2754. }
  2755. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  2756.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  2757.     *dataPtr = static_cast<long>(value); // big enough
  2758.     if (indPtr != 0)
  2759. *indPtr = sizeof(long);
  2760.     if (extField.m_pos >= 0)
  2761. extField.m_pos = 1;
  2762.     return;
  2763. }
  2764. if (extType.type() == ExtType::Ulong) {
  2765.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  2766.     *dataPtr = static_cast<unsigned long>(value); // XXX todo
  2767.     if (indPtr != 0)
  2768. *indPtr = sizeof(unsigned long);
  2769.     if (extField.m_pos >= 0)
  2770. extField.m_pos = 1;
  2771.     return;
  2772. }
  2773. if (extType.type() == ExtType::Sbigint) {
  2774.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  2775.     *dataPtr = static_cast<SQLBIGINT>(value); // big enough
  2776.     if (indPtr != 0)
  2777. *indPtr = sizeof(SQLBIGINT);
  2778.     if (extField.m_pos >= 0)
  2779. extField.m_pos = 1;
  2780.     return;
  2781. }
  2782. if (extType.type() == ExtType::Ubigint) {
  2783.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  2784.     *dataPtr = static_cast<SQLUBIGINT>(value);
  2785.     if (indPtr != 0)
  2786. *indPtr = sizeof(SQLUBIGINT);
  2787.     if (extField.m_pos >= 0)
  2788. extField.m_pos = 1;
  2789.     return;
  2790. }
  2791. if (extType.type() == ExtType::Float) {
  2792.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  2793.     *dataPtr = static_cast<float>(value); // big enough
  2794.     if (indPtr != 0)
  2795. *indPtr = sizeof(float);
  2796.     if (extField.m_pos >= 0)
  2797. extField.m_pos = 1;
  2798.     return;
  2799. }
  2800. if (extType.type() == ExtType::Double) {
  2801.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  2802.     *dataPtr = static_cast<double>(value); // big enough
  2803.     if (indPtr != 0)
  2804. *indPtr = sizeof(double);
  2805.     if (extField.m_pos >= 0)
  2806. extField.m_pos = 1;
  2807.     return;
  2808. }
  2809.     }
  2810.     if (sqlType.type() == SqlType::Double) {
  2811. if (extField.m_pos > 0) {
  2812.     ctx.setCode(SQL_NO_DATA);
  2813.     return;
  2814. }
  2815. SqlDouble value = sqlDouble();
  2816. if (extType.type() == ExtType::Char) {
  2817.     char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  2818.     if (! copyout_double_char(ctx, value, 14, dataPtr, extField.m_dataLen, indPtr))
  2819. return;
  2820.     if (extField.m_pos >= 0)
  2821. extField.m_pos = 1;
  2822.     return;
  2823. }
  2824. if (extType.type() == ExtType::Short || extType.type() == ExtType::Sshort) {
  2825.     short* dataPtr = static_cast<short*>(extField.m_dataPtr);
  2826.     *dataPtr = static_cast<short>(value); // XXX todo
  2827.     if (indPtr != 0)
  2828. *indPtr = sizeof(short);
  2829.     if (extField.m_pos >= 0)
  2830. extField.m_pos = 1;
  2831.     return;
  2832. }
  2833. if (extType.type() == ExtType::Ushort) {
  2834.     unsigned short* dataPtr = static_cast<unsigned short*>(extField.m_dataPtr);
  2835.     if (value < 0 || value > USHRT_MAX) {
  2836. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "value %g overflow", (double)value);
  2837. return;
  2838.     }
  2839.     *dataPtr = static_cast<short>(value);
  2840.     if (indPtr != 0)
  2841. *indPtr = sizeof(unsigned short);
  2842.     if (extField.m_pos >= 0)
  2843. extField.m_pos = 1;
  2844.     return;
  2845. }
  2846. if (extType.type() == ExtType::Long || extType.type() == ExtType::Slong) {
  2847.     long* dataPtr = static_cast<long*>(extField.m_dataPtr);
  2848.     *dataPtr = static_cast<long>(value); // big enough
  2849.     if (indPtr != 0)
  2850. *indPtr = sizeof(long);
  2851.     if (extField.m_pos >= 0)
  2852. extField.m_pos = 1;
  2853.     return;
  2854. }
  2855. if (extType.type() == ExtType::Ulong) {
  2856.     unsigned long* dataPtr = static_cast<unsigned long*>(extField.m_dataPtr);
  2857.     *dataPtr = static_cast<unsigned long>(value); // XXX todo
  2858.     if (indPtr != 0)
  2859. *indPtr = sizeof(unsigned long);
  2860.     if (extField.m_pos >= 0)
  2861. extField.m_pos = 1;
  2862.     return;
  2863. }
  2864. if (extType.type() == ExtType::Sbigint) {
  2865.     SQLBIGINT* dataPtr = static_cast<SQLBIGINT*>(extField.m_dataPtr);
  2866.     *dataPtr = static_cast<SQLBIGINT>(value); // big enough
  2867.     if (indPtr != 0)
  2868. *indPtr = sizeof(SQLBIGINT);
  2869.     if (extField.m_pos >= 0)
  2870. extField.m_pos = 1;
  2871.     return;
  2872. }
  2873. if (extType.type() == ExtType::Ubigint) {
  2874.     SQLUBIGINT* dataPtr = static_cast<SQLUBIGINT*>(extField.m_dataPtr);
  2875.     *dataPtr = static_cast<SQLUBIGINT>(value);
  2876.     if (indPtr != 0)
  2877. *indPtr = sizeof(SQLUBIGINT);
  2878.     if (extField.m_pos >= 0)
  2879. extField.m_pos = 1;
  2880.     return;
  2881. }
  2882. if (extType.type() == ExtType::Float) {
  2883.     float* dataPtr = static_cast<float*>(extField.m_dataPtr);
  2884.     *dataPtr = static_cast<float>(value); // big enough
  2885.     if (indPtr != 0)
  2886. *indPtr = sizeof(float);
  2887.     if (extField.m_pos >= 0)
  2888. extField.m_pos = 1;
  2889.     return;
  2890. }
  2891. if (extType.type() == ExtType::Double) {
  2892.     double* dataPtr = static_cast<double*>(extField.m_dataPtr);
  2893.     *dataPtr = static_cast<double>(value);
  2894.     if (indPtr != 0)
  2895. *indPtr = sizeof(double);
  2896.     if (extField.m_pos >= 0)
  2897. extField.m_pos = 1;
  2898.     return;
  2899. }
  2900.     }
  2901.     if (sqlType.type() == SqlType::Datetime) {
  2902. if (extField.m_pos > 0) {
  2903.     ctx.setCode(SQL_NO_DATA);
  2904.     return;
  2905. }
  2906. SqlDatetime value = sqlDatetime();
  2907. if (extType.type() == ExtType::Char) {
  2908.     char* dataPtr = static_cast<char*>(extField.m_dataPtr);
  2909.     char buf[100];
  2910.     sprintf(buf, "%02d%02u-%02u-%02u40%02u:%02u:%02u.%09u", value.cc(), value.yy(), value.mm(), value.dd(), value.HH(), value.MM(), value.SS(), value.ff());
  2911.     int n = strlen(buf);
  2912.     if (extField.m_dataLen < 20) {
  2913. ctx.pushStatus(Sqlstate::_22003, Error::Gen, "buffer too small for timestamp %s", buf);
  2914. return;
  2915.     }
  2916.     if (extField.m_dataLen < n) {
  2917. ctx.pushStatus(Sqlstate::_01004, Error::Gen, "truncating fractional part of timestamp %s", buf);
  2918. n = extField.m_dataLen;
  2919.     }
  2920.     if (! copyout_char_char(ctx, buf, n, dataPtr, extField.m_dataLen, indPtr, 0))
  2921. return;
  2922.     if (extField.m_pos >= 0)
  2923. extField.m_pos = 1;
  2924.     return;
  2925. }
  2926. if (extType.type() == ExtType::Timestamp) {
  2927.     SQL_TIMESTAMP_STRUCT* dataPtr = static_cast<SQL_TIMESTAMP_STRUCT*>(extField.m_dataPtr);
  2928.     // XXX assume same datatype
  2929.     dataPtr->year = value.cc() * 100 + value.yy();
  2930.     dataPtr->month = value.mm();
  2931.     dataPtr->day = value.dd();
  2932.     dataPtr->hour = value.HH();
  2933.     dataPtr->minute = value.MM();
  2934.     dataPtr->second = value.SS();
  2935.     dataPtr->fraction = value.ff();
  2936.     return;
  2937. }
  2938.     }
  2939.     ctx_assert(false); // SqlType::Null not applicable
  2940. }
  2941. void
  2942. SqlField::print(char* buf, unsigned size) const
  2943. {
  2944.     Ctx ctx;
  2945.     unsigned n = sqlSpec().sqlType().displaySize();
  2946.     SQLINTEGER ind = 0;
  2947.     ExtType extType(ExtType::Char);
  2948.     ExtSpec extSpec(extType);
  2949.     ExtField extField(extSpec, (SQLPOINTER)buf, size, &ind);
  2950.     buf[0] = 0;
  2951.     copyout(ctx, extField);
  2952.     if (ind == SQL_NULL_DATA)
  2953. snprintf(buf, size, "NULL");
  2954. }