transactd 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/BUILD_UNIX-JA +46 -67
  3. data/BUILD_WIN-JA +106 -63
  4. data/CMakeLists.txt +40 -15
  5. data/README +219 -75
  6. data/README-JA +207 -76
  7. data/README_ORMSRCGEN +118 -0
  8. data/README_ORMSRCGEN-JA +115 -0
  9. data/bin/common/tdclc_32_2_0.dll +0 -0
  10. data/bin/common/tdclc_64_2_0.dll +0 -0
  11. data/build/common/check_for_link_iconv.cmake +18 -14
  12. data/build/common/create_symlink.cmake.in +25 -0
  13. data/build/common/get_boost_libs.cmake +23 -23
  14. data/build/common/options.cmake +0 -66
  15. data/build/common/smart_install.cmake +3 -3
  16. data/build/common/transactd.rc.in +15 -5
  17. data/build/common/transactd_cl_common.cmake +37 -18
  18. data/build/common/transactd_cl_output.cmake +55 -13
  19. data/build/common/transactd_common.cmake +108 -31
  20. data/build/swig/php/generate.cmake.in +15 -17
  21. data/build/swig/php/generate.cmd.in +15 -9
  22. data/build/swig/php/php.swg +124 -82
  23. data/build/swig/php/transactd.no_yield.php +4494 -0
  24. data/build/swig/php/transactd.no_yield.php.git.patch +685 -0
  25. data/build/swig/php/transactd.no_yield.php.patch +685 -0
  26. data/build/swig/php/transactd.yield.php +4461 -0
  27. data/build/swig/php/transactd.yield.php.git.patch +652 -0
  28. data/build/swig/php/transactd.yield.php.patch +652 -0
  29. data/build/swig/referencecounter.h +79 -0
  30. data/build/swig/ruby/ruby.swg +226 -76
  31. data/build/swig/ruby/threadBlockRegionWrapper.h +71 -0
  32. data/build/swig/ruby/without_gvl.swg +87 -0
  33. data/build/swig/tdcl.i +659 -170
  34. data/build/swig/validatablepointer.h +91 -0
  35. data/build/tdclc/CMakeLists.txt +49 -34
  36. data/build/tdclc/{tdclc_64.cbproj → tdclc.cbproj} +65 -20
  37. data/build/tdclc/tdclc.rc +0 -0
  38. data/build/tdclcpp/CMakeLists.txt +84 -20
  39. data/build/tdclcpp/tdclcpp.rc +0 -0
  40. data/build/tdclcpp/{tdclcpp_bcb_64.cbproj → tdclcpp_bc.cbproj} +168 -44
  41. data/build/tdclrb/CMakeLists.txt +84 -66
  42. data/build/tdclrb/bldgem/extconf.rb +28 -3
  43. data/build/tdclrb/gem/helper.rb +11 -1
  44. data/build/tdclrb/gem_output.cmake +20 -16
  45. data/index_ja.html +15 -0
  46. data/source/bzs/db/IBlobBuffer.h +15 -17
  47. data/source/bzs/db/blobBuffer.h +186 -140
  48. data/source/bzs/db/blobStructs.h +37 -37
  49. data/source/bzs/db/engine/mysql/IReadRecords.h +34 -34
  50. data/source/bzs/db/engine/mysql/bookmark.h +150 -147
  51. data/source/bzs/db/engine/mysql/database.cpp +1721 -1526
  52. data/source/bzs/db/engine/mysql/database.h +608 -370
  53. data/source/bzs/db/engine/mysql/dbManager.cpp +213 -201
  54. data/source/bzs/db/engine/mysql/dbManager.h +115 -104
  55. data/source/bzs/db/engine/mysql/errorMessage.cpp +49 -50
  56. data/source/bzs/db/engine/mysql/errorMessage.h +25 -26
  57. data/source/bzs/db/engine/mysql/fieldAccess.h +55 -61
  58. data/source/bzs/db/engine/mysql/mydebuglog.cpp +326 -292
  59. data/source/bzs/db/engine/mysql/mydebuglog.h +63 -55
  60. data/source/bzs/db/engine/mysql/mysqlInternal.h +182 -125
  61. data/source/bzs/db/engine/mysql/mysqlThd.cpp +121 -121
  62. data/source/bzs/db/engine/mysql/mysqlThd.h +20 -20
  63. data/source/bzs/db/engine/mysql/percentageKey.h +241 -228
  64. data/source/bzs/db/protocol/ICommandExecuter.h +18 -17
  65. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +543 -514
  66. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +155 -158
  67. data/source/bzs/db/protocol/tdap/btrDate.cpp +213 -180
  68. data/source/bzs/db/protocol/tdap/btrDate.h +39 -37
  69. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +173 -0
  70. data/source/bzs/db/protocol/tdap/client/activeTable.h +165 -0
  71. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +370 -0
  72. data/source/bzs/db/protocol/tdap/client/bulkInsert.h +13 -23
  73. data/source/bzs/db/protocol/tdap/client/client.cpp +81 -68
  74. data/source/bzs/db/protocol/tdap/client/client.h +361 -320
  75. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +17 -22
  76. data/source/bzs/db/protocol/tdap/client/connMgr.h +17 -19
  77. data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +243 -0
  78. data/source/bzs/db/protocol/tdap/client/connectionPool.h +109 -0
  79. data/source/bzs/db/protocol/tdap/client/database.cpp +327 -219
  80. data/source/bzs/db/protocol/tdap/client/database.h +141 -118
  81. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +60 -62
  82. data/source/bzs/db/protocol/tdap/client/databaseManager.h +255 -0
  83. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +315 -202
  84. data/source/bzs/db/protocol/tdap/client/dbDef.h +40 -32
  85. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +390 -371
  86. data/source/bzs/db/protocol/tdap/client/errorMessage.cpp +148 -56
  87. data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +149 -57
  88. data/source/bzs/db/protocol/tdap/client/export.h +35 -0
  89. data/source/bzs/db/protocol/tdap/client/field.cpp +1985 -0
  90. data/source/bzs/db/protocol/tdap/client/field.h +393 -0
  91. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +14 -14
  92. data/source/bzs/db/protocol/tdap/client/fieldDDF.h +11 -14
  93. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.cpp +123 -0
  94. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.h +58 -0
  95. data/source/bzs/db/protocol/tdap/client/fields.h +178 -0
  96. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +13 -16
  97. data/source/bzs/db/protocol/tdap/client/fileDDF.h +11 -17
  98. data/source/bzs/db/protocol/tdap/client/filter.h +423 -259
  99. data/source/bzs/db/protocol/tdap/client/groupComp.h +117 -0
  100. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +818 -0
  101. data/source/bzs/db/protocol/tdap/client/groupQuery.h +281 -0
  102. data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +14 -17
  103. data/source/bzs/db/protocol/tdap/client/indexDDF.h +11 -14
  104. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +231 -0
  105. data/source/bzs/db/protocol/tdap/client/memRecord.h +145 -0
  106. data/source/bzs/db/protocol/tdap/client/memRecordset.cpp +448 -0
  107. data/source/bzs/db/protocol/tdap/client/memRecordset.h +159 -0
  108. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +300 -173
  109. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +53 -36
  110. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +171 -128
  111. data/source/bzs/db/protocol/tdap/client/nsTable.h +121 -87
  112. data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +173 -0
  113. data/source/bzs/db/protocol/tdap/client/recordset.cpp +209 -0
  114. data/source/bzs/db/protocol/tdap/client/recordset.h +86 -0
  115. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +596 -0
  116. data/source/bzs/db/protocol/tdap/client/request.h +227 -170
  117. data/source/bzs/db/protocol/tdap/client/serializer.cpp +1288 -0
  118. data/source/bzs/db/protocol/tdap/client/serializer.h +295 -0
  119. data/source/bzs/db/protocol/tdap/client/sharedData.cpp +9 -12
  120. data/source/bzs/db/protocol/tdap/client/sharedData.h +18 -16
  121. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +494 -473
  122. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +51 -53
  123. data/source/bzs/db/protocol/tdap/client/stringConverter.h +214 -148
  124. data/source/bzs/db/protocol/tdap/client/table.cpp +929 -1665
  125. data/source/bzs/db/protocol/tdap/client/table.h +413 -87
  126. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +642 -534
  127. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +25 -40
  128. data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +11 -15
  129. data/source/bzs/db/protocol/tdap/client/trdormapi.h +378 -437
  130. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +1 -1
  131. data/source/bzs/db/protocol/tdap/fieldComp.h +127 -0
  132. data/source/bzs/db/protocol/tdap/myDateTime.cpp +352 -345
  133. data/source/bzs/db/protocol/tdap/mysql/characterset.cpp +75 -78
  134. data/source/bzs/db/protocol/tdap/mysql/characterset.h +18 -19
  135. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +216 -199
  136. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +23 -14
  137. data/source/bzs/db/protocol/tdap/mysql/debuglog.cpp +354 -314
  138. data/source/bzs/db/protocol/tdap/mysql/debuglog.h +57 -47
  139. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +905 -739
  140. data/source/bzs/db/protocol/tdap/mysql/request.h +152 -159
  141. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +1044 -879
  142. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +87 -81
  143. data/source/bzs/db/protocol/tdap/tdapRequest.h +162 -130
  144. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +368 -166
  145. data/source/bzs/db/protocol/tdap/tdapSchema.h +702 -566
  146. data/source/bzs/db/protocol/tdap/tdapcapi.h +387 -353
  147. data/source/bzs/db/transactd/appBuilderImple.h +21 -20
  148. data/source/bzs/db/transactd/appModule.cpp +350 -98
  149. data/source/bzs/db/transactd/appModule.h +31 -37
  150. data/source/bzs/db/transactd/connManager.cpp +138 -135
  151. data/source/bzs/db/transactd/connManager.h +28 -21
  152. data/source/bzs/db/transactd/connectionRecord.h +39 -39
  153. data/source/bzs/db/transactd/transactd.cpp +217 -203
  154. data/source/bzs/env/boost_bcb_link.h +131 -0
  155. data/source/bzs/env/compiler.h +136 -79
  156. data/source/bzs/env/crosscompile.cpp +57 -57
  157. data/source/bzs/env/crosscompile.h +130 -115
  158. data/source/bzs/env/fileopen.h +7 -8
  159. data/source/bzs/env/mbcswchrLinux.cpp +4 -9
  160. data/source/bzs/env/mbcswchrLinux.h +37 -34
  161. data/source/bzs/env/tcharMinGW.h +59 -0
  162. data/source/bzs/env/tstring.h +90 -95
  163. data/source/bzs/example/changeSchema.cpp +22 -23
  164. data/source/bzs/example/changeSchema_c.cpp +22 -24
  165. data/source/bzs/example/connection_pool_c.cpp +49 -104
  166. data/source/bzs/example/createDatabase.cpp +40 -47
  167. data/source/bzs/example/createDatabase_c.cpp +38 -43
  168. data/source/bzs/example/deleteRecords.cpp +10 -15
  169. data/source/bzs/example/deleteRecords_c.cpp +10 -14
  170. data/source/bzs/example/dropDatabase.cpp +3 -9
  171. data/source/bzs/example/dropDatabase_c.cpp +5 -6
  172. data/source/bzs/example/insertRecords.cpp +37 -29
  173. data/source/bzs/example/insertRecords_c.cpp +19 -25
  174. data/source/bzs/example/ormap_c.cpp +621 -0
  175. data/source/bzs/example/queryData.cpp +371 -0
  176. data/source/bzs/example/queryData.h +16 -0
  177. data/source/bzs/example/query_c.cpp +109 -0
  178. data/source/bzs/example/readRecords.cpp +27 -27
  179. data/source/bzs/example/readRecords_c.cpp +25 -23
  180. data/source/bzs/example/updateRecords.cpp +16 -21
  181. data/source/bzs/example/updateRecords_c.cpp +8 -12
  182. data/source/bzs/example/update_with_transaction.cpp +21 -24
  183. data/source/bzs/example/update_with_transaction_c.cpp +12 -15
  184. data/source/bzs/example/useORMRecord.cpp +177 -0
  185. data/source/bzs/netsvc/client/tcpClient.cpp +167 -156
  186. data/source/bzs/netsvc/client/tcpClient.h +541 -489
  187. data/source/bzs/netsvc/server/IAppModule.h +119 -32
  188. data/source/bzs/netsvc/server/iserver.h +21 -23
  189. data/source/bzs/netsvc/server/serverCpt.cpp +421 -391
  190. data/source/bzs/netsvc/server/serverCpt.h +41 -43
  191. data/source/bzs/netsvc/server/serverPipe.cpp +580 -565
  192. data/source/bzs/netsvc/server/serverPipe.h +44 -45
  193. data/source/bzs/netsvc/server/serverTpool.cpp +333 -303
  194. data/source/bzs/netsvc/server/serverTpool.h +38 -43
  195. data/source/bzs/rtl/benchmark.cpp +91 -31
  196. data/source/bzs/rtl/benchmark.h +76 -22
  197. data/source/bzs/rtl/datetime.cpp +231 -233
  198. data/source/bzs/rtl/datetime.h +16 -16
  199. data/source/bzs/rtl/debuglog.cpp +48 -51
  200. data/source/bzs/rtl/debuglog.h +55 -44
  201. data/source/bzs/rtl/exception.h +55 -48
  202. data/source/bzs/rtl/stl_uty.cpp +27 -28
  203. data/source/bzs/rtl/stl_uty.h +28 -29
  204. data/source/bzs/rtl/stringBuffers.cpp +8 -6
  205. data/source/bzs/rtl/stringBuffers.h +16 -9
  206. data/source/bzs/rtl/strtrim.cpp +90 -91
  207. data/source/bzs/rtl/strtrim.h +14 -16
  208. data/source/bzs/test/tdclatl/bench_query_atl.js +647 -0
  209. data/source/bzs/test/tdclatl/bench_tdclatl.js +303 -303
  210. data/source/bzs/test/tdclatl/test_query_atl.js +669 -0
  211. data/source/bzs/test/tdclphp/bench.php +357 -0
  212. data/source/bzs/test/tdclphp/transactd_Test.php +907 -303
  213. data/source/bzs/test/tdclphp/transactd_blob_Test.php +21 -49
  214. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +41 -75
  215. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +23 -37
  216. data/source/bzs/test/tdclphp/transactd_pool_Test.php +120 -0
  217. data/source/bzs/test/tdclrb/bench_tdclcpp.rb +4 -6
  218. data/source/bzs/test/tdclrb/prepare.rb +15 -12
  219. data/source/bzs/test/tdclrb/transactd_blob_spec.rb +29 -32
  220. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +0 -29
  221. data/source/bzs/test/tdclrb/transactd_kanjischema_spec.rb +18 -19
  222. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +107 -0
  223. data/source/bzs/test/tdclrb/transactd_spec.rb +734 -142
  224. data/source/bzs/test/transactdBench/query_bench.cpp +156 -0
  225. data/source/bzs/test/transactdBench/scaling_bench.cpp +265 -0
  226. data/source/bzs/test/transactdBench/transactdBench.cpp +107 -83
  227. data/source/bzs/test/transactdBench/transactdBench2.cpp +122 -83
  228. data/source/bzs/test/transactdBench/workerBase.cpp +5 -0
  229. data/source/bzs/test/transactdBench/workerBase.h +88 -0
  230. data/source/bzs/test/transactdBench/workerMySQLImple.h +333 -0
  231. data/source/bzs/test/transactdBench/workerTransactdImple.h +201 -0
  232. data/source/bzs/test/trdclengn/test_blob.cpp +121 -73
  233. data/source/bzs/test/trdclengn/test_trdclengn.cpp +1244 -426
  234. data/source/global/ormsrcgen/confParam.h +80 -0
  235. data/source/global/ormsrcgen/fieldName.cpp +77 -0
  236. data/source/global/ormsrcgen/fieldName.h +43 -0
  237. data/source/global/ormsrcgen/main.cpp +196 -0
  238. data/source/global/ormsrcgen/srcgen.cpp +763 -0
  239. data/source/global/ormsrcgen/srcgen.h +72 -0
  240. data/source/global/ormsrcgen/template/fieldNameList_sample.txt +2 -0
  241. data/source/global/ormsrcgen/template/ormDataClass_template.cpp +48 -0
  242. data/source/global/ormsrcgen/template/ormDataClass_template.h +34 -0
  243. data/source/global/ormsrcgen/template/ormMapClass_template.cpp +51 -0
  244. data/source/global/ormsrcgen/template/ormMapClass_template.h +62 -0
  245. data/source/global/ormsrcgen/template/template.cnf +38 -0
  246. data/source/global/querystmts/querystmts.cpp +237 -0
  247. data/source/global/tdclatl/ConnectParams.cpp +77 -0
  248. data/source/global/tdclatl/ConnectParams.h +70 -0
  249. data/source/global/tdclatl/Database.cpp +132 -128
  250. data/source/global/tdclatl/Database.h +60 -49
  251. data/source/global/tdclatl/DbDef.cpp +68 -64
  252. data/source/global/tdclatl/DbDef.h +36 -36
  253. data/source/global/tdclatl/Field.cpp +12 -17
  254. data/source/global/tdclatl/Field.h +15 -12
  255. data/source/global/tdclatl/FieldDef.cpp +75 -36
  256. data/source/global/tdclatl/FieldDef.h +38 -19
  257. data/source/global/tdclatl/FieldDefs.cpp +74 -0
  258. data/source/global/tdclatl/FieldDefs.h +56 -0
  259. data/source/global/tdclatl/FieldNames.cpp +99 -0
  260. data/source/global/tdclatl/FieldNames.h +66 -0
  261. data/source/global/tdclatl/Flags.cpp +75 -37
  262. data/source/global/tdclatl/Flags.h +13 -12
  263. data/source/global/tdclatl/GroupQuery.cpp +119 -0
  264. data/source/global/tdclatl/GroupQuery.h +65 -0
  265. data/source/global/tdclatl/KeyDef.cpp +15 -14
  266. data/source/global/tdclatl/KeyDef.h +20 -17
  267. data/source/global/tdclatl/KeySegment.cpp +13 -12
  268. data/source/global/tdclatl/PooledDbManager.cpp +223 -0
  269. data/source/global/tdclatl/PooledDbManager.h +76 -0
  270. data/source/global/tdclatl/QueryBase.cpp +206 -127
  271. data/source/global/tdclatl/QueryBase.h +55 -59
  272. data/source/global/tdclatl/Record.cpp +214 -0
  273. data/source/global/tdclatl/Record.h +96 -0
  274. data/source/global/tdclatl/Recordset.cpp +278 -0
  275. data/source/global/tdclatl/Recordset.h +83 -0
  276. data/source/global/tdclatl/RecordsetQuery.cpp +118 -0
  277. data/source/global/tdclatl/RecordsetQuery.h +126 -0
  278. data/source/global/tdclatl/Table.cpp +57 -60
  279. data/source/global/tdclatl/Table.h +32 -29
  280. data/source/global/tdclatl/TableDef.cpp +63 -62
  281. data/source/global/tdclatl/TableDef.h +20 -22
  282. data/source/global/tdclatl/TdVersion.cpp +3 -3
  283. data/source/global/tdclatl/TdVersion.h +15 -11
  284. data/source/global/tdclatl/_IDatabaseEvents_CP.h +99 -92
  285. data/source/global/tdclatl/activeTable.cpp +355 -0
  286. data/source/global/tdclatl/activeTable.h +79 -0
  287. data/source/global/tdclatl/dllmain.cpp +4 -3
  288. data/source/global/tdclatl/dllmain.h +7 -6
  289. data/source/global/tdclatl/keySegment.h +22 -18
  290. data/source/global/tdclatl/resource.h +0 -0
  291. data/source/global/tdclatl/stdafx.h +6 -4
  292. data/source/global/tdclatl/targetver.h +0 -1
  293. data/source/global/tdclatl/tdclatl.cpp +10 -5
  294. data/source/global/tdclatl/tdclatl.idl +530 -14
  295. data/source/linux/charsetConvert.h +78 -79
  296. data/source/linux/linuxTypes.h +9 -12
  297. data/source/linux/tchar.h +168 -166
  298. data/transactd.gemspec +24 -16
  299. metadata +98 -12
  300. data/bin/common/tdclc_32_1_2.dll +0 -0
  301. data/bin/common/tdclc_64_1_2.dll +0 -0
  302. data/build/tdclc/tdclc_32.cbproj +0 -173
  303. data/build/tdclcpp/tdclcpp_bcb_32.cbproj +0 -232
  304. data/build/tdclrb/GEM_VERSION +0 -3
  305. data/source/bzs/db/protocol/tdap/client/filter.cpp +0 -43
  306. data/source/bzs/example/useORM.cpp +0 -585
