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

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 <NdbApi.hpp>
  14. #include <common/ResultArea.hpp>
  15. #include <codegen/Code_query_sys.hpp>
  16. #include <codegen/Code_table.hpp>
  17. #define NULL_CHAR ((char*)0)
  18. #define NULL_INT (-2147483647)
  19. struct Typeinfo {
  20.     const char* m_type_name; // 1
  21.     int m_data_type; // 2
  22.     int m_column_size; // 3
  23.     const char* m_literal_prefix; // 4
  24.     const char* m_literal_suffix; // 5
  25.     const char* m_create_params; // 6
  26.     int m_nullable; // 7
  27.     int m_case_sensitive; // 8
  28.     int m_searchable; // 9
  29.     int m_unsigned_attribute; // 10
  30.     int m_fixed_prec_scale; // 11
  31.     int m_auto_unique_value; // 12
  32.     const char* m_local_type_name; // 13
  33.     int m_minimum_scale; // 14
  34.     int m_maximum_scale; // 15
  35.     int m_sql_data_type; // 16
  36.     int m_sql_datetime_sub; // 17
  37.     int m_num_prec_radix; // 18
  38.     int m_interval_precision; // 19
  39. };
  40. static const Typeinfo
  41. typeinfoList[] = {
  42.     { "CHAR", // 1
  43. SQL_CHAR, // 2
  44. 8000, // 3
  45. "'", // 4
  46. "'", // 5
  47. "length", // 6
  48. SQL_NULLABLE, // 7
  49. SQL_TRUE, // 8
  50. SQL_SEARCHABLE, // 9
  51. NULL_INT, // 10
  52. SQL_FALSE, // 11
  53. NULL_INT, // 12
  54. NULL_CHAR, // 13
  55. NULL_INT, // 14
  56. NULL_INT, // 15
  57. SQL_CHAR, // 16
  58. NULL_INT, // 17
  59. NULL_INT, // 18
  60. NULL_INT // 19
  61.     },
  62.     { "VARCHAR", // 1
  63. SQL_VARCHAR, // 2
  64. 8000, // 3
  65. "'", // 4
  66. "'", // 5
  67. "length", // 6
  68. SQL_NULLABLE, // 7
  69. SQL_TRUE, // 8
  70. SQL_SEARCHABLE, // 9
  71. NULL_INT, // 10
  72. SQL_FALSE, // 11
  73. NULL_INT, // 12
  74. NULL_CHAR, // 13
  75. NULL_INT, // 14
  76. NULL_INT, // 15
  77. SQL_VARCHAR, // 16
  78. NULL_INT, // 17
  79. NULL_INT, // 18
  80. NULL_INT // 19
  81.     },
  82.     { "BINARY", // 1
  83. SQL_BINARY, // 2
  84. 8000, // 3
  85. "'", // 4
  86. "'", // 5
  87. "length", // 6
  88. SQL_NULLABLE, // 7
  89. SQL_TRUE, // 8
  90. SQL_SEARCHABLE, // 9
  91. NULL_INT, // 10
  92. SQL_FALSE, // 11
  93. NULL_INT, // 12
  94. NULL_CHAR, // 13
  95. NULL_INT, // 14
  96. NULL_INT, // 15
  97. SQL_BINARY, // 16
  98. NULL_INT, // 17
  99. NULL_INT, // 18
  100. NULL_INT // 19
  101.     },
  102.     { "VARBINARY", // 1
  103. SQL_VARBINARY, // 2
  104. 8000, // 3
  105. "'", // 4
  106. "'", // 5
  107. "length", // 6
  108. SQL_NULLABLE, // 7
  109. SQL_TRUE, // 8
  110. SQL_SEARCHABLE, // 9
  111. NULL_INT, // 10
  112. SQL_FALSE, // 11
  113. NULL_INT, // 12
  114. NULL_CHAR, // 13
  115. NULL_INT, // 14
  116. NULL_INT, // 15
  117. SQL_VARBINARY, // 16
  118. NULL_INT, // 17
  119. NULL_INT, // 18
  120. NULL_INT // 19
  121.     },
  122.     { "SMALLINT", // 1
  123. SQL_SMALLINT, // 2
  124. 4, // 3
  125. NULL_CHAR, // 4
  126. NULL_CHAR, // 5
  127. NULL_CHAR, // 6
  128. SQL_NULLABLE, // 7
  129. SQL_FALSE, // 8
  130. SQL_SEARCHABLE, // 9
  131. SQL_FALSE, // 10
  132. SQL_TRUE, // 11
  133. SQL_FALSE, // 12
  134. NULL_CHAR, // 13
  135. NULL_INT, // 14
  136. NULL_INT, // 15
  137. SQL_SMALLINT, // 16
  138. NULL_INT, // 17
  139. 10, // 18
  140. NULL_INT // 19
  141.     },
  142.     { "SMALLINT UNSIGNED", // 1
  143. SQL_SMALLINT, // 2
  144. 4, // 3
  145. NULL_CHAR, // 4
  146. NULL_CHAR, // 5
  147. NULL_CHAR, // 6
  148. SQL_NULLABLE, // 7
  149. SQL_FALSE, // 8
  150. SQL_SEARCHABLE, // 9
  151. SQL_TRUE, // 10
  152. SQL_TRUE, // 11
  153. SQL_FALSE, // 12
  154. NULL_CHAR, // 13
  155. NULL_INT, // 14
  156. NULL_INT, // 15
  157. SQL_SMALLINT, // 16
  158. NULL_INT, // 17
  159. 10, // 18
  160. NULL_INT // 19
  161.     },
  162.     { "INT", // 1
  163. SQL_INTEGER, // 2
  164. 9, // 3
  165. NULL_CHAR, // 4
  166. NULL_CHAR, // 5
  167. NULL_CHAR, // 6
  168. SQL_NULLABLE, // 7
  169. SQL_FALSE, // 8
  170. SQL_SEARCHABLE, // 9
  171. SQL_FALSE, // 10
  172. SQL_TRUE, // 11
  173. SQL_FALSE, // 12
  174. NULL_CHAR, // 13
  175. NULL_INT, // 14
  176. NULL_INT, // 15
  177. SQL_INTEGER, // 16
  178. NULL_INT, // 17
  179. 10, // 18
  180. NULL_INT // 19
  181.     },
  182.     { "INT UNSIGNED", // 1
  183. SQL_INTEGER, // 2
  184. 9, // 3
  185. NULL_CHAR, // 4
  186. NULL_CHAR, // 5
  187. NULL_CHAR, // 6
  188. SQL_NULLABLE, // 7
  189. SQL_FALSE, // 8
  190. SQL_SEARCHABLE, // 9
  191. SQL_TRUE, // 10
  192. SQL_TRUE, // 11
  193. SQL_FALSE, // 12
  194. NULL_CHAR, // 13
  195. NULL_INT, // 14
  196. NULL_INT, // 15
  197. SQL_INTEGER, // 16
  198. NULL_INT, // 17
  199. 10, // 18
  200. NULL_INT // 19
  201.     },
  202.     { "BIGINT", // 1
  203. SQL_BIGINT, // 2
  204. 19, // 3
  205. NULL_CHAR, // 4
  206. NULL_CHAR, // 5
  207. NULL_CHAR, // 6
  208. SQL_NULLABLE, // 7
  209. SQL_FALSE, // 8
  210. SQL_SEARCHABLE, // 9
  211. SQL_FALSE, // 10
  212. SQL_TRUE, // 11
  213. SQL_FALSE, // 12
  214. NULL_CHAR, // 13
  215. NULL_INT, // 14
  216. NULL_INT, // 15
  217. SQL_BIGINT, // 16
  218. NULL_INT, // 17
  219. 10, // 18
  220. NULL_INT // 19
  221.     },
  222.     { "BIGINT UNSIGNED", // 1
  223. SQL_BIGINT, // 2
  224. 19, // 3
  225. NULL_CHAR, // 4
  226. NULL_CHAR, // 5
  227. NULL_CHAR, // 6
  228. SQL_NULLABLE, // 7
  229. SQL_FALSE, // 8
  230. SQL_SEARCHABLE, // 9
  231. SQL_TRUE, // 10
  232. SQL_TRUE, // 11
  233. SQL_FALSE, // 12
  234. NULL_CHAR, // 13
  235. NULL_INT, // 14
  236. NULL_INT, // 15
  237. SQL_BIGINT, // 16
  238. NULL_INT, // 17
  239. 10, // 18
  240. NULL_INT // 19
  241.     },
  242.     { "REAL", // 1
  243. SQL_REAL, // 2
  244. 31, // 3
  245. NULL_CHAR, // 4
  246. NULL_CHAR, // 5
  247. NULL_CHAR, // 6
  248. SQL_NULLABLE, // 7
  249. SQL_FALSE, // 8
  250. SQL_SEARCHABLE, // 9
  251. SQL_FALSE, // 10
  252. SQL_TRUE, // 11
  253. SQL_FALSE, // 12
  254. NULL_CHAR, // 13
  255. NULL_INT, // 14
  256. NULL_INT, // 15
  257. SQL_REAL, // 16
  258. NULL_INT, // 17
  259. 2, // 18
  260. NULL_INT // 19
  261.     },
  262.     { "FLOAT", // 1
  263. SQL_DOUBLE, // 2
  264. 63, // 3
  265. NULL_CHAR, // 4
  266. NULL_CHAR, // 5
  267. NULL_CHAR, // 6
  268. SQL_NULLABLE, // 7
  269. SQL_FALSE, // 8
  270. SQL_SEARCHABLE, // 9
  271. SQL_FALSE, // 10
  272. SQL_TRUE, // 11
  273. SQL_FALSE, // 12
  274. NULL_CHAR, // 13
  275. NULL_INT, // 14
  276. NULL_INT, // 15
  277. SQL_DOUBLE, // 16
  278. NULL_INT, // 17
  279. 2, // 18
  280. NULL_INT // 19
  281.     },
  282.     { "DATETIME", // 1
  283. SQL_TYPE_TIMESTAMP, // 2
  284. 30, // 3
  285. NULL_CHAR, // 4
  286. NULL_CHAR, // 5
  287. NULL_CHAR, // 6
  288. SQL_NULLABLE, // 7
  289. SQL_FALSE, // 8
  290. SQL_SEARCHABLE, // 9
  291. SQL_FALSE, // 10
  292. SQL_TRUE, // 11
  293. SQL_FALSE, // 12
  294. NULL_CHAR, // 13
  295. NULL_INT, // 14
  296. NULL_INT, // 15
  297. SQL_DATETIME, // 16 XXX
  298. NULL_INT, // 17
  299. 2, // 18
  300. NULL_INT // 19
  301.     }
  302. };
  303. const unsigned
  304. typeinfoCount = sizeof(typeinfoList)/sizeof(typeinfoList[0]);
  305. void
  306. Exec_query_sys::execImpl(Ctx& ctx, Ctl& ctl)
  307. {
  308.     const Code& code = getCode();
  309.     Data& data = getData();
  310.     Ndb* const ndb = ndbObject();
  311.     NdbDictionary::Dictionary* ndbDictionary = ndb->getDictionary();
  312.     if (ndbDictionary == 0) {
  313. ctx.pushStatus(ndb, "getDictionary");
  314. return;
  315.     }
  316.     if (code.m_sysId == DictSys::OdbcTypeinfo || code.m_sysId == DictSys::Dual) {
  317. data.m_rowPos = 0; // at first entry
  318. return;
  319.     }
  320.     if (code.m_sysId == DictSys::OdbcTables || code.m_sysId == DictSys::OdbcColumns || code.m_sysId == DictSys::OdbcPrimarykeys) {
  321. // take all objects
  322. if (ndbDictionary->listObjects(data.m_objectList) == -1) {
  323.     ctx.pushStatus(ndb, "listObjects");
  324.     return;
  325. }
  326. data.m_tablePos = 0; // at first entry
  327. data.m_attrPos = 0;
  328. data.m_keyPos = 0;
  329. return;
  330.     }
  331.     ctx_assert(false);
  332. }
  333. static bool
  334. isNdbTable(const NdbDictionary::Dictionary::List::Element& element)
  335. {
  336.     switch (element.type) {
  337.     //case NdbDictionary::Object::SystemTable:
  338.     case NdbDictionary::Object::UserTable:
  339.     case NdbDictionary::Object::UniqueHashIndex:
  340.     case NdbDictionary::Object::HashIndex:
  341.     case NdbDictionary::Object::UniqueOrderedIndex:
  342.     case NdbDictionary::Object::OrderedIndex:
  343. return true;
  344.     default:
  345. break;
  346.     }
  347.     return false;
  348. }
  349. bool
  350. Exec_query_sys::fetchImpl(Ctx &ctx, Ctl& ctl)
  351. {
  352.     const Code& code = getCode();
  353.     Data& data = getData();
  354.     Ndb* const ndb = ndbObject();
  355.     NdbDictionary::Dictionary* ndbDictionary = ndb->getDictionary();
  356.     if (ndbDictionary == 0) {
  357. ctx.pushStatus(ndb, "getDictionary");
  358. return false;
  359.     }
  360.     if (code.m_sysId == DictSys::OdbcTypeinfo) {
  361. if (data.m_rowPos >= typeinfoCount) {
  362.     return false;
  363. }
  364. SqlRow& row = data.m_sqlRow;
  365. const Typeinfo& typeinfo = typeinfoList[data.m_rowPos++];
  366. for (unsigned i = 1; i <= code.m_attrCount; i++) {
  367.     SqlField& f = data.m_sqlRow.getEntry(i);
  368.     switch (1 + code.m_attrId[i]) {
  369.     case 1:
  370. if (typeinfo.m_type_name == NULL_CHAR)
  371.     f.sqlNull(true);
  372. else
  373.     f.sqlVarchar(typeinfo.m_type_name, SQL_NTS);
  374. break;
  375.     case 2:
  376. if (typeinfo.m_data_type == NULL_INT)
  377.     f.sqlNull(true);
  378. else
  379.     f.sqlInteger(typeinfo.m_data_type);
  380. break;
  381.     case 3:
  382. if (typeinfo.m_column_size == NULL_INT)
  383.     f.sqlNull(true);
  384. else
  385.     f.sqlInteger(typeinfo.m_column_size);
  386. break;
  387.     case 4:
  388. if (typeinfo.m_literal_prefix == NULL_CHAR)
  389.     f.sqlNull(true);
  390. else
  391.     f.sqlVarchar(typeinfo.m_literal_prefix, SQL_NTS);
  392. break;
  393.     case 5:
  394. if (typeinfo.m_literal_suffix == NULL_CHAR)
  395.     f.sqlNull(true);
  396. else
  397.     f.sqlVarchar(typeinfo.m_literal_suffix, SQL_NTS);
  398. break;
  399.     case 6:
  400. if (typeinfo.m_create_params == NULL_CHAR)
  401.     f.sqlNull(true);
  402. else
  403.     f.sqlVarchar(typeinfo.m_create_params, SQL_NTS);
  404. break;
  405.     case 7:
  406. if (typeinfo.m_nullable == NULL_INT)
  407.     f.sqlNull(true);
  408. else
  409.     f.sqlInteger(typeinfo.m_nullable);
  410. break;
  411.     case 8:
  412. if (typeinfo.m_case_sensitive == NULL_INT)
  413.     f.sqlNull(true);
  414. else
  415.     f.sqlInteger(typeinfo.m_case_sensitive);
  416. break;
  417.     case 9:
  418. if (typeinfo.m_searchable == NULL_INT)
  419.     f.sqlNull(true);
  420. else
  421.     f.sqlInteger(typeinfo.m_searchable);
  422. break;
  423.     case 10:
  424. if (typeinfo.m_unsigned_attribute == NULL_INT)
  425.     f.sqlNull(true);
  426. else
  427.     f.sqlInteger(typeinfo.m_unsigned_attribute);
  428. break;
  429.     case 11:
  430. if (typeinfo.m_fixed_prec_scale == NULL_INT)
  431.     f.sqlNull(true);
  432. else
  433.     f.sqlInteger(typeinfo.m_fixed_prec_scale);
  434. break;
  435.     case 12:
  436. if (typeinfo.m_auto_unique_value == NULL_INT)
  437.     f.sqlNull(true);
  438. else
  439.     f.sqlInteger(typeinfo.m_auto_unique_value);
  440. break;
  441.     case 13:
  442. if (typeinfo.m_local_type_name == NULL_CHAR)
  443.     f.sqlNull(true);
  444. else
  445.     f.sqlVarchar(typeinfo.m_local_type_name, SQL_NTS);
  446. break;
  447.     case 14:
  448. if (typeinfo.m_minimum_scale == NULL_INT)
  449.     f.sqlNull(true);
  450. else
  451.     f.sqlInteger(typeinfo.m_minimum_scale);
  452. break;
  453.     case 15:
  454. if (typeinfo.m_maximum_scale == NULL_INT)
  455.     f.sqlNull(true);
  456. else
  457.     f.sqlInteger(typeinfo.m_maximum_scale);
  458. break;
  459.     case 16:
  460. if (typeinfo.m_sql_data_type == NULL_INT)
  461.     f.sqlNull(true);
  462. else
  463.     f.sqlInteger(typeinfo.m_sql_data_type);
  464. break;
  465.     case 17:
  466. if (typeinfo.m_sql_datetime_sub == NULL_INT)
  467.     f.sqlNull(true);
  468. else
  469.     f.sqlInteger(typeinfo.m_sql_datetime_sub);
  470. break;
  471.     case 18:
  472. if (typeinfo.m_sql_datetime_sub == NULL_INT)
  473.     f.sqlNull(true);
  474. else
  475.     f.sqlInteger(typeinfo.m_sql_datetime_sub);
  476. break;
  477.     case 19:
  478. if (typeinfo.m_interval_precision == NULL_INT)
  479.     f.sqlNull(true);
  480. else
  481.     f.sqlInteger(typeinfo.m_interval_precision);
  482. break;
  483.     default:
  484. ctx_assert(false);
  485. break;
  486.     }
  487. }
  488. return true;
  489.     }
  490.     if (code.m_sysId == DictSys::OdbcTables) {
  491. if (data.m_tablePos >= data.m_objectList.count) {
  492.     return false;
  493. }
  494. NdbDictionary::Dictionary::List::Element& element = data.m_objectList.elements[data.m_tablePos++];
  495. for (unsigned i = 1; i <= code.m_attrCount; i++) {
  496.     SqlField& f = data.m_sqlRow.getEntry(i);
  497.     switch (1 + code.m_attrId[i]) {
  498.     case 1: // TABLE_CAT
  499. f.sqlNull(true);
  500. break;
  501.     case 2: // TABLE_SCHEM
  502. f.sqlNull(true);
  503. break;
  504.     case 3: // TABLE_NAME
  505. f.sqlVarchar(element.name, SQL_NTS);
  506. break;
  507.     case 4: { // TABLE_TYPE
  508. if (element.type == NdbDictionary::Object::SystemTable)
  509.     f.sqlVarchar("SYSTEM TABLE", SQL_NTS);
  510. else if (element.type == NdbDictionary::Object::UserTable)
  511.     f.sqlVarchar("TABLE", SQL_NTS);
  512. else if (element.type == NdbDictionary::Object::UniqueHashIndex)
  513.     f.sqlVarchar("UNIQUE HASH INDEX", SQL_NTS);
  514. else if (element.type == NdbDictionary::Object::HashIndex)
  515.     f.sqlVarchar("HASH INDEX", SQL_NTS);
  516. else if (element.type == NdbDictionary::Object::UniqueOrderedIndex)
  517.     f.sqlVarchar("UNIQUE INDEX", SQL_NTS);
  518. else if (element.type == NdbDictionary::Object::OrderedIndex)
  519.     f.sqlVarchar("INDEX", SQL_NTS);
  520. else if (element.type == NdbDictionary::Object::IndexTrigger)
  521.     f.sqlVarchar("INDEX TRIGGER", SQL_NTS);
  522. else if (element.type == NdbDictionary::Object::SubscriptionTrigger)
  523.     f.sqlVarchar("SUBSCRIPTION TRIGGER", SQL_NTS);
  524. else if (element.type == NdbDictionary::Object::ReadOnlyConstraint)
  525.     f.sqlVarchar("READ ONLY CONSTRAINT", SQL_NTS);
  526. else
  527.     f.sqlVarchar("UNKNOWN", SQL_NTS);
  528. }
  529. break;
  530.     case 5: // REMARKS
  531. f.sqlNull(true);
  532. break;
  533.     default:
  534. ctx_assert(false);
  535. break;
  536.     }
  537. }
  538. return true;
  539.     }
  540.     if (code.m_sysId == DictSys::OdbcColumns) {
  541. if (data.m_tablePos >= data.m_objectList.count) {
  542.     return false;
  543. }
  544. const NdbDictionary::Dictionary::List::Element& element = data.m_objectList.elements[data.m_tablePos];
  545. unsigned nattr;
  546. const NdbDictionary::Table* ndbTable;
  547. nattr = 0;
  548. if (isNdbTable(element)) {
  549.     ndbTable = ndbDictionary->getTable(element.name);
  550.     if (ndbTable == 0) {
  551. ctx.pushStatus(ndbDictionary->getNdbError(), "getTable %s", element.name);
  552. return false;
  553.     }
  554.     nattr = ndbTable->getNoOfColumns();
  555. }
  556. while (data.m_attrPos >= nattr) {
  557.     if (++data.m_tablePos >= data.m_objectList.count) {
  558. return false;
  559.     }
  560.     const NdbDictionary::Dictionary::List::Element& element = data.m_objectList.elements[data.m_tablePos];
  561.     nattr = 0;
  562.     if (isNdbTable(element)) {
  563. ndbTable = ndbDictionary->getTable(element.name);
  564. if (ndbTable == 0) {
  565.     ctx.pushStatus(ndbDictionary->getNdbError(), "getTable %s", element.name);
  566.     return false;
  567. }
  568. data.m_attrPos = 0;
  569. nattr = ndbTable->getNoOfColumns();
  570.     }
  571. }
  572. int attrId = data.m_attrPos++;
  573. const NdbDictionary::Column* ndbColumn = ndbTable->getColumn(attrId);
  574. if (ndbColumn == 0) {
  575.     ctx.pushStatus(ndbDictionary->getNdbError(), "getColumn %s.%d", ndbTable->getName(), attrId);
  576.     return false;
  577. }
  578. SqlType sqlType(ctx, ndbColumn);
  579. if (! ctx.ok())
  580.     return false;
  581. const char* p;
  582. for (unsigned i = 1; i <= code.m_attrCount; i++) {
  583.     SqlField& f = data.m_sqlRow.getEntry(i);
  584.     switch (1 + code.m_attrId[i]) {
  585.     case 1: // TABLE_CAT
  586. f.sqlNull(true);
  587. break;
  588.     case 2: // TABLE_SCHEM
  589. f.sqlNull(true);
  590. break;
  591.     case 3: // TABLE_NAME
  592. f.sqlVarchar(ndbTable->getName(), SQL_NTS);
  593. break;
  594.     case 4: // COLUMN_NAME
  595. f.sqlVarchar(ndbColumn->getName(), SQL_NTS);
  596. break;
  597.     case 5: // DATA_TYPE
  598. f.sqlInteger(sqlType.type());
  599. break;
  600.     case 6: // TYPE_NAME
  601. f.sqlVarchar(sqlType.typeName(), SQL_NTS);
  602. break;
  603.     case 7: // COLUMN_SIZE
  604. f.sqlInteger(sqlType.displaySize());
  605. break;
  606.     case 8: // BUFFER_LENGTH
  607. f.sqlInteger(sqlType.size());
  608. break;
  609.     case 9: // DECIMAL_DIGITS
  610. if (sqlType.type() == SqlType::Char)
  611.     f.sqlNull(true);
  612. else
  613.     f.sqlInteger(0);
  614. break;
  615.     case 10: // NUM_PREC_RADIX
  616. if (sqlType.type() == SqlType::Integer || sqlType.type() == SqlType::Bigint)
  617.     f.sqlInteger(10);
  618. else
  619.     f.sqlNull(true);
  620. break;
  621.     case 11: // NULLABLE
  622. if (sqlType.nullable())
  623.     f.sqlInteger(SQL_NULLABLE);
  624. else
  625.     f.sqlInteger(SQL_NO_NULLS);
  626. break;
  627.     case 12: // REMARKS
  628. f.sqlNull(true);
  629. break;
  630.     case 13: // COLUMN_DEF
  631. if ((p = ndbColumn->getDefaultValue()) != 0)
  632.     f.sqlVarchar(p, SQL_NTS);
  633. else
  634.     f.sqlNull(true);
  635. break;
  636.     case 14: // SQL_DATA_TYPE
  637. f.sqlInteger(sqlType.type());
  638. break;
  639.     case 15: // SQL_DATETIME_SUB
  640. f.sqlNull(true);
  641. break;
  642.     case 16: // CHAR_OCTET_LENGTH
  643. if (sqlType.type() == SqlType::Char)
  644.     f.sqlInteger(sqlType.length());
  645. else
  646.     f.sqlNull(true);
  647. break;
  648.     case 17: // ORDINAL_POSITION
  649. f.sqlInteger(1 + attrId);
  650. break;
  651.     case 18: // IS_NULLABLE
  652. if (sqlType.nullable())
  653.     f.sqlVarchar("YES", SQL_NTS);
  654. else
  655.     f.sqlVarchar("NO", SQL_NTS);
  656. break;
  657. break;
  658.     default:
  659. ctx_assert(false);
  660. break;
  661.     }
  662. }
  663. return true;
  664.     }
  665.     if (code.m_sysId == DictSys::OdbcPrimarykeys) {
  666. if (data.m_tablePos >= data.m_objectList.count) {
  667.     return false;
  668. }
  669. NdbDictionary::Dictionary::List::Element& element = data.m_objectList.elements[data.m_tablePos];
  670. unsigned nkeys;
  671. const NdbDictionary::Table* ndbTable;
  672. nkeys = 0;
  673. if (isNdbTable(element)) {
  674.     ndbTable = ndbDictionary->getTable(element.name);
  675.     if (ndbTable == 0) {
  676. ctx.pushStatus(ndbDictionary->getNdbError(), "getTable %s", element.name);
  677. return false;
  678.     }
  679.     nkeys = ndbTable->getNoOfPrimaryKeys();
  680. }
  681. while (data.m_keyPos >= nkeys) {
  682.     if (++data.m_tablePos >= data.m_objectList.count) {
  683. return false;
  684.     }
  685.     NdbDictionary::Dictionary::List::Element& element = data.m_objectList.elements[data.m_tablePos];
  686.     nkeys = 0;
  687.     if (isNdbTable(element)) {
  688. ndbTable = ndbDictionary->getTable(element.name);
  689. if (ndbTable == 0) {
  690.     ctx.pushStatus(ndbDictionary->getNdbError(), "getTable %s", element.name);
  691.     return false;
  692. }
  693. data.m_keyPos = 0;
  694. nkeys = ndbTable->getNoOfPrimaryKeys();
  695.     }
  696. }
  697. unsigned keyPos = data.m_keyPos++;
  698. const char* keyName = ndbTable->getPrimaryKey(keyPos);
  699. if (keyName == 0)
  700.     keyName = "?";
  701. for (unsigned i = 1; i <= code.m_attrCount; i++) {
  702.     SqlField& f = data.m_sqlRow.getEntry(i);
  703.     switch (1 + code.m_attrId[i]) {
  704.     case 1: // TABLE_CAT
  705. f.sqlNull(true);
  706. break;
  707.     case 2: // TABLE_SCHEM
  708. f.sqlNull(true);
  709. break;
  710.     case 3: // TABLE_NAME
  711. f.sqlVarchar(ndbTable->getName(), SQL_NTS);
  712. break;
  713.     case 4: // COLUMN_NAME
  714. f.sqlVarchar(keyName, SQL_NTS);
  715. break;
  716.     case 5: // KEY_SEQ
  717. f.sqlInteger(1 + keyPos);
  718. break;
  719.     case 6: // PK_NAME
  720. f.sqlNull(true);
  721. break;
  722.     default:
  723. ctx_assert(false);
  724. break;
  725.     }
  726. }
  727. return true;
  728.     }
  729.     if (code.m_sysId == DictSys::Dual) {
  730. if (data.m_rowPos > 0) {
  731.     return false;
  732. }
  733. data.m_rowPos++;
  734. for (unsigned i = 1; i <= code.m_attrCount; i++) {
  735.     SqlField& f = data.m_sqlRow.getEntry(i);
  736.     switch (1 + code.m_attrId[i]) {
  737.     case 1: // DUMMY
  738. f.sqlVarchar("X", 1);
  739. break;
  740.     default:
  741. ctx_assert(false);
  742. break;
  743.     }
  744. }
  745. return true;
  746.     }
  747.     ctx_assert(false);
  748.     return false;
  749. }