prestogres 0.1.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 (393) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +20 -0
  4. data/LICENSE +202 -0
  5. data/NOTICE +22 -0
  6. data/README.md +217 -0
  7. data/Rakefile +13 -0
  8. data/VERSION +1 -0
  9. data/bin/prestogres +254 -0
  10. data/config/pcp.conf.sample +28 -0
  11. data/config/pgpool.conf +678 -0
  12. data/config/pool_hba.conf +84 -0
  13. data/config/pool_passwd +0 -0
  14. data/config/postgresql.conf +2 -0
  15. data/ext/.gitignore +6 -0
  16. data/ext/depend +26 -0
  17. data/ext/extconf.rb +4 -0
  18. data/ext/prestogres_config.c +12 -0
  19. data/pgpool2/.gitignore +36 -0
  20. data/pgpool2/AUTHORS +4 -0
  21. data/pgpool2/COPYING +12 -0
  22. data/pgpool2/ChangeLog +1 -0
  23. data/pgpool2/INSTALL +1 -0
  24. data/pgpool2/Makefile.am +159 -0
  25. data/pgpool2/Makefile.in +1187 -0
  26. data/pgpool2/NEWS +4960 -0
  27. data/pgpool2/README +1 -0
  28. data/pgpool2/README.euc_jp +1 -0
  29. data/pgpool2/README.online-recovery +62 -0
  30. data/pgpool2/TODO +103 -0
  31. data/pgpool2/ac_func_accept_argtypes.m4 +85 -0
  32. data/pgpool2/aclocal.m4 +1088 -0
  33. data/pgpool2/c-compiler.m4 +134 -0
  34. data/pgpool2/c-library.m4 +325 -0
  35. data/pgpool2/child.c +2097 -0
  36. data/pgpool2/config.guess +1532 -0
  37. data/pgpool2/config.h.in +332 -0
  38. data/pgpool2/config.sub +1640 -0
  39. data/pgpool2/configure +15752 -0
  40. data/pgpool2/configure.in +392 -0
  41. data/pgpool2/depcomp +522 -0
  42. data/pgpool2/doc/basebackup.sh +17 -0
  43. data/pgpool2/doc/pgpool-de.html +4220 -0
  44. data/pgpool2/doc/pgpool-en.html +5738 -0
  45. data/pgpool2/doc/pgpool-fr.html +4118 -0
  46. data/pgpool2/doc/pgpool-ja.css +198 -0
  47. data/pgpool2/doc/pgpool-ja.html +11279 -0
  48. data/pgpool2/doc/pgpool-zh_cn.html +4445 -0
  49. data/pgpool2/doc/pgpool.css +280 -0
  50. data/pgpool2/doc/pgpool_remote_start +13 -0
  51. data/pgpool2/doc/recovery.conf.sample +117 -0
  52. data/pgpool2/doc/tutorial-en.html +707 -0
  53. data/pgpool2/doc/tutorial-ja.html +422 -0
  54. data/pgpool2/doc/tutorial-memqcache-en.html +325 -0
  55. data/pgpool2/doc/tutorial-memqcache-ja.html +370 -0
  56. data/pgpool2/doc/tutorial-memqcache-zh_cn.html +322 -0
  57. data/pgpool2/doc/tutorial-watchdog-en.html +306 -0
  58. data/pgpool2/doc/tutorial-watchdog-ja.html +343 -0
  59. data/pgpool2/doc/tutorial-watchdog-zh_cn.html +301 -0
  60. data/pgpool2/doc/tutorial-zh_cn.html +537 -0
  61. data/pgpool2/doc/watchdog.png +0 -0
  62. data/pgpool2/doc/wd-en.html +236 -0
  63. data/pgpool2/doc/wd-en.jpg +0 -0
  64. data/pgpool2/doc/wd-ja.html +219 -0
  65. data/pgpool2/doc/wd-ja.jpg +0 -0
  66. data/pgpool2/doc/wd-zh_cn.html +201 -0
  67. data/pgpool2/doc/where_to_send_queries.odg +0 -0
  68. data/pgpool2/doc/where_to_send_queries.pdf +0 -0
  69. data/pgpool2/general.m4 +166 -0
  70. data/pgpool2/getopt_long.c +200 -0
  71. data/pgpool2/getopt_long.h +44 -0
  72. data/pgpool2/install-sh +251 -0
  73. data/pgpool2/ltmain.sh +8406 -0
  74. data/pgpool2/m4/libtool.m4 +7360 -0
  75. data/pgpool2/m4/ltoptions.m4 +368 -0
  76. data/pgpool2/m4/ltsugar.m4 +123 -0
  77. data/pgpool2/m4/ltversion.m4 +23 -0
  78. data/pgpool2/m4/lt~obsolete.m4 +92 -0
  79. data/pgpool2/main.c +2971 -0
  80. data/pgpool2/md5.c +444 -0
  81. data/pgpool2/md5.h +28 -0
  82. data/pgpool2/missing +360 -0
  83. data/pgpool2/mkinstalldirs +40 -0
  84. data/pgpool2/parser/Makefile.am +50 -0
  85. data/pgpool2/parser/Makefile.in +559 -0
  86. data/pgpool2/parser/copyfuncs.c +3310 -0
  87. data/pgpool2/parser/gram.c +39100 -0
  88. data/pgpool2/parser/gram.h +940 -0
  89. data/pgpool2/parser/gram.y +13408 -0
  90. data/pgpool2/parser/gramparse.h +74 -0
  91. data/pgpool2/parser/keywords.c +32 -0
  92. data/pgpool2/parser/keywords.h +39 -0
  93. data/pgpool2/parser/kwlist.h +425 -0
  94. data/pgpool2/parser/kwlookup.c +88 -0
  95. data/pgpool2/parser/list.c +1156 -0
  96. data/pgpool2/parser/makefuncs.c +518 -0
  97. data/pgpool2/parser/makefuncs.h +83 -0
  98. data/pgpool2/parser/memnodes.h +79 -0
  99. data/pgpool2/parser/nodes.c +29 -0
  100. data/pgpool2/parser/nodes.h +609 -0
  101. data/pgpool2/parser/outfuncs.c +5790 -0
  102. data/pgpool2/parser/parsenodes.h +2615 -0
  103. data/pgpool2/parser/parser.c +262 -0
  104. data/pgpool2/parser/parser.h +46 -0
  105. data/pgpool2/parser/pg_class.h +158 -0
  106. data/pgpool2/parser/pg_config_manual.h +273 -0
  107. data/pgpool2/parser/pg_list.h +352 -0
  108. data/pgpool2/parser/pg_trigger.h +147 -0
  109. data/pgpool2/parser/pg_wchar.h +492 -0
  110. data/pgpool2/parser/pool_memory.c +342 -0
  111. data/pgpool2/parser/pool_memory.h +77 -0
  112. data/pgpool2/parser/pool_parser.h +222 -0
  113. data/pgpool2/parser/pool_string.c +121 -0
  114. data/pgpool2/parser/pool_string.h +37 -0
  115. data/pgpool2/parser/primnodes.h +1280 -0
  116. data/pgpool2/parser/scan.c +4094 -0
  117. data/pgpool2/parser/scan.l +1451 -0
  118. data/pgpool2/parser/scanner.h +120 -0
  119. data/pgpool2/parser/scansup.c +221 -0
  120. data/pgpool2/parser/scansup.h +28 -0
  121. data/pgpool2/parser/snprintf.c +1102 -0
  122. data/pgpool2/parser/stringinfo.c +294 -0
  123. data/pgpool2/parser/stringinfo.h +178 -0
  124. data/pgpool2/parser/value.c +78 -0
  125. data/pgpool2/parser/value.h +62 -0
  126. data/pgpool2/parser/wchar.c +2048 -0
  127. data/pgpool2/pcp.conf.sample +28 -0
  128. data/pgpool2/pcp/Makefile.am +40 -0
  129. data/pgpool2/pcp/Makefile.in +771 -0
  130. data/pgpool2/pcp/libpcp_ext.h +250 -0
  131. data/pgpool2/pcp/md5.c +444 -0
  132. data/pgpool2/pcp/md5.h +28 -0
  133. data/pgpool2/pcp/pcp.c +1652 -0
  134. data/pgpool2/pcp/pcp.h +61 -0
  135. data/pgpool2/pcp/pcp_attach_node.c +172 -0
  136. data/pgpool2/pcp/pcp_detach_node.c +185 -0
  137. data/pgpool2/pcp/pcp_error.c +87 -0
  138. data/pgpool2/pcp/pcp_node_count.c +160 -0
  139. data/pgpool2/pcp/pcp_node_info.c +198 -0
  140. data/pgpool2/pcp/pcp_pool_status.c +166 -0
  141. data/pgpool2/pcp/pcp_proc_count.c +166 -0
  142. data/pgpool2/pcp/pcp_proc_info.c +261 -0
  143. data/pgpool2/pcp/pcp_promote_node.c +185 -0
  144. data/pgpool2/pcp/pcp_recovery_node.c +172 -0
  145. data/pgpool2/pcp/pcp_stop_pgpool.c +179 -0
  146. data/pgpool2/pcp/pcp_stream.c +385 -0
  147. data/pgpool2/pcp/pcp_stream.h +52 -0
  148. data/pgpool2/pcp/pcp_systemdb_info.c +194 -0
  149. data/pgpool2/pcp/pcp_watchdog_info.c +211 -0
  150. data/pgpool2/pcp_child.c +1493 -0
  151. data/pgpool2/pg_md5.c +305 -0
  152. data/pgpool2/pgpool.8.in +121 -0
  153. data/pgpool2/pgpool.conf +553 -0
  154. data/pgpool2/pgpool.conf.sample +666 -0
  155. data/pgpool2/pgpool.conf.sample-master-slave +665 -0
  156. data/pgpool2/pgpool.conf.sample-replication +664 -0
  157. data/pgpool2/pgpool.conf.sample-stream +664 -0
  158. data/pgpool2/pgpool.spec +264 -0
  159. data/pgpool2/pgpool_adm/TODO +7 -0
  160. data/pgpool2/pgpool_adm/pgpool_adm--1.0.sql +85 -0
  161. data/pgpool2/pgpool_adm/pgpool_adm.c +558 -0
  162. data/pgpool2/pgpool_adm/pgpool_adm.control +5 -0
  163. data/pgpool2/pgpool_adm/pgpool_adm.h +46 -0
  164. data/pgpool2/pgpool_adm/pgpool_adm.sql.in +85 -0
  165. data/pgpool2/pool.h +655 -0
  166. data/pgpool2/pool_auth.c +1390 -0
  167. data/pgpool2/pool_config.c +5007 -0
  168. data/pgpool2/pool_config.h +284 -0
  169. data/pgpool2/pool_config.l +3281 -0
  170. data/pgpool2/pool_config_md5.c +29 -0
  171. data/pgpool2/pool_connection_pool.c +812 -0
  172. data/pgpool2/pool_error.c +242 -0
  173. data/pgpool2/pool_globals.c +27 -0
  174. data/pgpool2/pool_hba.c +1723 -0
  175. data/pgpool2/pool_hba.conf.sample +67 -0
  176. data/pgpool2/pool_ip.c +567 -0
  177. data/pgpool2/pool_ip.h +65 -0
  178. data/pgpool2/pool_ipc.h +38 -0
  179. data/pgpool2/pool_lobj.c +242 -0
  180. data/pgpool2/pool_lobj.h +32 -0
  181. data/pgpool2/pool_memqcache.c +3818 -0
  182. data/pgpool2/pool_memqcache.h +268 -0
  183. data/pgpool2/pool_params.c +163 -0
  184. data/pgpool2/pool_passwd.c +249 -0
  185. data/pgpool2/pool_passwd.h +41 -0
  186. data/pgpool2/pool_path.c +193 -0
  187. data/pgpool2/pool_path.h +81 -0
  188. data/pgpool2/pool_process_context.c +247 -0
  189. data/pgpool2/pool_process_context.h +62 -0
  190. data/pgpool2/pool_process_query.c +5001 -0
  191. data/pgpool2/pool_process_reporting.c +1671 -0
  192. data/pgpool2/pool_process_reporting.h +44 -0
  193. data/pgpool2/pool_proto2.c +671 -0
  194. data/pgpool2/pool_proto_modules.c +3524 -0
  195. data/pgpool2/pool_proto_modules.h +185 -0
  196. data/pgpool2/pool_query_cache.c +1020 -0
  197. data/pgpool2/pool_query_context.c +1871 -0
  198. data/pgpool2/pool_query_context.h +105 -0
  199. data/pgpool2/pool_relcache.c +284 -0
  200. data/pgpool2/pool_relcache.h +78 -0
  201. data/pgpool2/pool_rewrite_outfuncs.c +9060 -0
  202. data/pgpool2/pool_rewrite_query.c +715 -0
  203. data/pgpool2/pool_rewrite_query.h +192 -0
  204. data/pgpool2/pool_select_walker.c +1150 -0
  205. data/pgpool2/pool_select_walker.h +68 -0
  206. data/pgpool2/pool_sema.c +161 -0
  207. data/pgpool2/pool_session_context.c +952 -0
  208. data/pgpool2/pool_session_context.h +203 -0
  209. data/pgpool2/pool_shmem.c +185 -0
  210. data/pgpool2/pool_signal.c +158 -0
  211. data/pgpool2/pool_signal.h +61 -0
  212. data/pgpool2/pool_ssl.c +339 -0
  213. data/pgpool2/pool_stream.c +962 -0
  214. data/pgpool2/pool_stream.h +61 -0
  215. data/pgpool2/pool_system.c +659 -0
  216. data/pgpool2/pool_timestamp.c +1215 -0
  217. data/pgpool2/pool_timestamp.h +38 -0
  218. data/pgpool2/pool_type.h +171 -0
  219. data/pgpool2/pool_worker_child.c +384 -0
  220. data/pgpool2/ps_status.c +404 -0
  221. data/pgpool2/recovery.c +435 -0
  222. data/pgpool2/redhat/pgpool.conf.sample.patch +52 -0
  223. data/pgpool2/redhat/pgpool.init +201 -0
  224. data/pgpool2/redhat/pgpool.sysconfig +7 -0
  225. data/pgpool2/redhat/rpm_installer/basebackup-replication.sh +53 -0
  226. data/pgpool2/redhat/rpm_installer/basebackup-stream.sh +55 -0
  227. data/pgpool2/redhat/rpm_installer/config_for_script +17 -0
  228. data/pgpool2/redhat/rpm_installer/failover.sh +64 -0
  229. data/pgpool2/redhat/rpm_installer/getsources.sh +141 -0
  230. data/pgpool2/redhat/rpm_installer/install.sh +1363 -0
  231. data/pgpool2/redhat/rpm_installer/pgpool_recovery_pitr +47 -0
  232. data/pgpool2/redhat/rpm_installer/pgpool_remote_start +15 -0
  233. data/pgpool2/redhat/rpm_installer/recovery.conf +4 -0
  234. data/pgpool2/redhat/rpm_installer/uninstall.sh +57 -0
  235. data/pgpool2/sample/dist_def_pgbench.sql +73 -0
  236. data/pgpool2/sample/pgpool.pam +3 -0
  237. data/pgpool2/sample/pgpool_recovery +20 -0
  238. data/pgpool2/sample/pgpool_recovery_pitr +19 -0
  239. data/pgpool2/sample/pgpool_remote_start +13 -0
  240. data/pgpool2/sample/replicate_def_pgbench.sql +18 -0
  241. data/pgpool2/sql/insert_lock.sql +15 -0
  242. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.c +280 -0
  243. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.sql.in +19 -0
  244. data/pgpool2/sql/pgpool-recovery/pgpool_recovery--1.0.sql +24 -0
  245. data/pgpool2/sql/pgpool-recovery/pgpool_recovery.control +5 -0
  246. data/pgpool2/sql/pgpool-recovery/uninstall_pgpool-recovery.sql +3 -0
  247. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.c +206 -0
  248. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.sql.in +4 -0
  249. data/pgpool2/sql/pgpool-regclass/pgpool_regclass--1.0.sql +7 -0
  250. data/pgpool2/sql/pgpool-regclass/pgpool_regclass.control +5 -0
  251. data/pgpool2/sql/pgpool-regclass/uninstall_pgpool-regclass.sql +1 -0
  252. data/pgpool2/sql/system_db.sql +38 -0
  253. data/pgpool2/strlcpy.c +85 -0
  254. data/pgpool2/test/C/test_extended.c +98 -0
  255. data/pgpool2/test/jdbc/.cvsignore +2 -0
  256. data/pgpool2/test/jdbc/AutoCommitTest.java +45 -0
  257. data/pgpool2/test/jdbc/BatchTest.java +55 -0
  258. data/pgpool2/test/jdbc/ColumnTest.java +60 -0
  259. data/pgpool2/test/jdbc/CreateTempTableTest.java +48 -0
  260. data/pgpool2/test/jdbc/InsertTest.java +34 -0
  261. data/pgpool2/test/jdbc/LockTest.java +36 -0
  262. data/pgpool2/test/jdbc/PgpoolTest.java +75 -0
  263. data/pgpool2/test/jdbc/README.euc_jp +73 -0
  264. data/pgpool2/test/jdbc/RunTest.java +83 -0
  265. data/pgpool2/test/jdbc/SelectTest.java +37 -0
  266. data/pgpool2/test/jdbc/UpdateTest.java +32 -0
  267. data/pgpool2/test/jdbc/expected/CreateTempTable +1 -0
  268. data/pgpool2/test/jdbc/expected/autocommit +10 -0
  269. data/pgpool2/test/jdbc/expected/batch +1 -0
  270. data/pgpool2/test/jdbc/expected/column +100 -0
  271. data/pgpool2/test/jdbc/expected/insert +1 -0
  272. data/pgpool2/test/jdbc/expected/lock +100 -0
  273. data/pgpool2/test/jdbc/expected/select +2 -0
  274. data/pgpool2/test/jdbc/expected/update +1 -0
  275. data/pgpool2/test/jdbc/pgpool.properties +7 -0
  276. data/pgpool2/test/jdbc/prepare.sql +54 -0
  277. data/pgpool2/test/jdbc/run.sh +6 -0
  278. data/pgpool2/test/parser/.cvsignore +6 -0
  279. data/pgpool2/test/parser/README +32 -0
  280. data/pgpool2/test/parser/expected/copy.out +17 -0
  281. data/pgpool2/test/parser/expected/create.out +64 -0
  282. data/pgpool2/test/parser/expected/cursor.out +37 -0
  283. data/pgpool2/test/parser/expected/delete.out +10 -0
  284. data/pgpool2/test/parser/expected/drop.out +12 -0
  285. data/pgpool2/test/parser/expected/insert.out +13 -0
  286. data/pgpool2/test/parser/expected/misc.out +28 -0
  287. data/pgpool2/test/parser/expected/prepare.out +4 -0
  288. data/pgpool2/test/parser/expected/privileges.out +31 -0
  289. data/pgpool2/test/parser/expected/scanner.out +30 -0
  290. data/pgpool2/test/parser/expected/select.out +89 -0
  291. data/pgpool2/test/parser/expected/transaction.out +38 -0
  292. data/pgpool2/test/parser/expected/update.out +11 -0
  293. data/pgpool2/test/parser/expected/v84.out +37 -0
  294. data/pgpool2/test/parser/expected/v90.out +25 -0
  295. data/pgpool2/test/parser/expected/var.out +22 -0
  296. data/pgpool2/test/parser/input/alter.sql +2 -0
  297. data/pgpool2/test/parser/input/copy.sql +17 -0
  298. data/pgpool2/test/parser/input/create.sql +64 -0
  299. data/pgpool2/test/parser/input/cursor.sql +37 -0
  300. data/pgpool2/test/parser/input/delete.sql +10 -0
  301. data/pgpool2/test/parser/input/drop.sql +12 -0
  302. data/pgpool2/test/parser/input/insert.sql +13 -0
  303. data/pgpool2/test/parser/input/misc.sql +28 -0
  304. data/pgpool2/test/parser/input/prepare.sql +4 -0
  305. data/pgpool2/test/parser/input/privileges.sql +31 -0
  306. data/pgpool2/test/parser/input/scanner.sql +34 -0
  307. data/pgpool2/test/parser/input/select.sql +89 -0
  308. data/pgpool2/test/parser/input/transaction.sql +38 -0
  309. data/pgpool2/test/parser/input/update.sql +11 -0
  310. data/pgpool2/test/parser/input/v84.sql +37 -0
  311. data/pgpool2/test/parser/input/v90.sql +38 -0
  312. data/pgpool2/test/parser/input/var.sql +22 -0
  313. data/pgpool2/test/parser/main.c +96 -0
  314. data/pgpool2/test/parser/parse_schedule +16 -0
  315. data/pgpool2/test/parser/pool.h +13 -0
  316. data/pgpool2/test/parser/run-test +62 -0
  317. data/pgpool2/test/pdo-test/README.euc_jp +58 -0
  318. data/pgpool2/test/pdo-test/SQLlist/test1.sql +3 -0
  319. data/pgpool2/test/pdo-test/SQLlist/test2.sql +3 -0
  320. data/pgpool2/test/pdo-test/collections.inc +11 -0
  321. data/pgpool2/test/pdo-test/def.inc +7 -0
  322. data/pgpool2/test/pdo-test/log.txt +0 -0
  323. data/pgpool2/test/pdo-test/mod/database.inc +36 -0
  324. data/pgpool2/test/pdo-test/mod/def.inc +0 -0
  325. data/pgpool2/test/pdo-test/mod/errorhandler.inc +27 -0
  326. data/pgpool2/test/pdo-test/pdotest.php +11 -0
  327. data/pgpool2/test/pdo-test/regsql.inc +56 -0
  328. data/pgpool2/test/pgpool_setup +898 -0
  329. data/pgpool2/test/regression/README +39 -0
  330. data/pgpool2/test/regression/clean.sh +21 -0
  331. data/pgpool2/test/regression/libs.sh +16 -0
  332. data/pgpool2/test/regression/regress.sh +166 -0
  333. data/pgpool2/test/regression/tests/001.load_balance/test.sh +128 -0
  334. data/pgpool2/test/regression/tests/002.native_replication/PgTester.java +47 -0
  335. data/pgpool2/test/regression/tests/002.native_replication/create.sql +6 -0
  336. data/pgpool2/test/regression/tests/002.native_replication/test.sh +71 -0
  337. data/pgpool2/test/regression/tests/003.failover/expected.r +6 -0
  338. data/pgpool2/test/regression/tests/003.failover/expected.s +6 -0
  339. data/pgpool2/test/regression/tests/003.failover/test.sh +45 -0
  340. data/pgpool2/test/regression/tests/004.watchdog/master.conf +12 -0
  341. data/pgpool2/test/regression/tests/004.watchdog/standby.conf +19 -0
  342. data/pgpool2/test/regression/tests/004.watchdog/test.sh +52 -0
  343. data/pgpool2/test/regression/tests/050.bug58/test.sh +50 -0
  344. data/pgpool2/test/regression/tests/051.bug60/bug.sql +12 -0
  345. data/pgpool2/test/regression/tests/051.bug60/database-clean.sql +6 -0
  346. data/pgpool2/test/regression/tests/051.bug60/database-setup.sql +28 -0
  347. data/pgpool2/test/regression/tests/051.bug60/test.sh +79 -0
  348. data/pgpool2/test/regression/tests/052.do_query/test.sh +44 -0
  349. data/pgpool2/test/regression/tests/053.insert_lock_hangs/test.sh +81 -0
  350. data/pgpool2/test/regression/tests/054.postgres_fdw/test.sh +67 -0
  351. data/pgpool2/test/regression/tests/055.backend_all_down/test.sh +52 -0
  352. data/pgpool2/test/regression/tests/056.bug63/jdbctest2.java +66 -0
  353. data/pgpool2/test/regression/tests/056.bug63/test.sh +47 -0
  354. data/pgpool2/test/regression/tests/057.bug61/test.sh +40 -0
  355. data/pgpool2/test/regression/tests/058.bug68/jdbctest3.java +45 -0
  356. data/pgpool2/test/regression/tests/058.bug68/test.sh +47 -0
  357. data/pgpool2/test/timestamp/expected/insert.out +16 -0
  358. data/pgpool2/test/timestamp/expected/misc.out +3 -0
  359. data/pgpool2/test/timestamp/expected/update.out +6 -0
  360. data/pgpool2/test/timestamp/input/insert.sql +16 -0
  361. data/pgpool2/test/timestamp/input/misc.sql +3 -0
  362. data/pgpool2/test/timestamp/input/update.sql +6 -0
  363. data/pgpool2/test/timestamp/main.c +129 -0
  364. data/pgpool2/test/timestamp/parse_schedule +3 -0
  365. data/pgpool2/test/timestamp/run-test +69 -0
  366. data/pgpool2/version.h +1 -0
  367. data/pgpool2/watchdog/Makefile.am +17 -0
  368. data/pgpool2/watchdog/Makefile.in +505 -0
  369. data/pgpool2/watchdog/test/stab.c +266 -0
  370. data/pgpool2/watchdog/test/test.c +85 -0
  371. data/pgpool2/watchdog/test/wd_child_t.c +87 -0
  372. data/pgpool2/watchdog/test/wd_lifecheck_t.c +87 -0
  373. data/pgpool2/watchdog/test/wd_packet_t.c +87 -0
  374. data/pgpool2/watchdog/test/wd_ping_t.c +20 -0
  375. data/pgpool2/watchdog/watchdog.c +408 -0
  376. data/pgpool2/watchdog/watchdog.h +209 -0
  377. data/pgpool2/watchdog/wd_child.c +444 -0
  378. data/pgpool2/watchdog/wd_ext.h +123 -0
  379. data/pgpool2/watchdog/wd_heartbeat.c +577 -0
  380. data/pgpool2/watchdog/wd_if.c +216 -0
  381. data/pgpool2/watchdog/wd_init.c +126 -0
  382. data/pgpool2/watchdog/wd_interlock.c +347 -0
  383. data/pgpool2/watchdog/wd_lifecheck.c +512 -0
  384. data/pgpool2/watchdog/wd_list.c +429 -0
  385. data/pgpool2/watchdog/wd_packet.c +1159 -0
  386. data/pgpool2/watchdog/wd_ping.c +330 -0
  387. data/pgpool2/ylwrap +223 -0
  388. data/pgsql/presto_client.py +346 -0
  389. data/pgsql/prestogres.py +156 -0
  390. data/pgsql/setup_functions.sql +21 -0
  391. data/pgsql/setup_language.sql +3 -0
  392. data/prestogres.gemspec +23 -0
  393. metadata +496 -0
