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,88 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * kwlookup.c
4
+ * lexical token lookup for key words in PostgreSQL
5
+ *
6
+ * NB - this file is also used by ECPG and several frontend programs in
7
+ * src/bin/ including pg_dump and psql
8
+ *
9
+ * Portions Copyright (c) 2003-2009, PgPool Global Development Group
10
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
11
+ * Portions Copyright (c) 1994, Regents of the University of California
12
+ *
13
+ *
14
+ * IDENTIFICATION
15
+ * src/backend/parser/kwlookup.c
16
+ *
17
+ *-------------------------------------------------------------------------
18
+ */
19
+
20
+ /* use c.h so this can be built as either frontend or backend */
21
+ #include <string.h>
22
+ #include "pool_parser.h"
23
+ #include "keywords.h"
24
+
25
+ /*
26
+ * ScanKeywordLookup - see if a given word is a keyword
27
+ *
28
+ * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
29
+ *
30
+ * The match is done case-insensitively. Note that we deliberately use a
31
+ * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
32
+ * even if we are in a locale where tolower() would produce more or different
33
+ * translations. This is to conform to the SQL99 spec, which says that
34
+ * keywords are to be matched in this way even though non-keyword identifiers
35
+ * receive a different case-normalization mapping.
36
+ */
37
+ const ScanKeyword *
38
+ ScanKeywordLookup(const char *text,
39
+ const ScanKeyword *keywords,
40
+ int num_keywords)
41
+ {
42
+ int len,
43
+ i;
44
+ char word[NAMEDATALEN];
45
+ const ScanKeyword *low;
46
+ const ScanKeyword *high;
47
+
48
+ len = strlen(text);
49
+ /* We assume all keywords are shorter than NAMEDATALEN. */
50
+ if (len >= NAMEDATALEN)
51
+ return NULL;
52
+
53
+ /*
54
+ * Apply an ASCII-only downcasing. We must not use tolower() since it may
55
+ * produce the wrong translation in some locales (eg, Turkish).
56
+ */
57
+ for (i = 0; i < len; i++)
58
+ {
59
+ char ch = text[i];
60
+
61
+ if (ch >= 'A' && ch <= 'Z')
62
+ ch += 'a' - 'A';
63
+ word[i] = ch;
64
+ }
65
+ word[len] = '\0';
66
+
67
+ /*
68
+ * Now do a binary search using plain strcmp() comparison.
69
+ */
70
+ low = keywords;
71
+ high = keywords + (num_keywords - 1);
72
+ while (low <= high)
73
+ {
74
+ const ScanKeyword *middle;
75
+ int difference;
76
+
77
+ middle = low + (high - low) / 2;
78
+ difference = strcmp(middle->name, word);
79
+ if (difference == 0)
80
+ return middle;
81
+ else if (difference < 0)
82
+ low = middle + 1;
83
+ else
84
+ high = middle - 1;
85
+ }
86
+
87
+ return NULL;
88
+ }
@@ -0,0 +1,1156 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * list.c
4
+ * implementation for PostgreSQL generic linked list package
5
+ *
6
+ *
7
+ * Portions Copyright (c) 2003-2013, PgPool Global Development Group
8
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
9
+ * Portions Copyright (c) 1994, Regents of the University of California
10
+ *
11
+ *
12
+ * IDENTIFICATION
13
+ * src/backend/nodes/list.c
14
+ *
15
+ *-------------------------------------------------------------------------
16
+ */
17
+ /*#include "postgres.h"*/
18
+
19
+ #include <stdlib.h>
20
+ #include "pool_memory.h"
21
+ #include "pg_list.h"
22
+
23
+
24
+
25
+ /*
26
+ * Routines to simplify writing assertions about the type of a list; a
27
+ * NIL list is considered to be an empty list of any type.
28
+ */
29
+ #define IsPointerList(l) ((l) == NIL || IsA((l), List))
30
+ #define IsIntegerList(l) ((l) == NIL || IsA((l), IntList))
31
+ #define IsOidList(l) ((l) == NIL || IsA((l), OidList))
32
+
33
+ #define check_list_invariants(l)
34
+
35
+ /*
36
+ * Return a freshly allocated List. Since empty non-NIL lists are
37
+ * invalid, new_list() also allocates the head cell of the new list:
38
+ * the caller should be sure to fill in that cell's data.
39
+ */
40
+ static List *
41
+ new_list(NodeTag type)
42
+ {
43
+ List *new_list;
44
+ ListCell *new_head;
45
+
46
+ new_head = (ListCell *) palloc(sizeof(*new_head));
47
+ new_head->next = NULL;
48
+ /* new_head->data is left undefined! */
49
+
50
+ new_list = (List *) palloc(sizeof(*new_list));
51
+ new_list->type = type;
52
+ new_list->length = 1;
53
+ new_list->head = new_head;
54
+ new_list->tail = new_head;
55
+
56
+ return new_list;
57
+ }
58
+
59
+ /*
60
+ * Allocate a new cell and make it the head of the specified
61
+ * list. Assumes the list it is passed is non-NIL.
62
+ *
63
+ * The data in the new head cell is undefined; the caller should be
64
+ * sure to fill it in
65
+ */
66
+ static void
67
+ new_head_cell(List *list)
68
+ {
69
+ ListCell *new_head;
70
+
71
+ new_head = (ListCell *) palloc(sizeof(*new_head));
72
+ new_head->next = list->head;
73
+
74
+ list->head = new_head;
75
+ list->length++;
76
+ }
77
+
78
+ /*
79
+ * Allocate a new cell and make it the tail of the specified
80
+ * list. Assumes the list it is passed is non-NIL.
81
+ *
82
+ * The data in the new tail cell is undefined; the caller should be
83
+ * sure to fill it in
84
+ */
85
+ static void
86
+ new_tail_cell(List *list)
87
+ {
88
+ ListCell *new_tail;
89
+
90
+ new_tail = (ListCell *) palloc(sizeof(*new_tail));
91
+ new_tail->next = NULL;
92
+
93
+ list->tail->next = new_tail;
94
+ list->tail = new_tail;
95
+ list->length++;
96
+ }
97
+
98
+ /*
99
+ * Append a pointer to the list. A pointer to the modified list is
100
+ * returned. Note that this function may or may not destructively
101
+ * modify the list; callers should always use this function's return
102
+ * value, rather than continuing to use the pointer passed as the
103
+ * first argument.
104
+ */
105
+ List *
106
+ lappend(List *list, void *datum)
107
+ {
108
+ if (list == NIL)
109
+ list = new_list(T_List);
110
+ else
111
+ new_tail_cell(list);
112
+
113
+ lfirst(list->tail) = datum;
114
+ check_list_invariants(list);
115
+ return list;
116
+ }
117
+
118
+ /*
119
+ * Append an integer to the specified list. See lappend()
120
+ */
121
+ List *
122
+ lappend_int(List *list, int datum)
123
+ {
124
+ if (list == NIL)
125
+ list = new_list(T_IntList);
126
+ else
127
+ new_tail_cell(list);
128
+
129
+ lfirst_int(list->tail) = datum;
130
+ check_list_invariants(list);
131
+ return list;
132
+ }
133
+
134
+ /*
135
+ * Append an OID to the specified list. See lappend()
136
+ */
137
+ List *
138
+ lappend_oid(List *list, Oid datum)
139
+ {
140
+ if (list == NIL)
141
+ list = new_list(T_OidList);
142
+ else
143
+ new_tail_cell(list);
144
+
145
+ lfirst_oid(list->tail) = datum;
146
+ check_list_invariants(list);
147
+ return list;
148
+ }
149
+
150
+ /*
151
+ * Add a new cell to the list, in the position after 'prev_cell'. The
152
+ * data in the cell is left undefined, and must be filled in by the
153
+ * caller. 'list' is assumed to be non-NIL, and 'prev_cell' is assumed
154
+ * to be non-NULL and a member of 'list'.
155
+ */
156
+ static ListCell *
157
+ add_new_cell(List *list, ListCell *prev_cell)
158
+ {
159
+ ListCell *new_cell;
160
+
161
+ new_cell = (ListCell *) palloc(sizeof(*new_cell));
162
+ /* new_cell->data is left undefined! */
163
+ new_cell->next = prev_cell->next;
164
+ prev_cell->next = new_cell;
165
+
166
+ if (list->tail == prev_cell)
167
+ list->tail = new_cell;
168
+
169
+ list->length++;
170
+
171
+ return new_cell;
172
+ }
173
+
174
+ /*
175
+ * Add a new cell to the specified list (which must be non-NIL);
176
+ * it will be placed after the list cell 'prev' (which must be
177
+ * non-NULL and a member of 'list'). The data placed in the new cell
178
+ * is 'datum'. The newly-constructed cell is returned.
179
+ */
180
+ ListCell *
181
+ lappend_cell(List *list, ListCell *prev, void *datum)
182
+ {
183
+ ListCell *new_cell;
184
+
185
+ new_cell = add_new_cell(list, prev);
186
+ lfirst(new_cell) = datum;
187
+ check_list_invariants(list);
188
+ return new_cell;
189
+ }
190
+
191
+ ListCell *
192
+ lappend_cell_int(List *list, ListCell *prev, int datum)
193
+ {
194
+ ListCell *new_cell;
195
+
196
+ new_cell = add_new_cell(list, prev);
197
+ lfirst_int(new_cell) = datum;
198
+ check_list_invariants(list);
199
+ return new_cell;
200
+ }
201
+
202
+ ListCell *
203
+ lappend_cell_oid(List *list, ListCell *prev, Oid datum)
204
+ {
205
+ ListCell *new_cell;
206
+
207
+ new_cell = add_new_cell(list, prev);
208
+ lfirst_oid(new_cell) = datum;
209
+ check_list_invariants(list);
210
+ return new_cell;
211
+ }
212
+
213
+ /*
214
+ * Prepend a new element to the list. A pointer to the modified list
215
+ * is returned. Note that this function may or may not destructively
216
+ * modify the list; callers should always use this function's return
217
+ * value, rather than continuing to use the pointer passed as the
218
+ * second argument.
219
+ *
220
+ * Caution: before Postgres 8.0, the original List was unmodified and
221
+ * could be considered to retain its separate identity. This is no longer
222
+ * the case.
223
+ */
224
+ List *
225
+ lcons(void *datum, List *list)
226
+ {
227
+ if (list == NIL)
228
+ list = new_list(T_List);
229
+ else
230
+ new_head_cell(list);
231
+
232
+ lfirst(list->head) = datum;
233
+ check_list_invariants(list);
234
+ return list;
235
+ }
236
+
237
+ /*
238
+ * Prepend an integer to the list. See lcons()
239
+ */
240
+ List *
241
+ lcons_int(int datum, List *list)
242
+ {
243
+ if (list == NIL)
244
+ list = new_list(T_IntList);
245
+ else
246
+ new_head_cell(list);
247
+
248
+ lfirst_int(list->head) = datum;
249
+ check_list_invariants(list);
250
+ return list;
251
+ }
252
+
253
+ /*
254
+ * Prepend an OID to the list. See lcons()
255
+ */
256
+ List *
257
+ lcons_oid(Oid datum, List *list)
258
+ {
259
+ if (list == NIL)
260
+ list = new_list(T_OidList);
261
+ else
262
+ new_head_cell(list);
263
+
264
+ lfirst_oid(list->head) = datum;
265
+ check_list_invariants(list);
266
+ return list;
267
+ }
268
+
269
+ /*
270
+ * Concatenate list2 to the end of list1, and return list1. list1 is
271
+ * destructively changed. Callers should be sure to use the return
272
+ * value as the new pointer to the concatenated list: the 'list1'
273
+ * input pointer may or may not be the same as the returned pointer.
274
+ *
275
+ * The nodes in list2 are merely appended to the end of list1 in-place
276
+ * (i.e. they aren't copied; the two lists will share some of the same
277
+ * storage). Therefore, invoking list_free() on list2 will also
278
+ * invalidate a portion of list1.
279
+ */
280
+ List *
281
+ list_concat(List *list1, List *list2)
282
+ {
283
+ if (list1 == NIL)
284
+ return list2;
285
+ if (list2 == NIL)
286
+ return list1;
287
+ if (list1 == list2)
288
+ elog(ERROR, "cannot list_concat() a list to itself");
289
+
290
+ list1->length += list2->length;
291
+ list1->tail->next = list2->head;
292
+ list1->tail = list2->tail;
293
+
294
+ check_list_invariants(list1);
295
+ return list1;
296
+ }
297
+
298
+ /*
299
+ * Truncate 'list' to contain no more than 'new_size' elements. This
300
+ * modifies the list in-place! Despite this, callers should use the
301
+ * pointer returned by this function to refer to the newly truncated
302
+ * list -- it may or may not be the same as the pointer that was
303
+ * passed.
304
+ *
305
+ * Note that any cells removed by list_truncate() are NOT pfree'd.
306
+ */
307
+ List *
308
+ list_truncate(List *list, int new_size)
309
+ {
310
+ ListCell *cell;
311
+ int n;
312
+
313
+ if (new_size <= 0)
314
+ return NIL; /* truncate to zero length */
315
+
316
+ /* If asked to effectively extend the list, do nothing */
317
+ if (new_size >= list_length(list))
318
+ return list;
319
+
320
+ n = 1;
321
+ foreach(cell, list)
322
+ {
323
+ if (n == new_size)
324
+ {
325
+ cell->next = NULL;
326
+ list->tail = cell;
327
+ list->length = new_size;
328
+ check_list_invariants(list);
329
+ return list;
330
+ }
331
+ n++;
332
+ }
333
+
334
+ /* keep the compiler quiet; never reached */
335
+ return list;
336
+ }
337
+
338
+ /*
339
+ * Locate the n'th cell (counting from 0) of the list. It is an assertion
340
+ * failure if there is no such cell.
341
+ */
342
+ static ListCell *
343
+ list_nth_cell(const List *list, int n)
344
+ {
345
+ ListCell *match;
346
+
347
+ check_list_invariants(list);
348
+
349
+ /* Does the caller actually mean to fetch the tail? */
350
+ if (n == list->length - 1)
351
+ return list->tail;
352
+
353
+ for (match = list->head; n-- > 0; match = match->next)
354
+ ;
355
+
356
+ return match;
357
+ }
358
+
359
+ /*
360
+ * Return the data value contained in the n'th element of the
361
+ * specified list. (List elements begin at 0.)
362
+ */
363
+ void *
364
+ list_nth(const List *list, int n)
365
+ {
366
+ return lfirst(list_nth_cell(list, n));
367
+ }
368
+
369
+ /*
370
+ * Return the integer value contained in the n'th element of the
371
+ * specified list.
372
+ */
373
+ int
374
+ list_nth_int(const List *list, int n)
375
+ {
376
+ return lfirst_int(list_nth_cell(list, n));
377
+ }
378
+
379
+ /*
380
+ * Return the OID value contained in the n'th element of the specified
381
+ * list.
382
+ */
383
+ Oid
384
+ list_nth_oid(const List *list, int n)
385
+ {
386
+ return lfirst_oid(list_nth_cell(list, n));
387
+ }
388
+
389
+ #if 0
390
+ /*
391
+ * Return true iff 'datum' is a member of the list. Equality is
392
+ * determined via equal(), so callers should ensure that they pass a
393
+ * Node as 'datum'.
394
+ */
395
+ bool
396
+ list_member(const List *list, const void *datum)
397
+ {
398
+ const ListCell *cell;
399
+
400
+ check_list_invariants(list);
401
+
402
+ foreach(cell, list)
403
+ {
404
+ if (equal(lfirst(cell), datum))
405
+ return true;
406
+ }
407
+
408
+ return false;
409
+ }
410
+ #endif
411
+
412
+ /*
413
+ * Return true iff 'datum' is a member of the list. Equality is
414
+ * determined by using simple pointer comparison.
415
+ */
416
+ bool
417
+ list_member_ptr(const List *list, const void *datum)
418
+ {
419
+ const ListCell *cell;
420
+
421
+ check_list_invariants(list);
422
+
423
+ foreach(cell, list)
424
+ {
425
+ if (lfirst(cell) == datum)
426
+ return true;
427
+ }
428
+
429
+ return false;
430
+ }
431
+
432
+ /*
433
+ * Return true iff the integer 'datum' is a member of the list.
434
+ */
435
+ bool
436
+ list_member_int(const List *list, int datum)
437
+ {
438
+ const ListCell *cell;
439
+
440
+ check_list_invariants(list);
441
+
442
+ foreach(cell, list)
443
+ {
444
+ if (lfirst_int(cell) == datum)
445
+ return true;
446
+ }
447
+
448
+ return false;
449
+ }
450
+
451
+ /*
452
+ * Return true iff the OID 'datum' is a member of the list.
453
+ */
454
+ bool
455
+ list_member_oid(const List *list, Oid datum)
456
+ {
457
+ const ListCell *cell;
458
+
459
+ check_list_invariants(list);
460
+
461
+ foreach(cell, list)
462
+ {
463
+ if (lfirst_oid(cell) == datum)
464
+ return true;
465
+ }
466
+
467
+ return false;
468
+ }
469
+
470
+ /*
471
+ * Delete 'cell' from 'list'; 'prev' is the previous element to 'cell'
472
+ * in 'list', if any (i.e. prev == NULL iff list->head == cell)
473
+ *
474
+ * The cell is pfree'd, as is the List header if this was the last member.
475
+ */
476
+ List *
477
+ list_delete_cell(List *list, ListCell *cell, ListCell *prev)
478
+ {
479
+ check_list_invariants(list);
480
+
481
+ /*
482
+ * If we're about to delete the last node from the list, free the whole
483
+ * list instead and return NIL, which is the only valid representation of
484
+ * a zero-length list.
485
+ */
486
+ if (list->length == 1)
487
+ {
488
+ list_free(list);
489
+ return NIL;
490
+ }
491
+
492
+ /*
493
+ * Otherwise, adjust the necessary list links, deallocate the particular
494
+ * node we have just removed, and return the list we were given.
495
+ */
496
+ list->length--;
497
+
498
+ if (prev)
499
+ prev->next = cell->next;
500
+ else
501
+ list->head = cell->next;
502
+
503
+ if (list->tail == cell)
504
+ list->tail = prev;
505
+
506
+ pfree(cell);
507
+ return list;
508
+ }
509
+
510
+ #if 0
511
+ /*
512
+ * Delete the first cell in list that matches datum, if any.
513
+ * Equality is determined via equal().
514
+ */
515
+ List *
516
+ list_delete(List *list, void *datum)
517
+ {
518
+ ListCell *cell;
519
+ ListCell *prev;
520
+
521
+ check_list_invariants(list);
522
+
523
+ prev = NULL;
524
+ foreach(cell, list)
525
+ {
526
+ if (equal(lfirst(cell), datum))
527
+ return list_delete_cell(list, cell, prev);
528
+
529
+ prev = cell;
530
+ }
531
+
532
+ /* Didn't find a match: return the list unmodified */
533
+ return list;
534
+ }
535
+ #endif
536
+
537
+ /* As above, but use simple pointer equality */
538
+ List *
539
+ list_delete_ptr(List *list, void *datum)
540
+ {
541
+ ListCell *cell;
542
+ ListCell *prev;
543
+
544
+ check_list_invariants(list);
545
+
546
+ prev = NULL;
547
+ foreach(cell, list)
548
+ {
549
+ if (lfirst(cell) == datum)
550
+ return list_delete_cell(list, cell, prev);
551
+
552
+ prev = cell;
553
+ }
554
+
555
+ /* Didn't find a match: return the list unmodified */
556
+ return list;
557
+ }
558
+
559
+ /* As above, but for integers */
560
+ List *
561
+ list_delete_int(List *list, int datum)
562
+ {
563
+ ListCell *cell;
564
+ ListCell *prev;
565
+
566
+ check_list_invariants(list);
567
+
568
+ prev = NULL;
569
+ foreach(cell, list)
570
+ {
571
+ if (lfirst_int(cell) == datum)
572
+ return list_delete_cell(list, cell, prev);
573
+
574
+ prev = cell;
575
+ }
576
+
577
+ /* Didn't find a match: return the list unmodified */
578
+ return list;
579
+ }
580
+
581
+ /* As above, but for OIDs */
582
+ List *
583
+ list_delete_oid(List *list, Oid datum)
584
+ {
585
+ ListCell *cell;
586
+ ListCell *prev;
587
+
588
+ check_list_invariants(list);
589
+
590
+ prev = NULL;
591
+ foreach(cell, list)
592
+ {
593
+ if (lfirst_oid(cell) == datum)
594
+ return list_delete_cell(list, cell, prev);
595
+
596
+ prev = cell;
597
+ }
598
+
599
+ /* Didn't find a match: return the list unmodified */
600
+ return list;
601
+ }
602
+
603
+ /*
604
+ * Delete the first element of the list.
605
+ *
606
+ * This is useful to replace the Lisp-y code "list = lnext(list);" in cases
607
+ * where the intent is to alter the list rather than just traverse it.
608
+ * Beware that the removed cell is freed, whereas the lnext() coding leaves
609
+ * the original list head intact if there's another pointer to it.
610
+ */
611
+ List *
612
+ list_delete_first(List *list)
613
+ {
614
+ check_list_invariants(list);
615
+
616
+ if (list == NIL)
617
+ return NIL; /* would an error be better? */
618
+
619
+ return list_delete_cell(list, list_head(list), NULL);
620
+ }
621
+
622
+ #if 0
623
+ /*
624
+ * Generate the union of two lists. This is calculated by copying
625
+ * list1 via list_copy(), then adding to it all the members of list2
626
+ * that aren't already in list1.
627
+ *
628
+ * Whether an element is already a member of the list is determined
629
+ * via equal().
630
+ *
631
+ * The returned list is newly-allocated, although the content of the
632
+ * cells is the same (i.e. any pointed-to objects are not copied).
633
+ *
634
+ * NB: this function will NOT remove any duplicates that are present
635
+ * in list1 (so it only performs a "union" if list1 is known unique to
636
+ * start with). Also, if you are about to write "x = list_union(x, y)"
637
+ * you probably want to use list_concat_unique() instead to avoid wasting
638
+ * the list cells of the old x list.
639
+ *
640
+ * This function could probably be implemented a lot faster if it is a
641
+ * performance bottleneck.
642
+ */
643
+ List *
644
+ list_union(const List *list1, const List *list2)
645
+ {
646
+ List *result;
647
+ const ListCell *cell;
648
+
649
+ result = list_copy(list1);
650
+ foreach(cell, list2)
651
+ {
652
+ if (!list_member(result, lfirst(cell)))
653
+ result = lappend(result, lfirst(cell));
654
+ }
655
+
656
+ check_list_invariants(result);
657
+ return result;
658
+ }
659
+ #endif
660
+
661
+ /*
662
+ * This variant of list_union() determines duplicates via simple
663
+ * pointer comparison.
664
+ */
665
+ List *
666
+ list_union_ptr(const List *list1, const List *list2)
667
+ {
668
+ List *result;
669
+ const ListCell *cell;
670
+
671
+ result = list_copy(list1);
672
+ foreach(cell, list2)
673
+ {
674
+ if (!list_member_ptr(result, lfirst(cell)))
675
+ result = lappend(result, lfirst(cell));
676
+ }
677
+
678
+ check_list_invariants(result);
679
+ return result;
680
+ }
681
+
682
+ /*
683
+ * This variant of list_union() operates upon lists of integers.
684
+ */
685
+ List *
686
+ list_union_int(const List *list1, const List *list2)
687
+ {
688
+ List *result;
689
+ const ListCell *cell;
690
+
691
+ result = list_copy(list1);
692
+ foreach(cell, list2)
693
+ {
694
+ if (!list_member_int(result, lfirst_int(cell)))
695
+ result = lappend_int(result, lfirst_int(cell));
696
+ }
697
+
698
+ check_list_invariants(result);
699
+ return result;
700
+ }
701
+
702
+ /*
703
+ * This variant of list_union() operates upon lists of OIDs.
704
+ */
705
+ List *
706
+ list_union_oid(const List *list1, const List *list2)
707
+ {
708
+ List *result;
709
+ const ListCell *cell;
710
+
711
+ result = list_copy(list1);
712
+ foreach(cell, list2)
713
+ {
714
+ if (!list_member_oid(result, lfirst_oid(cell)))
715
+ result = lappend_oid(result, lfirst_oid(cell));
716
+ }
717
+
718
+ check_list_invariants(result);
719
+ return result;
720
+ }
721
+
722
+ #if 0
723
+ /*
724
+ * Return a list that contains all the cells in list1 that are not in
725
+ * list2. The returned list is freshly allocated via palloc(), but the
726
+ * cells themselves point to the same objects as the cells of the
727
+ * input lists.
728
+ *
729
+ * This variant works on lists of pointers, and determines list
730
+ * membership via equal()
731
+ */
732
+ List *
733
+ list_difference(const List *list1, const List *list2)
734
+ {
735
+ const ListCell *cell;
736
+ List *result = NIL;
737
+
738
+ if (list2 == NIL)
739
+ return list_copy(list1);
740
+
741
+ foreach(cell, list1)
742
+ {
743
+ if (!list_member(list2, lfirst(cell)))
744
+ result = lappend(result, lfirst(cell));
745
+ }
746
+
747
+ check_list_invariants(result);
748
+ return result;
749
+ }
750
+ #endif
751
+
752
+ /*
753
+ * This variant of list_difference() determines list membership via
754
+ * simple pointer equality.
755
+ */
756
+ List *
757
+ list_difference_ptr(const List *list1, const List *list2)
758
+ {
759
+ const ListCell *cell;
760
+ List *result = NIL;
761
+
762
+ if (list2 == NIL)
763
+ return list_copy(list1);
764
+
765
+ foreach(cell, list1)
766
+ {
767
+ if (!list_member_ptr(list2, lfirst(cell)))
768
+ result = lappend(result, lfirst(cell));
769
+ }
770
+
771
+ check_list_invariants(result);
772
+ return result;
773
+ }
774
+
775
+ /*
776
+ * This variant of list_difference() operates upon lists of integers.
777
+ */
778
+ List *
779
+ list_difference_int(const List *list1, const List *list2)
780
+ {
781
+ const ListCell *cell;
782
+ List *result = NIL;
783
+
784
+ if (list2 == NIL)
785
+ return list_copy(list1);
786
+
787
+ foreach(cell, list1)
788
+ {
789
+ if (!list_member_int(list2, lfirst_int(cell)))
790
+ result = lappend_int(result, lfirst_int(cell));
791
+ }
792
+
793
+ check_list_invariants(result);
794
+ return result;
795
+ }
796
+
797
+ /*
798
+ * This variant of list_difference() operates upon lists of OIDs.
799
+ */
800
+ List *
801
+ list_difference_oid(const List *list1, const List *list2)
802
+ {
803
+ const ListCell *cell;
804
+ List *result = NIL;
805
+
806
+ if (list2 == NIL)
807
+ return list_copy(list1);
808
+
809
+ foreach(cell, list1)
810
+ {
811
+ if (!list_member_oid(list2, lfirst_oid(cell)))
812
+ result = lappend_oid(result, lfirst_oid(cell));
813
+ }
814
+
815
+ check_list_invariants(result);
816
+ return result;
817
+ }
818
+
819
+ #if 0
820
+ /*
821
+ * Append datum to list, but only if it isn't already in the list.
822
+ *
823
+ * Whether an element is already a member of the list is determined
824
+ * via equal().
825
+ */
826
+ List *
827
+ list_append_unique(List *list, void *datum)
828
+ {
829
+ if (list_member(list, datum))
830
+ return list;
831
+ else
832
+ return lappend(list, datum);
833
+ }
834
+ #endif
835
+
836
+ /*
837
+ * This variant of list_append_unique() determines list membership via
838
+ * simple pointer equality.
839
+ */
840
+ List *
841
+ list_append_unique_ptr(List *list, void *datum)
842
+ {
843
+ if (list_member_ptr(list, datum))
844
+ return list;
845
+ else
846
+ return lappend(list, datum);
847
+ }
848
+
849
+ /*
850
+ * This variant of list_append_unique() operates upon lists of integers.
851
+ */
852
+ List *
853
+ list_append_unique_int(List *list, int datum)
854
+ {
855
+ if (list_member_int(list, datum))
856
+ return list;
857
+ else
858
+ return lappend_int(list, datum);
859
+ }
860
+
861
+ /*
862
+ * This variant of list_append_unique() operates upon lists of OIDs.
863
+ */
864
+ List *
865
+ list_append_unique_oid(List *list, Oid datum)
866
+ {
867
+ if (list_member_oid(list, datum))
868
+ return list;
869
+ else
870
+ return lappend_oid(list, datum);
871
+ }
872
+
873
+ #if 0
874
+ /*
875
+ * Append to list1 each member of list2 that isn't already in list1.
876
+ *
877
+ * Whether an element is already a member of the list is determined
878
+ * via equal().
879
+ *
880
+ * This is almost the same functionality as list_union(), but list1 is
881
+ * modified in-place rather than being copied. Note also that list2's cells
882
+ * are not inserted in list1, so the analogy to list_concat() isn't perfect.
883
+ */
884
+ List *
885
+ list_concat_unique(List *list1, List *list2)
886
+ {
887
+ ListCell *cell;
888
+
889
+ foreach(cell, list2)
890
+ {
891
+ if (!list_member(list1, lfirst(cell)))
892
+ list1 = lappend(list1, lfirst(cell));
893
+ }
894
+
895
+ check_list_invariants(list1);
896
+ return list1;
897
+ }
898
+ #endif
899
+
900
+ /*
901
+ * This variant of list_concat_unique() determines list membership via
902
+ * simple pointer equality.
903
+ */
904
+ List *
905
+ list_concat_unique_ptr(List *list1, List *list2)
906
+ {
907
+ ListCell *cell;
908
+
909
+ foreach(cell, list2)
910
+ {
911
+ if (!list_member_ptr(list1, lfirst(cell)))
912
+ list1 = lappend(list1, lfirst(cell));
913
+ }
914
+
915
+ check_list_invariants(list1);
916
+ return list1;
917
+ }
918
+
919
+ /*
920
+ * This variant of list_concat_unique() operates upon lists of integers.
921
+ */
922
+ List *
923
+ list_concat_unique_int(List *list1, List *list2)
924
+ {
925
+ ListCell *cell;
926
+
927
+ foreach(cell, list2)
928
+ {
929
+ if (!list_member_int(list1, lfirst_int(cell)))
930
+ list1 = lappend_int(list1, lfirst_int(cell));
931
+ }
932
+
933
+ check_list_invariants(list1);
934
+ return list1;
935
+ }
936
+
937
+ /*
938
+ * This variant of list_concat_unique() operates upon lists of OIDs.
939
+ */
940
+ List *
941
+ list_concat_unique_oid(List *list1, List *list2)
942
+ {
943
+ ListCell *cell;
944
+
945
+ foreach(cell, list2)
946
+ {
947
+ if (!list_member_oid(list1, lfirst_oid(cell)))
948
+ list1 = lappend_oid(list1, lfirst_oid(cell));
949
+ }
950
+
951
+ check_list_invariants(list1);
952
+ return list1;
953
+ }
954
+
955
+ /*
956
+ * Free all storage in a list, and optionally the pointed-to elements
957
+ */
958
+ static void
959
+ list_free_private(List *list, bool deep)
960
+ {
961
+ ListCell *cell;
962
+
963
+ check_list_invariants(list);
964
+
965
+ cell = list_head(list);
966
+ while (cell != NULL)
967
+ {
968
+ ListCell *tmp = cell;
969
+
970
+ cell = lnext(cell);
971
+ if (deep)
972
+ pfree(lfirst(tmp));
973
+ pfree(tmp);
974
+ }
975
+
976
+ if (list)
977
+ pfree(list);
978
+ }
979
+
980
+ /*
981
+ * Free all the cells of the list, as well as the list itself. Any
982
+ * objects that are pointed-to by the cells of the list are NOT
983
+ * free'd.
984
+ *
985
+ * On return, the argument to this function has been freed, so the
986
+ * caller would be wise to set it to NIL for safety's sake.
987
+ */
988
+ void
989
+ list_free(List *list)
990
+ {
991
+ list_free_private(list, false);
992
+ }
993
+
994
+ /*
995
+ * Free all the cells of the list, the list itself, and all the
996
+ * objects pointed-to by the cells of the list (each element in the
997
+ * list must contain a pointer to a palloc()'d region of memory!)
998
+ *
999
+ * On return, the argument to this function has been freed, so the
1000
+ * caller would be wise to set it to NIL for safety's sake.
1001
+ */
1002
+ void
1003
+ list_free_deep(List *list)
1004
+ {
1005
+ /*
1006
+ * A "deep" free operation only makes sense on a list of pointers.
1007
+ */
1008
+ list_free_private(list, true);
1009
+ }
1010
+
1011
+ /*
1012
+ * Return a shallow copy of the specified list.
1013
+ */
1014
+ List *
1015
+ list_copy(const List *oldlist)
1016
+ {
1017
+ List *newlist;
1018
+ ListCell *newlist_prev;
1019
+ ListCell *oldlist_cur;
1020
+
1021
+ if (oldlist == NIL)
1022
+ return NIL;
1023
+
1024
+ newlist = new_list(oldlist->type);
1025
+ newlist->length = oldlist->length;
1026
+
1027
+ /*
1028
+ * Copy over the data in the first cell; new_list() has already allocated
1029
+ * the head cell itself
1030
+ */
1031
+ newlist->head->data = oldlist->head->data;
1032
+
1033
+ newlist_prev = newlist->head;
1034
+ oldlist_cur = oldlist->head->next;
1035
+ while (oldlist_cur)
1036
+ {
1037
+ ListCell *newlist_cur;
1038
+
1039
+ newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));
1040
+ newlist_cur->data = oldlist_cur->data;
1041
+ newlist_prev->next = newlist_cur;
1042
+
1043
+ newlist_prev = newlist_cur;
1044
+ oldlist_cur = oldlist_cur->next;
1045
+ }
1046
+
1047
+ newlist_prev->next = NULL;
1048
+ newlist->tail = newlist_prev;
1049
+
1050
+ check_list_invariants(newlist);
1051
+ return newlist;
1052
+ }
1053
+
1054
+ /*
1055
+ * Return a shallow copy of the specified list, without the first N elements.
1056
+ */
1057
+ List *
1058
+ list_copy_tail(const List *oldlist, int nskip)
1059
+ {
1060
+ List *newlist;
1061
+ ListCell *newlist_prev;
1062
+ ListCell *oldlist_cur;
1063
+
1064
+ if (nskip < 0)
1065
+ nskip = 0; /* would it be better to elog? */
1066
+
1067
+ if (oldlist == NIL || nskip >= oldlist->length)
1068
+ return NIL;
1069
+
1070
+ newlist = new_list(oldlist->type);
1071
+ newlist->length = oldlist->length - nskip;
1072
+
1073
+ /*
1074
+ * Skip over the unwanted elements.
1075
+ */
1076
+ oldlist_cur = oldlist->head;
1077
+ while (nskip-- > 0)
1078
+ oldlist_cur = oldlist_cur->next;
1079
+
1080
+ /*
1081
+ * Copy over the data in the first remaining cell; new_list() has already
1082
+ * allocated the head cell itself
1083
+ */
1084
+ newlist->head->data = oldlist_cur->data;
1085
+
1086
+ newlist_prev = newlist->head;
1087
+ oldlist_cur = oldlist_cur->next;
1088
+ while (oldlist_cur)
1089
+ {
1090
+ ListCell *newlist_cur;
1091
+
1092
+ newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));
1093
+ newlist_cur->data = oldlist_cur->data;
1094
+ newlist_prev->next = newlist_cur;
1095
+
1096
+ newlist_prev = newlist_cur;
1097
+ oldlist_cur = oldlist_cur->next;
1098
+ }
1099
+
1100
+ newlist_prev->next = NULL;
1101
+ newlist->tail = newlist_prev;
1102
+
1103
+ check_list_invariants(newlist);
1104
+ return newlist;
1105
+ }
1106
+
1107
+ /*
1108
+ * When using non-GCC compilers, we can't define these as inline
1109
+ * functions in pg_list.h, so they are defined here.
1110
+ *
1111
+ * TODO: investigate supporting inlining for some non-GCC compilers.
1112
+ */
1113
+ #ifndef __GNUC__
1114
+
1115
+ ListCell *
1116
+ list_head(const List *l)
1117
+ {
1118
+ return l ? l->head : NULL;
1119
+ }
1120
+
1121
+ ListCell *
1122
+ list_tail(List *l)
1123
+ {
1124
+ return l ? l->tail : NULL;
1125
+ }
1126
+
1127
+ int
1128
+ list_length(const List *l)
1129
+ {
1130
+ return l ? l->length : 0;
1131
+ }
1132
+ #endif /* ! __GNUC__ */
1133
+
1134
+ /*
1135
+ * Temporary compatibility functions
1136
+ *
1137
+ * In order to avoid warnings for these function definitions, we need
1138
+ * to include a prototype here as well as in pg_list.h. That's because
1139
+ * we don't enable list API compatibility in list.c, so we
1140
+ * don't see the prototypes for these functions.
1141
+ */
1142
+
1143
+ /*
1144
+ * Given a list, return its length. This is merely defined for the
1145
+ * sake of backward compatibility: we can't afford to define a macro
1146
+ * called "length", so it must be a function. New code should use the
1147
+ * list_length() macro in order to avoid the overhead of a function
1148
+ * call.
1149
+ */
1150
+ int length(const List *list);
1151
+
1152
+ int
1153
+ length(const List *list)
1154
+ {
1155
+ return list_length((List *)list);
1156
+ }