@@ -1,35 +1,32 @@
1
- /*=================================================================
2
- Copyright (C) 2012 2013 BizStation Corp All rights reserved.
1
+ /* =================================================================
2
+ Copyright (C) 2012 2013 BizStation Corp All rights reserved.
3
3
 
4
- This program is free software; you can redistribute it and/or
5
- modify it under the terms of the GNU General Public License
6
- as published by the Free Software Foundation; either version 2
7
- of the License, or (at your option) any later version.
4
+ This program is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU General Public License
6
+ as published by the Free Software Foundation; either version 2
7
+ of the License, or (at your option) any later version.
8
8
 
9
- This program is distributed in the hope that it will be useful,
10
- but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- GNU General Public License for more details.
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
13
 
14
- You should have received a copy of the GNU General Public License
15
- along with this program; if not, write to the Free Software
16
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17
- 02111-1307, USA.
18
- =================================================================*/
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program; if not, write to the Free Software
16
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17
+ 02111-1307, USA.
18
+ ================================================================= */
19
19
 
20
20
  #include "database.h"
21
21
  #include <boost/bind.hpp>
22
22
  #include "IReadRecords.h"
23
23
  #include "percentageKey.h"
24
-
25
24
  #include "mydebuglog.h"
26
-
27
25
  #include "mysqlThd.h"
28
26
  #include "bookmark.h"
29
27
  #include <bzs/rtl/stl_uty.h>
30
28
  #include <boost/shared_array.hpp>
31
29
 
32
- extern int g_useBtrvVariableTable;
33
30
  namespace bzs
34
31
  {
35
32
  namespace db
@@ -41,1438 +38,1624 @@ namespace mysql
41
38
 
42
39
  using namespace std;
43
40
 
41
+ #define KEYLEN_ALLCOPY 0
42
+ #define OPEN_TABLE_TIMEOUT_SEC 2
44
43
 
45
- unsigned int hash(const char *s, size_t len)
44
+ unsigned int hash(const char* s, size_t len)
46
45
  {
47
46
  unsigned int h = 0;
48
- for (size_t i=0;i < len; i++)
49
- h = h * 137 + *(s+i);
50
- return h % 1987;
47
+ for (size_t i = 0; i < len; i++)
48
+ h = h * 137 + *(s + i);
49
+ return h % 1987;
51
50
  }
52
51
 
53
52
  tableCacheCounter::tableCacheCounter()
54
53
  {
55
-
56
54
  }
57
55
 
58
- int tableCacheCounter::getHash(const std::string& dbname, const std::string& tbname)
56
+ int tableCacheCounter::getHash(const std::string& dbname,
57
+ const std::string& tbname)
59
58
  {
60
- char tmp[256];
61
- sprintf_s(tmp, 256,"%s%s",dbname.c_str(), tbname.c_str());
62
- return hash(tmp, strlen(tmp));
59
+ char tmp[256];
60
+ sprintf_s(tmp, 256, "%s%s", dbname.c_str(), tbname.c_str());
61
+ return hash(tmp, strlen(tmp));
63
62
  }
64
63
 
65
- size_t tableCacheCounter::getCounterIndex(const std::string& dbname, const std::string& tbname)
64
+ size_t tableCacheCounter::getCounterIndex(const std::string& dbname,
65
+ const std::string& tbname)
66
66
  {
67
- int h = getHash(dbname, tbname);
68
- vector<int>::iterator pos = find(m_tables.begin(),m_tables.end(), h);
69
- if (pos == m_tables.end())
70
- {
71
- m_tables.push_back(h);
72
- m_counts.push_back(0);
73
- return m_counts.size() - 1;
74
- }
75
- return pos - m_tables.begin();
67
+ int h = getHash(dbname, tbname);
68
+ vector<int>::iterator pos = find(m_tables.begin(), m_tables.end(), h);
69
+ if (pos == m_tables.end())
70
+ {
71
+ m_tables.push_back(h);
72
+ m_counts.push_back(0);
73
+ return m_counts.size() - 1;
74
+ }
75
+ return pos - m_tables.begin();
76
76
  }
77
77
 
78
- void tableCacheCounter::addref(const std::string& dbname, const std::string& tbname)
78
+ void tableCacheCounter::addref(const std::string& dbname,
79
+ const std::string& tbname)
79
80
  {
80
-
81
- boost::mutex::scoped_lock lck(m_mutex);
82
- size_t pos = getCounterIndex(dbname, tbname);
83
- ++m_counts[pos];
81
+
82
+ boost::mutex::scoped_lock lck(m_mutex);
83
+ size_t pos = getCounterIndex(dbname, tbname);
84
+ ++m_counts[pos];
84
85
  }
85
86
 
86
- int tableCacheCounter::count(const std::string& dbname, const std::string& tbname)
87
+ int tableCacheCounter::count(const std::string& dbname,
88
+ const std::string& tbname)
87
89
  {
88
- boost::mutex::scoped_lock lck(m_mutex);
89
- size_t pos = getCounterIndex(dbname, tbname);
90
- return m_counts[pos];
90
+ boost::mutex::scoped_lock lck(m_mutex);
91
+ size_t pos = getCounterIndex(dbname, tbname);
92
+ return m_counts[pos];
91
93
  }
92
94
 
93
- void tableCacheCounter::release(const std::string& dbname, const std::string& tbname)
95
+ void tableCacheCounter::release(const std::string& dbname,
96
+ const std::string& tbname)
94
97
  {
95
- boost::mutex::scoped_lock lck(m_mutex);
96
- size_t pos = getCounterIndex(dbname, tbname);
97
- --m_counts[pos];
98
+ boost::mutex::scoped_lock lck(m_mutex);
99
+ size_t pos = getCounterIndex(dbname, tbname);
100
+ --m_counts[pos];
98
101
  }
99
102
 
100
- #define KEYLEN_ALLCOPY 0
101
- #define OPEN_TABLE_TIMEOUT_SEC 2
102
-
103
103
  void lockTable(THD* thd, TABLE* tb)
104
104
  {
105
- bool append = (thd->lock!=0);
106
- thd->in_lock_tables = 1;
107
- MYSQL_LOCK *lockMrg=NULL;
105
+ bool append = (thd->lock != 0);
106
+ thd->in_lock_tables = 1;
108
107
 
109
- MYSQL_LOCK *lock = mysql_lock_tables(thd, &tb, 1, 0);
110
- if (!append)
111
- thd->lock = lock;
112
- else if (lock)
113
- {
114
- MYSQL_LOCK *lockMrg = mysql_lock_merge(thd->lock, lock);
115
- if (lockMrg)
116
- thd->lock= lockMrg;
117
- }
118
- thd->in_lock_tables= 0;
119
- DEBUG_WRITELOG_SP1("LOCK TABLE table =%s\n", tb->s->table_name.str);
108
+ MYSQL_LOCK* lock = mysql_lock_tables(thd, &tb, 1, 0);
109
+ if (!append)
110
+ thd->lock = lock;
111
+ else if (lock)
112
+ {
113
+ MYSQL_LOCK* lockMrg = mysql_lock_merge(thd->lock, lock);
114
+ if (lockMrg)
115
+ thd->lock = lockMrg;
116
+ }
117
+ thd->in_lock_tables = 0;
118
+ DEBUG_WRITELOG_SP1("LOCK TABLE table =%s\n", tb->s->table_name.str);
120
119
 
121
- return ;
120
+ return;
122
121
  }
123
122
 
124
- /** The present lock type is returned.
123
+ /** The present lock type is returned.
125
124
  * The true lock type of innodb is controlled by m_thd->lex->sql_command.
126
125
  */
127
126
  thr_lock_type locktype(bool trn, enum_sql_command cmd)
128
127
  {
129
- if (trn)
130
- return TL_WRITE;
131
- thr_lock_type lock_type = TL_READ;
132
- switch(cmd)
133
- {
134
- case SQLCOM_INSERT:
135
- case SQLCOM_DELETE:
136
- case SQLCOM_UPDATE:
137
- case SQLCOM_DROP_TABLE:
138
- case SQLCOM_CREATE_TABLE:
139
- case SQLCOM_CREATE_INDEX:
140
- lock_type = TL_WRITE;
141
- default:
142
- ;
143
- break;
144
- }
145
- return lock_type;
128
+ if (trn)
129
+ return TL_WRITE;
130
+ thr_lock_type lock_type = TL_READ;
131
+ switch (cmd)
132
+ {
133
+ case SQLCOM_INSERT:
134
+ case SQLCOM_DELETE:
135
+ case SQLCOM_UPDATE:
136
+ case SQLCOM_DROP_TABLE:
137
+ case SQLCOM_CREATE_TABLE:
138
+ case SQLCOM_CREATE_INDEX:
139
+ lock_type = TL_WRITE;
140
+ default:
141
+ break;
142
+ }
143
+ return lock_type;
146
144
  }
147
145
 
148
146
  bool unlockTables(bool releaseStatementLock, THD* thd, bool rollback)
149
147
  {
150
- if (thd->lock)
151
- {
152
- bool ret;
153
- if (rollback)
154
- ret = trans_rollback_stmt(thd);
155
- else
156
- ret = trans_commit_stmt(thd);
157
- if (releaseStatementLock)
158
- thd->mdl_context.release_statement_locks();
159
- mysql_unlock_tables(thd, thd->lock);
160
- thd->lock = 0;
161
- return !ret;
162
- }
163
- return false;
164
-
148
+ if (thd->lock)
149
+ {
150
+ bool ret;
151
+ if (rollback)
152
+ ret = trans_rollback_stmt(thd);
153
+ else
154
+ ret = trans_commit_stmt(thd);
155
+ if (releaseStatementLock)
156
+ thd->mdl_context.release_statement_locks();
157
+ mysql_unlock_tables(thd, thd->lock);
158
+ thd->lock = 0;
159
+ return !ret;
160
+ }
161
+ return false;
165
162
  }
166
163
 
167
164
  #ifdef _MSC_VER
168
- #pragma warning(disable:4355)
165
+ #pragma warning(disable : 4355)
169
166
  #endif
170
167
 
171
-
172
- bool g_safe_share_mode=false;
168
+ bool g_safe_share_mode = false;
173
169
  tableCacheCounter database::tableRef;
174
170
 
175
171
  database::database(const char* name, short cid)
176
- :m_dbname(name),m_thd(createThdForThread()),m_cid(cid)
177
- ,m_inTransaction(0),m_inSnapshot(0),m_trnType(0)
172
+ : m_dbname(name), m_thd(createThdForThread()), m_cid(cid),
173
+ m_inTransaction(0), m_inSnapshot(0), m_trnType(0)
178
174
  {
179
- m_thd->security_ctx->skip_grants();
180
-
181
-
182
-
183
-
175
+ m_thd->security_ctx->skip_grants();
184
176
  }
185
177
 
186
178
  #ifdef _MSC_VER
187
- #pragma warning(default:4355)
188
- #endif
179
+ #pragma warning(default : 4355)
180
+ #endif
189
181
 
190
182
  database::~database()
191
183
  {
192
- use();
193
- unUseTables(false);
194
- closeForReopen();
195
- m_tables.clear();//It clears ahead of the destructor of m_trn.
196
- deleteThdForThread(m_thd);
184
+ use();
185
+ unUseTables(false);
186
+ closeForReopen();
187
+ m_tables.clear(); // It clears ahead of the destructor of m_trn.
188
+ deleteThdForThread(m_thd);
197
189
  }
198
190
 
199
191
  void database::use() const
200
192
  {
201
- attachThd(m_thd);
202
- m_thd->clear_error();
193
+ attachThd(m_thd);
194
+ m_thd->clear_error();
203
195
  }
204
196
 
205
197
  // locktable
206
198
  table* database::useTable(int index, enum_sql_command cmd)
207
199
  {
208
- if (index>=(int)m_tables.size())
209
- THROW_BZS_ERROR_WITH_CODEMSG(1, "Invalid table id.");
210
-
211
- table* tb = m_tables[index].get();
212
- if (tb == NULL)
213
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED, "Invalid table id.");
214
-
215
- if (tb->m_blobBuffer)
216
- tb->m_blobBuffer->clear();
217
- if (tb->islocked())
218
- {
219
- if (tb->m_table==NULL)
220
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED, "Invalid table id.");
221
- return tb;
222
- }
223
- if (g_safe_share_mode && tb->m_table==NULL)
224
- reopen();
225
- if (tb->m_table==NULL)
226
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED, "Invalid table id.");
227
- bool trn = (m_inTransaction>0) & (tb->mode() != TD_OPEN_READONLY);
228
- tb->m_table->reginfo.lock_type = locktype(trn, cmd);
229
- if ((tb->mode() == TD_OPEN_READONLY) && (tb->m_table->reginfo.lock_type == TL_WRITE))
230
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_ACCESS_DENIED, "Access denined.");
231
- if (m_thd->lock==0)
232
- {
233
- m_thd->lex->sql_command = cmd;
234
- m_thd->tx_isolation= (enum_tx_isolation) m_thd->variables.tx_isolation;
235
- cp_thd_set_read_only(m_thd);
236
- }
237
- lockTable(m_thd, tb->m_table);
238
-
239
-
240
- if ((tb->m_table->reginfo.lock_type == TL_WRITE) && (m_thd->variables.sql_log_bin))
241
- m_thd->set_current_stmt_binlog_format_row();
242
- tb->setLocked(true);
243
- if (g_safe_share_mode)
244
- {
245
- tb->m_keyconv.setKey(tb->m_table->key_info);
246
- if (tb->keyNum()>=0)
247
- tb->m_table->file->ha_index_init(tb->keyNum(), 1/*sorted*/);
248
- else if(tb->keyNum() == -2)
249
- tb->m_table->file->ha_rnd_init(false);
250
- }
251
-
252
- return tb;
200
+ if (index >= (int)m_tables.size())
201
+ THROW_BZS_ERROR_WITH_CODEMSG(1, "Invalid table id.");
202
+
203
+ table* tb = m_tables[index].get();
204
+ if (tb == NULL)
205
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED,
206
+ "Invalid table id.");
207
+
208
+ if (tb->m_blobBuffer)
209
+ tb->m_blobBuffer->clear();
210
+ if (tb->islocked())
211
+ {
212
+ if (tb->m_table == NULL)
213
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED,
214
+ "Invalid table id.");
215
+ return tb;
216
+ }
217
+ if (g_safe_share_mode && tb->m_table == NULL)
218
+ reopen();
219
+ if (tb->m_table == NULL)
220
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED,
221
+ "Invalid table id.");
222
+ bool trn = ((m_inTransaction > 0) & (tb->mode() != TD_OPEN_READONLY));
223
+ tb->m_table->reginfo.lock_type = locktype(trn, cmd);
224
+ if ((tb->mode() == TD_OPEN_READONLY) &&
225
+ (tb->m_table->reginfo.lock_type == TL_WRITE))
226
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_ACCESS_DENIED, "Access denined.");
227
+ if (m_thd->lock == 0)
228
+ {
229
+ m_thd->lex->sql_command = cmd;
230
+ m_thd->tx_isolation = (enum_tx_isolation)m_thd->variables.tx_isolation;
231
+ cp_thd_set_read_only(m_thd);
232
+ }
233
+ lockTable(m_thd, tb->m_table);
234
+
235
+ if ((tb->m_table->reginfo.lock_type == TL_WRITE) &&
236
+ (m_thd->variables.sql_log_bin))
237
+ m_thd->set_current_stmt_binlog_format_row();
238
+ tb->setLocked(true);
239
+ if (g_safe_share_mode)
240
+ {
241
+ int ret = 0;
242
+ tb->m_keyconv.setKey(tb->m_table->key_info);
243
+ if (tb->keyNum() >= 0)
244
+ ret =
245
+ tb->m_table->file->ha_index_init(tb->keyNum(), 1 /* sorted */);
246
+ else if (tb->keyNum() == -2)
247
+ ret = tb->m_table->file->ha_rnd_init(false);
248
+ if (ret)
249
+ THROW_BZS_ERROR_WITH_CODEMSG(ERROR_INDEX_RND_INIT,
250
+ "UseTable index_init error.");
251
+ }
252
+
253
+ return tb;
253
254
  }
254
255
 
255
256
  void database::unUseTable(table* tb)
256
257
  {
257
- if (tb->islocked() && (m_inTransaction + m_inSnapshot==0))
258
- { //Only this table is lock release.
259
- bool needUnlock = (locktype(false, m_thd->lex->sql_command)==TL_WRITE);
260
- bool changed = tb->isChanged();
261
- tb->resetTransctionInfo(m_thd);
262
- bool rollback = (!changed && needUnlock);
263
- if (unlockTables(needUnlock, m_thd, rollback))
264
- {
265
- DEBUG_WRITELOG_SP1("UNLOCK TABLE table =%s\n", tb->m_table->s->table_name.str);
266
- }else
267
- {
268
- DEBUG_WRITELOG_SP1("UNLOCK TABLE ERROR table =%s\n", tb->m_table->s->table_name.str);
269
- if (m_thd->is_error())
270
- {
271
-
272
- if (ER_LOCK_WAIT_TIMEOUT == m_thd->cp_get_sql_error())
273
- m_stat = STATUS_CANNOT_LOCK_TABLE;
274
- else
275
- m_stat = m_thd->cp_get_sql_error();
276
- THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "Transaction commit error.");
277
- }
278
- }
279
- if (g_safe_share_mode)
280
- {
281
- unUseTables(false);
282
- closeForReopen();
283
- }
284
-
285
- }
258
+ if (tb->islocked() && (m_inTransaction + m_inSnapshot == 0))
259
+ { // Only this table is lock release.
260
+ bool needUnlock =
261
+ (locktype(false, m_thd->lex->sql_command) == TL_WRITE);
262
+ bool changed = tb->isChanged();
263
+ tb->resetTransctionInfo(m_thd);
264
+ bool rollback = (!changed && needUnlock);
265
+ if (unlockTables(needUnlock, m_thd, rollback))
266
+ {
267
+ DEBUG_WRITELOG_SP1("UNLOCK TABLE table =%s\n",
268
+ tb->m_table->s->table_name.str);
269
+ }
270
+ else
271
+ {
272
+ DEBUG_WRITELOG_SP1("UNLOCK TABLE ERROR table =%s\n",
273
+ tb->m_table->s->table_name.str);
274
+ if (m_thd->is_error())
275
+ {
276
+
277
+ if (ER_LOCK_WAIT_TIMEOUT == m_thd->cp_get_sql_error())
278
+ m_stat = STATUS_CANNOT_LOCK_TABLE;
279
+ else
280
+ m_stat = m_thd->cp_get_sql_error();
281
+ THROW_BZS_ERROR_WITH_CODEMSG(m_stat,
282
+ "Transaction commit error.");
283
+ }
284
+ }
285
+ if (g_safe_share_mode)
286
+ {
287
+ unUseTables(false);
288
+ closeForReopen();
289
+ }
290
+ }
286
291
  }
287
292
 
288
293
  void database::unUseTables(bool rollback)
289
294
  {
290
- //All the table lock release
291
- bool needUnlock = (locktype((m_inTransaction>0), m_thd->lex->sql_command)==TL_WRITE);
292
- m_inTransaction = 0;
293
- m_inSnapshot = 0;
294
- for (int i=0;i<(int)m_tables.size();i++)
295
- {
296
- if (m_tables[i])
297
- m_tables[i]->resetTransctionInfo(m_thd);
298
- }
299
- if (unlockTables(needUnlock, m_thd, rollback))
300
- {
301
- DEBUG_WRITELOG("UNLOCK TABLES \n")
302
- }
303
- else
304
- {
305
- if (m_thd->is_error())
306
- {
307
- DEBUG_WRITELOG("UNLOCK TABLES ERROR \n");
308
- if (ER_LOCK_WAIT_TIMEOUT == m_thd->cp_get_sql_error())
309
- m_stat = STATUS_CANNOT_LOCK_TABLE;
310
- else
311
- m_stat = m_thd->cp_get_sql_error();
312
- THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "Transaction commit error.");
313
- }
314
- }
315
- if (g_safe_share_mode)
316
- closeForReopen();
317
-
295
+ // All the table lock release
296
+ bool needUnlock =
297
+ (locktype((m_inTransaction > 0), m_thd->lex->sql_command) == TL_WRITE);
298
+ m_inTransaction = 0;
299
+ m_inSnapshot = 0;
300
+ for (int i = 0; i < (int)m_tables.size(); i++)
301
+ {
302
+ if (m_tables[i])
303
+ m_tables[i]->resetTransctionInfo(m_thd);
304
+ }
305
+ if (unlockTables(needUnlock, m_thd, rollback))
306
+ {
307
+ DEBUG_WRITELOG("UNLOCK TABLES \n")
308
+ }
309
+ else
310
+ {
311
+ if (m_thd->is_error())
312
+ {
313
+ DEBUG_WRITELOG("UNLOCK TABLES ERROR \n");
314
+ if (ER_LOCK_WAIT_TIMEOUT == m_thd->cp_get_sql_error())
315
+ m_stat = STATUS_CANNOT_LOCK_TABLE;
316
+ else
317
+ m_stat = m_thd->cp_get_sql_error();
318
+ THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "Transaction commit error.");
319
+ }
320
+ }
321
+ if (g_safe_share_mode)
322
+ closeForReopen();
318
323
  }
