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,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
+