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,1215 @@
1
+ /* -*-pgsql-c-*- */
2
+ /*
3
+ * $Header$
4
+ *
5
+ * pgpool: a language independent connection pool server for PostgreSQL
6
+ * written by Tatsuo Ishii
7
+ *
8
+ * Copyright (c) 2003-2013 PgPool Global Development Group
9
+ *
10
+ * Permission to use, copy, modify, and distribute this software and
11
+ * its documentation for any purpose and without fee is hereby
12
+ * granted, provided that the above copyright notice appear in all
13
+ * copies and that both that copyright notice and this permission
14
+ * notice appear in supporting documentation, and that the name of the
15
+ * author not be used in advertising or publicity pertaining to
16
+ * distribution of the software without specific, written prior
17
+ * permission. The author makes no representations about the
18
+ * suitability of this software for any purpose. It is provided "as
19
+ * is" without express or implied warranty.
20
+ *
21
+ */
22
+ #include <arpa/inet.h>
23
+ #include <stdlib.h>
24
+ #include <string.h>
25
+
26
+ #include "pool.h"
27
+ #include "pool_timestamp.h"
28
+ #include "pool_relcache.h"
29
+ #include "pool_select_walker.h"
30
+ #include "pool_config.h"
31
+ #include "parser/parsenodes.h"
32
+ #include "parser/parser.h"
33
+ #include "parser/pool_memory.h"
34
+
35
+
36
+ typedef struct {
37
+ char *attrname; /* attribute name */
38
+ char *adsrc; /* default value expression */
39
+ int use_timestamp;
40
+ } TSAttr;
41
+
42
+ typedef struct {
43
+ int relnatts;
44
+ TSAttr attr[1];
45
+ } TSRel;
46
+
47
+ typedef struct {
48
+ A_Const *ts_const;
49
+ POOL_CONNECTION_POOL *backend;
50
+ char *relname;
51
+ int num_params; /* num of original params (for Parse) */
52
+ bool rewrite_to_params;
53
+ bool rewrite; /* has rewritten? */
54
+ List *params; /* list of additional params */
55
+ } TSRewriteContext;
56
+
57
+ static void *ts_register_func(POOL_SELECT_RESULT *res);
58
+ static void *ts_unregister_func(void *data);
59
+ static TSRel *relcache_lookup(TSRewriteContext *ctx);
60
+ static bool isStringConst(Node *node, const char *str);
61
+ static bool rewrite_timestamp_walker(Node *node, void *context);
62
+ static bool rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx);
63
+ static bool rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx);
64
+ static char *get_current_timestamp(POOL_CONNECTION_POOL *backend);
65
+ static Node *makeTsExpr(TSRewriteContext *ctx);
66
+ static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression);
67
+ bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context);
68
+
69
+ POOL_RELCACHE *ts_relcache;
70
+
71
+
72
+ static void *
73
+ ts_register_func(POOL_SELECT_RESULT *res)
74
+ {
75
+ /* Number of result columns included in res */
76
+ #define NUM_COLS 3
77
+
78
+ TSRel *rel;
79
+ int i;
80
+
81
+ if (res->numrows == 0)
82
+ return NULL;
83
+
84
+ rel = (TSRel *) malloc(sizeof(TSRel) + sizeof(TSAttr) * (res->numrows - 1));
85
+
86
+ for (i = 0; i < res->numrows; i++)
87
+ {
88
+ int index = 0;
89
+
90
+ rel->attr[i].attrname = strdup(res->data[i * NUM_COLS + index]);
91
+ index++;
92
+
93
+ if (res->data[i * NUM_COLS + index])
94
+ rel->attr[i].adsrc = strdup(res->data[i * NUM_COLS + index]);
95
+ else
96
+ rel->attr[i].adsrc = NULL;
97
+
98
+ index++;
99
+
100
+ rel->attr[i].use_timestamp = *(res->data[i * NUM_COLS + index]) == 't';
101
+ pool_debug("attrname %s adsrc %s use_timestamp = %d",
102
+ rel->attr[i].attrname, (rel->attr[i].adsrc? rel->attr[i].adsrc:"NULL"),
103
+ rel->attr[i].use_timestamp);
104
+ }
105
+
106
+ rel->relnatts = res->numrows;
107
+ return (void *) rel;
108
+ }
109
+
110
+
111
+ static void *
112
+ ts_unregister_func(void *data)
113
+ {
114
+ TSRel *rel = (TSRel *) data;
115
+
116
+ if (rel == NULL)
117
+ return NULL;
118
+
119
+ free(rel);
120
+ return rel;
121
+ }
122
+
123
+
124
+ static TSRel*
125
+ relcache_lookup(TSRewriteContext *ctx)
126
+ {
127
+ #define ATTRDEFQUERY "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%')" \
128
+ " AND (a.atttypid = 'timestamp'::regtype::oid OR" \
129
+ " a.atttypid = 'timestamp with time zone'::regtype::oid OR" \
130
+ " a.atttypid = 'date'::regtype::oid OR" \
131
+ " a.atttypid = 'time'::regtype::oid OR" \
132
+ " a.atttypid = 'time with time zone'::regtype::oid)" \
133
+ " , false)" \
134
+ " FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \
135
+ " LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \
136
+ " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s'" \
137
+ " ORDER BY a.attnum"
138
+
139
+ #define ATTRDEFQUERY2 "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%')" \
140
+ " AND (a.atttypid = 'timestamp'::regtype::oid OR" \
141
+ " a.atttypid = 'timestamp with time zone'::regtype::oid OR" \
142
+ " a.atttypid = 'date'::regtype::oid OR" \
143
+ " a.atttypid = 'time'::regtype::oid OR" \
144
+ " a.atttypid = 'time with time zone'::regtype::oid)" \
145
+ " , false)" \
146
+ " FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \
147
+ " LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \
148
+ " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s')" \
149
+ " ORDER BY a.attnum"
150
+
151
+ char *query;
152
+
153
+ if (pool_has_pgpool_regclass())
154
+ {
155
+ query = ATTRDEFQUERY2;
156
+ }
157
+ else
158
+ {
159
+ query = ATTRDEFQUERY;
160
+ }
161
+
162
+ if (!ts_relcache)
163
+ {
164
+ ts_relcache = pool_create_relcache(pool_config->relcache_size, query, ts_register_func, ts_unregister_func, false);
165
+
166
+ if (ts_relcache == NULL)
167
+ {
168
+ pool_error("relcache_lookup: pool_create_relcache error");
169
+ return NULL;
170
+ }
171
+ }
172
+
173
+ return (TSRel *) pool_search_relcache(ts_relcache, ctx->backend, ctx->relname);
174
+ }
175
+
176
+
177
+ static Node *
178
+ makeTsExpr(TSRewriteContext *ctx)
179
+ {
180
+ ParamRef *param;
181
+
182
+ if (!ctx->rewrite_to_params)
183
+ return (Node *) ctx->ts_const;
184
+
185
+ param = makeNode(ParamRef);
186
+ param->number = 0;
187
+ ctx->params = lappend(ctx->params, param);
188
+ return (Node *) param;
189
+ }
190
+
191
+
192
+ static bool
193
+ isStringConst(Node *node, const char *str)
194
+ {
195
+ A_Const *a_const;
196
+ Value val;
197
+
198
+ if (!IsA(node, A_Const))
199
+ return false;
200
+
201
+ a_const = (A_Const *) node;
202
+ val = a_const->val;
203
+
204
+ if (val.type == T_String && val.val.str && strcmp(str, val.val.str) == 0)
205
+ return true;
206
+
207
+ return false;
208
+ }
209
+
210
+
211
+ bool
212
+ isSystemType(Node *node, const char *name)
213
+ {
214
+ TypeName *typename;
215
+
216
+ if (!IsA(node, TypeName))
217
+ return false;
218
+
219
+ typename = (TypeName *) node;
220
+ if (list_length(typename->names) == 2 &&
221
+ strcmp("pg_catalog", strVal(linitial(typename->names))) == 0 &&
222
+ strcmp(name, strVal(lsecond(typename->names))) == 0)
223
+ return true;
224
+
225
+ return false;
226
+ }
227
+
228
+
229
+ static bool
230
+ isSystemTypeCast(Node *node, const char *name)
231
+ {
232
+ TypeCast *typecast;
233
+
234
+ if (!IsA(node, TypeCast))
235
+ return false;
236
+
237
+ typecast = (TypeCast *) node;
238
+ return isSystemType((Node *) typecast->typeName, name);
239
+ }
240
+
241
+ /*
242
+ * walker function for raw_expression_tree_walker
243
+ */
244
+ static bool
245
+ rewrite_timestamp_walker(Node *node, void *context)
246
+ {
247
+ TSRewriteContext *ctx = (TSRewriteContext *) context;
248
+
249
+ if (node == NULL)
250
+ return false;
251
+
252
+ if (nodeTag(node) == T_FuncCall)
253
+ {
254
+ /* `now()' FuncCall */
255
+ FuncCall *fcall = (FuncCall *) node;
256
+
257
+ if ((list_length(fcall->funcname) == 1 &&
258
+ strcmp("now", strVal(linitial(fcall->funcname))) == 0) ||
259
+ (list_length(fcall->funcname) == 2 &&
260
+ strcmp("pg_catalog", strVal(linitial(fcall->funcname))) == 0 &&
261
+ strcmp("now", strVal(lsecond(fcall->funcname))) == 0))
262
+ {
263
+ TypeCast *tc = makeNode(TypeCast);
264
+ tc->arg = makeTsExpr(ctx);
265
+ tc->typeName = SystemTypeName("text");
266
+
267
+ fcall->funcname = SystemFuncName("timestamptz");
268
+ fcall->args = list_make1(tc);
269
+ ctx->rewrite = true;
270
+ }
271
+ }
272
+ else if (IsA(node, TypeCast))
273
+ {
274
+ /* CURRENT_DATE, CURRENT_TIME, LOCALTIMESTAMP, LOCALTIME etc.*/
275
+ TypeCast *tc = (TypeCast *) node;
276
+
277
+ if ((isSystemType((Node *) tc->typeName, "date") ||
278
+ isSystemType((Node *) tc->typeName, "timestamp") ||
279
+ isSystemType((Node *) tc->typeName, "timestamptz") ||
280
+ isSystemType((Node *) tc->typeName, "time") ||
281
+ isSystemType((Node *) tc->typeName, "timetz")))
282
+ {
283
+ /* rewrite `'now'::timestamp' and `'now'::text::timestamp' both */
284
+ if (isSystemTypeCast(tc->arg, "text"))
285
+ tc = (TypeCast *) tc->arg;
286
+
287
+ if (isStringConst(tc->arg, "now"))
288
+ {
289
+ tc->arg = (Node *) makeTsExpr(ctx);
290
+ ctx->rewrite = true;
291
+ }
292
+ }
293
+ }
294
+ else if (IsA(node, ParamRef))
295
+ {
296
+ ParamRef *param = (ParamRef *) node;
297
+
298
+ /* count how many params in original query */
299
+ if (ctx->num_params < param->number)
300
+ ctx->num_params = param->number;
301
+ }
302
+
303
+ return raw_expression_tree_walker(node, rewrite_timestamp_walker, context);
304
+ }
305
+
306
+
307
+ /*
308
+ * Get `now()' from MASTER node
309
+ */
310
+ static char *
311
+ get_current_timestamp(POOL_CONNECTION_POOL *backend)
312
+ {
313
+ POOL_SELECT_RESULT *res;
314
+ POOL_STATUS status;
315
+ static char timestamp[64];
316
+
317
+ status = do_query(MASTER(backend), "SELECT now()", &res, MAJOR(backend));
318
+ if (status != POOL_CONTINUE)
319
+ {
320
+ pool_error("get_current_timestamp: do_query failed");
321
+ free_select_result(res);
322
+ return NULL;
323
+ }
324
+
325
+ if (res->numrows != 1)
326
+ {
327
+ free_select_result(res);
328
+ return NULL;
329
+ }
330
+
331
+ strlcpy(timestamp, res->data[0], sizeof(timestamp));
332
+
333
+ free_select_result(res);
334
+ return timestamp;
335
+ }
336
+
337
+
338
+ /*
339
+ * rewrite InsertStmt
340
+ */
341
+ static bool
342
+ rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx)
343
+ {
344
+ int i;
345
+ bool rewrite = false;
346
+ TSRel *relcache;
347
+
348
+
349
+ if (i_stmt->selectStmt == NULL)
350
+ {
351
+ List *values = NIL;
352
+ SelectStmt *selectStmt = makeNode(SelectStmt);
353
+
354
+ relcache = relcache_lookup(ctx);
355
+ if (relcache == NULL)
356
+ return false;
357
+
358
+ /*
359
+ * INSERT INTO rel DEFAULT VALUES
360
+ * rewrite to:
361
+ * INSERT INTO rel VALUES (DEFAULT, '2009-..',...)
362
+ */
363
+
364
+ for (i = 0; i < relcache->relnatts; i++)
365
+ {
366
+ if (relcache->attr[i].use_timestamp)
367
+ {
368
+ rewrite = true;
369
+ if (ctx->rewrite_to_params)
370
+ values = lappend(values, makeTsExpr(ctx));
371
+ else
372
+ values = lappend(values,
373
+ makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc));
374
+ }
375
+ else
376
+ values = lappend(values, makeNode(SetToDefault));
377
+ }
378
+ if (rewrite)
379
+ {
380
+ selectStmt->valuesLists = list_make1(values);
381
+ i_stmt->selectStmt = (Node *) selectStmt;
382
+ }
383
+
384
+ return rewrite;
385
+ }
386
+ else if (IsA(i_stmt->selectStmt, SelectStmt))
387
+ {
388
+ SelectStmt *selectStmt = (SelectStmt *) i_stmt->selectStmt;
389
+ ListCell *lc_row, *lc_val, *lc_col;
390
+
391
+ /*
392
+ * Rewrite `now()' call to timestamp literal.
393
+ */
394
+ raw_expression_tree_walker(
395
+ (Node *) selectStmt,
396
+ rewrite_timestamp_walker, (void *) ctx);
397
+
398
+ rewrite = ctx->rewrite;
399
+
400
+ /*
401
+ * if `INSERT INTO rel SELECT ...'
402
+ */
403
+ if (selectStmt->valuesLists == NIL)
404
+ return rewrite;
405
+
406
+ relcache = relcache_lookup(ctx);
407
+ if (relcache == NULL)
408
+ return false;
409
+
410
+ if (i_stmt->cols == NIL)
411
+ {
412
+ /*
413
+ * INSERT INTO rel VALUES (...)
414
+ *
415
+ * CREATE TABLE r1 (
416
+ * i1 int,
417
+ * t1 timestamp default now(),
418
+ * i2 int,
419
+ * t2 timestamp default now(),
420
+ * )
421
+ *
422
+ * INSERT INTO r1 VALUES (1, DEFAULT);
423
+ * rewrite to:
424
+ * INSERT INTO r1 VALUES (1, '20xx-xx-xx...', DEFAULT, '2..')
425
+ */
426
+ foreach (lc_row, selectStmt->valuesLists)
427
+ {
428
+ List *values = lfirst(lc_row);
429
+
430
+ i = 0;
431
+ foreach (lc_val, values)
432
+ {
433
+ if (relcache->attr[i].use_timestamp == true && IsA(lfirst(lc_val), SetToDefault))
434
+ {
435
+ rewrite = true;
436
+ if (ctx->rewrite_to_params)
437
+ lfirst(lc_val) = makeTsExpr(ctx);
438
+ else
439
+ lfirst(lc_val) = makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc);
440
+ }
441
+ i++;
442
+ }
443
+
444
+ /* fill rest columns */
445
+ for (; i < relcache->relnatts; i++)
446
+ {
447
+ if (relcache->attr[i].use_timestamp == true)
448
+ {
449
+ rewrite = true;
450
+ if (ctx->rewrite_to_params)
451
+ values = lappend(values, makeTsExpr(ctx));
452
+ else
453
+ values = lappend(values,
454
+ makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc));
455
+ }
456
+ else
457
+ values = lappend(values, makeNode(SetToDefault));
458
+ }
459
+ }
460
+ }
461
+ else
462
+ {
463
+ /*
464
+ * INSERT INTO rel(col1, col2) VALUES (val, val2)
465
+ *
466
+ * if timestamp column is not given by column list
467
+ * add colname to column list and add timestamp to values list.
468
+ */
469
+ int append_columns = 0;
470
+ int *append_columns_list;
471
+ ResTarget *col;
472
+
473
+ append_columns_list = (int *)malloc(sizeof(int)*relcache->relnatts);
474
+
475
+ for (i = 0; i < relcache->relnatts; i++)
476
+ {
477
+ if (relcache->attr[i].use_timestamp == false)
478
+ continue;
479
+
480
+ foreach (lc_col, i_stmt->cols)
481
+ {
482
+ col = lfirst(lc_col);
483
+
484
+ if (strcmp(relcache->attr[i].attrname, col->name) == 0)
485
+ break;
486
+ }
487
+
488
+ if (lc_col == NULL)
489
+ {
490
+ /* column not found in query, append it.*/
491
+ rewrite = true;
492
+ col = makeNode(ResTarget);
493
+ col->name = relcache->attr[i].attrname;
494
+ col->indirection = NIL;
495
+ col->val = NULL;
496
+ i_stmt->cols = lappend(i_stmt->cols, col);
497
+ append_columns_list[append_columns++] = i;
498
+ }
499
+ }
500
+
501
+ foreach (lc_row, selectStmt->valuesLists)
502
+ {
503
+ List *values = lfirst(lc_row);
504
+
505
+ /* replace DEFAULT to literal */
506
+ forboth (lc_col, i_stmt->cols, lc_val, values)
507
+ {
508
+ col = lfirst(lc_col);
509
+ for (i = 0; i < relcache->relnatts; i++)
510
+ {
511
+ if (strcmp(relcache->attr[i].attrname, col->name) == 0)
512
+ break;
513
+ }
514
+
515
+ if (relcache->attr[i].use_timestamp == true && IsA(lfirst(lc_val), SetToDefault))
516
+ {
517
+ rewrite = true;
518
+ if (ctx->rewrite_to_params)
519
+ lfirst(lc_val) = makeTsExpr(ctx);
520
+ else
521
+ lfirst(lc_val) = makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc);
522
+ }
523
+ }
524
+
525
+ /* add ts_const to values list */
526
+ for (i = 0; i < append_columns; i++)
527
+ {
528
+ if (ctx->rewrite_to_params)
529
+ values = lappend(values, makeTsExpr(ctx));
530
+ else
531
+ values = lappend(values,
532
+ makeStringConstFromQuery(ctx->backend, relcache->attr[append_columns_list[i]].adsrc));
533
+ }
534
+ }
535
+ free(append_columns_list);
536
+ }
537
+ }
538
+
539
+ return rewrite;
540
+ }
541
+
542
+
543
+ /*
544
+ * rewrite UpdateStmt
545
+ */
546
+ static bool
547
+ rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx)
548
+ {
549
+ TSRel *relcache = NULL;
550
+ ListCell *lc;
551
+ bool rewrite;
552
+
553
+ /* rewrite "update ... set col1 = now()" */
554
+ raw_expression_tree_walker(
555
+ (Node *) u_stmt->targetList,
556
+ rewrite_timestamp_walker, (void *) ctx);
557
+
558
+ raw_expression_tree_walker(
559
+ (Node *) u_stmt->whereClause,
560
+ rewrite_timestamp_walker, (void *) ctx);
561
+
562
+ raw_expression_tree_walker(
563
+ (Node *) u_stmt->fromClause,
564
+ rewrite_timestamp_walker, (void *) ctx);
565
+
566
+ rewrite = ctx->rewrite;
567
+
568
+ /* rewrite "update ... set col1 = default" */
569
+ foreach (lc, u_stmt->targetList)
570
+ {
571
+ ResTarget *res = (ResTarget *) lfirst(lc);
572
+ int i;
573
+
574
+ if (IsA(res->val, SetToDefault))
575
+ {
576
+ relcache = relcache_lookup(ctx);
577
+ if (relcache == NULL)
578
+ return false;
579
+
580
+ for (i = 0; i < relcache->relnatts; i++)
581
+ {
582
+ if (strcmp(relcache->attr[i].attrname, res->name) == 0)
583
+ {
584
+ if (relcache->attr[i].use_timestamp)
585
+ {
586
+ if (ctx->rewrite_to_params)
587
+ res->val = (Node *) makeTsExpr(ctx);
588
+ else
589
+ res->val = (Node *)makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc);
590
+ rewrite = true;
591
+ }
592
+ break;
593
+ }
594
+ }
595
+ }
596
+ }
597
+ return rewrite;
598
+ }
599
+
600
+ /*
601
+ * Rewrite `now()' to timestamp literal.
602
+ * returns query string as palloced string, or NULL if not to need rewrite.
603
+ */
604
+ char *
605
+ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node,
606
+ bool rewrite_to_params, POOL_SENT_MESSAGE *message)
607
+ {
608
+ TSRewriteContext ctx;
609
+ Node *stmt;
610
+ bool rewrite = false;
611
+ char *timestamp;
612
+ char *rewrite_query;
613
+
614
+ if (node == NULL)
615
+ return NULL;
616
+
617
+ if (!REPLICATION)
618
+ return NULL;
619
+
620
+ /* init context */
621
+ ctx.ts_const = makeNode(A_Const);
622
+ ctx.ts_const->val.type = T_String;
623
+ ctx.rewrite_to_params = rewrite_to_params;
624
+ ctx.backend = backend;
625
+ ctx.num_params = 0;
626
+ ctx.rewrite = false;
627
+ ctx.params = NIL;
628
+
629
+ /*
630
+ * Prepare?
631
+ */
632
+ if (IsA(node, PrepareStmt))
633
+ {
634
+ stmt = ((PrepareStmt *) node)->query;
635
+ ctx.rewrite_to_params = true;
636
+ }
637
+ else
638
+ stmt = node;
639
+
640
+ if (IsA(stmt, InsertStmt))
641
+ {
642
+ InsertStmt *i_stmt = (InsertStmt *) stmt;
643
+ ctx.relname = nodeToString(i_stmt->relation);
644
+ rewrite = rewrite_timestamp_insert(i_stmt, &ctx);
645
+ }
646
+ else if (IsA(stmt, UpdateStmt))
647
+ {
648
+ UpdateStmt *u_stmt = (UpdateStmt *) stmt;
649
+ ctx.relname = nodeToString(u_stmt->relation);
650
+ rewrite = rewrite_timestamp_update(u_stmt, &ctx);
651
+ }
652
+ else if (IsA(stmt, DeleteStmt))
653
+ {
654
+ DeleteStmt *d_stmt = (DeleteStmt *) stmt;
655
+ raw_expression_tree_walker(
656
+ (Node *) d_stmt->usingClause,
657
+ rewrite_timestamp_walker, (void *) &ctx);
658
+
659
+ raw_expression_tree_walker(
660
+ (Node *) d_stmt->whereClause,
661
+ rewrite_timestamp_walker, (void *) &ctx);
662
+ rewrite = ctx.rewrite;
663
+ }
664
+ else if (IsA(stmt, ExecuteStmt))
665
+ {
666
+ ExecuteStmt *e_stmt = (ExecuteStmt *) stmt;
667
+
668
+ /* rewrite params */
669
+ raw_expression_tree_walker(
670
+ (Node *) e_stmt->params,
671
+ rewrite_timestamp_walker, (void *) &ctx);
672
+
673
+ rewrite = ctx.rewrite;
674
+
675
+ /* add params */
676
+ if (message)
677
+ {
678
+ int i;
679
+
680
+ for (i = 0; i < message->num_tsparams; i++)
681
+ {
682
+ e_stmt->params = lappend(e_stmt->params, ctx.ts_const);
683
+ rewrite = true;
684
+ }
685
+ }
686
+ }
687
+ else
688
+ ;
689
+
690
+ if (!rewrite)
691
+ return NULL;
692
+
693
+ if (ctx.rewrite_to_params && message)
694
+ {
695
+ ListCell *lc;
696
+ int num = ctx.num_params + 1;
697
+
698
+ /* renumber params */
699
+ foreach (lc, ctx.params)
700
+ {
701
+ ParamRef *param = (ParamRef *) lfirst(lc);
702
+ param->number = num++;
703
+ }
704
+
705
+ /* save to portal */
706
+ message->num_tsparams = list_length(ctx.params);
707
+
708
+ /* add param type */
709
+ if (IsA(node, PrepareStmt))
710
+ {
711
+ int i;
712
+ PrepareStmt *p_stmt = (PrepareStmt *) node;
713
+
714
+ for (i = 0; i < message->num_tsparams; i++)
715
+ p_stmt->argtypes =
716
+ lappend(p_stmt->argtypes, SystemTypeName("timestamptz"));
717
+ }
718
+ }
719
+ else
720
+ {
721
+ timestamp = get_current_timestamp(backend);
722
+ if (timestamp == NULL)
723
+ {
724
+ pool_error("rewrite_timestamp: could not get current timestamp");
725
+ return NULL;
726
+ }
727
+
728
+ ctx.ts_const->val.val.str = timestamp;
729
+ }
730
+ rewrite_query = nodeToString(node);
731
+
732
+ return rewrite_query;
733
+ }
734
+
735
+
736
+ /*
737
+ * rewrite Bind message to add parameter
738
+ */
739
+ char *
740
+ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend,
741
+ POOL_SENT_MESSAGE *message,
742
+ const char *orig_msg, int *len)
743
+ {
744
+ int16 tmp2,
745
+ num_params,
746
+ num_formats;
747
+ int32 tmp4;
748
+ int i,
749
+ ts_len,
750
+ copy_len;
751
+ const char *copy_from;
752
+ char *ts,
753
+ *copy_to,
754
+ *new_msg;
755
+
756
+ #ifdef TIMESTAMPDEBUG
757
+ fprintf(stderr, "message length:%d\n", *len);
758
+ for(i=0;i<*len;i++)
759
+ {
760
+ fprintf(stderr, "%02x ", orig_msg[i]);
761
+ }
762
+ #endif
763
+
764
+ ts = get_current_timestamp(backend);
765
+ if (ts == NULL)
766
+ {
767
+ pool_error("bind_rewrite_timestamp: could not get current timestamp");
768
+ return NULL;
769
+ }
770
+
771
+ ts_len = strlen(ts);
772
+
773
+ *len += (strlen(ts) + sizeof(int32)) * message->num_tsparams;
774
+ new_msg = copy_to = (char *) malloc(*len + message->num_tsparams * sizeof(int16));
775
+ copy_from = orig_msg;
776
+
777
+ /* portal_name */
778
+ copy_len = strlen(copy_from) + 1;
779
+ memcpy(copy_to, copy_from, copy_len);
780
+ copy_to += copy_len; copy_from += copy_len;
781
+
782
+ /* stmt_name */
783
+ copy_len = strlen(copy_from) + 1;
784
+ memcpy(copy_to, copy_from, copy_len);
785
+ copy_to += copy_len; copy_from += copy_len;
786
+
787
+ /* format code */
788
+ memcpy(&tmp2, copy_from, sizeof(int16));
789
+ copy_len = sizeof(int16);
790
+ tmp2 = num_formats = ntohs(tmp2);
791
+
792
+ if (num_formats > 1)
793
+ {
794
+ /* enlarge message length */
795
+ *len += message->num_tsparams * sizeof(int16);
796
+ tmp2 += message->num_tsparams;
797
+ }
798
+ tmp2 = htons(tmp2);
799
+ memcpy(copy_to, &tmp2, copy_len); /* copy number of format codes */
800
+ copy_to += copy_len; copy_from += copy_len;
801
+
802
+ copy_len = num_formats * sizeof(int16);
803
+
804
+ memcpy(copy_to, copy_from, copy_len); /* copy format codes */
805
+ copy_to += copy_len; copy_from += copy_len;
806
+
807
+ if (num_formats > 1)
808
+ {
809
+ /* set format codes to zero(text) */
810
+ memset(copy_to, 0, message->num_tsparams * 2);
811
+ copy_to += sizeof(int16) * message->num_tsparams;
812
+ }
813
+
814
+ /* num params */
815
+ memcpy(&tmp2, copy_from, sizeof(int16));
816
+ copy_len = sizeof(int16);
817
+ num_params = ntohs(tmp2);
818
+ tmp2 = htons(num_params + message->num_tsparams);
819
+ memcpy(copy_to, &tmp2, sizeof(int16));
820
+ copy_to += copy_len; copy_from += copy_len;
821
+
822
+ /* params */
823
+ copy_len = 0;
824
+ for (i = 0; i < num_params; i++)
825
+ {
826
+ memcpy(&tmp4, copy_from + copy_len, sizeof(int32));
827
+ tmp4 = ntohl(tmp4); /* param length */
828
+ copy_len += sizeof(int32);
829
+
830
+ /* If param length is -1, it indicates that the value is NULL
831
+ * and we don't have value slot. So we don't add up copy_len.
832
+ */
833
+ if (tmp4 > 0)
834
+ {
835
+ copy_len += tmp4;
836
+ }
837
+ }
838
+ memcpy(copy_to, copy_from, copy_len);
839
+ copy_to += copy_len; copy_from += copy_len;
840
+
841
+ tmp4 = htonl(ts_len);
842
+ for (i = 0; i < message->num_tsparams; i++)
843
+ {
844
+ memcpy(copy_to, &tmp4, sizeof(int32));
845
+ copy_to += sizeof(int32);
846
+ memcpy(copy_to, ts, ts_len);
847
+ copy_to += ts_len;
848
+ }
849
+
850
+ /* result format code */
851
+ memcpy(&tmp2, copy_from, sizeof(int16));
852
+ copy_len = sizeof(int16);
853
+ copy_len += sizeof(int16) * ntohs(tmp2);
854
+ memcpy(copy_to, copy_from, copy_len);
855
+
856
+ return new_msg;
857
+ }
858
+
859
+ static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression)
860
+ {
861
+ A_Const *con;
862
+ POOL_SELECT_RESULT *res;
863
+ POOL_STATUS status;
864
+ char query[1024];
865
+ int len;
866
+ char *str;
867
+
868
+ snprintf(query, sizeof(query), "SELECT %s", expression);
869
+ status = do_query(MASTER(backend), query, &res, MAJOR(backend));
870
+ if (status != POOL_CONTINUE)
871
+ {
872
+ pool_error("makeStringConstFromQuery: do_query failed");
873
+ free_select_result(res);
874
+ return NULL;
875
+ }
876
+
877
+ if (res->numrows != 1)
878
+ {
879
+ free_select_result(res);
880
+ return NULL;
881
+ }
882
+
883
+ len = strlen(res->data[0]) + 1;
884
+ str = palloc(len);
885
+ strcpy(str, res->data[0]);
886
+ free_select_result(res);
887
+
888
+ con = makeNode(A_Const);
889
+ con->val.type = T_String;
890
+ con->val.val.str = str;
891
+ return con;
892
+ }
893
+
894
+ /* from nodeFuncs.c start */
895
+
896
+ /*
897
+ * raw_expression_tree_walker --- walk raw parse trees
898
+ *
899
+ * This has exactly the same API as expression_tree_walker, but instead of
900
+ * walking post-analysis parse trees, it knows how to walk the node types
901
+ * found in raw grammar output. (There is not currently any need for a
902
+ * combined walker, so we keep them separate in the name of efficiency.)
903
+ * Unlike expression_tree_walker, there is no special rule about query
904
+ * boundaries: we descend to everything that's possibly interesting.
905
+ *
906
+ * Currently, the node type coverage extends to SelectStmt and everything
907
+ * that could appear under it, but not other statement types.
908
+ */
909
+ bool
910
+ raw_expression_tree_walker(Node *node, bool (*walker) (), void *context)
911
+ {
912
+ ListCell *temp;
913
+
914
+ /*
915
+ * The walker has already visited the current node, and so we need only
916
+ * recurse into any sub-nodes it has.
917
+ */
918
+ if (node == NULL)
919
+ return false;
920
+
921
+ /* Guard against stack overflow due to overly complex expressions */
922
+ /*
923
+ check_stack_depth();
924
+ */
925
+
926
+ switch (nodeTag(node))
927
+ {
928
+ case T_SetToDefault:
929
+ case T_CurrentOfExpr:
930
+ case T_Integer:
931
+ case T_Float:
932
+ case T_String:
933
+ case T_BitString:
934
+ case T_Null:
935
+ case T_ParamRef:
936
+ case T_A_Const:
937
+ case T_A_Star:
938
+ /* primitive node types with no subnodes */
939
+ break;
940
+ case T_Alias:
941
+ /* we assume the colnames list isn't interesting */
942
+ break;
943
+ case T_RangeVar:
944
+ return walker(((RangeVar *) node)->alias, context);
945
+ case T_SubLink:
946
+ {
947
+ SubLink *sublink = (SubLink *) node;
948
+
949
+ if (walker(sublink->testexpr, context))
950
+ return true;
951
+ /* we assume the operName is not interesting */
952
+ if (walker(sublink->subselect, context))
953
+ return true;
954
+ }
955
+ break;
956
+ case T_CaseExpr:
957
+ {
958
+ CaseExpr *caseexpr = (CaseExpr *) node;
959
+
960
+ if (walker(caseexpr->arg, context))
961
+ return true;
962
+ /* we assume walker doesn't care about CaseWhens, either */
963
+ foreach(temp, caseexpr->args)
964
+ {
965
+ CaseWhen *when = (CaseWhen *) lfirst(temp);
966
+
967
+ Assert(IsA(when, CaseWhen));
968
+ if (walker(when->expr, context))
969
+ return true;
970
+ if (walker(when->result, context))
971
+ return true;
972
+ }
973
+ if (walker(caseexpr->defresult, context))
974
+ return true;
975
+ }
976
+ break;
977
+ case T_RowExpr:
978
+ /* Assume colnames isn't interesting */
979
+ return walker(((RowExpr *) node)->args, context);
980
+ case T_CoalesceExpr:
981
+ return walker(((CoalesceExpr *) node)->args, context);
982
+ case T_MinMaxExpr:
983
+ return walker(((MinMaxExpr *) node)->args, context);
984
+ case T_XmlExpr:
985
+ {
986
+ XmlExpr *xexpr = (XmlExpr *) node;
987
+
988
+ if (walker(xexpr->named_args, context))
989
+ return true;
990
+ /* we assume walker doesn't care about arg_names */
991
+ if (walker(xexpr->args, context))
992
+ return true;
993
+ }
994
+ break;
995
+ case T_NullTest:
996
+ return walker(((NullTest *) node)->arg, context);
997
+ case T_BooleanTest:
998
+ return walker(((BooleanTest *) node)->arg, context);
999
+ case T_JoinExpr:
1000
+ {
1001
+ JoinExpr *join = (JoinExpr *) node;
1002
+
1003
+ if (walker(join->larg, context))
1004
+ return true;
1005
+ if (walker(join->rarg, context))
1006
+ return true;
1007
+ if (walker(join->quals, context))
1008
+ return true;
1009
+ if (walker(join->alias, context))
1010
+ return true;
1011
+ /* using list is deemed uninteresting */
1012
+ }
1013
+ break;
1014
+ case T_IntoClause:
1015
+ {
1016
+ IntoClause *into = (IntoClause *) node;
1017
+
1018
+ if (walker(into->rel, context))
1019
+ return true;
1020
+ /* colNames, options are deemed uninteresting */
1021
+ }
1022
+ break;
1023
+ case T_List:
1024
+ foreach(temp, (List *) node)
1025
+ {
1026
+ if (walker((Node *) lfirst(temp), context))
1027
+ return true;
1028
+ }
1029
+ break;
1030
+ case T_SelectStmt:
1031
+ {
1032
+ SelectStmt *stmt = (SelectStmt *) node;
1033
+
1034
+ if (walker(stmt->distinctClause, context))
1035
+ return true;
1036
+ if (walker(stmt->intoClause, context))
1037
+ return true;
1038
+ if (walker(stmt->targetList, context))
1039
+ return true;
1040
+ if (walker(stmt->fromClause, context))
1041
+ return true;
1042
+ if (walker(stmt->whereClause, context))
1043
+ return true;
1044
+ if (walker(stmt->groupClause, context))
1045
+ return true;
1046
+ if (walker(stmt->havingClause, context))
1047
+ return true;
1048
+ if (walker(stmt->windowClause, context))
1049
+ return true;
1050
+ if (walker(stmt->withClause, context))
1051
+ return true;
1052
+ if (walker(stmt->valuesLists, context))
1053
+ return true;
1054
+ if (walker(stmt->sortClause, context))
1055
+ return true;
1056
+ if (walker(stmt->limitOffset, context))
1057
+ return true;
1058
+ if (walker(stmt->limitCount, context))
1059
+ return true;
1060
+ if (walker(stmt->lockingClause, context))
1061
+ return true;
1062
+ if (walker(stmt->larg, context))
1063
+ return true;
1064
+ if (walker(stmt->rarg, context))
1065
+ return true;
1066
+ }
1067
+ break;
1068
+ case T_A_Expr:
1069
+ {
1070
+ A_Expr *expr = (A_Expr *) node;
1071
+
1072
+ if (walker(expr->lexpr, context))
1073
+ return true;
1074
+ if (walker(expr->rexpr, context))
1075
+ return true;
1076
+ /* operator name is deemed uninteresting */
1077
+ }
1078
+ break;
1079
+ case T_ColumnRef:
1080
+ /* we assume the fields contain nothing interesting */
1081
+ break;
1082
+ case T_FuncCall:
1083
+ {
1084
+ FuncCall *fcall = (FuncCall *) node;
1085
+
1086
+ if (walker(fcall->args, context))
1087
+ return true;
1088
+ if (walker(fcall->over, context))
1089
+ return true;
1090
+ /* function name is deemed uninteresting */
1091
+ }
1092
+ break;
1093
+ case T_A_Indices:
1094
+ {
1095
+ A_Indices *indices = (A_Indices *) node;
1096
+
1097
+ if (walker(indices->lidx, context))
1098
+ return true;
1099
+ if (walker(indices->uidx, context))
1100
+ return true;
1101
+ }
1102
+ break;
1103
+ case T_A_Indirection:
1104
+ {
1105
+ A_Indirection *indir = (A_Indirection *) node;
1106
+
1107
+ if (walker(indir->arg, context))
1108
+ return true;
1109
+ if (walker(indir->indirection, context))
1110
+ return true;
1111
+ }
1112
+ break;
1113
+ case T_A_ArrayExpr:
1114
+ return walker(((A_ArrayExpr *) node)->elements, context);
1115
+ case T_ResTarget:
1116
+ {
1117
+ ResTarget *rt = (ResTarget *) node;
1118
+
1119
+ if (walker(rt->indirection, context))
1120
+ return true;
1121
+ if (walker(rt->val, context))
1122
+ return true;
1123
+ }
1124
+ break;
1125
+ case T_TypeCast:
1126
+ {
1127
+ TypeCast *tc = (TypeCast *) node;
1128
+
1129
+ if (walker(tc->arg, context))
1130
+ return true;
1131
+ if (walker(tc->typeName, context))
1132
+ return true;
1133
+ }
1134
+ break;
1135
+ case T_SortBy:
1136
+ return walker(((SortBy *) node)->node, context);
1137
+ case T_WindowDef:
1138
+ {
1139
+ WindowDef *wd = (WindowDef *) node;
1140
+
1141
+ if (walker(wd->partitionClause, context))
1142
+ return true;
1143
+ if (walker(wd->orderClause, context))
1144
+ return true;
1145
+ }
1146
+ break;
1147
+ case T_RangeSubselect:
1148
+ {
1149
+ RangeSubselect *rs = (RangeSubselect *) node;
1150
+
1151
+ if (walker(rs->subquery, context))
1152
+ return true;
1153
+ if (walker(rs->alias, context))
1154
+ return true;
1155
+ }
1156
+ break;
1157
+ case T_RangeFunction:
1158
+ {
1159
+ RangeFunction *rf = (RangeFunction *) node;
1160
+
1161
+ if (walker(rf->funccallnode, context))
1162
+ return true;
1163
+ if (walker(rf->alias, context))
1164
+ return true;
1165
+ }
1166
+ break;
1167
+ case T_TypeName:
1168
+ {
1169
+ TypeName *tn = (TypeName *) node;
1170
+
1171
+ if (walker(tn->typmods, context))
1172
+ return true;
1173
+ if (walker(tn->arrayBounds, context))
1174
+ return true;
1175
+ /* type name itself is deemed uninteresting */
1176
+ }
1177
+ break;
1178
+ case T_ColumnDef:
1179
+ {
1180
+ ColumnDef *coldef = (ColumnDef *) node;
1181
+
1182
+ if (walker(coldef->typeName, context))
1183
+ return true;
1184
+ if (walker(coldef->raw_default, context))
1185
+ return true;
1186
+ /* for now, constraints are ignored */
1187
+ }
1188
+ break;
1189
+ case T_LockingClause:
1190
+ return walker(((LockingClause *) node)->lockedRels, context);
1191
+ case T_XmlSerialize:
1192
+ {
1193
+ XmlSerialize *xs = (XmlSerialize *) node;
1194
+
1195
+ if (walker(xs->expr, context))
1196
+ return true;
1197
+ if (walker(xs->typeName, context))
1198
+ return true;
1199
+ }
1200
+ break;
1201
+ case T_WithClause:
1202
+ return walker(((WithClause *) node)->ctes, context);
1203
+ case T_CommonTableExpr:
1204
+ return walker(((CommonTableExpr *) node)->ctequery, context);
1205
+ default:
1206
+ /*
1207
+ elog(ERROR, "unrecognized node type: %d",
1208
+ (int) nodeTag(node));
1209
+ */
1210
+ break;
1211
+ }
1212
+ return false;
1213
+ }
1214
+ /* from nodeFuncs.c end */
1215
+