319
324
 
320
325
  bool database::beginTrn(short type)
321
326
  {
322
- ++m_inTransaction;
323
- if (m_inTransaction == 1)
324
- {
325
- m_trnType = type;
326
- return true;
327
- }
328
- return false;
327
+ ++m_inTransaction;
328
+ if (m_inTransaction == 1)
329
+ {
330
+ m_trnType = type;
331
+ return true;
332
+ }
333
+ return false;
329
334
  }
330
335
 
331
336
  bool database::commitTrn()
332
337
  {
333
- if (m_inTransaction>0)
334
- {
335
- --m_inTransaction;
336
- if (m_inTransaction==0)
337
- unUseTables(false);
338
- }
339
- return (m_inTransaction == 0);
338
+ if (m_inTransaction > 0)
339
+ {
340
+ --m_inTransaction;
341
+ if (m_inTransaction == 0)
342
+ unUseTables(false);
343
+ }
344
+ return (m_inTransaction == 0);
340
345
  }
341
346
 
342
347
  bool database::abortTrn()
343
348
  {
344
- if (m_inTransaction>0)
345
- {
346
- --m_inTransaction;
347
- if (m_inTransaction==0)
348
- unUseTables(true);
349
- }
350
- return (m_inTransaction == 0);
349
+ if (m_inTransaction > 0)
350
+ {
351
+ --m_inTransaction;
352
+ if (m_inTransaction == 0)
353
+ unUseTables(true);
354
+ }
355
+ return (m_inTransaction == 0);
351
356
  }
352
357
 
353
358
  bool database::beginSnapshot()
354
359
  {
355
- ++m_inSnapshot;
356
- return (m_inSnapshot == 1);
360
+ ++m_inSnapshot;
361
+ return (m_inSnapshot == 1);
357
362
  }
358
363
 
359
364
  bool database::endSnapshot()
360
365
  {
361
- if (m_inSnapshot>0)
362
- {
363
- --m_inSnapshot;
364
- if (m_inSnapshot==0)
365
- unUseTables(false);
366
- }
367
- return (m_inSnapshot == 0);
366
+ if (m_inSnapshot > 0)
367
+ {
368
+ --m_inSnapshot;
369
+ if (m_inSnapshot == 0)
370
+ unUseTables(false);
371
+ }
372
+ return (m_inSnapshot == 0);
368
373
  }
369
374
 
370
- /** Metadata lock, a table name is case-sensitive
375
+ /** Metadata lock, a table name is case-sensitive
371
376
  * However, in actual opening, it is not distinguished at Windows.
372
377
  */
373
- TABLE* database::doOpenTable(const std::string& name, short mode, const char* ownerName)
374
- {
375
- TABLE_LIST tables;
376
- m_thd->variables.lock_wait_timeout = OPEN_TABLE_TIMEOUT_SEC;
377
- tables.init_one_table(m_dbname.c_str(), m_dbname.size(), name.c_str(), name.size(), name.c_str(), TL_READ);
378
- Open_table_context ot_act(m_thd, 0);
379
- if (mode == TD_OPEN_EXCLUSIVE)
380
- tables.mdl_request.set_type(MDL_EXCLUSIVE);
381
- else
382
- tables.mdl_request.set_type(MDL_SHARED_READ);
383
-
384
- if (cp_open_table(m_thd, &tables, &ot_act))
385
- {
386
- m_stat = STATUS_TABLE_NOTOPEN;
387
- if (ER_LOCK_WAIT_TIMEOUT == m_thd->cp_get_sql_error())
388
- m_stat = STATUS_CANNOT_LOCK_TABLE;
389
- THROW_BZS_ERROR_WITH_CODEMSG(m_stat, name.c_str());
390
- }
391
-
392
- //Check owner name
393
- if (ownerName && ownerName[0])
394
- {
395
- const char* p = tables.table->s->comment.str;
396
- if ((p[0] == '%') && (p[1] =='@') && (p[2] =='%'))
397
- {
398
- int readNoNeed = p[3] - '0';
399
- if ((mode == TD_OPEN_READONLY) && readNoNeed)
400
- ;
401
- else if (strcmp(p + 4, ownerName))
402
- {
403
- m_stat = STATUS_INVALID_OWNERNAME;
404
- return NULL;
405
- }
406
- }
407
- }
408
-
409
- tables.table->use_all_columns();
410
- tables.table->open_by_handler = 1;
378
+ TABLE* database::doOpenTable(const std::string& name, short mode,
379
+ const char* ownerName)
380
+ {
381
+ TABLE_LIST tables;
382
+ m_thd->variables.lock_wait_timeout = OPEN_TABLE_TIMEOUT_SEC;
383
+ enum_mdl_type type_arg =
384
+ (mode == TD_OPEN_EXCLUSIVE) ? MDL_EXCLUSIVE : MDL_SHARED_READ;
385
+ thr_lock_type locltype = (mode == TD_OPEN_EXCLUSIVE) ? TL_WRITE : TL_READ;
386
+ tables.init_one_table(m_dbname.c_str(), m_dbname.size(), name.c_str(),
387
+ name.size(), name.c_str(), locltype);
388
+ tables.mdl_request.set_type(type_arg);
389
+
390
+ Open_table_context ot_act(m_thd, MYSQL_OPEN_GET_NEW_TABLE);
391
+ m_thd->cp_set_overwrite_status(true);
392
+ if (cp_open_table(m_thd, &tables, &ot_act))
393
+ {
394
+ m_stat = STATUS_TABLE_NOTOPEN;
395
+ if (ER_LOCK_WAIT_TIMEOUT == m_thd->cp_get_sql_error())
396
+ m_stat = STATUS_CANNOT_LOCK_TABLE;
397
+ THROW_BZS_ERROR_WITH_CODEMSG(m_stat, name.c_str());
398
+ }
399
+
400
+ // Check owner name
401
+ if (ownerName && ownerName[0])
402
+ {
403
+ const char* p = tables.table->s->comment.str;
404
+ if ((p[0] == '%') && (p[1] == '@') && (p[2] == '%'))
405
+ {
406
+ int readNoNeed = p[3] - '0';
407
+ if ((mode == TD_OPEN_READONLY) && readNoNeed)
408
+ ;
409
+ else if (strcmp(p + 4, ownerName))
410
+ {
411
+ m_stat = STATUS_INVALID_OWNERNAME;
412
+ return NULL;
413
+ }
414
+ }
415
+ }
416
+
417
+ tables.table->use_all_columns();
418
+ tables.table->open_by_handler = 1;
411
419
  #if (defined(DEBUG) && defined(WIN32))
412
- char buf[10];
413
- sprintf(buf, "%d", tables.table->field[1]->key_length());
414
- OutputDebugString(buf);
420
+ char buf[10];
421
+ sprintf(buf, "%d", tables.table->field[1]->key_length());
422
+ OutputDebugString(buf);
415
423
  #endif
416
- return tables.table;
424
+ return tables.table;
417
425
  }
418
426
 
419
- table* database::openTable(const std::string& name, short mode, const char* ownerName)
427
+ table* database::openTable(const std::string& name, short mode,
428
+ const char* ownerName)
420
429
  {
421
- if (existsTable(name))
422
- {
423
- tableRef.addref(m_dbname, name);//addef first then table open.
424
- TABLE* t = doOpenTable(name, mode, ownerName);
425
- if (t)
426
- {
427
- boost::shared_ptr<table> tb(new table(t , *this, name, mode, (int)m_tables.size()));
428
- m_tables.push_back(tb);
429
- m_stat = STATUS_SUCCESS;
430
- return tb.get();
431
- }
432
- return NULL;
433
- }
434
- m_stat = STATUS_TABLE_NOTOPEN;
435
- THROW_BZS_ERROR_WITH_CODEMSG(m_stat, name.c_str());
430
+ if (existsTable(name))
431
+ {
432
+
433
+ TABLE* t = doOpenTable(name, mode, ownerName);
434
+ if (t)
435
+ {
436
+ boost::shared_ptr<table> tb(
437
+ new table(t, *this, name, mode, (int)m_tables.size()));
438
+ m_tables.push_back(tb);
439
+ m_stat = STATUS_SUCCESS;
440
+ tableRef.addref(m_dbname, name); // addef first then table open.
441
+ return tb.get();
442
+ }
443
+ return NULL;
444
+ }
445
+ m_stat = STATUS_TABLE_NOTOPEN;
446
+ THROW_BZS_ERROR_WITH_CODEMSG(m_stat, name.c_str());
436
447
  }
437
448
 
438
449
  void database::closeTable(const std::string& name, bool drop)
439
450
  {
440
- for (int i=(int)m_tables.size()-1;i>=0;i--)
441
- {
442
- if (m_tables[i] && (m_tables[i]->m_name == name))
443
- {
444
- m_tables[i].reset();
445
- DEBUG_WRITELOG_SP1("CLOSE TABLE table id=%d \n", i);
446
- }
447
- }
451
+ for (int i = (int)m_tables.size() - 1; i >= 0; i--)
452
+ {
453
+ if (m_tables[i] && (m_tables[i]->m_name == name))
454
+ {
455
+ closeTable(m_tables[i].get());
456
+ return;
457
+ }
458
+ }
459
+ }
460
+
461
+ int tableUseCount(const std::vector<boost::shared_ptr<table> >& tables,
462
+ const char* name)
463
+ {
464
+ int ret = 0;
465
+ for (int i = (int)tables.size() - 1; i >= 0; i--)
466
+ {
467
+ if (tables[i] && (tables[i]->name() == name))
468
+ ++ret;
469
+ }
470
+ return ret;
448
471
  }
449
472
 
450
473
  void database::closeTable(table* tb)
451
474
  {
452
- for (int i=(int)m_tables.size()-1;i>=0;i--)
453
- {
454
- if (m_tables[i] && (m_tables[i].get() == tb))
455
- {
456
- m_tables[i].reset();
457
- DEBUG_WRITELOG_SP1("CLOSE TABLE table id=%d \n", i);
458
- }
459
- }
475
+ for (int i = (int)m_tables.size() - 1; i >= 0; i--)
476
+ {
477
+ if (m_tables[i] && (m_tables[i].get() == tb))
478
+ {
479
+ short mode = tb->m_mode;
480
+ TABLE* src = tb->m_table;
481
+
482
+ unUseTable(m_tables[i].get());
483
+ m_tables[i].reset();
484
+ if (mode == TD_OPEN_EXCLUSIVE)
485
+ {
486
+ if (tableUseCount(m_tables, src->s->table_name.str) == 1)
487
+ {
488
+ for (TABLE** tbl = &m_thd->open_tables; *tbl != 0;
489
+ *tbl = (*tbl)->next)
490
+ {
491
+ if (*tbl == src)
492
+ {
493
+ TABLE* tbptr = (*tbl);
494
+ MDL_ticket* tc = tbptr->mdl_ticket;
495
+ close_thread_table(m_thd, tbl);
496
+ m_thd->mdl_context
497
+ .set_explicit_duration_for_all_locks();
498
+ m_thd->mdl_context.release_all_locks_for_name(tc);
499
+ m_thd->mdl_context
500
+ .set_transaction_duration_for_all_locks();
501
+ }
502
+ break;
503
+ }
504
+ }
505
+ }
506
+
507
+ DEBUG_WRITELOG_SP1("CLOSE TABLE table id=%d \n", i);
508
+ }
509
+ }
460
510
  }
461
511
 
462
512
  void database::closeForReopen()
463
513
  {
464
- //A transaction is committed compulsorily.
465
-
466
- for (size_t i=0;i<m_tables.size();i++)
467
- {
468
- if (m_tables[i] && (m_tables[i]->m_table!=NULL))
469
- m_tables[i]->resetInternalTable(NULL);
470
- }
514
+ // A transaction is committed compulsorily.
515
+
516
+ for (size_t i = 0; i < m_tables.size(); i++)
517
+ {
518
+ if (m_tables[i] && (m_tables[i]->m_table != NULL))
519
+ m_tables[i]->resetInternalTable(NULL);
520
+ }
471
521
 
472
- trans_commit_stmt(m_thd);
473
- close_thread_tables(m_thd);
474
- m_thd->mdl_context.release_transactional_locks();//It is certainly after close_thread_tables.
475
-
522
+ trans_commit_stmt(m_thd);
523
+ if (m_thd->mdl_context.has_locks())
524
+ close_thread_tables(m_thd);
525
+ m_thd->mdl_context.release_transactional_locks();
526
+ // It is certainly after close_thread_tables.
476
527
  }
477
528
 
478
529
  void database::reopen()
479
530
  {
480
- for (size_t i=0;i<m_tables.size();i++)
481
- {
482
- if (m_tables[i] && (m_tables[i]->m_table==NULL))
483
- {
484
- TABLE* table = doOpenTable(m_tables[i]->m_name.c_str(), m_tables[i]->m_mode, NULL);
485
- if (table)
486
- m_tables[i]->resetInternalTable(table);
487
- else
488
- m_tables[i].reset();
489
- }
490
- }
531
+ for (size_t i = 0; i < m_tables.size(); i++)
532
+ {
533
+ if (m_tables[i] && (m_tables[i]->m_table == NULL))
534
+ {
535
+ TABLE* table = doOpenTable(m_tables[i]->m_name.c_str(),
536
+ m_tables[i]->m_mode, NULL);
537
+ if (table)
538
+ m_tables[i]->resetInternalTable(table);
539
+ else
540
+ m_tables[i].reset();
541
+ }
542
+ }
491
543
  }
492
544
 
493
545
  bool database::existsTable(const std::string& name)
494
546
  {
495
- char tmp[FN_REFLEN + 1];
496
-
497
- build_table_filename(tmp, sizeof(tmp) - 1,
498
- m_dbname.c_str(), name.c_str(), reg_ext, 0);
499
- MY_STAT st;
500
- if (mysql_file_stat(0, tmp, &st, MYF(0)))
501
- return true;
502
- return false;
503
-
547
+ char tmp[FN_REFLEN + 1];
548
+
549
+ build_table_filename(tmp, sizeof(tmp) - 1, m_dbname.c_str(), name.c_str(),
550
+ reg_ext, 0);
551
+ MY_STAT st;
552
+ if (mysql_file_stat(0, tmp, &st, MYF(0)))
553
+ return true;
554
+ return false;
504
555
  }
505
556
 
506
557
  bool database::existsDatabase()
507
558
  {
508
- char tmp[FN_REFLEN + 1];
509
- size_t len = build_table_filename(tmp, sizeof(tmp) - 1, m_dbname.c_str(), "", "", 0);
510
- tmp[len-1]= 0x00;
559
+ char tmp[FN_REFLEN + 1];
560
+ size_t len =
561
+ build_table_filename(tmp, sizeof(tmp) - 1, m_dbname.c_str(), "", "", 0);
562
+ tmp[len - 1] = 0x00;
511
563
 
512
- MY_STAT stat;
513
- if (mysql_file_stat(0, tmp, &stat, MYF(0)))
514
- return true;
515
- return false;
564
+ MY_STAT stat;
565
+ if (mysql_file_stat(0, tmp, &stat, MYF(0)))
566
+ return true;
567
+ return false;
516
568
  }
517
569
 
518
570
  class autoincSetup
519
571
  {
520
- TABLE* m_table;
572
+ TABLE* m_table;
573
+
521
574
  public:
522
- autoincSetup(TABLE* table):m_table(table)
523
- {
524
- m_table->next_number_field = m_table->found_next_number_field;
525
- }
526
- ~autoincSetup()
527
- {
528
- m_table->next_number_field = 0;
529
- }
575
+ autoincSetup(TABLE* table) : m_table(table)
576
+ {
577
+ m_table->next_number_field = m_table->found_next_number_field;
578
+ }
579
+
580
+ ~autoincSetup() { m_table->next_number_field = 0; }
530
581
  };
531
582
 
532
583
  /** Number of NIS fields
533
584
  */
534
585
  unsigned short nisFieldNum(TABLE* tb)
535
586
  {
536
- if (tb->s->null_fields)
537
- {
538
- int offset= 1;
539
-
540
- for (unsigned int i=tb->s->fields-offset;i>=0;--i)
541
- if (isNisField(tb->s->field[i]->field_name)==false)
542
- return (unsigned short)(tb->s->fields - i - offset);
543
- return tb->s->fields;
544
- }
545
-
546
- return 0;
587
+ if (tb->s->null_fields)
588
+ {
589
+ int offset = 1;
590
+
591
+ for (int i = tb->s->fields - offset; i >= 0; --i)
592
+ if (isNisField(tb->s->field[i]->field_name) == false)
593
+ return (unsigned short)(tb->s->fields - i - offset);
594
+ return tb->s->fields;
595
+ }
596
+
597
+ return 0;
547
598
  }
548
599
 
549
600
  bool table::noKeybufResult = true;
550
601
 
551
- table::table(TABLE* myTable, database& db, const std::string& name, short mode, int id)
552
- :m_table(myTable),m_db(db),m_name(name), m_mode(mode),m_blobBuffer(NULL)
553
- ,m_id(id),m_keyNum(-1),m_stat(0)
554
- ,m_validCursor(true),m_cursor(false)
555
- ,m_keybuf(new unsigned char[MAX_KEYLEN])
556
- ,m_nonNccKeybuf(new unsigned char[MAX_KEYLEN])
557
- ,m_nonNcc(false),m_bulkInserting(false)
558
- ,m_keyconv(m_table->key_info, m_table->s->keys)
559
- ,m_locked(false),m_changed(false),m_nounlock(false)
560
-
561
- {
562
-
563
- m_table->read_set = &m_table->s->all_set;
564
- m_recordFormatType = RF_VALIABLE_LEN;
565
- m_lastVarLenBytes = 0;
566
-
567
- //Is the Nis field included or not?
568
- m_nullFields = nisFieldNum(m_table);
569
-
570
- if (m_table->s->varchar_fields + m_table->s->blob_fields == 0)
571
- m_recordFormatType = RF_FIXED_LEN;
572
- else if ((m_table->s->varchar_fields == 1) && g_useBtrvVariableTable)
573
- {
574
- Field** fd = m_table->field + lastVarFiledNum();
575
- if (isVarType((*fd)->type()) && ((*fd)->part_of_key.is_clear_all()/* == Bitmap<64>()*/)
576
- && ((*fd)->key_start.is_clear_all()/* == Bitmap<64>()*/)
577
- && (((*fd)->charset()) == &my_charset_bin))
578
- {
579
- m_recordFormatType = RF_FIXED_PLUS_VALIABLE_LEN;
580
-
581
- /* The number of bytes of the length area of the last VAR field */
582
- m_lastVarLenBytes = lastVarFiled()->field_length < 256 ? 1:2;
583
- }
584
- }
585
-
586
- if (m_nullFields)
587
- m_recordFormatType |= RF_INCLUDE_NIS;
588
- m_recordLenCl = (uint)(m_table->s->reclength-(uint)(m_table->s->null_fields>0) - m_nullFields-m_lastVarLenBytes);
589
-
590
- //Chash null field
591
- if (m_table->s->null_fields)
592
- {
593
- for (int i=0;i<(int)m_table->s->fields;++i)
594
- {
595
- Field* fd = m_table->field[i];
596
- if (fd->null_bit && fd->part_of_key.is_clear_all())
597
- m_nonKeySegNullFields.push_back(fd);
598
- }
599
- }
602
+ table::table(TABLE* myTable, database& db, const std::string& name, short mode,
603
+ int id)
604
+ : m_table(myTable), m_name(name), m_mode(mode), m_id(id), m_db(db),
605
+ m_keyNum(-1), m_keybuf(new unsigned char[MAX_KEYLEN]),
606
+ m_nonNccKeybuf(new unsigned char[MAX_KEYLEN]), m_nonNcc(false), m_stat(0),
607
+ m_validCursor(true), m_cursor(false), m_locked(false), m_changed(false),
608
+ m_nounlock(false), m_bulkInserting(false),
609
+ m_keyconv(m_table->key_info, m_table->s->keys), m_blobBuffer(NULL)
610
+
611
+ {
612
+
613
+ m_table->read_set = &m_table->s->all_set;
614
+
615
+ m_recordFormatType = RF_VALIABLE_LEN;
616
+ #ifdef USE_BTRV_VARIABLE_LEN
617
+ m_lastVarLenBytes = 0;
618
+ #endif
619
+ // Is the Nis field included or not?
620
+ m_nullFields = nisFieldNum(m_table);
621
+
622
+ if (m_table->s->varchar_fields + m_table->s->blob_fields == 0)
623
+ m_recordFormatType = RF_FIXED_LEN;
624
+ #ifdef USE_BTRV_VARIABLE_LEN
625
+ else if (m_table->s->varchar_fields == 1)
626
+ {
627
+ Field** fd = m_table->field + lastVarFiledNum();
628
+ if (isVarType((*fd)->type()) && ((*fd)->part_of_key.is_clear_all()) &&
629
+ ((*fd)->key_start.is_clear_all()) &&
630
+ (((*fd)->charset()) == &my_charset_bin))
631
+ {
632
+ m_recordFormatType = RF_FIXED_PLUS_VALIABLE_LEN;
633
+
634
+ /* The number of bytes of the length area of the last VAR field */
635
+ m_lastVarLenBytes = lastVarFiled()->field_length < 256 ? 1 : 2;
636
+ }
637
+ }
638
+ #endif
639
+ if (m_nullFields)
640
+ m_recordFormatType |= RF_INCLUDE_NIS;
641
+ #ifdef USE_BTRV_VARIABLE_LEN
642
+ m_recordLenCl = (uint)(m_table->s->reclength - m_table->s->null_bytes -
643
+ m_nullFields - m_lastVarLenBytes);
644
+ #else
645
+ m_recordLenCl =
646
+ (uint)(m_table->s->reclength - m_table->s->null_bytes - m_nullFields);
647
+ #endif
648
+ // Chash null field
649
+ if (m_table->s->null_fields)
650
+ {
651
+ for (int i = 0; i < (int)m_table->s->fields; ++i)
652
+ {
653
+ Field* fd = m_table->field[i];
654
+ if (fd->null_bit && fd->part_of_key.is_clear_all())
655
+ m_nonKeySegNullFields.push_back(fd);
656
+ }
657
+ }
600
658
  }
601
659
 
602
660
  table::~table()
603
661
  {
604
- resetInternalTable(NULL);
605
- database::tableRef.release(m_db.name(), m_name);
662
+ resetInternalTable(NULL);
663
+ database::tableRef.release(m_db.name(), m_name);
606
664
  }
607
665
 
608
666
  void table::resetTransctionInfo(THD* thd)
609
667
  {
610
- if (m_table)
611
- {
612
- if (m_changed)
613
- query_cache_invalidate3(thd, m_table, 1);
614
- m_changed = false;
615
- m_table->next_number_field = 0;
616
- m_table->file->next_insert_id = 0;
617
- }
618
- m_locked = false;
619
- m_validCursor = false;
620
- m_nounlock = false;
668
+ if (m_table)
669
+ {
670
+ if (m_changed)
671
+ query_cache_invalidate3(thd, m_table, 1);
672
+ m_changed = false;
673
+ m_table->next_number_field = 0;
674
+ m_table->file->next_insert_id = 0;
675
+ }
676
+ m_locked = false;
677
+ m_validCursor = false;
678
+ m_nounlock = false;
621
679
  }
622
680
 
623
681
  void table::resetInternalTable(TABLE* table)
624
682
  {
625
- if (table==NULL)
626
- {
627
- if (m_table)
628
- m_table->file->ha_index_or_rnd_end();
629
- m_table = NULL;
630
- }else
631
- {
632
- m_table = table;
633
- m_table->read_set = &m_table->s->all_set;
634
- m_locked = false;
635
- m_changed = false;
636
- m_validCursor = false;
637
- m_nounlock = false;
638
-
639
- }
683
+ if (table == NULL)
684
+ {
685
+ if (m_table)
686
+ m_table->file->ha_index_or_rnd_end();
687
+ m_table = NULL;
688
+ }
689
+ else
690
+ {
691
+ m_table = table;
692
+ m_table->read_set = &m_table->s->all_set;
693
+ m_locked = false;
694
+ m_changed = false;
695
+ m_validCursor = false;
696
+ m_nounlock = false;
697
+ }
640
698
  }
641
699
 
642
700
  bool table::setNonKey(bool scan)
643
701
  {
644
- if (m_keyNum != -2)
645
- {
646
- m_table->file->ha_index_or_rnd_end();
647
- m_table->file->ha_rnd_init(scan);
648
- m_keyNum = -2;
649
- }
650
- return true;
702
+ if (m_keyNum != -2)
703
+ {
704
+ m_table->file->ha_index_or_rnd_end();
705
+ int ret = m_table->file->ha_rnd_init(scan);
706
+ if (ret)
707
+ THROW_BZS_ERROR_WITH_CODEMSG(ERROR_INDEX_RND_INIT,
708
+ "setNonKey rnd_init error.");
709
+ m_keyNum = -2;
710
+ }
711
+ return true;
651
712
  }
652
713
 
653
714
  bool table::setKeyNum(char num, bool sorted)
654
715
  {
655
- if ((m_keyNum != num) || ((m_keyNum >= 0)&& (m_table->file->inited == handler::NONE)))
656
- {
657
- m_table->file->ha_index_or_rnd_end();
658
-
659
- if(keynumCheck(num))
660
- {
661
- m_keyNum = num;
662
- m_table->file->ha_index_init(m_keyNum, sorted);
663
- return true;
664
- }
665
- else
666
- {
667
- m_stat = STATUS_INVALID_KEYNUM;
668
- return false;
669
- }
670
- }
671
- return true;
716
+ if ((m_keyNum != num) ||
717
+ ((m_keyNum >= 0) && (m_table->file->inited == handler::NONE)))
718
+ {
719
+ m_table->file->ha_index_or_rnd_end();
720
+
721
+ if (keynumCheck(num))
722
+ {
723
+ m_keyNum = num;
724
+ m_table->file->ha_index_init(m_keyNum, sorted);
725
+ return true;
726
+ }
727
+ else
728
+ {
729
+ m_stat = STATUS_INVALID_KEYNUM;
730
+ return false;
731
+ }
732
+ }
733
+ return true;
672
734
  }
673
735
 
674
736
  void table::fillNull(uchar* ptr, int size)
675
737
  {
676
- for (int i = 0;i < size;i++)
677
- {
678
- if (ptr[i] == 0)
679
- {
680
- memset(ptr + i, 0, size - i);
681
- break;
682
- }
683
- }
738
+ for (int i = 0; i < size; i++)
739
+ {
740
+ if (ptr[i] == 0)
741
+ {
742
+ memset(ptr + i, 0, size - i);
743
+ break;
744
+ }
745
+ }
684
746
  }
685
747
 
686
748
  void table::setKeyValues(const uchar* ptr, int size)
687
749
  {
688
- KEY& key = m_table->key_info[m_keyNum];
689
- memcpy(&m_keybuf[0], ptr, std::min(MAX_KEYLEN, size));
690
- int pos = 0;
691
- for (int j = 0; j < (int)key.user_defined_key_parts; j++)
692
- {
693
- KEY_PART_INFO& seg = key.key_part[j];
694
- if (seg.field->type()==MYSQL_TYPE_STRING)
695
- fillNull(&m_keybuf[pos], seg.field->pack_length());
696
- pos+=seg.field->pack_length();
697
- }
750
+ KEY& key = m_table->key_info[m_keyNum];
751
+ memcpy(&m_keybuf[0], ptr, std::min(MAX_KEYLEN, size));
752
+ int pos = 0;
753
+ for (int j = 0; j < (int)key.user_defined_key_parts; j++)
754
+ {
755
+ KEY_PART_INFO& seg = key.key_part[j];
756
+ if (seg.field->type() == MYSQL_TYPE_STRING)
757
+ fillNull(&m_keybuf[pos], seg.field->pack_length());
758
+ pos += seg.field->pack_length();
759
+ }
698
760
  }
699
761
 
700
762
  /**
701
- If null able field segment that need add null indicator byte befor segment.
702
- Then key buffer length equal key length + null able segments.
703
-
704
- The purpose of null key is non create index.
705
- At read operation set not null(zero) to null indicator.
706
-
707
- Size bytes of var and blob field is 2 byte fixed.
708
- All most of key_part.length(segment lenght) is equal field.pack_length.
709
- But blob and prefix index is not equal pack_length.
710
-
711
- Client needs to make the right image except for null byte.
712
- */
713
- void table::setKeyValuesPacked(const uchar* ptr, int size)
714
- {
715
-
716
- KEY& key = m_table->key_info[m_keyNum];
717
- int to = 0;
718
- const uchar* from = ptr;
719
- uint key_length = key.key_length;
720
-
721
- for (int j = 0; j < (int)key.user_defined_key_parts; j++)
722
- {
723
- KEY_PART_INFO& seg = key.key_part[j];
724
- if (seg.null_bit)
725
- {
726
- m_keybuf[to++] = 0x00;
727
- seg.field->set_notnull();
728
- }
729
- if (seg.null_bit && isNisField(seg.field->field_name))
730
- {
731
- m_keybuf[to++] = 0x00;
732
- seg.field->set_notnull();
733
- }
734
- else
735
- {
736
- int copylen = seg.length;
737
- if (seg.key_part_flag & HA_BLOB_PART || seg.key_part_flag & HA_VAR_LENGTH_PART)
738
- copylen += 2;
739
- memcpy(&m_keybuf[to], from, copylen);
740
- to += copylen;
741
- from += copylen;
742
-
743
- if (to>=MAX_KEYLEN)
744
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_KEYBUFFERTOOSMALL, "");
745
- }
746
- }
747
-
763
+ If null able field segment that need add null indicator byte befor segment.
764
+ Then key buffer length equal key length + null able segments.
765
+
766
+ The purpose of null key is non create index.
767
+ At read operation set not null(zero) to null indicator.
768
+
769
+ Size bytes of var and blob field is 2 byte fixed.
770
+ All most of key_part.length(segment lenght) is equal field.pack_length.
771
+ But blob and prefix index is not equal pack_length.
772
+
773
+ Client needs to make the right image except for null byte.
774
+ */
775
+ short table::setKeyValuesPacked(const uchar* ptr, int size)
776
+ {
777
+ KEY& key = m_table->key_info[m_keyNum];
778
+ int to = 0;
779
+ const uchar* from = ptr;
780
+ int ret = -1;
781
+ for (int j = 0; j < (int)key.user_defined_key_parts; j++)
782
+ {
783
+ KEY_PART_INFO& seg = key.key_part[j];
784
+ if (seg.null_bit)
785
+ {
786
+ m_keybuf[to++] = 0x00;
787
+ seg.field->set_notnull();
788
+ }
789
+ if (seg.null_bit && isNisField(seg.field->field_name))
790
+ {
791
+ m_keybuf[to++] = 0x00;
792
+ seg.field->set_notnull();
793
+ }
794
+ else
795
+ {
796
+ unsigned short copylen = seg.length; // length = store_len - varlen
797
+ unsigned short copyspace = copylen;
798
+ if (seg.key_part_flag & HA_BLOB_PART ||
799
+ seg.key_part_flag & HA_VAR_LENGTH_PART)
800
+ {
801
+ copylen += 2; // varlen= allways 2byte
802
+ copyspace = copylen;
803
+ unsigned short len = *((unsigned short*)from) + 2;
804
+ copylen = std::min<unsigned short>(copylen, len);
805
+ if (copylen != copyspace)
806
+ memset(&m_keybuf[to], 0, copyspace);
807
+ }
808
+
809
+ if ((from + copylen) - ptr > size)
810
+ {
811
+ if (ret == -1)
812
+ ret = j;
813
+ // key data size is too short as whole key_parts length
814
+ memset(&m_keybuf[to], 0, copyspace);
815
+ }
816
+ else
817
+ {
818
+ memcpy(&m_keybuf[to], from, copylen);
819
+ from += copyspace;
820
+ }
821
+ to += copyspace;
822
+
823
+ if (to >= MAX_KEYLEN)
824
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_KEYBUFFERTOOSMALL, "");
825
+ }
826
+ }
827
+ return ret;
748
828
  }
749
829
 
750
830
  uint table::keyPackCopy(uchar* ptr)
751
831
  {
752
- //if nokey and getbookmark operation then keynum = -2
753
- if (m_keyNum < 0) return 0;
754
-
755
- KEY& key = m_table->key_info[m_keyNum];
756
- if ((key.flags & HA_NULL_PART_KEY) || (key.flags & HA_VAR_LENGTH_KEY))
757
- {
758
- int from = 0;
759
- uchar* to = ptr;
760
- uint key_length = key.key_length;
761
-
762
- for (int j = 0; j < (int)key.user_defined_key_parts; j++)
763
- {
764
- KEY_PART_INFO& seg = key.key_part[j];
765
- if (seg.null_bit)
766
- from++;
767
- if (seg.null_bit && isNisField(seg.field->field_name))
768
- from++;
769
- else
770
- {
771
- int copylen = seg.length;
772
- if (seg.key_part_flag & HA_BLOB_PART || seg.key_part_flag & HA_VAR_LENGTH_PART)
773
- copylen += 2;
774
- memcpy(to, &m_keybuf[from], copylen);
775
- to += copylen;
776
- from += copylen;
777
-
778
- }
779
- }
780
- return (uint)(to-ptr);
781
- }
782
- memcpy(ptr, keybuf(), keylen());
783
- return keylen();
784
- }
785
-
786
- void* table::record()const
787
- {
788
- Field* fd = m_table->field[0];
789
- return fd->ptr;
790
- }
791
-
792
- /** if offset and lastVarLenBytes() is non zero that is m_recordFormatType=RF_FIXED_PLUS_VALIABLE_LEN.
832
+ // if nokey and getbookmark operation then keynum = -2
833
+ if (m_keyNum < 0)
834
+ return 0;
835
+
836
+ KEY& key = m_table->key_info[m_keyNum];
837
+ if ((key.flags & HA_NULL_PART_KEY) || (key.flags & HA_VAR_LENGTH_KEY))
838
+ {
839
+ int from = 0;
840
+ uchar* to = ptr;
841
+ for (int j = 0; j < (int)key.user_defined_key_parts; j++)
842
+ {
843
+ KEY_PART_INFO& seg = key.key_part[j];
844
+ if (seg.null_bit)
845
+ from++;
846
+ if (seg.null_bit && isNisField(seg.field->field_name))
847
+ from++;
848
+ else
849
+ {
850
+ int copylen = seg.length;
851
+ if (seg.key_part_flag & HA_BLOB_PART ||
852
+ seg.key_part_flag & HA_VAR_LENGTH_PART)
853
+ copylen += 2;
854
+ memcpy(to, &m_keybuf[from], copylen);
855
+ to += copylen;
856
+ from += copylen;
857
+ }
858
+ }
859
+ return (uint)(to - ptr);
860
+ }
861
+ memcpy(ptr, keybuf(), keylen());
862
+ return keylen();
863
+ }
864
+
865
+ void* table::record() const
866
+ {
867
+ Field* fd = m_table->field[0];
868
+ return fd->ptr;
869
+ }
870
+
871
+ /** if offset and lastVarLenBytes() is non zero that is
872
+ * m_recordFormatType=RF_FIXED_PLUS_VALIABLE_LEN.
793
873
  * ptr is excluding null flag sgement.
794
874
  */
795
875
  void table::setRecord(void* ptr, unsigned short size, int offset)
796
876
  {
797
- m_cursor = false;
798
- Field* fd = m_table->field[0];//remove null flag segment
799
- if (offset + size <= (unsigned short)m_table->s->reclength + lastVarLenBytes())
800
- {
801
- if (size>0)
802
- memcpy(fd->ptr + offset, ptr, size);
803
- }
804
- else
805
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_DATASIZE, "");
877
+ m_cursor = false;
878
+ Field* fd = m_table->field[0]; // remove null flag segment
879
+ #ifdef USE_BTRV_VARIABLE_LEN
880
+ if (offset + size <=
881
+ (unsigned short)m_table->s->reclength + lastVarLenBytes())
882
+ {
883
+ #else
884
+ if (offset + size <= (unsigned short)m_table->s->reclength)
885
+ {
886
+
887
+ #endif
888
+
889
+ if (size > 0)
890
+ memcpy(fd->ptr + offset, ptr, size);
891
+ }
892
+ else
893
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_DATASIZE, "");
806
894
  }
