prestogres 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +20 -0
- data/LICENSE +202 -0
- data/NOTICE +22 -0
- data/README.md +217 -0
- data/Rakefile +13 -0
- data/VERSION +1 -0
- data/bin/prestogres +254 -0
- data/config/pcp.conf.sample +28 -0
- data/config/pgpool.conf +678 -0
- data/config/pool_hba.conf +84 -0
- data/config/pool_passwd +0 -0
- data/config/postgresql.conf +2 -0
- data/ext/.gitignore +6 -0
- data/ext/depend +26 -0
- data/ext/extconf.rb +4 -0
- data/ext/prestogres_config.c +12 -0
- data/pgpool2/.gitignore +36 -0
- data/pgpool2/AUTHORS +4 -0
- data/pgpool2/COPYING +12 -0
- data/pgpool2/ChangeLog +1 -0
- data/pgpool2/INSTALL +1 -0
- data/pgpool2/Makefile.am +159 -0
- data/pgpool2/Makefile.in +1187 -0
- data/pgpool2/NEWS +4960 -0
- data/pgpool2/README +1 -0
- data/pgpool2/README.euc_jp +1 -0
- data/pgpool2/README.online-recovery +62 -0
- data/pgpool2/TODO +103 -0
- data/pgpool2/ac_func_accept_argtypes.m4 +85 -0
- data/pgpool2/aclocal.m4 +1088 -0
- data/pgpool2/c-compiler.m4 +134 -0
- data/pgpool2/c-library.m4 +325 -0
- data/pgpool2/child.c +2097 -0
- data/pgpool2/config.guess +1532 -0
- data/pgpool2/config.h.in +332 -0
- data/pgpool2/config.sub +1640 -0
- data/pgpool2/configure +15752 -0
- data/pgpool2/configure.in +392 -0
- data/pgpool2/depcomp +522 -0
- data/pgpool2/doc/basebackup.sh +17 -0
- data/pgpool2/doc/pgpool-de.html +4220 -0
- data/pgpool2/doc/pgpool-en.html +5738 -0
- data/pgpool2/doc/pgpool-fr.html +4118 -0
- data/pgpool2/doc/pgpool-ja.css +198 -0
- data/pgpool2/doc/pgpool-ja.html +11279 -0
- data/pgpool2/doc/pgpool-zh_cn.html +4445 -0
- data/pgpool2/doc/pgpool.css +280 -0
- data/pgpool2/doc/pgpool_remote_start +13 -0
- data/pgpool2/doc/recovery.conf.sample +117 -0
- data/pgpool2/doc/tutorial-en.html +707 -0
- data/pgpool2/doc/tutorial-ja.html +422 -0
- data/pgpool2/doc/tutorial-memqcache-en.html +325 -0
- data/pgpool2/doc/tutorial-memqcache-ja.html +370 -0
- data/pgpool2/doc/tutorial-memqcache-zh_cn.html +322 -0
- data/pgpool2/doc/tutorial-watchdog-en.html +306 -0
- data/pgpool2/doc/tutorial-watchdog-ja.html +343 -0
- data/pgpool2/doc/tutorial-watchdog-zh_cn.html +301 -0
- data/pgpool2/doc/tutorial-zh_cn.html +537 -0
- data/pgpool2/doc/watchdog.png +0 -0
- data/pgpool2/doc/wd-en.html +236 -0
- data/pgpool2/doc/wd-en.jpg +0 -0
- data/pgpool2/doc/wd-ja.html +219 -0
- data/pgpool2/doc/wd-ja.jpg +0 -0
- data/pgpool2/doc/wd-zh_cn.html +201 -0
- data/pgpool2/doc/where_to_send_queries.odg +0 -0
- data/pgpool2/doc/where_to_send_queries.pdf +0 -0
- data/pgpool2/general.m4 +166 -0
- data/pgpool2/getopt_long.c +200 -0
- data/pgpool2/getopt_long.h +44 -0
- data/pgpool2/install-sh +251 -0
- data/pgpool2/ltmain.sh +8406 -0
- data/pgpool2/m4/libtool.m4 +7360 -0
- data/pgpool2/m4/ltoptions.m4 +368 -0
- data/pgpool2/m4/ltsugar.m4 +123 -0
- data/pgpool2/m4/ltversion.m4 +23 -0
- data/pgpool2/m4/lt~obsolete.m4 +92 -0
- data/pgpool2/main.c +2971 -0
- data/pgpool2/md5.c +444 -0
- data/pgpool2/md5.h +28 -0
- data/pgpool2/missing +360 -0
- data/pgpool2/mkinstalldirs +40 -0
- data/pgpool2/parser/Makefile.am +50 -0
- data/pgpool2/parser/Makefile.in +559 -0
- data/pgpool2/parser/copyfuncs.c +3310 -0
- data/pgpool2/parser/gram.c +39100 -0
- data/pgpool2/parser/gram.h +940 -0
- data/pgpool2/parser/gram.y +13408 -0
- data/pgpool2/parser/gramparse.h +74 -0
- data/pgpool2/parser/keywords.c +32 -0
- data/pgpool2/parser/keywords.h +39 -0
- data/pgpool2/parser/kwlist.h +425 -0
- data/pgpool2/parser/kwlookup.c +88 -0
- data/pgpool2/parser/list.c +1156 -0
- data/pgpool2/parser/makefuncs.c +518 -0
- data/pgpool2/parser/makefuncs.h +83 -0
- data/pgpool2/parser/memnodes.h +79 -0
- data/pgpool2/parser/nodes.c +29 -0
- data/pgpool2/parser/nodes.h +609 -0
- data/pgpool2/parser/outfuncs.c +5790 -0
- data/pgpool2/parser/parsenodes.h +2615 -0
- data/pgpool2/parser/parser.c +262 -0
- data/pgpool2/parser/parser.h +46 -0
- data/pgpool2/parser/pg_class.h +158 -0
- data/pgpool2/parser/pg_config_manual.h +273 -0
- data/pgpool2/parser/pg_list.h +352 -0
- data/pgpool2/parser/pg_trigger.h +147 -0
- data/pgpool2/parser/pg_wchar.h +492 -0
- data/pgpool2/parser/pool_memory.c +342 -0
- data/pgpool2/parser/pool_memory.h +77 -0
- data/pgpool2/parser/pool_parser.h +222 -0
- data/pgpool2/parser/pool_string.c +121 -0
- data/pgpool2/parser/pool_string.h +37 -0
- data/pgpool2/parser/primnodes.h +1280 -0
- data/pgpool2/parser/scan.c +4094 -0
- data/pgpool2/parser/scan.l +1451 -0
- data/pgpool2/parser/scanner.h +120 -0
- data/pgpool2/parser/scansup.c +221 -0
- data/pgpool2/parser/scansup.h +28 -0
- data/pgpool2/parser/snprintf.c +1102 -0
- data/pgpool2/parser/stringinfo.c +294 -0
- data/pgpool2/parser/stringinfo.h +178 -0
- data/pgpool2/parser/value.c +78 -0
- data/pgpool2/parser/value.h +62 -0
- data/pgpool2/parser/wchar.c +2048 -0
- data/pgpool2/pcp.conf.sample +28 -0
- data/pgpool2/pcp/Makefile.am +40 -0
- data/pgpool2/pcp/Makefile.in +771 -0
- data/pgpool2/pcp/libpcp_ext.h +250 -0
- data/pgpool2/pcp/md5.c +444 -0
- data/pgpool2/pcp/md5.h +28 -0
- data/pgpool2/pcp/pcp.c +1652 -0
- data/pgpool2/pcp/pcp.h +61 -0
- data/pgpool2/pcp/pcp_attach_node.c +172 -0
- data/pgpool2/pcp/pcp_detach_node.c +185 -0
- data/pgpool2/pcp/pcp_error.c +87 -0
- data/pgpool2/pcp/pcp_node_count.c +160 -0
- data/pgpool2/pcp/pcp_node_info.c +198 -0
- data/pgpool2/pcp/pcp_pool_status.c +166 -0
- data/pgpool2/pcp/pcp_proc_count.c +166 -0
- data/pgpool2/pcp/pcp_proc_info.c +261 -0
- data/pgpool2/pcp/pcp_promote_node.c +185 -0
- data/pgpool2/pcp/pcp_recovery_node.c +172 -0
- data/pgpool2/pcp/pcp_stop_pgpool.c +179 -0
- data/pgpool2/pcp/pcp_stream.c +385 -0
- data/pgpool2/pcp/pcp_stream.h +52 -0
- data/pgpool2/pcp/pcp_systemdb_info.c +194 -0
- data/pgpool2/pcp/pcp_watchdog_info.c +211 -0
- data/pgpool2/pcp_child.c +1493 -0
- data/pgpool2/pg_md5.c +305 -0
- data/pgpool2/pgpool.8.in +121 -0
- data/pgpool2/pgpool.conf +553 -0
- data/pgpool2/pgpool.conf.sample +666 -0
- data/pgpool2/pgpool.conf.sample-master-slave +665 -0
- data/pgpool2/pgpool.conf.sample-replication +664 -0
- data/pgpool2/pgpool.conf.sample-stream +664 -0
- data/pgpool2/pgpool.spec +264 -0
- data/pgpool2/pgpool_adm/TODO +7 -0
- data/pgpool2/pgpool_adm/pgpool_adm--1.0.sql +85 -0
- data/pgpool2/pgpool_adm/pgpool_adm.c +558 -0
- data/pgpool2/pgpool_adm/pgpool_adm.control +5 -0
- data/pgpool2/pgpool_adm/pgpool_adm.h +46 -0
- data/pgpool2/pgpool_adm/pgpool_adm.sql.in +85 -0
- data/pgpool2/pool.h +655 -0
- data/pgpool2/pool_auth.c +1390 -0
- data/pgpool2/pool_config.c +5007 -0
- data/pgpool2/pool_config.h +284 -0
- data/pgpool2/pool_config.l +3281 -0
- data/pgpool2/pool_config_md5.c +29 -0
- data/pgpool2/pool_connection_pool.c +812 -0
- data/pgpool2/pool_error.c +242 -0
- data/pgpool2/pool_globals.c +27 -0
- data/pgpool2/pool_hba.c +1723 -0
- data/pgpool2/pool_hba.conf.sample +67 -0
- data/pgpool2/pool_ip.c +567 -0
- data/pgpool2/pool_ip.h +65 -0
- data/pgpool2/pool_ipc.h +38 -0
- data/pgpool2/pool_lobj.c +242 -0
- data/pgpool2/pool_lobj.h +32 -0
- data/pgpool2/pool_memqcache.c +3818 -0
- data/pgpool2/pool_memqcache.h +268 -0
- data/pgpool2/pool_params.c +163 -0
- data/pgpool2/pool_passwd.c +249 -0
- data/pgpool2/pool_passwd.h +41 -0
- data/pgpool2/pool_path.c +193 -0
- data/pgpool2/pool_path.h +81 -0
- data/pgpool2/pool_process_context.c +247 -0
- data/pgpool2/pool_process_context.h +62 -0
- data/pgpool2/pool_process_query.c +5001 -0
- data/pgpool2/pool_process_reporting.c +1671 -0
- data/pgpool2/pool_process_reporting.h +44 -0
- data/pgpool2/pool_proto2.c +671 -0
- data/pgpool2/pool_proto_modules.c +3524 -0
- data/pgpool2/pool_proto_modules.h +185 -0
- data/pgpool2/pool_query_cache.c +1020 -0
- data/pgpool2/pool_query_context.c +1871 -0
- data/pgpool2/pool_query_context.h +105 -0
- data/pgpool2/pool_relcache.c +284 -0
- data/pgpool2/pool_relcache.h +78 -0
- data/pgpool2/pool_rewrite_outfuncs.c +9060 -0
- data/pgpool2/pool_rewrite_query.c +715 -0
- data/pgpool2/pool_rewrite_query.h +192 -0
- data/pgpool2/pool_select_walker.c +1150 -0
- data/pgpool2/pool_select_walker.h +68 -0
- data/pgpool2/pool_sema.c +161 -0
- data/pgpool2/pool_session_context.c +952 -0
- data/pgpool2/pool_session_context.h +203 -0
- data/pgpool2/pool_shmem.c +185 -0
- data/pgpool2/pool_signal.c +158 -0
- data/pgpool2/pool_signal.h +61 -0
- data/pgpool2/pool_ssl.c +339 -0
- data/pgpool2/pool_stream.c +962 -0
- data/pgpool2/pool_stream.h +61 -0
- data/pgpool2/pool_system.c +659 -0
- data/pgpool2/pool_timestamp.c +1215 -0
- data/pgpool2/pool_timestamp.h +38 -0
- data/pgpool2/pool_type.h +171 -0
- data/pgpool2/pool_worker_child.c +384 -0
- data/pgpool2/ps_status.c +404 -0
- data/pgpool2/recovery.c +435 -0
- data/pgpool2/redhat/pgpool.conf.sample.patch +52 -0
- data/pgpool2/redhat/pgpool.init +201 -0
- data/pgpool2/redhat/pgpool.sysconfig +7 -0
- data/pgpool2/redhat/rpm_installer/basebackup-replication.sh +53 -0
- data/pgpool2/redhat/rpm_installer/basebackup-stream.sh +55 -0
- data/pgpool2/redhat/rpm_installer/config_for_script +17 -0
- data/pgpool2/redhat/rpm_installer/failover.sh +64 -0
- data/pgpool2/redhat/rpm_installer/getsources.sh +141 -0
- data/pgpool2/redhat/rpm_installer/install.sh +1363 -0
- data/pgpool2/redhat/rpm_installer/pgpool_recovery_pitr +47 -0
- data/pgpool2/redhat/rpm_installer/pgpool_remote_start +15 -0
- data/pgpool2/redhat/rpm_installer/recovery.conf +4 -0
- data/pgpool2/redhat/rpm_installer/uninstall.sh +57 -0
- data/pgpool2/sample/dist_def_pgbench.sql +73 -0
- data/pgpool2/sample/pgpool.pam +3 -0
- data/pgpool2/sample/pgpool_recovery +20 -0
- data/pgpool2/sample/pgpool_recovery_pitr +19 -0
- data/pgpool2/sample/pgpool_remote_start +13 -0
- data/pgpool2/sample/replicate_def_pgbench.sql +18 -0
- data/pgpool2/sql/insert_lock.sql +15 -0
- data/pgpool2/sql/pgpool-recovery/pgpool-recovery.c +280 -0
- data/pgpool2/sql/pgpool-recovery/pgpool-recovery.sql.in +19 -0
- data/pgpool2/sql/pgpool-recovery/pgpool_recovery--1.0.sql +24 -0
- data/pgpool2/sql/pgpool-recovery/pgpool_recovery.control +5 -0
- data/pgpool2/sql/pgpool-recovery/uninstall_pgpool-recovery.sql +3 -0
- data/pgpool2/sql/pgpool-regclass/pgpool-regclass.c +206 -0
- data/pgpool2/sql/pgpool-regclass/pgpool-regclass.sql.in +4 -0
- data/pgpool2/sql/pgpool-regclass/pgpool_regclass--1.0.sql +7 -0
- data/pgpool2/sql/pgpool-regclass/pgpool_regclass.control +5 -0
- data/pgpool2/sql/pgpool-regclass/uninstall_pgpool-regclass.sql +1 -0
- data/pgpool2/sql/system_db.sql +38 -0
- data/pgpool2/strlcpy.c +85 -0
- data/pgpool2/test/C/test_extended.c +98 -0
- data/pgpool2/test/jdbc/.cvsignore +2 -0
- data/pgpool2/test/jdbc/AutoCommitTest.java +45 -0
- data/pgpool2/test/jdbc/BatchTest.java +55 -0
- data/pgpool2/test/jdbc/ColumnTest.java +60 -0
- data/pgpool2/test/jdbc/CreateTempTableTest.java +48 -0
- data/pgpool2/test/jdbc/InsertTest.java +34 -0
- data/pgpool2/test/jdbc/LockTest.java +36 -0
- data/pgpool2/test/jdbc/PgpoolTest.java +75 -0
- data/pgpool2/test/jdbc/README.euc_jp +73 -0
- data/pgpool2/test/jdbc/RunTest.java +83 -0
- data/pgpool2/test/jdbc/SelectTest.java +37 -0
- data/pgpool2/test/jdbc/UpdateTest.java +32 -0
- data/pgpool2/test/jdbc/expected/CreateTempTable +1 -0
- data/pgpool2/test/jdbc/expected/autocommit +10 -0
- data/pgpool2/test/jdbc/expected/batch +1 -0
- data/pgpool2/test/jdbc/expected/column +100 -0
- data/pgpool2/test/jdbc/expected/insert +1 -0
- data/pgpool2/test/jdbc/expected/lock +100 -0
- data/pgpool2/test/jdbc/expected/select +2 -0
- data/pgpool2/test/jdbc/expected/update +1 -0
- data/pgpool2/test/jdbc/pgpool.properties +7 -0
- data/pgpool2/test/jdbc/prepare.sql +54 -0
- data/pgpool2/test/jdbc/run.sh +6 -0
- data/pgpool2/test/parser/.cvsignore +6 -0
- data/pgpool2/test/parser/README +32 -0
- data/pgpool2/test/parser/expected/copy.out +17 -0
- data/pgpool2/test/parser/expected/create.out +64 -0
- data/pgpool2/test/parser/expected/cursor.out +37 -0
- data/pgpool2/test/parser/expected/delete.out +10 -0
- data/pgpool2/test/parser/expected/drop.out +12 -0
- data/pgpool2/test/parser/expected/insert.out +13 -0
- data/pgpool2/test/parser/expected/misc.out +28 -0
- data/pgpool2/test/parser/expected/prepare.out +4 -0
- data/pgpool2/test/parser/expected/privileges.out +31 -0
- data/pgpool2/test/parser/expected/scanner.out +30 -0
- data/pgpool2/test/parser/expected/select.out +89 -0
- data/pgpool2/test/parser/expected/transaction.out +38 -0
- data/pgpool2/test/parser/expected/update.out +11 -0
- data/pgpool2/test/parser/expected/v84.out +37 -0
- data/pgpool2/test/parser/expected/v90.out +25 -0
- data/pgpool2/test/parser/expected/var.out +22 -0
- data/pgpool2/test/parser/input/alter.sql +2 -0
- data/pgpool2/test/parser/input/copy.sql +17 -0
- data/pgpool2/test/parser/input/create.sql +64 -0
- data/pgpool2/test/parser/input/cursor.sql +37 -0
- data/pgpool2/test/parser/input/delete.sql +10 -0
- data/pgpool2/test/parser/input/drop.sql +12 -0
- data/pgpool2/test/parser/input/insert.sql +13 -0
- data/pgpool2/test/parser/input/misc.sql +28 -0
- data/pgpool2/test/parser/input/prepare.sql +4 -0
- data/pgpool2/test/parser/input/privileges.sql +31 -0
- data/pgpool2/test/parser/input/scanner.sql +34 -0
- data/pgpool2/test/parser/input/select.sql +89 -0
- data/pgpool2/test/parser/input/transaction.sql +38 -0
- data/pgpool2/test/parser/input/update.sql +11 -0
- data/pgpool2/test/parser/input/v84.sql +37 -0
- data/pgpool2/test/parser/input/v90.sql +38 -0
- data/pgpool2/test/parser/input/var.sql +22 -0
- data/pgpool2/test/parser/main.c +96 -0
- data/pgpool2/test/parser/parse_schedule +16 -0
- data/pgpool2/test/parser/pool.h +13 -0
- data/pgpool2/test/parser/run-test +62 -0
- data/pgpool2/test/pdo-test/README.euc_jp +58 -0
- data/pgpool2/test/pdo-test/SQLlist/test1.sql +3 -0
- data/pgpool2/test/pdo-test/SQLlist/test2.sql +3 -0
- data/pgpool2/test/pdo-test/collections.inc +11 -0
- data/pgpool2/test/pdo-test/def.inc +7 -0
- data/pgpool2/test/pdo-test/log.txt +0 -0
- data/pgpool2/test/pdo-test/mod/database.inc +36 -0
- data/pgpool2/test/pdo-test/mod/def.inc +0 -0
- data/pgpool2/test/pdo-test/mod/errorhandler.inc +27 -0
- data/pgpool2/test/pdo-test/pdotest.php +11 -0
- data/pgpool2/test/pdo-test/regsql.inc +56 -0
- data/pgpool2/test/pgpool_setup +898 -0
- data/pgpool2/test/regression/README +39 -0
- data/pgpool2/test/regression/clean.sh +21 -0
- data/pgpool2/test/regression/libs.sh +16 -0
- data/pgpool2/test/regression/regress.sh +166 -0
- data/pgpool2/test/regression/tests/001.load_balance/test.sh +128 -0
- data/pgpool2/test/regression/tests/002.native_replication/PgTester.java +47 -0
- data/pgpool2/test/regression/tests/002.native_replication/create.sql +6 -0
- data/pgpool2/test/regression/tests/002.native_replication/test.sh +71 -0
- data/pgpool2/test/regression/tests/003.failover/expected.r +6 -0
- data/pgpool2/test/regression/tests/003.failover/expected.s +6 -0
- data/pgpool2/test/regression/tests/003.failover/test.sh +45 -0
- data/pgpool2/test/regression/tests/004.watchdog/master.conf +12 -0
- data/pgpool2/test/regression/tests/004.watchdog/standby.conf +19 -0
- data/pgpool2/test/regression/tests/004.watchdog/test.sh +52 -0
- data/pgpool2/test/regression/tests/050.bug58/test.sh +50 -0
- data/pgpool2/test/regression/tests/051.bug60/bug.sql +12 -0
- data/pgpool2/test/regression/tests/051.bug60/database-clean.sql +6 -0
- data/pgpool2/test/regression/tests/051.bug60/database-setup.sql +28 -0
- data/pgpool2/test/regression/tests/051.bug60/test.sh +79 -0
- data/pgpool2/test/regression/tests/052.do_query/test.sh +44 -0
- data/pgpool2/test/regression/tests/053.insert_lock_hangs/test.sh +81 -0
- data/pgpool2/test/regression/tests/054.postgres_fdw/test.sh +67 -0
- data/pgpool2/test/regression/tests/055.backend_all_down/test.sh +52 -0
- data/pgpool2/test/regression/tests/056.bug63/jdbctest2.java +66 -0
- data/pgpool2/test/regression/tests/056.bug63/test.sh +47 -0
- data/pgpool2/test/regression/tests/057.bug61/test.sh +40 -0
- data/pgpool2/test/regression/tests/058.bug68/jdbctest3.java +45 -0
- data/pgpool2/test/regression/tests/058.bug68/test.sh +47 -0
- data/pgpool2/test/timestamp/expected/insert.out +16 -0
- data/pgpool2/test/timestamp/expected/misc.out +3 -0
- data/pgpool2/test/timestamp/expected/update.out +6 -0
- data/pgpool2/test/timestamp/input/insert.sql +16 -0
- data/pgpool2/test/timestamp/input/misc.sql +3 -0
- data/pgpool2/test/timestamp/input/update.sql +6 -0
- data/pgpool2/test/timestamp/main.c +129 -0
- data/pgpool2/test/timestamp/parse_schedule +3 -0
- data/pgpool2/test/timestamp/run-test +69 -0
- data/pgpool2/version.h +1 -0
- data/pgpool2/watchdog/Makefile.am +17 -0
- data/pgpool2/watchdog/Makefile.in +505 -0
- data/pgpool2/watchdog/test/stab.c +266 -0
- data/pgpool2/watchdog/test/test.c +85 -0
- data/pgpool2/watchdog/test/wd_child_t.c +87 -0
- data/pgpool2/watchdog/test/wd_lifecheck_t.c +87 -0
- data/pgpool2/watchdog/test/wd_packet_t.c +87 -0
- data/pgpool2/watchdog/test/wd_ping_t.c +20 -0
- data/pgpool2/watchdog/watchdog.c +408 -0
- data/pgpool2/watchdog/watchdog.h +209 -0
- data/pgpool2/watchdog/wd_child.c +444 -0
- data/pgpool2/watchdog/wd_ext.h +123 -0
- data/pgpool2/watchdog/wd_heartbeat.c +577 -0
- data/pgpool2/watchdog/wd_if.c +216 -0
- data/pgpool2/watchdog/wd_init.c +126 -0
- data/pgpool2/watchdog/wd_interlock.c +347 -0
- data/pgpool2/watchdog/wd_lifecheck.c +512 -0
- data/pgpool2/watchdog/wd_list.c +429 -0
- data/pgpool2/watchdog/wd_packet.c +1159 -0
- data/pgpool2/watchdog/wd_ping.c +330 -0
- data/pgpool2/ylwrap +223 -0
- data/pgsql/presto_client.py +346 -0
- data/pgsql/prestogres.py +156 -0
- data/pgsql/setup_functions.sql +21 -0
- data/pgsql/setup_language.sql +3 -0
- data/prestogres.gemspec +23 -0
- metadata +496 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* -*-pgsql-c-*- */
|
|
2
|
+
/*
|
|
3
|
+
*
|
|
4
|
+
* $Header$
|
|
5
|
+
*
|
|
6
|
+
* pgpool: a language independent connection pool server for PostgreSQL
|
|
7
|
+
* written by Tatsuo Ishii
|
|
8
|
+
*
|
|
9
|
+
* Portions Copyright (c) 2003-2008, PgPool Global Development Group
|
|
10
|
+
* Portions Copyright (c) 2004, PostgreSQL Global Development Group
|
|
11
|
+
*
|
|
12
|
+
* Permission to use, copy, modify, and distribute this software and
|
|
13
|
+
* its documentation for any purpose and without fee is hereby
|
|
14
|
+
* granted, provided that the above copyright notice appear in all
|
|
15
|
+
* copies and that both that copyright notice and this permission
|
|
16
|
+
* notice appear in supporting documentation, and that the name of the
|
|
17
|
+
* author not be used in advertising or publicity pertaining to
|
|
18
|
+
* distribution of the software without specific, written prior
|
|
19
|
+
* permission. The author makes no representations about the
|
|
20
|
+
* suitability of this software for any purpose. It is provided "as
|
|
21
|
+
* is" without express or implied warranty.
|
|
22
|
+
*
|
|
23
|
+
* pool.h.: master definition header file
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
#ifndef POOL_SIGNAL_H
|
|
28
|
+
#define POOL_SIGNAL_H
|
|
29
|
+
|
|
30
|
+
/*
|
|
31
|
+
* Signal stuff. Stolen from PostgreSQL source code.
|
|
32
|
+
*/
|
|
33
|
+
#include <signal.h>
|
|
34
|
+
|
|
35
|
+
#ifdef HAVE_SIGPROCMASK
|
|
36
|
+
extern sigset_t UnBlockSig,
|
|
37
|
+
BlockSig,
|
|
38
|
+
AuthBlockSig;
|
|
39
|
+
|
|
40
|
+
#define POOL_SETMASK(mask) sigprocmask(SIG_SETMASK, mask, NULL)
|
|
41
|
+
#define POOL_SETMASK2(mask, oldmask) sigprocmask(SIG_SETMASK, mask, oldmask)
|
|
42
|
+
#else
|
|
43
|
+
extern int UnBlockSig,
|
|
44
|
+
BlockSig,
|
|
45
|
+
AuthBlockSig;
|
|
46
|
+
|
|
47
|
+
#ifndef WIN32
|
|
48
|
+
#define POOL_SETMASK(mask) sigsetmask(*((int*)(mask)))
|
|
49
|
+
#define POOL_SETMASK2(mask, oldmask) do {oldmask = POOL_SETMASK(mask)} while (0)
|
|
50
|
+
#else
|
|
51
|
+
#define POOL_SETMASK(mask) pqsigsetmask(*((int*)(mask)))
|
|
52
|
+
#define POOL_SETMASK2(mask, oldmask) do {oldmask = POOL_SETMASK(mask)} while (0)
|
|
53
|
+
int pqsigsetmask(int mask);
|
|
54
|
+
#endif
|
|
55
|
+
#endif
|
|
56
|
+
|
|
57
|
+
typedef void (*pool_sighandler_t) (int);
|
|
58
|
+
extern pool_sighandler_t pool_signal(int signo, pool_sighandler_t func);
|
|
59
|
+
extern void poolinitmask(void);
|
|
60
|
+
|
|
61
|
+
#endif /* POOL_SIGNAL_H */
|
data/pgpool2/pool_ssl.c
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
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
|
+
* pool_ssl.c: ssl negotiation functions
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
#include <string.h>
|
|
26
|
+
|
|
27
|
+
#include "config.h"
|
|
28
|
+
#include "pool.h"
|
|
29
|
+
#include "pool_stream.h"
|
|
30
|
+
#include "pool_config.h"
|
|
31
|
+
|
|
32
|
+
#ifdef USE_SSL
|
|
33
|
+
|
|
34
|
+
#define SSL_RETURN_VOID_IF(cond, msg) \
|
|
35
|
+
do { \
|
|
36
|
+
if ( (cond) ) { \
|
|
37
|
+
perror_ssl( (msg) ); \
|
|
38
|
+
return; \
|
|
39
|
+
} \
|
|
40
|
+
} while (0);
|
|
41
|
+
|
|
42
|
+
#define SSL_RETURN_ERROR_IF(cond, msg) \
|
|
43
|
+
do { \
|
|
44
|
+
if ( (cond) ) { \
|
|
45
|
+
perror_ssl( (msg) ); \
|
|
46
|
+
return -1; \
|
|
47
|
+
} \
|
|
48
|
+
} while (0);
|
|
49
|
+
|
|
50
|
+
#include <arpa/inet.h> /* for htonl() */
|
|
51
|
+
|
|
52
|
+
/* Major/minor codes to negotiate SSL prior to startup packet */
|
|
53
|
+
#define NEGOTIATE_SSL_CODE ( 1234<<16 | 5679 )
|
|
54
|
+
|
|
55
|
+
/* enum flag for differentiating server->client vs client->server SSL */
|
|
56
|
+
enum ssl_conn_type { ssl_conn_clientserver, ssl_conn_serverclient };
|
|
57
|
+
|
|
58
|
+
/* perform per-connection ssl initialization. returns nonzero on error */
|
|
59
|
+
static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype);
|
|
60
|
+
|
|
61
|
+
/* OpenSSL error message */
|
|
62
|
+
static void perror_ssl(const char *context);
|
|
63
|
+
|
|
64
|
+
/* attempt to negotiate a secure connection */
|
|
65
|
+
void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) {
|
|
66
|
+
int ssl_packet[2] = { htonl(sizeof(int)*2), htonl(NEGOTIATE_SSL_CODE) };
|
|
67
|
+
char server_response;
|
|
68
|
+
|
|
69
|
+
cp->ssl_active = -1;
|
|
70
|
+
|
|
71
|
+
if ( (!pool_config->ssl) || init_ssl_ctx(cp, ssl_conn_clientserver))
|
|
72
|
+
return;
|
|
73
|
+
|
|
74
|
+
pool_debug("pool_ssl: sending client->server SSL request");
|
|
75
|
+
pool_write_and_flush(cp, ssl_packet, sizeof(int)*2);
|
|
76
|
+
|
|
77
|
+
if (pool_read(cp, &server_response, 1) < 0)
|
|
78
|
+
{
|
|
79
|
+
pool_error("pool_ssl_negotiate_clientserver: pool_read failed");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
pool_debug("pool_ssl: client->server SSL response: %c", server_response);
|
|
84
|
+
|
|
85
|
+
switch (server_response) {
|
|
86
|
+
case 'S':
|
|
87
|
+
SSL_set_fd(cp->ssl, cp->fd);
|
|
88
|
+
SSL_RETURN_VOID_IF( (SSL_connect(cp->ssl) < 0),
|
|
89
|
+
"SSL_connect");
|
|
90
|
+
cp->ssl_active = 1;
|
|
91
|
+
break;
|
|
92
|
+
case 'N':
|
|
93
|
+
/*
|
|
94
|
+
* If backend does not support SSL but pgpool does, we get this.
|
|
95
|
+
* i.e. This is normal.
|
|
96
|
+
*/
|
|
97
|
+
pool_debug("pool_ssl: server doesn't want to talk SSL");
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
pool_error("pool_ssl: unhandled response: %c", server_response);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
/* attempt to negotiate a secure connection */
|
|
107
|
+
void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp) {
|
|
108
|
+
|
|
109
|
+
cp->ssl_active = -1;
|
|
110
|
+
|
|
111
|
+
if ( (!pool_config->ssl) || init_ssl_ctx(cp, ssl_conn_serverclient)) {
|
|
112
|
+
/* write back an "SSL reject" response before returning */
|
|
113
|
+
pool_write_and_flush(cp, "N", 1);
|
|
114
|
+
} else {
|
|
115
|
+
/* write back an "SSL accept" response */
|
|
116
|
+
pool_write_and_flush(cp, "S", 1);
|
|
117
|
+
|
|
118
|
+
SSL_set_fd(cp->ssl, cp->fd);
|
|
119
|
+
SSL_RETURN_VOID_IF( (SSL_accept(cp->ssl) < 0), "SSL_accept");
|
|
120
|
+
cp->ssl_active = 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
void pool_ssl_close(POOL_CONNECTION *cp) {
|
|
125
|
+
if (cp->ssl) {
|
|
126
|
+
SSL_shutdown(cp->ssl);
|
|
127
|
+
SSL_free(cp->ssl);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (cp->ssl_ctx)
|
|
131
|
+
SSL_CTX_free(cp->ssl_ctx);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size) {
|
|
135
|
+
int n;
|
|
136
|
+
int err;
|
|
137
|
+
|
|
138
|
+
retry:
|
|
139
|
+
errno = 0;
|
|
140
|
+
n = SSL_read(cp->ssl, buf, size);
|
|
141
|
+
err = SSL_get_error(cp->ssl, n);
|
|
142
|
+
|
|
143
|
+
switch (err)
|
|
144
|
+
{
|
|
145
|
+
case SSL_ERROR_NONE:
|
|
146
|
+
break;
|
|
147
|
+
case SSL_ERROR_WANT_READ:
|
|
148
|
+
case SSL_ERROR_WANT_WRITE:
|
|
149
|
+
|
|
150
|
+
/*
|
|
151
|
+
* Returning 0 here would cause caller to wait for read-ready,
|
|
152
|
+
* which is not correct since what SSL wants is wait for
|
|
153
|
+
* write-ready. The former could get us stuck in an infinite
|
|
154
|
+
* wait, so don't risk it; busy-loop instead.
|
|
155
|
+
*/
|
|
156
|
+
goto retry;
|
|
157
|
+
|
|
158
|
+
case SSL_ERROR_SYSCALL:
|
|
159
|
+
if (n == -1)
|
|
160
|
+
{
|
|
161
|
+
pool_error("SSL_read error: %d", err);
|
|
162
|
+
}
|
|
163
|
+
else
|
|
164
|
+
{
|
|
165
|
+
pool_error("SSL_read error: EOF detected");
|
|
166
|
+
n = -1;
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
|
|
170
|
+
case SSL_ERROR_SSL:
|
|
171
|
+
case SSL_ERROR_ZERO_RETURN:
|
|
172
|
+
perror_ssl("SSL_read");
|
|
173
|
+
n = -1;
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
pool_error("pool_ssl_read: unrecognized error code: %d", err);
|
|
177
|
+
/*
|
|
178
|
+
* We assume that the connection is broken. Returns 0
|
|
179
|
+
* rather than -1 in this case because -1 triggers
|
|
180
|
+
* unwanted failover in the caller (pool_read).
|
|
181
|
+
*/
|
|
182
|
+
n = 0;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return n;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size)
|
|
190
|
+
{
|
|
191
|
+
int n;
|
|
192
|
+
int err;
|
|
193
|
+
|
|
194
|
+
retry:
|
|
195
|
+
errno = 0;
|
|
196
|
+
n = SSL_write(cp->ssl, buf, size);
|
|
197
|
+
err = SSL_get_error(cp->ssl, n);
|
|
198
|
+
switch (err)
|
|
199
|
+
{
|
|
200
|
+
case SSL_ERROR_NONE:
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
case SSL_ERROR_WANT_READ:
|
|
204
|
+
case SSL_ERROR_WANT_WRITE:
|
|
205
|
+
goto retry;
|
|
206
|
+
|
|
207
|
+
case SSL_ERROR_SYSCALL:
|
|
208
|
+
if (n == -1)
|
|
209
|
+
{
|
|
210
|
+
pool_error("SSL_write error: %d", err);
|
|
211
|
+
}
|
|
212
|
+
else
|
|
213
|
+
{
|
|
214
|
+
pool_error("SSL_write error: EOF detected");
|
|
215
|
+
n = -1;
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
|
|
219
|
+
case SSL_ERROR_SSL:
|
|
220
|
+
case SSL_ERROR_ZERO_RETURN:
|
|
221
|
+
perror_ssl("SSL_write");
|
|
222
|
+
n = -1;
|
|
223
|
+
break;
|
|
224
|
+
|
|
225
|
+
default:
|
|
226
|
+
pool_error("pool_ssl_write: unrecognized error code: %d", err);
|
|
227
|
+
/*
|
|
228
|
+
* We assume that the connection is broken.
|
|
229
|
+
*/
|
|
230
|
+
n = -1;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
return n;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype) {
|
|
237
|
+
int error = 0;
|
|
238
|
+
char *cacert = NULL, *cacert_dir = NULL;
|
|
239
|
+
|
|
240
|
+
/* initialize SSL members */
|
|
241
|
+
cp->ssl_ctx = SSL_CTX_new(TLSv1_method());
|
|
242
|
+
SSL_RETURN_ERROR_IF( (! cp->ssl_ctx), "SSL_CTX_new" );
|
|
243
|
+
|
|
244
|
+
if ( conntype == ssl_conn_serverclient) {
|
|
245
|
+
error = SSL_CTX_use_certificate_file(cp->ssl_ctx,
|
|
246
|
+
pool_config->ssl_cert,
|
|
247
|
+
SSL_FILETYPE_PEM);
|
|
248
|
+
SSL_RETURN_ERROR_IF( (error <= 0), "Loading SSL certificate");
|
|
249
|
+
|
|
250
|
+
error = SSL_CTX_use_PrivateKey_file(cp->ssl_ctx,
|
|
251
|
+
pool_config->ssl_key,
|
|
252
|
+
SSL_FILETYPE_PEM);
|
|
253
|
+
SSL_RETURN_ERROR_IF( (error <= 0), "Loading SSL private key");
|
|
254
|
+
} else {
|
|
255
|
+
/* set extra verification if ssl_ca_cert or ssl_ca_cert_dir are set */
|
|
256
|
+
if (strlen(pool_config->ssl_ca_cert))
|
|
257
|
+
cacert = pool_config->ssl_ca_cert;
|
|
258
|
+
if (strlen(pool_config->ssl_ca_cert_dir))
|
|
259
|
+
cacert_dir = pool_config->ssl_ca_cert_dir;
|
|
260
|
+
|
|
261
|
+
if ( cacert || cacert_dir ) {
|
|
262
|
+
error = (!SSL_CTX_load_verify_locations(cp->ssl_ctx,
|
|
263
|
+
cacert,
|
|
264
|
+
cacert_dir));
|
|
265
|
+
SSL_RETURN_ERROR_IF(error, "SSL verification setup");
|
|
266
|
+
SSL_CTX_set_verify(cp->ssl_ctx, SSL_VERIFY_PEER, NULL);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
cp->ssl = SSL_new(cp->ssl_ctx);
|
|
271
|
+
SSL_RETURN_ERROR_IF( (! cp->ssl), "SSL_new");
|
|
272
|
+
|
|
273
|
+
return 0;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
static void perror_ssl(const char *context) {
|
|
277
|
+
unsigned long err;
|
|
278
|
+
static const char *no_err_reason = "no SSL error reported";
|
|
279
|
+
const char *reason;
|
|
280
|
+
|
|
281
|
+
err = ERR_get_error();
|
|
282
|
+
if (! err) {
|
|
283
|
+
reason = no_err_reason;
|
|
284
|
+
} else {
|
|
285
|
+
reason = ERR_reason_error_string(err);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (reason != NULL) {
|
|
289
|
+
pool_error("pool_ssl: %s: %s", context, reason);
|
|
290
|
+
} else {
|
|
291
|
+
pool_error("pool_ssl: %s: Unknown SSL error %lu", context, err);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/*
|
|
296
|
+
* Return true if SSL layer has any pending data in buffer
|
|
297
|
+
*/
|
|
298
|
+
bool pool_ssl_pending(POOL_CONNECTION *cp)
|
|
299
|
+
{
|
|
300
|
+
if (cp->ssl_active > 0 && SSL_pending(cp->ssl) > 0)
|
|
301
|
+
return true;
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
#else /* USE_SSL: wrap / no-op ssl functionality if it's not available */
|
|
306
|
+
|
|
307
|
+
void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp) {
|
|
308
|
+
pool_debug("pool_ssl: SSL requested but SSL support is not available");
|
|
309
|
+
pool_write_and_flush(cp, "N", 1);
|
|
310
|
+
cp->ssl_active = -1;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) {
|
|
314
|
+
pool_debug("pool_ssl: SSL requested but SSL support is not available");
|
|
315
|
+
cp->ssl_active = -1;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
void pool_ssl_close(POOL_CONNECTION *cp) { return; }
|
|
319
|
+
|
|
320
|
+
int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size) {
|
|
321
|
+
pool_error("pool_ssl: SSL i/o called but SSL support is not available");
|
|
322
|
+
notice_backend_error(cp->db_node_id);
|
|
323
|
+
child_exit(1);
|
|
324
|
+
return -1; /* never reached */
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size) {
|
|
328
|
+
pool_error("pool_ssl: SSL i/o called but SSL support is not available");
|
|
329
|
+
notice_backend_error(cp->db_node_id);
|
|
330
|
+
child_exit(1);
|
|
331
|
+
return -1; /* never reached */
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
bool pool_ssl_pending(POOL_CONNECTION *cp)
|
|
335
|
+
{
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
#endif /* USE_SSL */
|
|
@@ -0,0 +1,962 @@
|
|
|
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
|
+
* pool_stream.c: stream I/O modules
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
#include "config.h"
|
|
26
|
+
|
|
27
|
+
#ifdef HAVE_SYS_SELECT_H
|
|
28
|
+
#include <sys/select.h>
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
#include <stdio.h>
|
|
32
|
+
#include <stdlib.h>
|
|
33
|
+
#include <string.h>
|
|
34
|
+
#include <errno.h>
|
|
35
|
+
#include <unistd.h>
|
|
36
|
+
|
|
37
|
+
#ifdef HAVE_FCNTL_H
|
|
38
|
+
#include <fcntl.h>
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
#include "pool.h"
|
|
42
|
+
#include "pool_stream.h"
|
|
43
|
+
#include "pool_config.h"
|
|
44
|
+
|
|
45
|
+
static int mystrlen(char *str, int upper, int *flag);
|
|
46
|
+
static int mystrlinelen(char *str, int upper, int *flag);
|
|
47
|
+
static int save_pending_data(POOL_CONNECTION *cp, void *data, int len);
|
|
48
|
+
static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len);
|
|
49
|
+
|
|
50
|
+
/*
|
|
51
|
+
* open read/write file descriptors.
|
|
52
|
+
* returns POOL_CONNECTION on success otherwise NULL.
|
|
53
|
+
*/
|
|
54
|
+
POOL_CONNECTION *pool_open(int fd)
|
|
55
|
+
{
|
|
56
|
+
POOL_CONNECTION *cp;
|
|
57
|
+
|
|
58
|
+
cp = (POOL_CONNECTION *)malloc(sizeof(POOL_CONNECTION));
|
|
59
|
+
if (cp == NULL)
|
|
60
|
+
{
|
|
61
|
+
pool_error("pool_open: malloc failed: %s", strerror(errno));
|
|
62
|
+
return NULL;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
memset(cp, 0, sizeof(*cp));
|
|
66
|
+
|
|
67
|
+
/* initialize write buffer */
|
|
68
|
+
cp->wbuf = malloc(WRITEBUFSZ);
|
|
69
|
+
if (cp->wbuf == NULL)
|
|
70
|
+
{
|
|
71
|
+
pool_error("pool_open: malloc failed");
|
|
72
|
+
return NULL;
|
|
73
|
+
}
|
|
74
|
+
cp->wbufsz = WRITEBUFSZ;
|
|
75
|
+
cp->wbufpo = 0;
|
|
76
|
+
|
|
77
|
+
/* initialize pending data buffer */
|
|
78
|
+
cp->hp = malloc(READBUFSZ);
|
|
79
|
+
if (cp->hp == NULL)
|
|
80
|
+
{
|
|
81
|
+
pool_error("pool_open: malloc failed");
|
|
82
|
+
free(cp);
|
|
83
|
+
return NULL;
|
|
84
|
+
}
|
|
85
|
+
cp->bufsz = READBUFSZ;
|
|
86
|
+
cp->po = 0;
|
|
87
|
+
cp->len = 0;
|
|
88
|
+
cp->sbuf = NULL;
|
|
89
|
+
cp->sbufsz = 0;
|
|
90
|
+
cp->buf2 = NULL;
|
|
91
|
+
cp->bufsz2 = 0;
|
|
92
|
+
|
|
93
|
+
cp->fd = fd;
|
|
94
|
+
return cp;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/*
|
|
98
|
+
* close read/write file descriptors.
|
|
99
|
+
*/
|
|
100
|
+
void pool_close(POOL_CONNECTION *cp)
|
|
101
|
+
{
|
|
102
|
+
/*
|
|
103
|
+
* shutdown connection to the client so that pgpool is not blocked
|
|
104
|
+
*/
|
|
105
|
+
if (!cp->isbackend)
|
|
106
|
+
shutdown(cp->fd, 1);
|
|
107
|
+
close(cp->fd);
|
|
108
|
+
|
|
109
|
+
free(cp->wbuf);
|
|
110
|
+
free(cp->hp);
|
|
111
|
+
if (cp->sbuf)
|
|
112
|
+
free(cp->sbuf);
|
|
113
|
+
if (cp->buf2)
|
|
114
|
+
free(cp->buf2);
|
|
115
|
+
pool_discard_params(&cp->params);
|
|
116
|
+
|
|
117
|
+
pool_ssl_close(cp);
|
|
118
|
+
|
|
119
|
+
free(cp);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/*
|
|
123
|
+
* read len bytes from cp
|
|
124
|
+
* returns 0 on success otherwise -1.
|
|
125
|
+
*/
|
|
126
|
+
int pool_read(POOL_CONNECTION *cp, void *buf, int len)
|
|
127
|
+
{
|
|
128
|
+
static char readbuf[READBUFSZ];
|
|
129
|
+
|
|
130
|
+
int consume_size;
|
|
131
|
+
int readlen;
|
|
132
|
+
|
|
133
|
+
consume_size = consume_pending_data(cp, buf, len);
|
|
134
|
+
len -= consume_size;
|
|
135
|
+
buf += consume_size;
|
|
136
|
+
|
|
137
|
+
while (len > 0)
|
|
138
|
+
{
|
|
139
|
+
if (pool_check_fd(cp))
|
|
140
|
+
{
|
|
141
|
+
if (!IS_MASTER_NODE_ID(cp->db_node_id) && (getpid() != mypid))
|
|
142
|
+
{
|
|
143
|
+
pool_log("pool_read: data is not ready in DB node: %d. abort this session",
|
|
144
|
+
cp->db_node_id);
|
|
145
|
+
exit(1);
|
|
146
|
+
}
|
|
147
|
+
else
|
|
148
|
+
{
|
|
149
|
+
pool_error("pool_read: pool_check_fd failed (%s)", strerror(errno));
|
|
150
|
+
return -1;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (cp->ssl_active > 0) {
|
|
155
|
+
readlen = pool_ssl_read(cp, readbuf, READBUFSZ);
|
|
156
|
+
} else {
|
|
157
|
+
readlen = read(cp->fd, readbuf, READBUFSZ);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (readlen == -1)
|
|
161
|
+
{
|
|
162
|
+
if (errno == EINTR || errno == EAGAIN)
|
|
163
|
+
{
|
|
164
|
+
pool_debug("pool_read: retrying due to %s", strerror(errno));
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
pool_error("pool_read: read failed (%s)", strerror(errno));
|
|
169
|
+
|
|
170
|
+
if (cp->isbackend)
|
|
171
|
+
{
|
|
172
|
+
/* if fail_over_on_backend_error is true, then trigger failover */
|
|
173
|
+
if (pool_config->fail_over_on_backend_error)
|
|
174
|
+
{
|
|
175
|
+
notice_backend_error(cp->db_node_id);
|
|
176
|
+
child_exit(1);
|
|
177
|
+
pool_log("pool_read: do not failover because I am the main process");
|
|
178
|
+
return -1;
|
|
179
|
+
}
|
|
180
|
+
else
|
|
181
|
+
{
|
|
182
|
+
pool_log("pool_read: do not failover because fail_over_on_backend_error is off");
|
|
183
|
+
return -1;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else
|
|
187
|
+
{
|
|
188
|
+
return -1;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else if (readlen == 0)
|
|
192
|
+
{
|
|
193
|
+
if (cp->isbackend)
|
|
194
|
+
{
|
|
195
|
+
pool_error("pool_read: EOF encountered with backend");
|
|
196
|
+
return -1;
|
|
197
|
+
|
|
198
|
+
#ifdef NOT_USED
|
|
199
|
+
/* fatal error, notice to parent and exit */
|
|
200
|
+
notice_backend_error(IS_MASTER_NODE_ID(cp->db_node_id));
|
|
201
|
+
child_exit(1);
|
|
202
|
+
#endif
|
|
203
|
+
}
|
|
204
|
+
else
|
|
205
|
+
{
|
|
206
|
+
/*
|
|
207
|
+
* if backend offers authentication method, frontend could close connection
|
|
208
|
+
*/
|
|
209
|
+
return -1;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (len < readlen)
|
|
214
|
+
{
|
|
215
|
+
/* overrun. we need to save remaining data to pending buffer */
|
|
216
|
+
if (save_pending_data(cp, readbuf+len, readlen-len))
|
|
217
|
+
return -1;
|
|
218
|
+
memmove(buf, readbuf, len);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
memmove(buf, readbuf, readlen);
|
|
223
|
+
buf += readlen;
|
|
224
|
+
len -= readlen;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/*
|
|
231
|
+
* read exactly len bytes from cp
|
|
232
|
+
* returns buffer address on success otherwise NULL.
|
|
233
|
+
*/
|
|
234
|
+
char *pool_read2(POOL_CONNECTION *cp, int len)
|
|
235
|
+
{
|
|
236
|
+
char *buf;
|
|
237
|
+
int req_size;
|
|
238
|
+
int alloc_size;
|
|
239
|
+
int consume_size;
|
|
240
|
+
int readlen;
|
|
241
|
+
|
|
242
|
+
req_size = cp->len + len;
|
|
243
|
+
|
|
244
|
+
if (req_size > cp->bufsz2)
|
|
245
|
+
{
|
|
246
|
+
alloc_size = ((req_size+1)/READBUFSZ+1)*READBUFSZ;
|
|
247
|
+
cp->buf2 = realloc(cp->buf2, alloc_size);
|
|
248
|
+
if (cp->buf2 == NULL)
|
|
249
|
+
{
|
|
250
|
+
pool_error("pool_read2: failed to realloc");
|
|
251
|
+
exit(1);
|
|
252
|
+
}
|
|
253
|
+
cp->bufsz2 = alloc_size;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
buf = cp->buf2;
|
|
257
|
+
|
|
258
|
+
consume_size = consume_pending_data(cp, buf, len);
|
|
259
|
+
len -= consume_size;
|
|
260
|
+
buf += consume_size;
|
|
261
|
+
|
|
262
|
+
while (len > 0)
|
|
263
|
+
{
|
|
264
|
+
if (pool_check_fd(cp))
|
|
265
|
+
{
|
|
266
|
+
if (!IS_MASTER_NODE_ID(cp->db_node_id))
|
|
267
|
+
{
|
|
268
|
+
pool_log("pool_read2: data is not ready in DB node:%d. abort this session",
|
|
269
|
+
cp->db_node_id);
|
|
270
|
+
exit(1);
|
|
271
|
+
}
|
|
272
|
+
else
|
|
273
|
+
{
|
|
274
|
+
pool_error("pool_read2: pool_check_fd failed (%s)", strerror(errno));
|
|
275
|
+
return NULL;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (cp->ssl_active > 0) {
|
|
280
|
+
readlen = pool_ssl_read(cp, buf, len);
|
|
281
|
+
} else {
|
|
282
|
+
readlen = read(cp->fd, buf, len);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (readlen == -1)
|
|
286
|
+
{
|
|
287
|
+
if (errno == EINTR || errno == EAGAIN)
|
|
288
|
+
{
|
|
289
|
+
pool_debug("pool_read2: retrying due to %s", strerror(errno));
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
pool_error("pool_read2: read failed (%s)", strerror(errno));
|
|
294
|
+
|
|
295
|
+
if (cp->isbackend)
|
|
296
|
+
{
|
|
297
|
+
/* if fail_over_on_backend_error is true, then trigger failover */
|
|
298
|
+
if (pool_config->fail_over_on_backend_error)
|
|
299
|
+
{
|
|
300
|
+
notice_backend_error(cp->db_node_id);
|
|
301
|
+
child_exit(1);
|
|
302
|
+
pool_log("pool_read2: do not failover because I am the main process");
|
|
303
|
+
return NULL;
|
|
304
|
+
}
|
|
305
|
+
else
|
|
306
|
+
{
|
|
307
|
+
pool_log("pool_read2: do not failover because fail_over_on_backend_error is off");
|
|
308
|
+
return NULL;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else
|
|
312
|
+
{
|
|
313
|
+
return NULL;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
else if (readlen == 0)
|
|
317
|
+
{
|
|
318
|
+
if (cp->isbackend)
|
|
319
|
+
{
|
|
320
|
+
pool_error("pool_read2: EOF encountered with backend");
|
|
321
|
+
return NULL;
|
|
322
|
+
|
|
323
|
+
#ifdef NOT_USED
|
|
324
|
+
/* fatal error, notice to parent and exit */
|
|
325
|
+
notice_backend_error(IS_MASTER_NODE_ID(cp->db_node_id));
|
|
326
|
+
child_exit(1);
|
|
327
|
+
#endif
|
|
328
|
+
}
|
|
329
|
+
else
|
|
330
|
+
{
|
|
331
|
+
/*
|
|
332
|
+
* if backend offers authentication method, frontend could close connection
|
|
333
|
+
*/
|
|
334
|
+
return NULL;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
buf += readlen;
|
|
339
|
+
len -= readlen;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return cp->buf2;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/*
|
|
346
|
+
* write len bytes to cp the write buffer.
|
|
347
|
+
* returns 0 on success otherwise -1.
|
|
348
|
+
*/
|
|
349
|
+
int pool_write(POOL_CONNECTION *cp, void *buf, int len)
|
|
350
|
+
{
|
|
351
|
+
if (len < 0)
|
|
352
|
+
{
|
|
353
|
+
pool_error("pool_write: invalid request size: %d", len);
|
|
354
|
+
return -1;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (cp->no_forward)
|
|
358
|
+
return 0;
|
|
359
|
+
|
|
360
|
+
while (len > 0)
|
|
361
|
+
{
|
|
362
|
+
int remainder = WRITEBUFSZ - cp->wbufpo;
|
|
363
|
+
|
|
364
|
+
if (cp->wbufpo >= WRITEBUFSZ)
|
|
365
|
+
{
|
|
366
|
+
/*
|
|
367
|
+
* Write buffer is full. so flush buffer.
|
|
368
|
+
* wbufpo is reset in pool_flush_it().
|
|
369
|
+
*/
|
|
370
|
+
if (pool_flush_it(cp) == -1)
|
|
371
|
+
return -1;
|
|
372
|
+
remainder = WRITEBUFSZ;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/* check buffer size */
|
|
376
|
+
if (remainder >= len)
|
|
377
|
+
{
|
|
378
|
+
/* OK, buffer size is enough. */
|
|
379
|
+
remainder = len;
|
|
380
|
+
}
|
|
381
|
+
memcpy(cp->wbuf+cp->wbufpo, buf, remainder);
|
|
382
|
+
cp->wbufpo += remainder;
|
|
383
|
+
buf += remainder;
|
|
384
|
+
len -= remainder;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return 0;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/*
|
|
391
|
+
* flush write buffer
|
|
392
|
+
*/
|
|
393
|
+
int pool_flush_it(POOL_CONNECTION *cp)
|
|
394
|
+
{
|
|
395
|
+
int sts;
|
|
396
|
+
int wlen;
|
|
397
|
+
int offset;
|
|
398
|
+
wlen = cp->wbufpo;
|
|
399
|
+
|
|
400
|
+
if (wlen == 0)
|
|
401
|
+
{
|
|
402
|
+
return 0;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
offset = 0;
|
|
406
|
+
|
|
407
|
+
for (;;)
|
|
408
|
+
{
|
|
409
|
+
errno = 0;
|
|
410
|
+
|
|
411
|
+
#ifdef NOT_USED
|
|
412
|
+
if (!cp->isbackend)
|
|
413
|
+
{
|
|
414
|
+
fd_set writemask;
|
|
415
|
+
fd_set exceptmask;
|
|
416
|
+
|
|
417
|
+
FD_ZERO(&writemask);
|
|
418
|
+
FD_ZERO(&exceptmask);
|
|
419
|
+
FD_SET(cp->fd, &writemask);
|
|
420
|
+
FD_SET(cp->fd, &exceptmask);
|
|
421
|
+
|
|
422
|
+
sts = select(cp->fd+1, NULL, &writemask, &exceptmask, NULL);
|
|
423
|
+
if (sts == -1)
|
|
424
|
+
{
|
|
425
|
+
if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
|
|
426
|
+
continue;
|
|
427
|
+
|
|
428
|
+
pool_error("pool_flush_it: select() failed. reason: %s", strerror(errno));
|
|
429
|
+
cp->wbufpo = 0;
|
|
430
|
+
return -1;
|
|
431
|
+
}
|
|
432
|
+
else if (sts == 0)
|
|
433
|
+
{
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
else if (FD_ISSET(cp->fd, &exceptmask))
|
|
437
|
+
{
|
|
438
|
+
pool_log("pool_flush_it: exception occurred");
|
|
439
|
+
cp->wbufpo = 0;
|
|
440
|
+
return -1;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
#endif
|
|
444
|
+
if (cp->ssl_active > 0) {
|
|
445
|
+
sts = pool_ssl_write(cp, cp->wbuf + offset, wlen);
|
|
446
|
+
} else {
|
|
447
|
+
sts = write(cp->fd, cp->wbuf + offset, wlen);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (sts > 0)
|
|
451
|
+
{
|
|
452
|
+
wlen -= sts;
|
|
453
|
+
|
|
454
|
+
if (wlen == 0)
|
|
455
|
+
{
|
|
456
|
+
/* write completed */
|
|
457
|
+
break;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
else if (wlen < 0)
|
|
461
|
+
{
|
|
462
|
+
pool_error("pool_flush_it: invalid write size %d", sts);
|
|
463
|
+
cp->wbufpo = 0;
|
|
464
|
+
return -1;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
else
|
|
468
|
+
{
|
|
469
|
+
/* need to write remaining data */
|
|
470
|
+
offset += sts;
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
else if (errno == EAGAIN || errno == EINTR)
|
|
476
|
+
{
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
else
|
|
481
|
+
{
|
|
482
|
+
/* If this is the backend stream, report error. Otherwise
|
|
483
|
+
* just report debug message.
|
|
484
|
+
*/
|
|
485
|
+
if (cp->isbackend)
|
|
486
|
+
pool_error("pool_flush_it: write failed to backend (%d). reason: %s offset: %d wlen: %d",
|
|
487
|
+
cp->db_node_id, strerror(errno), offset, wlen);
|
|
488
|
+
else
|
|
489
|
+
pool_debug("pool_flush_it: write failed to frontend. reason: %s offset: %d wlen: %d",
|
|
490
|
+
strerror(errno), offset, wlen);
|
|
491
|
+
|
|
492
|
+
cp->wbufpo = 0;
|
|
493
|
+
return -1;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
cp->wbufpo = 0;
|
|
498
|
+
|
|
499
|
+
return 0;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/*
|
|
503
|
+
* flush write buffer and degenerate/failover if error occurs
|
|
504
|
+
*/
|
|
505
|
+
int pool_flush(POOL_CONNECTION *cp)
|
|
506
|
+
{
|
|
507
|
+
if (pool_flush_it(cp) == -1)
|
|
508
|
+
{
|
|
509
|
+
if (cp->isbackend)
|
|
510
|
+
{
|
|
511
|
+
/* if fail_over_on_backend_error is true, then trigger failover */
|
|
512
|
+
if (pool_config->fail_over_on_backend_error)
|
|
513
|
+
{
|
|
514
|
+
notice_backend_error(cp->db_node_id);
|
|
515
|
+
child_exit(1);
|
|
516
|
+
pool_log("pool_flush: do not failover because I am the main process");
|
|
517
|
+
return -1;
|
|
518
|
+
}
|
|
519
|
+
else
|
|
520
|
+
{
|
|
521
|
+
pool_log("pool_flush: do not failover because fail_over_on_backend_error is off");
|
|
522
|
+
return -1;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
else
|
|
526
|
+
{
|
|
527
|
+
/*
|
|
528
|
+
* If we are in replication mode, we need to continue the
|
|
529
|
+
* processing with backends to keep consistency among
|
|
530
|
+
* backends, thus ignore error.
|
|
531
|
+
*/
|
|
532
|
+
if (REPLICATION)
|
|
533
|
+
return 0;
|
|
534
|
+
else
|
|
535
|
+
return -1;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return 0;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/*
|
|
542
|
+
* combo of pool_write and pool_flush
|
|
543
|
+
*/
|
|
544
|
+
int pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len)
|
|
545
|
+
{
|
|
546
|
+
if (pool_write(cp, buf, len))
|
|
547
|
+
return -1;
|
|
548
|
+
return pool_flush(cp);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/*
|
|
552
|
+
* read a string until EOF or NULL is encountered.
|
|
553
|
+
* if line is not 0, read until new line is encountered.
|
|
554
|
+
*/
|
|
555
|
+
char *pool_read_string(POOL_CONNECTION *cp, int *len, int line)
|
|
556
|
+
{
|
|
557
|
+
int readp;
|
|
558
|
+
int readsize;
|
|
559
|
+
int readlen;
|
|
560
|
+
int strlength;
|
|
561
|
+
int flag;
|
|
562
|
+
int consume_size;
|
|
563
|
+
|
|
564
|
+
#ifdef DEBUG
|
|
565
|
+
static char pbuf[READBUFSZ];
|
|
566
|
+
#endif
|
|
567
|
+
|
|
568
|
+
*len = 0;
|
|
569
|
+
readp = 0;
|
|
570
|
+
|
|
571
|
+
/* initialize read buffer */
|
|
572
|
+
if (cp->sbufsz == 0)
|
|
573
|
+
{
|
|
574
|
+
cp->sbuf = malloc(READBUFSZ);
|
|
575
|
+
if (cp->sbuf == NULL)
|
|
576
|
+
{
|
|
577
|
+
pool_error("pool_read_string: malloc failed");
|
|
578
|
+
return NULL;
|
|
579
|
+
}
|
|
580
|
+
cp->sbufsz = READBUFSZ;
|
|
581
|
+
*cp->sbuf = '\0';
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/* any pending data? */
|
|
585
|
+
if (cp->len)
|
|
586
|
+
{
|
|
587
|
+
if (line)
|
|
588
|
+
strlength = mystrlinelen(cp->hp+cp->po, cp->len, &flag);
|
|
589
|
+
else
|
|
590
|
+
strlength = mystrlen(cp->hp+cp->po, cp->len, &flag);
|
|
591
|
+
|
|
592
|
+
/* buffer is too small? */
|
|
593
|
+
if ((strlength + 1) > cp->sbufsz)
|
|
594
|
+
{
|
|
595
|
+
cp->sbufsz = ((strlength+1)/READBUFSZ+1)*READBUFSZ;
|
|
596
|
+
cp->sbuf = realloc(cp->sbuf, cp->sbufsz);
|
|
597
|
+
if (cp->sbuf == NULL)
|
|
598
|
+
{
|
|
599
|
+
pool_error("pool_read_string: realloc failed");
|
|
600
|
+
return NULL;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/* consume pending and save to read string buffer */
|
|
605
|
+
consume_size = consume_pending_data(cp, cp->sbuf, strlength);
|
|
606
|
+
|
|
607
|
+
*len = strlength;
|
|
608
|
+
|
|
609
|
+
/* is the string null terminated? */
|
|
610
|
+
if (consume_size == strlength && !flag)
|
|
611
|
+
{
|
|
612
|
+
/* not null or line terminated.
|
|
613
|
+
* we need to read more since we have not encountered NULL or new line yet
|
|
614
|
+
*/
|
|
615
|
+
readsize = cp->sbufsz - strlength;
|
|
616
|
+
readp = strlength;
|
|
617
|
+
}
|
|
618
|
+
else
|
|
619
|
+
{
|
|
620
|
+
pool_debug("pool_read_string: read all from pending data. po:%d len:%d",
|
|
621
|
+
cp->po, cp->len);
|
|
622
|
+
return cp->sbuf;
|
|
623
|
+
}
|
|
624
|
+
} else
|
|
625
|
+
{
|
|
626
|
+
readsize = cp->sbufsz;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
for (;;)
|
|
630
|
+
{
|
|
631
|
+
if (pool_check_fd(cp))
|
|
632
|
+
{
|
|
633
|
+
if (!IS_MASTER_NODE_ID(cp->db_node_id))
|
|
634
|
+
{
|
|
635
|
+
pool_log("pool_read_string: data is not ready in DB node:%d. abort this session",
|
|
636
|
+
cp->db_node_id);
|
|
637
|
+
exit(1);
|
|
638
|
+
}
|
|
639
|
+
else
|
|
640
|
+
{
|
|
641
|
+
pool_error("pool_read_string: pool_check_fd failed (%s)", strerror(errno));
|
|
642
|
+
return NULL;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (cp->ssl_active > 0) {
|
|
647
|
+
readlen = pool_ssl_read(cp, cp->sbuf+readp, readsize);
|
|
648
|
+
} else {
|
|
649
|
+
readlen = read(cp->fd, cp->sbuf+readp, readsize);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
if (readlen == -1)
|
|
653
|
+
{
|
|
654
|
+
pool_error("pool_read_string: read() failed. reason:%s", strerror(errno));
|
|
655
|
+
|
|
656
|
+
if (cp->isbackend)
|
|
657
|
+
{
|
|
658
|
+
notice_backend_error(cp->db_node_id);
|
|
659
|
+
child_exit(1);
|
|
660
|
+
return NULL;
|
|
661
|
+
}
|
|
662
|
+
else
|
|
663
|
+
{
|
|
664
|
+
return NULL;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
else if (readlen == 0) /* EOF detected */
|
|
668
|
+
{
|
|
669
|
+
/*
|
|
670
|
+
* just returns an error, not trigger failover or degeneration
|
|
671
|
+
*/
|
|
672
|
+
pool_error("pool_read_string: read () EOF detected");
|
|
673
|
+
return NULL;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/* check overrun */
|
|
677
|
+
if (line)
|
|
678
|
+
strlength = mystrlinelen(cp->sbuf+readp, readlen, &flag);
|
|
679
|
+
else
|
|
680
|
+
strlength = mystrlen(cp->sbuf+readp, readlen, &flag);
|
|
681
|
+
|
|
682
|
+
if (strlength < readlen)
|
|
683
|
+
{
|
|
684
|
+
save_pending_data(cp, cp->sbuf+readp+strlength, readlen-strlength);
|
|
685
|
+
*len += strlength;
|
|
686
|
+
pool_debug("pool_read_string: total result %d with pending data po:%d len:%d", *len, cp->po, cp->len);
|
|
687
|
+
return cp->sbuf;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
*len += readlen;
|
|
691
|
+
|
|
692
|
+
/* encountered null or newline? */
|
|
693
|
+
if (flag)
|
|
694
|
+
{
|
|
695
|
+
/* ok we have read all data */
|
|
696
|
+
pool_debug("pool_read_string: total result %d ", *len);
|
|
697
|
+
break;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
readp += readlen;
|
|
701
|
+
readsize = READBUFSZ;
|
|
702
|
+
|
|
703
|
+
if ((*len+readsize) > cp->sbufsz)
|
|
704
|
+
{
|
|
705
|
+
cp->sbufsz += READBUFSZ;
|
|
706
|
+
|
|
707
|
+
cp->sbuf = realloc(cp->sbuf, cp->sbufsz);
|
|
708
|
+
if (cp->sbuf == NULL)
|
|
709
|
+
{
|
|
710
|
+
pool_error("pool_read_string: realloc failed");
|
|
711
|
+
return NULL;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return cp->sbuf;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/*
|
|
719
|
+
* returns the byte length of str, including \0, no more than upper.
|
|
720
|
+
* if encountered \0, flag is set to non 0.
|
|
721
|
+
* example:
|
|
722
|
+
* mystrlen("abc", 2) returns 2
|
|
723
|
+
* mystrlen("abc", 3) returns 3
|
|
724
|
+
* mystrlen("abc", 4) returns 4
|
|
725
|
+
* mystrlen("abc", 5) returns 4
|
|
726
|
+
*/
|
|
727
|
+
static int mystrlen(char *str, int upper, int *flag)
|
|
728
|
+
{
|
|
729
|
+
int len;
|
|
730
|
+
|
|
731
|
+
*flag = 0;
|
|
732
|
+
|
|
733
|
+
for (len = 0;len < upper; len++, str++)
|
|
734
|
+
{
|
|
735
|
+
if (!*str)
|
|
736
|
+
{
|
|
737
|
+
len++;
|
|
738
|
+
*flag = 1;
|
|
739
|
+
break;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
return len;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/*
|
|
746
|
+
* returns the byte length of str terminated by \n or \0 (including \n or \0), no more than upper.
|
|
747
|
+
* if encountered \0 or \n, flag is set to non 0.
|
|
748
|
+
* example:
|
|
749
|
+
* mystrlinelen("abc", 2) returns 2
|
|
750
|
+
* mystrlinelen("abc", 3) returns 3
|
|
751
|
+
* mystrlinelen("abc", 4) returns 4
|
|
752
|
+
* mystrlinelen("abc", 5) returns 4
|
|
753
|
+
* mystrlinelen("abcd\nefg", 4) returns 4
|
|
754
|
+
* mystrlinelen("abcd\nefg", 5) returns 5
|
|
755
|
+
* mystrlinelen("abcd\nefg", 6) returns 5
|
|
756
|
+
*/
|
|
757
|
+
static int mystrlinelen(char *str, int upper, int *flag)
|
|
758
|
+
{
|
|
759
|
+
int len;
|
|
760
|
+
|
|
761
|
+
*flag = 0;
|
|
762
|
+
|
|
763
|
+
for (len = 0;len < upper; len++, str++)
|
|
764
|
+
{
|
|
765
|
+
if (!*str || *str == '\n')
|
|
766
|
+
{
|
|
767
|
+
len++;
|
|
768
|
+
*flag = 1;
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return len;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/*
|
|
776
|
+
* save pending data
|
|
777
|
+
*/
|
|
778
|
+
static int save_pending_data(POOL_CONNECTION *cp, void *data, int len)
|
|
779
|
+
{
|
|
780
|
+
int reqlen;
|
|
781
|
+
size_t realloc_size;
|
|
782
|
+
char *p;
|
|
783
|
+
|
|
784
|
+
/* to be safe */
|
|
785
|
+
if (cp->len == 0)
|
|
786
|
+
cp->po = 0;
|
|
787
|
+
|
|
788
|
+
reqlen = cp->po + cp->len + len;
|
|
789
|
+
|
|
790
|
+
/* pending buffer is enough? */
|
|
791
|
+
if (reqlen > cp->bufsz)
|
|
792
|
+
{
|
|
793
|
+
/* too small, enlarge it */
|
|
794
|
+
realloc_size = (reqlen/READBUFSZ+1)*READBUFSZ;
|
|
795
|
+
p = realloc(cp->hp, realloc_size);
|
|
796
|
+
if (p == NULL)
|
|
797
|
+
{
|
|
798
|
+
pool_error("save_pending_data: realloc failed");
|
|
799
|
+
return -1;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
cp->bufsz = realloc_size;
|
|
803
|
+
cp->hp = p;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
memmove(cp->hp + cp->po + cp->len, data, len);
|
|
807
|
+
cp->len += len;
|
|
808
|
+
|
|
809
|
+
return 0;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
/*
|
|
813
|
+
* consume pending data. returns actually consumed data length.
|
|
814
|
+
*/
|
|
815
|
+
static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len)
|
|
816
|
+
{
|
|
817
|
+
int consume_size;
|
|
818
|
+
|
|
819
|
+
if (cp->len <= 0)
|
|
820
|
+
return 0;
|
|
821
|
+
|
|
822
|
+
consume_size = Min(len, cp->len);
|
|
823
|
+
memmove(data, cp->hp + cp->po, consume_size);
|
|
824
|
+
cp->len -= consume_size;
|
|
825
|
+
|
|
826
|
+
if (cp->len <= 0)
|
|
827
|
+
cp->po = 0;
|
|
828
|
+
else
|
|
829
|
+
cp->po += consume_size;
|
|
830
|
+
|
|
831
|
+
return consume_size;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/*
|
|
835
|
+
* pool_unread: Put back data to input buffer
|
|
836
|
+
*/
|
|
837
|
+
int pool_unread(POOL_CONNECTION *cp, void *data, int len)
|
|
838
|
+
{
|
|
839
|
+
void *p = cp->hp;
|
|
840
|
+
int n = cp->len + len;
|
|
841
|
+
int realloc_size;
|
|
842
|
+
|
|
843
|
+
if (cp->bufsz < n)
|
|
844
|
+
{
|
|
845
|
+
realloc_size = (n/READBUFSZ+1)*READBUFSZ;
|
|
846
|
+
p = realloc(cp->hp, realloc_size);
|
|
847
|
+
if (p == NULL)
|
|
848
|
+
{
|
|
849
|
+
pool_error("pool_unread: realloc failed");
|
|
850
|
+
return -1;
|
|
851
|
+
}
|
|
852
|
+
cp->hp = p;
|
|
853
|
+
}
|
|
854
|
+
if (cp->len != 0)
|
|
855
|
+
memmove(p + len, cp->hp + cp->po, cp->len);
|
|
856
|
+
memmove(p, data, len);
|
|
857
|
+
cp->len = n;
|
|
858
|
+
cp->po = 0;
|
|
859
|
+
return 0;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/*
|
|
863
|
+
* pool_push: Push data into buffer stack.
|
|
864
|
+
*/
|
|
865
|
+
int pool_push(POOL_CONNECTION *cp, void *data, int len)
|
|
866
|
+
{
|
|
867
|
+
char *p;
|
|
868
|
+
|
|
869
|
+
pool_debug("pool_push: len: %d", len);
|
|
870
|
+
|
|
871
|
+
if (cp->bufsz3 == 0)
|
|
872
|
+
{
|
|
873
|
+
p = cp->buf3 = malloc(len);
|
|
874
|
+
if (p == NULL)
|
|
875
|
+
{
|
|
876
|
+
pool_error("pool_push: malloc failed. len:%d", len);
|
|
877
|
+
return -1;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
else
|
|
881
|
+
{
|
|
882
|
+
p = cp->buf3 + cp->bufsz3;
|
|
883
|
+
cp->buf3 = realloc(cp->buf3, cp->bufsz3 + len);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
memcpy(p, data, len);
|
|
887
|
+
cp->bufsz3 += len;
|
|
888
|
+
|
|
889
|
+
return 0;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/*
|
|
893
|
+
* pool_pop: Pop data from buffer stack and put back data using
|
|
894
|
+
* pool_unread.
|
|
895
|
+
*/
|
|
896
|
+
void pool_pop(POOL_CONNECTION *cp, int *len)
|
|
897
|
+
{
|
|
898
|
+
if (cp->bufsz3 == 0)
|
|
899
|
+
{
|
|
900
|
+
*len = 0;
|
|
901
|
+
pool_debug("pool_pop: len: %d", *len);
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
pool_unread(cp, cp->buf3, cp->bufsz3);
|
|
906
|
+
*len = cp->bufsz3;
|
|
907
|
+
free(cp->buf3);
|
|
908
|
+
cp->bufsz3 = 0;
|
|
909
|
+
cp->buf3 = NULL;
|
|
910
|
+
pool_debug("pool_pop: len: %d", *len);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
/*
|
|
914
|
+
* pool_stacklen: Returns buffer stack length
|
|
915
|
+
* pool_unread.
|
|
916
|
+
*/
|
|
917
|
+
int pool_stacklen(POOL_CONNECTION *cp)
|
|
918
|
+
{
|
|
919
|
+
return cp->bufsz3;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/*
|
|
923
|
+
* set non-block flag
|
|
924
|
+
*/
|
|
925
|
+
void pool_set_nonblock(int fd)
|
|
926
|
+
{
|
|
927
|
+
int var;
|
|
928
|
+
|
|
929
|
+
/* set fd to none blocking */
|
|
930
|
+
var = fcntl(fd, F_GETFL, 0);
|
|
931
|
+
if (var == -1)
|
|
932
|
+
{
|
|
933
|
+
pool_error("fcntl failed. %s", strerror(errno));
|
|
934
|
+
child_exit(1);
|
|
935
|
+
}
|
|
936
|
+
if (fcntl(fd, F_SETFL, var | O_NONBLOCK) == -1)
|
|
937
|
+
{
|
|
938
|
+
pool_error("fcntl failed. %s", strerror(errno));
|
|
939
|
+
child_exit(1);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/*
|
|
944
|
+
* unset non-block flag
|
|
945
|
+
*/
|
|
946
|
+
void pool_unset_nonblock(int fd)
|
|
947
|
+
{
|
|
948
|
+
int var;
|
|
949
|
+
|
|
950
|
+
/* set fd to none blocking */
|
|
951
|
+
var = fcntl(fd, F_GETFL, 0);
|
|
952
|
+
if (var == -1)
|
|
953
|
+
{
|
|
954
|
+
pool_error("fcntl failed. %s", strerror(errno));
|
|
955
|
+
child_exit(1);
|
|
956
|
+
}
|
|
957
|
+
if (fcntl(fd, F_SETFL, var & ~O_NONBLOCK) == -1)
|
|
958
|
+
{
|
|
959
|
+
pool_error("fcntl failed. %s", strerror(errno));
|
|
960
|
+
child_exit(1);
|
|
961
|
+
}
|
|
962
|
+
}
|