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,192 @@
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_rewrite_query.h: rewrite_query
22
+ *
23
+ */
24
+
25
+ #ifndef POOL_REWRITE_QUERY_H
26
+ #define POOL_REWRITE_QUERY_H
27
+
28
+ #include "parser/nodes.h"
29
+ #include "parser/parser.h"
30
+ #include "parser/pg_list.h"
31
+ #include "parser/parsenodes.h"
32
+ #include "parser/pool_memory.h"
33
+ #include "parser/pool_string.h"
34
+
35
+ /* return code set */
36
+ #define INSERT_SQL_RESTRICTION 1
37
+ #define SELECT_INIT 2
38
+ #define SELECT_BACKEND_CONNECT 3
39
+ #define SELECT_NOT_BACKEND_CONNECT 4
40
+ #define SELECT_PGCATALOG 5
41
+ #define SELECT_CHECK_PGCATALOG_REPLICATION 6
42
+ #define SELECT_DEFAULT 7
43
+ #define SELECT_DEFAULT_INSIDE_DBLINK 8
44
+ #define SELECT_AEXPR 9
45
+ #define SELECT_AEXPR_FALSE 10
46
+ #define SELECT_ONETABLE 11
47
+ #define SELECT_ONETABLE_FALSE 12
48
+ #define SELECT_RELATION_ERROR 13
49
+ #define INSERT_DIST_NO_RULE 14
50
+ #define SEND_PARALLEL_ENGINE 15
51
+ #define SEND_LOADBALANCE_ENGINE 16
52
+ #define SELECT_NOT_REPLICATION 17
53
+ #define SELECT_REWRITE 18
54
+ #define SELECT_ANALYZE 19
55
+ #define SELECT_DEFAULT_PREP 20
56
+
57
+ /* build Sub-Select`s target List */
58
+ typedef struct {
59
+ char **col_list; /* column list */
60
+ char **type_list; /* type list */
61
+ int *return_list; /* order of col_list */
62
+ int col_num; /* column number */
63
+ bool valid; /* return to frontend */
64
+ } SelectDefInfo;
65
+
66
+ /* This struct is used as each table/sub-select of FROM-CLUASE */
67
+ typedef struct {
68
+ DistDefInfo *distinfo; /* distribution table into */
69
+ RepliDefInfo *repliinfo; /* replication table info */
70
+ SelectDefInfo *selectinfo; /* Sub-Select info */
71
+ char *alias; /* alias name */
72
+ char state; /* P = parallel, L = loadbalance S = systemdb(dblink) E = error*/
73
+ int ret_num; /* build column number */
74
+ } RangeInfo;
75
+
76
+ /* build Virtual Table of FROM-Clause */
77
+ typedef struct {
78
+ char **col_list; /* column list */
79
+ char **type_list; /* type list */
80
+ char **table_list; /* table list */
81
+ char *state_list; /* state of each column */
82
+ int *column_no; /* order of column */
83
+ int *valid; /* valid column is true */
84
+ int col_num; /* virtual table column num */
85
+ } VirtualTable;
86
+
87
+ /* this struct is used by JOIN Expr */
88
+ typedef struct {
89
+ char **col_list; /* column list */
90
+ char **type_list; /* type list */
91
+ char **table_list; /* table list */
92
+ char state; /* P = parallel, L = loadbalance S = systemdb(dblink) E = error*/
93
+ int *valid; /* valid column is true */
94
+ int col_num; /* number of column */
95
+ char **using_list; /* if join expr has using-list, column name is listed up */
96
+ int using_length; /* column number of using-list */
97
+ } JoinTable;
98
+
99
+ /* this struct is used in optimization of aggregate opr */
100
+ typedef struct {
101
+ ColumnRef **usec_p; /* targetlist columns */
102
+ FuncCall **tfunc_p; /* targetlist funcs */
103
+ ColumnRef **col_p; /* group by columns */
104
+ FuncCall **hfunc_p; /* having funcs */
105
+ int *umapc; /* order of number */
106
+ int u_num; /* targetlist columns num */
107
+ int t_num; /* targetlist funcs num */
108
+ int c_num; /* group by column num */
109
+ int h_num; /* having funcs num */
110
+ int hc_num; /* having column num */
111
+ int s_num; /* sort funcs num */
112
+ int sc_num; /* sort column num */
113
+ bool opt; /* optimization flag */
114
+ } Aggexpr;
115
+
116
+ /* main struct of analyzing query */
117
+ typedef struct {
118
+ int now_select; /* rank of select */
119
+ int part; /* the position of analyzing select statement */
120
+ int last_select; /* caller select rank */
121
+ int call_part; /* caller's potion */
122
+ int from_num; /* number for from-clause */
123
+ int larg_count; /* left arg count */
124
+ int rarg_count; /* right arg count */
125
+ int ret_count; /* return list count */
126
+ char state; /* final state */
127
+ char *table_name; /* table name or virtual table name */
128
+ char partstate[8]; /* state of analyzing part */
129
+ bool select_union; /* if UNION is used, this flag is true */
130
+ bool select_range; /* RangeSubSelect is used */
131
+ bool aggregate; /* aggregate optimization ? */
132
+ bool retlock; /* this is used */
133
+ Aggexpr *aggexpr; /* Aggexpr in this statement*/
134
+ RangeInfo **range; /* RangeInfo in from clause */
135
+ int rangeinfo_num; /* RangeInfo's number in this select statement*/
136
+ VirtualTable *virtual; /* Virtual Table in this select statement */
137
+ JoinTable *join; /* summary of join table */
138
+ SelectDefInfo *select_ret; /* build return list */
139
+ } AnalyzeSelect;
140
+
141
+ /*
142
+ * This struct is used as Information that relates
143
+ * to distribution processing of parallel query
144
+ */
145
+ typedef struct {
146
+ int r_code; /* analyze or rewrite */
147
+ int r_node; /* which node, query is sent */
148
+ int part; /* part of select statement */
149
+ int rewritelock; /* dblink start position and lock rewrite */
150
+ int analyze_num; /* sum of AnalyzeSelect */
151
+ int current_select; /* position of analyze[] */
152
+ int ignore_rewrite; /* dont rewrite */
153
+ int column; /* column number */
154
+ int virtual_num; /* Virtual table column number */
155
+ int ret_num; /* expect return column number */
156
+ bool is_pg_catalog; /* reference of pg_catalog */
157
+ bool is_loadbalance; /* load balance ? */
158
+ bool is_parallel; /* can parallel exec ? */
159
+ bool fromClause; /* having FromClause ? */
160
+ char *table_relname; /* table name */
161
+ char *table_alias; /* table alias name */
162
+ char *schemaname; /* schema */
163
+ char *dbname; /* connect dbname */
164
+ char *rewrite_query; /* execute query */
165
+ char table_state; /* final state */
166
+ POOL_STATUS status; /* return POOL_STATUS */
167
+ NodeTag type; /* Query Type */
168
+ AnalyzeSelect **analyze; /* point to analyzing result */
169
+ } RewriteQuery;
170
+
171
+ /* This info is used in dblink */
172
+ typedef struct {
173
+ char *hostaddr; /* hostname */
174
+ char *dbname; /* data base name */
175
+ char *user; /* access user name */
176
+ int port; /* access port number */
177
+ char *password; /* password of connection */
178
+ } ConInfoTodblink;
179
+
180
+ extern RewriteQuery *rewrite_query_stmt(Node *node, POOL_CONNECTION *frontend,POOL_CONNECTION_POOL *backend,RewriteQuery *message);
181
+ extern void nodeToRewriteString(RewriteQuery *message, ConInfoTodblink *dblink,void *obj);
182
+ char *pool_error_message(char *message);
183
+ extern int IsSelectpgcatalog(Node *node,POOL_CONNECTION_POOL *backend);
184
+ extern RewriteQuery *is_parallel_query(Node *node,POOL_CONNECTION_POOL *backend);
185
+ extern POOL_STATUS pool_parallel_exec(POOL_CONNECTION *frontend,POOL_CONNECTION_POOL *backend, char *string,Node *node,bool send_to_frontend);
186
+
187
+ POOL_STATUS pool_do_parallel_query(POOL_CONNECTION *frontend,
188
+ POOL_CONNECTION_POOL *backend,
189
+ Node *node, bool *parallel, char **string, int *len);
190
+
191
+ #endif /* POOL_REWRITE_QUERY_H */
192
+
@@ -0,0 +1,1150 @@
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 <stdlib.h>
23
+ #include <string.h>
24
+ #include <unistd.h>
25
+
26
+ #include "pool.h"
27
+ #include "pool_config.h"
28
+ #include "pool_select_walker.h"
29
+ #include "pool_relcache.h"
30
+ #include "parser/parsenodes.h"
31
+ #include "pool_session_context.h"
32
+ #include "pool_timestamp.h"
33
+
34
+ static bool function_call_walker(Node *node, void *context);
35
+ static bool system_catalog_walker(Node *node, void *context);
36
+ static bool is_system_catalog(char *table_name);
37
+ static bool temp_table_walker(Node *node, void *context);
38
+ static bool relation_walker(Node *node, void *context);
39
+ static bool unlogged_table_walker(Node *node, void *context);
40
+ static bool view_walker(Node *node, void *context);
41
+ static bool is_temp_table(char *table_name);
42
+ static bool insertinto_or_locking_clause_walker(Node *node, void *context);
43
+ static bool is_immutable_function(char *fname);
44
+ static bool select_table_walker(Node *node, void *context);
45
+ static bool non_immutable_function_call_walker(Node *node, void *context);
46
+ static char *strip_quote(char *str);
47
+ static char *make_table_name_from_rangevar(RangeVar *rangevar);
48
+
49
+ /*
50
+ * Return true if this SELECT has function calls *and* supposed to
51
+ * modify database. We check black/white function list to determine
52
+ * whether the function modifies database.
53
+ */
54
+ bool pool_has_function_call(Node *node)
55
+ {
56
+ SelectContext ctx;
57
+
58
+ if (!IsA(node, SelectStmt))
59
+ return false;
60
+
61
+ ctx.has_function_call = false;
62
+
63
+ raw_expression_tree_walker(node, function_call_walker, &ctx);
64
+
65
+ return ctx.has_function_call;
66
+ }
67
+
68
+ /*
69
+ * Return true if this SELECT has system catalog table.
70
+ */
71
+ bool pool_has_system_catalog(Node *node)
72
+ {
73
+
74
+ SelectContext ctx;
75
+
76
+ if (!IsA(node, SelectStmt))
77
+ return false;
78
+
79
+ ctx.has_system_catalog = false;
80
+
81
+ raw_expression_tree_walker(node, system_catalog_walker, &ctx);
82
+
83
+ return ctx.has_system_catalog;
84
+ }
85
+
86
+ /*
87
+ * Return true if this SELECT has temporary table.
88
+ */
89
+ bool pool_has_temp_table(Node *node)
90
+ {
91
+
92
+ SelectContext ctx;
93
+
94
+ if (!IsA(node, SelectStmt))
95
+ return false;
96
+
97
+ ctx.has_temp_table = false;
98
+
99
+ raw_expression_tree_walker(node, temp_table_walker, &ctx);
100
+
101
+ return ctx.has_temp_table;
102
+ }
103
+
104
+ /*
105
+ * Return true if this SELECT has at least one FROM
106
+ */
107
+ bool pool_has_relation(Node *node)
108
+ {
109
+
110
+ SelectContext ctx;
111
+
112
+ if (!IsA(node, SelectStmt))
113
+ return false;
114
+
115
+ ctx.has_temp_table = false;
116
+
117
+ raw_expression_tree_walker(node, relation_walker, &ctx);
118
+
119
+ return ctx.has_temp_table;
120
+ }
121
+
122
+ /*
123
+ * Return true if this SELECT has unlogged table.
124
+ */
125
+ bool pool_has_unlogged_table(Node *node)
126
+ {
127
+
128
+ SelectContext ctx;
129
+
130
+ if (!IsA(node, SelectStmt))
131
+ return false;
132
+
133
+ ctx.has_unlogged_table = false;
134
+
135
+ raw_expression_tree_walker(node, unlogged_table_walker, &ctx);
136
+
137
+ return ctx.has_unlogged_table;
138
+ }
139
+
140
+ /*
141
+ * Return true if this SELECT has a view.
142
+ */
143
+ bool pool_has_view(Node *node)
144
+ {
145
+
146
+ SelectContext ctx;
147
+
148
+ if (!IsA(node, SelectStmt))
149
+ return false;
150
+
151
+ ctx.has_view = false;
152
+
153
+ raw_expression_tree_walker(node, view_walker, &ctx);
154
+
155
+ return ctx.has_view;
156
+ }
157
+
158
+ /*
159
+ * Return true if this SELECT has INSERT INTO or FOR SHARE or FOR UPDATE.
160
+ */
161
+ bool pool_has_insertinto_or_locking_clause(Node *node)
162
+ {
163
+ SelectContext ctx;
164
+
165
+ if (!IsA(node, SelectStmt))
166
+ return false;
167
+
168
+ ctx.has_insertinto_or_locking_clause = false;
169
+
170
+ raw_expression_tree_walker(node, insertinto_or_locking_clause_walker, &ctx);
171
+
172
+ pool_debug("pool_has_insertinto_or_locking_clause: returns %d",
173
+ ctx.has_insertinto_or_locking_clause);
174
+
175
+ return ctx.has_insertinto_or_locking_clause;
176
+ }
177
+
178
+ /*
179
+ * Search function name in whilelist or blacklist regex array
180
+ * Return 1 on success (found in list)
181
+ * Return 0 when not found in list
182
+ * Return -1 if the given search type doesn't exist.
183
+ * Search type supported are: WHITELIST and BLACKLIST
184
+ */
185
+ int pattern_compare(char *str, const int type, const char *param_name)
186
+ {
187
+ int i = 0;
188
+
189
+ RegPattern *lists_patterns;
190
+ int *pattc;
191
+
192
+ if (strcmp(param_name, "white_function_list") == 0 ||
193
+ strcmp(param_name, "black_function_list") == 0)
194
+ {
195
+ lists_patterns = pool_config->lists_patterns;
196
+ pattc = &pool_config->pattc;
197
+
198
+ } else if (strcmp(param_name, "white_memqcache_table_list") == 0 ||
199
+ strcmp(param_name, "black_memqcache_table_list") == 0)
200
+ {
201
+ lists_patterns = pool_config->lists_memqcache_table_patterns;
202
+ pattc = &pool_config->memqcache_table_pattc;
203
+
204
+ } else {
205
+ pool_error("pattern_compare: unknown paramname %s", param_name);
206
+ return -1;
207
+ }
208
+
209
+ for (i = 0; i < *pattc; i++) {
210
+ if (lists_patterns[i].type != type)
211
+ continue;
212
+
213
+ if (regexec(&lists_patterns[i].regexv, str, 0, 0, 0) == 0)
214
+ {
215
+ switch(type) {
216
+ /* return 1 if string matches whitelist pattern */
217
+ case WHITELIST:
218
+ pool_debug("pattern_compare: %s (%s) matched: %s",
219
+ param_name, lists_patterns[i].pattern, str);
220
+ return 1;
221
+ /* return 1 if string matches blacklist pattern */
222
+ case BLACKLIST:
223
+ pool_debug("pattern_compare: %s (%s) matched: %s",
224
+ param_name, lists_patterns[i].pattern, str);
225
+ return 1;
226
+ default:
227
+ pool_error("pattern_compare: %s unknown pattern match type: %s", param_name, str);
228
+ return -1;
229
+ }
230
+ }
231
+ pool_debug("pattern_compare: %s (%s) not matched: %s",
232
+ param_name, lists_patterns[i].pattern, str);
233
+ }
234
+
235
+ /* return 0 otherwise */
236
+ return 0;
237
+ }
238
+
239
+ /*
240
+ * Walker function to find a function call which is supposed to write
241
+ * database.
242
+ */
243
+ static bool function_call_walker(Node *node, void *context)
244
+ {
245
+ SelectContext *ctx = (SelectContext *) context;
246
+
247
+ if (node == NULL)
248
+ return false;
249
+
250
+ if (IsA(node, FuncCall))
251
+ {
252
+ FuncCall *fcall = (FuncCall *)node;
253
+ char *fname;
254
+ int length = list_length(fcall->funcname);
255
+
256
+ if (length > 0)
257
+ {
258
+ if (length == 1) /* no schema qualification? */
259
+ {
260
+ fname = strVal(linitial(fcall->funcname));
261
+ }
262
+ else
263
+ {
264
+ fname = strVal(lsecond(fcall->funcname)); /* with schema qualification */
265
+ }
266
+
267
+ pool_debug("function_call_walker: function name: %s", fname);
268
+
269
+ /*
270
+ * Check white list if any.
271
+ */
272
+ if (pool_config->num_white_function_list > 0)
273
+ {
274
+ /* Search function in the white list regex patterns */
275
+ if (pattern_compare(fname, WHITELIST, "white_function_list") == 1) {
276
+ /* If the function is found in the white list, we can ignore it */
277
+ return raw_expression_tree_walker(node, function_call_walker, context);
278
+ }
279
+ /*
280
+ * Since the function was not found in white list, we
281
+ * have found a writing function.
282
+ */
283
+ ctx->has_function_call = true;
284
+ return false;
285
+ }
286
+
287
+ /*
288
+ * Check black list if any.
289
+ */
290
+ if (pool_config->num_black_function_list > 0)
291
+ {
292
+ /* Search function in the black list regex patterns */
293
+ if (pattern_compare(fname, BLACKLIST, "black_function_list") == 1) {
294
+ /* Found. */
295
+ ctx->has_function_call = true;
296
+ return false;
297
+ }
298
+ }
299
+ }
300
+ }
301
+ return raw_expression_tree_walker(node, function_call_walker, context);
302
+ }
303
+
304
+ /*
305
+ * Walker function to find a system catalog
306
+ */
307
+ static bool
308
+ system_catalog_walker(Node *node, void *context)
309
+ {
310
+ SelectContext *ctx = (SelectContext *) context;
311
+
312
+ if (node == NULL)
313
+ return false;
314
+
315
+ if (IsA(node, RangeVar))
316
+ {
317
+ RangeVar *rgv = (RangeVar *)node;
318
+
319
+ pool_debug("system_catalog_walker: relname: %s", rgv->relname);
320
+
321
+ if (is_system_catalog(rgv->relname))
322
+ {
323
+ ctx->has_system_catalog = true;
324
+ return false;
325
+ }
326
+ }
327
+ return raw_expression_tree_walker(node, system_catalog_walker, context);
328
+ }
329
+
330
+ /*
331
+ * Walker function to find a temp table
332
+ */
333
+ static bool
334
+ temp_table_walker(Node *node, void *context)
335
+ {
336
+ SelectContext *ctx = (SelectContext *) context;
337
+
338
+ if (node == NULL)
339
+ return false;
340
+
341
+ if (IsA(node, RangeVar))
342
+ {
343
+ RangeVar *rgv = (RangeVar *)node;
344
+
345
+ pool_debug("temp_table_walker: relname: %s", rgv->relname);
346
+
347
+ if (is_temp_table(rgv->relname))
348
+ {
349
+ ctx->has_temp_table = true;
350
+ return false;
351
+ }
352
+ }
353
+ return raw_expression_tree_walker(node, temp_table_walker, context);
354
+ }
355
+
356
+ static bool
357
+ relation_walker(Node *node, void *context)
358
+ {
359
+ SelectContext *ctx = (SelectContext *) context;
360
+
361
+ if (node == NULL)
362
+ return false;
363
+
364
+ if (IsA(node, RangeVar))
365
+ {
366
+ ctx->has_temp_table = true;
367
+ return false;
368
+ }
369
+ return raw_expression_tree_walker(node, relation_walker, context);
370
+ }
371
+
372
+ /*
373
+ * Walker function to find a unlogged table
374
+ */
375
+ static bool
376
+ unlogged_table_walker(Node *node, void *context)
377
+ {
378
+ SelectContext *ctx = (SelectContext *) context;
379
+ char *relname;
380
+
381
+ if (node == NULL)
382
+ return false;
383
+
384
+ if (IsA(node, RangeVar))
385
+ {
386
+ RangeVar *rgv = (RangeVar *)node;
387
+ relname = make_table_name_from_rangevar(rgv);
388
+ pool_debug("unlogged_table_walker: relname: %s", relname);
389
+
390
+ if (is_unlogged_table(relname))
391
+ {
392
+ ctx->has_unlogged_table = true;
393
+ return false;
394
+ }
395
+ }
396
+ return raw_expression_tree_walker(node, unlogged_table_walker, context);
397
+ }
398
+
399
+ /*
400
+ * Walker function to find a view
401
+ */
402
+ static bool
403
+ view_walker(Node *node, void *context)
404
+ {
405
+ SelectContext *ctx = (SelectContext *) context;
406
+ char *relname;
407
+
408
+ if (node == NULL)
409
+ return false;
410
+
411
+ if (IsA(node, RangeVar))
412
+ {
413
+ RangeVar *rgv = (RangeVar *)node;
414
+ relname = make_table_name_from_rangevar(rgv);
415
+ pool_debug("view_walker: relname: %s", relname);
416
+
417
+ if (is_view(relname))
418
+ {
419
+ ctx->has_view = true;
420
+ return false;
421
+ }
422
+ }
423
+ return raw_expression_tree_walker(node, view_walker, context);
424
+ }
425
+
426
+ /*
427
+ * Judge the table used in a query represented by node is a system
428
+ * catalog or not.
429
+ */
430
+ static bool is_system_catalog(char *table_name)
431
+ {
432
+ /*
433
+ * Query to know if pg_namespace exists. PostgreSQL 7.2 or before doesn't have.
434
+ */
435
+ #define HASPGNAMESPACEQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s'"
436
+
437
+ /*
438
+ * Query to know if the target table belongs pg_catalog schema.
439
+ */
440
+ #define ISBELONGTOPGCATALOGQUERY "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = '%s' AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'"
441
+
442
+ #define ISBELONGTOPGCATALOGQUERY2 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.oid = pgpool_regclass('%s') AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'"
443
+
444
+ int hasreliscatalog;
445
+ bool result;
446
+ static POOL_RELCACHE *hasreliscatalog_cache;
447
+ static POOL_RELCACHE *relcache;
448
+ POOL_CONNECTION_POOL *backend;
449
+
450
+ if (table_name == NULL)
451
+ {
452
+ return false;
453
+ }
454
+
455
+ backend = pool_get_session_context()->backend;
456
+
457
+ /*
458
+ * Check if pg_namespace exists
459
+ */
460
+ if (!hasreliscatalog_cache)
461
+ {
462
+ char *query;
463
+
464
+ /* pgpool_regclass has been installed */
465
+ if (pool_has_pgpool_regclass())
466
+ {
467
+ query = ISBELONGTOPGCATALOGQUERY2;
468
+ }
469
+ else
470
+ {
471
+ query = ISBELONGTOPGCATALOGQUERY;
472
+ }
473
+
474
+ hasreliscatalog_cache = pool_create_relcache(pool_config->relcache_size, query,
475
+ int_register_func, int_unregister_func,
476
+ false);
477
+ if (hasreliscatalog_cache == NULL)
478
+ {
479
+ pool_error("is_system_catalog: pool_create_relcache error");
480
+ return false;
481
+ }
482
+ }
483
+
484
+ hasreliscatalog = pool_search_relcache(hasreliscatalog_cache, backend, "pg_namespace")==0?0:1;
485
+
486
+ if (hasreliscatalog)
487
+ {
488
+ /*
489
+ * If relcache does not exist, create it.
490
+ */
491
+ if (!relcache)
492
+ {
493
+ char *query;
494
+
495
+ /* pgpool_regclass has been installed */
496
+ if (pool_has_pgpool_regclass())
497
+ {
498
+ query = ISBELONGTOPGCATALOGQUERY2;
499
+ }
500
+ else
501
+ {
502
+ query = ISBELONGTOPGCATALOGQUERY;
503
+ }
504
+
505
+ relcache = pool_create_relcache(pool_config->relcache_size, query,
506
+ int_register_func, int_unregister_func,
507
+ false);
508
+ if (relcache == NULL)
509
+ {
510
+ pool_error("is_system_catalog: pool_create_relcache error");
511
+ return false;
512
+ }
513
+ }
514
+ /*
515
+ * Search relcache.
516
+ */
517
+ result = pool_search_relcache(relcache, backend, table_name)==0?false:true;
518
+ return result;
519
+ }
520
+
521
+ /*
522
+ * Pre 7.3. Just check whether the table starts with "pg_".
523
+ */
524
+ return (strcasecmp(table_name, "pg_") == 0);
525
+ }
526
+
527
+ /*
528
+ * Judge the table used in a query represented by node is a temporary
529
+ * table or not.
530
+ */
531
+ static POOL_RELCACHE *is_temp_table_relcache;
532
+
533
+ static bool is_temp_table(char *table_name)
534
+ {
535
+ /*
536
+ * Query to know if pg_class has relistemp column or not.
537
+ * PostgreSQL 8.4 and 9.0 have this.
538
+ */
539
+ #define HASRELITEMPPQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c, pg_attribute AS a WHERE c.relname = 'pg_class' AND a.attrelid = c.oid AND a.attname = 'relistemp'"
540
+
541
+ /*
542
+ * Query to know if the target table is a temporary one. This query
543
+ * is valid in PostgreSQL 7.3 to 8.3 and 9.1 or later. We do not use
544
+ * regclass (or its variant) here, because temporary tables never have
545
+ * schema qualified name.
546
+ */
547
+ #define ISTEMPQUERY83 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = '%s' AND c.relnamespace = n.oid AND n.nspname ~ '^pg_temp_'"
548
+
549
+ /*
550
+ * Query to know if the target table is a temporary one. This query
551
+ * is valid in PostgreSQL 8.4 and 9.0. We do not use regclass (or its
552
+ * variant) here, because temporary tables never have schema qualified
553
+ * name.
554
+ */
555
+ #define ISTEMPQUERY84 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relistemp"
556
+
557
+ int hasrelistemp;
558
+ bool result;
559
+ static POOL_RELCACHE *hasrelistemp_cache;
560
+ char *query;
561
+ POOL_CONNECTION_POOL *backend;
562
+
563
+ if (table_name == NULL)
564
+ {
565
+ return false;
566
+ }
567
+
568
+ backend = pool_get_session_context()->backend;
569
+
570
+ /*
571
+ * Check backend version
572
+ */
573
+ if (!hasrelistemp_cache)
574
+ {
575
+ hasrelistemp_cache = pool_create_relcache(pool_config->relcache_size, HASRELITEMPPQUERY,
576
+ int_register_func, int_unregister_func,
577
+ false);
578
+ if (hasrelistemp_cache == NULL)
579
+ {
580
+ pool_error("is_temp_table: pool_create_relcache error");
581
+ return false;
582
+ }
583
+ }
584
+
585
+ hasrelistemp = pool_search_relcache(hasrelistemp_cache, backend, "pg_class")==0?0:1;
586
+ if (hasrelistemp)
587
+ query = ISTEMPQUERY84;
588
+ else
589
+ query = ISTEMPQUERY83;
590
+
591
+ /*
592
+ * If relcache does not exist, create it.
593
+ */
594
+ if (!is_temp_table_relcache)
595
+ {
596
+ is_temp_table_relcache = pool_create_relcache(pool_config->relcache_size, query,
597
+ int_register_func, int_unregister_func,
598
+ true);
599
+ if (is_temp_table_relcache == NULL)
600
+ {
601
+ pool_error("is_temp_table: pool_create_relcache error");
602
+ return false;
603
+ }
604
+ }
605
+
606
+ /*
607
+ * Search relcache.
608
+ */
609
+ result = pool_search_relcache(is_temp_table_relcache, backend, table_name)==0?false:true;
610
+ return result;
611
+ }
612
+
613
+ /*
614
+ * Discard relcache used by is_temp_table_relcache().
615
+ */
616
+ void discard_temp_table_relcache(void)
617
+ {
618
+ if (is_temp_table_relcache)
619
+ {
620
+ pool_discard_relcache(is_temp_table_relcache);
621
+ is_temp_table_relcache = NULL;
622
+ }
623
+ }
624
+
625
+ /*
626
+ * Judge the table used in a query represented by node is a unlogged
627
+ * table or not.
628
+ */
629
+ bool is_unlogged_table(char *table_name)
630
+ {
631
+ /*
632
+ * Query to know if pg_class has relpersistence column or not.
633
+ * PostgreSQL 9.1 or later has this.
634
+ */
635
+ #define HASRELPERSISTENCEQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c, pg_catalog.pg_attribute AS a WHERE c.relname = 'pg_class' AND a.attrelid = c.oid AND a.attname = 'relpersistence'"
636
+
637
+ /*
638
+ * Query to know if the target table is a unlogged one. This query
639
+ * is valid in PostgreSQL 9.1 or later.
640
+ */
641
+ #define ISUNLOGGEDQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relpersistence = 'u'"
642
+
643
+ #define ISUNLOGGEDQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('%s') AND c.relpersistence = 'u'"
644
+
645
+ int hasrelpersistence;
646
+ static POOL_RELCACHE *hasrelpersistence_cache;
647
+ static POOL_RELCACHE *relcache;
648
+ POOL_CONNECTION_POOL *backend;
649
+
650
+ if (table_name == NULL)
651
+ {
652
+ return false;
653
+ }
654
+
655
+ backend = pool_get_session_context()->backend;
656
+
657
+ /*
658
+ * Check backend version
659
+ */
660
+ if (!hasrelpersistence_cache)
661
+ {
662
+ hasrelpersistence_cache = pool_create_relcache(pool_config->relcache_size, HASRELPERSISTENCEQUERY,
663
+ int_register_func, int_unregister_func,
664
+ false);
665
+ if (hasrelpersistence_cache == NULL)
666
+ {
667
+ pool_error("is_unlogged_table: pool_create_relcache error");
668
+ return false;
669
+ }
670
+ }
671
+
672
+ hasrelpersistence = pool_search_relcache(hasrelpersistence_cache, backend, "pg_class")==0?0:1;
673
+ if (hasrelpersistence)
674
+ {
675
+ bool result;
676
+ char *query;
677
+
678
+ /* pgpool_regclass has been installed */
679
+ if (pool_has_pgpool_regclass())
680
+ {
681
+ query = ISUNLOGGEDQUERY2;
682
+ }
683
+ else
684
+ {
685
+ query = ISUNLOGGEDQUERY;
686
+ }
687
+
688
+ /*
689
+ * If relcache does not exist, create it.
690
+ */
691
+ if (!relcache)
692
+ {
693
+ relcache = pool_create_relcache(pool_config->relcache_size, query,
694
+ int_register_func, int_unregister_func,
695
+ true);
696
+ if (relcache == NULL)
697
+ {
698
+ pool_error("is_unlogged_table: pool_create_relcache error");
699
+ return false;
700
+ }
701
+ }
702
+
703
+ /*
704
+ * Search relcache.
705
+ */
706
+ result = pool_search_relcache(relcache, backend, table_name)==0?false:true;
707
+ return result;
708
+ }
709
+ else
710
+ {
711
+ return false;
712
+ }
713
+ }
714
+
715
+ /*
716
+ * Judge the table used in a query is a view or not.
717
+ */
718
+ bool is_view(char *table_name)
719
+ {
720
+ /*
721
+ * Query to know if the target table is a view.
722
+ */
723
+ #define ISVIEWQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relkind = 'v'"
724
+
725
+ #define ISVIEWQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('%s') AND c.relkind = 'v'"
726
+
727
+ static POOL_RELCACHE *relcache;
728
+ POOL_CONNECTION_POOL *backend;
729
+ bool result;
730
+ char *query;
731
+
732
+ if (table_name == NULL)
733
+ {
734
+ return false;
735
+ }
736
+
737
+ backend = pool_get_session_context()->backend;
738
+
739
+ /* pgpool_regclass has been installed */
740
+ if (pool_has_pgpool_regclass())
741
+ {
742
+ query = ISVIEWQUERY2;
743
+ }
744
+ else
745
+ {
746
+ query = ISVIEWQUERY;
747
+ }
748
+
749
+ if (!relcache)
750
+ {
751
+ relcache = pool_create_relcache(pool_config->relcache_size, query,
752
+ int_register_func, int_unregister_func,
753
+ false);
754
+ if (relcache == NULL)
755
+ {
756
+ pool_error("is_view: pool_create_relcache error");
757
+ return false;
758
+ }
759
+
760
+ }
761
+
762
+ /*
763
+ * Search relcache.
764
+ */
765
+ result = pool_search_relcache(relcache, backend, table_name)==0?false:true;
766
+ return result;
767
+ }
768
+
769
+ /*
770
+ * Judge if we have pgpool_regclass or not.
771
+ */
772
+ bool pool_has_pgpool_regclass(void)
773
+ {
774
+ /*
775
+ * Query to know if pgpool_regclass exists.
776
+ */
777
+ #define HASPGPOOL_REGCLASSQUERY "SELECT count(*) from (SELECT has_function_privilege('%s', 'pgpool_regclass(cstring)', 'execute') WHERE EXISTS(SELECT * FROM pg_catalog.pg_proc AS p WHERE p.proname = 'pgpool_regclass')) AS s"
778
+
779
+ bool result;
780
+ static POOL_RELCACHE *relcache;
781
+ POOL_CONNECTION_POOL *backend;
782
+ char *user;
783
+
784
+ backend = pool_get_session_context()->backend;
785
+ user = MASTER_CONNECTION(backend)->sp->user;
786
+
787
+ if (!relcache)
788
+ {
789
+ relcache = pool_create_relcache(pool_config->relcache_size, HASPGPOOL_REGCLASSQUERY,
790
+ int_register_func, int_unregister_func,
791
+ false);
792
+ if (relcache == NULL)
793
+ {
794
+ pool_error("has_pgpool_regclass: pool_create_relcache error");
795
+ return false;
796
+ }
797
+ }
798
+
799
+ result = pool_search_relcache(relcache, backend, user)==0?0:1;
800
+ return result;
801
+ }
802
+
803
+ /*
804
+ * Walker function to find intoClause or lockingClause.
805
+ */
806
+ static bool insertinto_or_locking_clause_walker(Node *node, void *context)
807
+ {
808
+ SelectContext *ctx = (SelectContext *) context;
809
+
810
+ if (node == NULL)
811
+ return false;
812
+
813
+ if (IsA(node, IntoClause) || IsA(node, LockingClause))
814
+ {
815
+ ctx->has_insertinto_or_locking_clause = true;
816
+ return false;
817
+ }
818
+ return raw_expression_tree_walker(node, insertinto_or_locking_clause_walker, ctx);
819
+ }
820
+
821
+ /*
822
+ * Return true if this SELECT has non immutable function calls.
823
+ */
824
+ bool pool_has_non_immutable_function_call(Node *node)
825
+ {
826
+ SelectContext ctx;
827
+
828
+ if (!IsA(node, SelectStmt))
829
+ return false;
830
+
831
+ ctx.has_non_immutable_function_call = false;
832
+
833
+ raw_expression_tree_walker(node, non_immutable_function_call_walker, &ctx);
834
+
835
+ pool_debug("pool_has_non_immutable_function_call: %d", ctx.has_non_immutable_function_call);
836
+ return ctx.has_non_immutable_function_call;
837
+ }
838
+
839
+ /*
840
+ * Walker function to find non immutable function call.
841
+ */
842
+ static bool non_immutable_function_call_walker(Node *node, void *context)
843
+ {
844
+ SelectContext *ctx = (SelectContext *) context;
845
+
846
+ if (node == NULL)
847
+ return false;
848
+
849
+ if (IsA(node, FuncCall))
850
+ {
851
+ FuncCall *fcall = (FuncCall *)node;
852
+ char *fname;
853
+ int length = list_length(fcall->funcname);
854
+
855
+ if (length > 0)
856
+ {
857
+ if (length == 1) /* no schema qualification? */
858
+ {
859
+ fname = strVal(linitial(fcall->funcname));
860
+ }
861
+ else
862
+ {
863
+ fname = strVal(lsecond(fcall->funcname)); /* with schema qualification */
864
+ }
865
+
866
+ pool_debug("non_immutable_function_call_walker: function name: %s", fname);
867
+
868
+ /* Check system catalog if the function is immutable */
869
+ if (is_immutable_function(fname) == false)
870
+ {
871
+ /* Non immutable function call found */
872
+ ctx->has_non_immutable_function_call = true;
873
+ return false;
874
+ }
875
+ }
876
+ }
877
+ else if (IsA(node, TypeCast))
878
+ {
879
+ /* CURRENT_DATE, CURRENT_TIME, LOCALTIMESTAMP, LOCALTIME etc.*/
880
+ TypeCast *tc = (TypeCast *) node;
881
+
882
+ if ((isSystemType((Node *) tc->typeName, "date") ||
883
+ isSystemType((Node *) tc->typeName, "timestamp") ||
884
+ isSystemType((Node *) tc->typeName, "timestamptz") ||
885
+ isSystemType((Node *) tc->typeName, "time") ||
886
+ isSystemType((Node *) tc->typeName, "timetz")))
887
+ {
888
+ ctx->has_non_immutable_function_call = true;
889
+ return false;
890
+ }
891
+ }
892
+
893
+ return raw_expression_tree_walker(node, non_immutable_function_call_walker, context);
894
+ }
895
+
896
+ /*
897
+ * Check if the function is stable.
898
+ */
899
+ static bool is_immutable_function(char *fname)
900
+ {
901
+ /*
902
+ * Query to know if the function is IMMUTABLE
903
+ */
904
+ #define IS_STABLE_FUNCTION_QUERY "SELECT count(*) FROM pg_catalog.pg_proc AS p WHERE p.proname = '%s' AND p.provolatile = 'i'"
905
+ bool result;
906
+ static POOL_RELCACHE *relcache;
907
+ POOL_CONNECTION_POOL *backend;
908
+
909
+ backend = pool_get_session_context()->backend;
910
+
911
+ if (!relcache)
912
+ {
913
+ relcache = pool_create_relcache(pool_config->relcache_size, IS_STABLE_FUNCTION_QUERY,
914
+ int_register_func, int_unregister_func,
915
+ false);
916
+ if (relcache == NULL)
917
+ {
918
+ pool_error("is_immutable_function: pool_create_relcache error");
919
+ return false;
920
+ }
921
+ pool_debug("is_immutable_function: relcache created");
922
+ }
923
+
924
+ result = pool_search_relcache(relcache, backend, fname)==0?0:1;
925
+ pool_debug("is_immutable_function: search result:%d", result);
926
+ return result;
927
+ }
928
+
929
+ /*
930
+ * Convert table_name(possibly including schema name) to oid
931
+ */
932
+ int pool_table_name_to_oid(char *table_name)
933
+ {
934
+ /*
935
+ * Query to convert table name to oid
936
+ */
937
+ #define TABLE_TO_OID_QUERY "SELECT pgpool_regclass('%s')"
938
+ #define TABLE_TO_OID_QUERY2 "SELECT oid FROM pg_class WHERE relname = '%s'"
939
+
940
+ int oid = 0;
941
+ static POOL_RELCACHE *relcache;
942
+ POOL_CONNECTION_POOL *backend;
943
+ char *query;
944
+
945
+ if (table_name == NULL)
946
+ {
947
+ return oid;
948
+ }
949
+
950
+ backend = pool_get_session_context()->backend;
951
+
952
+ if (pool_has_pgpool_regclass())
953
+ {
954
+ query = TABLE_TO_OID_QUERY;
955
+ }
956
+ else
957
+ {
958
+ query = TABLE_TO_OID_QUERY2;
959
+ }
960
+
961
+ /*
962
+ * If relcache does not exist, create it.
963
+ */
964
+ if (!relcache)
965
+ {
966
+ relcache = pool_create_relcache(pool_config->relcache_size, query,
967
+ int_register_func, int_unregister_func,
968
+ true);
969
+ if (relcache == NULL)
970
+ {
971
+ pool_error("table_name_to_oid: pool_create_relcache error");
972
+ return oid;
973
+ }
974
+
975
+ /* Se do not cache if pgpool_regclass() returns 0, which indicates
976
+ * there's no such a table. In this case we do not want to cache the
977
+ * state because the table might be created later in this session.
978
+ */
979
+ relcache->no_cache_if_zero = true;
980
+ }
981
+
982
+ /*
983
+ * Search relcache.
984
+ */
985
+ oid = (int)(intptr_t)pool_search_relcache(relcache, backend, table_name);
986
+ return oid;
987
+ }
988
+
989
+ /*
990
+ * Extract table oids from SELECT statement. Returns number of oids.
991
+ * Oids are returned as an int array. The contents of oid array are
992
+ * discarded by next call to this function.
993
+ */
994
+ int pool_extract_table_oids_from_select_stmt(Node *node, SelectContext *ctx)
995
+ {
996
+ if (!IsA(node, SelectStmt))
997
+ return 0;
998
+
999
+ ctx->num_oids = 0;
1000
+ raw_expression_tree_walker(node, select_table_walker, ctx);
1001
+
1002
+ return ctx->num_oids;
1003
+ }
1004
+
1005
+ /*
1006
+ * Walker function to extract table oids from SELECT statement.
1007
+ */
1008
+ static bool
1009
+ select_table_walker(Node *node, void *context)
1010
+ {
1011
+ SelectContext *ctx = (SelectContext *) context;
1012
+ int num_oids;
1013
+
1014
+ if (node == NULL)
1015
+ return false;
1016
+
1017
+ if (IsA(node, RangeVar))
1018
+ {
1019
+ RangeVar *rgv = (RangeVar *)node;
1020
+ char *table;
1021
+ int oid;
1022
+ char *s;
1023
+
1024
+ table = make_table_name_from_rangevar(rgv);
1025
+ oid = pool_table_name_to_oid(table);
1026
+
1027
+ if (oid)
1028
+ {
1029
+ if (POOL_MAX_SELECT_OIDS <= ctx->num_oids)
1030
+ {
1031
+ pool_debug("select_table_walker: number of oids exceeds");
1032
+ return false;
1033
+ }
1034
+
1035
+ num_oids = ctx->num_oids++;
1036
+
1037
+ ctx->table_oids[num_oids] = oid;
1038
+ s = strip_quote(table);
1039
+ strlcpy(ctx->table_names[num_oids], s, POOL_NAMEDATALEN);
1040
+ free(s);
1041
+
1042
+ pool_debug("select_table_walker: ctx->table_names[%d] = %s",
1043
+ num_oids, ctx->table_names[num_oids]);
1044
+ }
1045
+ }
1046
+
1047
+ return raw_expression_tree_walker(node, select_table_walker, context);
1048
+ }
1049
+
1050
+ static char *strip_quote(char *str)
1051
+ {
1052
+ char *after;
1053
+ int i = 0;
1054
+
1055
+ after = malloc(sizeof(char) * strlen(str) + 1);
1056
+
1057
+ do {
1058
+ if (*str != '"')
1059
+ {
1060
+ after[i] = *str;
1061
+ i++;
1062
+ }
1063
+ str++;
1064
+ } while (*str != '\0');
1065
+
1066
+ after[i] = '\0';
1067
+
1068
+ return after;
1069
+ }
1070
+
1071
+ /*
1072
+ * makeRangeVarFromNameList
1073
+ * Utility routine to convert a qualified-name list into RangeVar form.
1074
+ *
1075
+ * Copied from backend/catalog/namespace.c
1076
+ */
1077
+ RangeVar *
1078
+ makeRangeVarFromNameList(List *names)
1079
+ {
1080
+ RangeVar *rel = makeRangeVar(NULL, NULL, -1);
1081
+
1082
+ switch (list_length(names))
1083
+ {
1084
+ case 1:
1085
+ rel->relname = strVal(linitial(names));
1086
+ break;
1087
+ case 2:
1088
+ rel->schemaname = strVal(linitial(names));
1089
+ rel->relname = strVal(lsecond(names));
1090
+ break;
1091
+ case 3:
1092
+ rel->catalogname = strVal(linitial(names));
1093
+ rel->schemaname = strVal(lsecond(names));
1094
+ rel->relname = strVal(lthird(names));
1095
+ break;
1096
+ default:
1097
+ pool_error("improper relation name (too many dotted names)");
1098
+ break;
1099
+ }
1100
+
1101
+ return rel;
1102
+ }
1103
+
1104
+ /*
1105
+ * Extract table name from RageVar. Make schema qualification name if
1106
+ * necessary. The returned table name is in static area. So next
1107
+ * call to this function will break previous result.
1108
+ */
1109
+ static char *make_table_name_from_rangevar(RangeVar *rangevar)
1110
+ {
1111
+ /*
1112
+ * Table name. Max size is calculated as follows:
1113
+ * schema name(POOL_NAMEDATALEN byte)
1114
+ * + single quote(1 byte)
1115
+ * + table name (POOL_NAMEDATALEN byte)
1116
+ * + NULL(1 byte)
1117
+ */
1118
+ static char tablename[POOL_NAMEDATALEN*2+1+1];
1119
+
1120
+ if (rangevar == NULL)
1121
+ {
1122
+ pool_error("make_table_name_from_rangevar: argument is NULL");
1123
+ return "";
1124
+ }
1125
+
1126
+ if (!IsA(rangevar, RangeVar))
1127
+ {
1128
+ pool_error("make_table_name_from_rangevar: argument is not a RangeVar (%d)",
1129
+ ((Node *)rangevar)->type);
1130
+ return "";
1131
+ }
1132
+
1133
+ *tablename = '\0';
1134
+
1135
+ if (rangevar->schemaname)
1136
+ {
1137
+ strncpy(tablename, rangevar->schemaname, POOL_NAMEDATALEN);
1138
+ strcat(tablename, ".");
1139
+ }
1140
+
1141
+ if (!rangevar->relname)
1142
+ {
1143
+ pool_error("make_table_name_from_rangevar: RangeVar->relname is NULL");
1144
+ return "";
1145
+ }
1146
+
1147
+ strncat(tablename, rangevar->relname, POOL_NAMEDATALEN);
1148
+ pool_debug("make_table_name_from_rangevar: tablename:%s", tablename);
1149
+ return tablename;
1150
+ }