807
895
 
808
896
  inline bool isNull(Field* fd)
809
897
  {
810
- if (isVarType(fd->type()))
811
- {
812
- int len = *((unsigned char*)fd->ptr);
813
- if (fd->field_length>255)
814
- len = *((unsigned short*)fd->ptr);
815
-
816
- return (len==0);
817
- }
818
- else if (isBlobType(fd->type()))
819
- return (0==blob_len(fd));
820
- else
821
- {
822
- unsigned int k=0;
823
- for (k=0;k<fd->key_length();k++)
824
- if (fd->ptr[k]) break;
825
-
826
- if (k==fd->key_length())
827
- return true;
828
- }
829
- return false;
898
+ if (isVarType(fd->type()))
899
+ {
900
+ int len = *((unsigned char*)fd->ptr);
901
+ if (fd->field_length > 255)
902
+ len = *((unsigned short*)fd->ptr);
903
+
904
+ return (len == 0);
905
+ }
906
+ else if (isBlobType(fd->type()))
907
+ return (0 == blob_len(fd));
908
+ else
909
+ {
910
+ unsigned int k = 0;
911
+ for (k = 0; k < fd->key_length(); k++)
912
+ if (fd->ptr[k])
913
+ break;
914
+
915
+ if (k == fd->key_length())
916
+ return true;
917
+ }
918
+ return false;
830
919
  }
831
920
 
832
921
  inline bool isNullNis(KEY& key, bool all)
833
922
  {
834
- for (int j=1;j<(int)key.user_defined_key_parts;j++)
835
- {
836
- Field* fd = key.key_part[j].field;
837
- if (key.key_part[j].null_bit)
838
- {
839
- bool v = isNull(fd);
840
- v ? fd->set_null():fd->set_notnull();
841
- if (all && !v)
842
- return false;
843
- else if(!all && v)
844
- return true;
845
- }
846
- }
847
- if (all)
848
- return true;
849
- return false;
923
+ for (int j = 1; j < (int)key.user_defined_key_parts; j++)
924
+ {
925
+ Field* fd = key.key_part[j].field;
926
+ if (key.key_part[j].null_bit)
927
+ {
928
+ bool v = isNull(fd);
929
+ v ? fd->set_null() : fd->set_notnull();
930
+ if (all && !v)
931
+ return false;
932
+ else if (!all && v)
933
+ return true;
934
+ }
935
+ }
936
+ if (all)
937
+ return true;
938
+ return false;
850
939
  }
851
940
 
852
941
  void table::setBlobFieldPointer(const bzs::db::blobHeader* hd)
853
942
  {
854
-
855
- if (hd)
943
+
944
+ if (hd)
856
945
  {
857
946
  assert(hd->curRow < hd->rows);
858
- const blobField* f = hd->nextField;
859
- for (int i=0;i<hd->fieldCount;i++)
947
+ const blobField* f = hd->nextField;
948
+ for (int i = 0; i < hd->fieldCount; i++)
860
949
  {
861
950
  Field* fd = m_table->field[f->fieldNum];
862
951
  int sizeByte = blob_var_bytes(fd);
863
952
  memcpy(fd->ptr, &f->size, sizeByte);
864
953
  const char* data = f->data();
865
- memcpy(fd->ptr+sizeByte, &data, sizeof(char*));
954
+ memcpy(fd->ptr + sizeByte, &data, sizeof(char*));
866
955
  f = f->next();
867
956
  }
868
- ++hd->curRow;
957
+ ++hd->curRow;
869
958
  hd->nextField = (blobField*)f;
870
959
  }
871
-
872
960
  }
873
961
 
874
962
  /** A packed data set to the record buffer.
875
963
  */
