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,1215 @@
|
|
|
1
|
+
/* -*-pgsql-c-*- */
|
|
2
|
+
/*
|
|
3
|
+
* $Header$
|
|
4
|
+
*
|
|
5
|
+
* pgpool: a language independent connection pool server for PostgreSQL
|
|
6
|
+
* written by Tatsuo Ishii
|
|
7
|
+
*
|
|
8
|
+
* Copyright (c) 2003-2013 PgPool Global Development Group
|
|
9
|
+
*
|
|
10
|
+
* Permission to use, copy, modify, and distribute this software and
|
|
11
|
+
* its documentation for any purpose and without fee is hereby
|
|
12
|
+
* granted, provided that the above copyright notice appear in all
|
|
13
|
+
* copies and that both that copyright notice and this permission
|
|
14
|
+
* notice appear in supporting documentation, and that the name of the
|
|
15
|
+
* author not be used in advertising or publicity pertaining to
|
|
16
|
+
* distribution of the software without specific, written prior
|
|
17
|
+
* permission. The author makes no representations about the
|
|
18
|
+
* suitability of this software for any purpose. It is provided "as
|
|
19
|
+
* is" without express or implied warranty.
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
#include <arpa/inet.h>
|
|
23
|
+
#include <stdlib.h>
|
|
24
|
+
#include <string.h>
|
|
25
|
+
|
|
26
|
+
#include "pool.h"
|
|
27
|
+
#include "pool_timestamp.h"
|
|
28
|
+
#include "pool_relcache.h"
|
|
29
|
+
#include "pool_select_walker.h"
|
|
30
|
+
#include "pool_config.h"
|
|
31
|
+
#include "parser/parsenodes.h"
|
|
32
|
+
#include "parser/parser.h"
|
|
33
|
+
#include "parser/pool_memory.h"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
typedef struct {
|
|
37
|
+
char *attrname; /* attribute name */
|
|
38
|
+
char *adsrc; /* default value expression */
|
|
39
|
+
int use_timestamp;
|
|
40
|
+
} TSAttr;
|
|
41
|
+
|
|
42
|
+
typedef struct {
|
|
43
|
+
int relnatts;
|
|
44
|
+
TSAttr attr[1];
|
|
45
|
+
} TSRel;
|
|
46
|
+
|
|
47
|
+
typedef struct {
|
|
48
|
+
A_Const *ts_const;
|
|
49
|
+
POOL_CONNECTION_POOL *backend;
|
|
50
|
+
char *relname;
|
|
51
|
+
int num_params; /* num of original params (for Parse) */
|
|
52
|
+
bool rewrite_to_params;
|
|
53
|
+
bool rewrite; /* has rewritten? */
|
|
54
|
+
List *params; /* list of additional params */
|
|
55
|
+
} TSRewriteContext;
|
|
56
|
+
|
|
57
|
+
static void *ts_register_func(POOL_SELECT_RESULT *res);
|
|
58
|
+
static void *ts_unregister_func(void *data);
|
|
59
|
+
static TSRel *relcache_lookup(TSRewriteContext *ctx);
|
|
60
|
+
static bool isStringConst(Node *node, const char *str);
|
|
61
|
+
static bool rewrite_timestamp_walker(Node *node, void *context);
|
|
62
|
+
static bool rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx);
|
|
63
|
+
static bool rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx);
|
|
64
|
+
static char *get_current_timestamp(POOL_CONNECTION_POOL *backend);
|
|
65
|
+
static Node *makeTsExpr(TSRewriteContext *ctx);
|
|
66
|
+
static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression);
|
|
67
|
+
bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context);
|
|
68
|
+
|
|
69
|
+
POOL_RELCACHE *ts_relcache;
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
static void *
|
|
73
|
+
ts_register_func(POOL_SELECT_RESULT *res)
|
|
74
|
+
{
|
|
75
|
+
/* Number of result columns included in res */
|
|
76
|
+
#define NUM_COLS 3
|
|
77
|
+
|
|
78
|
+
TSRel *rel;
|
|
79
|
+
int i;
|
|
80
|
+
|
|
81
|
+
if (res->numrows == 0)
|
|
82
|
+
return NULL;
|
|
83
|
+
|
|
84
|
+
rel = (TSRel *) malloc(sizeof(TSRel) + sizeof(TSAttr) * (res->numrows - 1));
|
|
85
|
+
|
|
86
|
+
for (i = 0; i < res->numrows; i++)
|
|
87
|
+
{
|
|
88
|
+
int index = 0;
|
|
89
|
+
|
|
90
|
+
rel->attr[i].attrname = strdup(res->data[i * NUM_COLS + index]);
|
|
91
|
+
index++;
|
|
92
|
+
|
|
93
|
+
if (res->data[i * NUM_COLS + index])
|
|
94
|
+
rel->attr[i].adsrc = strdup(res->data[i * NUM_COLS + index]);
|
|
95
|
+
else
|
|
96
|
+
rel->attr[i].adsrc = NULL;
|
|
97
|
+
|
|
98
|
+
index++;
|
|
99
|
+
|
|
100
|
+
rel->attr[i].use_timestamp = *(res->data[i * NUM_COLS + index]) == 't';
|
|
101
|
+
pool_debug("attrname %s adsrc %s use_timestamp = %d",
|
|
102
|
+
rel->attr[i].attrname, (rel->attr[i].adsrc? rel->attr[i].adsrc:"NULL"),
|
|
103
|
+
rel->attr[i].use_timestamp);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
rel->relnatts = res->numrows;
|
|
107
|
+
return (void *) rel;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
static void *
|
|
112
|
+
ts_unregister_func(void *data)
|
|
113
|
+
{
|
|
114
|
+
TSRel *rel = (TSRel *) data;
|
|
115
|
+
|
|
116
|
+
if (rel == NULL)
|
|
117
|
+
return NULL;
|
|
118
|
+
|
|
119
|
+
free(rel);
|
|
120
|
+
return rel;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
static TSRel*
|
|
125
|
+
relcache_lookup(TSRewriteContext *ctx)
|
|
126
|
+
{
|
|
127
|
+
#define ATTRDEFQUERY "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%')" \
|
|
128
|
+
" AND (a.atttypid = 'timestamp'::regtype::oid OR" \
|
|
129
|
+
" a.atttypid = 'timestamp with time zone'::regtype::oid OR" \
|
|
130
|
+
" a.atttypid = 'date'::regtype::oid OR" \
|
|
131
|
+
" a.atttypid = 'time'::regtype::oid OR" \
|
|
132
|
+
" a.atttypid = 'time with time zone'::regtype::oid)" \
|
|
133
|
+
" , false)" \
|
|
134
|
+
" FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \
|
|
135
|
+
" LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \
|
|
136
|
+
" WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s'" \
|
|
137
|
+
" ORDER BY a.attnum"
|
|
138
|
+
|
|
139
|
+
#define ATTRDEFQUERY2 "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%')" \
|
|
140
|
+
" AND (a.atttypid = 'timestamp'::regtype::oid OR" \
|
|
141
|
+
" a.atttypid = 'timestamp with time zone'::regtype::oid OR" \
|
|
142
|
+
" a.atttypid = 'date'::regtype::oid OR" \
|
|
143
|
+
" a.atttypid = 'time'::regtype::oid OR" \
|
|
144
|
+
" a.atttypid = 'time with time zone'::regtype::oid)" \
|
|
145
|
+
" , false)" \
|
|
146
|
+
" FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \
|
|
147
|
+
" LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \
|
|
148
|
+
" WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s')" \
|
|
149
|
+
" ORDER BY a.attnum"
|
|
150
|
+
|
|
151
|
+
char *query;
|
|
152
|
+
|
|
153
|
+
if (pool_has_pgpool_regclass())
|
|
154
|
+
{
|
|
155
|
+
query = ATTRDEFQUERY2;
|
|
156
|
+
}
|
|
157
|
+
else
|
|
158
|
+
{
|
|
159
|
+
query = ATTRDEFQUERY;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!ts_relcache)
|
|
163
|
+
{
|
|
164
|
+
ts_relcache = pool_create_relcache(pool_config->relcache_size, query, ts_register_func, ts_unregister_func, false);
|
|
165
|
+
|
|
166
|
+
if (ts_relcache == NULL)
|
|
167
|
+
{
|
|
168
|
+
pool_error("relcache_lookup: pool_create_relcache error");
|
|
169
|
+
return NULL;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return (TSRel *) pool_search_relcache(ts_relcache, ctx->backend, ctx->relname);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
static Node *
|
|
178
|
+
makeTsExpr(TSRewriteContext *ctx)
|
|
179
|
+
{
|
|
180
|
+
ParamRef *param;
|
|
181
|
+
|
|
182
|
+
if (!ctx->rewrite_to_params)
|
|
183
|
+
return (Node *) ctx->ts_const;
|
|
184
|
+
|
|
185
|
+
param = makeNode(ParamRef);
|
|
186
|
+
param->number = 0;
|
|
187
|
+
ctx->params = lappend(ctx->params, param);
|
|
188
|
+
return (Node *) param;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
static bool
|
|
193
|
+
isStringConst(Node *node, const char *str)
|
|
194
|
+
{
|
|
195
|
+
A_Const *a_const;
|
|
196
|
+
Value val;
|
|
197
|
+
|
|
198
|
+
if (!IsA(node, A_Const))
|
|
199
|
+
return false;
|
|
200
|
+
|
|
201
|
+
a_const = (A_Const *) node;
|
|
202
|
+
val = a_const->val;
|
|
203
|
+
|
|
204
|
+
if (val.type == T_String && val.val.str && strcmp(str, val.val.str) == 0)
|
|
205
|
+
return true;
|
|
206
|
+
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
bool
|
|
212
|
+
isSystemType(Node *node, const char *name)
|
|
213
|
+
{
|
|
214
|
+
TypeName *typename;
|
|
215
|
+
|
|
216
|
+
if (!IsA(node, TypeName))
|
|
217
|
+
return false;
|
|
218
|
+
|
|
219
|
+
typename = (TypeName *) node;
|
|
220
|
+
if (list_length(typename->names) == 2 &&
|
|
221
|
+
strcmp("pg_catalog", strVal(linitial(typename->names))) == 0 &&
|
|
222
|
+
strcmp(name, strVal(lsecond(typename->names))) == 0)
|
|
223
|
+
return true;
|
|
224
|
+
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
static bool
|
|
230
|
+
isSystemTypeCast(Node *node, const char *name)
|
|
231
|
+
{
|
|
232
|
+
TypeCast *typecast;
|
|
233
|
+
|
|
234
|
+
if (!IsA(node, TypeCast))
|
|
235
|
+
return false;
|
|
236
|
+
|
|
237
|
+
typecast = (TypeCast *) node;
|
|
238
|
+
return isSystemType((Node *) typecast->typeName, name);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/*
|
|
242
|
+
* walker function for raw_expression_tree_walker
|
|
243
|
+
*/
|
|
244
|
+
static bool
|
|
245
|
+
rewrite_timestamp_walker(Node *node, void *context)
|
|
246
|
+
{
|
|
247
|
+
TSRewriteContext *ctx = (TSRewriteContext *) context;
|
|
248
|
+
|
|
249
|
+
if (node == NULL)
|
|
250
|
+
return false;
|
|
251
|
+
|
|
252
|
+
if (nodeTag(node) == T_FuncCall)
|
|
253
|
+
{
|
|
254
|
+
/* `now()' FuncCall */
|
|
255
|
+
FuncCall *fcall = (FuncCall *) node;
|
|
256
|
+
|
|
257
|
+
if ((list_length(fcall->funcname) == 1 &&
|
|
258
|
+
strcmp("now", strVal(linitial(fcall->funcname))) == 0) ||
|
|
259
|
+
(list_length(fcall->funcname) == 2 &&
|
|
260
|
+
strcmp("pg_catalog", strVal(linitial(fcall->funcname))) == 0 &&
|
|
261
|
+
strcmp("now", strVal(lsecond(fcall->funcname))) == 0))
|
|
262
|
+
{
|
|
263
|
+
TypeCast *tc = makeNode(TypeCast);
|
|
264
|
+
tc->arg = makeTsExpr(ctx);
|
|
265
|
+
tc->typeName = SystemTypeName("text");
|
|
266
|
+
|
|
267
|
+
fcall->funcname = SystemFuncName("timestamptz");
|
|
268
|
+
fcall->args = list_make1(tc);
|
|
269
|
+
ctx->rewrite = true;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if (IsA(node, TypeCast))
|
|
273
|
+
{
|
|
274
|
+
/* CURRENT_DATE, CURRENT_TIME, LOCALTIMESTAMP, LOCALTIME etc.*/
|
|
275
|
+
TypeCast *tc = (TypeCast *) node;
|
|
276
|
+
|
|
277
|
+
if ((isSystemType((Node *) tc->typeName, "date") ||
|
|
278
|
+
isSystemType((Node *) tc->typeName, "timestamp") ||
|
|
279
|
+
isSystemType((Node *) tc->typeName, "timestamptz") ||
|
|
280
|
+
isSystemType((Node *) tc->typeName, "time") ||
|
|
281
|
+
isSystemType((Node *) tc->typeName, "timetz")))
|
|
282
|
+
{
|
|
283
|
+
/* rewrite `'now'::timestamp' and `'now'::text::timestamp' both */
|
|
284
|
+
if (isSystemTypeCast(tc->arg, "text"))
|
|
285
|
+
tc = (TypeCast *) tc->arg;
|
|
286
|
+
|
|
287
|
+
if (isStringConst(tc->arg, "now"))
|
|
288
|
+
{
|
|
289
|
+
tc->arg = (Node *) makeTsExpr(ctx);
|
|
290
|
+
ctx->rewrite = true;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
else if (IsA(node, ParamRef))
|
|
295
|
+
{
|
|
296
|
+
ParamRef *param = (ParamRef *) node;
|
|
297
|
+
|
|
298
|
+
/* count how many params in original query */
|
|
299
|
+
if (ctx->num_params < param->number)
|
|
300
|
+
ctx->num_params = param->number;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return raw_expression_tree_walker(node, rewrite_timestamp_walker, context);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
/*
|
|
308
|
+
* Get `now()' from MASTER node
|
|
309
|
+
*/
|
|
310
|
+
static char *
|
|
311
|
+
get_current_timestamp(POOL_CONNECTION_POOL *backend)
|
|
312
|
+
{
|
|
313
|
+
POOL_SELECT_RESULT *res;
|
|
314
|
+
POOL_STATUS status;
|
|
315
|
+
static char timestamp[64];
|
|
316
|
+
|
|
317
|
+
status = do_query(MASTER(backend), "SELECT now()", &res, MAJOR(backend));
|
|
318
|
+
if (status != POOL_CONTINUE)
|
|
319
|
+
{
|
|
320
|
+
pool_error("get_current_timestamp: do_query failed");
|
|
321
|
+
free_select_result(res);
|
|
322
|
+
return NULL;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (res->numrows != 1)
|
|
326
|
+
{
|
|
327
|
+
free_select_result(res);
|
|
328
|
+
return NULL;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
strlcpy(timestamp, res->data[0], sizeof(timestamp));
|
|
332
|
+
|
|
333
|
+
free_select_result(res);
|
|
334
|
+
return timestamp;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
/*
|
|
339
|
+
* rewrite InsertStmt
|
|
340
|
+
*/
|
|
341
|
+
static bool
|
|
342
|
+
rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx)
|
|
343
|
+
{
|
|
344
|
+
int i;
|
|
345
|
+
bool rewrite = false;
|
|
346
|
+
TSRel *relcache;
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
if (i_stmt->selectStmt == NULL)
|
|
350
|
+
{
|
|
351
|
+
List *values = NIL;
|
|
352
|
+
SelectStmt *selectStmt = makeNode(SelectStmt);
|
|
353
|
+
|
|
354
|
+
relcache = relcache_lookup(ctx);
|
|
355
|
+
if (relcache == NULL)
|
|
356
|
+
return false;
|
|
357
|
+
|
|
358
|
+
/*
|
|
359
|
+
* INSERT INTO rel DEFAULT VALUES
|
|
360
|
+
* rewrite to:
|
|
361
|
+
* INSERT INTO rel VALUES (DEFAULT, '2009-..',...)
|
|
362
|
+
*/
|
|
363
|
+
|
|
364
|
+
for (i = 0; i < relcache->relnatts; i++)
|
|
365
|
+
{
|
|
366
|
+
if (relcache->attr[i].use_timestamp)
|
|
367
|
+
{
|
|
368
|
+
rewrite = true;
|
|
369
|
+
if (ctx->rewrite_to_params)
|
|
370
|
+
values = lappend(values, makeTsExpr(ctx));
|
|
371
|
+
else
|
|
372
|
+
values = lappend(values,
|
|
373
|
+
makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc));
|
|
374
|
+
}
|
|
375
|
+
else
|
|
376
|
+
values = lappend(values, makeNode(SetToDefault));
|
|
377
|
+
}
|
|
378
|
+
if (rewrite)
|
|
379
|
+
{
|
|
380
|
+
selectStmt->valuesLists = list_make1(values);
|
|
381
|
+
i_stmt->selectStmt = (Node *) selectStmt;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return rewrite;
|
|
385
|
+
}
|
|
386
|
+
else if (IsA(i_stmt->selectStmt, SelectStmt))
|
|
387
|
+
{
|
|
388
|
+
SelectStmt *selectStmt = (SelectStmt *) i_stmt->selectStmt;
|
|
389
|
+
ListCell *lc_row, *lc_val, *lc_col;
|
|
390
|
+
|
|
391
|
+
/*
|
|
392
|
+
* Rewrite `now()' call to timestamp literal.
|
|
393
|
+
*/
|
|
394
|
+
raw_expression_tree_walker(
|
|
395
|
+
(Node *) selectStmt,
|
|
396
|
+
rewrite_timestamp_walker, (void *) ctx);
|
|
397
|
+
|
|
398
|
+
rewrite = ctx->rewrite;
|
|
399
|
+
|
|
400
|
+
/*
|
|
401
|
+
* if `INSERT INTO rel SELECT ...'
|
|
402
|
+
*/
|
|
403
|
+
if (selectStmt->valuesLists == NIL)
|
|
404
|
+
return rewrite;
|
|
405
|
+
|
|
406
|
+
relcache = relcache_lookup(ctx);
|
|
407
|
+
if (relcache == NULL)
|
|
408
|
+
return false;
|
|
409
|
+
|
|
410
|
+
if (i_stmt->cols == NIL)
|
|
411
|
+
{
|
|
412
|
+
/*
|
|
413
|
+
* INSERT INTO rel VALUES (...)
|
|
414
|
+
*
|
|
415
|
+
* CREATE TABLE r1 (
|
|
416
|
+
* i1 int,
|
|
417
|
+
* t1 timestamp default now(),
|
|
418
|
+
* i2 int,
|
|
419
|
+
* t2 timestamp default now(),
|
|
420
|
+
* )
|
|
421
|
+
*
|
|
422
|
+
* INSERT INTO r1 VALUES (1, DEFAULT);
|
|
423
|
+
* rewrite to:
|
|
424
|
+
* INSERT INTO r1 VALUES (1, '20xx-xx-xx...', DEFAULT, '2..')
|
|
425
|
+
*/
|
|
426
|
+
foreach (lc_row, selectStmt->valuesLists)
|
|
427
|
+
{
|
|
428
|
+
List *values = lfirst(lc_row);
|
|
429
|
+
|
|
430
|
+
i = 0;
|
|
431
|
+
foreach (lc_val, values)
|
|
432
|
+
{
|
|
433
|
+
if (relcache->attr[i].use_timestamp == true && IsA(lfirst(lc_val), SetToDefault))
|
|
434
|
+
{
|
|
435
|
+
rewrite = true;
|
|
436
|
+
if (ctx->rewrite_to_params)
|
|
437
|
+
lfirst(lc_val) = makeTsExpr(ctx);
|
|
438
|
+
else
|
|
439
|
+
lfirst(lc_val) = makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc);
|
|
440
|
+
}
|
|
441
|
+
i++;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/* fill rest columns */
|
|
445
|
+
for (; i < relcache->relnatts; i++)
|
|
446
|
+
{
|
|
447
|
+
if (relcache->attr[i].use_timestamp == true)
|
|
448
|
+
{
|
|
449
|
+
rewrite = true;
|
|
450
|
+
if (ctx->rewrite_to_params)
|
|
451
|
+
values = lappend(values, makeTsExpr(ctx));
|
|
452
|
+
else
|
|
453
|
+
values = lappend(values,
|
|
454
|
+
makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc));
|
|
455
|
+
}
|
|
456
|
+
else
|
|
457
|
+
values = lappend(values, makeNode(SetToDefault));
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
else
|
|
462
|
+
{
|
|
463
|
+
/*
|
|
464
|
+
* INSERT INTO rel(col1, col2) VALUES (val, val2)
|
|
465
|
+
*
|
|
466
|
+
* if timestamp column is not given by column list
|
|
467
|
+
* add colname to column list and add timestamp to values list.
|
|
468
|
+
*/
|
|
469
|
+
int append_columns = 0;
|
|
470
|
+
int *append_columns_list;
|
|
471
|
+
ResTarget *col;
|
|
472
|
+
|
|
473
|
+
append_columns_list = (int *)malloc(sizeof(int)*relcache->relnatts);
|
|
474
|
+
|
|
475
|
+
for (i = 0; i < relcache->relnatts; i++)
|
|
476
|
+
{
|
|
477
|
+
if (relcache->attr[i].use_timestamp == false)
|
|
478
|
+
continue;
|
|
479
|
+
|
|
480
|
+
foreach (lc_col, i_stmt->cols)
|
|
481
|
+
{
|
|
482
|
+
col = lfirst(lc_col);
|
|
483
|
+
|
|
484
|
+
if (strcmp(relcache->attr[i].attrname, col->name) == 0)
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (lc_col == NULL)
|
|
489
|
+
{
|
|
490
|
+
/* column not found in query, append it.*/
|
|
491
|
+
rewrite = true;
|
|
492
|
+
col = makeNode(ResTarget);
|
|
493
|
+
col->name = relcache->attr[i].attrname;
|
|
494
|
+
col->indirection = NIL;
|
|
495
|
+
col->val = NULL;
|
|
496
|
+
i_stmt->cols = lappend(i_stmt->cols, col);
|
|
497
|
+
append_columns_list[append_columns++] = i;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
foreach (lc_row, selectStmt->valuesLists)
|
|
502
|
+
{
|
|
503
|
+
List *values = lfirst(lc_row);
|
|
504
|
+
|
|
505
|
+
/* replace DEFAULT to literal */
|
|
506
|
+
forboth (lc_col, i_stmt->cols, lc_val, values)
|
|
507
|
+
{
|
|
508
|
+
col = lfirst(lc_col);
|
|
509
|
+
for (i = 0; i < relcache->relnatts; i++)
|
|
510
|
+
{
|
|
511
|
+
if (strcmp(relcache->attr[i].attrname, col->name) == 0)
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (relcache->attr[i].use_timestamp == true && IsA(lfirst(lc_val), SetToDefault))
|
|
516
|
+
{
|
|
517
|
+
rewrite = true;
|
|
518
|
+
if (ctx->rewrite_to_params)
|
|
519
|
+
lfirst(lc_val) = makeTsExpr(ctx);
|
|
520
|
+
else
|
|
521
|
+
lfirst(lc_val) = makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/* add ts_const to values list */
|
|
526
|
+
for (i = 0; i < append_columns; i++)
|
|
527
|
+
{
|
|
528
|
+
if (ctx->rewrite_to_params)
|
|
529
|
+
values = lappend(values, makeTsExpr(ctx));
|
|
530
|
+
else
|
|
531
|
+
values = lappend(values,
|
|
532
|
+
makeStringConstFromQuery(ctx->backend, relcache->attr[append_columns_list[i]].adsrc));
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
free(append_columns_list);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return rewrite;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
/*
|
|
544
|
+
* rewrite UpdateStmt
|
|
545
|
+
*/
|
|
546
|
+
static bool
|
|
547
|
+
rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx)
|
|
548
|
+
{
|
|
549
|
+
TSRel *relcache = NULL;
|
|
550
|
+
ListCell *lc;
|
|
551
|
+
bool rewrite;
|
|
552
|
+
|
|
553
|
+
/* rewrite "update ... set col1 = now()" */
|
|
554
|
+
raw_expression_tree_walker(
|
|
555
|
+
(Node *) u_stmt->targetList,
|
|
556
|
+
rewrite_timestamp_walker, (void *) ctx);
|
|
557
|
+
|
|
558
|
+
raw_expression_tree_walker(
|
|
559
|
+
(Node *) u_stmt->whereClause,
|
|
560
|
+
rewrite_timestamp_walker, (void *) ctx);
|
|
561
|
+
|
|
562
|
+
raw_expression_tree_walker(
|
|
563
|
+
(Node *) u_stmt->fromClause,
|
|
564
|
+
rewrite_timestamp_walker, (void *) ctx);
|
|
565
|
+
|
|
566
|
+
rewrite = ctx->rewrite;
|
|
567
|
+
|
|
568
|
+
/* rewrite "update ... set col1 = default" */
|
|
569
|
+
foreach (lc, u_stmt->targetList)
|
|
570
|
+
{
|
|
571
|
+
ResTarget *res = (ResTarget *) lfirst(lc);
|
|
572
|
+
int i;
|
|
573
|
+
|
|
574
|
+
if (IsA(res->val, SetToDefault))
|
|
575
|
+
{
|
|
576
|
+
relcache = relcache_lookup(ctx);
|
|
577
|
+
if (relcache == NULL)
|
|
578
|
+
return false;
|
|
579
|
+
|
|
580
|
+
for (i = 0; i < relcache->relnatts; i++)
|
|
581
|
+
{
|
|
582
|
+
if (strcmp(relcache->attr[i].attrname, res->name) == 0)
|
|
583
|
+
{
|
|
584
|
+
if (relcache->attr[i].use_timestamp)
|
|
585
|
+
{
|
|
586
|
+
if (ctx->rewrite_to_params)
|
|
587
|
+
res->val = (Node *) makeTsExpr(ctx);
|
|
588
|
+
else
|
|
589
|
+
res->val = (Node *)makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc);
|
|
590
|
+
rewrite = true;
|
|
591
|
+
}
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return rewrite;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/*
|
|
601
|
+
* Rewrite `now()' to timestamp literal.
|
|
602
|
+
* returns query string as palloced string, or NULL if not to need rewrite.
|
|
603
|
+
*/
|
|
604
|
+
char *
|
|
605
|
+
rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node,
|
|
606
|
+
bool rewrite_to_params, POOL_SENT_MESSAGE *message)
|
|
607
|
+
{
|
|
608
|
+
TSRewriteContext ctx;
|
|
609
|
+
Node *stmt;
|
|
610
|
+
bool rewrite = false;
|
|
611
|
+
char *timestamp;
|
|
612
|
+
char *rewrite_query;
|
|
613
|
+
|
|
614
|
+
if (node == NULL)
|
|
615
|
+
return NULL;
|
|
616
|
+
|
|
617
|
+
if (!REPLICATION)
|
|
618
|
+
return NULL;
|
|
619
|
+
|
|
620
|
+
/* init context */
|
|
621
|
+
ctx.ts_const = makeNode(A_Const);
|
|
622
|
+
ctx.ts_const->val.type = T_String;
|
|
623
|
+
ctx.rewrite_to_params = rewrite_to_params;
|
|
624
|
+
ctx.backend = backend;
|
|
625
|
+
ctx.num_params = 0;
|
|
626
|
+
ctx.rewrite = false;
|
|
627
|
+
ctx.params = NIL;
|
|
628
|
+
|
|
629
|
+
/*
|
|
630
|
+
* Prepare?
|
|
631
|
+
*/
|
|
632
|
+
if (IsA(node, PrepareStmt))
|
|
633
|
+
{
|
|
634
|
+
stmt = ((PrepareStmt *) node)->query;
|
|
635
|
+
ctx.rewrite_to_params = true;
|
|
636
|
+
}
|
|
637
|
+
else
|
|
638
|
+
stmt = node;
|
|
639
|
+
|
|
640
|
+
if (IsA(stmt, InsertStmt))
|
|
641
|
+
{
|
|
642
|
+
InsertStmt *i_stmt = (InsertStmt *) stmt;
|
|
643
|
+
ctx.relname = nodeToString(i_stmt->relation);
|
|
644
|
+
rewrite = rewrite_timestamp_insert(i_stmt, &ctx);
|
|
645
|
+
}
|
|
646
|
+
else if (IsA(stmt, UpdateStmt))
|
|
647
|
+
{
|
|
648
|
+
UpdateStmt *u_stmt = (UpdateStmt *) stmt;
|
|
649
|
+
ctx.relname = nodeToString(u_stmt->relation);
|
|
650
|
+
rewrite = rewrite_timestamp_update(u_stmt, &ctx);
|
|
651
|
+
}
|
|
652
|
+
else if (IsA(stmt, DeleteStmt))
|
|
653
|
+
{
|
|
654
|
+
DeleteStmt *d_stmt = (DeleteStmt *) stmt;
|
|
655
|
+
raw_expression_tree_walker(
|
|
656
|
+
(Node *) d_stmt->usingClause,
|
|
657
|
+
rewrite_timestamp_walker, (void *) &ctx);
|
|
658
|
+
|
|
659
|
+
raw_expression_tree_walker(
|
|
660
|
+
(Node *) d_stmt->whereClause,
|
|
661
|
+
rewrite_timestamp_walker, (void *) &ctx);
|
|
662
|
+
rewrite = ctx.rewrite;
|
|
663
|
+
}
|
|
664
|
+
else if (IsA(stmt, ExecuteStmt))
|
|
665
|
+
{
|
|
666
|
+
ExecuteStmt *e_stmt = (ExecuteStmt *) stmt;
|
|
667
|
+
|
|
668
|
+
/* rewrite params */
|
|
669
|
+
raw_expression_tree_walker(
|
|
670
|
+
(Node *) e_stmt->params,
|
|
671
|
+
rewrite_timestamp_walker, (void *) &ctx);
|
|
672
|
+
|
|
673
|
+
rewrite = ctx.rewrite;
|
|
674
|
+
|
|
675
|
+
/* add params */
|
|
676
|
+
if (message)
|
|
677
|
+
{
|
|
678
|
+
int i;
|
|
679
|
+
|
|
680
|
+
for (i = 0; i < message->num_tsparams; i++)
|
|
681
|
+
{
|
|
682
|
+
e_stmt->params = lappend(e_stmt->params, ctx.ts_const);
|
|
683
|
+
rewrite = true;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
else
|
|
688
|
+
;
|
|
689
|
+
|
|
690
|
+
if (!rewrite)
|
|
691
|
+
return NULL;
|
|
692
|
+
|
|
693
|
+
if (ctx.rewrite_to_params && message)
|
|
694
|
+
{
|
|
695
|
+
ListCell *lc;
|
|
696
|
+
int num = ctx.num_params + 1;
|
|
697
|
+
|
|
698
|
+
/* renumber params */
|
|
699
|
+
foreach (lc, ctx.params)
|
|
700
|
+
{
|
|
701
|
+
ParamRef *param = (ParamRef *) lfirst(lc);
|
|
702
|
+
param->number = num++;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/* save to portal */
|
|
706
|
+
message->num_tsparams = list_length(ctx.params);
|
|
707
|
+
|
|
708
|
+
/* add param type */
|
|
709
|
+
if (IsA(node, PrepareStmt))
|
|
710
|
+
{
|
|
711
|
+
int i;
|
|
712
|
+
PrepareStmt *p_stmt = (PrepareStmt *) node;
|
|
713
|
+
|
|
714
|
+
for (i = 0; i < message->num_tsparams; i++)
|
|
715
|
+
p_stmt->argtypes =
|
|
716
|
+
lappend(p_stmt->argtypes, SystemTypeName("timestamptz"));
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
else
|
|
720
|
+
{
|
|
721
|
+
timestamp = get_current_timestamp(backend);
|
|
722
|
+
if (timestamp == NULL)
|
|
723
|
+
{
|
|
724
|
+
pool_error("rewrite_timestamp: could not get current timestamp");
|
|
725
|
+
return NULL;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
ctx.ts_const->val.val.str = timestamp;
|
|
729
|
+
}
|
|
730
|
+
rewrite_query = nodeToString(node);
|
|
731
|
+
|
|
732
|
+
return rewrite_query;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
/*
|
|
737
|
+
* rewrite Bind message to add parameter
|
|
738
|
+
*/
|
|
739
|
+
char *
|
|
740
|
+
bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend,
|
|
741
|
+
POOL_SENT_MESSAGE *message,
|
|
742
|
+
const char *orig_msg, int *len)
|
|
743
|
+
{
|
|
744
|
+
int16 tmp2,
|
|
745
|
+
num_params,
|
|
746
|
+
num_formats;
|
|
747
|
+
int32 tmp4;
|
|
748
|
+
int i,
|
|
749
|
+
ts_len,
|
|
750
|
+
copy_len;
|
|
751
|
+
const char *copy_from;
|
|
752
|
+
char *ts,
|
|
753
|
+
*copy_to,
|
|
754
|
+
*new_msg;
|
|
755
|
+
|
|
756
|
+
#ifdef TIMESTAMPDEBUG
|
|
757
|
+
fprintf(stderr, "message length:%d\n", *len);
|
|
758
|
+
for(i=0;i<*len;i++)
|
|
759
|
+
{
|
|
760
|
+
fprintf(stderr, "%02x ", orig_msg[i]);
|
|
761
|
+
}
|
|
762
|
+
#endif
|
|
763
|
+
|
|
764
|
+
ts = get_current_timestamp(backend);
|
|
765
|
+
if (ts == NULL)
|
|
766
|
+
{
|
|
767
|
+
pool_error("bind_rewrite_timestamp: could not get current timestamp");
|
|
768
|
+
return NULL;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
ts_len = strlen(ts);
|
|
772
|
+
|
|
773
|
+
*len += (strlen(ts) + sizeof(int32)) * message->num_tsparams;
|
|
774
|
+
new_msg = copy_to = (char *) malloc(*len + message->num_tsparams * sizeof(int16));
|
|
775
|
+
copy_from = orig_msg;
|
|
776
|
+
|
|
777
|
+
/* portal_name */
|
|
778
|
+
copy_len = strlen(copy_from) + 1;
|
|
779
|
+
memcpy(copy_to, copy_from, copy_len);
|
|
780
|
+
copy_to += copy_len; copy_from += copy_len;
|
|
781
|
+
|
|
782
|
+
/* stmt_name */
|
|
783
|
+
copy_len = strlen(copy_from) + 1;
|
|
784
|
+
memcpy(copy_to, copy_from, copy_len);
|
|
785
|
+
copy_to += copy_len; copy_from += copy_len;
|
|
786
|
+
|
|
787
|
+
/* format code */
|
|
788
|
+
memcpy(&tmp2, copy_from, sizeof(int16));
|
|
789
|
+
copy_len = sizeof(int16);
|
|
790
|
+
tmp2 = num_formats = ntohs(tmp2);
|
|
791
|
+
|
|
792
|
+
if (num_formats > 1)
|
|
793
|
+
{
|
|
794
|
+
/* enlarge message length */
|
|
795
|
+
*len += message->num_tsparams * sizeof(int16);
|
|
796
|
+
tmp2 += message->num_tsparams;
|
|
797
|
+
}
|
|
798
|
+
tmp2 = htons(tmp2);
|
|
799
|
+
memcpy(copy_to, &tmp2, copy_len); /* copy number of format codes */
|
|
800
|
+
copy_to += copy_len; copy_from += copy_len;
|
|
801
|
+
|
|
802
|
+
copy_len = num_formats * sizeof(int16);
|
|
803
|
+
|
|
804
|
+
memcpy(copy_to, copy_from, copy_len); /* copy format codes */
|
|
805
|
+
copy_to += copy_len; copy_from += copy_len;
|
|
806
|
+
|
|
807
|
+
if (num_formats > 1)
|
|
808
|
+
{
|
|
809
|
+
/* set format codes to zero(text) */
|
|
810
|
+
memset(copy_to, 0, message->num_tsparams * 2);
|
|
811
|
+
copy_to += sizeof(int16) * message->num_tsparams;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/* num params */
|
|
815
|
+
memcpy(&tmp2, copy_from, sizeof(int16));
|
|
816
|
+
copy_len = sizeof(int16);
|
|
817
|
+
num_params = ntohs(tmp2);
|
|
818
|
+
tmp2 = htons(num_params + message->num_tsparams);
|
|
819
|
+
memcpy(copy_to, &tmp2, sizeof(int16));
|
|
820
|
+
copy_to += copy_len; copy_from += copy_len;
|
|
821
|
+
|
|
822
|
+
/* params */
|
|
823
|
+
copy_len = 0;
|
|
824
|
+
for (i = 0; i < num_params; i++)
|
|
825
|
+
{
|
|
826
|
+
memcpy(&tmp4, copy_from + copy_len, sizeof(int32));
|
|
827
|
+
tmp4 = ntohl(tmp4); /* param length */
|
|
828
|
+
copy_len += sizeof(int32);
|
|
829
|
+
|
|
830
|
+
/* If param length is -1, it indicates that the value is NULL
|
|
831
|
+
* and we don't have value slot. So we don't add up copy_len.
|
|
832
|
+
*/
|
|
833
|
+
if (tmp4 > 0)
|
|
834
|
+
{
|
|
835
|
+
copy_len += tmp4;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
memcpy(copy_to, copy_from, copy_len);
|
|
839
|
+
copy_to += copy_len; copy_from += copy_len;
|
|
840
|
+
|
|
841
|
+
tmp4 = htonl(ts_len);
|
|
842
|
+
for (i = 0; i < message->num_tsparams; i++)
|
|
843
|
+
{
|
|
844
|
+
memcpy(copy_to, &tmp4, sizeof(int32));
|
|
845
|
+
copy_to += sizeof(int32);
|
|
846
|
+
memcpy(copy_to, ts, ts_len);
|
|
847
|
+
copy_to += ts_len;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/* result format code */
|
|
851
|
+
memcpy(&tmp2, copy_from, sizeof(int16));
|
|
852
|
+
copy_len = sizeof(int16);
|
|
853
|
+
copy_len += sizeof(int16) * ntohs(tmp2);
|
|
854
|
+
memcpy(copy_to, copy_from, copy_len);
|
|
855
|
+
|
|
856
|
+
return new_msg;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression)
|
|
860
|
+
{
|
|
861
|
+
A_Const *con;
|
|
862
|
+
POOL_SELECT_RESULT *res;
|
|
863
|
+
POOL_STATUS status;
|
|
864
|
+
char query[1024];
|
|
865
|
+
int len;
|
|
866
|
+
char *str;
|
|
867
|
+
|
|
868
|
+
snprintf(query, sizeof(query), "SELECT %s", expression);
|
|
869
|
+
status = do_query(MASTER(backend), query, &res, MAJOR(backend));
|
|
870
|
+
if (status != POOL_CONTINUE)
|
|
871
|
+
{
|
|
872
|
+
pool_error("makeStringConstFromQuery: do_query failed");
|
|
873
|
+
free_select_result(res);
|
|
874
|
+
return NULL;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
if (res->numrows != 1)
|
|
878
|
+
{
|
|
879
|
+
free_select_result(res);
|
|
880
|
+
return NULL;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
len = strlen(res->data[0]) + 1;
|
|
884
|
+
str = palloc(len);
|
|
885
|
+
strcpy(str, res->data[0]);
|
|
886
|
+
free_select_result(res);
|
|
887
|
+
|
|
888
|
+
con = makeNode(A_Const);
|
|
889
|
+
con->val.type = T_String;
|
|
890
|
+
con->val.val.str = str;
|
|
891
|
+
return con;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
/* from nodeFuncs.c start */
|
|
895
|
+
|
|
896
|
+
/*
|
|
897
|
+
* raw_expression_tree_walker --- walk raw parse trees
|
|
898
|
+
*
|
|
899
|
+
* This has exactly the same API as expression_tree_walker, but instead of
|
|
900
|
+
* walking post-analysis parse trees, it knows how to walk the node types
|
|
901
|
+
* found in raw grammar output. (There is not currently any need for a
|
|
902
|
+
* combined walker, so we keep them separate in the name of efficiency.)
|
|
903
|
+
* Unlike expression_tree_walker, there is no special rule about query
|
|
904
|
+
* boundaries: we descend to everything that's possibly interesting.
|
|
905
|
+
*
|
|
906
|
+
* Currently, the node type coverage extends to SelectStmt and everything
|
|
907
|
+
* that could appear under it, but not other statement types.
|
|
908
|
+
*/
|
|
909
|
+
bool
|
|
910
|
+
raw_expression_tree_walker(Node *node, bool (*walker) (), void *context)
|
|
911
|
+
{
|
|
912
|
+
ListCell *temp;
|
|
913
|
+
|
|
914
|
+
/*
|
|
915
|
+
* The walker has already visited the current node, and so we need only
|
|
916
|
+
* recurse into any sub-nodes it has.
|
|
917
|
+
*/
|
|
918
|
+
if (node == NULL)
|
|
919
|
+
return false;
|
|
920
|
+
|
|
921
|
+
/* Guard against stack overflow due to overly complex expressions */
|
|
922
|
+
/*
|
|
923
|
+
check_stack_depth();
|
|
924
|
+
*/
|
|
925
|
+
|
|
926
|
+
switch (nodeTag(node))
|
|
927
|
+
{
|
|
928
|
+
case T_SetToDefault:
|
|
929
|
+
case T_CurrentOfExpr:
|
|
930
|
+
case T_Integer:
|
|
931
|
+
case T_Float:
|
|
932
|
+
case T_String:
|
|
933
|
+
case T_BitString:
|
|
934
|
+
case T_Null:
|
|
935
|
+
case T_ParamRef:
|
|
936
|
+
case T_A_Const:
|
|
937
|
+
case T_A_Star:
|
|
938
|
+
/* primitive node types with no subnodes */
|
|
939
|
+
break;
|
|
940
|
+
case T_Alias:
|
|
941
|
+
/* we assume the colnames list isn't interesting */
|
|
942
|
+
break;
|
|
943
|
+
case T_RangeVar:
|
|
944
|
+
return walker(((RangeVar *) node)->alias, context);
|
|
945
|
+
case T_SubLink:
|
|
946
|
+
{
|
|
947
|
+
SubLink *sublink = (SubLink *) node;
|
|
948
|
+
|
|
949
|
+
if (walker(sublink->testexpr, context))
|
|
950
|
+
return true;
|
|
951
|
+
/* we assume the operName is not interesting */
|
|
952
|
+
if (walker(sublink->subselect, context))
|
|
953
|
+
return true;
|
|
954
|
+
}
|
|
955
|
+
break;
|
|
956
|
+
case T_CaseExpr:
|
|
957
|
+
{
|
|
958
|
+
CaseExpr *caseexpr = (CaseExpr *) node;
|
|
959
|
+
|
|
960
|
+
if (walker(caseexpr->arg, context))
|
|
961
|
+
return true;
|
|
962
|
+
/* we assume walker doesn't care about CaseWhens, either */
|
|
963
|
+
foreach(temp, caseexpr->args)
|
|
964
|
+
{
|
|
965
|
+
CaseWhen *when = (CaseWhen *) lfirst(temp);
|
|
966
|
+
|
|
967
|
+
Assert(IsA(when, CaseWhen));
|
|
968
|
+
if (walker(when->expr, context))
|
|
969
|
+
return true;
|
|
970
|
+
if (walker(when->result, context))
|
|
971
|
+
return true;
|
|
972
|
+
}
|
|
973
|
+
if (walker(caseexpr->defresult, context))
|
|
974
|
+
return true;
|
|
975
|
+
}
|
|
976
|
+
break;
|
|
977
|
+
case T_RowExpr:
|
|
978
|
+
/* Assume colnames isn't interesting */
|
|
979
|
+
return walker(((RowExpr *) node)->args, context);
|
|
980
|
+
case T_CoalesceExpr:
|
|
981
|
+
return walker(((CoalesceExpr *) node)->args, context);
|
|
982
|
+
case T_MinMaxExpr:
|
|
983
|
+
return walker(((MinMaxExpr *) node)->args, context);
|
|
984
|
+
case T_XmlExpr:
|
|
985
|
+
{
|
|
986
|
+
XmlExpr *xexpr = (XmlExpr *) node;
|
|
987
|
+
|
|
988
|
+
if (walker(xexpr->named_args, context))
|
|
989
|
+
return true;
|
|
990
|
+
/* we assume walker doesn't care about arg_names */
|
|
991
|
+
if (walker(xexpr->args, context))
|
|
992
|
+
return true;
|
|
993
|
+
}
|
|
994
|
+
break;
|
|
995
|
+
case T_NullTest:
|
|
996
|
+
return walker(((NullTest *) node)->arg, context);
|
|
997
|
+
case T_BooleanTest:
|
|
998
|
+
return walker(((BooleanTest *) node)->arg, context);
|
|
999
|
+
case T_JoinExpr:
|
|
1000
|
+
{
|
|
1001
|
+
JoinExpr *join = (JoinExpr *) node;
|
|
1002
|
+
|
|
1003
|
+
if (walker(join->larg, context))
|
|
1004
|
+
return true;
|
|
1005
|
+
if (walker(join->rarg, context))
|
|
1006
|
+
return true;
|
|
1007
|
+
if (walker(join->quals, context))
|
|
1008
|
+
return true;
|
|
1009
|
+
if (walker(join->alias, context))
|
|
1010
|
+
return true;
|
|
1011
|
+
/* using list is deemed uninteresting */
|
|
1012
|
+
}
|
|
1013
|
+
break;
|
|
1014
|
+
case T_IntoClause:
|
|
1015
|
+
{
|
|
1016
|
+
IntoClause *into = (IntoClause *) node;
|
|
1017
|
+
|
|
1018
|
+
if (walker(into->rel, context))
|
|
1019
|
+
return true;
|
|
1020
|
+
/* colNames, options are deemed uninteresting */
|
|
1021
|
+
}
|
|
1022
|
+
break;
|
|
1023
|
+
case T_List:
|
|
1024
|
+
foreach(temp, (List *) node)
|
|
1025
|
+
{
|
|
1026
|
+
if (walker((Node *) lfirst(temp), context))
|
|
1027
|
+
return true;
|
|
1028
|
+
}
|
|
1029
|
+
break;
|
|
1030
|
+
case T_SelectStmt:
|
|
1031
|
+
{
|
|
1032
|
+
SelectStmt *stmt = (SelectStmt *) node;
|
|
1033
|
+
|
|
1034
|
+
if (walker(stmt->distinctClause, context))
|
|
1035
|
+
return true;
|
|
1036
|
+
if (walker(stmt->intoClause, context))
|
|
1037
|
+
return true;
|
|
1038
|
+
if (walker(stmt->targetList, context))
|
|
1039
|
+
return true;
|
|
1040
|
+
if (walker(stmt->fromClause, context))
|
|
1041
|
+
return true;
|
|
1042
|
+
if (walker(stmt->whereClause, context))
|
|
1043
|
+
return true;
|
|
1044
|
+
if (walker(stmt->groupClause, context))
|
|
1045
|
+
return true;
|
|
1046
|
+
if (walker(stmt->havingClause, context))
|
|
1047
|
+
return true;
|
|
1048
|
+
if (walker(stmt->windowClause, context))
|
|
1049
|
+
return true;
|
|
1050
|
+
if (walker(stmt->withClause, context))
|
|
1051
|
+
return true;
|
|
1052
|
+
if (walker(stmt->valuesLists, context))
|
|
1053
|
+
return true;
|
|
1054
|
+
if (walker(stmt->sortClause, context))
|
|
1055
|
+
return true;
|
|
1056
|
+
if (walker(stmt->limitOffset, context))
|
|
1057
|
+
return true;
|
|
1058
|
+
if (walker(stmt->limitCount, context))
|
|
1059
|
+
return true;
|
|
1060
|
+
if (walker(stmt->lockingClause, context))
|
|
1061
|
+
return true;
|
|
1062
|
+
if (walker(stmt->larg, context))
|
|
1063
|
+
return true;
|
|
1064
|
+
if (walker(stmt->rarg, context))
|
|
1065
|
+
return true;
|
|
1066
|
+
}
|
|
1067
|
+
break;
|
|
1068
|
+
case T_A_Expr:
|
|
1069
|
+
{
|
|
1070
|
+
A_Expr *expr = (A_Expr *) node;
|
|
1071
|
+
|
|
1072
|
+
if (walker(expr->lexpr, context))
|
|
1073
|
+
return true;
|
|
1074
|
+
if (walker(expr->rexpr, context))
|
|
1075
|
+
return true;
|
|
1076
|
+
/* operator name is deemed uninteresting */
|
|
1077
|
+
}
|
|
1078
|
+
break;
|
|
1079
|
+
case T_ColumnRef:
|
|
1080
|
+
/* we assume the fields contain nothing interesting */
|
|
1081
|
+
break;
|
|
1082
|
+
case T_FuncCall:
|
|
1083
|
+
{
|
|
1084
|
+
FuncCall *fcall = (FuncCall *) node;
|
|
1085
|
+
|
|
1086
|
+
if (walker(fcall->args, context))
|
|
1087
|
+
return true;
|
|
1088
|
+
if (walker(fcall->over, context))
|
|
1089
|
+
return true;
|
|
1090
|
+
/* function name is deemed uninteresting */
|
|
1091
|
+
}
|
|
1092
|
+
break;
|
|
1093
|
+
case T_A_Indices:
|
|
1094
|
+
{
|
|
1095
|
+
A_Indices *indices = (A_Indices *) node;
|
|
1096
|
+
|
|
1097
|
+
if (walker(indices->lidx, context))
|
|
1098
|
+
return true;
|
|
1099
|
+
if (walker(indices->uidx, context))
|
|
1100
|
+
return true;
|
|
1101
|
+
}
|
|
1102
|
+
break;
|
|
1103
|
+
case T_A_Indirection:
|
|
1104
|
+
{
|
|
1105
|
+
A_Indirection *indir = (A_Indirection *) node;
|
|
1106
|
+
|
|
1107
|
+
if (walker(indir->arg, context))
|
|
1108
|
+
return true;
|
|
1109
|
+
if (walker(indir->indirection, context))
|
|
1110
|
+
return true;
|
|
1111
|
+
}
|
|
1112
|
+
break;
|
|
1113
|
+
case T_A_ArrayExpr:
|
|
1114
|
+
return walker(((A_ArrayExpr *) node)->elements, context);
|
|
1115
|
+
case T_ResTarget:
|
|
1116
|
+
{
|
|
1117
|
+
ResTarget *rt = (ResTarget *) node;
|
|
1118
|
+
|
|
1119
|
+
if (walker(rt->indirection, context))
|
|
1120
|
+
return true;
|
|
1121
|
+
if (walker(rt->val, context))
|
|
1122
|
+
return true;
|
|
1123
|
+
}
|
|
1124
|
+
break;
|
|
1125
|
+
case T_TypeCast:
|
|
1126
|
+
{
|
|
1127
|
+
TypeCast *tc = (TypeCast *) node;
|
|
1128
|
+
|
|
1129
|
+
if (walker(tc->arg, context))
|
|
1130
|
+
return true;
|
|
1131
|
+
if (walker(tc->typeName, context))
|
|
1132
|
+
return true;
|
|
1133
|
+
}
|
|
1134
|
+
break;
|
|
1135
|
+
case T_SortBy:
|
|
1136
|
+
return walker(((SortBy *) node)->node, context);
|
|
1137
|
+
case T_WindowDef:
|
|
1138
|
+
{
|
|
1139
|
+
WindowDef *wd = (WindowDef *) node;
|
|
1140
|
+
|
|
1141
|
+
if (walker(wd->partitionClause, context))
|
|
1142
|
+
return true;
|
|
1143
|
+
if (walker(wd->orderClause, context))
|
|
1144
|
+
return true;
|
|
1145
|
+
}
|
|
1146
|
+
break;
|
|
1147
|
+
case T_RangeSubselect:
|
|
1148
|
+
{
|
|
1149
|
+
RangeSubselect *rs = (RangeSubselect *) node;
|
|
1150
|
+
|
|
1151
|
+
if (walker(rs->subquery, context))
|
|
1152
|
+
return true;
|
|
1153
|
+
if (walker(rs->alias, context))
|
|
1154
|
+
return true;
|
|
1155
|
+
}
|
|
1156
|
+
break;
|
|
1157
|
+
case T_RangeFunction:
|
|
1158
|
+
{
|
|
1159
|
+
RangeFunction *rf = (RangeFunction *) node;
|
|
1160
|
+
|
|
1161
|
+
if (walker(rf->funccallnode, context))
|
|
1162
|
+
return true;
|
|
1163
|
+
if (walker(rf->alias, context))
|
|
1164
|
+
return true;
|
|
1165
|
+
}
|
|
1166
|
+
break;
|
|
1167
|
+
case T_TypeName:
|
|
1168
|
+
{
|
|
1169
|
+
TypeName *tn = (TypeName *) node;
|
|
1170
|
+
|
|
1171
|
+
if (walker(tn->typmods, context))
|
|
1172
|
+
return true;
|
|
1173
|
+
if (walker(tn->arrayBounds, context))
|
|
1174
|
+
return true;
|
|
1175
|
+
/* type name itself is deemed uninteresting */
|
|
1176
|
+
}
|
|
1177
|
+
break;
|
|
1178
|
+
case T_ColumnDef:
|
|
1179
|
+
{
|
|
1180
|
+
ColumnDef *coldef = (ColumnDef *) node;
|
|
1181
|
+
|
|
1182
|
+
if (walker(coldef->typeName, context))
|
|
1183
|
+
return true;
|
|
1184
|
+
if (walker(coldef->raw_default, context))
|
|
1185
|
+
return true;
|
|
1186
|
+
/* for now, constraints are ignored */
|
|
1187
|
+
}
|
|
1188
|
+
break;
|
|
1189
|
+
case T_LockingClause:
|
|
1190
|
+
return walker(((LockingClause *) node)->lockedRels, context);
|
|
1191
|
+
case T_XmlSerialize:
|
|
1192
|
+
{
|
|
1193
|
+
XmlSerialize *xs = (XmlSerialize *) node;
|
|
1194
|
+
|
|
1195
|
+
if (walker(xs->expr, context))
|
|
1196
|
+
return true;
|
|
1197
|
+
if (walker(xs->typeName, context))
|
|
1198
|
+
return true;
|
|
1199
|
+
}
|
|
1200
|
+
break;
|
|
1201
|
+
case T_WithClause:
|
|
1202
|
+
return walker(((WithClause *) node)->ctes, context);
|
|
1203
|
+
case T_CommonTableExpr:
|
|
1204
|
+
return walker(((CommonTableExpr *) node)->ctequery, context);
|
|
1205
|
+
default:
|
|
1206
|
+
/*
|
|
1207
|
+
elog(ERROR, "unrecognized node type: %d",
|
|
1208
|
+
(int) nodeTag(node));
|
|
1209
|
+
*/
|
|
1210
|
+
break;
|
|
1211
|
+
}
|
|
1212
|
+
return false;
|
|
1213
|
+
}
|
|
1214
|
+
/* from nodeFuncs.c end */
|
|
1215
|
+
|