@@ -0,0 +1,78 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * value.c
4
+ * implementation of Value nodes
5
+ *
6
+ *
7
+ * Portions Copyright (c) 2003-2013, PgPool Global Development Group
8
+ * Copyright (c) 2003-2012, PostgreSQL Global Development Group
9
+ *
10
+ *
11
+ * IDENTIFICATION
12
+ * src/backend/nodes/value.c
13
+ *
14
+ *-------------------------------------------------------------------------
15
+ */
16
+ /*#include "postgres.h"*/
17
+
18
+ #include <stdlib.h>
19
+ #include "pool_memory.h"
20
+ #include "parsenodes.h"
21
+
22
+ /*
23
+ * makeInteger
24
+ */
25
+ Value *
26
+ makeInteger(long i)
27
+ {
28
+ Value *v = makeNode(Value);
29
+
30
+ v->type = T_Integer;
31
+ v->val.ival = i;
32
+ return v;
33
+ }
34
+
35
+ /*
36
+ * makeFloat
37
+ *
38
+ * Caller is responsible for passing a palloc'd string.
39
+ */
40
+ Value *
41
+ makeFloat(char *numericStr)
42
+ {
43
+ Value *v = makeNode(Value);
44
+
45
+ v->type = T_Float;
46
+ v->val.str = numericStr;
47
+ return v;
48
+ }
49
+
50
+ /*
51
+ * makeString
52
+ *
53
+ * Caller is responsible for passing a palloc'd string.
54
+ */
55
+ Value *
56
+ makeString(char *str)
57
+ {
58
+ Value *v = makeNode(Value);
59
+
60
+ v->type = T_String;
61
+ v->val.str = str;
62
+ return v;
63
+ }
64
+
65
+ /*
66
+ * makeBitString
67
+ *
68
+ * Caller is responsible for passing a palloc'd string.
69
+ */
70
+ Value *
71
+ makeBitString(char *str)
72
+ {
73
+ Value *v = makeNode(Value);
74
+
75
+ v->type = T_BitString;
76
+ v->val.str = str;
77
+ return v;
78
+ }
@@ -0,0 +1,62 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * value.h
4
+ * interface for Value nodes
5
+ *
6
+ *
7
+ * Copyright (c) 2003-2013, PgPool Global Development Group
8
+ * Copyright (c) 2003-2012, PostgreSQL Global Development Group
9
+ *
10
+ * src/include/nodes/value.h
11
+ *
12
+ *-------------------------------------------------------------------------
13
+ */
14
+
15
+ #ifndef VALUE_H
16
+ #define VALUE_H
17
+
18
+ #include "nodes.h"
19
+
20
+ /*----------------------
21
+ * Value node
22
+ *
23
+ * The same Value struct is used for five node types: T_Integer,
24
+ * T_Float, T_String, T_BitString, T_Null.
25
+ *
26
+ * Integral values are actually represented by a machine integer,
27
+ * but both floats and strings are represented as strings.
28
+ * Using T_Float as the node type simply indicates that
29
+ * the contents of the string look like a valid numeric literal.
30
+ *
31
+ * (Before Postgres 7.0, we used a double to represent T_Float,
32
+ * but that creates loss-of-precision problems when the value is
33
+ * ultimately destined to be converted to NUMERIC. Since Value nodes
34
+ * are only used in the parsing process, not for runtime data, it's
35
+ * better to use the more general representation.)
36
+ *
37
+ * Note that an integer-looking string will get lexed as T_Float if
38
+ * the value is too large to fit in a 'long'.
39
+ *
40
+ * Nulls, of course, don't need the value part at all.
41
+ *----------------------
42
+ */
43
+ typedef struct Value
44
+ {
45
+ NodeTag type; /* tag appropriately (eg. T_String) */
46
+ union ValUnion
47
+ {
48
+ long ival; /* machine integer */
49
+ char *str; /* string */
50
+ } val;
51
+ } Value;
52
+
53
+ #define intVal(v) (((Value *)(v))->val.ival)
54
+ #define floatVal(v) atof(((Value *)(v))->val.str)
55
+ #define strVal(v) (((Value *)(v))->val.str)
56
+
57
+ extern Value *makeInteger(long i);
58
+ extern Value *makeFloat(char *numericStr);
59
+ extern Value *makeString(char *str);
60
+ extern Value *makeBitString(char *str);
61
+
62
+ #endif /* VALUE_H */
@@ -0,0 +1,2048 @@
1
+ /*
2
+ * conversion functions between pg_wchar and multibyte streams.
3
+ * Tatsuo Ishii
4
+ * src/backend/utils/mb/wchar.c
5
+ *
6
+ */
7
+ /* can be used in either frontend or backend */
8
+ #include "pool_parser.h"
9
+ #include <stdio.h>
10
+ #include <string.h>
11
+ #include "pg_wchar.h"
12
+
13
+
14
+ /*
15
+ * conversion to pg_wchar is done by "table driven."
16
+ * to add an encoding support, define mb2wchar_with_len(), mblen(), dsplen()
17
+ * for the particular encoding. Note that if the encoding is only
18
+ * supported in the client, you don't need to define
19
+ * mb2wchar_with_len() function (SJIS is the case).
20
+ *
21
+ * These functions generally assume that their input is validly formed.
22
+ * The "verifier" functions, further down in the file, have to be more
23
+ * paranoid. We expect that mblen() does not need to examine more than
24
+ * the first byte of the character to discover the correct length.
25
+ *
26
+ * Note: for the display output of psql to work properly, the return values
27
+ * of the dsplen functions must conform to the Unicode standard. In particular
28
+ * the NUL character is zero width and control characters are generally
29
+ * width -1. It is recommended that non-ASCII encodings refer their ASCII
30
+ * subset to the ASCII routines to ensure consistency.
31
+ */
32
+
33
+ /*
34
+ * SQL/ASCII
35
+ */
36
+ static int
37
+ pg_ascii2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
38
+ {
39
+ int cnt = 0;
40
+
41
+ while (len > 0 && *from)
42
+ {
43
+ *to++ = *from++;
44
+ len--;
45
+ cnt++;
46
+ }
47
+ *to = 0;
48
+ return cnt;
49
+ }
50
+
51
+ static int
52
+ pg_ascii_mblen(const unsigned char *s)
53
+ {
54
+ return 1;
55
+ }
56
+
57
+ static int
58
+ pg_ascii_dsplen(const unsigned char *s)
59
+ {
60
+ if (*s == '\0')
61
+ return 0;
62
+ if (*s < 0x20 || *s == 0x7f)
63
+ return -1;
64
+
65
+ return 1;
66
+ }
67
+
68
+ /*
69
+ * EUC
70
+ */
71
+ static int
72
+ pg_euc2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
73
+ {
74
+ int cnt = 0;
75
+
76
+ while (len > 0 && *from)
77
+ {
78
+ if (*from == SS2 && len >= 2) /* JIS X 0201 (so called "1 byte
79
+ * KANA") */
80
+ {
81
+ from++;
82
+ *to = (SS2 << 8) | *from++;
83
+ len -= 2;
84
+ }
85
+ else if (*from == SS3 && len >= 3) /* JIS X 0212 KANJI */
86
+ {
87
+ from++;
88
+ *to = (SS3 << 16) | (*from++ << 8);
89
+ *to |= *from++;
90
+ len -= 3;
91
+ }
92
+ else if (IS_HIGHBIT_SET(*from) && len >= 2) /* JIS X 0208 KANJI */
93
+ {
94
+ *to = *from++ << 8;
95
+ *to |= *from++;
96
+ len -= 2;
97
+ }
98
+ else /* must be ASCII */
99
+ {
100
+ *to = *from++;
101
+ len--;
102
+ }
103
+ to++;
104
+ cnt++;
105
+ }
106
+ *to = 0;
107
+ return cnt;
108
+ }
109
+
110
+ static inline int
111
+ pg_euc_mblen(const unsigned char *s)
112
+ {
113
+ int len;
114
+
115
+ if (*s == SS2)
116
+ len = 2;
117
+ else if (*s == SS3)
118
+ len = 3;
119
+ else if (IS_HIGHBIT_SET(*s))
120
+ len = 2;
121
+ else
122
+ len = 1;
123
+ return len;
124
+ }
125
+
126
+ static inline int
127
+ pg_euc_dsplen(const unsigned char *s)
128
+ {
129
+ int len;
130
+
131
+ if (*s == SS2)
132
+ len = 2;
133
+ else if (*s == SS3)
134
+ len = 2;
135
+ else if (IS_HIGHBIT_SET(*s))
136
+ len = 2;
137
+ else
138
+ len = pg_ascii_dsplen(s);
139
+ return len;
140
+ }
141
+
142
+ /*
143
+ * EUC_JP
144
+ */
145
+ static int
146
+ pg_eucjp2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
147
+ {
148
+ return pg_euc2wchar_with_len(from, to, len);
149
+ }
150
+
151
+ static int
152
+ pg_eucjp_mblen(const unsigned char *s)
153
+ {
154
+ return pg_euc_mblen(s);
155
+ }
156
+
157
+ static int
158
+ pg_eucjp_dsplen(const unsigned char *s)
159
+ {
160
+ int len;
161
+
162
+ if (*s == SS2)
163
+ len = 1;
164
+ else if (*s == SS3)
165
+ len = 2;
166
+ else if (IS_HIGHBIT_SET(*s))
167
+ len = 2;
168
+ else
169
+ len = pg_ascii_dsplen(s);
170
+ return len;
171
+ }
172
+
173
+ /*
174
+ * EUC_KR
175
+ */
176
+ static int
177
+ pg_euckr2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
178
+ {
179
+ return pg_euc2wchar_with_len(from, to, len);
180
+ }
181
+
182
+ static int
183
+ pg_euckr_mblen(const unsigned char *s)
184
+ {
185
+ return pg_euc_mblen(s);
186
+ }
187
+
188
+ static int
189
+ pg_euckr_dsplen(const unsigned char *s)
190
+ {
191
+ return pg_euc_dsplen(s);
192
+ }
193
+
194
+ /*
195
+ * EUC_CN
196
+ *
197
+ */
198
+ static int
199
+ pg_euccn2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
200
+ {
201
+ int cnt = 0;
202
+
203
+ while (len > 0 && *from)
204
+ {
205
+ if (*from == SS2 && len >= 3) /* code set 2 (unused?) */
206
+ {
207
+ from++;
208
+ *to = (SS2 << 16) | (*from++ << 8);
209
+ *to |= *from++;
210
+ len -= 3;
211
+ }
212
+ else if (*from == SS3 && len >= 3) /* code set 3 (unused ?) */
213
+ {
214
+ from++;
215
+ *to = (SS3 << 16) | (*from++ << 8);
216
+ *to |= *from++;
217
+ len -= 3;
218
+ }
219
+ else if (IS_HIGHBIT_SET(*from) && len >= 2) /* code set 1 */
220
+ {
221
+ *to = *from++ << 8;
222
+ *to |= *from++;
223
+ len -= 2;
224
+ }
225
+ else
226
+ {
227
+ *to = *from++;
228
+ len--;
229
+ }
230
+ to++;
231
+ cnt++;
232
+ }
233
+ *to = 0;
234
+ return cnt;
235
+ }
236
+
237
+ static int
238
+ pg_euccn_mblen(const unsigned char *s)
239
+ {
240
+ int len;
241
+
242
+ if (IS_HIGHBIT_SET(*s))
243
+ len = 2;
244
+ else
245
+ len = 1;
246
+ return len;
247
+ }
248
+
249
+ static int
250
+ pg_euccn_dsplen(const unsigned char *s)
251
+ {
252
+ int len;
253
+
254
+ if (IS_HIGHBIT_SET(*s))
255
+ len = 2;
256
+ else
257
+ len = pg_ascii_dsplen(s);
258
+ return len;
259
+ }
260
+
261
+ /*
262
+ * EUC_TW
263
+ *
264
+ */
265
+ static int
266
+ pg_euctw2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
267
+ {
268
+ int cnt = 0;
269
+
270
+ while (len > 0 && *from)
271
+ {
272
+ if (*from == SS2 && len >= 4) /* code set 2 */
273
+ {
274
+ from++;
275
+ *to = (((uint32) SS2) << 24) | (*from++ << 16);
276
+ *to |= *from++ << 8;
277
+ *to |= *from++;
278
+ len -= 4;
279
+ }
280
+ else if (*from == SS3 && len >= 3) /* code set 3 (unused?) */
281
+ {
282
+ from++;
283
+ *to = (SS3 << 16) | (*from++ << 8);
284
+ *to |= *from++;
285
+ len -= 3;
286
+ }
287
+ else if (IS_HIGHBIT_SET(*from) && len >= 2) /* code set 2 */
288
+ {
289
+ *to = *from++ << 8;
290
+ *to |= *from++;
291
+ len -= 2;
292
+ }
293
+ else
294
+ {
295
+ *to = *from++;
296
+ len--;
297
+ }
298
+ to++;
299
+ cnt++;
300
+ }
301
+ *to = 0;
302
+ return cnt;
303
+ }
304
+
305
+ static int
306
+ pg_euctw_mblen(const unsigned char *s)
307
+ {
308
+ int len;
309
+
310
+ if (*s == SS2)
311
+ len = 4;
312
+ else if (*s == SS3)
313
+ len = 3;
314
+ else if (IS_HIGHBIT_SET(*s))
315
+ len = 2;
316
+ else
317
+ len = 1;
318
+ return len;
319
+ }
320
+
321
+ static int
322
+ pg_euctw_dsplen(const unsigned char *s)
323
+ {
324
+ int len;
325
+
326
+ if (*s == SS2)
327
+ len = 2;
328
+ else if (*s == SS3)
329
+ len = 2;
330
+ else if (IS_HIGHBIT_SET(*s))
331
+ len = 2;
332
+ else
333
+ len = pg_ascii_dsplen(s);
334
+ return len;
335
+ }
336
+
337
+ /*
338
+ * Convert pg_wchar to EUC_* encoding.
339
+ * caller must allocate enough space for "to", including a trailing zero!
340
+ * len: length of from.
341
+ * "from" not necessarily null terminated.
342
+ */
343
+ static int
344
+ pg_wchar2euc_with_len(const pg_wchar *from, unsigned char *to, int len)
345
+ {
346
+ int cnt = 0;
347
+
348
+ while (len > 0 && *from)
349
+ {
350
+ unsigned char c;
351
+
352
+ if ((c = (*from >> 24)))
353
+ {
354
+ *to++ = c;
355
+ *to++ = (*from >> 16) & 0xff;
356
+ *to++ = (*from >> 8) & 0xff;
357
+ *to++ = *from & 0xff;
358
+ cnt += 4;
359
+ }
360
+ else if ((c = (*from >> 16)))
361
+ {
362
+ *to++ = c;
363
+ *to++ = (*from >> 8) & 0xff;
364
+ *to++ = *from & 0xff;
365
+ cnt += 3;
366
+ }
367
+ else if ((c = (*from >> 8)))
368
+ {
369
+ *to++ = c;
370
+ *to++ = *from & 0xff;
371
+ cnt += 2;
372
+ }
373
+ else
374
+ {
375
+ *to++ = *from;
376
+ cnt++;
377
+ }
378
+ from++;
379
+ len--;
380
+ }
381
+ *to = 0;
382
+ return cnt;
383
+ }
384
+
385
+
386
+ /*
387
+ * JOHAB
388
+ */
389
+ static int
390
+ pg_johab_mblen(const unsigned char *s)
391
+ {
392
+ return pg_euc_mblen(s);
393
+ }
394
+
395
+ static int
396
+ pg_johab_dsplen(const unsigned char *s)
397
+ {
398
+ return pg_euc_dsplen(s);
399
+ }
400
+
401
+ /*
402
+ * convert UTF8 string to pg_wchar (UCS-4)
403
+ * caller must allocate enough space for "to", including a trailing zero!
404
+ * len: length of from.
405
+ * "from" not necessarily null terminated.
406
+ */
407
+ static int
408
+ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
409
+ {
410
+ int cnt = 0;
411
+ uint32 c1,
412
+ c2,
413
+ c3,
414
+ c4;
415
+
416
+ while (len > 0 && *from)
417
+ {
418
+ if ((*from & 0x80) == 0)
419
+ {
420
+ *to = *from++;
421
+ len--;
422
+ }
423
+ else if ((*from & 0xe0) == 0xc0)
424
+ {
425
+ if (len < 2)
426
+ break; /* drop trailing incomplete char */
427
+ c1 = *from++ & 0x1f;
428
+ c2 = *from++ & 0x3f;
429
+ *to = (c1 << 6) | c2;
430
+ len -= 2;
431
+ }
432
+ else if ((*from & 0xf0) == 0xe0)
433
+ {
434
+ if (len < 3)
435
+ break; /* drop trailing incomplete char */
436
+ c1 = *from++ & 0x0f;
437
+ c2 = *from++ & 0x3f;
438
+ c3 = *from++ & 0x3f;
439
+ *to = (c1 << 12) | (c2 << 6) | c3;
440
+ len -= 3;
441
+ }
442
+ else if ((*from & 0xf8) == 0xf0)
443
+ {
444
+ if (len < 4)
445
+ break; /* drop trailing incomplete char */
446
+ c1 = *from++ & 0x07;
447
+ c2 = *from++ & 0x3f;
448
+ c3 = *from++ & 0x3f;
449
+ c4 = *from++ & 0x3f;
450
+ *to = (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
451
+ len -= 4;
452
+ }
453
+ else
454
+ {
455
+ /* treat a bogus char as length 1; not ours to raise error */
456
+ *to = *from++;
457
+ len--;
458
+ }
459
+ to++;
460
+ cnt++;
461
+ }
462
+ *to = 0;
463
+ return cnt;
464
+ }
465
+
466
+
467
+ /*
468
+ * Map a Unicode code point to UTF-8. utf8string must have 4 bytes of
469
+ * space allocated.
470
+ */
471
+ unsigned char *
472
+ unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
473
+ {
474
+ if (c <= 0x7F)
475
+ {
476
+ utf8string[0] = c;
477
+ }
478
+ else if (c <= 0x7FF)
479
+ {
480
+ utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
481
+ utf8string[1] = 0x80 | (c & 0x3F);
482
+ }
483
+ else if (c <= 0xFFFF)
484
+ {
485
+ utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
486
+ utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
487
+ utf8string[2] = 0x80 | (c & 0x3F);
488
+ }
489
+ else
490
+ {
491
+ utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
492
+ utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
493
+ utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
494
+ utf8string[3] = 0x80 | (c & 0x3F);
495
+ }
496
+
497
+ return utf8string;
498
+ }
499
+
500
+ /*
501
+ * Trivial conversion from pg_wchar to UTF-8.
502
+ * caller should allocate enough space for "to"
503
+ * len: length of from.
504
+ * "from" not necessarily null terminated.
505
+ */
506
+ static int
507
+ pg_wchar2utf_with_len(const pg_wchar *from, unsigned char *to, int len)
508
+ {
509
+ int cnt = 0;
510
+
511
+ while (len > 0 && *from)
512
+ {
513
+ int char_len;
514
+
515
+ unicode_to_utf8(*from, to);
516
+ char_len = pg_utf_mblen(to);
517
+ cnt += char_len;
518
+ to += char_len;
519
+ from++;
520
+ len--;
521
+ }
522
+ *to = 0;
523
+ return cnt;
524
+ }
525
+
526
+ /*
527
+ * Return the byte length of a UTF8 character pointed to by s
528
+ *
529
+ * Note: in the current implementation we do not support UTF8 sequences
530
+ * of more than 4 bytes; hence do NOT return a value larger than 4.
531
+ * We return "1" for any leading byte that is either flat-out illegal or
532
+ * indicates a length larger than we support.
533
+ *
534
+ * pg_utf2wchar_with_len(), utf8_to_unicode(), pg_utf8_islegal(), and perhaps
535
+ * other places would need to be fixed to change this.
536
+ */
537
+ int
538
+ pg_utf_mblen(const unsigned char *s)
539
+ {
540
+ int len;
541
+
542
+ if ((*s & 0x80) == 0)
543
+ len = 1;
544
+ else if ((*s & 0xe0) == 0xc0)
545
+ len = 2;
546
+ else if ((*s & 0xf0) == 0xe0)
547
+ len = 3;
548
+ else if ((*s & 0xf8) == 0xf0)
549
+ len = 4;
550
+ #ifdef NOT_USED
551
+ else if ((*s & 0xfc) == 0xf8)
552
+ len = 5;
553
+ else if ((*s & 0xfe) == 0xfc)
554
+ len = 6;
555
+ #endif
556
+ else
557
+ len = 1;
558
+ return len;
559
+ }
560
+
561
+ /*
562
+ * This is an implementation of wcwidth() and wcswidth() as defined in
563
+ * "The Single UNIX Specification, Version 2, The Open Group, 1997"
564
+ * <http://www.UNIX-systems.org/online.html>
565
+ *
566
+ * Markus Kuhn -- 2001-09-08 -- public domain
567
+ *
568
+ * customised for PostgreSQL
569
+ *
570
+ * original available at : http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
571
+ */
572
+
573
+ struct mbinterval
574
+ {
575
+ unsigned short first;
576
+ unsigned short last;
577
+ };
578
+
579
+ /* auxiliary function for binary search in interval table */
580
+ static int
581
+ mbbisearch(pg_wchar ucs, const struct mbinterval * table, int max)
582
+ {
583
+ int min = 0;
584
+ int mid;
585
+
586
+ if (ucs < table[0].first || ucs > table[max].last)
587
+ return 0;
588
+ while (max >= min)
589
+ {
590
+ mid = (min + max) / 2;
591
+ if (ucs > table[mid].last)
592
+ min = mid + 1;
593
+ else if (ucs < table[mid].first)
594
+ max = mid - 1;
595
+ else
596
+ return 1;
597
+ }
598
+
599
+ return 0;
600
+ }
601
+
602
+
603
+ /* The following functions define the column width of an ISO 10646
604
+ * character as follows:
605
+ *
606
+ * - The null character (U+0000) has a column width of 0.
607
+ *
608
+ * - Other C0/C1 control characters and DEL will lead to a return
609
+ * value of -1.
610
+ *
611
+ * - Non-spacing and enclosing combining characters (general
612
+ * category code Mn or Me in the Unicode database) have a
613
+ * column width of 0.
614
+ *
615
+ * - Other format characters (general category code Cf in the Unicode
616
+ * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
617
+ *
618
+ * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
619
+ * have a column width of 0.
620
+ *
621
+ * - Spacing characters in the East Asian Wide (W) or East Asian
622
+ * FullWidth (F) category as defined in Unicode Technical
623
+ * Report #11 have a column width of 2.
624
+ *
625
+ * - All remaining characters (including all printable
626
+ * ISO 8859-1 and WGL4 characters, Unicode control characters,
627
+ * etc.) have a column width of 1.
628
+ *
629
+ * This implementation assumes that wchar_t characters are encoded
630
+ * in ISO 10646.
631
+ */
632
+
633
+ static int
634
+ ucs_wcwidth(pg_wchar ucs)
635
+ {
636
+ /* sorted list of non-overlapping intervals of non-spacing characters */
637
+ static const struct mbinterval combining[] = {
638
+ {0x0300, 0x034E}, {0x0360, 0x0362}, {0x0483, 0x0486},
639
+ {0x0488, 0x0489}, {0x0591, 0x05A1}, {0x05A3, 0x05B9},
640
+ {0x05BB, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2},
641
+ {0x05C4, 0x05C4}, {0x064B, 0x0655}, {0x0670, 0x0670},
642
+ {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED},
643
+ {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A},
644
+ {0x07A6, 0x07B0}, {0x0901, 0x0902}, {0x093C, 0x093C},
645
+ {0x0941, 0x0948}, {0x094D, 0x094D}, {0x0951, 0x0954},
646
+ {0x0962, 0x0963}, {0x0981, 0x0981}, {0x09BC, 0x09BC},
647
+ {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, {0x09E2, 0x09E3},
648
+ {0x0A02, 0x0A02}, {0x0A3C, 0x0A3C}, {0x0A41, 0x0A42},
649
+ {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A70, 0x0A71},
650
+ {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, {0x0AC1, 0x0AC5},
651
+ {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, {0x0B01, 0x0B01},
652
+ {0x0B3C, 0x0B3C}, {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43},
653
+ {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B82, 0x0B82},
654
+ {0x0BC0, 0x0BC0}, {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40},
655
+ {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},
656
+ {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD},
657
+ {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, {0x0DCA, 0x0DCA},
658
+ {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0E31, 0x0E31},
659
+ {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, {0x0EB1, 0x0EB1},
660
+ {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, {0x0EC8, 0x0ECD},
661
+ {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, {0x0F37, 0x0F37},
662
+ {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, {0x0F80, 0x0F84},
663
+ {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, {0x0F99, 0x0FBC},
664
+ {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, {0x1032, 0x1032},
665
+ {0x1036, 0x1037}, {0x1039, 0x1039}, {0x1058, 0x1059},
666
+ {0x1160, 0x11FF}, {0x17B7, 0x17BD}, {0x17C6, 0x17C6},
667
+ {0x17C9, 0x17D3}, {0x180B, 0x180E}, {0x18A9, 0x18A9},
668
+ {0x200B, 0x200F}, {0x202A, 0x202E}, {0x206A, 0x206F},
669
+ {0x20D0, 0x20E3}, {0x302A, 0x302F}, {0x3099, 0x309A},
670
+ {0xFB1E, 0xFB1E}, {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF},
671
+ {0xFFF9, 0xFFFB}
672
+ };
673
+
674
+ /* test for 8-bit control characters */
675
+ if (ucs == 0)
676
+ return 0;
677
+
678
+ if (ucs < 0x20 || (ucs >= 0x7f && ucs < 0xa0) || ucs > 0x0010ffff)
679
+ return -1;
680
+
681
+ /* binary search in table of non-spacing characters */
682
+ if (mbbisearch(ucs, combining,
683
+ sizeof(combining) / sizeof(struct mbinterval) - 1))
684
+ return 0;
685
+
686
+ /*
687
+ * if we arrive here, ucs is not a combining or C0/C1 control character
688
+ */
689
+
690
+ return 1 +
691
+ (ucs >= 0x1100 &&
692
+ (ucs <= 0x115f || /* Hangul Jamo init. consonants */
693
+ (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&
694
+ ucs != 0x303f) || /* CJK ... Yi */
695
+ (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
696
+ (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility
697
+ * Ideographs */
698
+ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
699
+ (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */
700
+ (ucs >= 0xffe0 && ucs <= 0xffe6) ||
701
+ (ucs >= 0x20000 && ucs <= 0x2ffff)));
702
+ }
703
+
704
+ /*
705
+ * Convert a UTF-8 character to a Unicode code point.
706
+ * This is a one-character version of pg_utf2wchar_with_len.
707
+ *
708
+ * No error checks here, c must point to a long-enough string.
709
+ */
710
+ pg_wchar
711
+ utf8_to_unicode(const unsigned char *c)
712
+ {
713
+ if ((*c & 0x80) == 0)
714
+ return (pg_wchar) c[0];
715
+ else if ((*c & 0xe0) == 0xc0)
716
+ return (pg_wchar) (((c[0] & 0x1f) << 6) |
717
+ (c[1] & 0x3f));
718
+ else if ((*c & 0xf0) == 0xe0)
719
+ return (pg_wchar) (((c[0] & 0x0f) << 12) |
720
+ ((c[1] & 0x3f) << 6) |
721
+ (c[2] & 0x3f));
722
+ else if ((*c & 0xf8) == 0xf0)
723
+ return (pg_wchar) (((c[0] & 0x07) << 18) |
724
+ ((c[1] & 0x3f) << 12) |
725
+ ((c[2] & 0x3f) << 6) |
726
+ (c[3] & 0x3f));
727
+ else
728
+ /* that is an invalid code on purpose */
729
+ return 0xffffffff;
730
+ }
731
+
732
+ static int
733
+ pg_utf_dsplen(const unsigned char *s)
734
+ {
735
+ return ucs_wcwidth(utf8_to_unicode(s));
736
+ }
737
+
738
+ /*
739
+ * convert mule internal code to pg_wchar
740
+ * caller should allocate enough space for "to"
741
+ * len: length of from.
742
+ * "from" not necessarily null terminated.
743
+ */
744
+ static int
745
+ pg_mule2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
746
+ {
747
+ int cnt = 0;
748
+
749
+ while (len > 0 && *from)
750
+ {
751
+ if (IS_LC1(*from) && len >= 2)
752
+ {
753
+ *to = *from++ << 16;
754
+ *to |= *from++;
755
+ len -= 2;
756
+ }
757
+ else if (IS_LCPRV1(*from) && len >= 3)
758
+ {
759
+ from++;
760
+ *to = *from++ << 16;
761
+ *to |= *from++;
762
+ len -= 3;
763
+ }
764
+ else if (IS_LC2(*from) && len >= 3)
765
+ {
766
+ *to = *from++ << 16;
767
+ *to |= *from++ << 8;
768
+ *to |= *from++;
769
+ len -= 3;
770
+ }
771
+ else if (IS_LCPRV2(*from) && len >= 4)
772
+ {
773
+ from++;
774
+ *to = *from++ << 16;
775
+ *to |= *from++ << 8;
776
+ *to |= *from++;
777
+ len -= 4;
778
+ }
779
+ else
780
+ { /* assume ASCII */
781
+ *to = (unsigned char) *from++;
782
+ len--;
783
+ }
784
+ to++;
785
+ cnt++;
786
+ }
787
+ *to = 0;
788
+ return cnt;
789
+ }
790
+
791
+ /*
792
+ * convert pg_wchar to mule internal code
793
+ * caller should allocate enough space for "to"
794
+ * len: length of from.
795
+ * "from" not necessarily null terminated.
796
+ */
797
+ static int
798
+ pg_wchar2mule_with_len(const pg_wchar *from, unsigned char *to, int len)
799
+ {
800
+ int cnt = 0;
801
+
802
+ while (len > 0 && *from)
803
+ {
804
+ unsigned char lb;
805
+
806
+ lb = (*from >> 16) & 0xff;
807
+ if (IS_LC1(lb))
808
+ {
809
+ *to++ = lb;
810
+ *to++ = *from & 0xff;
811
+ cnt += 2;
812
+ }
813
+ else if (IS_LC2(lb))
814
+ {
815
+ *to++ = lb;
816
+ *to++ = (*from >> 8) & 0xff;
817
+ *to++ = *from & 0xff;
818
+ cnt += 3;
819
+ }
820
+ else if (IS_LCPRV1_A_RANGE(lb))
821
+ {
822
+ *to++ = LCPRV1_A;
823
+ *to++ = lb;
824
+ *to++ = *from & 0xff;
825
+ cnt += 3;
826
+ }
827
+ else if (IS_LCPRV1_B_RANGE(lb))
828
+ {
829
+ *to++ = LCPRV1_B;
830
+ *to++ = lb;
831
+ *to++ = *from & 0xff;
832
+ cnt += 3;
833
+ }
834
+ else if (IS_LCPRV2_A_RANGE(lb))
835
+ {
836
+ *to++ = LCPRV2_A;
837
+ *to++ = lb;
838
+ *to++ = (*from >> 8) & 0xff;
839
+ *to++ = *from & 0xff;
840
+ cnt += 4;
841
+ }
842
+ else if (IS_LCPRV2_B_RANGE(lb))
843
+ {
844
+ *to++ = LCPRV2_B;
845
+ *to++ = lb;
846
+ *to++ = (*from >> 8) & 0xff;
847
+ *to++ = *from & 0xff;
848
+ cnt += 4;
849
+ }
850
+ else
851
+ {
852
+ *to++ = *from & 0xff;
853
+ cnt += 1;
854
+ }
855
+ from++;
856
+ len--;
857
+ }
858
+ *to = 0;
859
+ return cnt;
860
+ }
861
+
862
+ int
863
+ pg_mule_mblen(const unsigned char *s)
864
+ {
865
+ int len;
866
+
867
+ if (IS_LC1(*s))
868
+ len = 2;
869
+ else if (IS_LCPRV1(*s))
870
+ len = 3;
871
+ else if (IS_LC2(*s))
872
+ len = 3;
873
+ else if (IS_LCPRV2(*s))
874
+ len = 4;
875
+ else
876
+ len = 1; /* assume ASCII */
877
+ return len;
878
+ }
879
+
880
+ static int
881
+ pg_mule_dsplen(const unsigned char *s)
882
+ {
883
+ int len;
884
+
885
+ if (IS_LC1(*s))
886
+ len = 1;
887
+ else if (IS_LCPRV1(*s))
888
+ len = 1;
889
+ else if (IS_LC2(*s))
890
+ len = 2;
891
+ else if (IS_LCPRV2(*s))
892
+ len = 2;
893
+ else
894
+ len = 1; /* assume ASCII */
895
+
896
+ return len;
897
+ }
898
+
899
+ /*
900
+ * ISO8859-1
901
+ */
902
+ static int
903
+ pg_latin12wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
904
+ {
905
+ int cnt = 0;
906
+
907
+ while (len > 0 && *from)
908
+ {
909
+ *to++ = *from++;
910
+ len--;
911
+ cnt++;
912
+ }
913
+ *to = 0;
914
+ return cnt;
915
+ }
916
+
917
+ /*
918
+ * Trivial conversion from pg_wchar to single byte encoding. Just ignores
919
+ * high bits.
920
+ * caller should allocate enough space for "to"
921
+ * len: length of from.
922
+ * "from" not necessarily null terminated.
923
+ */
924
+ static int
925
+ pg_wchar2single_with_len(const pg_wchar *from, unsigned char *to, int len)
926
+ {
927
+ int cnt = 0;
928
+
929
+ while (len > 0 && *from)
930
+ {
931
+ *to++ = *from++;
932
+ len--;
933
+ cnt++;
934
+ }
935
+ *to = 0;
936
+ return cnt;
937
+ }
938
+
939
+ static int
940
+ pg_latin1_mblen(const unsigned char *s)
941
+ {
942
+ return 1;
943
+ }
944
+
945
+ static int
946
+ pg_latin1_dsplen(const unsigned char *s)
947
+ {
948
+ return pg_ascii_dsplen(s);
949
+ }
950
+
951
+ /*
952
+ * SJIS
953
+ */
954
+ static int
955
+ pg_sjis_mblen(const unsigned char *s)
956
+ {
957
+ int len;
958
+
959
+ if (*s >= 0xa1 && *s <= 0xdf)
960
+ len = 1; /* 1 byte kana? */
961
+ else if (IS_HIGHBIT_SET(*s))
962
+ len = 2; /* kanji? */
963
+ else
964
+ len = 1; /* should be ASCII */
965
+ return len;
966
+ }
967
+
968
+ static int
969
+ pg_sjis_dsplen(const unsigned char *s)
970
+ {
971
+ int len;
972
+
973
+ if (*s >= 0xa1 && *s <= 0xdf)
974
+ len = 1; /* 1 byte kana? */
975
+ else if (IS_HIGHBIT_SET(*s))
976
+ len = 2; /* kanji? */
977
+ else
978
+ len = pg_ascii_dsplen(s); /* should be ASCII */
979
+ return len;
980
+ }
981
+
982
+ /*
983
+ * Big5
984
+ */
985
+ static int
986
+ pg_big5_mblen(const unsigned char *s)
987
+ {
988
+ int len;
989
+
990
+ if (IS_HIGHBIT_SET(*s))
991
+ len = 2; /* kanji? */
992
+ else
993
+ len = 1; /* should be ASCII */
994
+ return len;
995
+ }
996
+
997
+ static int
998
+ pg_big5_dsplen(const unsigned char *s)
999
+ {
1000
+ int len;
1001
+
1002
+ if (IS_HIGHBIT_SET(*s))
1003
+ len = 2; /* kanji? */
1004
+ else
1005
+ len = pg_ascii_dsplen(s); /* should be ASCII */
1006
+ return len;
1007
+ }
1008
+
1009
+ /*
1010
+ * GBK
1011
+ */
1012
+ static int
1013
+ pg_gbk_mblen(const unsigned char *s)
1014
+ {
1015
+ int len;
1016
+
1017
+ if (IS_HIGHBIT_SET(*s))
1018
+ len = 2; /* kanji? */
1019
+ else
1020
+ len = 1; /* should be ASCII */
1021
+ return len;
1022
+ }
1023
+
1024
+ static int
1025
+ pg_gbk_dsplen(const unsigned char *s)
1026
+ {
1027
+ int len;
1028
+
1029
+ if (IS_HIGHBIT_SET(*s))
1030
+ len = 2; /* kanji? */
1031
+ else
1032
+ len = pg_ascii_dsplen(s); /* should be ASCII */
1033
+ return len;
1034
+ }
1035
+
1036
+ /*
1037
+ * UHC
1038
+ */
1039
+ static int
1040
+ pg_uhc_mblen(const unsigned char *s)
1041
+ {
1042
+ int len;
1043
+
1044
+ if (IS_HIGHBIT_SET(*s))
1045
+ len = 2; /* 2byte? */
1046
+ else
1047
+ len = 1; /* should be ASCII */
1048
+ return len;
1049
+ }
1050
+
1051
+ static int
1052
+ pg_uhc_dsplen(const unsigned char *s)
1053
+ {
1054
+ int len;
1055
+
1056
+ if (IS_HIGHBIT_SET(*s))
1057
+ len = 2; /* 2byte? */
1058
+ else
1059
+ len = pg_ascii_dsplen(s); /* should be ASCII */
1060
+ return len;
1061
+ }
1062
+
1063
+ /*
1064
+ * * GB18030
1065
+ * * Added by Bill Huang <bhuang@redhat.com>,<bill_huanghb@ybb.ne.jp>
1066
+ * */
1067
+ static int
1068
+ pg_gb18030_mblen(const unsigned char *s)
1069
+ {
1070
+ int len;
1071
+
1072
+ if (!IS_HIGHBIT_SET(*s))
1073
+ len = 1; /* ASCII */
1074
+ else
1075
+ {
1076
+ if ((*(s + 1) >= 0x40 && *(s + 1) <= 0x7e) || (*(s + 1) >= 0x80 && *(s + 1) <= 0xfe))
1077
+ len = 2;
1078
+ else if (*(s + 1) >= 0x30 && *(s + 1) <= 0x39)
1079
+ len = 4;
1080
+ else
1081
+ len = 2;
1082
+ }
1083
+ return len;
1084
+ }
1085
+
1086
+ static int
1087
+ pg_gb18030_dsplen(const unsigned char *s)
1088
+ {
1089
+ int len;
1090
+
1091
+ if (IS_HIGHBIT_SET(*s))
1092
+ len = 2;
1093
+ else
1094
+ len = pg_ascii_dsplen(s); /* ASCII */
1095
+ return len;
1096
+ }
1097
+
1098
+ /*
1099
+ *-------------------------------------------------------------------
1100
+ * multibyte sequence validators
1101
+ *
1102
+ * These functions accept "s", a pointer to the first byte of a string,
1103
+ * and "len", the remaining length of the string. If there is a validly
1104
+ * encoded character beginning at *s, return its length in bytes; else
1105
+ * return -1.
1106
+ *
1107
+ * The functions can assume that len > 0 and that *s != '\0', but they must
1108
+ * test for and reject zeroes in any additional bytes of a multibyte character.
1109
+ *
1110
+ * Note that this definition allows the function for a single-byte
1111
+ * encoding to be just "return 1".
1112
+ *-------------------------------------------------------------------
1113
+ */
1114
+
1115
+ static int
1116
+ pg_ascii_verifier(const unsigned char *s, int len)
1117
+ {
1118
+ return 1;
1119
+ }
1120
+
1121
+ #define IS_EUC_RANGE_VALID(c) ((c) >= 0xa1 && (c) <= 0xfe)
1122
+
1123
+ static int
1124
+ pg_eucjp_verifier(const unsigned char *s, int len)
1125
+ {
1126
+ int l;
1127
+ unsigned char c1,
1128
+ c2;
1129
+
1130
+ c1 = *s++;
1131
+
1132
+ switch (c1)
1133
+ {
1134
+ case SS2: /* JIS X 0201 */
1135
+ l = 2;
1136
+ if (l > len)
1137
+ return -1;
1138
+ c2 = *s++;
1139
+ if (c2 < 0xa1 || c2 > 0xdf)
1140
+ return -1;
1141
+ break;
1142
+
1143
+ case SS3: /* JIS X 0212 */
1144
+ l = 3;
1145
+ if (l > len)
1146
+ return -1;
1147
+ c2 = *s++;
1148
+ if (!IS_EUC_RANGE_VALID(c2))
1149
+ return -1;
1150
+ c2 = *s++;
1151
+ if (!IS_EUC_RANGE_VALID(c2))
1152
+ return -1;
1153
+ break;
1154
+
1155
+ default:
1156
+ if (IS_HIGHBIT_SET(c1)) /* JIS X 0208? */
1157
+ {
1158
+ l = 2;
1159
+ if (l > len)
1160
+ return -1;
1161
+ if (!IS_EUC_RANGE_VALID(c1))
1162
+ return -1;
1163
+ c2 = *s++;
1164
+ if (!IS_EUC_RANGE_VALID(c2))
1165
+ return -1;
1166
+ }
1167
+ else
1168
+ /* must be ASCII */
1169
+ {
1170
+ l = 1;
1171
+ }
1172
+ break;
1173
+ }
1174
+
1175
+ return l;
1176
+ }
1177
+
1178
+ static int
1179
+ pg_euckr_verifier(const unsigned char *s, int len)
1180
+ {
1181
+ int l;
1182
+ unsigned char c1,
1183
+ c2;
1184
+
1185
+ c1 = *s++;
1186
+
1187
+ if (IS_HIGHBIT_SET(c1))
1188
+ {
1189
+ l = 2;
1190
+ if (l > len)
1191
+ return -1;
1192
+ if (!IS_EUC_RANGE_VALID(c1))
1193
+ return -1;
1194
+ c2 = *s++;
1195
+ if (!IS_EUC_RANGE_VALID(c2))
1196
+ return -1;
1197
+ }
1198
+ else
1199
+ /* must be ASCII */
1200
+ {
1201
+ l = 1;
1202
+ }
1203
+
1204
+ return l;
1205
+ }
1206
+
1207
+ /* EUC-CN byte sequences are exactly same as EUC-KR */
1208
+ #define pg_euccn_verifier pg_euckr_verifier
1209
+
1210
+ static int
1211
+ pg_euctw_verifier(const unsigned char *s, int len)
1212
+ {
1213
+ int l;
1214
+ unsigned char c1,
1215
+ c2;
1216
+
1217
+ c1 = *s++;
1218
+
1219
+ switch (c1)
1220
+ {
1221
+ case SS2: /* CNS 11643 Plane 1-7 */
1222
+ l = 4;
1223
+ if (l > len)
1224
+ return -1;
1225
+ c2 = *s++;
1226
+ if (c2 < 0xa1 || c2 > 0xa7)
1227
+ return -1;
1228
+ c2 = *s++;
1229
+ if (!IS_EUC_RANGE_VALID(c2))
1230
+ return -1;
1231
+ c2 = *s++;
1232
+ if (!IS_EUC_RANGE_VALID(c2))
1233
+ return -1;
1234
+ break;
1235
+
1236
+ case SS3: /* unused */
1237
+ return -1;
1238
+
1239
+ default:
1240
+ if (IS_HIGHBIT_SET(c1)) /* CNS 11643 Plane 1 */
1241
+ {
1242
+ l = 2;
1243
+ if (l > len)
1244
+ return -1;
1245
+ /* no further range check on c1? */
1246
+ c2 = *s++;
1247
+ if (!IS_EUC_RANGE_VALID(c2))
1248
+ return -1;
1249
+ }
1250
+ else
1251
+ /* must be ASCII */
1252
+ {
1253
+ l = 1;
1254
+ }
1255
+ break;
1256
+ }
1257
+ return l;
1258
+ }
1259
+
1260
+ static int
1261
+ pg_johab_verifier(const unsigned char *s, int len)
1262
+ {
1263
+ int l,
1264
+ mbl;
1265
+ unsigned char c;
1266
+
1267
+ l = mbl = pg_johab_mblen(s);
1268
+
1269
+ if (len < l)
1270
+ return -1;
1271
+
1272
+ if (!IS_HIGHBIT_SET(*s))
1273
+ return mbl;
1274
+
1275
+ while (--l > 0)
1276
+ {
1277
+ c = *++s;
1278
+ if (!IS_EUC_RANGE_VALID(c))
1279
+ return -1;
1280
+ }
1281
+ return mbl;
1282
+ }
1283
+
1284
+ static int
1285
+ pg_mule_verifier(const unsigned char *s, int len)
1286
+ {
1287
+ int l,
1288
+ mbl;
1289
+ unsigned char c;
1290
+
1291
+ l = mbl = pg_mule_mblen(s);
1292
+
1293
+ if (len < l)
1294
+ return -1;
1295
+
1296
+ while (--l > 0)
1297
+ {
1298
+ c = *++s;
1299
+ if (!IS_HIGHBIT_SET(c))
1300
+ return -1;
1301
+ }
1302
+ return mbl;
1303
+ }
1304
+
1305
+ static int
1306
+ pg_latin1_verifier(const unsigned char *s, int len)
1307
+ {
1308
+ return 1;
1309
+ }
1310
+
1311
+ static int
1312
+ pg_sjis_verifier(const unsigned char *s, int len)
1313
+ {
1314
+ int l,
1315
+ mbl;
1316
+ unsigned char c1,
1317
+ c2;
1318
+
1319
+ l = mbl = pg_sjis_mblen(s);
1320
+
1321
+ if (len < l)
1322
+ return -1;
1323
+
1324
+ if (l == 1) /* pg_sjis_mblen already verified it */
1325
+ return mbl;
1326
+
1327
+ c1 = *s++;
1328
+ c2 = *s;
1329
+ if (!ISSJISHEAD(c1) || !ISSJISTAIL(c2))
1330
+ return -1;
1331
+ return mbl;
1332
+ }
1333
+
1334
+ static int
1335
+ pg_big5_verifier(const unsigned char *s, int len)
1336
+ {
1337
+ int l,
1338
+ mbl;
1339
+
1340
+ l = mbl = pg_big5_mblen(s);
1341
+
1342
+ if (len < l)
1343
+ return -1;
1344
+
1345
+ while (--l > 0)
1346
+ {
1347
+ if (*++s == '\0')
1348
+ return -1;
1349
+ }
1350
+
1351
+ return mbl;
1352
+ }
1353
+
1354
+ static int
1355
+ pg_gbk_verifier(const unsigned char *s, int len)
1356
+ {
1357
+ int l,
1358
+ mbl;
1359
+
1360
+ l = mbl = pg_gbk_mblen(s);
1361
+
1362
+ if (len < l)
1363
+ return -1;
1364
+
1365
+ while (--l > 0)
1366
+ {
1367
+ if (*++s == '\0')
1368
+ return -1;
1369
+ }
1370
+
1371
+ return mbl;
1372
+ }
1373
+
1374
+ static int
1375
+ pg_uhc_verifier(const unsigned char *s, int len)
1376
+ {
1377
+ int l,
1378
+ mbl;
1379
+
1380
+ l = mbl = pg_uhc_mblen(s);
1381
+
1382
+ if (len < l)
1383
+ return -1;
1384
+
1385
+ while (--l > 0)
1386
+ {
1387
+ if (*++s == '\0')
1388
+ return -1;
1389
+ }
1390
+
1391
+ return mbl;
1392
+ }
1393
+
1394
+ static int
1395
+ pg_gb18030_verifier(const unsigned char *s, int len)
1396
+ {
1397
+ int l,
1398
+ mbl;
1399
+
1400
+ l = mbl = pg_gb18030_mblen(s);
1401
+
1402
+ if (len < l)
1403
+ return -1;
1404
+
1405
+ while (--l > 0)
1406
+ {
1407
+ if (*++s == '\0')
1408
+ return -1;
1409
+ }
1410
+
1411
+ return mbl;
1412
+ }
1413
+
1414
+ static int
1415
+ pg_utf8_verifier(const unsigned char *s, int len)
1416
+ {
1417
+ int l = pg_utf_mblen(s);
1418
+
1419
+ if (len < l)
1420
+ return -1;
1421
+
1422
+ if (!pg_utf8_islegal(s, l))
1423
+ return -1;
1424
+
1425
+ return l;
1426
+ }
1427
+
1428
+ /*
1429
+ * Check for validity of a single UTF-8 encoded character
1430
+ *
1431
+ * This directly implements the rules in RFC3629. The bizarre-looking
1432
+ * restrictions on the second byte are meant to ensure that there isn't
1433
+ * more than one encoding of a given Unicode character point; that is,
1434
+ * you may not use a longer-than-necessary byte sequence with high order
1435
+ * zero bits to represent a character that would fit in fewer bytes.
1436
+ * To do otherwise is to create security hazards (eg, create an apparent
1437
+ * non-ASCII character that decodes to plain ASCII).
1438
+ *
1439
+ * length is assumed to have been obtained by pg_utf_mblen(), and the
1440
+ * caller must have checked that that many bytes are present in the buffer.
1441
+ */
1442
+ bool
1443
+ pg_utf8_islegal(const unsigned char *source, int length)
1444
+ {
1445
+ unsigned char a;
1446
+
1447
+ switch (length)
1448
+ {
1449
+ default:
1450
+ /* reject lengths 5 and 6 for now */
1451
+ return false;
1452
+ case 4:
1453
+ a = source[3];
1454
+ if (a < 0x80 || a > 0xBF)
1455
+ return false;
1456
+ /* FALL THRU */
1457
+ case 3:
1458
+ a = source[2];
1459
+ if (a < 0x80 || a > 0xBF)
1460
+ return false;
1461
+ /* FALL THRU */
1462
+ case 2:
1463
+ a = source[1];
1464
+ switch (*source)
1465
+ {
1466
+ case 0xE0:
1467
+ if (a < 0xA0 || a > 0xBF)
1468
+ return false;
1469
+ break;
1470
+ case 0xED:
1471
+ if (a < 0x80 || a > 0x9F)
1472
+ return false;
1473
+ break;
1474
+ case 0xF0:
1475
+ if (a < 0x90 || a > 0xBF)
1476
+ return false;
1477
+ break;
1478
+ case 0xF4:
1479
+ if (a < 0x80 || a > 0x8F)
1480
+ return false;
1481
+ break;
1482
+ default:
1483
+ if (a < 0x80 || a > 0xBF)
1484
+ return false;
1485
+ break;
1486
+ }
1487
+ /* FALL THRU */
1488
+ case 1:
1489
+ a = *source;
1490
+ if (a >= 0x80 && a < 0xC2)
1491
+ return false;
1492
+ if (a > 0xF4)
1493
+ return false;
1494
+ break;
1495
+ }
1496
+ return true;
1497
+ }
1498
+
1499
+ #ifndef FRONTEND
1500
+
1501
+ /*
1502
+ * Generic character incrementer function.
1503
+ *
1504
+ * Not knowing anything about the properties of the encoding in use, we just
1505
+ * keep incrementing the last byte until we get a validly-encoded result,
1506
+ * or we run out of values to try. We don't bother to try incrementing
1507
+ * higher-order bytes, so there's no growth in runtime for wider characters.
1508
+ * (If we did try to do that, we'd need to consider the likelihood that 255
1509
+ * is not a valid final byte in the encoding.)
1510
+ */
1511
+ static bool
1512
+ pg_generic_charinc(unsigned char *charptr, int len)
1513
+ {
1514
+ unsigned char *lastbyte = charptr + len - 1;
1515
+ mbverifier mbverify;
1516
+
1517
+ /* We can just invoke the character verifier directly. */
1518
+ mbverify = pg_wchar_table[GetDatabaseEncoding()].mbverify;
1519
+
1520
+ while (*lastbyte < (unsigned char) 255)
1521
+ {
1522
+ (*lastbyte)++;
1523
+ if ((*mbverify) (charptr, len) == len)
1524
+ return true;
1525
+ }
1526
+
1527
+ return false;
1528
+ }
1529
+
1530
+ /*
1531
+ * UTF-8 character incrementer function.
1532
+ *
1533
+ * For a one-byte character less than 0x7F, we just increment the byte.
1534
+ *
1535
+ * For a multibyte character, every byte but the first must fall between 0x80
1536
+ * and 0xBF; and the first byte must be between 0xC0 and 0xF4. We increment
1537
+ * the last byte that's not already at its maximum value. If we can't find a
1538
+ * byte that's less than the maximum allowable value, we simply fail. We also
1539
+ * need some special-case logic to skip regions used for surrogate pair
1540
+ * handling, as those should not occur in valid UTF-8.
1541
+ *
1542
+ * Note that we don't reset lower-order bytes back to their minimums, since
1543
+ * we can't afford to make an exhaustive search (see make_greater_string).
1544
+ */
1545
+ static bool
1546
+ pg_utf8_increment(unsigned char *charptr, int length)
1547
+ {
1548
+ unsigned char a;
1549
+ unsigned char limit;
1550
+
1551
+ switch (length)
1552
+ {
1553
+ default:
1554
+ /* reject lengths 5 and 6 for now */
1555
+ return false;
1556
+ case 4:
1557
+ a = charptr[3];
1558
+ if (a < 0xBF)
1559
+ {
1560
+ charptr[3]++;
1561
+ break;
1562
+ }
1563
+ /* FALL THRU */
1564
+ case 3:
1565
+ a = charptr[2];
1566
+ if (a < 0xBF)
1567
+ {
1568
+ charptr[2]++;
1569
+ break;
1570
+ }
1571
+ /* FALL THRU */
1572
+ case 2:
1573
+ a = charptr[1];
1574
+ switch (*charptr)
1575
+ {
1576
+ case 0xED:
1577
+ limit = 0x9F;
1578
+ break;
1579
+ case 0xF4:
1580
+ limit = 0x8F;
1581
+ break;
1582
+ default:
1583
+ limit = 0xBF;
1584
+ break;
1585
+ }
1586
+ if (a < limit)
1587
+ {
1588
+ charptr[1]++;
1589
+ break;
1590
+ }
1591
+ /* FALL THRU */
1592
+ case 1:
1593
+ a = *charptr;
1594
+ if (a == 0x7F || a == 0xDF || a == 0xEF || a == 0xF4)
1595
+ return false;
1596
+ charptr[0]++;
1597
+ break;
1598
+ }
1599
+
1600
+ return true;
1601
+ }
1602
+
1603
+ /*
1604
+ * EUC-JP character incrementer function.
1605
+ *
1606
+ * If the sequence starts with SS2 (0x8e), it must be a two-byte sequence
1607
+ * representing JIS X 0201 characters with the second byte ranging between
1608
+ * 0xa1 and 0xdf. We just increment the last byte if it's less than 0xdf,
1609
+ * and otherwise rewrite the whole sequence to 0xa1 0xa1.
1610
+ *
1611
+ * If the sequence starts with SS3 (0x8f), it must be a three-byte sequence
1612
+ * in which the last two bytes range between 0xa1 and 0xfe. The last byte
1613
+ * is incremented if possible, otherwise the second-to-last byte.
1614
+ *
1615
+ * If the sequence starts with a value other than the above and its MSB
1616
+ * is set, it must be a two-byte sequence representing JIS X 0208 characters
1617
+ * with both bytes ranging between 0xa1 and 0xfe. The last byte is
1618
+ * incremented if possible, otherwise the second-to-last byte.
1619
+ *
1620
+ * Otherwise, the sequence is a single-byte ASCII character. It is
1621
+ * incremented up to 0x7f.
1622
+ */
1623
+ static bool
1624
+ pg_eucjp_increment(unsigned char *charptr, int length)
1625
+ {
1626
+ unsigned char c1,
1627
+ c2;
1628
+ int i;
1629
+
1630
+ c1 = *charptr;
1631
+
1632
+ switch (c1)
1633
+ {
1634
+ case SS2: /* JIS X 0201 */
1635
+ if (length != 2)
1636
+ return false;
1637
+
1638
+ c2 = charptr[1];
1639
+
1640
+ if (c2 >= 0xdf)
1641
+ charptr[0] = charptr[1] = 0xa1;
1642
+ else if (c2 < 0xa1)
1643
+ charptr[1] = 0xa1;
1644
+ else
1645
+ charptr[1]++;
1646
+ break;
1647
+
1648
+ case SS3: /* JIS X 0212 */
1649
+ if (length != 3)
1650
+ return false;
1651
+
1652
+ for (i = 2; i > 0; i--)
1653
+ {
1654
+ c2 = charptr[i];
1655
+ if (c2 < 0xa1)
1656
+ {
1657
+ charptr[i] = 0xa1;
1658
+ return true;
1659
+ }
1660
+ else if (c2 < 0xfe)
1661
+ {
1662
+ charptr[i]++;
1663
+ return true;
1664
+ }
1665
+ }
1666
+
1667
+ /* Out of 3-byte code region */
1668
+ return false;
1669
+
1670
+ default:
1671
+ if (IS_HIGHBIT_SET(c1)) /* JIS X 0208? */
1672
+ {
1673
+ if (length != 2)
1674
+ return false;
1675
+
1676
+ for (i = 1; i >= 0; i--)
1677
+ {
1678
+ c2 = charptr[i];
1679
+ if (c2 < 0xa1)
1680
+ {
1681
+ charptr[i] = 0xa1;
1682
+ return true;
1683
+ }
1684
+ else if (c2 < 0xfe)
1685
+ {
1686
+ charptr[i]++;
1687
+ return true;
1688
+ }
1689
+ }
1690
+
1691
+ /* Out of 2 byte code region */
1692
+ return false;
1693
+ }
1694
+ else
1695
+ { /* ASCII, single byte */
1696
+ if (c1 > 0x7e)
1697
+ return false;
1698
+ (*charptr)++;
1699
+ }
1700
+ break;
1701
+ }
1702
+
1703
+ return true;
1704
+ }
1705
+ #endif /* !FRONTEND */
1706
+
1707
+
1708
+ /*
1709
+ *-------------------------------------------------------------------
1710
+ * encoding info table
1711
+ * XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h)
1712
+ *-------------------------------------------------------------------
1713
+ */
1714
+ pg_wchar_tbl pg_wchar_table[] = {
1715
+ {pg_ascii2wchar_with_len, pg_wchar2single_with_len, pg_ascii_mblen, pg_ascii_dsplen, pg_ascii_verifier, 1}, /* PG_SQL_ASCII */
1716
+ {pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifier, 3}, /* PG_EUC_JP */
1717
+ {pg_euccn2wchar_with_len, pg_wchar2euc_with_len, pg_euccn_mblen, pg_euccn_dsplen, pg_euccn_verifier, 2}, /* PG_EUC_CN */
1718
+ {pg_euckr2wchar_with_len, pg_wchar2euc_with_len, pg_euckr_mblen, pg_euckr_dsplen, pg_euckr_verifier, 3}, /* PG_EUC_KR */
1719
+ {pg_euctw2wchar_with_len, pg_wchar2euc_with_len, pg_euctw_mblen, pg_euctw_dsplen, pg_euctw_verifier, 4}, /* PG_EUC_TW */
1720
+ {pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifier, 3}, /* PG_EUC_JIS_2004 */
1721
+ {pg_utf2wchar_with_len, pg_wchar2utf_with_len, pg_utf_mblen, pg_utf_dsplen, pg_utf8_verifier, 4}, /* PG_UTF8 */
1722
+ {pg_mule2wchar_with_len, pg_wchar2mule_with_len, pg_mule_mblen, pg_mule_dsplen, pg_mule_verifier, 4}, /* PG_MULE_INTERNAL */
1723
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN1 */
1724
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN2 */
1725
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN3 */
1726
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN4 */
1727
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN5 */
1728
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN6 */
1729
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN7 */
1730
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN8 */
1731
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN9 */
1732
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_LATIN10 */
1733
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1256 */
1734
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1258 */
1735
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN866 */
1736
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN874 */
1737
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_KOI8R */
1738
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1251 */
1739
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1252 */
1740
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* ISO-8859-5 */
1741
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* ISO-8859-6 */
1742
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* ISO-8859-7 */
1743
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* ISO-8859-8 */
1744
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1250 */
1745
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1253 */
1746
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1254 */
1747
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1255 */
1748
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_WIN1257 */
1749
+ {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifier, 1}, /* PG_KOI8U */
1750
+ {0, 0, pg_sjis_mblen, pg_sjis_dsplen, pg_sjis_verifier, 2}, /* PG_SJIS */
1751
+ {0, 0, pg_big5_mblen, pg_big5_dsplen, pg_big5_verifier, 2}, /* PG_BIG5 */
1752
+ {0, 0, pg_gbk_mblen, pg_gbk_dsplen, pg_gbk_verifier, 2}, /* PG_GBK */
1753
+ {0, 0, pg_uhc_mblen, pg_uhc_dsplen, pg_uhc_verifier, 2}, /* PG_UHC */
1754
+ {0, 0, pg_gb18030_mblen, pg_gb18030_dsplen, pg_gb18030_verifier, 4}, /* PG_GB18030 */
1755
+ {0, 0, pg_johab_mblen, pg_johab_dsplen, pg_johab_verifier, 3}, /* PG_JOHAB */
1756
+ {0, 0, pg_sjis_mblen, pg_sjis_dsplen, pg_sjis_verifier, 2} /* PG_SHIFT_JIS_2004 */
1757
+ };
1758
+
1759
+ /* returns the byte length of a word for mule internal code */
1760
+ int
1761
+ pg_mic_mblen(const unsigned char *mbstr)
1762
+ {
1763
+ return pg_mule_mblen(mbstr);
1764
+ }
1765
+
1766
+ /*
1767
+ * Returns the byte length of a multibyte character.
1768
+ */
1769
+ int
1770
+ pg_encoding_mblen(int encoding, const char *mbstr)
1771
+ {
1772
+ Assert(PG_VALID_ENCODING(encoding));
1773
+
1774
+ return ((encoding >= 0 &&
1775
+ encoding < sizeof(pg_wchar_table) / sizeof(pg_wchar_tbl)) ?
1776
+ ((*pg_wchar_table[encoding].mblen) ((const unsigned char *) mbstr)) :
1777
+ ((*pg_wchar_table[PG_SQL_ASCII].mblen) ((const unsigned char *) mbstr)));
1778
+ }
1779
+
1780
+ /*
1781
+ * Returns the display length of a multibyte character.
1782
+ */
1783
+ int
1784
+ pg_encoding_dsplen(int encoding, const char *mbstr)
1785
+ {
1786
+ Assert(PG_VALID_ENCODING(encoding));
1787
+
1788
+ return ((encoding >= 0 &&
1789
+ encoding < sizeof(pg_wchar_table) / sizeof(pg_wchar_tbl)) ?
1790
+ ((*pg_wchar_table[encoding].dsplen) ((const unsigned char *) mbstr)) :
1791
+ ((*pg_wchar_table[PG_SQL_ASCII].dsplen) ((const unsigned char *) mbstr)));
1792
+ }
1793
+
1794
+ /*
1795
+ * Verify the first multibyte character of the given string.
1796
+ * Return its byte length if good, -1 if bad. (See comments above for
1797
+ * full details of the mbverify API.)
1798
+ */
1799
+ int
1800
+ pg_encoding_verifymb(int encoding, const char *mbstr, int len)
1801
+ {
1802
+ Assert(PG_VALID_ENCODING(encoding));
1803
+
1804
+ return ((encoding >= 0 &&
1805
+ encoding < sizeof(pg_wchar_table) / sizeof(pg_wchar_tbl)) ?
1806
+ ((*pg_wchar_table[encoding].mbverify) ((const unsigned char *) mbstr, len)) :
1807
+ ((*pg_wchar_table[PG_SQL_ASCII].mbverify) ((const unsigned char *) mbstr, len)));
1808
+ }
1809
+
1810
+ /*
1811
+ * fetch maximum length of a given encoding
1812
+ */
1813
+ int
1814
+ pg_encoding_max_length(int encoding)
1815
+ {
1816
+ Assert(PG_VALID_ENCODING(encoding));
1817
+
1818
+ return pg_wchar_table[encoding].maxmblen;
1819
+ }
1820
+
1821
+ #ifndef FRONTEND
1822
+
1823
+ /*
1824
+ * fetch maximum length of the encoding for the current database
1825
+ */
1826
+ int
1827
+ pg_database_encoding_max_length(void)
1828
+ {
1829
+ return pg_wchar_table[GetDatabaseEncoding()].maxmblen;
1830
+ }
1831
+
1832
+ /*
1833
+ * get the character incrementer for the encoding for the current database
1834
+ */
1835
+ mbcharacter_incrementer
1836
+ pg_database_encoding_character_incrementer(void)
1837
+ {
1838
+ /*
1839
+ * Eventually it might be best to add a field to pg_wchar_table[], but for
1840
+ * now we just use a switch.
1841
+ */
1842
+ switch (GetDatabaseEncoding())
1843
+ {
1844
+ case PG_UTF8:
1845
+ return pg_utf8_increment;
1846
+
1847
+ case PG_EUC_JP:
1848
+ return pg_eucjp_increment;
1849
+
1850
+ default:
1851
+ return pg_generic_charinc;
1852
+ }
1853
+ }
1854
+
1855
+ /*
1856
+ * Verify mbstr to make sure that it is validly encoded in the current
1857
+ * database encoding. Otherwise same as pg_verify_mbstr().
1858
+ */
1859
+ bool
1860
+ pg_verifymbstr(const char *mbstr, int len, bool noError)
1861
+ {
1862
+ return
1863
+ pg_verify_mbstr_len(GetDatabaseEncoding(), mbstr, len, noError) >= 0;
1864
+ }
1865
+
1866
+ /*
1867
+ * Verify mbstr to make sure that it is validly encoded in the specified
1868
+ * encoding.
1869
+ */
1870
+ bool
1871
+ pg_verify_mbstr(int encoding, const char *mbstr, int len, bool noError)
1872
+ {
1873
+ return pg_verify_mbstr_len(encoding, mbstr, len, noError) >= 0;
1874
+ }
1875
+
1876
+ /*
1877
+ * Verify mbstr to make sure that it is validly encoded in the specified
1878
+ * encoding.
1879
+ *
1880
+ * mbstr is not necessarily zero terminated; length of mbstr is
1881
+ * specified by len.
1882
+ *
1883
+ * If OK, return length of string in the encoding.
1884
+ * If a problem is found, return -1 when noError is
1885
+ * true; when noError is false, ereport() a descriptive message.
1886
+ */
1887
+ int
1888
+ pg_verify_mbstr_len(int encoding, const char *mbstr, int len, bool noError)
1889
+ {
1890
+ mbverifier mbverify;
1891
+ int mb_len;
1892
+
1893
+ Assert(PG_VALID_ENCODING(encoding));
1894
+
1895
+ /*
1896
+ * In single-byte encodings, we need only reject nulls (\0).
1897
+ */
1898
+ if (pg_encoding_max_length(encoding) <= 1)
1899
+ {
1900
+ const char *nullpos = memchr(mbstr, 0, len);
1901
+
1902
+ if (nullpos == NULL)
1903
+ return len;
1904
+ if (noError)
1905
+ return -1;
1906
+ report_invalid_encoding(encoding, nullpos, 1);
1907
+ }
1908
+
1909
+ /* fetch function pointer just once */
1910
+ mbverify = pg_wchar_table[encoding].mbverify;
1911
+
1912
+ mb_len = 0;
1913
+
1914
+ while (len > 0)
1915
+ {
1916
+ int l;
1917
+
1918
+ /* fast path for ASCII-subset characters */
1919
+ if (!IS_HIGHBIT_SET(*mbstr))
1920
+ {
1921
+ if (*mbstr != '\0')
1922
+ {
1923
+ mb_len++;
1924
+ mbstr++;
1925
+ len--;
1926
+ continue;
1927
+ }
1928
+ if (noError)
1929
+ return -1;
1930
+ report_invalid_encoding(encoding, mbstr, len);
1931
+ }
1932
+
1933
+ l = (*mbverify) ((const unsigned char *) mbstr, len);
1934
+
1935
+ if (l < 0)
1936
+ {
1937
+ if (noError)
1938
+ return -1;
1939
+ report_invalid_encoding(encoding, mbstr, len);
1940
+ }
1941
+
1942
+ mbstr += l;
1943
+ len -= l;
1944
+ mb_len++;
1945
+ }
1946
+ return mb_len;
1947
+ }
1948
+
1949
+ /*
1950
+ * check_encoding_conversion_args: check arguments of a conversion function
1951
+ *
1952
+ * "expected" arguments can be either an encoding ID or -1 to indicate that
1953
+ * the caller will check whether it accepts the ID.
1954
+ *
1955
+ * Note: the errors here are not really user-facing, so elog instead of
1956
+ * ereport seems sufficient. Also, we trust that the "expected" encoding
1957
+ * arguments are valid encoding IDs, but we don't trust the actuals.
1958
+ */
1959
+ void
1960
+ check_encoding_conversion_args(int src_encoding,
1961
+ int dest_encoding,
1962
+ int len,
1963
+ int expected_src_encoding,
1964
+ int expected_dest_encoding)
1965
+ {
1966
+ if (!PG_VALID_ENCODING(src_encoding))
1967
+ elog(ERROR, "invalid source encoding ID: %d", src_encoding);
1968
+ if (src_encoding != expected_src_encoding && expected_src_encoding >= 0)
1969
+ elog(ERROR, "expected source encoding \"%s\", but got \"%s\"",
1970
+ pg_enc2name_tbl[expected_src_encoding].name,
1971
+ pg_enc2name_tbl[src_encoding].name);
1972
+ if (!PG_VALID_ENCODING(dest_encoding))
1973
+ elog(ERROR, "invalid destination encoding ID: %d", dest_encoding);
1974
+ if (dest_encoding != expected_dest_encoding && expected_dest_encoding >= 0)
1975
+ elog(ERROR, "expected destination encoding \"%s\", but got \"%s\"",
1976
+ pg_enc2name_tbl[expected_dest_encoding].name,
1977
+ pg_enc2name_tbl[dest_encoding].name);
1978
+ if (len < 0)
1979
+ elog(ERROR, "encoding conversion length must not be negative");
1980
+ }
1981
+
1982
+ /*
1983
+ * report_invalid_encoding: complain about invalid multibyte character
1984
+ *
1985
+ * note: len is remaining length of string, not length of character;
1986
+ * len must be greater than zero, as we always examine the first byte.
1987
+ */
1988
+ void
1989
+ report_invalid_encoding(int encoding, const char *mbstr, int len)
1990
+ {
1991
+ int l = pg_encoding_mblen(encoding, mbstr);
1992
+ char buf[8 * 5 + 1];
1993
+ char *p = buf;
1994
+ int j,
1995
+ jlimit;
1996
+
1997
+ jlimit = Min(l, len);
1998
+ jlimit = Min(jlimit, 8); /* prevent buffer overrun */
1999
+
2000
+ for (j = 0; j < jlimit; j++)
2001
+ {
2002
+ p += sprintf(p, "0x%02x", (unsigned char) mbstr[j]);
2003
+ if (j < jlimit - 1)
2004
+ p += sprintf(p, " ");
2005
+ }
2006
+
2007
+ ereport(ERROR,
2008
+ (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
2009
+ errmsg("invalid byte sequence for encoding \"%s\": %s",
2010
+ pg_enc2name_tbl[encoding].name,
2011
+ buf)));
2012
+ }
2013
+
2014
+ /*
2015
+ * report_untranslatable_char: complain about untranslatable character
2016
+ *
2017
+ * note: len is remaining length of string, not length of character;
2018
+ * len must be greater than zero, as we always examine the first byte.
2019
+ */
2020
+ void
2021
+ report_untranslatable_char(int src_encoding, int dest_encoding,
2022
+ const char *mbstr, int len)
2023
+ {
2024
+ int l = pg_encoding_mblen(src_encoding, mbstr);
2025
+ char buf[8 * 5 + 1];
2026
+ char *p = buf;
2027
+ int j,
2028
+ jlimit;
2029
+
2030
+ jlimit = Min(l, len);
2031
+ jlimit = Min(jlimit, 8); /* prevent buffer overrun */
2032
+
2033
+ for (j = 0; j < jlimit; j++)
2034
+ {
2035
+ p += sprintf(p, "0x%02x", (unsigned char) mbstr[j]);
2036
+ if (j < jlimit - 1)
2037
+ p += sprintf(p, " ");
2038
+ }
2039
+
2040
+ ereport(ERROR,
2041
+ (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
2042
+ errmsg("character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"",
2043
+ buf,
2044
+ pg_enc2name_tbl[src_encoding].name,
2045
+ pg_enc2name_tbl[dest_encoding].name)));
2046
+ }
2047
+
2048
+ #endif /* !FRONTEND */