876
- void table::setRecordFromPacked(const uchar* packedPtr, uint size, const bzs::db::blobHeader* hd)
877
- {
878
- const uchar* p = packedPtr;
879
- if (recordFormatType() & RF_FIXED_PLUS_VALIABLE_LEN)
880
- {
881
- int varlenbyte = lastVarLenBytes();
882
- int varlenStartPos = lastVarFieldPos();
883
- setRecord((void*)p, varlenStartPos);
884
- int len = std::min((int)(size - varlenStartPos), (int)recordLenCl() - varlenStartPos);
885
- if (len > 0)
886
- {
887
- setRecord(&len, varlenbyte, varlenStartPos);
888
- //if (len > 0)
889
- setRecord((void*)(p + varlenStartPos), len, varlenStartPos + varlenbyte);
890
- }else if (len == 0)
891
- ;
892
- else
893
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_BUFFERTOOSMALL, "copyDataTo");
894
- }else if ((recordFormatType() & RF_VALIABLE_LEN)
895
- || (recordFormatType() & RF_INCLUDE_NIS))
896
- {
897
- //It copies for every field.
898
- for (uint i=0;i<m_table->s->fields;i++)
899
- {
900
- Field* fd = m_table->field[i];
901
- if (isNisField(fd->field_name))
902
- fd->ptr[0] = 0x00;//The Nis field is not sent from a client.
903
- else
904
- {
905
- int len = fd->pack_length();
906
- if (isVarType(fd->type()))
907
- len = var_total_len(p, var_bytes(fd));
908
-
909
- memcpy(fd->ptr, p, len);
910
- p += len;
911
- }
912
- }
913
- if (m_table->s->blob_fields)
914
- setBlobFieldPointer(hd);
915
- }
916
- else
917
- setRecord((void*)p, std::min(size, recordLenCl()));
918
-
919
- }
920
-
921
- /** A record image is packed, and is copied to the specified buffer, and length is returned.
922
- * -maxsize can be specified when recordFormatType() is RF_VALIABLE_LEN.
923
- * -Length is not inspected if maxsize is zero.
924
- * -When a buffer is too short, zero is returned to a result.
964
+ void table::setRecordFromPacked(const uchar* packedPtr, uint size,
965
+ const bzs::db::blobHeader* hd)
966
+ {
967
+ const uchar* p = packedPtr;
968
+
969
+ #ifdef USE_BTRV_VARIABLE_LEN
970
+ if (recordFormatType() & RF_FIXED_PLUS_VALIABLE_LEN)
971
+ {
972
+ int varlenbyte = lastVarLenBytes();
973
+ int varlenStartPos = lastVarFieldPos();
974
+ setRecord((void*)p, varlenStartPos);
975
+ int len = std::min((int)(size - varlenStartPos),
976
+ (int)recordLenCl() - varlenStartPos);
977
+ if (len > 0)
978
+ {
979
+ setRecord(&len, varlenbyte, varlenStartPos);
980
+ // if (len > 0)
981
+ setRecord((void*)(p + varlenStartPos), len,
982
+ varlenStartPos + varlenbyte);
983
+ }
984
+ else if (len == 0)
985
+ ;
986
+ else
987
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_BUFFERTOOSMALL,
988
+ "setRecordFromPacked");
989
+ }
990
+ else if ((recordFormatType() & RF_VALIABLE_LEN) ||
991
+ (recordFormatType() & RF_INCLUDE_NIS))
992
+ {
993
+ #else
994
+ if ((recordFormatType() & RF_VALIABLE_LEN) ||
995
+ (recordFormatType() & RF_INCLUDE_NIS))
996
+ {
997
+ #endif
998
+ // It copies for every field.
999
+ for (uint i = 0; i < m_table->s->fields; i++)
1000
+ {
1001
+ Field* fd = m_table->field[i];
1002
+ if (isNisField(fd->field_name))
1003
+ fd->ptr[0] = 0x00; // The Nis field is not sent from a client.
1004
+ else
1005
+ {
1006
+ int len = fd->pack_length();
1007
+ if (isVarType(fd->type()))
1008
+ {
1009
+ len = var_total_len(p, var_bytes(fd));
1010
+ if (len > (int)fd->pack_length())
1011
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_BUFFERTOOSMALL,
1012
+ "setRecordFromPacked");
1013
+ }
1014
+ else if (size < (uint)len)
1015
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_BUFFERTOOSMALL,
1016
+ "setRecordFromPacked");
1017
+ memcpy(fd->ptr, p, len);
1018
+ p += len;
1019
+ size -= len;
1020
+ }
1021
+ }
1022
+ if (m_table->s->blob_fields)
1023
+ setBlobFieldPointer(hd);
1024
+ }
1025
+ else
1026
+ setRecord((void*)p, std::min(size, recordLenCl()));
1027
+ }
1028
+
1029
+ /** A record image is packed, and is copied to the specified buffer, and length
1030
+ *is returned.
1031
+ * -maxsize can be specified when recordFormatType() is RF_VALIABLE_LEN.
1032
+ * -Length is not inspected if maxsize is zero.
1033
+ * -When a buffer is too short, zero is returned to a result.
925
1034
  */
