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,185 @@
1
+ /* -*-pgsql-c-*- */
2
+ /*
3
+ *
4
+ * $Header$
5
+ *
6
+ * pgpool: a language independent connection pool server for PostgreSQL
7
+ * written by Tatsuo Ishii
8
+ *
9
+ * Copyright (c) 2003-2012 PgPool Global Development Group
10
+ *
11
+ * Permission to use, copy, modify, and distribute this software and
12
+ * its documentation for any purpose and without fee is hereby
13
+ * granted, provided that the above copyright notice appear in all
14
+ * copies and that both that copyright notice and this permission
15
+ * notice appear in supporting documentation, and that the name of the
16
+ * author not be used in advertising or publicity pertaining to
17
+ * distribution of the software without specific, written prior
18
+ * permission. The author makes no representations about the
19
+ * suitability of this software for any purpose. It is provided "as
20
+ * is" without express or implied warranty.
21
+ *
22
+ * pool_proto_modules.h.: header file for pool_proto_modules.c, pool_proto2.c
23
+ * and pool_process_query.c
24
+ *
25
+ */
26
+
27
+ #ifndef POOL_PROTO_MODULES_H
28
+ #define POOL_PROTO_MODULES_H
29
+
30
+ #include "parser/parser.h"
31
+ #include "parser/pool_memory.h"
32
+ #include "parser/pg_list.h"
33
+ #include "parser/parsenodes.h"
34
+ #include "pool_rewrite_query.h"
35
+ #include "pool_session_context.h"
36
+ #include "pool_process_reporting.h"
37
+
38
+ #define SPECIFIED_ERROR 1
39
+ #define POOL_DUMMY_WRITE_QUERY "DELETE FROM foo WHERE col = 'pgpool: unable to parse the query'"
40
+ #define POOL_DUMMY_READ_QUERY "SELECT 'pgpool: unable to parse the query'"
41
+ #define POOL_ERROR_QUERY "send invalid query from pgpool to abort transaction"
42
+
43
+ extern char *copy_table; /* copy table name */
44
+ extern char *copy_schema; /* copy table name */
45
+ extern char copy_delimiter; /* copy delimiter char */
46
+ extern char *copy_null; /* copy null string */
47
+
48
+ extern int is_select_pgcatalog;
49
+ extern int is_select_for_update; /* also for SELECT ... INTO */
50
+ extern bool is_parallel_table;
51
+ extern char *parsed_query;
52
+
53
+ /*
54
+ * modules defined in pool_proto_modules.c
55
+ */
56
+ extern POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
57
+ POOL_CONNECTION_POOL *backend,
58
+ int len, char *contents);
59
+
60
+ extern POOL_STATUS Execute(POOL_CONNECTION *frontend,
61
+ POOL_CONNECTION_POOL *backend,
62
+ int len, char *contents);
63
+
64
+ extern POOL_STATUS Parse(POOL_CONNECTION *frontend,
65
+ POOL_CONNECTION_POOL *backend,
66
+ int len, char *contents);
67
+
68
+ extern POOL_STATUS Bind(POOL_CONNECTION *frontend,
69
+ POOL_CONNECTION_POOL *backend,
70
+ int len, char *contents);
71
+
72
+ extern POOL_STATUS Describe(POOL_CONNECTION *frontend,
73
+ POOL_CONNECTION_POOL *backend,
74
+ int len, char *contents);
75
+
76
+ extern POOL_STATUS Close(POOL_CONNECTION *frontend,
77
+ POOL_CONNECTION_POOL *backend,
78
+ int len, char *contents);
79
+
80
+ extern POOL_STATUS FunctionCall3(POOL_CONNECTION *frontend,
81
+ POOL_CONNECTION_POOL *backend,
82
+ int len, char *contents);
83
+
84
+ extern POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
85
+ POOL_CONNECTION_POOL *backend, bool send_ready, bool cache_commit);
86
+
87
+ extern POOL_STATUS ParseComplete(POOL_CONNECTION *frontend,
88
+ POOL_CONNECTION_POOL *backend);
89
+
90
+ extern POOL_STATUS BindComplete(POOL_CONNECTION *frontend,
91
+ POOL_CONNECTION_POOL *backend);
92
+
93
+ extern POOL_STATUS CloseComplete(POOL_CONNECTION *frontend,
94
+ POOL_CONNECTION_POOL *backend);
95
+
96
+ extern POOL_STATUS CommandComplete(POOL_CONNECTION *frontend,
97
+ POOL_CONNECTION_POOL *backend);
98
+
99
+ extern POOL_STATUS ErrorResponse3(POOL_CONNECTION *frontend,
100
+ POOL_CONNECTION_POOL *backend);
101
+
102
+ extern POOL_STATUS CopyInResponse(POOL_CONNECTION *frontend,
103
+ POOL_CONNECTION_POOL *backend);
104
+
105
+ extern POOL_STATUS CopyOutResponse(POOL_CONNECTION *frontend,
106
+ POOL_CONNECTION_POOL *backend);
107
+
108
+ extern POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend,
109
+ POOL_CONNECTION_POOL *backend, int copyin);
110
+
111
+ extern POOL_STATUS FunctionCall(POOL_CONNECTION *frontend,
112
+ POOL_CONNECTION_POOL *backend);
113
+
114
+ extern POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
115
+ POOL_CONNECTION_POOL *backend);
116
+
117
+ extern POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend,
118
+ POOL_CONNECTION_POOL *backend,
119
+ int *state, short *num_fields);
120
+
121
+ /*
122
+ * modules defined in pool_proto2.c
123
+ */
124
+ extern POOL_STATUS AsciiRow(POOL_CONNECTION *frontend,
125
+ POOL_CONNECTION_POOL *backend,
126
+ short num_fields);
127
+
128
+ extern POOL_STATUS BinaryRow(POOL_CONNECTION *frontend,
129
+ POOL_CONNECTION_POOL *backend,
130
+ short num_fields);
131
+
132
+ extern POOL_STATUS CompletedResponse(POOL_CONNECTION *frontend,
133
+ POOL_CONNECTION_POOL *backend);
134
+
135
+ extern POOL_STATUS CursorResponse(POOL_CONNECTION *frontend,
136
+ POOL_CONNECTION_POOL *backend);
137
+
138
+ extern POOL_STATUS EmptyQueryResponse(POOL_CONNECTION *frontend,
139
+ POOL_CONNECTION_POOL *backend);
140
+
141
+ extern POOL_STATUS FunctionResultResponse(POOL_CONNECTION *frontend,
142
+ POOL_CONNECTION_POOL *backend);
143
+
144
+ extern POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend,
145
+ POOL_CONNECTION_POOL *backend);
146
+
147
+ extern int RowDescription(POOL_CONNECTION *frontend,
148
+ POOL_CONNECTION_POOL *backend,
149
+ short *result);
150
+
151
+
152
+ extern POOL_STATUS wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoVersion);
153
+ extern int is_select_query(Node *node, char *sql);
154
+ extern bool is_commit_query(Node *node);
155
+ extern bool is_rollback_query(Node *node);
156
+ extern bool is_commit_or_rollback_query(Node *node);
157
+ extern bool is_strict_query(Node *node); /* returns non 0 if this is strict query */
158
+ extern int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node);
159
+ extern POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *query, InsertStmt *node, int lock_kind);
160
+ extern char *parse_copy_data(char *buf, int len, char delimiter, int col_id);
161
+ extern int check_copy_from_stdin(Node *node); /* returns non 0 if this is a COPY FROM STDIN */
162
+ extern void query_ps_status(char *query, POOL_CONNECTION_POOL *backend); /* show ps status */
163
+ extern POOL_STATUS start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node *node);
164
+ extern POOL_STATUS end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
165
+ extern int detect_deadlock_error(POOL_CONNECTION *master, int major);
166
+ extern int detect_serialization_error(POOL_CONNECTION *master, int major, bool unread);
167
+ extern int detect_active_sql_transaction_error(POOL_CONNECTION *backend, int major);
168
+ extern int detect_query_cancel_error(POOL_CONNECTION *backend, int major);
169
+ extern bool is_partition_table(POOL_CONNECTION_POOL *backend, Node *node);
170
+ extern POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp);
171
+ extern void query_cache_register(char kind, POOL_CONNECTION *frontend, char *database, char *data, int data_len);
172
+ extern int is_drop_database(Node *node); /* returns non 0 if this is a DROP DATABASE command */
173
+
174
+ extern POOL_STATUS send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int major);
175
+ extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend,
176
+ int node_id, char *kind,
177
+ int len, char *string);
178
+
179
+ extern int synchronize(POOL_CONNECTION *cp);
180
+ extern POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *decided_kind);
181
+ extern POOL_STATUS read_kind_from_one_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *kind, int node);
182
+ extern POOL_STATUS do_error_command(POOL_CONNECTION *backend, int major);
183
+ extern POOL_STATUS raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend);
184
+
185
+ #endif
@@ -0,0 +1,1020 @@
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-2010 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
+ * pool_query_cache.c: query cache
22
+ *
23
+ */
24
+
25
+ #include <errno.h>
26
+ #include <stdlib.h>
27
+ #include <string.h>
28
+ #include <sys/types.h>
29
+ #include <netinet/in.h>
30
+ #include <arpa/inet.h>
31
+ #include <time.h>
32
+ #include <sys/time.h>
33
+ #include <unistd.h>
34
+ #ifdef HAVE_SYS_SELECT_H
35
+ #include <sys/select.h>
36
+ #endif
37
+
38
+ #include "pool.h"
39
+ #include "md5.h"
40
+ #include "pool_stream.h"
41
+ #include "pool_config.h"
42
+ #include "pool_proto_modules.h"
43
+ #include "parser/parsenodes.h"
44
+
45
+ #define QUERY_CACHE_TABLE_NAME "query_cache"
46
+ #define CACHE_REGISTER_PREPARED_STMT "register_prepared_stmt"
47
+ #define DEFAULT_CACHE_SIZE 8192
48
+
49
+ #define SYSDB_CON (SYSDB_CONNECTION->con)
50
+ #define SYSDB_MAJOR (SYSDB_CONNECTION->sp->major)
51
+ #define CACHE_TABLE_INFO (SYSDB_INFO->query_cache_table_info)
52
+
53
+ /* data structure to store RowDescription and DataRow cache */
54
+ typedef struct
55
+ {
56
+ char *md5_query; /* query in md5 hushed format*/
57
+ char *query; /* query string */
58
+ char *cache; /* cached data */
59
+ int cache_size; /* cached data size */
60
+ int cache_offset; /* points the end of cache */
61
+ char *db_name; /* database name */
62
+ char *create_time; /* cache create timestamp in ISO format */
63
+ } QueryCacheInfo;
64
+
65
+ typedef enum
66
+ {
67
+ CACHE_FOUND, CACHE_NOT_FOUND, CACHE_ERROR
68
+ } CACHE_STATUS;
69
+
70
+ static QueryCacheInfo *query_cache_info;
71
+
72
+ static CACHE_STATUS search_system_db_for_cache(POOL_CONNECTION *frontend, char *sql, int sql_len, struct timeval *t, char tstate);
73
+ static int ForwardCacheToFrontend(POOL_CONNECTION *frontend, char *cache, char tstate);
74
+ static int init_query_cache_info(POOL_CONNECTION *pc, char *database, char *query);
75
+ static void free_query_cache_info(void);
76
+ static int malloc_failed(void *p);
77
+ static int write_cache(void *buf, int len);
78
+ static char *pq_time_to_str(time_t t);
79
+ static int system_db_connection_exists(void);
80
+ static void define_prepared_statements(void);
81
+
82
+ /* --------------------------------
83
+ * pool_clear_cache - clears cache data from the SystemDB
84
+ *
85
+ * return 0 on success, -1 otherwise
86
+ * --------------------------------
87
+ */
88
+ int
89
+ pool_clear_cache_by_time(Interval *interval, int size)
90
+ {
91
+ PGresult *pg_result = NULL;
92
+ long interval_in_days = 0;
93
+ long interval_in_seconds = 0;
94
+ time_t query_delete_timepoint;
95
+ char *query_delete_timepoint_in_str = NULL;
96
+ int sql_len;
97
+ char *sql = NULL;
98
+ int i;
99
+
100
+ if (! system_db_connection_exists())
101
+ return -1;
102
+
103
+ for (i = 0; i < size; i++)
104
+ {
105
+ int q = interval[i].quantity;
106
+
107
+ switch (interval[i].unit)
108
+ {
109
+ case millennium:
110
+ case millenniums:
111
+ q *= 10;
112
+
113
+ case century:
114
+ case centuries:
115
+ q *= 10;
116
+
117
+ case decade:
118
+ case decades:
119
+ q *= 10;
120
+
121
+ case year:
122
+ case years:
123
+ q *= 12;
124
+
125
+ case month:
126
+ case months:
127
+ q *= 31; /* should I change this according to the month? */
128
+ interval_in_days += q;
129
+ break;
130
+
131
+ case week:
132
+ case weeks:
133
+ q *= 7;
134
+
135
+ case day:
136
+ case days:
137
+ q *= 24;
138
+
139
+ case hour:
140
+ case hours:
141
+ q *= 60;
142
+
143
+ case minute:
144
+ case minutes:
145
+ q *= 60;
146
+
147
+ case second:
148
+ case seconds:
149
+ interval_in_seconds += q;
150
+ break;
151
+ }
152
+ }
153
+
154
+ interval_in_seconds = (interval_in_days * 86400) + interval_in_seconds;
155
+ query_delete_timepoint = time(NULL) - interval_in_seconds;
156
+
157
+ query_delete_timepoint_in_str = pq_time_to_str(query_delete_timepoint);
158
+ if (malloc_failed(query_delete_timepoint_in_str))
159
+ return -1;
160
+
161
+ sql_len =
162
+ strlen(pool_config->system_db_schema) +
163
+ strlen(QUERY_CACHE_TABLE_NAME) +
164
+ strlen(query_delete_timepoint_in_str) +
165
+ 64;
166
+
167
+ sql = (char *)malloc(sql_len);
168
+ if (malloc_failed(sql))
169
+ {
170
+ free(query_delete_timepoint_in_str);
171
+ return -1;
172
+ }
173
+
174
+ snprintf(sql, sql_len,
175
+ "DELETE FROM %s.%s WHERE create_time <= '%s'",
176
+ pool_config->system_db_schema,
177
+ QUERY_CACHE_TABLE_NAME,
178
+ query_delete_timepoint_in_str);
179
+
180
+ pool_debug("pool_clear_cache: delete all query cache created before '%s'", query_delete_timepoint_in_str);
181
+
182
+ pg_result = PQexec(system_db_info->pgconn, sql);
183
+ if (!pg_result || PQresultStatus(pg_result) != PGRES_COMMAND_OK)
184
+ {
185
+ pool_error("pool_clear_cache: PQexec() failed. reason: %s",
186
+ PQerrorMessage(system_db_info->pgconn));
187
+
188
+ PQclear(pg_result);
189
+ free(query_delete_timepoint_in_str);
190
+ free(sql);
191
+ return -1;
192
+ }
193
+
194
+ PQclear(pg_result);
195
+ free(query_delete_timepoint_in_str);
196
+ free(sql);
197
+
198
+ return 0;
199
+ }
200
+
201
+ /* --------------------------------
202
+ * pool_query_cache_table_exists - checks if query_cache table exists in the SystemDB
203
+ *
204
+ * This function is called once and only once from the pgpool parent process.
205
+ * return 1 if query_cache table exists, 0 otherwise.
206
+ * --------------------------------
207
+ */
208
+ int
209
+ pool_query_cache_table_exists(void)
210
+ {
211
+ PGresult *pg_result = NULL;
212
+ char *sql = NULL;
213
+ int sql_len = strlen(pool_config->system_db_schema) + strlen(QUERY_CACHE_TABLE_NAME) + 64;
214
+
215
+ if (! system_db_connection_exists())
216
+ return 0;
217
+
218
+ sql = (char *)malloc(sql_len);
219
+ if (malloc_failed(sql))
220
+ return 0;
221
+
222
+ snprintf(sql, sql_len,
223
+ "SELECT hash, query, value, dbname, create_time FROM %s.%s LIMIT 1",
224
+ pool_config->system_db_schema,
225
+ QUERY_CACHE_TABLE_NAME);
226
+
227
+ pg_result = PQexec(system_db_info->pgconn, sql);
228
+ if (!pg_result || PQresultStatus(pg_result) != PGRES_TUPLES_OK)
229
+ {
230
+ pool_error("pool_query_cache_table_exists: PQexec() failed. reason: %s",
231
+ PQerrorMessage(system_db_info->pgconn));
232
+
233
+ PQclear(pg_result);
234
+ free(sql);
235
+ return 0;
236
+ }
237
+
238
+ PQclear(pg_result);
239
+ pool_close_libpq_connection();
240
+ free(sql);
241
+
242
+ return 1;
243
+ }
244
+
245
+ /* --------------------------------
246
+ * pool_query_cache_lookup - retrieve query cache from the SystemDB
247
+ *
248
+ * creates a SQL query string for searching a cache from the SystemDB.
249
+ *
250
+ * returns POOL_CONTINUE if cache is found. returns POOL_END if cache was
251
+ * not found. returns POOL_ERROR if an error has been encountered while
252
+ * searching.
253
+ *
254
+ * Note that POOL_END and POOL_ERROR are treated the same by the caller
255
+ * (pool_process_query.c).
256
+ * POOL_END and POOL_ERROR both indicates to the caller that the search
257
+ * query must be forwarded to the backends in order to retrieve data and
258
+ * the result be cached.
259
+ * Only difference is that POOL_ERROR indicates that some fatal error has
260
+ * occurred; query cache function, however, should be seamless to the user
261
+ * whether cache was not found or error has occurred during cache retrieve.
262
+ * --------------------------------
263
+ */
264
+ POOL_STATUS
265
+ pool_query_cache_lookup(POOL_CONNECTION *frontend, char *query, char *database, char tstate)
266
+ {
267
+ char *sql = NULL;
268
+ int sql_len;
269
+ char md5_query[33];
270
+ struct timeval timeout;
271
+ int status;
272
+
273
+ if (! system_db_connection_exists())
274
+ return POOL_ERROR; /* same as POOL_END ... at least for now */
275
+
276
+ sql_len =
277
+ strlen(pool_config->system_db_schema) +
278
+ strlen(QUERY_CACHE_TABLE_NAME) +
279
+ sizeof(md5_query) +
280
+ strlen(database) +
281
+ 64;
282
+ sql = (char *)malloc(sql_len);
283
+ if (malloc_failed(sql))
284
+ return POOL_ERROR; /* should I exit here rather than returning an error? */
285
+
286
+ /* cached data lookup */
287
+ pool_md5_hash(query, strlen(query), md5_query);
288
+ snprintf(sql, sql_len, "SELECT value FROM %s.%s WHERE hash = '%s' AND dbname = '%s'",
289
+ pool_config->system_db_schema,
290
+ QUERY_CACHE_TABLE_NAME,
291
+ md5_query,
292
+ database);
293
+
294
+ /* set timeout value for select */
295
+ timeout.tv_sec = pool_config->child_life_time;
296
+ timeout.tv_usec = 0;
297
+
298
+ pool_debug("pool_query_cache_lookup: searching cache for query: \"%s\"", query);
299
+ status = search_system_db_for_cache(frontend, sql, strlen(sql)+1, &timeout, tstate);
300
+
301
+ /* make sure that the remaining data is discarded */
302
+ SYSDB_CON->po = 0;
303
+ SYSDB_CON->len = 0;
304
+
305
+ free(sql);
306
+
307
+ /* cache found, and no backend communication needed */
308
+ if (status == CACHE_FOUND)
309
+ {
310
+ return POOL_CONTINUE;
311
+ }
312
+
313
+ /* cache not found */
314
+
315
+ if (status == CACHE_ERROR)
316
+ {
317
+ pool_error("pool_query_cache_lookup: query cache lookup failed");
318
+ /* reset the SystemDB connection */
319
+ if (system_db_info->pgconn)
320
+ pool_close_libpq_connection();
321
+ return POOL_ERROR; /* same as POOL_END ... at least for now */
322
+ }
323
+
324
+ pool_debug("pool_query_cache_lookup: query cache not found");
325
+ return POOL_END;
326
+ }
327
+
328
+ /* --------------------------------
329
+ * search_system_db_for_cache - search for query cache in libpq protocol level
330
+ *
331
+ * sends a cache searching query string using libpq protocol to the SystemDB.
332
+ * if the SystemDB returns cache, forward the data to the frontend, and return
333
+ * CACHE_FOUND. if cache was not found, silently discards the remaining data
334
+ * returned by the SystemDB, and return CACHE_NOT_FOUND. returns CACHE_ERROR
335
+ * if an error was encountered.
336
+ * --------------------------------
337
+ */
338
+ static CACHE_STATUS
339
+ search_system_db_for_cache(POOL_CONNECTION *frontend, char *sql, int sql_len, struct timeval *t, char tstate)
340
+ {
341
+ fd_set readmask;
342
+ int fds;
343
+ int num_fds;
344
+ struct timeval *timeout = NULL;
345
+ char kind;
346
+ int readlen;
347
+ char *data = NULL;
348
+ CACHE_STATUS return_value = CACHE_ERROR;
349
+ int cache_found = 0;
350
+
351
+ pool_debug("pool_query_cache_lookup: executing query: \"%s\"", sql);
352
+
353
+ pool_write(SYSDB_CON, "Q", 1);
354
+ if (SYSDB_MAJOR == PROTO_MAJOR_V3)
355
+ {
356
+ int sendlen = htonl(sql_len + 4);
357
+ pool_write(SYSDB_CON, &sendlen, sizeof(sendlen));
358
+ }
359
+ if (pool_write_and_flush(SYSDB_CON, sql, sql_len) < 0)
360
+ {
361
+ pool_error("pool_query_cache_lookup: error while sending data to the SystemDB");
362
+ return CACHE_ERROR;
363
+ }
364
+
365
+ if ((t->tv_sec + t->tv_usec) == 0)
366
+ timeout = NULL;
367
+ else
368
+ timeout = t;
369
+
370
+ /* don't really need select() or for(;;) here, but we may need it someday... or not */
371
+ for (;;)
372
+ {
373
+ FD_ZERO(&readmask);
374
+ num_fds = 0;
375
+
376
+ num_fds = SYSDB_CON->fd + 1;
377
+ FD_SET(SYSDB_CON->fd, &readmask);
378
+ fds = select(num_fds, &readmask, NULL, NULL, timeout);
379
+ if (fds == -1)
380
+ {
381
+ if (errno == EINTR)
382
+ continue;
383
+
384
+ pool_error("pool_query_cache_lookup: select() failed. reason: %s", strerror(errno));
385
+ return CACHE_ERROR;
386
+ }
387
+
388
+ /* select() timeout */
389
+ if (fds == 0)
390
+ return CACHE_ERROR;
391
+
392
+ for (;;)
393
+ {
394
+ if (! FD_ISSET(SYSDB_CON->fd, &readmask))
395
+ {
396
+ pool_error("pool_query_cache_lookup: select() failed");
397
+ return CACHE_ERROR;
398
+ }
399
+
400
+ /* read kind */
401
+ if (pool_read(SYSDB_CON, &kind, sizeof(kind)) < 0)
402
+ {
403
+ pool_error("pool_query_cache_lookup: error while reading message kind");
404
+ return CACHE_ERROR;
405
+ }
406
+ pool_debug("pool_query_cache_lookup: received %c from systemdb", kind);
407
+
408
+ /* just do the routine work of reading data in. data won't be used */
409
+ if (kind == 'T')
410
+ {
411
+ if (SYSDB_MAJOR == PROTO_MAJOR_V3)
412
+ {
413
+ if (pool_read(SYSDB_CON, &readlen, sizeof(int)) < 0)
414
+ {
415
+ pool_error("pool_query_cache_lookup: error while reading message length");
416
+ return CACHE_ERROR;
417
+ }
418
+ readlen = ntohl(readlen) - sizeof(int);
419
+ data = pool_read2(SYSDB_CON, readlen);
420
+ }
421
+ else
422
+ {
423
+ data = pool_read_string(SYSDB_CON, &readlen, 0);
424
+ }
425
+ }
426
+ else if (kind == 'D') /* cache found! forward it to the frontend */
427
+ {
428
+ char *cache;
429
+ int status;
430
+
431
+ cache_found = 1;
432
+
433
+ if (SYSDB_MAJOR == PROTO_MAJOR_V3)
434
+ {
435
+ if (pool_read(SYSDB_CON, &readlen, sizeof(readlen)) < 0)
436
+ {
437
+ pool_error("pool_query_cache_lookup: error while reading message length");
438
+ return CACHE_ERROR;
439
+ }
440
+ readlen = ntohl(readlen) - sizeof(int);
441
+ cache = pool_read2(SYSDB_CON, readlen);
442
+ }
443
+ else
444
+ {
445
+ cache = pool_read_string(SYSDB_CON, &readlen, 0);
446
+ }
447
+
448
+ if (cache == NULL)
449
+ {
450
+ pool_error("pool_query_cache_lookup: error while reading message body");
451
+ return CACHE_ERROR;
452
+ }
453
+
454
+ cache[readlen] = '\0';
455
+
456
+ cache += sizeof(short); /* number of columns in 'D' (we know it's always going to be 1, so skip) */
457
+ cache += sizeof(int); /* length of escaped bytea cache in string format. don't need the length */
458
+
459
+ status = ForwardCacheToFrontend(frontend, cache, tstate);
460
+ if (status < 0)
461
+ {
462
+ /* fatal error has occurred while forwarding cache */
463
+ pool_error("pool_query_cache_lookup: query cache forwarding failed");
464
+ return_value = CACHE_ERROR;
465
+ }
466
+ }
467
+ else if (kind == 'C') /* see if 'D' was received */
468
+ {
469
+ if (cache_found)
470
+ return_value = CACHE_FOUND;
471
+ else
472
+ return_value = CACHE_NOT_FOUND;
473
+
474
+ /* must discard the remaining data */
475
+ if (SYSDB_MAJOR == PROTO_MAJOR_V3)
476
+ {
477
+ if (pool_read(SYSDB_CON, &readlen, sizeof(int)) < 0)
478
+ {
479
+ pool_error("pool_query_cache_lookup: error while reading message length");
480
+ return CACHE_ERROR;
481
+ }
482
+ readlen = ntohl(readlen) - sizeof(int);
483
+ data = pool_read2(SYSDB_CON, readlen);
484
+ }
485
+ else
486
+ {
487
+ data = pool_read_string(SYSDB_CON, &readlen, 0);
488
+ }
489
+ }
490
+ else if (kind == 'Z')
491
+ {
492
+ /* must discard the remaining data */
493
+ if (SYSDB_MAJOR == PROTO_MAJOR_V3)
494
+ {
495
+ if (pool_read(SYSDB_CON, &readlen, sizeof(int)) < 0)
496
+ {
497
+ pool_error("pool_query_cache_lookup: error while reading message length");
498
+ return CACHE_ERROR;
499
+ }
500
+ readlen = ntohl(readlen) - sizeof(int);
501
+ data = pool_read2(SYSDB_CON, readlen);
502
+ }
503
+ else
504
+ {
505
+ data = pool_read_string(SYSDB_CON, &readlen, 0);
506
+ }
507
+
508
+ break;
509
+ }
510
+ else if (kind == 'E')
511
+ {
512
+ /* must discard the remaining data */
513
+ if (SYSDB_MAJOR == PROTO_MAJOR_V3)
514
+ {
515
+ if (pool_read(SYSDB_CON, &readlen, sizeof(int)) < 0)
516
+ {
517
+ pool_error("pool_query_cache_lookup: error while reading message length");
518
+ return CACHE_ERROR;
519
+ }
520
+ readlen = ntohl(readlen) - sizeof(int);
521
+ data = pool_read2(SYSDB_CON, readlen);
522
+ }
523
+ else
524
+ {
525
+ data = pool_read_string(SYSDB_CON, &readlen, 0);
526
+ }
527
+
528
+ return_value = CACHE_ERROR;
529
+ }
530
+ else
531
+ {
532
+ /* shouldn't get here, but just in case */
533
+ return CACHE_ERROR;
534
+ }
535
+ }
536
+
537
+ break;
538
+ }
539
+
540
+ return return_value;
541
+ }
542
+
543
+ /* --------------------------------
544
+ * ForwardCacheToFrontend - simply forwards cached data to the frontend
545
+ *
546
+ * since the cached data passed from the caller is in escaped binary string
547
+ * format, unescape it and send it to the frontend appending 'Z' at the end.
548
+ * returns 0 on success, -1 otherwise.
549
+ * --------------------------------
550
+ */
551
+ static int ForwardCacheToFrontend(POOL_CONNECTION *frontend, char *cache, char tstate)
552
+ {
553
+ int sendlen;
554
+ size_t sz;
555
+ char *binary_cache = NULL;
556
+
557
+ binary_cache = (char *)PQunescapeBytea((unsigned char *)cache, &sz);
558
+ sendlen = (int) sz;
559
+ if (malloc_failed(binary_cache))
560
+ return -1;
561
+
562
+ pool_debug("ForwardCacheToFrontend: query cache found (%d bytes)", sendlen);
563
+
564
+ /* forward cache to the frontend */
565
+ pool_write(frontend, binary_cache, sendlen);
566
+
567
+ /* send ReadyForQuery to the frontend*/
568
+ pool_write(frontend, "Z", 1);
569
+ sendlen = htonl(5);
570
+ pool_write(frontend, &sendlen, sizeof(int));
571
+ if (pool_write_and_flush(frontend, &tstate, 1) < 0)
572
+ {
573
+ pool_error("pool_query_cache_lookup: error while writing data to the frontend");
574
+ PQfreemem(binary_cache);
575
+ return -1;
576
+ }
577
+
578
+ PQfreemem(binary_cache);
579
+ return 0;
580
+ }
581
+
582
+ /* --------------------------------
583
+ * pool_query_cache_register() - register query cache to the SystemDB
584
+ *
585
+ * returns 0 on success, -1 otherwise
586
+ * --------------------------------
587
+ */
588
+ int
589
+ pool_query_cache_register(char kind,
590
+ POOL_CONNECTION *frontend,
591
+ char *database,
592
+ char *data,
593
+ int data_len,
594
+ char *query)
595
+ {
596
+ int ret;
597
+ int send_len;
598
+
599
+ if (! system_db_connection_exists())
600
+ return -1;
601
+ if (! CACHE_TABLE_INFO.has_prepared_statement)
602
+ define_prepared_statements();
603
+
604
+ switch (kind)
605
+ {
606
+ case 'T': /* RowDescription */
607
+ {
608
+ /* for all SELECT result data from the backend, 'T' must come first */
609
+ if (query_cache_info != NULL)
610
+ {
611
+ pool_error("pool_query_cache_register: received RowDescription in the wrong order");
612
+ free_query_cache_info();
613
+ return -1;
614
+ }
615
+
616
+ pool_debug("pool_query_cache_register: saving cache for query: \"%s\"", query);
617
+
618
+ /* initialize query_cache_info and save the query */
619
+ ret = init_query_cache_info(frontend, database, query);
620
+ if (ret)
621
+ return ret;
622
+
623
+ /* store data into the cache */
624
+ write_cache(&kind, 1);
625
+ send_len = htonl(data_len + sizeof(int));
626
+ write_cache(&send_len, sizeof(int));
627
+ write_cache(data, data_len);
628
+
629
+ break;
630
+ }
631
+
632
+ case 'D': /* DataRow */
633
+ {
634
+ /* for all SELECT result data from the backend, 'T' must come first */
635
+ if (query_cache_info == NULL)
636
+ {
637
+ pool_error("pool_query_cache_register: received DataRow in the wrong order");
638
+ return -1;
639
+ }
640
+
641
+ write_cache(&kind, 1);
642
+ send_len = htonl(data_len + sizeof(int));
643
+ write_cache(&send_len, sizeof(int));
644
+ write_cache(data, data_len);
645
+
646
+ break;
647
+ }
648
+
649
+ case 'C': /* CommandComplete */
650
+ {
651
+ PGresult *pg_result = NULL;
652
+ char *escaped_query = NULL;
653
+ size_t escaped_query_len;
654
+ time_t now = time(NULL);
655
+ char *values[5];
656
+ int values_len[5];
657
+ int values_format[5];
658
+ int i;
659
+
660
+ /* for all SELECT result data from the backend, 'T' must come first */
661
+ if (query_cache_info == NULL)
662
+ {
663
+ pool_error("pool_query_cache_register: received CommandComplete in the wrong order");
664
+ return -1;
665
+ }
666
+
667
+ /* pack CommandComplete data into the cache */
668
+ write_cache(&kind, 1);
669
+ send_len = htonl(data_len + sizeof(int));
670
+ write_cache(&send_len, sizeof(int));
671
+ write_cache(data, data_len);
672
+
673
+ query_cache_info->create_time = pq_time_to_str(now);
674
+ if (malloc_failed(query_cache_info->create_time))
675
+ {
676
+ free_query_cache_info();
677
+ return -1;
678
+ }
679
+
680
+ escaped_query = (char *)malloc(strlen(query_cache_info->query) * 2 + 1);
681
+ if (malloc_failed(escaped_query))
682
+ {
683
+ free_query_cache_info();
684
+ return -1;
685
+ }
686
+
687
+ /* escaped_query_len = PQescapeStringConn(system_db_info->pgconn, */
688
+ /* escaped_query, */
689
+ /* query_cache_info->query, */
690
+ /* strlen(query_cache_info->query))); */
691
+ escaped_query_len = PQescapeString(escaped_query, query_cache_info->query, strlen(query_cache_info->query));
692
+
693
+ /* all the result data have been received. store into the SystemDB */
694
+ values[0] = strdup(query_cache_info->md5_query);
695
+ values[1] = strdup(escaped_query);
696
+ values[2] = (char *)malloc(query_cache_info->cache_offset);
697
+ memcpy(values[2], query_cache_info->cache, query_cache_info->cache_offset);
698
+ values[3] = strdup(query_cache_info->db_name);
699
+ values[4] = strdup(query_cache_info->create_time);
700
+ for (i = 0; i < 5; i++)
701
+ {
702
+ if (malloc_failed(values[i]))
703
+ {
704
+ pool_error("pool_query_cache_register: malloc() failed");
705
+ free_query_cache_info();
706
+ {
707
+ int j;
708
+ for (j = 0; j < i; j++)
709
+ free(values[j]);
710
+ }
711
+ return -1;
712
+ }
713
+
714
+ values_len[i] = strlen(values[i]);
715
+ }
716
+ values_format[0] = values_format[1] = values_format[3] = values_format[4] = 0;
717
+ values_format[2] = 1;
718
+ values_len[2] = query_cache_info->cache_offset;
719
+
720
+ pg_result = PQexecPrepared(system_db_info->pgconn,
721
+ CACHE_TABLE_INFO.register_prepared_statement,
722
+ 5,
723
+ (const char * const *)values,
724
+ values_len,
725
+ values_format,
726
+ 0);
727
+ if (!pg_result || PQresultStatus(pg_result) != PGRES_COMMAND_OK)
728
+ {
729
+ pool_error("pool_query_cache_register: PQexecPrepared() failed. reason: %s",
730
+ PQerrorMessage(system_db_info->pgconn));
731
+
732
+ PQclear(pg_result);
733
+ PQfreemem(escaped_query);
734
+ free_query_cache_info();
735
+ for (i = 0; i < 5; i++)
736
+ free(values[i]);
737
+ return -1;
738
+ }
739
+
740
+ PQclear(pg_result);
741
+ PQfreemem(escaped_query);
742
+ for (i = 0; i < 5; i++)
743
+ free(values[i]);
744
+ free_query_cache_info();
745
+
746
+ break;
747
+ }
748
+
749
+ case 'E':
750
+ {
751
+ pool_debug("pool_query_cache_register: received 'E': free query cache buffer");
752
+
753
+ pool_close_libpq_connection();
754
+ free_query_cache_info();
755
+
756
+ break;
757
+ }
758
+ }
759
+
760
+ return 0;
761
+ }
762
+
763
+ /* --------------------------------
764
+ * init_query_cache_info() - allocate memory for query_cache_info and stores query
765
+ *
766
+ * returns 0 on success, -1 otherwise
767
+ `* --------------------------------
768
+ */
769
+ static int
770
+ init_query_cache_info(POOL_CONNECTION *pc, char *database, char *query)
771
+ {
772
+ int query_len; /* length of the SELECT query to be cached */
773
+
774
+ query_cache_info = (QueryCacheInfo *)malloc(sizeof(QueryCacheInfo));
775
+ if (malloc_failed(query_cache_info))
776
+ return -1;
777
+
778
+ /* query */
779
+ query_len = strlen(query);
780
+ query_cache_info->query = (char *)malloc(query_len + 1);
781
+ if (malloc_failed(query_cache_info->query))
782
+ return -1;
783
+ memcpy(query_cache_info->query, query, query_len + 1);
784
+
785
+ /* md5_query */
786
+ query_cache_info->md5_query = (char *)malloc(33); /* md5sum is always 33 bytes (including the '\0') */
787
+ if (malloc_failed(query_cache_info->md5_query))
788
+ return -1;
789
+ pool_md5_hash(query_cache_info->query, query_len, query_cache_info->md5_query);
790
+
791
+ /* malloc DEFAULT_CACHE_SIZE for query_cache_info->cache */
792
+ query_cache_info->cache = (char *)malloc(DEFAULT_CACHE_SIZE);
793
+ if (malloc_failed(query_cache_info->cache))
794
+ return -1;
795
+ query_cache_info->cache_size = DEFAULT_CACHE_SIZE;
796
+ query_cache_info->cache_offset = 0;
797
+
798
+ /* save database name */
799
+ query_cache_info->db_name = (char *)malloc(strlen(database)+1);
800
+ if (malloc_failed(query_cache_info->db_name))
801
+ return -1;
802
+ strcpy(query_cache_info->db_name, database);
803
+
804
+ /* initialize create_timestamp */
805
+ query_cache_info->create_time = NULL;
806
+
807
+ return 0;
808
+ }
809
+
810
+ /* --------------------------------
811
+ * free_query_cache_info() - free query_cache_info and its members
812
+ * --------------------------------
813
+ */
814
+ static void
815
+ free_query_cache_info(void)
816
+ {
817
+ if (query_cache_info == NULL)
818
+ return;
819
+
820
+ free(query_cache_info->md5_query);
821
+ free(query_cache_info->query);
822
+ free(query_cache_info->cache);
823
+ free(query_cache_info->db_name);
824
+ if (query_cache_info->create_time)
825
+ free(query_cache_info->create_time);
826
+ free(query_cache_info);
827
+ query_cache_info = NULL;
828
+ }
829
+
830
+ /* --------------------------------
831
+ * malloc_failed() - checks if the caller's most recent malloc() has succeeded
832
+ *
833
+ * returns 0 if malloc() was a success, -1 otherwise
834
+ `* --------------------------------
835
+ */
836
+ static int
837
+ malloc_failed(void *p)
838
+ {
839
+ if (p != NULL)
840
+ return 0;
841
+
842
+ pool_error("pool_query_cache: malloc() failed");
843
+ free_query_cache_info();
844
+
845
+ return -1;
846
+ }
847
+
848
+ /* --------------------------------
849
+ * write_cache() - append result data to buffer
850
+ *
851
+ * returns 0 on success, -1 otherwise
852
+ * --------------------------------
853
+ */
854
+ static int
855
+ write_cache(void *buf, int len)
856
+ {
857
+ int required_len;
858
+
859
+ if (len < 0)
860
+ return -1;
861
+
862
+ required_len = query_cache_info->cache_offset + len;
863
+ if (required_len > query_cache_info->cache_size)
864
+ {
865
+ char *ptr;
866
+
867
+ required_len = query_cache_info->cache_size * 2;
868
+ ptr = (char *)realloc(query_cache_info->cache, required_len);
869
+ if (malloc_failed(ptr))
870
+ return -1;
871
+
872
+ query_cache_info->cache = ptr;
873
+ query_cache_info->cache_size = required_len;
874
+
875
+ pool_debug("pool_query_cache: extended cache buffer size to %d", query_cache_info->cache_size);
876
+ }
877
+
878
+ memcpy(query_cache_info->cache + query_cache_info->cache_offset, buf, len);
879
+ query_cache_info->cache_offset += len;
880
+
881
+ return 0;
882
+ }
883
+
884
+ /* --------------------------------
885
+ * pq_time_to_str() - convert time_t to ISO standard time output string
886
+ *
887
+ * returns a pointer to newly allocated string, NULL if malloc fails
888
+ * --------------------------------
889
+ */
890
+ static char *
891
+ pq_time_to_str(time_t t)
892
+ {
893
+ char *time_p;
894
+ char iso_time[32];
895
+ struct tm *tm;
896
+
897
+ tm = localtime(&t);
898
+ strftime(iso_time, sizeof(iso_time), "%Y-%m-%d %H:%M:%S%z", tm);
899
+
900
+ time_p = strdup(iso_time);
901
+
902
+ return time_p;
903
+ }
904
+
905
+
906
+ /* --------------------------------
907
+ * system_db_connection_exists() - checks and if a connection to the SystemDB exists
908
+ *
909
+ * if not connected, it makes an attempt to connect to the SystemDB. If a connection
910
+ * exists, returns 1, returns 0 otherwise.
911
+ * --------------------------------
912
+ */
913
+ static int
914
+ system_db_connection_exists(void)
915
+ {
916
+ if (!system_db_info->pgconn ||
917
+ (PQstatus(system_db_info->pgconn) != CONNECTION_OK))
918
+ {
919
+ if (system_db_connect())
920
+ return 0;
921
+ }
922
+
923
+ return 1;
924
+ }
925
+
926
+
927
+ /* --------------------------------
928
+ * define_prepared_statements() - defines prepared statements for the current session
929
+ * --------------------------------
930
+ */
931
+ static void
932
+ define_prepared_statements(void)
933
+ {
934
+ PGresult *pg_result;
935
+ char *sql = NULL;
936
+ int sql_len;
937
+
938
+ sql_len =
939
+ strlen(pool_config->system_db_schema) +
940
+ strlen(QUERY_CACHE_TABLE_NAME) +
941
+ 1024;
942
+
943
+ sql = (char *)malloc(sql_len);
944
+ if (malloc_failed(sql))
945
+ {
946
+ pool_error("pool_query_cache: malloc() failed");
947
+ return;
948
+ }
949
+
950
+ free(CACHE_TABLE_INFO.register_prepared_statement);
951
+ CACHE_TABLE_INFO.register_prepared_statement
952
+ = strdup(CACHE_REGISTER_PREPARED_STMT);
953
+ if (malloc_failed(CACHE_TABLE_INFO.register_prepared_statement))
954
+ {
955
+ pool_error("pool_query_cache: malloc() failed");
956
+ free(sql);
957
+ return;
958
+ }
959
+
960
+ #ifdef HAVE_PQPREPARE
961
+ snprintf(sql, sql_len,
962
+ "INSERT INTO %s.%s VALUES ( $1, $2, $3, $4, $5 )",
963
+ pool_config->system_db_schema,
964
+ QUERY_CACHE_TABLE_NAME);
965
+ pg_result = PQprepare(system_db_info->pgconn,
966
+ CACHE_TABLE_INFO.register_prepared_statement,
967
+ sql,
968
+ 5,
969
+ NULL);
970
+ #else
971
+ snprintf(sql, sql_len,
972
+ "PREPARE %s (TEXT, TEXT, BYTEA, TEXT, TIMESTAMP WITH TIME ZONE) AS INSERT INTO %s.%s VALUES ( $1, $2, $3, $4, $5 )",
973
+ CACHE_TABLE_INFO.register_prepared_statement,
974
+ pool_config->system_db_schema,
975
+ QUERY_CACHE_TABLE_NAME);
976
+ pg_result = PQexec(system_db_info->pgconn, sql);
977
+ #endif
978
+ if (!pg_result || PQresultStatus(pg_result) != PGRES_COMMAND_OK)
979
+ {
980
+ pool_error("pool_query_cache: PQprepare() failed: %s", PQerrorMessage(system_db_info->pgconn));
981
+ free(CACHE_TABLE_INFO.register_prepared_statement);
982
+ free(sql);
983
+ return;
984
+ }
985
+
986
+ pool_debug("pool_query_cache: prepared statements created");
987
+ CACHE_TABLE_INFO.has_prepared_statement = 1;
988
+
989
+ free(sql);
990
+ PQclear(pg_result);
991
+ }
992
+
993
+ /* --------------------------------
994
+ * Execute query cache look up
995
+ * --------------------------------
996
+ */
997
+ POOL_STATUS pool_execute_query_cache_lookup(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node *node)
998
+ {
999
+ SelectStmt *select = (SelectStmt *)node;
1000
+ POOL_STATUS status = POOL_END; /* cache not found */
1001
+
1002
+ if (! (select->intoClause || select->lockingClause))
1003
+ {
1004
+ parsed_query = strdup(nodeToString(node));
1005
+ if (parsed_query == NULL)
1006
+ {
1007
+ pool_error("pool_execute_query_cache_lookup: malloc failed");
1008
+ return POOL_ERROR;
1009
+ }
1010
+
1011
+ status = pool_query_cache_lookup(frontend, parsed_query, backend->info->database, TSTATE(backend, MASTER_NODE_ID));
1012
+ if (status == POOL_CONTINUE)
1013
+ {
1014
+ free(parsed_query);
1015
+ parsed_query = NULL;
1016
+ }
1017
+ }
1018
+
1019
+ return status;
1020
+ }