prestogres 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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 */