926
- uint table::recordPackCopy(char* buf, uint maxsize)
927
- {
928
- char* p = buf;
929
-
930
- if ((recordFormatType() & RF_VALIABLE_LEN)
931
- || (recordFormatType() & RF_INCLUDE_NIS))
932
- {
933
- int blobs = 0;
934
- for (uint i=0;i<m_table->s->fields;i++)
935
- {
936
- Field* fd = m_table->field[i];
937
- if (isNisField(fd->field_name))
938
- ;//The Nis field is not sent to a client.
939
- else
940
- {
941
- uint len = fd->pack_length();
942
- if (isVarType(fd->type()))
943
- len = var_total_len(fd);
944
- if (maxsize && ((p - buf + len) > maxsize))
945
- return 0;
946
- memcpy(p, fd->ptr, len);
947
- p+=len;
948
- if (isBlobType(fd->type()))
949
- {
950
- ++blobs;
951
- addBlobBuffer(fd->field_index);
952
- }
953
- }
954
- }
955
- setBlobFieldCount(blobs);
956
- }else
957
- {
958
- uint varLenBytes = lastVarLenBytes();
959
- uint varLenBytesPos = lastVarFieldPos();
960
- const uchar* data = (const uchar *) record();
961
- int len = recordLenCl();
962
- if (varLenBytes)
963
- {
964
- memcpy(p, data, varLenBytesPos);
965
- p += varLenBytesPos;
966
- data += varLenBytesPos;
967
- if (varLenBytes == 1)
968
- len = *data;
969
- else
970
- len = *((const unsigned short*)data);
971
- //In the variable length of tdap type, it returns except for varsize.
972
- data += varLenBytes;
973
- }
974
- memcpy(p, data, len);
975
- p += len;
976
- }
977
- return (uint)(p - buf);
1035
+ uint table::recordPackCopy(char* buf, uint maxsize)
1036
+ {
1037
+ char* p = buf;
1038
+ #ifdef USE_BTRV_VARIABLE_LEN
1039
+ if (recordFormatType() & RF_FIXED_PLUS_VALIABLE_LEN)
1040
+ {
1041
+ uint varLenBytes = lastVarLenBytes();
1042
+ uint varLenBytesPos = lastVarFieldPos();
1043
+ const uchar* data = (const uchar*)record();
1044
+ int len = recordLenCl();
1045
+ if (varLenBytes)
1046
+ {
1047
+ memcpy(p, data, varLenBytesPos);
1048
+ p += varLenBytesPos;
1049
+ data += varLenBytesPos;
1050
+ if (varLenBytes == 1)
1051
+ len = *data;
1052
+ else
1053
+ len = *((const unsigned short*)data);
1054
+ // In the variable length of tdap type, it returns except for
1055
+ // varsize.
1056
+ data += varLenBytes;
1057
+ }
1058
+ memcpy(p, data, len);
1059
+ p += len;
1060
+ }
1061
+ else if ((recordFormatType() & RF_VALIABLE_LEN) ||
1062
+ (recordFormatType() & RF_INCLUDE_NIS))
1063
+ {
1064
+ #else
1065
+ if ((recordFormatType() & RF_VALIABLE_LEN) ||
1066
+ (recordFormatType() & RF_INCLUDE_NIS))
1067
+ {
1068
+ #endif
1069
+ int blobs = 0;
1070
+ for (uint i = 0; i < m_table->s->fields; i++)
1071
+ {
1072
+ Field* fd = m_table->field[i];
1073
+ if (isNisField(fd->field_name))
1074
+ ;
1075
+ // The Nis field is not sent to a client.
1076
+ else
1077
+ {
1078
+ uint len = fd->pack_length();
1079
+ if (isVarType(fd->type()))
1080
+ len = var_total_len(fd);
1081
+ if (maxsize && ((p - buf + len) > maxsize))
1082
+ return 0;
1083
+ memcpy(p, fd->ptr, len);
1084
+ p += len;
1085
+ if (isBlobType(fd->type()))
1086
+ {
1087
+ ++blobs;
1088
+ addBlobBuffer(fd->field_index);
1089
+ }
1090
+ }
1091
+ }
1092
+ setBlobFieldCount(blobs);
1093
+ }
1094
+ else
1095
+ {
1096
+ const uchar* data = (const uchar*)record();
1097
+ int len = recordLenCl();
1098
+ memcpy(p, data, len);
1099
+ p += len;
1100
+ }
1101
+ return (uint)(p - buf);
978
1102
  }
979
1103
 
980
- inline bool table::keynumCheck(char num)
1104
+ ushort table::fieldPackCopy(unsigned char* dest, short filedNum)
981
1105
  {
982
- return ((num>=0) && (num < (short)m_table->s->keys));
983
- //||(num == m_table->s->primary_key));
1106
+ Field* fd = m_table->field[filedNum];
1107
+ uint len = fd->pack_length();
1108
+ if (isVarType(fd->type()))
1109
+ len = var_total_len(fd);
1110
+ #ifdef USE_BTRV_VARIABLE_LEN
1111
+ if (lastVarFiledNum() == filedNum)
1112
+ {
1113
+ len -= lastVarLenBytes();
1114
+ memcpy(dest, fd->ptr + lastVarLenBytes(), len);
1115
+ }
1116
+ else
1117
+ #endif
1118
+ memcpy(dest, fd->ptr, len);
1119
+ return (ushort)len;
1120
+ }
984
1121
 
1122
+ inline bool table::keynumCheck(char num)
1123
+ {
1124
+ return ((num >= 0) && (num < (short)m_table->s->keys));
985
1125
  }
986
1126
 
987
1127
  inline void table::unlockRow()
988
1128
  {
989
- if (!m_nounlock && m_validCursor && m_db.inTransaction() && (m_db.transactionType()== 0))
990
- {
991
- m_table->file->unlock_row();
992
- m_nounlock = false;
993
- }
994
-
1129
+ if (!m_nounlock && m_validCursor && m_db.inTransaction() &&
1130
+ (m_db.transactionType() == 0))
1131
+ {
1132
+ m_table->file->unlock_row();
1133
+ m_nounlock = false;
1134
+ }
995
1135
  }
1136
+
996
1137
  /* read by key
997
1138
  * A key field value is set in advance
998
1139
  */
999
- void table::seekKey(enum ha_rkey_function find_flag)
1000
- {
1001
- m_nonNcc = false;
1002
- if(keynumCheck(m_keyNum))
1003
- {
1004
- unlockRow();
1005
- m_stat = m_table->file->ha_index_read_map(m_table->record[0], &m_keybuf[0], keymap(), find_flag);
1006
- m_cursor = m_validCursor = (m_stat == 0);
1007
- if (m_stat==0)
1008
- {
1009
- if (find_flag != HA_READ_KEY_EXACT)
1010
- key_copy(&m_keybuf[0], m_table->record[0], &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1011
- }
1012
- }else
1013
- m_stat = STATUS_INVALID_KEYNUM;
1014
- if ((m_stat == HA_ERR_KEY_NOT_FOUND) && (find_flag != HA_READ_KEY_EXACT))
1015
- m_stat = HA_ERR_END_OF_FILE;
1140
+ void table::seekKey(enum ha_rkey_function find_flag, key_part_map keyMap)
1141
+ {
1142
+ m_nonNcc = false;
1143
+ if (keynumCheck(m_keyNum))
1144
+ {
1145
+ unlockRow();
1146
+ m_stat = m_table->file->ha_index_read_map(
1147
+ m_table->record[0], &m_keybuf[0], keyMap /* keymap() */, find_flag);
1148
+ m_cursor = m_validCursor = (m_stat == 0);
1149
+ if (m_stat == 0)
1150
+ {
1151
+ if (find_flag != HA_READ_KEY_EXACT)
1152
+ key_copy(&m_keybuf[0], m_table->record[0],
1153
+ &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1154
+ }
1155
+ }
1156
+ else
1157
+ m_stat = STATUS_INVALID_KEYNUM;
1158
+ if ((m_stat == HA_ERR_KEY_NOT_FOUND) && (find_flag != HA_READ_KEY_EXACT))
1159
+ m_stat = HA_ERR_END_OF_FILE;
1016
1160
  }
1017
1161
 
1018
1162
  void table::moveKey(boost::function<int()> func)
1019
1163
  {
1020
- m_nonNcc = false;
1021
- if(keynumCheck(m_keyNum))
1022
- {
1023
- unlockRow();
1024
-
1025
- m_stat = func();
1026
- m_cursor = m_validCursor = (m_stat == 0);
1027
- if (m_stat == 0)
1028
- key_copy(&m_keybuf[0], m_table->record[0], &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1029
- }else
1030
- m_stat = STATUS_INVALID_KEYNUM;
1031
- if (m_stat == HA_ERR_KEY_NOT_FOUND)
1032
- m_stat = HA_ERR_END_OF_FILE;
1033
-
1034
- }
1035
-
1036
- void table::getNextSame()
1037
- {
1038
- m_nonNcc = false;
1039
- if(keynumCheck(m_keyNum))
1040
- {
1041
- if (m_validCursor && m_db.inTransaction() && (m_db.transactionType()== 0))
1042
- m_table->file->unlock_row();
1043
- m_stat = m_table->file->ha_index_next_same(m_table->record[0], &m_keybuf[0], keymap());
1044
- m_cursor = m_validCursor = (m_stat == 0);
1045
- if (m_stat==0)
1046
- key_copy(&m_keybuf[0], m_table->record[0], &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1047
- }else
1048
- m_stat = STATUS_INVALID_KEYNUM;
1164
+ m_nonNcc = false;
1165
+ if (keynumCheck(m_keyNum))
1166
+ {
1167
+ unlockRow();
1168
+
1169
+ m_stat = func();
1170
+ m_cursor = m_validCursor = (m_stat == 0);
1171
+ if (m_stat == 0)
1172
+ key_copy(&m_keybuf[0], m_table->record[0],
1173
+ &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1174
+ }
1175
+ else
1176
+ m_stat = STATUS_INVALID_KEYNUM;
1177
+ if (m_stat == HA_ERR_KEY_NOT_FOUND)
1178
+ m_stat = HA_ERR_END_OF_FILE;
1179
+ }
1180
+
1181
+ void table::getNextSame(key_part_map keyMap)
1182
+ {
1183
+ m_nonNcc = false;
1184
+ if (keynumCheck(m_keyNum))
1185
+ {
1186
+ if (m_validCursor && m_db.inTransaction() &&
1187
+ (m_db.transactionType() == 0))
1188
+ m_table->file->unlock_row();
1189
+ m_stat = m_table->file->ha_index_next_same(
1190
+ m_table->record[0], &m_keybuf[0], keyMap /* keymap() */);
1191
+ m_cursor = m_validCursor = (m_stat == 0);
1192
+ if (m_stat == 0)
1193
+ key_copy(&m_keybuf[0], m_table->record[0],
1194
+ &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1195
+ }
1196
+ else
1197
+ m_stat = STATUS_INVALID_KEYNUM;
1049
1198
  }
1050
1199
 
1051
1200
  void table::getLast()
1052
1201
  {
1053
- moveKey(boost::bind(&handler::ha_index_last, m_table->file, m_table->record[0]));
1202
+ moveKey(boost::bind(&handler::ha_index_last, m_table->file,
1203
+ m_table->record[0]));
1054
1204
  }
1055
1205
 
1056
1206
  void table::getFirst()
1057
1207
  {
1058
- moveKey(boost::bind(&handler::ha_index_first, m_table->file, m_table->record[0]));
1059
-
1208
+ moveKey(boost::bind(&handler::ha_index_first, m_table->file,
1209
+ m_table->record[0]));
1210
+
1060
1211
  #if (defined(DEBUG) && defined(WIN32))
1061
1212
 
1062
- char buf[1024];
1063
- sprintf(buf, "name=%s reclength=%d rec_buff_length=%d\r\n",m_name.c_str(), m_table->s->reclength
1064
- ,m_table->s->rec_buff_length);
1065
- OutputDebugString(buf);
1066
- for (uint i=0;i<m_table->s->fields;i++)
1067
- {
1068
- Field* fd = m_table->s->field[i];
1069
-
1070
- sprintf(buf, "\tpack_length=%d field_length=%d key_length=%d\r\n",fd->pack_length()
1071
- , fd->field_length,fd->key_length());
1072
- OutputDebugString(buf);
1073
- }
1213
+ char buf[1024];
1214
+ sprintf(buf, "name=%s reclength=%d rec_buff_length=%d\r\n", m_name.c_str(),
1215
+ m_table->s->reclength, m_table->s->rec_buff_length);
1216
+ OutputDebugString(buf);
1217
+ for (uint i = 0; i < m_table->s->fields; i++)
1218
+ {
1219
+ Field* fd = m_table->s->field[i];
1220
+
1221
+ sprintf(buf, "\tpack_length=%d field_length=%d key_length=%d\r\n",
1222
+ fd->pack_length(), fd->field_length, fd->key_length());
1223
+ OutputDebugString(buf);
1224
+ }
1074
1225
  #endif
1075
1226
  }
1076
1227
 
1077
1228
  void table::getNext()
1078
1229
  {
1079
- if (!m_cursor)
1080
- {
1081
- m_stat = HA_ERR_NO_ACTIVE_RECORD;
1082
- return ;
1083
- }
1084
- if (m_nonNcc)
1085
- {//It moves to the position after updating.
1086
- //Since it may be lost, ref is compared and the next is decided.
1087
- movePos(position(true), m_keyNum, true);
1088
- if (m_stat) return ;
1089
- }
1090
- moveKey(boost::bind(&handler::ha_index_next, m_table->file, m_table->record[0]));
1091
-
1230
+ if (!m_cursor)
1231
+ {
1232
+ m_stat = HA_ERR_NO_ACTIVE_RECORD;
1233
+ return;
1234
+ }
1235
+ if (m_nonNcc)
1236
+ { // It moves to the position after updating.
1237
+ // Since it may be lost, ref is compared and the next is decided.
1238
+ movePos(position(true), m_keyNum, true);
1239
+ if (m_stat)
1240
+ return;
1241
+ }
1242
+ moveKey(boost::bind(&handler::ha_index_next, m_table->file,
1243
+ m_table->record[0]));
1092
1244
  }
1093
1245
 
1094
1246
  void table::getPrev()
1095
1247
  {
1096
- if (!m_cursor)
1097
- {
1098
- m_stat = HA_ERR_NO_ACTIVE_RECORD;
1099
- return ;
1100
- }
1101
- if (m_nonNcc)
1102
- {
1103
- movePos(position(true), m_keyNum, true);
1104
- if (m_stat) return ;
1105
- }
1106
- moveKey(boost::bind(&handler::ha_index_prev, m_table->file, m_table->record[0]));
1248
+ if (!m_cursor)
1249
+ {
1250
+ m_stat = HA_ERR_NO_ACTIVE_RECORD;
1251
+ return;
1252
+ }
1253
+ if (m_nonNcc)
1254
+ {
1255
+ movePos(position(true), m_keyNum, true);
1256
+ if (m_stat)
1257
+ return;
1258
+ }
1259
+ moveKey(boost::bind(&handler::ha_index_prev, m_table->file,
1260
+ m_table->record[0]));
1107
1261
  }
1108
1262
 
1109
1263
  bool table::keyCheckForPercent()
1110
1264
  {
1111
- if (m_keyNum == -1)
1112
- m_keyNum = m_table->s->primary_key;
1113
- //The value of the beginning of a key
1114
- KEY& key = m_table->key_info[m_keyNum];
1115
- if (key.key_length > 128)
1116
- return false;
1117
- return true;
1265
+ if (m_keyNum == -1)
1266
+ m_keyNum = m_table->s->primary_key;
1267
+ // The value of the beginning of a key
1268
+ KEY& key = m_table->key_info[m_keyNum];
1269
+ if (key.key_length > 128)
1270
+ return false;
1271
+ return true;
1118
1272
  }
1119
1273
 
1120
1274
  void table::preBuildPercent(uchar* first, uchar* last)
1121
1275
  {
1122
- KEY& key = m_table->key_info[m_keyNum];
1123
- getFirst();
1124
- if (m_stat == 0)
1125
- {
1126
- key_copy(first, m_table->record[0], &key, KEYLEN_ALLCOPY);
1127
- getLast();
1128
- if (m_stat == 0)
1129
- {
1130
- key_copy(last, m_table->record[0], &key, KEYLEN_ALLCOPY);
1131
- memset(m_keybuf.get(), 0, MAX_KEYLEN);
1132
- }else
1133
- THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "connot seek last position.");
1134
- }else
1135
- THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "connot seek first position.");
1276
+ KEY& key = m_table->key_info[m_keyNum];
1277
+ getFirst();
1278
+ if (m_stat == 0)
1279
+ {
1280
+ key_copy(first, m_table->record[0], &key, KEYLEN_ALLCOPY);
1281
+ getLast();
1282
+ if (m_stat == 0)
1283
+ {
1284
+ key_copy(last, m_table->record[0], &key, KEYLEN_ALLCOPY);
1285
+ memset(m_keybuf.get(), 0, MAX_KEYLEN);
1286
+ }
1287
+ else
1288
+ THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "connot seek last position.");
1289
+ }
1290
+ else
1291
+ THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "connot seek first position.");
1136
1292
  }
1137
1293
 
1138
1294
  void table::getByPercentage(unsigned short per)
1139
1295
  {
1140
- m_nonNcc = false;
1141
- if (!keyCheckForPercent())
1142
- {
1143
- m_stat = STATUS_INVALID_KEYNUM;
1144
- return ;
1145
- }
1146
- if (per > 9800)
1147
- {
1148
- getLast();
1149
- return;
1150
- }else if(per < 200)
1151
- {
1152
- getFirst();
1153
- return;
1154
- }
1155
-
1156
- uchar keybufFirst[MAX_KEYLEN]={0x00};
1157
- uchar keybufLast[MAX_KEYLEN]={0x00};
1158
- preBuildPercent(keybufFirst, keybufLast);
1159
- if (m_stat == 0)
1160
- {
1161
- //5% of position is obtained.
1162
- uchar* st = keybufFirst;
1163
- uchar* en = keybufLast;
1164
- uchar* cu = (uchar*) keybuf();
1165
- KEY& key = m_table->key_info[m_keyNum];
1166
- uint keylen = key.key_length + 10;
1167
- boost::shared_array<uchar> stbuf(new uchar[keylen]);
1168
- boost::shared_array<uchar> lsbuf(new uchar[keylen]);
1169
- boost::shared_array<uchar> stbufResult(new uchar[keylen]);
1170
- boost::shared_array<uchar> lsbufResult(new uchar[keylen]);
1171
- percentageKey pk(key, st, en, cu);
1172
- bool forwoard=true;
1173
- int ov = 0;
1174
- int sameCount = 0;
1175
- while(1)
1176
- {
1177
- pk.reset(st, en, cu);
1178
- int ret = pk.setKeyValueByPer(5000, forwoard);
1179
- if (ret == KEY_ALL_SGMENTS_SAME)
1180
- break;//THROW_BZS_ERROR_WITH_CODEMSG(1, "first and last record are same key value.");
1181
- else if(ret == KEY_NEED_SGMENT_COPY)
1182
- pk.copyFirstDeferentSegment();
1183
- int v = percentage(keybufFirst, keybufLast, cu)-1000;
1184
- (ov == v)?++sameCount:sameCount= 0;
1185
- if (sameCount > 100)
1186
- break;
1187
- ov = v;
1188
- if (v < -250)
1189
- {
1190
- memcpy(stbuf.get(), cu, keylen);
1191
- st = stbuf.get();
1192
- forwoard = true;
1193
- }else if (v > 250)
1194
- {
1195
- memcpy(lsbuf.get(), cu, keylen);
1196
- en = lsbuf.get();
1197
- forwoard = false;
1198
- }else
1199
- break;
1200
- }
1201
- memcpy(stbufResult.get(), cu, keylen);
1202
- if (per > 1000)
1203
- {
1204
- //95% of position is obtained.
1205
- forwoard=true;
1206
- memcpy(cu, keybufLast, keylen);
1207
- memcpy(lsbuf.get(), keybufLast, keylen);
1208
- en = lsbuf.get();
1209
- while(1)
1210
- {
1211
- pk.reset(st, en, cu);
1212
- int ret = pk.setKeyValueByPer(5000, forwoard);
1213
- if (ret == KEY_ALL_SGMENTS_SAME)
1214
- break;///THROW_BZS_ERROR_WITH_CODEMSG(1, "connot seek percant position.");
1215
- else if(ret == KEY_NEED_SGMENT_COPY)
1216
- pk.copyFirstDeferentSegment();
1217
- int v = percentage(keybufFirst, keybufLast, cu)-9000;
1218
- (ov == v)?++sameCount:sameCount= 0;
1219
- if (sameCount > 100)
1220
- break;
1221
- ov = v;
1222
- if (v < -250)
1223
- {
1224
- memcpy(stbuf.get(), cu, keylen);
1225
- st = stbuf.get();
1226
- forwoard = true;
1227
- }else if (v > 250)
1228
- {
1229
- memcpy(lsbuf.get(), cu, keylen);
1230
- en = lsbuf.get();
1231
- forwoard = false;
1232
- }else
1233
- break;
1234
- }
1235
- memcpy(lsbufResult.get(), cu, keylen);
1236
- pk.reset(stbufResult.get(), lsbufResult.get(), cu);
1237
-
1238
- pk.setKeyValueByPer( per, true);
1239
- }
1240
- seekKey(HA_READ_KEY_OR_NEXT);
1241
- }
1242
-
1296
+ m_nonNcc = false;
1297
+ if (!keyCheckForPercent())
1298
+ {
1299
+ m_stat = STATUS_INVALID_KEYNUM;
1300
+ return;
1301
+ }
1302
+ if (per > 9800)
1303
+ {
1304
+ getLast();
1305
+ return;
1306
+ }
1307
+ else if (per < 200)
1308
+ {
1309
+ getFirst();
1310
+ return;
1311
+ }
1312
+
1313
+ uchar keybufFirst[MAX_KEYLEN] = { 0x00 };
1314
+ uchar keybufLast[MAX_KEYLEN] = { 0x00 };
1315
+ preBuildPercent(keybufFirst, keybufLast);
1316
+ if (m_stat == 0)
1317
+ {
1318
+ // 5% of position is obtained.
1319
+ uchar* st = keybufFirst;
1320
+ uchar* en = keybufLast;
1321
+ uchar* cu = (uchar*)keybuf();
1322
+ KEY& key = m_table->key_info[m_keyNum];
1323
+ uint keylen = key.key_length + 10;
1324
+ boost::shared_array<uchar> stbuf(new uchar[keylen]);
1325
+ boost::shared_array<uchar> lsbuf(new uchar[keylen]);
1326
+ boost::shared_array<uchar> stbufResult(new uchar[keylen]);
1327
+ boost::shared_array<uchar> lsbufResult(new uchar[keylen]);
1328
+ percentageKey pk(key, st, en, cu);
1329
+ bool forwoard = true;
1330
+ int ov = 0;
1331
+ int sameCount = 0;
1332
+ while (1)
1333
+ {
1334
+ pk.reset(st, en, cu);
1335
+ int ret = pk.setKeyValueByPer(5000, forwoard);
1336
+ if (ret == KEY_ALL_SGMENTS_SAME)
1337
+ break; // THROW_BZS_ERROR_WITH_CODEMSG(1, "first and last record
1338
+ // are same key value.");
1339
+ else if (ret == KEY_NEED_SGMENT_COPY)
1340
+ pk.copyFirstDeferentSegment();
1341
+ int v = percentage(keybufFirst, keybufLast, cu) - 1000;
1342
+ (ov == v) ? ++sameCount : sameCount = 0;
1343
+ if (sameCount > 100)
1344
+ break;
1345
+ ov = v;
1346
+ if (v < -250)
1347
+ {
1348
+ memcpy(stbuf.get(), cu, keylen);
1349
+ st = stbuf.get();
1350
+ forwoard = true;
1351
+ }
1352
+ else if (v > 250)
1353
+ {
1354
+ memcpy(lsbuf.get(), cu, keylen);
1355
+ en = lsbuf.get();
1356
+ forwoard = false;
1357
+ }
1358
+ else
1359
+ break;
1360
+ }
1361
+ memcpy(stbufResult.get(), cu, keylen);
1362
+ if (per > 1000)
1363
+ {
1364
+ // 95% of position is obtained.
1365
+ forwoard = true;
1366
+ memcpy(cu, keybufLast, keylen);
1367
+ memcpy(lsbuf.get(), keybufLast, keylen);
1368
+ en = lsbuf.get();
1369
+ while (1)
1370
+ {
1371
+ pk.reset(st, en, cu);
1372
+ int ret = pk.setKeyValueByPer(5000, forwoard);
1373
+ if (ret == KEY_ALL_SGMENTS_SAME)
1374
+ break;
1375
+ /// THROW_BZS_ERROR_WITH_CODEMSG(1, "connot seek percant
1376
+ /// position.");
1377
+ else if (ret == KEY_NEED_SGMENT_COPY)
1378
+ pk.copyFirstDeferentSegment();
1379
+ int v = percentage(keybufFirst, keybufLast, cu) - 9000;
1380
+ (ov == v) ? ++sameCount : sameCount = 0;
1381
+ if (sameCount > 100)
1382
+ break;
1383
+ ov = v;
1384
+ if (v < -250)
1385
+ {
1386
+ memcpy(stbuf.get(), cu, keylen);
1387
+ st = stbuf.get();
1388
+ forwoard = true;
1389
+ }
1390
+ else if (v > 250)
1391
+ {
1392
+ memcpy(lsbuf.get(), cu, keylen);
1393
+ en = lsbuf.get();
1394
+ forwoard = false;
1395
+ }
1396
+ else
1397
+ break;
1398
+ }
1399
+ memcpy(lsbufResult.get(), cu, keylen);
1400
+ pk.reset(stbufResult.get(), lsbufResult.get(), cu);
1401
+
1402
+ pk.setKeyValueByPer(per, true);
1403
+ }
1404
+ seekKey(HA_READ_KEY_OR_NEXT, keymap());
1405
+ }
1243
1406
  }
1244
1407
 
1245
1408
  int table::percentage(uchar* first, uchar* last, uchar* cur)
1246
1409
  {
1247
- m_table->file->init_table_handle_for_HANDLER() ;
1248
- KEY& key = m_table->key_info[m_keyNum];
1249
- // 1 cur to last
1250
- key_range minkey;
1251
- minkey.key = cur;
1252
- minkey.length = key.key_length;
1253
- minkey.keypart_map = keymap();
1254
- minkey.flag = HA_READ_KEY_EXACT;
1255
- key_range maxkey = minkey;
1256
- maxkey.key = last;
1257
- ha_rows rows1 = m_table->file->records_in_range(m_keyNum, &minkey, &maxkey);
1258
-
1259
- //2 first to last
1260
- maxkey.key = first;
1261
- ha_rows rows2 = m_table->file->records_in_range(m_keyNum, &maxkey, &minkey);
1262
-
1263
- //3 record count
1264
- ha_rows total = recordCount(true);
1265
-
1266
- //result
1267
- int v1 =10000-(int)(rows1*(double)10000/total);
1268
-
1269
- int v2 =(int)(rows2*(double)10000/total);
1270
- if (abs(5000-v1) > abs(5000-v2))
1271
- return v1;
1272
- return v2;
1410
+ initHandler();
1411
+ KEY& key = m_table->key_info[m_keyNum];
1412
+ // 1 cur to last
1413
+ key_range minkey;
1414
+ minkey.key = cur;
1415
+ minkey.length = key.key_length;
1416
+ minkey.keypart_map = keymap();
1417
+ minkey.flag = HA_READ_KEY_EXACT;
1418
+ key_range maxkey = minkey;
1419
+ maxkey.key = last;
1420
+ ha_rows rows1 = m_table->file->records_in_range(m_keyNum, &minkey, &maxkey);
1421
+
1422
+ // 2 first to last
1423
+ maxkey.key = first;
1424
+ ha_rows rows2 = m_table->file->records_in_range(m_keyNum, &maxkey, &minkey);
1425
+
1426
+ // 3 record count
1427
+ ha_rows total = recordCount(true);
1428
+
1429
+ // result
1430
+ int v1 = 10000 - (int)(rows1 * (double)10000 / total);
1431
+
1432
+ int v2 = (int)(rows2 * (double)10000 / total);
1433
+ if (abs(5000 - v1) > abs(5000 - v2))
1434
+ return v1;
1435
+ return v2;
1273
1436
  }
1274
1437
 
1275
1438
  void table::calcPercentage()
1276
- {
1277
- if (!keyCheckForPercent())
1278
- {
1279
- m_stat = STATUS_INVALID_KEYNUM;
1280
- return;
1281
- }
1282
- m_percentResult = 0;
1283
- //The present key value is copied.
1284
- uchar keybufCur[MAX_KEYLEN]={0x00};
1285
- key_copy(keybufCur, m_table->record[0], &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1286
-
1287
- uchar keybufFirst[MAX_KEYLEN]={0x00};
1288
- uchar keybufLast[MAX_KEYLEN]={0x00};
1289
- preBuildPercent(keybufFirst, keybufLast);
1290
-
1291
- if (m_stat == 0)
1292
- { //restore current
1293
- setKeyValues(keybufCur, 128);
1294
- seekKey(HA_READ_KEY_EXACT);
1295
- if (m_stat == 0)
1296
- m_percentResult = percentage(keybufFirst,keybufLast, keybufCur);
1297
- }
1439
+ {
1440
+ if (!keyCheckForPercent())
1441
+ {
1442
+ m_stat = STATUS_INVALID_KEYNUM;
1443
+ return;
1444
+ }
1445
+ m_percentResult = 0;
1446
+ // The present key value is copied.
1447
+ uchar keybufCur[MAX_KEYLEN] = { 0x00 };
1448
+ key_copy(keybufCur, m_table->record[0], &m_table->key_info[m_keyNum],
1449
+ KEYLEN_ALLCOPY);
1450
+
1451
+ uchar keybufFirst[MAX_KEYLEN] = { 0x00 };
1452
+ uchar keybufLast[MAX_KEYLEN] = { 0x00 };
1453
+ preBuildPercent(keybufFirst, keybufLast);
1454
+
1455
+ if (m_stat == 0)
1456
+ { // restore current
1457
+ setKeyValues(keybufCur, 128);
1458
+ seekKey(HA_READ_KEY_EXACT, keymap());
1459
+ if (m_stat == 0)
1460
+ m_percentResult = percentage(keybufFirst, keybufLast, keybufCur);
1461
+ }
1298
1462
  }
1299
1463
 
1300
1464
  void table::stepFirst()
1301
1465
  {
1302
- if (m_table->s->primary_key < m_table->s->keys)
1303
- {
1304
- setKeyNum(m_table->s->primary_key);
1305
- getFirst();
1306
- }else
1307
- {
1308
- if (setNonKey(true))
1309
- {
1310
- m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1311
- m_cursor = m_validCursor = (m_stat == 0);
1312
- }
1313
- else
1314
- m_stat = STATUS_INVALID_KEYNUM;
1315
- }
1466
+ if (m_table->s->primary_key < m_table->s->keys)
1467
+ {
1468
+ setKeyNum(m_table->s->primary_key);
1469
+ getFirst();
1470
+ }
1471
+ else
1472
+ {
1473
+ if (setNonKey(true))
1474
+ {
1475
+ m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1476
+ m_cursor = m_validCursor = (m_stat == 0);
1477
+ }
1478
+ else
1479
+ m_stat = STATUS_INVALID_KEYNUM;
1480
+ }
1316
1481
  }
1317
1482
 
1318
1483
  void table::stepLast()
1319
1484
  {
1320
- if (m_table->s->primary_key < m_table->s->keys)
1321
- {
1322
- setKeyNum(m_table->s->primary_key);
1323
- getLast();
1324
- }else
1325
- m_stat = STATUS_NOSUPPORT_OP;
1485
+ if (m_table->s->primary_key < m_table->s->keys)
1486
+ {
1487
+ setKeyNum(m_table->s->primary_key);
1488
+ getLast();
1489
+ }
1490
+ else
1491
+ m_stat = STATUS_NOSUPPORT_OP;
1326
1492
  }
1327
1493
 
1328
1494
  void table::stepNext()
1329
1495
  {
1330
- m_nonNcc = false;
1331
- if (m_table->s->primary_key < m_table->s->keys)
1332
- {
1333
- setKeyNum(m_table->s->primary_key);
1334
- getNext();
1335
- }else
1336
- {
1337
- if (m_keyNum != -2)
1338
- {
1339
- if (setNonKey(false))
1340
- {
1341
- m_stat = m_table->file->ha_rnd_pos(m_table->record[0], (uchar*)position(true));
1342
- if (m_stat != 0)return;
1343
- }
1344
- }
1345
- m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1346
- m_cursor = m_validCursor = (m_stat == 0);
1347
- }
1496
+ m_nonNcc = false;
1497
+ if (m_table->s->primary_key < m_table->s->keys)
1498
+ {
1499
+ setKeyNum(m_table->s->primary_key);
1500
+ getNext();
1501
+ }
1502
+ else
1503
+ {
1504
+ if (m_keyNum != -2)
1505
+ {
1506
+ if (setNonKey(false))
1507
+ {
1508
+ m_stat = m_table->file->ha_rnd_pos(m_table->record[0],
1509
+ (uchar*)position(true));
1510
+ if (m_stat != 0)
1511
+ return;
1512
+ }
1513
+ }
1514
+ m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1515
+ m_cursor = m_validCursor = (m_stat == 0);
1516
+ }
1348
1517
  }
1349
1518
 
1350
1519
  void table::stepPrev()
1351
1520
  {
1352
- m_nonNcc = false;
1353
- if (m_table->s->primary_key < m_table->s->keys)
1354
- {
1355
- setKeyNum(m_table->s->primary_key);
1356
- getPrev();
1357
- }
1358
- else
1359
- m_stat = STATUS_NOSUPPORT_OP;
1360
- }
1361
-
1362
- void table::readRecords(IReadRecordsHandler* hdr, bool includeCurrent, int type)
1363
- {
1364
- if ((m_table->file->inited == handler::NONE) || !m_cursor)
1365
- {
1366
- m_stat = STATUS_NO_CURRENT;
1367
- return;
1368
- }
1369
- m_nonNcc = false;
1370
- int reject = (hdr->rejectCount()==0)?4096:hdr->rejectCount();
1371
- if (reject==0xFFFF)
1372
- reject = -1;
1373
- int rows = hdr->maxRows();
1374
-
1375
- //Is a current position read or not?
1376
- bool read = !includeCurrent;
1377
- bool unlock = (!m_db.inSnapshot() && !m_db.inTransaction()) || (m_db.inTransaction() && (m_db.transactionType()== 0));
1378
- bool forword = (type == READ_RECORD_GETNEXT) || (type == READ_RECORD_STEPNEXT);
1379
- while((reject!=0) && (rows!=0))
1380
- {
1381
- if (read)
1382
- {
1383
-
1384
- if (unlock && !m_nounlock && m_validCursor)
1385
- {
1386
- m_table->file->unlock_row();
1387
- m_nounlock = false;
1388
- }
1389
-
1390
- if (type == READ_RECORD_GETNEXT)
1391
- m_stat = m_table->file->ha_index_next(m_table->record[0]);
1392
- else if (type == READ_RECORD_GETPREV)
1393
- m_stat = m_table->file->ha_index_prev(m_table->record[0]);
1394
- else if (type == READ_RECORD_STEPNEXT)
1395
- m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1396
- else if (type == READ_RECORD_STEPPREV)
1397
- {
1398
- m_stat = STATUS_NOSUPPORT_OP;
1399
- return;
1400
- }
1401
- m_cursor = m_validCursor = (m_stat == 0);
1402
- }else
1403
- read = true;
1404
-
1405
-
1406
- if (m_stat)
1407
- break;
1408
- int ret = hdr->match(forword);
1409
- if (ret == REC_MACTH)
1410
- {
1411
- m_stat = hdr->write(position(), posPtrLen());
1412
- if (m_stat) break;
1413
- --rows;
1414
- }
1415
- else if (ret == REC_NOMACTH_NOMORE)
1416
- {
1417
- m_stat = STATUS_REACHED_FILTER_COND;
1418
- return ;
1419
- }
1420
- else
1421
- --reject;
1422
- }
1423
- //m_cursor = m_validCursor = (m_stat == 0);
1424
- if (reject ==0)
1425
- m_stat = STATUS_LIMMIT_OF_REJECT;
1426
-
1427
-
1428
- }
1429
-
1430
- /* seek to pos by ref
1521
+ m_nonNcc = false;
1522
+ if (m_table->s->primary_key < m_table->s->keys)
1523
+ {
1524
+ setKeyNum(m_table->s->primary_key);
1525
+ getPrev();
1526
+ }
1527
+ else
1528
+ m_stat = STATUS_NOSUPPORT_OP;
1529
+ }
1530
+
1531
+ void table::readRecords(IReadRecordsHandler* hdr, bool includeCurrent, int type,
1532
+ bool noBookmark)
1533
+ {
1534
+
1535
+ if ((m_table->file->inited == handler::NONE) || !m_cursor)
1536
+ {
1537
+ m_stat = STATUS_NO_CURRENT;
1538
+ return;
1539
+ }
1540
+ initHandler();
1541
+ m_nonNcc = false;
1542
+ int reject = (hdr->rejectCount() == 0) ? 4096 : hdr->rejectCount();
1543
+ if (reject == 0xFFFF)
1544
+ reject = -1;
1545
+ int rows = hdr->maxRows();
1546
+
1547
+ // dummy bookmark , use if bobbokmark=true
1548
+ unsigned int tmp = 0;
1549
+ const uchar* bm = (unsigned char*)&tmp;
1550
+
1551
+ // Is a current position read or not?
1552
+ bool read = !includeCurrent;
1553
+ bool unlock = (!m_db.inSnapshot() && !m_db.inTransaction()) ||
1554
+ (m_db.inTransaction() && (m_db.transactionType() == 0));
1555
+ bool forword =
1556
+ (type == READ_RECORD_GETNEXT) || (type == READ_RECORD_STEPNEXT);
1557
+ while ((reject != 0) && (rows != 0))
1558
+ {
1559
+ if (read)
1560
+ {
1561
+
1562
+ if (unlock && !m_nounlock && m_validCursor)
1563
+ {
1564
+ m_table->file->unlock_row();
1565
+ m_nounlock = false;
1566
+ }
1567
+
1568
+ if (type == READ_RECORD_GETNEXT)
1569
+ m_stat = m_table->file->ha_index_next(m_table->record[0]);
1570
+ else if (type == READ_RECORD_GETPREV)
1571
+ m_stat = m_table->file->ha_index_prev(m_table->record[0]);
1572
+ else if (type == READ_RECORD_STEPNEXT)
1573
+ m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1574
+ else if (type == READ_RECORD_STEPPREV)
1575
+ {
1576
+ m_stat = STATUS_NOSUPPORT_OP;
1577
+ return;
1578
+ }
1579
+ m_cursor = m_validCursor = (m_stat == 0);
1580
+ }
1581
+ else
1582
+ read = true;
1583
+
1584
+ if (m_stat)
1585
+ break;
1586
+ int ret = hdr->match(forword);
1587
+ if (ret == REC_MACTH)
1588
+ {
1589
+
1590
+ if (!noBookmark)
1591
+ bm = position();
1592
+ m_stat = hdr->write(bm, posPtrLen());
1593
+ if (m_stat)
1594
+ break;
1595
+ --rows;
1596
+ }
1597
+ else if (ret == REC_NOMACTH_NOMORE)
1598
+ {
1599
+ m_stat = STATUS_REACHED_FILTER_COND;
1600
+ return;
1601
+ }
1602
+ else
1603
+ --reject;
1604
+ }
1605
+ if (reject == 0)
1606
+ m_stat = STATUS_LIMMIT_OF_REJECT;
1607
+ }
1608
+
1609
+ /* seek to pos by ref
1431
1610
  * need before set keybuf and keynum
1432
1611
  */
1433
- //private
1434
- void table::seekPos(const uchar* rawPos)
1435
- {
1436
- seekKey(HA_READ_KEY_OR_NEXT);
1437
- if (m_keyNum == m_table->s->primary_key)
1438
- return;
1439
- int cmp;
1440
- while ((m_stat==0) && ((cmp = m_table->file->cmp_ref(position(true), rawPos))!=0))
1441
- {
1442
- unlockRow();
1443
- m_table->file->ha_index_next_same(m_table->record[0], &m_keybuf[0], keymap());
1444
- }
1612
+ // private
1613
+ void table::seekPos(const uchar* rawPos)
1614
+ {
1615
+ seekKey(HA_READ_KEY_OR_NEXT, keymap());
1616
+ if (m_keyNum == (int)m_table->s->primary_key)
1617
+ return;
1618
+ int cmp;
1619
+ while ((m_stat == 0) &&
1620
+ ((cmp = m_table->file->cmp_ref(position(true), rawPos)) != 0))
1621
+ {
1622
+ unlockRow();
1623
+ m_table->file->ha_index_next_same(m_table->record[0], &m_keybuf[0],
1624
+ keymap());
1625
+ }
1445
1626
  }
1446
1627
 
1447
1628
  void table::movePos(const uchar* pos, char keyNum, bool sureRawValue)
1448
1629
  {
1449
- const uchar* rawPos = pos;
1450
- if (!sureRawValue && (m_table->file->ref_length > REF_SIZE_MAX))
1451
- rawPos = bms()->getRefByBm(*(unsigned int*)pos);
1452
-
1453
- setNonKey();
1454
- unlockRow();
1455
- m_stat = m_table->file->ha_rnd_pos(m_table->record[0], (uchar*)rawPos);
1456
- m_cursor = (m_stat == 0);
1457
- if ((keyNum==-1)||(keyNum==-64))
1458
- return ;
1459
- if (m_stat==0)
1460
- {
1461
- if (m_keyNum != keyNum)
1462
- {// need key change
1463
- key_copy(&m_keybuf[0], m_table->record[0], &m_table->key_info[keyNum], KEYLEN_ALLCOPY);
1464
- //It seek(s) until ref becomes the same, since it is a duplication key.
1465
- setKeyNum(keyNum);
1466
- seekPos(rawPos);
1467
- }
1468
- }
1630
+ const uchar* rawPos = pos;
1631
+ if (!sureRawValue && (m_table->file->ref_length > REF_SIZE_MAX))
1632
+ rawPos = bms()->getRefByBm(*(unsigned int*)pos);
1633
+
1634
+ setNonKey();
1635
+ unlockRow();
1636
+ m_stat = m_table->file->ha_rnd_pos(m_table->record[0], (uchar*)rawPos);
1637
+ m_cursor = (m_stat == 0);
1638
+ if ((keyNum == -1) || (keyNum == -64) || (keyNum == -2))
1639
+ return;
1640
+ if (m_stat == 0)
1641
+ {
1642
+ if (m_keyNum != keyNum)
1643
+ { // need key change
1644
+ key_copy(&m_keybuf[0], m_table->record[0],
1645
+ &m_table->key_info[keyNum], KEYLEN_ALLCOPY);
1646
+ // It seek(s) until ref becomes the same, since it is a duplication
1647
+ // key.
1648
+ setKeyNum(keyNum);
1649
+ seekPos(rawPos);
1650
+ }
1651
+ }
1469
1652
  }
1470
1653
 
1471
- bookmarks* table::bms()
1654
+ bookmarks* table::bms()
1472
1655
  {
1473
- if (m_bms==NULL)
1474
- m_bms.reset(new bookmarks(m_table->file->ref_length));
1475
- return m_bms.get();
1656
+ if (m_bms == NULL)
1657
+ m_bms.reset(new bookmarks(m_table->file->ref_length));
1658
+ return m_bms.get();
1476
1659
  }
1477
1660
 
1478
1661
  /** get current record bookmark (position)
@@ -1480,123 +1663,121 @@ bookmarks* table::bms()
1480
1663
  */
1481
1664
  const uchar* table::position(bool raw)
1482
1665
  {
1483
- m_table->file->position(m_table->record[0]);// handler is set uniqu number to ref.
1484
- if (!raw && (m_table->file->ref_length > REF_SIZE_MAX))
1485
- return bms()->getBookmarkPtr(m_table->file->ref);
1486
- return m_table->file->ref;
1666
+ m_table->file->position(m_table->record[0]);
1667
+ // handler is set uniqu number to ref.
1668
+ if (!raw && (m_table->file->ref_length > REF_SIZE_MAX))
1669
+ return bms()->getBookmarkPtr(m_table->file->ref);
1670
+ return m_table->file->ref;
1487
1671
  }
1488
1672
 
1489
- uint table::posPtrLen()const
1673
+ uint table::posPtrLen() const
1490
1674
  {
1491
- return std::min(m_table->file->ref_length, (uint)REF_SIZE_MAX) ;
1675
+ return std::min(m_table->file->ref_length, (uint)REF_SIZE_MAX);
1492
1676
  }
1493
1677
 
1494
1678
  ha_rows table::recordCount(bool estimate)
1495
1679
  {
1496
- if ((m_table->file->ha_table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0)
1497
- return m_table->file->records();
1498
- if (estimate)
1499
- { //Since the answer of innodb is random, 1 returns also 0.
1500
- //Since it is important, in the case of 1
1501
- //, whether there is nothing or it is scan and investigate.
1502
- m_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1503
- ha_rows rows = m_table->file->records();
1504
- if (rows>1)
1505
- return rows;
1506
- }
1507
- uint n = 0;
1508
- m_table->read_set = &m_table->tmp_set;
1509
- m_table->write_set = &m_table->tmp_set;
1510
- bitmap_clear_all(m_table->read_set);
1511
- //bitmap_clear_all(m_table->write_set);
1512
-
1513
- char keynum = m_keyNum;
1514
- int inited = m_table->file->inited;
1515
- m_table->file->ha_index_or_rnd_end();
1516
-
1517
- m_table->file->extra(HA_EXTRA_KEYREAD);
1518
- if (setKeyNum((char)0, false/*sorted*/))
1519
- {
1520
- m_stat = m_table->file->ha_index_first(m_table->record[0]);
1521
- while (m_stat == 0)
1522
- {
1523
- n++;
1524
- m_stat = m_table->file->ha_index_next(m_table->record[0]);
1525
- }
1526
- m_table->file->extra(HA_EXTRA_NO_KEYREAD);
1527
-
1528
- //restore index init
1529
- if ((inited == (int)handler::INDEX) && (m_keyNum != keynum))
1530
- setKeyNum(keynum);
1531
- else if((inited == (int)handler::RND))
1532
- setNonKey(true/*scan*/);
1533
- }
1534
- else
1535
- {
1536
- setNonKey(true/*scan*/);
1537
- m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1538
- while (m_stat == 0)
1539
- {
1540
- n++;
1541
- m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1542
- }
1543
- }
1544
- m_table->file->extra(HA_EXTRA_NO_KEYREAD);
1545
- m_table->read_set = &m_table->s->all_set;
1546
- m_table->write_set = &m_table->s->all_set;
1547
- return n;
1680
+ if ((m_table->file->ha_table_flags() &
1681
+ (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0)
1682
+ return m_table->file->records();
1683
+ if (estimate)
1684
+ { // Since the answer of innodb is random, 1 returns also 0.
1685
+ // Since it is important, in the case of 1
1686
+ // , whether there is nothing or it is scan and investigate.
1687
+ m_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1688
+ ha_rows rows = m_table->file->records();
1689
+ if (rows > 1)
1690
+ return rows;
1691
+ }
1692
+ uint n = 0;
1693
+ fieldBitmap fb(m_table);
1694
+ char keynum = m_keyNum;
1695
+ int inited = m_table->file->inited;
1696
+ m_table->file->ha_index_or_rnd_end();
1697
+ fb.setKeyRead(true);
1698
+ if (setKeyNum((char)0, false /* sorted */))
1699
+ {
1700
+ initHandler();
1701
+ m_stat = m_table->file->ha_index_first(m_table->record[0]);
1702
+ while (m_stat == 0)
1703
+ {
1704
+ n++;
1705
+ m_stat = m_table->file->ha_index_next(m_table->record[0]);
1706
+ }
1707
+ fb.setKeyRead(false);
1708
+
1709
+ // restore index init
1710
+ if ((inited == (int)handler::INDEX) && (m_keyNum != keynum))
1711
+ setKeyNum(keynum);
1712
+ else if (inited == (int)handler::RND)
1713
+ setNonKey(true /* scan */);
1714
+ }
1715
+ else
1716
+ {
1717
+ setNonKey(true /* scan */);
1718
+ initHandler();
1719
+ m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1720
+ while (m_stat == 0)
1721
+ {
1722
+ ++n;
1723
+ m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1724
+ }
1725
+ }
1726
+ return n;
1548
1727
  }
1549
1728
 
1550
1729
  void table::clearBuffer()
1551
1730
  {
1552
- unsigned char* p = m_table->record[0];
1553
- empty_record(m_table);
1731
+ empty_record(m_table);
1554
1732
  }
1555
1733
 
1556
1734
  bool table::isNisKey(char num) const
1557
1735
  {
1558
- if((num>=0) && (num < (short)m_table->s->keys))
1559
- {
1560
- Field* fd = m_table->key_info[num].key_part[0].field; //Nis is only in a head segment.
1561
- if (isNisField(fd->field_name))
1562
- return true;
1563
- else if((fd->pack_length() == 1) && (fd->type() == MYSQL_TYPE_TINY) && fd->null_bit)
1564
- return true;
1565
- }
1566
- return false;
1736
+ if ((num >= 0) && (num < (short)m_table->s->keys))
1737
+ {
1738
+ Field* fd = m_table->key_info[num].key_part[0].field;
1739
+ // Nis is only in a head segment.
1740
+ if (isNisField(fd->field_name))
1741
+ return true;
1742
+ else if ((fd->pack_length() == 1) && (fd->type() == MYSQL_TYPE_TINY) &&
1743
+ fd->null_bit)
1744
+ return true;
1745
+ }
1746
+ return false;
1567
1747
  }
1568
1748
 
1569
1749
  bool setNullIf(KEY& key)
1570
1750
  {
1571
- bool nullkey = false;
1572
- Field* fd = key.key_part[0].field; //Nis is only in a head segment.
1573
- if (isNisField(fd->field_name))
1574
- {
1575
- if(isNullNis(key, fd->field_name[3]=='a'))
1576
- {
1577
- fd->set_null();
1578
- nullkey = true;
1579
- }
1580
- else
1581
- fd->set_notnull();
1582
- }
1583
- else
1584
- {
1585
- for (int j=0;j<(int)key.user_defined_key_parts;j++)
1586
- {
1587
- fd = key.key_part[j].field;
1588
- if (key.key_part[j].null_bit && fd->ptr)
1589
- {
1590
- if (isNull(fd))
1591
- {
1592
- fd->set_null();
1593
- nullkey = true;
1594
- }else
1595
- fd->set_notnull();
1596
- }
1597
- }
1598
- }
1599
- return nullkey;
1751
+ bool nullkey = false;
1752
+ Field* fd = key.key_part[0].field; // Nis is only in a head segment.
1753
+ if (isNisField(fd->field_name))
1754
+ {
1755
+ if (isNullNis(key, fd->field_name[3] == 'a'))
1756
+ {
1757
+ fd->set_null();
1758
+ nullkey = true;
1759
+ }
1760
+ else
1761
+ fd->set_notnull();
1762
+ }
1763
+ else
1764
+ {
1765
+ for (int j = 0; j < (int)key.user_defined_key_parts; j++)
1766
+ {
1767
+ fd = key.key_part[j].field;
1768
+ if (key.key_part[j].null_bit && fd->ptr)
1769
+ {
1770
+ if (isNull(fd))
1771
+ {
1772
+ fd->set_null();
1773
+ nullkey = true;
1774
+ }
1775
+ else
1776
+ fd->set_notnull();
1777
+ }
1778
+ }
1779
+ }
1780
+ return nullkey;
1600
1781
  }
1601
1782
 
1602
1783
  /** Sets null value for all null able key fields
@@ -1604,355 +1785,369 @@ bool setNullIf(KEY& key)
1604
1785
  */
1605
1786
  int table::setKeyNullFlags()
1606
1787
  {
1607
- int setCount = 0;
1608
- if (m_table->s->null_fields)
1609
- {
1610
- for (int i=0;i<(int)m_table->s->keys;i++)
1611
- {
1612
- KEY& key = m_table->key_info[i];
1613
- if (key.flags & HA_NULL_PART_KEY)
1614
- {
1615
- bool nullKey = setNullIf(key);
1616
- if (nullKey && (i == m_keyNum))
1617
- ++setCount;
1618
- }
1619
- }
1620
- }
1621
- return setCount;
1788
+ int setCount = 0;
1789
+ if (m_table->s->null_fields)
1790
+ {
1791
+ for (int i = 0; i < (int)m_table->s->keys; i++)
1792
+ {
1793
+ KEY& key = m_table->key_info[i];
1794
+ if (key.flags & HA_NULL_PART_KEY)
1795
+ {
1796
+ bool nullKey = setNullIf(key);
1797
+ if (nullKey && (i == m_keyNum))
1798
+ ++setCount;
1799
+ }
1800
+ }
1801
+ }
1802
+ return setCount;
1622
1803
  }
1623
1804
 
1624
1805
  /** Sets null value for all null able fields
1625
1806
  */
1626
1807
  void table::setFiledNullFlags()
1627
1808
  {
1628
- std::vector<Field*>::iterator it = m_nonKeySegNullFields.begin();
1629
- while (it != m_nonKeySegNullFields.end())
1630
- {
1631
- if (isNull(*it))
1632
- (*it)->set_null();
1633
- else
1634
- (*it)->set_notnull();
1635
- ++it;
1636
- }
1809
+ std::vector<Field*>::iterator it = m_nonKeySegNullFields.begin();
1810
+ while (it != m_nonKeySegNullFields.end())
1811
+ {
1812
+ if (isNull(*it))
1813
+ (*it)->set_null();
1814
+ else
1815
+ (*it)->set_notnull();
1816
+ ++it;
1817
+ }
1637
1818
  }
1638
1819
 
1639
1820
  __int64 table::insert(bool ncc)
1640
1821
  {
1641
- if ((m_mode==TD_OPEN_READONLY) || !cp_is_write_lock(m_table->file))
1642
- {
1643
- m_stat = STATUS_INVALID_LOCKTYPE;
1644
- return 0;
1645
- }
1646
- __int64 autoincValue = 0;
1647
-
1648
- {
1649
- autoincSetup setup(m_table);
1650
- if (!ncc)
1651
- key_copy(&m_nonNccKeybuf[0], m_table->record[1], &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1652
- setKeyNullFlags();
1653
- setFiledNullFlags();
1654
-
1655
- m_stat = m_table->file->ha_write_row(m_table->record[0]);
1656
- autoincValue = m_table->file->insert_id_for_cur_row;
1657
-
1658
- if (m_stat==0 && m_table->file->insert_id_for_cur_row)
1659
- {
1660
- if (!m_bulkInserting)
1661
- m_table->file->ha_release_auto_increment();
1662
- }
1663
- }
1664
-
1665
- if (m_stat==0)
1666
- {
1667
- if (!ncc)//innodb default is ncc=-1.
1668
- m_nonNcc = true;
1669
- else if (!m_bulkInserting)
1670
- key_copy(&m_keybuf[0], m_table->record[0], &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1671
- m_cursor = m_validCursor = m_nounlock = (m_stat == 0);
1672
-
1673
- m_changed = true;
1674
- }
1675
- return autoincValue;
1822
+ if ((m_mode == TD_OPEN_READONLY) || !cp_is_write_lock(m_table->file))
1823
+ {
1824
+ m_stat = STATUS_INVALID_LOCKTYPE;
1825
+ return 0;
1826
+ }
1827
+ __int64 autoincValue = 0;
1828
+
1829
+ {
1830
+ autoincSetup setup(m_table);
1831
+ if (!ncc)
1832
+ key_copy(&m_nonNccKeybuf[0], m_table->record[1],
1833
+ &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1834
+ setKeyNullFlags();
1835
+ setFiledNullFlags();
1836
+
1837
+ m_stat = m_table->file->ha_write_row(m_table->record[0]);
1838
+ autoincValue = m_table->file->insert_id_for_cur_row;
1839
+
1840
+ if (m_stat == 0 && m_table->file->insert_id_for_cur_row)
1841
+ {
1842
+ if (!m_bulkInserting)
1843
+ m_table->file->ha_release_auto_increment();
1844
+ }
1845
+ }
1846
+
1847
+ if (m_stat == 0)
1848
+ {
1849
+ if (!ncc) // innodb default is ncc=-1.
1850
+ m_nonNcc = true;
1851
+ else if (!m_bulkInserting)
1852
+ key_copy(&m_keybuf[0], m_table->record[0],
1853
+ &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1854
+ m_cursor = m_validCursor = m_nounlock = (m_stat == 0);
1855
+
1856
+ m_changed = true;
1857
+ }
1858
+ return autoincValue;
1676
1859
  }
1677
1860
 
1678
1861
  void table::beginUpdate(char keyNum)
1679
1862
  {
1680
- m_stat = 0;
1681
- m_table->file->try_semi_consistent_read(1);
1682
- beginDel();
1683
- if (m_stat==0)
1684
- {
1685
- if (keyNum >= 0)
1686
- {
1687
- key_copy(&m_nonNccKeybuf[0], m_table->record[0], &m_table->key_info[keyNum], KEYLEN_ALLCOPY);
1688
- setKeyNum(keyNum);
1689
- }
1690
- store_record(m_table, record[1]);
1691
- }
1863
+ m_stat = 0;
1864
+ m_table->file->try_semi_consistent_read(1);
1865
+ beginDel();
1866
+ if (m_stat == 0)
1867
+ {
1868
+ if (keyNum >= 0)
1869
+ {
1870
+ key_copy(&m_nonNccKeybuf[0], m_table->record[0],
1871
+ &m_table->key_info[keyNum], KEYLEN_ALLCOPY);
1872
+ setKeyNum(keyNum);
1873
+ }
1874
+ store_record(m_table, record[1]);
1875
+ }
1692
1876
  }
1693
1877
 
1694
1878
  void table::beginDel()
1695
1879
  {
1696
- if ((m_mode==TD_OPEN_READONLY) || !cp_is_write_lock(m_table->file))
1697
- {
1698
- m_stat = STATUS_INVALID_LOCKTYPE;
1699
- return;
1700
- }
1701
- if (m_cursor)
1702
- {
1703
- m_stat = 0;
1704
- /* The current position is established in advance.
1705
- If not in transaction then m_validCursor=false */
1706
- if (m_validCursor == false)
1707
- {
1708
- store_record(m_table, record[1]);
1709
- if (m_keyNum>=0)
1710
- {
1711
- //seek until ref is same.
1712
- uchar rawPos[128];
1713
- memcpy(rawPos, position(true), m_table->file->ref_length);
1714
- seekPos(rawPos);
1715
- }
1716
- else
1717
- movePos(position(true), -1, true);
1718
-
1719
- //Has blob fileds then ignore conflicts.
1720
- if ((m_table->s->blob_fields==0) && cmp_record(m_table, record[1]))
1721
- m_stat = STATUS_CHANGE_CONFLICT;
1722
-
1723
- m_cursor = m_validCursor = (m_stat == 0);
1724
- if (m_stat)
1725
- return ;
1726
- }
1727
-
1728
- }else
1729
- m_stat = STATUS_NO_CURRENT;
1880
+ if ((m_mode == TD_OPEN_READONLY) || !cp_is_write_lock(m_table->file))
1881
+ {
1882
+ m_stat = STATUS_INVALID_LOCKTYPE;
1883
+ return;
1884
+ }
1885
+ if (m_cursor)
1886
+ {
1887
+ m_stat = 0;
1888
+ /* The current position is established in advance.
1889
+ If not in transaction then m_validCursor=false */
1890
+ if (m_validCursor == false)
1891
+ {
1892
+ store_record(m_table, record[1]);
1893
+ if (m_keyNum >= 0)
1894
+ {
1895
+ // seek until ref is same.
1896
+ uchar rawPos[128];
1897
+ memcpy(rawPos, position(true), m_table->file->ref_length);
1898
+ seekPos(rawPos);
1899
+ }
1900
+ else
1901
+ movePos(position(true), -1, true);
1902
+
1903
+ // Has blob fileds then ignore conflicts.
1904
+ if ((m_table->s->blob_fields == 0) &&
1905
+ cmp_record(m_table, record[1]))
1906
+ m_stat = STATUS_CHANGE_CONFLICT;
1907
+
1908
+ m_cursor = m_validCursor = (m_stat == 0);
1909
+ if (m_stat)
1910
+ return;
1911
+ }
1912
+ }
1913
+ else
1914
+ m_stat = STATUS_NO_CURRENT;
1730
1915
  }
1731
1916
 
1732
1917
  /** Update current record.
1733
- * It is indispensable that there is a current record in advance
1734
- * and beginUpdate() is called.
1918
+ * It is indispensable that there is a current record in advance
1919
+ * and beginUpdate() is called.
1735
1920
  */
1736
1921
  void table::update(bool ncc)
1737
1922
  {
1738
- if (m_stat == 0)
1739
- {
1740
-
1741
- int nullFieldsOfCurrentKey = setKeyNullFlags();
1742
- setFiledNullFlags();
1743
- m_stat = m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
1744
- if (m_stat==0 || (m_stat==HA_ERR_RECORD_IS_THE_SAME))
1745
- {
1746
- m_stat = 0;
1747
- m_nonNcc = false;
1748
- if (!ncc)//innodb default is ncc=-1.
1749
- {
1750
- //Only when the present key value is changed
1751
- if (m_keyNum>=0)
1752
- {
1753
- const KEY& key = m_table->key_info[m_keyNum];
1754
- key_copy(&m_keybuf[0], m_table->record[0], (KEY*)&key, KEYLEN_ALLCOPY);
1755
- if (memcmp(&m_nonNccKeybuf[0], &m_keybuf[0], key.key_length))
1756
- {
1757
- //Since the NULL key was set, a current position is lost.
1758
- if (nullFieldsOfCurrentKey==0)
1759
- m_nonNcc = true;
1760
- }
1761
- }
1762
- }
1763
- m_cursor = m_validCursor = m_nounlock = (m_stat == 0);
1764
- }
1765
- }
1766
- if (m_stat==0)
1767
- m_changed = true;
1768
- m_table->file->try_semi_consistent_read(0);
1769
- }
1770
-
1771
- /** del current record.
1772
- * It is indispensable that there is a current record in advance
1923
+ if (m_stat == 0)
1924
+ {
1925
+
1926
+ int nullFieldsOfCurrentKey = setKeyNullFlags();
1927
+ setFiledNullFlags();
1928
+ m_stat = m_table->file->ha_update_row(m_table->record[1],
1929
+ m_table->record[0]);
1930
+ if (m_stat == 0 || (m_stat == HA_ERR_RECORD_IS_THE_SAME))
1931
+ {
1932
+ m_stat = 0;
1933
+ m_nonNcc = false;
1934
+ if (!ncc) // innodb default is ncc=-1.
1935
+ {
1936
+ // Only when the present key value is changed
1937
+ if (m_keyNum >= 0)
1938
+ {
1939
+ const KEY& key = m_table->key_info[m_keyNum];
1940
+ key_copy(&m_keybuf[0], m_table->record[0], (KEY*)&key,
1941
+ KEYLEN_ALLCOPY);
1942
+ if (memcmp(&m_nonNccKeybuf[0], &m_keybuf[0],
1943
+ key.key_length))
1944
+ {
1945
+ // Since the NULL key was set, a current position is
1946
+ // lost.
1947
+ if (nullFieldsOfCurrentKey == 0)
1948
+ m_nonNcc = true;
1949
+ }
1950
+ }
1951
+ }
1952
+ m_cursor = m_validCursor = m_nounlock = (m_stat == 0);
1953
+ }
1954
+ }
1955
+ if (m_stat == 0)
1956
+ m_changed = true;
1957
+ m_table->file->try_semi_consistent_read(0);
1958
+ }
1959
+
1960
+ /** del current record.
1961
+ * It is indispensable that there is a current record in advance
1773
1962
  * and beginDel() is called.
1774
- */
1963
+ */
1775
1964
  void table::del()
1776
1965
  {
1777
- if (m_stat == 0)
1778
- m_stat = m_table->file->ha_delete_row(m_table->record[0]);
1779
- if (m_stat==0)
1780
- m_changed = true;
1966
+ if (m_stat == 0)
1967
+ m_stat = m_table->file->ha_delete_row(m_table->record[0]);
1968
+ if (m_stat == 0)
1969
+ m_changed = true;
1781
1970
  }
1782
1971
 
1972
+ #ifdef USE_BTRV_VARIABLE_LEN
1973
+
1783
1974
  /** The offset position of the last VAR field data
1784
1975
  */
1785
- unsigned short table::lastVarFieldPos()const
1786
- {
1787
- if (m_table->s->varchar_fields && (m_recordFormatType == RF_FIXED_PLUS_VALIABLE_LEN))
1788
- return (unsigned short)(lastVarFiled()->ptr - m_table->s->field[0]->ptr);
1789
- return 0;
1976
+ unsigned short table::lastVarFieldPos() const
1977
+ {
1978
+ if (m_table->s->varchar_fields &&
1979
+ (m_recordFormatType & RF_FIXED_PLUS_VALIABLE_LEN))
1980
+ return (unsigned short)(lastVarFiled()->ptr -
1981
+ m_table->s->field[0]->ptr);
1982
+ return 0;
1790
1983
  }
1791
1984
 
1792
- /** The data length of the field
1985
+ #endif
1986
+
1987
+ /** The data length of the field
1793
1988
  */
1794
1989
  unsigned short table::fieldDataLen(int fieldNum) const
1795
1990
  {
1796
- Field* fd = m_table->field[fieldNum];
1797
- if (isVarType(fd->type()))
1798
- return var_strlen(fd);
1799
- return fd->pack_length();
1991
+ Field* fd = m_table->field[fieldNum];
1992
+ if (isVarType(fd->type()))
1993
+ return var_strlen(fd);
1994
+ return fd->pack_length();
1800
1995
  }
1801
1996
 
1802
1997
  const char* table::keyName(char keyNum)
1803
1998
  {
1804
- if((keyNum>=0) && (keyNum < (short)m_table->s->keys))
1805
- {
1806
- KEY& key = m_table->key_info[keyNum];
1807
- return key.name;
1808
- }
1809
- return "";
1999
+ if ((keyNum >= 0) && (keyNum < (short)m_table->s->keys))
2000
+ {
2001
+ KEY& key = m_table->key_info[keyNum];
2002
+ return key.name;
2003
+ }
2004
+ return "";
1810
2005
  }
1811
2006
 
1812
- int table::keynumByName(const char* name)const
2007
+ int table::keynumByName(const char* name) const
1813
2008
  {
1814
- if (*name==0x00)
1815
- name = "PRIMARY";
1816
- for (int i=0; i<(int)m_table->s->keys; i++)
1817
- {
1818
- if (strcmp(m_table->key_info[i].name, name) == 0)
1819
- return i;
1820
- }
1821
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_KEYNAME, name);
2009
+ if (*name == 0x00)
2010
+ name = "PRIMARY";
2011
+ for (int i = 0; i < (int)m_table->s->keys; i++)
2012
+ {
2013
+ if (strcmp(m_table->key_info[i].name, name) == 0)
2014
+ return i;
2015
+ }
2016
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_KEYNAME, name);
1822
2017
  }
1823
2018
 
1824
2019
  void table::startBulkInsert(ha_rows rows)
1825
2020
  {
1826
- m_table->file->ha_start_bulk_insert(rows);
1827
- m_bulkInserting = true;
2021
+ m_table->file->ha_start_bulk_insert(rows);
2022
+ m_bulkInserting = true;
1828
2023
  }
1829
2024
 
1830
2025
  void table::endBulkInsert()
1831
2026
  {
1832
- if (m_bulkInserting)
1833
- {
1834
- key_copy(&m_keybuf[0], m_table->record[0], &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1835
- m_bulkInserting = false;
1836
- m_table->file->ha_release_auto_increment();
1837
- m_table->file->ha_end_bulk_insert();
1838
- }
2027
+ if (m_bulkInserting)
2028
+ {
2029
+ key_copy(&m_keybuf[0], m_table->record[0], &m_table->key_info[m_keyNum],
2030
+ KEYLEN_ALLCOPY);
2031
+ m_bulkInserting = false;
2032
+ m_table->file->ha_release_auto_increment();
2033
+ m_table->file->ha_end_bulk_insert();
2034
+ }
1839
2035
  }
1840
2036
 
1841
- const char* table::valStr(int filedNum, int &size)
2037
+ const char* table::valStr(int filedNum, int& size)
1842
2038
  {
1843
- assert((filedNum>=0) && (filedNum < (int)m_table->s->fields));
2039
+ assert((filedNum >= 0) && (filedNum < (int)m_table->s->fields));
1844
2040
 
1845
- Field* fd = m_table->field[filedNum];
1846
- size = -1;
1847
- if (fd->is_null())
1848
- return "";
1849
- else
1850
- fd->val_str(&m_str, &m_str);
1851
- size = m_str.length();
1852
- return m_str.c_ptr();
1853
-
2041
+ Field* fd = m_table->field[filedNum];
2042
+ size = -1;
2043
+ if (fd->is_null())
2044
+ return "";
2045
+ else
2046
+ fd->val_str(&m_str, &m_str);
2047
+ size = m_str.length();
2048
+ return m_str.c_ptr();
1854
2049
  }
1855
-
2050
+
1856
2051
  uint table::makeBlobFieldList(int fieldNum)
1857
2052
  {
1858
- m_blobBuffer->clear();
1859
- int st = fieldNum==-1?0:fieldNum;
1860
- int en = fieldNum==-1?m_table->s->fields:fieldNum+1;
1861
- uint count = 0;
1862
- for (int i=st;i<en;i++)
1863
- {
1864
- Field* fd = m_table->field[fieldNum];
1865
- if (isBlobType(fd->type()))
1866
- {
1867
- m_blobBuffer->addBlob(blob_len(fd), fd->field_index, fd->ptr + blob_var_bytes(fd));
1868
- count++;
1869
- }
1870
- }
1871
- m_blobBuffer->setFieldCount(count);
1872
- return count;
2053
+ m_blobBuffer->clear();
2054
+ int st = fieldNum == -1 ? 0 : fieldNum;
2055
+ int en = fieldNum == -1 ? m_table->s->fields : fieldNum + 1;
2056
+ uint count = 0;
2057
+ for (int i = st; i < en; i++)
2058
+ {
2059
+ Field* fd = m_table->field[fieldNum];
2060
+ if (isBlobType(fd->type()))
2061
+ {
2062
+ m_blobBuffer->addBlob(blob_len(fd), fd->field_index,
2063
+ fd->ptr + blob_var_bytes(fd));
2064
+ count++;
2065
+ }
2066
+ }
2067
+ m_blobBuffer->setFieldCount(count);
2068
+ return count;
1873
2069
  }
1874
2070
 
1875
2071
  #ifdef USE_HANDLERSOCKET
1876
- int table::fieldIndexByName(const char* name)const
2072
+
2073
+ int table::fieldIndexByName(const char* name) const
1877
2074
  {
1878
- int index = 0;
1879
- for (Field** fd=m_table->field ; *fd; ++fd)
1880
- {
1881
- if (strcmp(name, (*fd)->field_name)==0)
1882
- return index;
1883
- ++index;
1884
- }
1885
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_FIELDNAME, name);
2075
+ int index = 0;
2076
+ for (Field** fd = m_table->field; *fd; ++fd)
2077
+ {
2078
+ if (strcmp(name, (*fd)->field_name) == 0)
2079
+ return index;
2080
+ ++index;
2081
+ }
2082
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_FIELDNAME, name);
1886
2083
  }
1887
2084
 
1888
2085
  void table::setUseFieldList(const std::string& csv)
1889
2086
  {
1890
- std::vector< std::string> values ;
1891
- split(values, csv, ",");
1892
- for (int i=0;i<values.size();i++)
1893
- addUseField(fieldIndexByName(values[i].c_str()));
1894
-
2087
+ std::vector<std::string> values;
2088
+ split(values, csv, ",");
2089
+ for (int i = 0; i < values.size(); i++)
2090
+ addUseField(fieldIndexByName(values[i].c_str()));
1895
2091
  }
1896
2092
 
1897
2093
  inline void setSegmentValue(const KEY_PART_INFO& segment, const std::string& v)
1898
2094
  {
1899
- segment.field->set_notnull();
1900
- if (!((v.size() == 1) && (v[0] == 0x00)))
1901
- segment.field->store(v.c_str(), (uint)v.size(), &my_charset_bin);
1902
- else
1903
- segment.field->set_null();
2095
+ segment.field->set_notnull();
2096
+ if (!((v.size() == 1) && (v[0] == 0x00)))
2097
+ segment.field->store(v.c_str(), (uint)v.size(), &my_charset_bin);
2098
+ else
2099
+ segment.field->set_null();
1904
2100
  }
1905
2101
 
1906
- void table::setKeyValues(const std::vector<std::string>& values, int keypart, const std::string* inValue)
2102
+ void table::setKeyValues(const std::vector<std::string>& values, int keypart,
2103
+ const std::string* inValue)
1907
2104
  {
1908
- KEY& key = m_table->key_info[m_keyNum];
1909
- for (int i=0;i<(int)key.user_defined_key_parts;i++)
1910
- if (i < values.size())
1911
- setSegmentValue(key.key_part[i], values[i]);
1912
- if (keypart !=-1)
1913
- setSegmentValue(key.key_part[keypart], *inValue);
1914
- key_copy(&m_keybuf[0], m_table->record[0], &key, KEYLEN_ALLCOPY);
1915
-
2105
+ KEY& key = m_table->key_info[m_keyNum];
2106
+ for (int i = 0; i < (int)key.user_defined_key_parts; i++)
2107
+ if (i < (int)values.size())
2108
+ setSegmentValue(key.key_part[i], values[i]);
2109
+ if (keypart != -1)
2110
+ setSegmentValue(key.key_part[keypart], *inValue);
2111
+ key_copy(&m_keybuf[0], m_table->record[0], &key, KEYLEN_ALLCOPY);
1916
2112
  }
1917
2113
 
1918
2114
  void table::setValue(int index, const std::string& v, int type)
1919
2115
  {
1920
- Field* field = *(m_table->field+index);
1921
- if ((v.size() == 1) && (v[0] == 0x00))
1922
- field->set_null();
1923
- else
1924
- field->set_notnull();
1925
- if ((type == UPDATE_INC) || (type == UPDATE_DEC))
1926
- {
1927
- __int64 old = field->val_int();
1928
- __int64 intv = _atoi64(v.c_str());
1929
- if (type == UPDATE_INC)
1930
- field->store(old + intv , false);
1931
- else
1932
- field->store(old - intv , false);
1933
- }else
1934
- field->store(v.c_str(), (uint)v.size(), &my_charset_bin);
2116
+ Field* field = *(m_table->field + index);
2117
+ if ((v.size() == 1) && (v[0] == 0x00))
2118
+ field->set_null();
2119
+ else
2120
+ field->set_notnull();
2121
+ if ((type == UPDATE_INC) || (type == UPDATE_DEC))
2122
+ {
2123
+ __int64 old = field->val_int();
2124
+ __int64 intv = _atoi64(v.c_str());
2125
+ if (type == UPDATE_INC)
2126
+ field->store(old + intv, false);
2127
+ else
2128
+ field->store(old - intv, false);
2129
+ }
2130
+ else
2131
+ field->store(v.c_str(), (uint)v.size(), &my_charset_bin);
1935
2132
  }
1936
2133
 
1937
2134
  void table::setUseValues(const std::vector<std::string>& values, int type)
1938
2135
  {
1939
- for (int i=0;i<values.size();i++)
1940
- {
1941
- if (useFields().size()>i)
1942
- setValue(m_useFields[i], values[i], type);
1943
- }
2136
+ for (int i = 0; i < (int)values.size(); i++)
2137
+ {
2138
+ if ((int)useFields().size() > i)
2139
+ setValue(m_useFields[i], values[i], type);
2140
+ }
1944
2141
  }
1945
2142
 
1946
2143
  void table::checkFiledIndex(int index)
1947
2144
  {
1948
- assert(index>=0);
2145
+ assert(index >= 0);
1949
2146
  }
1950
2147
 
1951
- #endif //USE_HANDLERSOCKET
1952
-
1953
- }//namespace mysql
1954
- }//namespace engine
1955
- }//namespace db
1956
- }//namespace bzs
1957
-
2148
+ #endif // USE_HANDLERSOCKET
1958
2149
 
2150
+ } // namespace mysql
2151
+ } // namespace engine
2152
+ } // namespace db
2153
+ } // namespace bzs