transactd 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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