pax_global_header00006660000000000000000000000064146630107150014515gustar00rootroot0000000000000052 comment=85e07af6ca4675a26fa2281370c37371b883b2a9 pg_hint_plan-REL17_1_7_0/000077500000000000000000000000001466301071500152005ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/.gitattributes000066400000000000000000000001101466301071500200630ustar00rootroot00000000000000# Test output files that contain extra whitespace *.out -whitespace pg_hint_plan-REL17_1_7_0/.github/000077500000000000000000000000001466301071500165405ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/.github/workflows/000077500000000000000000000000001466301071500205755ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/.github/workflows/test.yml000066400000000000000000000053201466301071500222770ustar00rootroot00000000000000name: regression test on: push: branches: - PG17 - PG16 - PG15 - PG14 - PG13 - PG12 pull_request: branches: - PG17 - PG16 - PG15 - PG14 - PG13 - PG12 schedule: # Runs at 00:00 UTC on every Sunday. - cron: "0 0 * * SUN" jobs: test: strategy: fail-fast: false runs-on: ubuntu-latest env: PGPORT: 55435 PGUSER: runner steps: - name: Checkout uses: actions/checkout@v2 - name: Set PATH and PG_VERSION run: | if [ "${{ github.ref_name }}" == 'PG17' ]; then echo "PG_VERSION=17" >> $GITHUB_ENV elif [ "${{ github.ref_name }}" == 'PG16' ]; then echo "PG_VERSION=16" >> $GITHUB_ENV elif [ "${{ github.ref_name }}" == 'PG15' ]; then echo "PG_VERSION=15" >> $GITHUB_ENV elif [ "${{ github.ref_name }}" == 'PG14' ]; then echo "PG_VERSION=14" >> $GITHUB_ENV elif [ "${{ github.ref_name }}" == 'PG13' ]; then echo "PG_VERSION=13" >> $GITHUB_ENV elif [ "${{ github.ref_name }}" == 'PG12' ]; then echo "PG_VERSION=12" >> $GITHUB_ENV fi - name: Build PostgreSQL run: | sudo -nH apt-get -q update sudo -nH apt-get -y install libreadline-dev zlib1g-dev bison flex gcc wget -q -O postgresql.tar.bz2 https://ftp.postgresql.org/pub/snapshot/${PG_VERSION}/postgresql-${PG_VERSION}-snapshot.tar.bz2 mkdir -p ~/source tar --extract --file postgresql.tar.bz2 --directory ~/source --strip-components 1 cd ~/source ./configure --prefix=$HOME/pgsql --enable-cassert --enable-debug make -j 2 make -C contrib/file_fdw make -C contrib/btree_gist make -C contrib/btree_gin sudo make install sudo make -C contrib/file_fdw install sudo make -C contrib/btree_gist install sudo make -C contrib/btree_gin install echo "$HOME/pgsql/bin" >> $GITHUB_PATH - name: Build pg_hint_plan run: | make USE_PGXS=1 clean make USE_PGXS=1 PG_CONFIG=$(which pg_config) sudo make USE_PGXS=1 PG_CONFIG=$(which pg_config) install - name: Start PostgreSQL Server run: | initdb -D regression_data --no-locale -E UTF8 -A trust echo "shared_preload_libraries = 'pg_hint_plan'" >> regression_data/postgresql.conf pg_ctl start -D regression_data -o "-p ${PGPORT}" - name: Make installcheck run: | make installcheck USE_PGXS=1 || status=$? if test -f regression.diffs; then cat regression.diffs; fi exit $status pg_hint_plan-REL17_1_7_0/.gitignore000066400000000000000000000003731466301071500171730ustar00rootroot00000000000000# Global excludes across all subdirectories *.o *.so *.bc tags regression.* *.tar.gz *~ # Generated subdirectories /.deps/ /log/ /results/ /tmp_check/ /RPMS/ # Generated files /query_scan.c # Documentation artifacts docs/_build docs/locale/**/*.mo pg_hint_plan-REL17_1_7_0/COPYRIGHT000066400000000000000000000030711466301071500164740ustar00rootroot00000000000000Copyright (c) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the NIPPON TELEGRAPH AND TELEPHONE CORPORATION (NTT) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. pg_hint_plan-REL17_1_7_0/COPYRIGHT.postgresql000066400000000000000000000024231466301071500206760ustar00rootroot00000000000000core.c and make_join_rel.c are the parts of PostgreSQL Database Management System (formerly known as Postgres, then as Postgres95). Copyright holders of those files are following organizations: Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group Portions Copyright (c) 1994, The Regents of the University of California Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. pg_hint_plan-REL17_1_7_0/META.json000066400000000000000000000020041466301071500166150ustar00rootroot00000000000000{ "name": "pg_hint_plan17", "abstract": "Query hints in SQL comments", "description": "This library adds support for query hints in SQL comments in PostgreSQL 17.", "version": "1.7.0", "maintainer": [ "Michael Paquier " ], "license": "bsd", "prereqs": { "runtime": { "requires": { "PostgreSQL": ">= 17.0.0, < 18.0.0" } } }, "provides": { "pg_hint_plan": { "abstract": "Query hints in SQL comments", "file": "pg_hint_plan--1.3.0.sql", "docfile": "README.md", "version": "1.7.0" } }, "resources": { "bugtracker": { "web": "https://github.com/ossc-db/pg_hint_plan/issues" }, "repository": { "url": "https://github.com/ossc-db/pg_hint_plan.git", "web": "https://github.com/ossc-db/pg_hint_plan/", "type": "git" } }, "meta-spec": { "version": "1.0.0", "url": "https://pgxn.org/meta/spec.txt" }, "tags": [ "sql", "plan", "performance", "hint" ] } pg_hint_plan-REL17_1_7_0/Makefile000066400000000000000000000046171466301071500166500ustar00rootroot00000000000000# # pg_hint_plan: Makefile # # Copyright (c) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # MODULE_big = pg_hint_plan OBJS = \ $(WIN32RES) \ pg_hint_plan.o \ query_scan.o HINTPLANVER = 1.7.0 REGRESS = init base_plan pg_hint_plan ut-init ut-A ut-S ut-J ut-L ut-G ut-R \ ut-fdw ut-W ut-T ut-fini plpgsql hint_table oldextversions REGRESS_OPTS = --encoding=UTF8 EXTENSION = pg_hint_plan DATA = \ pg_hint_plan--1.3.0.sql \ pg_hint_plan--1.3.0--1.3.1.sql \ pg_hint_plan--1.3.1--1.3.2.sql \ pg_hint_plan--1.3.2--1.3.3.sql \ pg_hint_plan--1.3.3--1.3.4.sql \ pg_hint_plan--1.3.5--1.3.6.sql \ pg_hint_plan--1.3.4--1.3.5.sql \ pg_hint_plan--1.3.6--1.3.7.sql \ pg_hint_plan--1.3.7--1.3.8.sql \ pg_hint_plan--1.3.8--1.3.9.sql \ pg_hint_plan--1.3.9--1.3.10.sql \ pg_hint_plan--1.3.10--1.4.sql \ pg_hint_plan--1.4--1.4.1.sql \ pg_hint_plan--1.4.1--1.4.2.sql \ pg_hint_plan--1.4.2--1.4.3.sql \ pg_hint_plan--1.4.3--1.5.sql \ pg_hint_plan--1.5--1.5.1.sql \ pg_hint_plan--1.5.1--1.5.2.sql \ pg_hint_plan--1.5.2--1.6.0.sql \ pg_hint_plan--1.6.0--1.6.1.sql \ pg_hint_plan--1.6.1--1.7.0.sql EXTRA_CLEAN = RPMS # Switch environment between standalone make and make check with # EXTRA_INSTALL from PostgreSQL tree # run the following command in the PG tree to run a regression test # loading this module. # $ make check EXTRA_INSTALL= EXTRA_REGRESS_OPTS="--temp-config /pg_hint_plan.conf" ifeq ($(wildcard $(DESTDIR)/../src/Makefile.global),) PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) else subdir = `pwd` top_builddir = $(DESTDIR)/.. include $(DESTDIR)/../src/Makefile.global include $(DESTDIR)/../contrib/contrib-global.mk endif STARBALL17 = pg_hint_plan17-$(HINTPLANVER).tar.gz STARBALLS = $(STARBALL17) TARSOURCES = Makefile *.c *.h COPYRIGHT* \ pg_hint_plan--*.sql \ pg_hint_plan.control \ docs/* expected/*.out sql/*.sql \ data/data.csv SPECS/*.spec rpms: rpm17 # pg_hint_plan.c includes core.c and make_join_rel.c pg_hint_plan.o: core.c make_join_rel.c $(STARBALLS): $(TARSOURCES) if [ -h $(subst .tar.gz,,$@) ]; then rm $(subst .tar.gz,,$@); fi if [ -e $(subst .tar.gz,,$@) ]; then \ echo "$(subst .tar.gz,,$@) is not a symlink. Stop."; \ exit 1; \ fi ln -s . $(subst .tar.gz,,$@) tar -chzf $@ $(addprefix $(subst .tar.gz,,$@)/, $^) rm $(subst .tar.gz,,$@) rpm17: $(STARBALL17) MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_hint_plan17.spec pg_hint_plan-REL17_1_7_0/README.md000066400000000000000000000021131466301071500164540ustar00rootroot00000000000000# pg\_hint\_plan 1.7 `pg_hint_plan` makes it possible to tweak PostgreSQL execution plans using so-called "hints" in SQL comments, like `/*+ SeqScan(a) */`. PostgreSQL uses a cost-based optimizer, that uses data statistics, not static rules. The planner (optimizer) estimates costs of each possible execution plans for a SQL statement, then executes the plan with the lowest cost. The planner does its best to select the best execution plan, but it is far from perfect, since it may not count some data properties, like correlation between columns. For more details, please see the various documentations available in the **docs/** directory: 1. [Description](docs/description.md) 1. [The hint table](docs/hint_table.md) 1. [Installation](docs/installation.md) 1. [Uninstallation](docs/uninstallation.md) 1. [Details in hinting](docs/hint_details.md) 1. [Errors](docs/errors.md) 1. [Functional limitations](docs/functional_limitations.md) 1. [Requirements](docs/requirements.md) 1. [Hints list](docs/hint_list.md) * * * * * Copyright (c) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION pg_hint_plan-REL17_1_7_0/SPECS/000077500000000000000000000000001466301071500160555ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/SPECS/pg_hint_plan17.spec000066400000000000000000000064171466301071500215530ustar00rootroot00000000000000# SPEC file for pg_hint_plan # Copyright(c) 2022-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION %define _pgdir /usr/pgsql-17 %define _bindir %{_pgdir}/bin %define _libdir %{_pgdir}/lib %define _datadir %{_pgdir}/share %define _bcdir %{_libdir}/bitcode %define _mybcdir %{_bcdir}/pg_hint_plan %if "%(echo ${MAKE_ROOT})" != "" %define _rpmdir %(echo ${MAKE_ROOT})/RPMS %define _sourcedir %(echo ${MAKE_ROOT}) %endif ## Set general information for pg_hint_plan. Summary: Optimizer hint on PostgreSQL 17 Name: pg_hint_plan17 Version: 1.7.0 Release: 1%{?dist} License: BSD Group: Applications/Databases Source0: %{name}-%{version}.tar.gz URL: https://github.com/ossc-db/pg_hint_plan BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n) Vendor: NIPPON TELEGRAPH AND TELEPHONE CORPORATION ## We use postgresql-devel package BuildRequires: postgresql17-devel Requires: postgresql17-server ## Description for "pg_hint_plan" %description pg_hint_plan provides capability to tweak execution plans to be executed on PostgreSQL. Note that this package is available for only PostgreSQL 17. %package llvmjit Requires: postgresql17-server, postgresql17-llvmjit Requires: pg_hint_plan17 = 1.7.0 Summary: Just-in-time compilation support for pg_hint_plan17 %description llvmjit Just-in-time compilation support for pg_hint_plan17 ## pre work for build pg_hint_plan %prep PATH=/usr/pgsql-17/bin:$PATH if [ "${MAKE_ROOT}" != "" ]; then pushd ${MAKE_ROOT} make clean %{name}-%{version}.tar.gz popd fi if [ ! -d %{_rpmdir} ]; then mkdir -p %{_rpmdir}; fi %setup -q ## Set variables for build environment %build PATH=/usr/pgsql-17/bin:$PATH make USE_PGXS=1 LDFLAGS+=-Wl,--build-id %{?_smp_mflags} ## Set variables for install %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} %clean rm -rf %{buildroot} %files %defattr(0755,root,root) %{_libdir}/pg_hint_plan.so %defattr(0644,root,root) %{_datadir}/extension/pg_hint_plan--1.3.0.sql %{_datadir}/extension/pg_hint_plan--1.3.0--1.3.1.sql %{_datadir}/extension/pg_hint_plan--1.3.1--1.3.2.sql %{_datadir}/extension/pg_hint_plan--1.3.2--1.3.3.sql %{_datadir}/extension/pg_hint_plan--1.3.3--1.3.4.sql %{_datadir}/extension/pg_hint_plan--1.3.4--1.3.5.sql %{_datadir}/extension/pg_hint_plan--1.3.5--1.3.6.sql %{_datadir}/extension/pg_hint_plan--1.3.6--1.3.7.sql %{_datadir}/extension/pg_hint_plan--1.3.7--1.3.8.sql %{_datadir}/extension/pg_hint_plan--1.3.8--1.3.9.sql %{_datadir}/extension/pg_hint_plan--1.3.9--1.3.10.sql %{_datadir}/extension/pg_hint_plan--1.3.10--1.4.sql %{_datadir}/extension/pg_hint_plan--1.4--1.4.1.sql %{_datadir}/extension/pg_hint_plan--1.4.1--1.4.2.sql %{_datadir}/extension/pg_hint_plan--1.4.2--1.4.3.sql %{_datadir}/extension/pg_hint_plan--1.4.3--1.5.sql %{_datadir}/extension/pg_hint_plan--1.5--1.5.1.sql %{_datadir}/extension/pg_hint_plan--1.5.1--1.5.2.sql %{_datadir}/extension/pg_hint_plan--1.5.2--1.6.0.sql %{_datadir}/extension/pg_hint_plan--1.6.0--1.6.1.sql %{_datadir}/extension/pg_hint_plan--1.6.1--1.7.0.sql %{_datadir}/extension/pg_hint_plan.control %files llvmjit %defattr(0755,root,root) %{_mybcdir} %defattr(0644,root,root) %{_bcdir}/pg_hint_plan.index.bc %{_mybcdir}/pg_hint_plan.bc # History of pg_hint_plan. %changelog * Tue Aug 29 2023 Michael Paquier - Support PostgreSQL 17. pg_hint_plan-REL17_1_7_0/core.c000066400000000000000000001335131466301071500163020ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * core.c * Routines copied from PostgreSQL core distribution. * * The main purpose of this files is having access to static functions in core. * Another purpose is tweaking functions behavior by replacing part of them by * macro definitions. See at the end of pg_hint_plan.c for details. Anyway, * this file *must* contain required functions without making any change. * * This file contains the following functions from corresponding files. * * src/backend/optimizer/path/allpaths.c * * public functions: * standard_join_search(): This funcion is not static. The reason for * including this function is make_rels_by_clause_joins. In order to * avoid generating apparently unwanted join combination, we decided to * change the behavior of make_join_rel, which is called under this * function. * * static functions: * set_plain_rel_pathlist() * create_plain_partial_paths() * * src/backend/optimizer/path/joinrels.c * * public functions: * join_search_one_level(): We have to modify this to call my definition of * make_rels_by_clause_joins. * * static functions: * make_rels_by_clause_joins() * make_rels_by_clauseless_joins() * join_is_legal() * has_join_restriction() * restriction_is_constant_false() * build_child_join_sjinfo() * get_matching_part_pairs() * compute_partition_bounds() * try_partitionwise_join() * * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- */ #include "access/tsmapi.h" #include "catalog/pg_operator.h" #include "foreign/fdwapi.h" /* * set_plain_rel_pathlist * Build access paths for a plain relation (no subquery, no inheritance) */ static void set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) { Relids required_outer; /* * We don't support pushing join clauses into the quals of a seqscan, but * it could still have required parameterization due to LATERAL refs in * its tlist. */ required_outer = rel->lateral_relids; /* Consider sequential scan */ add_path(rel, create_seqscan_path(root, rel, required_outer, 0)); /* If appropriate, consider parallel sequential scan */ if (rel->consider_parallel && required_outer == NULL) create_plain_partial_paths(root, rel); /* Consider index scans */ create_index_paths(root, rel); /* Consider TID scans */ create_tidscan_paths(root, rel); } /* * standard_join_search * Find possible joinpaths for a query by successively finding ways * to join component relations into join relations. * * 'levels_needed' is the number of iterations needed, ie, the number of * independent jointree items in the query. This is > 1. * * 'initial_rels' is a list of RelOptInfo nodes for each independent * jointree item. These are the components to be joined together. * Note that levels_needed == list_length(initial_rels). * * Returns the final level of join relations, i.e., the relation that is * the result of joining all the original relations together. * At least one implementation path must be provided for this relation and * all required sub-relations. * * To support loadable plugins that modify planner behavior by changing the * join searching algorithm, we provide a hook variable that lets a plugin * replace or supplement this function. Any such hook must return the same * final join relation as the standard code would, but it might have a * different set of implementation paths attached, and only the sub-joinrels * needed for these paths need have been instantiated. * * Note to plugin authors: the functions invoked during standard_join_search() * modify root->join_rel_list and root->join_rel_hash. If you want to do more * than one join-order search, you'll probably need to save and restore the * original states of those data structures. See geqo_eval() for an example. */ RelOptInfo * standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels) { int lev; RelOptInfo *rel; /* * This function cannot be invoked recursively within any one planning * problem, so join_rel_level[] can't be in use already. */ Assert(root->join_rel_level == NULL); /* * We employ a simple "dynamic programming" algorithm: we first find all * ways to build joins of two jointree items, then all ways to build joins * of three items (from two-item joins and single items), then four-item * joins, and so on until we have considered all ways to join all the * items into one rel. * * root->join_rel_level[j] is a list of all the j-item rels. Initially we * set root->join_rel_level[1] to represent all the single-jointree-item * relations. */ root->join_rel_level = (List **) palloc0((levels_needed + 1) * sizeof(List *)); root->join_rel_level[1] = initial_rels; for (lev = 2; lev <= levels_needed; lev++) { ListCell *lc; /* * Determine all possible pairs of relations to be joined at this * level, and build paths for making each one from every available * pair of lower-level relations. */ join_search_one_level(root, lev); /* * Run generate_partitionwise_join_paths() and * generate_useful_gather_paths() for each just-processed joinrel. We * could not do this earlier because both regular and partial paths * can get added to a particular joinrel at multiple times within * join_search_one_level. * * After that, we're done creating paths for the joinrel, so run * set_cheapest(). */ foreach(lc, root->join_rel_level[lev]) { rel = (RelOptInfo *) lfirst(lc); /* Create paths for partitionwise joins. */ generate_partitionwise_join_paths(root, rel); /* * Except for the topmost scan/join rel, consider gathering * partial paths. We'll do the same for the topmost scan/join rel * once we know the final targetlist (see grouping_planner's and * its call to apply_scanjoin_target_to_paths). */ if (!bms_equal(rel->relids, root->all_query_rels)) generate_useful_gather_paths(root, rel, false); /* Find and save the cheapest paths for this rel */ set_cheapest(rel); #ifdef OPTIMIZER_DEBUG pprint(rel); #endif } } /* * We should have a single rel at the final level. */ if (root->join_rel_level[levels_needed] == NIL) elog(ERROR, "failed to build any %d-way joins", levels_needed); Assert(list_length(root->join_rel_level[levels_needed]) == 1); rel = (RelOptInfo *) linitial(root->join_rel_level[levels_needed]); root->join_rel_level = NULL; return rel; } /* * create_plain_partial_paths * Build partial access paths for parallel scan of a plain relation */ static void create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel) { int parallel_workers; parallel_workers = compute_parallel_worker(rel, rel->pages, -1, max_parallel_workers_per_gather); /* If any limit was set to zero, the user doesn't want a parallel scan. */ if (parallel_workers <= 0) return; /* Add an unordered partial path based on a parallel sequential scan. */ add_partial_path(rel, create_seqscan_path(root, rel, NULL, parallel_workers)); } /* * join_search_one_level * Consider ways to produce join relations containing exactly 'level' * jointree items. (This is one step of the dynamic-programming method * embodied in standard_join_search.) Join rel nodes for each feasible * combination of lower-level rels are created and returned in a list. * Implementation paths are created for each such joinrel, too. * * level: level of rels we want to make this time * root->join_rel_level[j], 1 <= j < level, is a list of rels containing j items * * The result is returned in root->join_rel_level[level]. */ void join_search_one_level(PlannerInfo *root, int level) { List **joinrels = root->join_rel_level; ListCell *r; int k; Assert(joinrels[level] == NIL); /* Set join_cur_level so that new joinrels are added to proper list */ root->join_cur_level = level; /* * First, consider left-sided and right-sided plans, in which rels of * exactly level-1 member relations are joined against initial relations. * We prefer to join using join clauses, but if we find a rel of level-1 * members that has no join clauses, we will generate Cartesian-product * joins against all initial rels not already contained in it. */ foreach(r, joinrels[level - 1]) { RelOptInfo *old_rel = (RelOptInfo *) lfirst(r); if (old_rel->joininfo != NIL || old_rel->has_eclass_joins || has_join_restriction(root, old_rel)) { int first_rel; /* * There are join clauses or join order restrictions relevant to * this rel, so consider joins between this rel and (only) those * initial rels it is linked to by a clause or restriction. * * At level 2 this condition is symmetric, so there is no need to * look at initial rels before this one in the list; we already * considered such joins when we were at the earlier rel. (The * mirror-image joins are handled automatically by make_join_rel.) * In later passes (level > 2), we join rels of the previous level * to each initial rel they don't already include but have a join * clause or restriction with. */ if (level == 2) /* consider remaining initial rels */ first_rel = foreach_current_index(r) + 1; else first_rel = 0; make_rels_by_clause_joins(root, old_rel, joinrels[1], first_rel); } else { /* * Oops, we have a relation that is not joined to any other * relation, either directly or by join-order restrictions. * Cartesian product time. * * We consider a cartesian product with each not-already-included * initial rel, whether it has other join clauses or not. At * level 2, if there are two or more clauseless initial rels, we * will redundantly consider joining them in both directions; but * such cases aren't common enough to justify adding complexity to * avoid the duplicated effort. */ make_rels_by_clauseless_joins(root, old_rel, joinrels[1]); } } /* * Now, consider "bushy plans" in which relations of k initial rels are * joined to relations of level-k initial rels, for 2 <= k <= level-2. * * We only consider bushy-plan joins for pairs of rels where there is a * suitable join clause (or join order restriction), in order to avoid * unreasonable growth of planning time. */ for (k = 2;; k++) { int other_level = level - k; /* * Since make_join_rel(x, y) handles both x,y and y,x cases, we only * need to go as far as the halfway point. */ if (k > other_level) break; foreach(r, joinrels[k]) { RelOptInfo *old_rel = (RelOptInfo *) lfirst(r); int first_rel; ListCell *r2; /* * We can ignore relations without join clauses here, unless they * participate in join-order restrictions --- then we might have * to force a bushy join plan. */ if (old_rel->joininfo == NIL && !old_rel->has_eclass_joins && !has_join_restriction(root, old_rel)) continue; if (k == other_level) /* only consider remaining rels */ first_rel = foreach_current_index(r) + 1; else first_rel = 0; for_each_from(r2, joinrels[other_level], first_rel) { RelOptInfo *new_rel = (RelOptInfo *) lfirst(r2); if (!bms_overlap(old_rel->relids, new_rel->relids)) { /* * OK, we can build a rel of the right level from this * pair of rels. Do so if there is at least one relevant * join clause or join order restriction. */ if (have_relevant_joinclause(root, old_rel, new_rel) || have_join_order_restriction(root, old_rel, new_rel)) { (void) make_join_rel(root, old_rel, new_rel); } } } } } /*---------- * Last-ditch effort: if we failed to find any usable joins so far, force * a set of cartesian-product joins to be generated. This handles the * special case where all the available rels have join clauses but we * cannot use any of those clauses yet. This can only happen when we are * considering a join sub-problem (a sub-joinlist) and all the rels in the * sub-problem have only join clauses with rels outside the sub-problem. * An example is * * SELECT ... FROM a INNER JOIN b ON TRUE, c, d, ... * WHERE a.w = c.x and b.y = d.z; * * If the "a INNER JOIN b" sub-problem does not get flattened into the * upper level, we must be willing to make a cartesian join of a and b; * but the code above will not have done so, because it thought that both * a and b have joinclauses. We consider only left-sided and right-sided * cartesian joins in this case (no bushy). *---------- */ if (joinrels[level] == NIL) { /* * This loop is just like the first one, except we always call * make_rels_by_clauseless_joins(). */ foreach(r, joinrels[level - 1]) { RelOptInfo *old_rel = (RelOptInfo *) lfirst(r); make_rels_by_clauseless_joins(root, old_rel, joinrels[1]); } /*---------- * When special joins are involved, there may be no legal way * to make an N-way join for some values of N. For example consider * * SELECT ... FROM t1 WHERE * x IN (SELECT ... FROM t2,t3 WHERE ...) AND * y IN (SELECT ... FROM t4,t5 WHERE ...) * * We will flatten this query to a 5-way join problem, but there are * no 4-way joins that join_is_legal() will consider legal. We have * to accept failure at level 4 and go on to discover a workable * bushy plan at level 5. * * However, if there are no special joins and no lateral references * then join_is_legal() should never fail, and so the following sanity * check is useful. *---------- */ if (joinrels[level] == NIL && root->join_info_list == NIL && !root->hasLateralRTEs) elog(ERROR, "failed to build any %d-way joins", level); } } /* * make_rels_by_clause_joins * Build joins between the given relation 'old_rel' and other relations * that participate in join clauses that 'old_rel' also participates in * (or participate in join-order restrictions with it). * The join rels are returned in root->join_rel_level[join_cur_level]. * * Note: at levels above 2 we will generate the same joined relation in * multiple ways --- for example (a join b) join c is the same RelOptInfo as * (b join c) join a, though the second case will add a different set of Paths * to it. This is the reason for using the join_rel_level mechanism, which * automatically ensures that each new joinrel is only added to the list once. * * 'old_rel' is the relation entry for the relation to be joined * 'other_rels': a list containing the other rels to be considered for joining * 'first_rel_idx': the first rel to be considered in 'other_rels' * * Currently, this is only used with initial rels in other_rels, but it * will work for joining to joinrels too. */ static void make_rels_by_clause_joins(PlannerInfo *root, RelOptInfo *old_rel, List *other_rels, int first_rel_idx) { ListCell *l; for_each_from(l, other_rels, first_rel_idx) { RelOptInfo *other_rel = (RelOptInfo *) lfirst(l); if (!bms_overlap(old_rel->relids, other_rel->relids) && (have_relevant_joinclause(root, old_rel, other_rel) || have_join_order_restriction(root, old_rel, other_rel))) { (void) make_join_rel(root, old_rel, other_rel); } } } /* * make_rels_by_clauseless_joins * Given a relation 'old_rel' and a list of other relations * 'other_rels', create a join relation between 'old_rel' and each * member of 'other_rels' that isn't already included in 'old_rel'. * The join rels are returned in root->join_rel_level[join_cur_level]. * * 'old_rel' is the relation entry for the relation to be joined * 'other_rels': a list containing the other rels to be considered for joining * * Currently, this is only used with initial rels in other_rels, but it would * work for joining to joinrels too. */ static void make_rels_by_clauseless_joins(PlannerInfo *root, RelOptInfo *old_rel, List *other_rels) { ListCell *l; foreach(l, other_rels) { RelOptInfo *other_rel = (RelOptInfo *) lfirst(l); if (!bms_overlap(other_rel->relids, old_rel->relids)) { (void) make_join_rel(root, old_rel, other_rel); } } } /* * join_is_legal * Determine whether a proposed join is legal given the query's * join order constraints; and if it is, determine the join type. * * Caller must supply not only the two rels, but the union of their relids. * (We could simplify the API by computing joinrelids locally, but this * would be redundant work in the normal path through make_join_rel. * Note that this value does NOT include the RT index of any outer join that * might need to be performed here, so it's not the canonical identifier * of the join relation.) * * On success, *sjinfo_p is set to NULL if this is to be a plain inner join, * else it's set to point to the associated SpecialJoinInfo node. Also, * *reversed_p is set true if the given relations need to be swapped to * match the SpecialJoinInfo node. */ static bool join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, Relids joinrelids, SpecialJoinInfo **sjinfo_p, bool *reversed_p) { SpecialJoinInfo *match_sjinfo; bool reversed; bool unique_ified; bool must_be_leftjoin; ListCell *l; /* * Ensure output params are set on failure return. This is just to * suppress uninitialized-variable warnings from overly anal compilers. */ *sjinfo_p = NULL; *reversed_p = false; /* * If we have any special joins, the proposed join might be illegal; and * in any case we have to determine its join type. Scan the join info * list for matches and conflicts. */ match_sjinfo = NULL; reversed = false; unique_ified = false; must_be_leftjoin = false; foreach(l, root->join_info_list) { SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); /* * This special join is not relevant unless its RHS overlaps the * proposed join. (Check this first as a fast path for dismissing * most irrelevant SJs quickly.) */ if (!bms_overlap(sjinfo->min_righthand, joinrelids)) continue; /* * Also, not relevant if proposed join is fully contained within RHS * (ie, we're still building up the RHS). */ if (bms_is_subset(joinrelids, sjinfo->min_righthand)) continue; /* * Also, not relevant if SJ is already done within either input. */ if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) && bms_is_subset(sjinfo->min_righthand, rel1->relids)) continue; if (bms_is_subset(sjinfo->min_lefthand, rel2->relids) && bms_is_subset(sjinfo->min_righthand, rel2->relids)) continue; /* * If it's a semijoin and we already joined the RHS to any other rels * within either input, then we must have unique-ified the RHS at that * point (see below). Therefore the semijoin is no longer relevant in * this join path. */ if (sjinfo->jointype == JOIN_SEMI) { if (bms_is_subset(sjinfo->syn_righthand, rel1->relids) && !bms_equal(sjinfo->syn_righthand, rel1->relids)) continue; if (bms_is_subset(sjinfo->syn_righthand, rel2->relids) && !bms_equal(sjinfo->syn_righthand, rel2->relids)) continue; } /* * If one input contains min_lefthand and the other contains * min_righthand, then we can perform the SJ at this join. * * Reject if we get matches to more than one SJ; that implies we're * considering something that's not really valid. */ if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) && bms_is_subset(sjinfo->min_righthand, rel2->relids)) { if (match_sjinfo) return false; /* invalid join path */ match_sjinfo = sjinfo; reversed = false; } else if (bms_is_subset(sjinfo->min_lefthand, rel2->relids) && bms_is_subset(sjinfo->min_righthand, rel1->relids)) { if (match_sjinfo) return false; /* invalid join path */ match_sjinfo = sjinfo; reversed = true; } else if (sjinfo->jointype == JOIN_SEMI && bms_equal(sjinfo->syn_righthand, rel2->relids) && create_unique_path(root, rel2, rel2->cheapest_total_path, sjinfo) != NULL) { /*---------- * For a semijoin, we can join the RHS to anything else by * unique-ifying the RHS (if the RHS can be unique-ified). * We will only get here if we have the full RHS but less * than min_lefthand on the LHS. * * The reason to consider such a join path is exemplified by * SELECT ... FROM a,b WHERE (a.x,b.y) IN (SELECT c1,c2 FROM c) * If we insist on doing this as a semijoin we will first have * to form the cartesian product of A*B. But if we unique-ify * C then the semijoin becomes a plain innerjoin and we can join * in any order, eg C to A and then to B. When C is much smaller * than A and B this can be a huge win. So we allow C to be * joined to just A or just B here, and then make_join_rel has * to handle the case properly. * * Note that actually we'll allow unique-ified C to be joined to * some other relation D here, too. That is legal, if usually not * very sane, and this routine is only concerned with legality not * with whether the join is good strategy. *---------- */ if (match_sjinfo) return false; /* invalid join path */ match_sjinfo = sjinfo; reversed = false; unique_ified = true; } else if (sjinfo->jointype == JOIN_SEMI && bms_equal(sjinfo->syn_righthand, rel1->relids) && create_unique_path(root, rel1, rel1->cheapest_total_path, sjinfo) != NULL) { /* Reversed semijoin case */ if (match_sjinfo) return false; /* invalid join path */ match_sjinfo = sjinfo; reversed = true; unique_ified = true; } else { /* * Otherwise, the proposed join overlaps the RHS but isn't a valid * implementation of this SJ. But don't panic quite yet: the RHS * violation might have occurred previously, in one or both input * relations, in which case we must have previously decided that * it was OK to commute some other SJ with this one. If we need * to perform this join to finish building up the RHS, rejecting * it could lead to not finding any plan at all. (This can occur * because of the heuristics elsewhere in this file that postpone * clauseless joins: we might not consider doing a clauseless join * within the RHS until after we've performed other, validly * commutable SJs with one or both sides of the clauseless join.) * This consideration boils down to the rule that if both inputs * overlap the RHS, we can allow the join --- they are either * fully within the RHS, or represent previously-allowed joins to * rels outside it. */ if (bms_overlap(rel1->relids, sjinfo->min_righthand) && bms_overlap(rel2->relids, sjinfo->min_righthand)) continue; /* assume valid previous violation of RHS */ /* * The proposed join could still be legal, but only if we're * allowed to associate it into the RHS of this SJ. That means * this SJ must be a LEFT join (not SEMI or ANTI, and certainly * not FULL) and the proposed join must not overlap the LHS. */ if (sjinfo->jointype != JOIN_LEFT || bms_overlap(joinrelids, sjinfo->min_lefthand)) return false; /* invalid join path */ /* * To be valid, the proposed join must be a LEFT join; otherwise * it can't associate into this SJ's RHS. But we may not yet have * found the SpecialJoinInfo matching the proposed join, so we * can't test that yet. Remember the requirement for later. */ must_be_leftjoin = true; } } /* * Fail if violated any SJ's RHS and didn't match to a LEFT SJ: the * proposed join can't associate into an SJ's RHS. * * Also, fail if the proposed join's predicate isn't strict; we're * essentially checking to see if we can apply outer-join identity 3, and * that's a requirement. (This check may be redundant with checks in * make_outerjoininfo, but I'm not quite sure, and it's cheap to test.) */ if (must_be_leftjoin && (match_sjinfo == NULL || match_sjinfo->jointype != JOIN_LEFT || !match_sjinfo->lhs_strict)) return false; /* invalid join path */ /* * We also have to check for constraints imposed by LATERAL references. */ if (root->hasLateralRTEs) { bool lateral_fwd; bool lateral_rev; Relids join_lateral_rels; /* * The proposed rels could each contain lateral references to the * other, in which case the join is impossible. If there are lateral * references in just one direction, then the join has to be done with * a nestloop with the lateral referencer on the inside. If the join * matches an SJ that cannot be implemented by such a nestloop, the * join is impossible. * * Also, if the lateral reference is only indirect, we should reject * the join; whatever rel(s) the reference chain goes through must be * joined to first. * * Another case that might keep us from building a valid plan is the * implementation restriction described by have_dangerous_phv(). */ lateral_fwd = bms_overlap(rel1->relids, rel2->lateral_relids); lateral_rev = bms_overlap(rel2->relids, rel1->lateral_relids); if (lateral_fwd && lateral_rev) return false; /* have lateral refs in both directions */ if (lateral_fwd) { /* has to be implemented as nestloop with rel1 on left */ if (match_sjinfo && (reversed || unique_ified || match_sjinfo->jointype == JOIN_FULL)) return false; /* not implementable as nestloop */ /* check there is a direct reference from rel2 to rel1 */ if (!bms_overlap(rel1->relids, rel2->direct_lateral_relids)) return false; /* only indirect refs, so reject */ /* check we won't have a dangerous PHV */ if (have_dangerous_phv(root, rel1->relids, rel2->lateral_relids)) return false; /* might be unable to handle required PHV */ } else if (lateral_rev) { /* has to be implemented as nestloop with rel2 on left */ if (match_sjinfo && (!reversed || unique_ified || match_sjinfo->jointype == JOIN_FULL)) return false; /* not implementable as nestloop */ /* check there is a direct reference from rel1 to rel2 */ if (!bms_overlap(rel2->relids, rel1->direct_lateral_relids)) return false; /* only indirect refs, so reject */ /* check we won't have a dangerous PHV */ if (have_dangerous_phv(root, rel2->relids, rel1->lateral_relids)) return false; /* might be unable to handle required PHV */ } /* * LATERAL references could also cause problems later on if we accept * this join: if the join's minimum parameterization includes any rels * that would have to be on the inside of an outer join with this join * rel, then it's never going to be possible to build the complete * query using this join. We should reject this join not only because * it'll save work, but because if we don't, the clauseless-join * heuristics might think that legality of this join means that some * other join rel need not be formed, and that could lead to failure * to find any plan at all. We have to consider not only rels that * are directly on the inner side of an OJ with the joinrel, but also * ones that are indirectly so, so search to find all such rels. */ join_lateral_rels = min_join_parameterization(root, joinrelids, rel1, rel2); if (join_lateral_rels) { Relids join_plus_rhs = bms_copy(joinrelids); bool more; do { more = false; foreach(l, root->join_info_list) { SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); /* ignore full joins --- their ordering is predetermined */ if (sjinfo->jointype == JOIN_FULL) continue; if (bms_overlap(sjinfo->min_lefthand, join_plus_rhs) && !bms_is_subset(sjinfo->min_righthand, join_plus_rhs)) { join_plus_rhs = bms_add_members(join_plus_rhs, sjinfo->min_righthand); more = true; } } } while (more); if (bms_overlap(join_plus_rhs, join_lateral_rels)) return false; /* will not be able to join to some RHS rel */ } } /* Otherwise, it's a valid join */ *sjinfo_p = match_sjinfo; *reversed_p = reversed; return true; } /* * has_join_restriction * Detect whether the specified relation has join-order restrictions, * due to being inside an outer join or an IN (sub-SELECT), * or participating in any LATERAL references or multi-rel PHVs. * * Essentially, this tests whether have_join_order_restriction() could * succeed with this rel and some other one. It's OK if we sometimes * say "true" incorrectly. (Therefore, we don't bother with the relatively * expensive has_legal_joinclause test.) */ static bool has_join_restriction(PlannerInfo *root, RelOptInfo *rel) { ListCell *l; if (rel->lateral_relids != NULL || rel->lateral_referencers != NULL) return true; foreach(l, root->placeholder_list) { PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l); if (bms_is_subset(rel->relids, phinfo->ph_eval_at) && !bms_equal(rel->relids, phinfo->ph_eval_at)) return true; } foreach(l, root->join_info_list) { SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); /* ignore full joins --- other mechanisms preserve their ordering */ if (sjinfo->jointype == JOIN_FULL) continue; /* ignore if SJ is already contained in rel */ if (bms_is_subset(sjinfo->min_lefthand, rel->relids) && bms_is_subset(sjinfo->min_righthand, rel->relids)) continue; /* restricted if it overlaps LHS or RHS, but doesn't contain SJ */ if (bms_overlap(sjinfo->min_lefthand, rel->relids) || bms_overlap(sjinfo->min_righthand, rel->relids)) return true; } return false; } /* * restriction_is_constant_false --- is a restrictlist just FALSE? * * In cases where a qual is provably constant FALSE, eval_const_expressions * will generally have thrown away anything that's ANDed with it. In outer * join situations this will leave us computing cartesian products only to * decide there's no match for an outer row, which is pretty stupid. So, * we need to detect the case. * * If only_pushed_down is true, then consider only quals that are pushed-down * from the point of view of the joinrel. */ static bool restriction_is_constant_false(List *restrictlist, RelOptInfo *joinrel, bool only_pushed_down) { ListCell *lc; /* * Despite the above comment, the restriction list we see here might * possibly have other members besides the FALSE constant, since other * quals could get "pushed down" to the outer join level. So we check * each member of the list. */ foreach(lc, restrictlist) { RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc); if (only_pushed_down && !RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids)) continue; if (rinfo->clause && IsA(rinfo->clause, Const)) { Const *con = (Const *) rinfo->clause; /* constant NULL is as good as constant FALSE for our purposes */ if (con->constisnull) return true; if (!DatumGetBool(con->constvalue)) return true; } } return false; } /* * Construct the SpecialJoinInfo for a child-join by translating * SpecialJoinInfo for the join between parents. left_relids and right_relids * are the relids of left and right side of the join respectively. * * If translations are added to or removed from this function, consider * updating free_child_join_sjinfo() accordingly. */ static SpecialJoinInfo * build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo, Relids left_relids, Relids right_relids) { SpecialJoinInfo *sjinfo = makeNode(SpecialJoinInfo); AppendRelInfo **left_appinfos; int left_nappinfos; AppendRelInfo **right_appinfos; int right_nappinfos; /* Dummy SpecialJoinInfos can be created without any translation. */ if (parent_sjinfo->jointype == JOIN_INNER) { Assert(parent_sjinfo->ojrelid == 0); init_dummy_sjinfo(sjinfo, left_relids, right_relids); return sjinfo; } memcpy(sjinfo, parent_sjinfo, sizeof(SpecialJoinInfo)); left_appinfos = find_appinfos_by_relids(root, left_relids, &left_nappinfos); right_appinfos = find_appinfos_by_relids(root, right_relids, &right_nappinfos); sjinfo->min_lefthand = adjust_child_relids(sjinfo->min_lefthand, left_nappinfos, left_appinfos); sjinfo->min_righthand = adjust_child_relids(sjinfo->min_righthand, right_nappinfos, right_appinfos); sjinfo->syn_lefthand = adjust_child_relids(sjinfo->syn_lefthand, left_nappinfos, left_appinfos); sjinfo->syn_righthand = adjust_child_relids(sjinfo->syn_righthand, right_nappinfos, right_appinfos); /* outer-join relids need no adjustment */ sjinfo->semi_rhs_exprs = (List *) adjust_appendrel_attrs(root, (Node *) sjinfo->semi_rhs_exprs, right_nappinfos, right_appinfos); pfree(left_appinfos); pfree(right_appinfos); return sjinfo; } /* * get_matching_part_pairs * Generate pairs of partitions to be joined from inputs */ static void get_matching_part_pairs(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *rel1, RelOptInfo *rel2, List **parts1, List **parts2) { bool rel1_is_simple = IS_SIMPLE_REL(rel1); bool rel2_is_simple = IS_SIMPLE_REL(rel2); int cnt_parts; *parts1 = NIL; *parts2 = NIL; for (cnt_parts = 0; cnt_parts < joinrel->nparts; cnt_parts++) { RelOptInfo *child_joinrel = joinrel->part_rels[cnt_parts]; RelOptInfo *child_rel1; RelOptInfo *child_rel2; Relids child_relids1; Relids child_relids2; /* * If this segment of the join is empty, it means that this segment * was ignored when previously creating child-join paths for it in * try_partitionwise_join() as it would not contribute to the join * result, due to one or both inputs being empty; add NULL to each of * the given lists so that this segment will be ignored again in that * function. */ if (!child_joinrel) { *parts1 = lappend(*parts1, NULL); *parts2 = lappend(*parts2, NULL); continue; } /* * Get a relids set of partition(s) involved in this join segment that * are from the rel1 side. */ child_relids1 = bms_intersect(child_joinrel->relids, rel1->all_partrels); Assert(bms_num_members(child_relids1) == bms_num_members(rel1->relids)); /* * Get a child rel for rel1 with the relids. Note that we should have * the child rel even if rel1 is a join rel, because in that case the * partitions specified in the relids would have matching/overlapping * boundaries, so the specified partitions should be considered as * ones to be joined when planning partitionwise joins of rel1, * meaning that the child rel would have been built by the time we get * here. */ if (rel1_is_simple) { int varno = bms_singleton_member(child_relids1); child_rel1 = find_base_rel(root, varno); } else child_rel1 = find_join_rel(root, child_relids1); Assert(child_rel1); /* * Get a relids set of partition(s) involved in this join segment that * are from the rel2 side. */ child_relids2 = bms_intersect(child_joinrel->relids, rel2->all_partrels); Assert(bms_num_members(child_relids2) == bms_num_members(rel2->relids)); /* * Get a child rel for rel2 with the relids. See above comments. */ if (rel2_is_simple) { int varno = bms_singleton_member(child_relids2); child_rel2 = find_base_rel(root, varno); } else child_rel2 = find_join_rel(root, child_relids2); Assert(child_rel2); /* * The join of rel1 and rel2 is legal, so is the join of the child * rels obtained above; add them to the given lists as a join pair * producing this join segment. */ *parts1 = lappend(*parts1, child_rel1); *parts2 = lappend(*parts2, child_rel2); } } /* * compute_partition_bounds * Compute the partition bounds for a join rel from those for inputs */ static void compute_partition_bounds(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo, List **parts1, List **parts2) { /* * If we don't have the partition bounds for the join rel yet, try to * compute those along with pairs of partitions to be joined. */ if (joinrel->nparts == -1) { PartitionScheme part_scheme = joinrel->part_scheme; PartitionBoundInfo boundinfo = NULL; int nparts = 0; Assert(joinrel->boundinfo == NULL); Assert(joinrel->part_rels == NULL); /* * See if the partition bounds for inputs are exactly the same, in * which case we don't need to work hard: the join rel will have the * same partition bounds as inputs, and the partitions with the same * cardinal positions will form the pairs. * * Note: even in cases where one or both inputs have merged bounds, it * would be possible for both the bounds to be exactly the same, but * it seems unlikely to be worth the cycles to check. */ if (!rel1->partbounds_merged && !rel2->partbounds_merged && rel1->nparts == rel2->nparts && partition_bounds_equal(part_scheme->partnatts, part_scheme->parttyplen, part_scheme->parttypbyval, rel1->boundinfo, rel2->boundinfo)) { boundinfo = rel1->boundinfo; nparts = rel1->nparts; } else { /* Try merging the partition bounds for inputs. */ boundinfo = partition_bounds_merge(part_scheme->partnatts, part_scheme->partsupfunc, part_scheme->partcollation, rel1, rel2, parent_sjinfo->jointype, parts1, parts2); if (boundinfo == NULL) { joinrel->nparts = 0; return; } nparts = list_length(*parts1); joinrel->partbounds_merged = true; } Assert(nparts > 0); joinrel->boundinfo = boundinfo; joinrel->nparts = nparts; joinrel->part_rels = (RelOptInfo **) palloc0(sizeof(RelOptInfo *) * nparts); } else { Assert(joinrel->nparts > 0); Assert(joinrel->boundinfo); Assert(joinrel->part_rels); /* * If the join rel's partbounds_merged flag is true, it means inputs * are not guaranteed to have the same partition bounds, therefore we * can't assume that the partitions at the same cardinal positions * form the pairs; let get_matching_part_pairs() generate the pairs. * Otherwise, nothing to do since we can assume that. */ if (joinrel->partbounds_merged) { get_matching_part_pairs(root, joinrel, rel1, rel2, parts1, parts2); Assert(list_length(*parts1) == joinrel->nparts); Assert(list_length(*parts2) == joinrel->nparts); } } } /* * Assess whether join between given two partitioned relations can be broken * down into joins between matching partitions; a technique called * "partitionwise join" * * Partitionwise join is possible when a. Joining relations have same * partitioning scheme b. There exists an equi-join between the partition keys * of the two relations. * * Partitionwise join is planned as follows (details: optimizer/README.) * * 1. Create the RelOptInfos for joins between matching partitions i.e * child-joins and add paths to them. * * 2. Construct Append or MergeAppend paths across the set of child joins. * This second phase is implemented by generate_partitionwise_join_paths(). * * The RelOptInfo, SpecialJoinInfo and restrictlist for each child join are * obtained by translating the respective parent join structures. */ static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo, List *parent_restrictlist) { bool rel1_is_simple = IS_SIMPLE_REL(rel1); bool rel2_is_simple = IS_SIMPLE_REL(rel2); List *parts1 = NIL; List *parts2 = NIL; ListCell *lcr1 = NULL; ListCell *lcr2 = NULL; int cnt_parts; /* Guard against stack overflow due to overly deep partition hierarchy. */ check_stack_depth(); /* Nothing to do, if the join relation is not partitioned. */ if (joinrel->part_scheme == NULL || joinrel->nparts == 0) return; /* The join relation should have consider_partitionwise_join set. */ Assert(joinrel->consider_partitionwise_join); /* * We can not perform partitionwise join if either of the joining * relations is not partitioned. */ if (!IS_PARTITIONED_REL(rel1) || !IS_PARTITIONED_REL(rel2)) return; Assert(REL_HAS_ALL_PART_PROPS(rel1) && REL_HAS_ALL_PART_PROPS(rel2)); /* The joining relations should have consider_partitionwise_join set. */ Assert(rel1->consider_partitionwise_join && rel2->consider_partitionwise_join); /* * The partition scheme of the join relation should match that of the * joining relations. */ Assert(joinrel->part_scheme == rel1->part_scheme && joinrel->part_scheme == rel2->part_scheme); Assert(!(joinrel->partbounds_merged && (joinrel->nparts <= 0))); compute_partition_bounds(root, rel1, rel2, joinrel, parent_sjinfo, &parts1, &parts2); if (joinrel->partbounds_merged) { lcr1 = list_head(parts1); lcr2 = list_head(parts2); } /* * Create child-join relations for this partitioned join, if those don't * exist. Add paths to child-joins for a pair of child relations * corresponding to the given pair of parent relations. */ for (cnt_parts = 0; cnt_parts < joinrel->nparts; cnt_parts++) { RelOptInfo *child_rel1; RelOptInfo *child_rel2; bool rel1_empty; bool rel2_empty; SpecialJoinInfo *child_sjinfo; List *child_restrictlist; RelOptInfo *child_joinrel; AppendRelInfo **appinfos; int nappinfos; if (joinrel->partbounds_merged) { child_rel1 = lfirst_node(RelOptInfo, lcr1); child_rel2 = lfirst_node(RelOptInfo, lcr2); lcr1 = lnext(parts1, lcr1); lcr2 = lnext(parts2, lcr2); } else { child_rel1 = rel1->part_rels[cnt_parts]; child_rel2 = rel2->part_rels[cnt_parts]; } rel1_empty = (child_rel1 == NULL || IS_DUMMY_REL(child_rel1)); rel2_empty = (child_rel2 == NULL || IS_DUMMY_REL(child_rel2)); /* * Check for cases where we can prove that this segment of the join * returns no rows, due to one or both inputs being empty (including * inputs that have been pruned away entirely). If so just ignore it. * These rules are equivalent to populate_joinrel_with_paths's rules * for dummy input relations. */ switch (parent_sjinfo->jointype) { case JOIN_INNER: case JOIN_SEMI: if (rel1_empty || rel2_empty) continue; /* ignore this join segment */ break; case JOIN_LEFT: case JOIN_ANTI: if (rel1_empty) continue; /* ignore this join segment */ break; case JOIN_FULL: if (rel1_empty && rel2_empty) continue; /* ignore this join segment */ break; default: /* other values not expected here */ elog(ERROR, "unrecognized join type: %d", (int) parent_sjinfo->jointype); break; } /* * If a child has been pruned entirely then we can't generate paths * for it, so we have to reject partitionwise joining unless we were * able to eliminate this partition above. */ if (child_rel1 == NULL || child_rel2 == NULL) { /* * Mark the joinrel as unpartitioned so that later functions treat * it correctly. */ joinrel->nparts = 0; return; } /* * If a leaf relation has consider_partitionwise_join=false, it means * that it's a dummy relation for which we skipped setting up tlist * expressions and adding EC members in set_append_rel_size(), so * again we have to fail here. */ if (rel1_is_simple && !child_rel1->consider_partitionwise_join) { Assert(child_rel1->reloptkind == RELOPT_OTHER_MEMBER_REL); Assert(IS_DUMMY_REL(child_rel1)); joinrel->nparts = 0; return; } if (rel2_is_simple && !child_rel2->consider_partitionwise_join) { Assert(child_rel2->reloptkind == RELOPT_OTHER_MEMBER_REL); Assert(IS_DUMMY_REL(child_rel2)); joinrel->nparts = 0; return; } /* We should never try to join two overlapping sets of rels. */ Assert(!bms_overlap(child_rel1->relids, child_rel2->relids)); /* * Construct SpecialJoinInfo from parent join relations's * SpecialJoinInfo. */ child_sjinfo = build_child_join_sjinfo(root, parent_sjinfo, child_rel1->relids, child_rel2->relids); /* Find the AppendRelInfo structures */ appinfos = find_appinfos_by_relids(root, bms_union(child_rel1->relids, child_rel2->relids), &nappinfos); /* * Construct restrictions applicable to the child join from those * applicable to the parent join. */ child_restrictlist = (List *) adjust_appendrel_attrs(root, (Node *) parent_restrictlist, nappinfos, appinfos); /* Find or construct the child join's RelOptInfo */ child_joinrel = joinrel->part_rels[cnt_parts]; if (!child_joinrel) { child_joinrel = build_child_join_rel(root, child_rel1, child_rel2, joinrel, child_restrictlist, child_sjinfo); joinrel->part_rels[cnt_parts] = child_joinrel; joinrel->live_parts = bms_add_member(joinrel->live_parts, cnt_parts); joinrel->all_partrels = bms_add_members(joinrel->all_partrels, child_joinrel->relids); } /* Assert we got the right one */ Assert(bms_equal(child_joinrel->relids, adjust_child_relids(joinrel->relids, nappinfos, appinfos))); /* And make paths for the child join */ populate_joinrel_with_paths(root, child_rel1, child_rel2, child_joinrel, child_sjinfo, child_restrictlist); pfree(appinfos); free_child_join_sjinfo(child_sjinfo); } } /* * free_child_join_sjinfo * Free memory consumed by a SpecialJoinInfo created by * build_child_join_sjinfo() * * Only members that are translated copies of their counterpart in the parent * SpecialJoinInfo are freed here. */ static void free_child_join_sjinfo(SpecialJoinInfo *sjinfo) { /* * Dummy SpecialJoinInfos of inner joins do not have any translated fields * and hence no fields that to be freed. */ if (sjinfo->jointype != JOIN_INNER) { bms_free(sjinfo->min_lefthand); bms_free(sjinfo->min_righthand); bms_free(sjinfo->syn_lefthand); bms_free(sjinfo->syn_righthand); /* * semi_rhs_exprs may in principle be freed, but a simple pfree() does * not suffice, so we leave it alone. */ } pfree(sjinfo); } pg_hint_plan-REL17_1_7_0/data/000077500000000000000000000000001466301071500161115ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/data/data.csv000066400000000000000000000000521466301071500175340ustar00rootroot000000000000001,1 2,2 3,3 4,4 5,5 6,6 7,7 8,8 9,9 10,10 pg_hint_plan-REL17_1_7_0/docs/000077500000000000000000000000001466301071500161305ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/docs/Makefile000066400000000000000000000011721466301071500175710ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) pg_hint_plan-REL17_1_7_0/docs/README000066400000000000000000000054241466301071500170150ustar00rootroot00000000000000pg_hint_plan documentation ========================== Introduction ------------ Markdown format is kept as a main format, relying on python sphinx and myst_parser to render an HTML documentation if needed. Note that while markdown is more readable as raw text, it's a way simpler syntax that lacks a lot of features that reStructuredText offers. Relying on sphinx gives us an opportunity to later write parts of the documentation in reStructuredText if needed, but also offers other appealing features like multilingual documentation. Readthedocs is the expected target, so use its theme and follow its recommendation about pinning various requirement versions. Building the doc locally ------------------------ The documentation can be built locally easily using make -C docs/ html The rendered documentation will be generated in docs/html/_build/html Note that you need to have all python prerequirements installed, which can be done using: pip install -r docs/requirements.txt If you need to update the requirements (which shouldn't be needed frequently), update the docs/requirements.in and generate the target docs/requirements.txt using pip-compile. See the link about this tool below for more details on how to use it. Translation ----------- Note that each translator has to follow all those steps whenever the translation needs to be updated. Note also that those commands assume that the current working directory is docs/. - Bootstrapping the translation (the .pot files) is simply done using make gettext This will generate the various .pot file in _build/gettext. - The per-language translation files (the .po files) can then be generated. We currently only support Japanese, the rest of the commands will assume a single Japanese translation. Those files can be generated using: sphinx-intl update -p _build/gettext -l ja The files are generated (or updated) in the docs/locale/ja/LC_MESSAGES/. - You can then translate the .po file with any editor (poedit, vim...) - The translated documentation can be built using: make -e SPHINXOPTS="-D language='ja'" html - If everything is ok, you can commit the modifications in the .po files. References ---------- References if you're interested in the various design choices: - quickstart for RTD with sphinx: https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html - reproducible builds: https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html - myst parser: https://myst-parser.readthedocs.io - pip-tools / pip-compile: https://pip-tools.readthedocs.io - RTD sphinx theme: https://sphinx-rtd-theme.readthedocs.io - Internationalization: https://www.sphinx-doc.org/en/master/usage/advanced/intl.html https://docs.readthedocs.io/en/stable/localization.html#projects-with-multiple-translations-sphinx-only pg_hint_plan-REL17_1_7_0/docs/conf.py000066400000000000000000000025251466301071500174330ustar00rootroot00000000000000# Configuration file for the Sphinx documentation builder. # # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information project = 'pg_hint_plan' copyright = '2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION' author = 'NIPPON TELEGRAPH AND TELEPHONE CORPORATION' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = ['sphinx_rtd_theme', 'myst_parser'] templates_path = ['_templates'] exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output html_theme = 'sphinx_rtd_theme' #html_static_path = ['_static'] # Internationalization # https://www.sphinx-doc.org/en/master/usage/advanced/intl.html # https://docs.readthedocs.io/en/stable/guides/manage-translations-sphinx.html locale_dirs = ['locale/'] # path is example but recommended. gettext_compact = False # optional. gettext_uuid = True # optional. pg_hint_plan-REL17_1_7_0/docs/description.md000066400000000000000000000023301466301071500207730ustar00rootroot00000000000000# Description ## Basic Usage `pg_hint_plan` reads hinting phrases in a comment of special form given a SQL statement. A hint can be specified by prefixing it with the sequence `"/\*+"` and ending it with `"\*/"`. Hint phrases consist of hint names and parameters enclosed by parentheses and delimited by whitespaces. Hint phrases can use newlines for readability. In the example below, a hash join is selected as the join method while doing a sequential scan on `pgbench_accounts`: ```sql =# /*+ HashJoin(a b) SeqScan(a) */ EXPLAIN SELECT * FROM pgbench_branches b JOIN pgbench_accounts a ON b.bid = a.bid ORDER BY a.aid; QUERY PLAN --------------------------------------------------------------------------------------- Sort (cost=31465.84..31715.84 rows=100000 width=197) Sort Key: a.aid -> Hash Join (cost=1.02..4016.02 rows=100000 width=197) Hash Cond: (a.bid = b.bid) -> Seq Scan on pgbench_accounts a (cost=0.00..2640.00 rows=100000 width=97) -> Hash (cost=1.01..1.01 rows=1 width=100) -> Seq Scan on pgbench_branches b (cost=0.00..1.01 rows=1 width=100) (7 rows) ``` pg_hint_plan-REL17_1_7_0/docs/errors.md000066400000000000000000000015741466301071500177750ustar00rootroot00000000000000# Errors `pg_hint_plan` stops hint parsing on any error and will uses the hints already parsed. Here are some typical errors. ## Syntax errors Any syntactical errors or wrong hint names are reported as a syntax error. These errors are reported in the server log with the message level specified by `pg_hint_plan.message_level` if `pg_hint_plan.debug_print` is on and above. ## Incorrect Object definitions Incorrect object definitions result in silently ignoring the hints. This kind of error is reported as a "Not Used Hint" in the server logs. ## Redundant or conflicting hints The last hint is considered when redundant hints are defined or hints conflict with each other. This kind of error is reported as a duplicated hints. ## Nested comments Hint comments cannot be recursive. If detected, hint parsing is immediately stopped and all the hints already parsed are ignored. pg_hint_plan-REL17_1_7_0/docs/functional_limitations.md000066400000000000000000000017331466301071500232340ustar00rootroot00000000000000(functional-limitations)= # Functional limitations ## Influence of planner GUC parameters The planner does not try to consider joining order for FROM clause entries more than `from_collapse_limit`. `pg_hint_plan` cannot affect the joining order in this case. ## Hints trying to enforce non-executable plans Planner chooses any executable plans when the enforced plan cannot be executed: - `FULL OUTER JOIN` to use nested loop. - Use of indexes that do not have columns used in quals. - TID scans for queries without ctid conditions. ## Queries in ECPG ECPG removes comments in queries written as embedded SQLs so hints cannot be passed to it. The only exception `EXECUTE`, that passes the query string to the server as-is. The hint table can be used in the case. ## Query Identifiers When `compute_query_id` is enabled, PostgreSQL generates a query ID, ignoring comments. Hence, queries with different hints, still written the same way, may compute the same query ID. pg_hint_plan-REL17_1_7_0/docs/hint_details.md000066400000000000000000000170721466301071500211300ustar00rootroot00000000000000# Details in hinting ## Syntax and placement `pg_hint_plan` reads hints from only the first block comment and stops parsing from any characters except alphabetical characters, digits, spaces, underscores, commas and parentheses. In the following example, `HashJoin(a b)` and `SeqScan(a)` are parsed as hints, but `IndexScan(a)` and `MergeJoin(a b)` are not: ```sql =# /*+ HashJoin(a b) SeqScan(a) */ /*+ IndexScan(a) */ EXPLAIN SELECT /*+ MergeJoin(a b) */ * FROM pgbench_branches b JOIN pgbench_accounts a ON b.bid = a.bid ORDER BY a.aid; QUERY PLAN --------------------------------------------------------------------------------------- Sort (cost=31465.84..31715.84 rows=100000 width=197) Sort Key: a.aid -> Hash Join (cost=1.02..4016.02 rows=100000 width=197) Hash Cond: (a.bid = b.bid) -> Seq Scan on pgbench_accounts a (cost=0.00..2640.00 rows=100000 width=97) -> Hash (cost=1.01..1.01 rows=1 width=100) -> Seq Scan on pgbench_branches b (cost=0.00..1.01 rows=1 width=100) (7 rows) ``` ## Using with PL/pgSQL `pg_hint_plan` works for queries in PL/pgSQL scripts with some restrictions. - Hints affect only on the following kind of queries: - Queries that return one row (`SELECT`, `INSERT`, `UPDATE` and `DELETE`) - Queries that return multiple rows (`RETURN QUERY`) - Dynamic SQL statements (`EXECUTE`) - Cursor open (`OPEN`) - Loop over result of a query (`FOR`) - A hint comment has to be placed after the first word in a query as preceding comments are not sent as a part of this query. ```plpgsql =# CREATE FUNCTION hints_func(integer) RETURNS integer AS $$ DECLARE id integer; cnt integer; BEGIN SELECT /*+ NoIndexScan(a) */ aid INTO id FROM pgbench_accounts a WHERE aid = $1; SELECT /*+ SeqScan(a) */ count(*) INTO cnt FROM pgbench_accounts a; RETURN id + cnt; END; $$ LANGUAGE plpgsql; ``` ## Upper and lower case handling in object names Unlike the way PostgreSQL handles object names, `pg_hint_plan` compares bare object names in hints against the database internal object names in a case-sensitive manner. Therefore, an object name TBL in a hint matches only "TBL" in the database and does not match any unquoted names like TBL, tbl or Tbl. ## Escaping special characters in object names The objects defined in a hint's parameter can use double quotes if they include parentheses, double quotes and white spaces. The escaping rules are the same as PostgreSQL. ## Distinction between multiple occurences of a table `pg_hint_plan` identifies the target object by using aliases if any. This behavior is useful to point to a specific occurrence among multiple occurrences of one table. ```sql =# /*+ HashJoin(t1 t1) */ EXPLAIN SELECT * FROM s1.t1 JOIN public.t1 ON (s1.t1.id=public.t1.id); INFO: hint syntax error at or near "HashJoin(t1 t1)" DETAIL: Relation name "t1" is ambiguous. ... =# /*+ HashJoin(pt st) */ EXPLAIN SELECT * FROM s1.t1 st JOIN public.t1 pt ON (st.id=pt.id); QUERY PLAN --------------------------------------------------------------------- Hash Join (cost=64.00..1112.00 rows=28800 width=8) Hash Cond: (st.id = pt.id) -> Seq Scan on t1 st (cost=0.00..34.00 rows=2400 width=4) -> Hash (cost=34.00..34.00 rows=2400 width=4) -> Seq Scan on t1 pt (cost=0.00..34.00 rows=2400 width=4) ``` ## Underlying tables of views or rules Hints are not applicable on views, but they can affect the queries within the view if the object names match the names in the expanded query on the view. Assigning aliases to the tables in a view enables them to be manipulated from outside the view. ```sql =# CREATE VIEW v1 AS SELECT * FROM t2; =# EXPLAIN /*+ HashJoin(t1 v1) */ SELECT * FROM t1 JOIN v1 ON (c1.a = v1.a); QUERY PLAN ------------------------------------------------------------------ Hash Join (cost=3.27..18181.67 rows=101 width=8) Hash Cond: (t1.a = t2.a) -> Seq Scan on t1 (cost=0.00..14427.01 rows=1000101 width=4) -> Hash (cost=2.01..2.01 rows=101 width=4) -> Seq Scan on t2 (cost=0.00..2.01 rows=101 width=4) ``` ## Inheritance Hints can only point to the parent of an inheritance tree and the hints affect all the tables in an inheritance tree. Hints pointing directly to inherited children have no effect. ## Hints in multistatements One multistatement can have exactly one hint comment and the hint affects all of the individual statements in the multistatement. ## VALUES expressions `VALUES` expressions in `FROM` clause are named as `*VALUES*` internally these can be hinted if it is the only `VALUES` of a query. Two or more `VALUES` expressions in a query cannot be distinguished by looking at an `EXPLAIN` result, resulting in ambiguous results: ```sql =# /*+ MergeJoin(*VALUES*_1 *VALUES*) */ EXPLAIN SELECT * FROM (VALUES (1, 1), (2, 2)) v (a, b) JOIN (VALUES (1, 5), (2, 8), (3, 4)) w (a, c) ON v.a = w.a; INFO: pg_hint_plan: hint syntax error at or near "MergeJoin(*VALUES*_1 *VALUES*) " DETAIL: Relation name "*VALUES*" is ambiguous. QUERY PLAN ------------------------------------------------------------------------- Hash Join (cost=0.05..0.12 rows=2 width=16) Hash Cond: ("*VALUES*_1".column1 = "*VALUES*".column1) -> Values Scan on "*VALUES*_1" (cost=0.00..0.04 rows=3 width=8) -> Hash (cost=0.03..0.03 rows=2 width=8) -> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=8) ``` ## Subqueries Subqueries context can be occasionally hinted using the name `ANY_subquery`: IN (SELECT ... {LIMIT | OFFSET ...} ...) = ANY (SELECT ... {LIMIT | OFFSET ...} ...) = SOME (SELECT ... {LIMIT | OFFSET ...} ...) For these syntaxes, the planner internally assigns the name to the subquery when planning joins on tables including it, so join hints are applicable on such joins using the implicit name. For example: ```sql =# /*+HashJoin(a1 ANY_subquery)*/ EXPLAIN SELECT * FROM pgbench_accounts a1 WHERE aid IN (SELECT bid FROM pgbench_accounts a2 LIMIT 10); QUERY PLAN --------------------------------------------------------------------------------------------- Hash Semi Join (cost=0.49..2903.00 rows=1 width=97) Hash Cond: (a1.aid = a2.bid) -> Seq Scan on pgbench_accounts a1 (cost=0.00..2640.00 rows=100000 width=97) -> Hash (cost=0.36..0.36 rows=10 width=4) -> Limit (cost=0.00..0.26 rows=10 width=4) -> Seq Scan on pgbench_accounts a2 (cost=0.00..2640.00 rows=100000 width=4) ``` ## Using `IndexOnlyScan` hint Index scan may be unexpectedly performed on another index when the index specified in IndexOnlyScan hint cannot perform an index only scan. ## About `NoIndexScan` A `NoIndexScan` hint implies `NoIndexOnlyScan`. ## Parallel hints and `UNION` A `UNION` can run in parallel only when all underlying subqueries are parallel-safe. Hence, enforcing parallel on any of the subqueries will let a parallel-executable `UNION` run in parallel. Meanwhile, a parallel hint with zero workers prevents a scan from being executed in parallel. ## Setting `pg_hint_plan` parameters by Set hints `pg_hint_plan` parameters influence their own behavior so some parameters will not work as one could expect: - Hints to change `enable_hint`, `enable_hint_table` are ignored even though they are reported as "used hints" in debug logs. - Setting `debug_print` and `message_level` in the middle of query processing. pg_hint_plan-REL17_1_7_0/docs/hint_list.md000066400000000000000000000066161466301071500204600ustar00rootroot00000000000000(hint-list)= # Hint list The available hints are listed below. | Group | Format | Description | |:------|:-------|:------------| | Scan method | `SeqScan(table)`| Forces sequential scan on the table. | | | `TidScan(table)` | Forces TID scan on the table. | | | `IndexScan(table[ index...])` | Forces index scan on the table. Restricts to specified indexes if any. | | | `IndexOnlyScan(table[ index...])` | Forces index-only scan on the table. Restricts to specified indexes if any. Index scan may be used if index-only scan is not available. | | | `BitmapScan(table[ index...])`| Forces bitmap scan on the table. Restricts to specified indexes if any. | | | `IndexScanRegexp(table[ POSIX Regexp...])`
`IndexOnlyScanRegexp(table[ POSIX Regexp...])`
`BitmapScanRegexp(table[ POSIX Regexp...])` | Forces index scan, index-only scan (For PostgreSQL 9.2 and later) or bitmap scan on the table. Restricts to indexes that matches the specified POSIX regular expression pattern. | | | `NoSeqScan(table)`| Forces to *not* do sequential scan on the table. | | | `NoTidScan(table)`| Forces to *not* do TID scan on the table.| | | `NoIndexScan(table)`| Forces to *not* do index scan and index-only scan on the table. | | | `NoIndexOnlyScan(table)`| Forces to *not* do index only scan on the table. | | | `NoBitmapScan(table)` | Forces to *not* do bitmap scan on the table. | | Join method| `NestLoop(table table[ table...])` | Forces nested loop for the joins on the tables specified. | | | `HashJoin(table table[ table...])`| Forces hash join for the joins on the tables specified. | | | `MergeJoin(table table[ table...])` | Forces merge join for the joins on the tables specified. | | | `NoNestLoop(table table[ table...])`| Forces to *not* do nested loop for the joins on the tables specified. | | | `NoHashJoin(table table[ table...])`| Forces to *not* do hash join for the joins on the tables specified. | | | `NoMergeJoin(table table[ table...])` | Forces to *not* do merge join for the joins on the tables specified. | | Join order | `Leading(table table[ table...])` | Forces join order as specified. | | | `Leading()`| Forces join order and directions as specified. A join pair is a pair of tables and/or other join pairs enclosed by parentheses, which can make a nested structure. | | Behavior control on Join | `Memoize(table table[ table...])` | Allows the topmost join of a join among the specified tables to Memoize the inner result. Not enforced. | | | `NoMemoize(table table[ table...])` | Inhibits the topmost join of a join among the specified tables from Memoizing the inner result. | | Row number correction | `Rows(table table[ table...] correction)` | Corrects row number of a result of the joins on the tables specified. The available correction methods are absolute (#), addition (+), subtract (-) and multiplication (*). should be a string that strtod() can understand. | | Parallel query configuration | `Parallel(table <# of workers> [soft\|hard])` | Enforces or inhibits parallel execution of the specified table. <# of workers> is the desired number of parallel workers, where zero means inhibiting parallel execution. If the third parameter is soft (default), it just changes max\_parallel\_workers\_per\_gather and leaves everything else to the planner. Hard enforces the specified number of workers. | | GUC | `Set(GUC-param value)` | Sets GUC parameter to the value defined while planner is running. | pg_hint_plan-REL17_1_7_0/docs/hint_table.md000066400000000000000000000163631466301071500205740ustar00rootroot00000000000000# The hint table Hints can be specified in a comment, still this can be inconvenient in the case where queries cannot be edited. In the case, hints can be placed in a special table named `"hint_plan.hints"`. The table consists of the following columns: | column | description | |:-------|:------------| | `id` | Unique number to identify a row for a hint.
This column is filled automatically by sequence. | | `query_id` | A unique query ID, generated by the backend when the GUC compute_query_id is enabled | | `application_name` | The value of `application_name` where sessions can apply a hint.
The hint in the example below applies to sessions connected from psql.
An empty string implies that all sessions will apply the hint. | | `hints` | Hint phrase.
This must be a series of hints excluding surrounding comment marks. | The following example shows how to operate with the hint table. ```sql =# EXPLAIN (VERBOSE, COSTS false) SELECT * FROM t1 WHERE t1.id = 1; QUERY PLAN ---------------------------------------- Seq Scan on public.t1 Output: id, id2 Filter: (t1.id = 1) Query Identifier: -7164653396197960701 (4 rows) =# INSERT INTO hint_plan.hints(query_id, application_name, hints) VALUES (-7164653396197960701, '', 'SeqScan(t1)'); INSERT 0 1 =# UPDATE hint_plan.hints SET hints = 'IndexScan(t1)' WHERE id = 1; UPDATE 1 =# DELETE FROM hint_plan.hints WHERE id = 1; DELETE 1 ``` The hint table is owned by the extension owner and has the same default privileges as of the time of its creation, during `CREATE EXTENSION`. Hints in the hint table are prioritized over hints in comments. The query ID can be retrieved with `pg_stat_statements` or with `EXPLAIN (VERBOSE)`. ## Types of hints Hinting phrases are classified in multiple types based on what kind of object and how they can affect the planner. See [Hint list](#hint-list) for more details. ### Hints for Scan methods Scan method hints enforce specific scanning methods on the target table. `pg_hint_plan` recognizes the target table by alias names if any. These are for example `SeqScan` or `IndexScan`. Scan hints work on ordinary tables, inheritance tables, UNLOGGED tables, temporary tables and system catalogs. External (foreign) tables, table functions, VALUES clause, CTEs, views and subqueries are not affected. ```sql =# /*+ SeqScan(t1) IndexScan(t2 t2_pkey) */ SELECT * FROM table1 t1 JOIN table table2 t2 ON (t1.key = t2.key); ``` ### Hints for Join methods Join method hints enforce the join methods of the joins involving the specified tables. This can affect joins only on ordinary tables. Inheritance tables, UNLOGGED tables, temporary tables, external (foreign) tables, system catalogs, table functions, VALUES command results and CTEs are allowed to be in the parameter list. Joins on views and subqueries are not affected. ### Hints for Joining order This hint, named "Leading", enforces the order of join on two or more tables. There are two methods of enforcing it. The first method enforces a specific order of joining but does not restrict the direction at each join level. The second method enforces the join direction additionally. See [hint list](#hint-list) for more details. For example: ```sql =# /*+ NestLoop(t1 t2) MergeJoin(t1 t2 t3) Leading(t1 t2 t3) */ SELECT * FROM table1 t1 JOIN table table2 t2 ON (t1.key = t2.key) JOIN table table3 t3 ON (t2.key = t3.key); ``` ### Hints for Row number corrections This hint, named "Rows", changes the row number estimation of joins that comes from restrictions in the planner. For example: ```sql =# /*+ Rows(a b #10) */ SELECT... ; Sets rows of join result to 10 =# /*+ Rows(a b +10) */ SELECT... ; Increments row number by 10 =# /*+ Rows(a b -10) */ SELECT... ; Subtracts 10 from the row number. =# /*+ Rows(a b *10) */ SELECT... ; Makes the number 10 times larger. ``` ### Hints for parallel plans This hint, named `Parallel`, enforces parallel execution configuration on scans. The third parameter specifies the strength of the enforcement. `soft` means that `pg_hint_plan` only changes `max_parallel_worker_per_gather` and leaves all the others to the planner to set. `hard` changes other planner parameters so as to forcibly apply the update. This can affect ordinary tables, inheritance parents, unlogged tables and system catalogs. External tables, table functions, `VALUES` clauses, CTEs, views and subqueries are not affected. Internal tables of a view can be specified by its real name or its alias as the target object. The following example shows that the query is enforced differently on each table: ```sql =# EXPLAIN /*+ Parallel(c1 3 hard) Parallel(c2 5 hard) */ SELECT c2.a FROM c1 JOIN c2 ON (c1.a = c2.a); QUERY PLAN ------------------------------------------------------------------------------- Hash Join (cost=2.86..11406.38 rows=101 width=4) Hash Cond: (c1.a = c2.a) -> Gather (cost=0.00..7652.13 rows=1000101 width=4) Workers Planned: 3 -> Parallel Seq Scan on c1 (cost=0.00..7652.13 rows=322613 width=4) -> Hash (cost=1.59..1.59 rows=101 width=4) -> Gather (cost=0.00..1.59 rows=101 width=4) Workers Planned: 5 -> Parallel Seq Scan on c2 (cost=0.00..1.59 rows=59 width=4) =# EXPLAIN /*+ Parallel(tl 5 hard) */ SELECT sum(a) FROM tl; QUERY PLAN ----------------------------------------------------------------------------------- Finalize Aggregate (cost=693.02..693.03 rows=1 width=8) -> Gather (cost=693.00..693.01 rows=5 width=8) Workers Planned: 5 -> Partial Aggregate (cost=693.00..693.01 rows=1 width=8) -> Parallel Seq Scan on tl (cost=0.00..643.00 rows=20000 width=4) ``` ### GUC parameters set during planning `Set` hints change GUC parameters just while planning. GUC parameter shown in [Query Planning](http://www.postgresql.org/docs/current/static/runtime-config-query.html) can have the expected effects on planning unless an other hint conflicts with the planner method configuration parameters. When multiple hints change the same GUC, the last hint takes effect. [GUC parameters for `pg_hint_plan`](#guc-parameters-for-pg_hint_plan) are also settable by this hint but it may not work as expected. See [Functional limitations](#functional-limitations) for details. ```sql =# /*+ Set(random_page_cost 2.0) */ SELECT * FROM table1 t1 WHERE key = 'value'; ... ``` (guc-parameters-for-pg_hint_plan)= ## GUC parameters for `pg_hint_plan` The following GUC parameters affect the behavior of `pg_hint_plan`: | Parameter name | Description | Default | |:---------------|:------------|:--------| | `pg_hint_plan.enable_hint` | True enables `pg_hint_plan`. | `on` | | `pg_hint_plan.enable_hint_table` | True enables hinting by table. | `off` | | `pg_hint_plan.parse_messages` | Specifies the log level of hint parse error. Valid values are `error`, `warning`, `notice`, `info`, `log`, `debug`. | `INFO` | | `pg_hint_plan.debug_print` | Controls debug print and verbosity. Valid values are `off`, `on`, `detailed` and `verbose`. | `off` | | `pg_hint_plan.message_level` | Specifies message level of debug print. Valid values are `error`, `warning`, `notice`, `info`, `log`, `debug`. | `INFO` | pg_hint_plan-REL17_1_7_0/docs/index.md000066400000000000000000000003601466301071500175600ustar00rootroot00000000000000# pg_hint_plan 1.7 ```{contents} Table of Contents :depth: 2 ``` ```{toctree} synopsis.md description.md hint_table.md installation.md uninstallation.md hint_details.md errors.md functional_limitations.md requirements.md hint_list.md ``` pg_hint_plan-REL17_1_7_0/docs/installation.md000066400000000000000000000024741466301071500211620ustar00rootroot00000000000000# Installation This section describes the installation steps. ## Building binary module Simply run `make` at the top of the source tree, then `make install` as an appropriate user. The `PATH` environment variable should be set properly to point to a PostgreSQL set of binaries: $ tar xzvf pg_hint_plan-1.x.x.tar.gz $ cd pg_hint_plan-1.x.x $ make $ su $ make install ## Installing from a binary package On Debian and Ubuntu `pg_hint_plan` is available as a binary package from the pgdg (PostgreSQL Global Development Group) repository. Assuming you've already added the repository to `apt` sources, installing the package is as simple as: ``` sudo apt install postgresql--pg-hint-plan ``` Please visit https://www.postgresql.org/download/linux/ if you need help at adding the repository. ## Loading `pg_hint_plan` `pg_hint_plan` does not require `CREATE EXTENSION`. Loading it with a `LOAD` command will activate it and of course you can load it globally by setting `shared_preload_libraries` in `postgresql.conf`. Or you might be interested in `ALTER USER SET`/`ALTER DATABASE SET` for automatic loading in specific sessions. ```sql postgres=# LOAD 'pg_hint_plan'; LOAD ``` Run `CREATE EXTENSION` and `SET pg_hint_plan.enable_hint_table TO on` if you are planning to use the hint table. pg_hint_plan-REL17_1_7_0/docs/locale/000077500000000000000000000000001466301071500173675ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/docs/locale/ja/000077500000000000000000000000001466301071500177615ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/000077500000000000000000000000001466301071500215465ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/description.po000066400000000000000000000043621466301071500244360ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan description. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-09 10:50+0900\n" "PO-Revision-Date: 2023-11-09 15:31+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.2.2\n" #: ../../description.md:1 0082a55147374c7ab16faf346b5cde78 msgid "Description" msgstr "機能説明" #: ../../description.md:3 a578f7e648784224aa5562b6c0859fe0 msgid "Basic Usage" msgstr "基本的な使用方法" #: ../../description.md:5 3b1114e41a8e4a9a88e435ba40b8ed46 msgid "" "`pg_hint_plan` reads hinting phrases in a comment of special form given " "a SQL statement. A hint can be specified by prefixing it with the " "sequence `\"/\\*+\"` and ending it with `\"\\*/\"`. Hint phrases " "consist of hint names and parameters enclosed by parentheses and " "delimited by whitespaces. Hint phrases can use newlines for readability." msgstr "" "`pg_hint_plan`はSQL文に与えられた特別な形式のコメント内のヒント句を読み取" "ります。\n" "ヒントは先頭に `\"/*+\"`というシーケンスを付け、最後に `\"*/\"` を付ける" "ことで指定できます。\n" "ヒント句はヒント名とそれに続くパラメータを括弧で囲み、スペースで区切った" "ものです。\n" "ヒント句は読みやすくするために改行することができます。" #: ../../description.md:11 4bf58e34acd743419ea82b29b6e2f6fb msgid "" "In the example below, a hash join is selected as the join method while " "doing a sequential scan on `pgbench_accounts`:" msgstr "" "以下の例では、`pgbench_accounts` に対してシーケンシャルスキャンを行う際に" "結合方法としてハッシュ結合が選択されています。" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/errors.po000066400000000000000000000071611466301071500234270ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan errors. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-09 10:50+0900\n" "PO-Revision-Date: 2023-11-09 15:48+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.2.2\n" #: ../../errors.md:1 7bb59eaf638542abb9586f050733a4e0 msgid "Errors" msgstr "エラー" #: ../../errors.md:3 e3db83c556504b0abfe85134459031bc msgid "`pg_hint_plan` stops hint parsing on any error and will uses the hints already parsed. Here are some typical errors." msgstr "`pg_hint_plan`はエラーが発生するとヒントの構文解析を停止し、既に構文解析されたヒントを使用します。以下は典型的なエラーです。" #: ../../errors.md:6 a8760d36d17f470ab6afbbb02c1ff219 msgid "Syntax errors" msgstr "シンタックスエラー" #: ../../errors.md:8 b1414efb066a4ddfbad0ce8cbe16fb58 msgid "" "Any syntactical errors or wrong hint names are reported as a syntax error. These errors are reported in the server log with the message level " "specified by `pg_hint_plan.message_level` if `pg_hint_plan.debug_print` is on and above." msgstr "" "構文的なエラーやヒント名の誤りなどはシンタックスエラーとして出力されます。これらのエラーは`pg_hint_plan.debug_print`がON以上の場合、`pg_hint_plan." "message_level`によって指定されたメッセージレベルでサーバログに出力されます。" #: ../../errors.md:13 d28f5080cc7e41acabc18494d6ac768a msgid "Incorrect Object definitions" msgstr "誤ったオブジェクトの指定" #: ../../errors.md:15 1643ff73330f44eea56fd6babeb8a4e4 msgid "" "Incorrect object definitions result in silently ignoring the hints. This kind of error is reported as a \"Not Used Hint\" in the server logs." msgstr "" "オブジェクトの指定に誤りがあるとヒントは無言で無視されます。この種類のエラーはシンタックスエラーと同様の条件で \"Not used hints\" としてサーバログ" "に出力されます。" #: ../../errors.md:18 da03af4bd07e450c952f8f8c471d9f71 msgid "Redundant or conflicting hints" msgstr "冗長または競合するヒント" #: ../../errors.md:20 833a65ab64b043c08b4cb3aaf687272a msgid "" "The last hint is considered when redundant hints are defined or hints conflict with each other. This kind of error is reported as a duplicated " "hints." msgstr "" "冗長なヒントが指定されている場合やヒント同士が競合している場合は、最後のヒントが考慮されます。この種類のエラーは \"duplication hints\" として報告" "されます。" #: ../../errors.md:24 f3374244abe74052b9814e28cbe98045 msgid "Nested comments" msgstr "ネストされたコメント" #: ../../errors.md:26 020914d49a2d42b28d82f4fd898d99dc msgid "Hint comments cannot be recursive. If detected, hint parsing is immediately stopped and all the hints already parsed are ignored." msgstr "ヒントコメントは再帰的に使用できません。 検出された場合、ヒントの構文解析は直ちに停止され、既に解析されたヒントはすべて無視されます。" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/functional_limitations.po000066400000000000000000000101331466301071500266620ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan functional limitations. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-16 12:31+0900\n" "PO-Revision-Date: 2024-08-16 13:33+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.3.1\n" #: ../../functional_limitations.md:3 cdca82a1d620474dbe6ae7963902efc6 msgid "Functional limitations" msgstr "機能的な制限事項" #: ../../functional_limitations.md:5 a8c002bdce31413fb8ab6ad209959b7a msgid "Influence of planner GUC parameters" msgstr "プランナGUCパラメータの影響" #: ../../functional_limitations.md:7 66d956ba91054e41a7b64404a94d02d4 msgid "" "The planner does not try to consider joining order for FROM clause entries more than `from_collapse_limit`. `pg_hint_plan` " "cannot affect the joining order in this case." msgstr "" "プランナは、`from_collapse_limit`を超えるFROM句の項目に対する結合順を考慮しようとしません。`pg_hint_plan`は、このケースに対して" "期待される結合順に影響を与えることはできません。" #: ../../functional_limitations.md:11 d2d87ece0880473bb26163f8796bdbbd msgid "Hints trying to enforce non-executable plans" msgstr "実行不可能なプランの強制を試みるヒント" #: ../../functional_limitations.md:13 c822f5eff64344fdb74441f020adc9d3 msgid "Planner chooses any executable plans when the enforced plan cannot be executed:" msgstr "強制されたプランが実行できない場合、プランナは任意の実行可能なプランを選択します。" #: ../../functional_limitations.md:16 91203421b35849378107a7849f744145 msgid "`FULL OUTER JOIN` to use nested loop." msgstr "・`FULL OUTER JOIN`をnested loopで使用" #: ../../functional_limitations.md:17 f0c25ab9fdcb4071b27b606e88674826 msgid "Use of indexes that do not have columns used in quals." msgstr "・条件式で使用されるカラムを持っていないインデックスを使用" #: ../../functional_limitations.md:18 a44a945fa9264add9e122eb040dfbd67 msgid "TID scans for queries without ctid conditions." msgstr "・ctid条件が無いクエリに対するTIDスキャンの実行" #: ../../functional_limitations.md:20 493ce9960d9e4a3583ae80715a0d8787 msgid "Queries in ECPG" msgstr "ECPG内のクエリ" #: ../../functional_limitations.md:22 885fc863076f43ab8478e2d0b5dcfe27 msgid "" "ECPG removes comments in queries written as embedded SQLs so hints cannot be passed to it. The only exception `EXECUTE`, that " "passes the query string to the server as-is. The hint table can be used in the case." msgstr "" "ECPGは埋め込みSQLとして書かれたクエリのコメントを削除するのでヒントを渡すことはできません。唯一の例外は`EXECUTE`で、これはクエ" "リ文字列をそのままサーバに渡します。このようなケースにおいてはヒントテーブルを利用することができます。" #: ../../functional_limitations.md:26 18f70c8a2766414dbf58c0762e46e038 msgid "Query Identifiers" msgstr "クエリ識別子" #: ../../functional_limitations.md:28 5f42debfe174469a8092d72cda481309 msgid "" "When `compute_query_id` is enabled, PostgreSQL generates a query ID, ignoring comments. Hence, queries with different hints, " "still written the same way, may compute the same query ID." msgstr "" "`compute_query_id` が有効になっている場合、PostgreSQL はコメントを無視してクエリ ID を生成します。したがって、異なるヒントを持" "つクエリでも同じように書かれたクエリは、同一のクエリIDが計算される可能性があります。" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/hint_details.po000066400000000000000000000310671466301071500245640ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan hint details. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-16 12:31+0900\n" "PO-Revision-Date: 2024-08-16 13:12+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.3.1\n" #: ../../hint_details.md:1 30ff42665cc94a1fa7803a81fb2a7268 msgid "Details in hinting" msgstr "ヒントの詳細" #: ../../hint_details.md:3 d758a5557f8a421c92836d4ecff2dbf4 msgid "Syntax and placement" msgstr "構文と配置" #: ../../hint_details.md:5 0a26d128ac0449a3938cd5c423d02983 msgid "" "`pg_hint_plan` reads hints from only the first block comment and stops parsing from any characters except alphabetical characters, digits, spaces, underscores, commas and " "parentheses. In the following example, `HashJoin(a b)` and `SeqScan(a)` are parsed as hints, but `IndexScan(a)` and `MergeJoin(a b)` are not:" msgstr "" "`pg_hint_plan`は最初のブロックコメントのみからヒントを読み、アルファベット、数字、スペース、アンダースコア、カンマ、括弧の文字以外は構文解析を停止します。以下の例では、" "`HashJoin(a b)`と`SeqScan(a)`はヒントとして構文解析されますが、`IndexScan(a)`と`MergeJoin(a b)`はヒントとして構文解析されません。" #: ../../hint_details.md:33 065290ff3e0a41d1842375f958607e17 msgid "Using with PL/pgSQL" msgstr "PL/pgSQLでの使用" #: ../../hint_details.md:35 16b2b4f45cd04a01919703786da2243c msgid "`pg_hint_plan` works for queries in PL/pgSQL scripts with some restrictions." msgstr "`pg_hint_plan`はPL/pgSQLスクリプト内のクエリに対してはいくつかの制限付きで動作します。" #: ../../hint_details.md:37 f28aa14fdec44505af4bfaae463ac5ae msgid "Hints affect only on the following kind of queries:" msgstr "ヒントは以下のような種類のクエリにのみ影響します。" #: ../../hint_details.md:38 04d710873f7e4a8e82881b22e79a81df msgid "Queries that return one row (`SELECT`, `INSERT`, `UPDATE` and `DELETE`)" msgstr "・1行を返すクエリ (`SELECT`、`INSERT`、`UPDATE`、`DELETE`)" #: ../../hint_details.md:39 849971e08b48418fb40f9cb4efd7008c msgid "Queries that return multiple rows (`RETURN QUERY`)" msgstr "・複数行を返すクエリ (`RETURNクエリ`)" #: ../../hint_details.md:40 a82ea036bbf3429fadb0b9e1a1d6250a msgid "Dynamic SQL statements (`EXECUTE`)" msgstr "・動的なSQL文 (`EXECUTE`)" #: ../../hint_details.md:41 cd51a04e670f40f388c0d1d3b6603caf msgid "Cursor open (`OPEN`)" msgstr "・カーソルを開く (`OPEN`)" #: ../../hint_details.md:42 7c99c6bdee6249dda0afe9a522fa187e msgid "Loop over result of a query (`FOR`)" msgstr "・クエリの結果をループ (`FOR`)" #: ../../hint_details.md:43 b6b33c925fc04c91a6a8ea063712bff0 msgid "A hint comment has to be placed after the first word in a query as preceding comments are not sent as a part of this query." msgstr "ヒントコメントは次のようにクエリの最初の単語の後に配置する必要があります。クエリよりも先行するコメントはクエリの一部として送信されません。" #: ../../hint_details.md:62 0ae7c2afe36e49b8843380496c43f199 msgid "Upper and lower case handling in object names" msgstr "オブジェクト名の大文字と小文字の区別" #: ../../hint_details.md:64 7aaa07320ddb4d34b68fd2966665bf64 msgid "" "Unlike the way PostgreSQL handles object names, `pg_hint_plan` compares bare object names in hints against the database internal object names in a case-sensitive manner. " "Therefore, an object name TBL in a hint matches only \"TBL\" in the database and does not match any unquoted names like TBL, tbl or Tbl." msgstr "" "PostgreSQLがオブジェクト名を扱う方法とは異なり、`pg_hint_plan`はヒントに含まれるオブジェクト名とデータベース内部のオブジェクト名を大文字・小文字を区別して比較します。したがっ" "て、ヒント内のオブジェクト名TBLはデータベース内の \"TBL \"にのみマッチし、TBL、tbl、Tblのような引用符のない名前にはマッチしません。" #: ../../hint_details.md:70 5edac367e3f34ab0bb7afad11b2b1404 msgid "Escaping special characters in object names" msgstr "オブジェクト名の特殊文字のエスケープ" #: ../../hint_details.md:72 546cc0526cc1476f85ec431621473fad msgid "" "The objects defined in a hint's parameter can use double quotes if they include parentheses, double quotes and white spaces. The escaping rules are the same as PostgreSQL." msgstr "ヒントのパラメータに指定されたオブジェクト名に括弧、二重引用符、空白を含む場合、二重引用符で囲む必要があります。エスケープの規則はPostgreSQLと同じです。" #: ../../hint_details.md:76 ebb11dda21f548b9b6f9ca8a816ea941 msgid "Distinction between multiple occurences of a table" msgstr "複数出現するテーブルの区別" #: ../../hint_details.md:78 9e5fd8d3357648c19d62897b59ce8b5f msgid "`pg_hint_plan` identifies the target object by using aliases if any. This behavior is useful to point to a specific occurrence among multiple occurrences of one table." msgstr "`pg_hint_plan`は別名が存在する場合、それを使用して対象オブジェクトを特定します。この動作は、1つのテーブルが複数出現する中から特定のものを指定するのに便利です。" #: ../../hint_details.md:101 419eaadba493450694a1a039a5d67562 msgid "Underlying tables of views or rules" msgstr "ビューまたはルールの根底にあるテーブル" #: ../../hint_details.md:103 05f1ab2b2d644ee78ce2e0c5057bcd9a msgid "" "Hints are not applicable on views, but they can affect the queries within the view if the object names match the names in the expanded query on the view. Assigning aliases to " "the tables in a view enables them to be manipulated from outside the view." msgstr "" "ヒントはビュー自体には適用されませんが、オブジェクト名がビュー上に展開されたクエリ内のオブジェクト名と一致する場合、ビュー内のクエリに影響を与えることができます。ビュー内のテー" "ブルに別名を割り当てると、ビューの外からそれらを操作することができます。" #: ../../hint_details.md:121 d81a66ce90ca48edb415b092f5690892 msgid "Inheritance" msgstr "継承" #: ../../hint_details.md:123 86c3562c292f4868ba574a399bc8b5db msgid "" "Hints can only point to the parent of an inheritance tree and the hints affect all the tables in an inheritance tree. Hints pointing directly to inherited children have no " "effect." msgstr "ヒントは継承ツリーの親だけを指定することができ、そのヒントはすべての継承ツリー内のすべてのテーブルに影響します。継承された子を直接指定するヒントは無効です。" #: ../../hint_details.md:127 f01a507da8ed45958c52f6ad55f998ea msgid "Hints in multistatements" msgstr "マルチステートメントでのヒント" #: ../../hint_details.md:129 e24a1d1c1edb4748a0573d104e7c3532 msgid "One multistatement can have exactly one hint comment and the hint affects all of the individual statements in the multistatement." msgstr "1つのマルチステートメントに1つのヒントコメントを指定することができ、そのヒントはマルチステートメント内のすべてのステートメントに影響します。" #: ../../hint_details.md:132 7ab1fa26e6b74a19b7c44a186bc93a18 msgid "VALUES expressions" msgstr "VALUES式" #: ../../hint_details.md:134 1d97f6fc28ee46c58bc325d9102d1ee7 msgid "" "`VALUES` expressions in `FROM` clause are named as `*VALUES*` internally these can be hinted if it is the only `VALUES` of a query. Two or more `VALUES` expressions in a " "query cannot be distinguished by looking at an `EXPLAIN` result, resulting in ambiguous results:" msgstr "" "`FROM`句の`VALUES`式は、内部的には`*VALUES*`と名付けられ、それがクエリ内の唯一の`VALUES`である場合はヒントを使用できる可能性があります。2つ以上の`VALUES`式があるクエリは" "`EXPLAIN`の結果を見て区別が出来ず、曖昧な結果になります。" #: ../../hint_details.md:154 636c66f86ccc4c938da8429b753dab59 msgid "Subqueries" msgstr "副問い合わせ" #: ../../hint_details.md:156 62a8d739d2d9443bb292c8397211f4f4 msgid "Subqueries context can be occasionally hinted using the name `ANY_subquery`:" msgstr "サブクエリのコンテキストは`ANY_subquery`という名前を使用しヒントにすることができる場合があります。" #: ../../hint_details.md:162 59ae74ca166743ec9c463756422865fd msgid "" "For these syntaxes, the planner internally assigns the name to the subquery when planning joins on tables including it, so join hints are applicable on such joins using the " "implicit name. For example:" msgstr "" "これらの構文では副問い合わせを含むテーブルの結合を計画する際に、プランナは副問い合わせに対し内部的に名前を割り当てます。そのため、結合方法ヒントは暗黙の名前を使用している結合に" "適用することができます。以下は例です。" #: ../../hint_details.md:182 56e28c4fad6741959407ba67a1be3ffc msgid "Using `IndexOnlyScan` hint" msgstr "IndexOnlyScanヒントの使用" #: ../../hint_details.md:184 c8df5ac8fc8f4805abf2596cc4c17697 msgid "Index scan may be unexpectedly performed on another index when the index specified in IndexOnlyScan hint cannot perform an index only scan." msgstr "IndexOnlyScanヒントで指定されたインデックスでインデックスオンリースキャンを実行できない場合、インデックススキャンは予期せず別のインデックスで実行されることがあります。" #: ../../hint_details.md:187 d5f3694aa4a74b6180519f0245c77b19 msgid "About `NoIndexScan`" msgstr "NoIndexScanについて" #: ../../hint_details.md:189 af2d8839c12d405497c61ac7f096db16 msgid "A `NoIndexScan` hint implies `NoIndexOnlyScan`." msgstr "`NoIndexScan`ヒントは`NoIndexOnlyScan`を含んでいます。" #: ../../hint_details.md:191 7b1c81d6a8f445dda90d5cb8b940831b msgid "Parallel hints and `UNION`" msgstr "Parallelヒントと`UNION`" #: ../../hint_details.md:193 4378045c44ba4b068053d96a93b804e3 msgid "" "A `UNION` can run in parallel only when all underlying subqueries are parallel-safe. Hence, enforcing parallel on any of the subqueries will let a parallel-executable `UNION` " "run in parallel. Meanwhile, a parallel hint with zero workers prevents a scan from being executed in parallel." msgstr "" "UNIONが並列に実行できるのは、その下にあるすべてのサブクエリの並列実行が安全である場合のみです。したがってサブクエリのいずれかに並列実行を強制することで、並列実行可能なUNIONが並" "列で実行されます。一方、ワーカーがゼロのPARALLELヒントはスキャンの並列実行を禁止します。" #: ../../hint_details.md:198 7e9d03cde3d143bab35e398326a95c6e msgid "Setting `pg_hint_plan` parameters by Set hints" msgstr "Set ヒントによる`pg_hint_plan`のパラメータ設定" #: ../../hint_details.md:200 3be5ca4f3613473692ea3455539d8331 msgid "`pg_hint_plan` parameters influence their own behavior so some parameters will not work as one could expect:" msgstr "・`pg_hint_plan`のパラメータはそれ自身の動作に影響を与えるため、一部のパラメータは期待通りに動作しません。" #: ../../hint_details.md:203 5e695b242e46453cada9f438b4130518 msgid "Hints to change `enable_hint`, `enable_hint_table` are ignored even though they are reported as \"used hints\" in debug logs." msgstr "・`enable_hint`, `enable_hint_table`を変更するヒントは、デバッグログに\"used hints\"として報告されても無視されます。" #: ../../hint_details.md:205 f0ebb2cc2425457488d18e1a58430c48 msgid "Setting `debug_print` and `message_level` in the middle of query processing." msgstr "・`debug_print`と`message_level`の設定は、対象クエリの処理の途中から動作します。" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/hint_list.po000066400000000000000000000324401466301071500241060ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan hint list. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-09 10:50+0900\n" "PO-Revision-Date: 2024-08-16 14:15+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.3.1\n" #: ../../hint_list.md:2 c40cade5f7394eff896a1fae64bb3ca2 msgid "Hint list" msgstr "ヒント一覧" #: ../../hint_list.md:4 2b0acbfb86334a4fae352628abd1bea2 msgid "The available hints are listed below." msgstr "使用可能なヒントは以下の通りです。" #: ../../hint_list.md f91b7fcf62f34ce88bfc5951b88d2a29 msgid "Group" msgstr "グループ" #: ../../hint_list.md 40323de5ffdc4f9cbf0780ba64efebb0 msgid "Format" msgstr "書式" #: ../../hint_list.md bd08a39ffa394a1485b63af6e23b2cec msgid "Description" msgstr "説明" #: ../../hint_list.md f4146154e6da45f7b2dc29d6bfd6c6a7 msgid "Scan method" msgstr "スキャン方法" #: ../../hint_list.md b1b3b1a782994cd6b760df17dbafa074 msgid "`SeqScan(table)`" msgstr "`SeqScan(テーブル)`" #: ../../hint_list.md f82f7f55ea184a2c92f5e1e9509e318e msgid "Forces sequential scan on the table." msgstr "指定されたテーブルにシーケンシャルスキャンを強制します。" #: ../../hint_list.md 145bd514e772470ab1a5924bb6109643 msgid "`TidScan(table)`" msgstr "`TidScan(テーブル)`" #: ../../hint_list.md 958102fdfa3f4971b73b5be989813f43 msgid "Forces TID scan on the table." msgstr "指定されたテーブルにTid スキャンを強制します。検索条件にctidを指定した場合にのみ有効です。" #: ../../hint_list.md e28e42e2bdb14ac1a39c21f22e89f555 msgid "`IndexScan(table[ index...])`" msgstr "`IndexScan(テーブル[ インデックス...])`" #: ../../hint_list.md dfbea9060cff4572954e015184ff0cc1 msgid "Forces index scan on the table. Restricts to specified indexes if any." msgstr "指定されたテーブルにインデックススキャンを強制します。指定されたインデックスがある場合は、そのインデックスに限定されます。" #: ../../hint_list.md 09b256ecb32a4e09b4f34fdd29bde0a1 msgid "`IndexOnlyScan(table[ index...])`" msgstr "`IndexOnlyScan(テーブル[ インデックス...])`" #: ../../hint_list.md 3d25b282381e442aad737d8a240a2278 msgid "Forces index-only scan on the table. Restricts to specified indexes if any. Index scan may be used if index-only scan is not available." msgstr "" "指定されたテーブルにインデックスオンリースキャンを強制します。指定されたインデックスがある場合は、そのインデックスに限定されます。インデックスオンリースキャンが利用できない場合、インデッ" "クススキャンが使用されることがあります。" #: ../../hint_list.md ef6a8a2ee1434574a7a97aafc8d17b44 msgid "`BitmapScan(table[ index...])`" msgstr "`BitmapScan(テーブル[ インデックス...])`" #: ../../hint_list.md 00c7618bea744cabb797e8522e9196c3 msgid "Forces bitmap scan on the table. Restricts to specified indexes if any." msgstr "指定されたテーブルにビットマップスキャンを強制します。指定されたインデックスがある場合は、そのインデックスに限定されます。" #: ../../hint_list.md d81cb4f03ae64385bad555f177cdfe00 msgid "`IndexScanRegexp(table[ POSIX Regexp...])`
`IndexOnlyScanRegexp(table[ POSIX Regexp...])`
`BitmapScanRegexp(table[ POSIX Regexp...])`" msgstr "`IndexScanRegexp(テーブル[ POSIX正規表現...])`
`IndexOnlyScanRegexp(テーブル[ POSIX正規表現...])`
`BitmapScanRegexp(テーブル[ POSIX正規表現...])`" #: ../../hint_list.md 5d6890da45c349078f67f070a5ee21da msgid "Forces index scan, index-only scan (For PostgreSQL 9.2 and later) or bitmap scan on the table. Restricts to indexes that matches the specified POSIX regular expression pattern." msgstr "" "指定されたテーブルにインデックススキャン、インデックスオンリースキャン(PostgreSQL 9.2以降)、ビットマップスキャンを強制します。指定されたPOSIX正規表現パターンに一致するインデックスに限" "定されます。" #: ../../hint_list.md c78d46c767ff4c3b9137559cd9926280 msgid "`NoSeqScan(table)`" msgstr "`NoSeqScan(テーブル)`" #: ../../hint_list.md faed61dedefa4e9f9fb9be090e255edc msgid "Forces to *not* do sequential scan on the table." msgstr "指定されたテーブルにシーケンシャルスキャンを行わないように強制します。" #: ../../hint_list.md ab5e0d65a07c448e81ca8e12797df933 msgid "`NoTidScan(table)`" msgstr "`NoTidScan(テーブル)`" #: ../../hint_list.md cd3695b5208f416f92aa6e63e7a14d1b msgid "Forces to *not* do TID scan on the table." msgstr "指定されたテーブルにTIDスキャンを行わないように強制します。" #: ../../hint_list.md 4f0508bf243c43c383d24734bc3ecb40 msgid "`NoIndexScan(table)`" msgstr "`NoIndexScan(テーブル)`" #: ../../hint_list.md 0809d85d431846c3ba854441fa5e3615 msgid "Forces to *not* do index scan and index-only scan on the table." msgstr "指定されたテーブルに対してインデックススキャン、インデックスオンリースキャンを行わないように強制します。" #: ../../hint_list.md 31f3e92fcd7f4f278cff7305fdc89ec2 msgid "`NoIndexOnlyScan(table)`" msgstr "`NoIndexOnlyScan(テーブル)`" #: ../../hint_list.md 77890cf2fe81441aaa17378e6254ef3b msgid "Forces to *not* do index only scan on the table." msgstr "指定されたテーブルにTIDスキャンを行わないように強制します。" #: ../../hint_list.md b92575691ae2461fbf89f613acd9ea89 msgid "`NoBitmapScan(table)`" msgstr "`NoBitmapScan(テーブル)`" #: ../../hint_list.md 334171be615a499ca764f9d7331765c6 msgid "Forces to *not* do bitmap scan on the table." msgstr "指定されたテーブルにビットマップスキャンを行わないように強制します。" #: ../../hint_list.md c7a5b8df02cd4727be915878e1ab144e msgid "Join method" msgstr "結合方法" #: ../../hint_list.md 547262bc8f1a463385eae1c799959982 msgid "`NestLoop(table table[ table...])`" msgstr "`NestLoop(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 31460cf6de3f4541a0a837bd17c09ecb msgid "Forces nested loop for the joins on the tables specified." msgstr "指定されたテーブルで構成された結合にネステッドループ結合を強制します。" #: ../../hint_list.md 9488fd678bac48309d7355ebb65c31f7 msgid "`HashJoin(table table[ table...])`" msgstr "`HashJoin(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 0e5228a6ccb646808507f07171028866 msgid "Forces hash join for the joins on the tables specified." msgstr "指定されたテーブルで構成された結合にハッシュ結合を強制します。" #: ../../hint_list.md 23840bb111534beebb84a9720ef73edf msgid "`MergeJoin(table table[ table...])`" msgstr "`MergeJoin(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 922c4b3dee5740feabe8064c3cb0b5fc msgid "Forces merge join for the joins on the tables specified." msgstr "指定されたテーブルで構成された結合にマージ結合を強制します。" #: ../../hint_list.md 9d74eb0256e345d1ac4401c417403291 msgid "`NoNestLoop(table table[ table...])`" msgstr "`NoNestLoop(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 9a5dcf745f034721a76969eff89575a2 msgid "Forces to *not* do nested loop for the joins on the tables specified." msgstr "指定されたテーブルで構成する結合にネステッドループ結合が行われないように強制します。" #: ../../hint_list.md c29046a3b4e54453ba444c8fd8d4e26d msgid "`NoHashJoin(table table[ table...])`" msgstr "`NoHashJoin(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md c2971905586543b487fb53812bf35961 msgid "Forces to *not* do hash join for the joins on the tables specified." msgstr "指定されたテーブルで構成する結合にハッシュ結合が行われないように強制します。" #: ../../hint_list.md ae780b74c8524858bfd7b88696af6e97 msgid "`NoMergeJoin(table table[ table...])`" msgstr "`NoMergeJoin(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md d24008e3567944be8aacae813ba4105e msgid "Forces to *not* do merge join for the joins on the tables specified." msgstr "指定されたテーブルで構成する結合にマージ結合が行われないように強制します。" #: ../../hint_list.md 8154344c9f9e47508fd63f089fffa3c2 msgid "Join order" msgstr "結合順序" #: ../../hint_list.md c45be6a3fcc64f6e97c7386e9306a97b msgid "`Leading(table table[ table...])`" msgstr "`Leading(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 78b43f0317d9456789c4c5adf4ccddaf msgid "Forces join order as specified." msgstr "指定された結合順序に強制します。" #: ../../hint_list.md e882b1ca7bce4e0b814cf095200d9eb2 msgid "`Leading()`" msgstr "`Leading(<結合のペア>)`" #: ../../hint_list.md c18c0f1dca87413e8e319600619b7867 msgid "Forces join order and directions as specified. A join pair is a pair of tables and/or other join pairs enclosed by parentheses, which can make a nested structure." msgstr "指定された結合順序と方向を強制します。結合ペアは、括弧で囲まれたテーブルや他の結合ペアのペアであり、入れ子構造を作ることができます。" #: ../../hint_list.md 3711c2f8a3c04944bf5762e3ae68cdd1 msgid "Behavior control on Join" msgstr "結合時の挙動制御" #: ../../hint_list.md b99d34945e5a4d07a030a34ed76e47a2 msgid "`Memoize(table table[ table...])`" msgstr "`Memoize(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 9866d5d20fb94c0099520bcb6edddbd1 msgid "Allows the topmost join of a join among the specified tables to Memoize the inner result. Not enforced." msgstr "指定されたテーブル間の結合の最上位の結合において内部表の結果をメモすることを許可する (これは強制ではないことに注意)。" #: ../../hint_list.md 8f6a69e9f51a49f1ae925809bb47a14d msgid "`NoMemoize(table table[ table...])`" msgstr "`NoMemoize(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md a73672326e2046e59e895b5e0baedef1 msgid "Inhibits the topmost join of a join among the specified tables from Memoizing the inner result." msgstr "指定されたテーブル間の結合の最上位の結合において内部表の結果をメモすることを禁止します。" #: ../../hint_list.md 3872222d3ec048a98dbb3deb96f950aa msgid "Row number correction" msgstr "見積り行数の補正" #: ../../hint_list.md 180b1e30ad6e4342b88089cf66a14c29 msgid "`Rows(table table[ table...] correction)`" msgstr "`Rows(テーブル テーブル[ テーブル...] 行数補正)`" #: ../../hint_list.md 827854e5182f4f859f79abaeda7ad8a0 msgid "" "Corrects row number of a result of the joins on the tables specified. The available correction methods are absolute (#), addition (+), subtract (-) and multiplication (*). " " should be a string that strtod() can understand." msgstr "指定されたテーブルの結合結果の見積り行数を補正します。補正方法は、絶対値(#)、加算(+)、減算(-)、乗算(*)です。はstrtod()が読み込める文字列でなければなりません。" #: ../../hint_list.md a47c2a56dcea4861ba83cfdd8bcbea11 msgid "Parallel query configuration" msgstr "パラレルクエリの設定" #: ../../hint_list.md ad67231a118a4c0d8114f74dc9d67afc msgid "`Parallel(table <# of workers> [soft|hard])`" msgstr "`Parallel(table <ワーカー数> [soft|hard])`" #: ../../hint_list.md 9aaf73225b934735bbbee9f49469340e msgid "" "Enforces or inhibits parallel execution of the specified table. <# of workers> is the desired number of parallel workers, where zero means inhibiting parallel execution. If the third " "parameter is soft (default), it just changes max\\_parallel\\_workers\\_per\\_gather and leaves everything else to the planner. Hard enforces the specified number of workers." msgstr "" "指定されたテーブルの並列実行を強制または禁止します。<ワーカー数>は希望する並列ワーカー数で、0は並列実行を禁止することを意味します。第3パラメータがsoft(デフォルト)の場合、" "max_parallel_workers_per_gatherを変更するだけで、その他すべてはプランナに任せます。hardは指定された数のワーカーを強制することを意味します。" #: ../../hint_list.md d22ccbc78ad648498c306050c5b494f2 msgid "GUC" msgstr "GUCパラメータ" #: ../../hint_list.md 31157060ff3e4e74b9e1617bb5351fe5 msgid "`Set(GUC-param value)`" msgstr "`Set(GUCパラメータ 値)`" #: ../../hint_list.md 44a5a20bd91841e19c3a21d01286b5b4 msgid "Sets GUC parameter to the value defined while planner is running." msgstr "プランナが実行中の間、GUCパラメータの値を設定します。" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/hint_table.po000066400000000000000000000361641466301071500242310ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan hint table. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-16 12:31+0900\n" "PO-Revision-Date: 2024-08-16 14:14+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.3.1\n" #: ../../hint_table.md:1 d5e29e9243944d378afc28a3ef9e4261 msgid "The hint table" msgstr "ヒントテーブル" #: ../../hint_table.md:3 47bc7fa2efae4cfcb040da3133fa74af msgid "" "Hints can be specified in a comment, still this can be inconvenient in the case where queries cannot be edited. In the case, hints can be placed in a " "special table named `\"hint_plan.hints\"`. The table consists of the following columns:" msgstr "" "ヒントは特別な形式のコメント内に記載されていますがクエリを編集できない場合には不便です。このような場合には `\"hint_plan.hints\"` という名前の特別なテー" "ブルにヒントを置くことができます。このテーブルは以下のカラムで構成されています。" #: ../../hint_table.md 257b4d6ddbe7427e828401975dbf5c75 msgid "column" msgstr "列名" #: ../../hint_table.md a265878e2d434780b4bb3c614b60f4a7 msgid "description" msgstr "説明" #: ../../hint_table.md 0626b241d00c4139a3b21495beb7f395 msgid "`id`" msgstr "`id`" #: ../../hint_table.md fa107e7b73bb441987e6c46cd5abb911 msgid "Unique number to identify a row for a hint.
This column is filled automatically by sequence." msgstr "ユーザがヒントの行を識別するためのユニークな番号です。
この列はシーケンスによって自動的に埋められます。" #: ../../hint_table.md 97c539337d894cd3b64fb6efe0490d02 msgid "`query_id`" msgstr "`query_id`" #: ../../hint_table.md 6600ea7b7cdf4b9695a49a9df74d4d14 msgid "A unique query ID, generated by the backend when the GUC compute_query_id is enabled" msgstr "GUCのcompute_query_idが有効な場合にバックエンドによって生成される一意のクエリID。" #: ../../hint_table.md 0a057e3f21d848f197414fcec0570e9e msgid "`application_name`" msgstr "`application_name`" #: ../../hint_table.md 41a7f7d2faf54ade8a041c5fa1316843 msgid "" "The value of `application_name` where sessions can apply a hint.
The hint in the example below applies to sessions connected from psql.
An " "empty string implies that all sessions will apply the hint." msgstr "" "ヒントの適用対象のアプリケーション名を指定します。
下記の例ではpsqlから実行されたクエリのみがヒントの適用対象となります。
全てのアプリケーションに" "ヒントを適用したいときは、空文字列を登録します。" #: ../../hint_table.md f594152664974e1dba79681ba20743c5 msgid "`hints`" msgstr "`hints`" #: ../../hint_table.md 104a6c7ac4e4442e8521e494d63874cd msgid "Hint phrase.
This must be a series of hints excluding surrounding comment marks." msgstr "ヒント句を指定します。
コメントの記号を除いたヒントのみを登録します。" #: ../../hint_table.md:14 2aa6f927e9a94a82b9a405ca2a13e211 msgid "The following example shows how to operate with the hint table." msgstr "以下の例はヒントテーブルの操作方法を示しています。" #: ../../hint_table.md:36 ad072848da8548fe81277c310879bc0c msgid "" "The hint table is owned by the extension owner and has the same default privileges as of the time of its creation, during `CREATE EXTENSION`. Hints in " "the hint table are prioritized over hints in comments." msgstr "" "ヒントテーブルは拡張機能の所有者が所有し、拡張機能作成時におけるデフォルトの権限を持ちます。ヒントテーブル内のヒントはコメント内のヒントよりも優先されま" "す。" #: ../../hint_table.md:40 c8fe0e15e08b4a0fab8510ed71ad21b5 msgid "The query ID can be retrieved with `pg_stat_statements` or with `EXPLAIN (VERBOSE)`." msgstr "クエリIDは `pg_stat_statements` または `EXPLAIN (VERBOSE)` で取得できます。" #: ../../hint_table.md:43 c5cbb642d29740e8b996da4532c76b9f msgid "Types of hints" msgstr "ヒントの種類" #: ../../hint_table.md:45 860e8cdc60d743039bb9b2d0ea84c152 msgid "" "Hinting phrases are classified in multiple types based on what kind of object and how they can affect the planner. See [Hint list](#hint-list) for " "more details." msgstr "" "ヒント句は、対象の種類とプランナーにどのような影響を与えるかに基づいて複数のタイプに分類されます。 詳細は [ヒント一覧](#hint-list) を参照してください。" #: ../../hint_table.md:49 81c5d901db3d496cb739ca90ca6dfd5d msgid "Hints for Scan methods" msgstr "スキャン方法" #: ../../hint_table.md:51 bdd078bb5e09472babc95bbdc85cb6ea msgid "" "Scan method hints enforce specific scanning methods on the target table. `pg_hint_plan` recognizes the target table by alias names if any. These are " "for example `SeqScan` or `IndexScan`." msgstr "" "スキャン方法のヒントは、対象のテーブルに対して特定のスキャン方法を強制するものです。`pg_hint_plan`は対象のテーブルに別名が存在する場合、別名で認識しま" "す。この種類の例は`SeqScan`や`IndexScan`などです。" #: ../../hint_table.md:55 73f2ba98001348898615cb42c58b1af6 msgid "" "Scan hints work on ordinary tables, inheritance tables, UNLOGGED tables, temporary tables and system catalogs. External (foreign) tables, table " "functions, VALUES clause, CTEs, views and subqueries are not affected." msgstr "" "スキャン方法のヒントは、通常のテーブル・継承テーブル・UNLOGGEDテーブル・一時テーブル・システムカタログに効果があります。外部テーブル・テーブル関数・" "VALUES句・CTE・ビュー・副問い合わせには影響を与えません。" #: ../../hint_table.md:67 eeaae9de758b4d1499fc954d14c79db0 msgid "Hints for Join methods" msgstr "結合方法" #: ../../hint_table.md:69 1103ebdd7e654948bd11b6fd104e1757 msgid "Join method hints enforce the join methods of the joins involving the specified tables." msgstr "結合方法のヒントは、指定したテーブルを含む結合の結合方法を強制するものです。" #: ../../hint_table.md:72 fa0aa667050e43148583eb9a76886ab2 msgid "" "This can affect joins only on ordinary tables. Inheritance tables, UNLOGGED tables, temporary tables, external (foreign) tables, system catalogs, " "table functions, VALUES command results and CTEs are allowed to be in the parameter list. Joins on views and subqueries are not affected." msgstr "" "これは、通常のテーブル・継承テーブル・UNLOGGEDテーブル・一時テーブル・外部テーブル・システムカタログ・テーブル関数・VALUESコマンド結果、およびパラメータ" "リストに含めることが許可されているCTEの結合にのみ影響を与えます。しかし、ビュー・副問い合わせの結合には影響を与えません。" #: ../../hint_table.md:77 6a9df9a5627c4718bbb239723eb8c6c9 msgid "Hints for Joining order" msgstr "結合順" #: ../../hint_table.md:79 3871b177565446e5b90a8a9b78ddc809 msgid "" "This hint, named \"Leading\", enforces the order of join on two or more tables. There are two methods of enforcing it. The first method enforces a " "specific order of joining but does not restrict the direction at each join level. The second method enforces the join direction additionally. See " "[hint list](#hint-list) for more details. For example:" msgstr "" "`Leading`ヒントは、2つ以上のテーブルの結合順を強制するものです。強制には2つの方法があります。1つは特定の結合順を強制し各結合レベルでは方向を制限しない方" "法です。もう1つは結合の方向を追加で指定するものです。詳細は [ヒント一覧](#hint-list) を参照してください。以下は例です。" #: ../../hint_table.md:96 f06e77ee2abd4cd796cad3d0cb9228b6 msgid "Hints for Row number corrections" msgstr "行数補正" #: ../../hint_table.md:98 d3f4087fc6df4ba1bf25714d3b5d1d73 msgid "This hint, named \"Rows\", changes the row number estimation of joins that comes from restrictions in the planner. For example:" msgstr "`Rows`ヒントは、プランナの制限に起因する結合の見積り行数誤りを修正します。以下は例です。" #: ../../hint_table.md:108 5b5f4d8c0a3644c3900834ed79050b46 msgid "Hints for parallel plans" msgstr "パラレルプラン" #: ../../hint_table.md:110 7ff9e4b9e2ab4325a7d8db4b610edc15 msgid "" "This hint, named `Parallel`, enforces parallel execution configuration on scans. The third parameter specifies the strength of the enforcement. `soft` " "means that `pg_hint_plan` only changes `max_parallel_worker_per_gather` and leaves all the others to the planner to set. `hard` changes other planner " "parameters so as to forcibly apply the update. This can affect ordinary tables, inheritance parents, unlogged tables and system catalogs. External " "tables, table functions, `VALUES` clauses, CTEs, views and subqueries are not affected. Internal tables of a view can be specified by its real name or " "its alias as the target object. The following example shows that the query is enforced differently on each table:" msgstr "" "`Parallel`ヒント は、スキャンの並列実行の設定を強制するものです。第3パラメータは強制の強さを指定します。`soft` は `pg_hint_plan` が " "`max_parallel_worker_per_gather` を変更するだけで、その他のすべてはプランナに任せることを意味します。`hard`はプランナのパラメータを変更し、強制的にその" "数値を適用するようにします。\n" "このヒントは通常のテーブル・継承の親テーブル・UNLOGGEDテーブル・システムカタログに影響を与えることができます。外部テーブル・テーブル関数・VALUE句・CTE・" "ビュー・サブクエリには影響を与えません。\n" "ビューの内部テーブルについては、対象オブジェクトとして実名/別名を用いて指定できます。次の例のクエリは、各テーブルで異なる設定を強制しています。" #: ../../hint_table.md:146 45e5d5c076714f68bfa303be3ac45107 msgid "GUC parameters set during planning" msgstr "プランニング中のGUCパラメータの設定" #: ../../hint_table.md:148 5437230ab09a445d80fa1cacb76fcb06 msgid "" "`Set` hints change GUC parameters just while planning. GUC parameter shown in [Query Planning](http://www.postgresql.org/docs/current/static/runtime-" "config-query.html) can have the expected effects on planning unless an other hint conflicts with the planner method configuration parameters. When " "multiple hints change the same GUC, the last hint takes effect. [GUC parameters for `pg_hint_plan`](#guc-parameters-for-pg_hint_plan) are also settable " "by this hint but it may not work as expected. See [Functional limitations](#functional-limitations) for details." msgstr "" "`Set`ヒントはプランニング中のみGUCパラメータを変更します。 [Query Planning](http://www.postgresql.org/docs/current/static/runtime-config-query.html) で" "示したGUCパラメータは、他のヒントがプランナの設定パラメータと競合しない限り、期待される効果を発揮することができます。同じGUCパラメータに関するヒントのう" "ち、最後のものが効果を発揮します。[pg_hint_planのGUCパラメータ](#guc-parameters-for-pg_hint_plan) もこのヒントで設定可能ですが期待通りには動作しません。" "詳しくは [機能的な制限事項](functional_limitations) を参照してください。" #: ../../hint_table.md:164 62e65a9215d041a9b25f40d2aec22ed7 msgid "GUC parameters for `pg_hint_plan`" msgstr "pg_hint_planのGUCパラメータ" #: ../../hint_table.md:166 34c7ef2b017041928934d57f22ee5828 msgid "The following GUC parameters affect the behavior of `pg_hint_plan`:" msgstr "以下のGUCパラメータは`pg_hint_plan`の動作を制御します。" #: ../../hint_table.md 5d17e6a2dd294a58b68442672f9723bf msgid "Parameter name" msgstr "パラメータ名" #: ../../hint_table.md f2d269076d224dc18e066cb27e80089e msgid "Description" msgstr "説明" #: ../../hint_table.md b0223245ed2a4693ab41fd7715e8fe3d msgid "Default" msgstr "デフォルト値" #: ../../hint_table.md 4e7482606a8141b6961b8db74d8820a4 msgid "`pg_hint_plan.enable_hint`" msgstr "`pg_hint_plan.enable_hint`" #: ../../hint_table.md e556bec8fcc04b859b48fb0be0528d25 msgid "True enables `pg_hint_plan`." msgstr "Trueはpg_hint_planを有効にします。" #: ../../hint_table.md 7bfae58a0571426ca570a972781def2b msgid "`on`" msgstr "`on`" #: ../../hint_table.md ed96b88c617e4e49a73a8fffd04a8c6f msgid "`pg_hint_plan.enable_hint_table`" msgstr "`pg_hint_plan.enable_hint_table`" #: ../../hint_table.md fe43fd4e5cc547f79add4b378ad35fc3 msgid "True enables hinting by table." msgstr "Trueはテーブルによってヒントを指定する機能を有効にします。" #: ../../hint_table.md 0474c686048c4290a22295dc8dcd5df4 e660670e5fbf4f7b97173f4340eb82f4 msgid "`off`" msgstr "`off`" #: ../../hint_table.md 33590bf0ffd64d839af909b31f35e8cb msgid "`pg_hint_plan.parse_messages`" msgstr "`pg_hint_plan.parse_messages`" #: ../../hint_table.md c340fdd99b374c2d9ff1fef685d26ce3 msgid "Specifies the log level of hint parse error. Valid values are `error`, `warning`, `notice`, `info`, `log`, `debug`." msgstr "" "指定したヒントを構文解析できなかった場合のログメッセージのレベルを指定します。指定可能な値は、`error`、`warning`、`notice`、`info`、`log`、`debug`です。" #: ../../hint_table.md 363b14bba8874bfabf2d981c4420b1fb 4770dd2d59b945898f1ade9b58127b45 msgid "`INFO`" msgstr "`INFO`" #: ../../hint_table.md 156e6b925df24c978ae2345e83255954 msgid "`pg_hint_plan.debug_print`" msgstr "`pg_hint_plan.debug_print`" #: ../../hint_table.md c5088bbf9dae403790de11636ad2cbc4 msgid "Controls debug print and verbosity. Valid values are `off`, `on`, `detailed` and `verbose`." msgstr "動作状況を示すログメッセージの出力を制御します。指定可能な値は `off`、`on`、`detailed`、`verbose`です。" #: ../../hint_table.md 7b1961e1403a4fa9bf15f296ae39c0b2 msgid "`pg_hint_plan.message_level`" msgstr "`pg_hint_plan.message_level`" #: ../../hint_table.md 0dd33a2c38b544b5b1d7f9618dc71106 msgid "Specifies message level of debug print. Valid values are `error`, `warning`, `notice`, `info`, `log`, `debug`." msgstr "動作ログメッセージのログレベルを指定します。指定可能な値は、`error`、`warning`、`notice`、`info`、`log`、`debug`です。" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/index.po000066400000000000000000000017061466301071500232210ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan index page. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: pg_hint_plan \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-02 12:25+0800\n" "PO-Revision-Date: 2023-03-02 12:28+0800\n" "Last-Translator: Julien Rouhaud \n" "Language: ja\n" "Language-Team: \n" "Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.12.1\n" #: ../../index.md:1 1477c3a63d6140379ebc8ee8e6949aac msgid "pg_hint_plan 1.7" msgstr "pg_hint_plan 1.7" #: ../../index.md:2 b5608f9be7e34270a28850acab4a3fae msgid "Table of Contents" msgstr "目次" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/installation.po000066400000000000000000000102621466301071500246100ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan installation. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-16 12:31+0900\n" "PO-Revision-Date: 2024-08-16 13:16+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.3.1\n" #: ../../installation.md:1 50df0ae9dc3440d6a815c6ef26c7554c msgid "Installation" msgstr "インストール" #: ../../installation.md:3 ce350c3d57b946cf850065fae5e451f5 msgid "This section describes the installation steps." msgstr "このセクションはpg_hint_planのインストール方法について説明します。" #: ../../installation.md:5 9b0f6b3fcef044d2ad1995eb6ddd9b4c msgid "Building binary module" msgstr "バイナリモジュールのビルド" #: ../../installation.md:7 906f2a0f48ad43e6a9bdb693beeaa89f msgid "" "Simply run `make` at the top of the source tree, then `make install` as " "an appropriate user. The `PATH` environment variable should be set " "properly to point to a PostgreSQL set of binaries:" msgstr "" "ソースツリーの先頭で `make` を実行し、適切なユーザで `make install` を実" "行してください。環境変数 `PATH` は、PostgreSQLのバイナリを指すように適切" "に設定する必要があります。" #: ../../installation.md:17 fa39e0a770924c769e4b135228295613 msgid "Installing from a binary package" msgstr "バイナリパッケージからのインストール" #: ../../installation.md:19 919e858345704fff88dc911a8ced663c msgid "" "On Debian and Ubuntu `pg_hint_plan` is available as a binary package " "from the pgdg (PostgreSQL Global Development Group) repository. " "Assuming you've already added the repository to `apt` sources, " "installing the package is as simple as:" msgstr "" "Debian と Ubuntu では `pg_hint_plan` を pgdg (PostgreSQL Global " "Development Group) リポジトリからバイナリパッケージとして入手できます。 " "すでに `apt` ソースにリポジトリを追加していると仮定すると、パッケージのイ" "ンストールは以下のように簡単です。" #: ../../installation.md:28 2dc3c05224514f588dcad0bae41f6e37 msgid "" "Please visit https://www.postgresql.org/download/linux/ if you need help " "at adding the repository." msgstr "" "リポジトリの追加に関するヘルプが必要な場合は、https://www.postgresql.org/" "download/linux/ にアクセスしてください。" #: ../../installation.md:31 f8cec76d911a42748efd32fddef63c7b msgid "Loading `pg_hint_plan`" msgstr "`pg_hint_plan`のロード" #: ../../installation.md:33 73461d6617604fcbbf2e0acf508ac896 msgid "" "`pg_hint_plan` does not require `CREATE EXTENSION`. Loading it with a " "`LOAD` command will activate it and of course you can load it globally " "by setting `shared_preload_libraries` in `postgresql.conf`. Or you " "might be interested in `ALTER USER SET`/`ALTER DATABASE SET` for " "automatic loading in specific sessions." msgstr "" "`pg_hint_plan` は基本的に`CREATE EXTENSION`を必要としません。単純に`LOAD`" "コマンドで有効化できます。もちろん、`postgresql.conf`の" "`shared_preload_libraries` を設定することで全体にロード することもできま" "す。また、特定のユーザに対し自動的にロードするための`ALTER USER SET`/" "`ALTER DATABASE SET`に興味があるかもしれません。" #: ../../installation.md:44 ea8f6cb49cac4ab3b2db7161387344cd msgid "" "Run `CREATE EXTENSION` and `SET pg_hint_plan.enable_hint_table TO on` if " "you are planning to use the hint table." msgstr "" "ヒントテーブルを使用する場合は、`CREATE EXTENSION` を実行し`SET " "pg_hint_plan.enable_hint_table TO on`を実行してください。" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/requirements.po000066400000000000000000000052431466301071500246350ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan requirements. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-09 10:50+0900\n" "PO-Revision-Date: 2023-11-10 08:31+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.2.2\n" #: ../../requirements.md:1 26f3405d14e1471d98d797d27f70f0e1 msgid "Requirements" msgstr "動作環境" #: ../../requirements.md:3 e2a338fd547c4102a8ba452a1ce76fe4 msgid "pg_hint_plan 1.7 requires PostgreSQL 17." msgstr "pg_hint_plan 1.7 は PostgreSQL 17 のみをサポートします。" #: ../../requirements.md:5 2f43757380444e08ab0e181a788a1b78 msgid "PostgreSQL versions tested" msgstr "テスト済みのPostgreSQLバージョン" #: ../../requirements.md:7 744d9ef1bc3240a9af15e103cf476a19 msgid "Version 17" msgstr "・バージョン 17" #: ../../requirements.md:9 27a4d38176f445efaec1e1f5367ab674 msgid "OS versions tested" msgstr "テスト済みのOSバージョン" #: ../../requirements.md:11 eb5a718ba289445eb2478b2650b23bfd msgid "CentOS 8.5" msgstr "・CentOS 8.5" #: ../../requirements.md:13 4f3befbd04964972b9a7fb70ba217dfe msgid "See also" msgstr "関連項目" #: ../../requirements.md:16 13bf779462964c18a3e97148198d04f3 msgid "References" msgstr "" #: ../../requirements.md:18 554dc9beb49d4774a7e3c99e426cc9c1 msgid "[EXPLAIN](http://www.postgresql.org/docs/current/static/sql-explain.html)" msgstr "[EXPLAIN](http://www.postgresql.org/docs/current/static/sql-explain.html)" #: ../../requirements.md:19 f960539e7df047a39a37f7660b8ed5e5 msgid "[SET](http://www.postgresql.org/docs/current/static/sql-set.html)" msgstr "[SET](http://www.postgresql.org/docs/current/static/sql-set.html)" #: ../../requirements.md:20 bab201f98ce04f06a704b1f766459215 msgid "" "[Server Config](http://www.postgresql.org/docs/current/static/runtime-config." "html)" msgstr "" "[Server Config](http://www.postgresql.org/docs/current/static/runtime-config." "html)" #: ../../requirements.md:21 562b990d519e4102a2fe16ae980a37ef msgid "" "[Parallel Plans](http://www.postgresql.org/docs/current/static/parallel-plans." "html)" msgstr "" "[Parallel Plans](http://www.postgresql.org/docs/current/static/parallel-plans." "html)" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/synopsis.po000066400000000000000000000043571466301071500240060ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan synopsis. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-09 10:50+0900\n" "PO-Revision-Date: 2023-11-10 08:42+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.2.2\n" #: ../../synopsis.md:1 5f2c3282c7b24c629ef71f0dbfff3d60 msgid "Synopsis" msgstr "概要" #: ../../synopsis.md:3 a16cf76f5d7f484da866552664d1ec30 msgid "`pg_hint_plan` makes it possible to tweak PostgreSQL execution plans using \"hints\" in SQL comments, as of `/*+ SeqScan(a) */`." msgstr "`pg_hint_plan`はSQLコメント内のヒント (`/*+ SeqScan(a) */`など) を用いることで実行計画を制御することができます。" #: ../../synopsis.md:6 e5e5c5196620409aa703e094e4d8ad9f msgid "" "PostgreSQL uses a cost-based optimizer, which utilizes data statistics, not static rules. The planner (optimizer) estimates costs of each possible execution plans for a SQL statement then the execution plan " "with the lowest cost is executed. The planner does its best to select the best execution plan, but is not always perfect, since it doesn't take into account some of the data properties or correlations between " "columns." msgstr "" "PostgreSQLのプランナは静的なルールではなくデータの統計情報を用いたコストベースのオプティマイザを利用しています。プランナ(オプティマイザ)はSQL文に対して可能な限りの実行計画のコストを推定し、最もコストが低い実行" "計画を選択します。プランナは最適な実行計画を選択するために最善を尽くしますが、データの特性やカラム間の相関を考慮していないため、必ずしも完璧ではありません。" pg_hint_plan-REL17_1_7_0/docs/locale/ja/LC_MESSAGES/uninstallation.po000066400000000000000000000030441466301071500251530ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan uninstallation. # Copyright (C) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # Tatsuro Yamada , 2023-2024. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-09 10:50+0900\n" "PO-Revision-Date: 2023-11-10 08:46+0900\n" "Last-Translator: Tatsuro Yamada \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.12.1\n" "X-Generator: Poedit 3.2.2\n" #: ../../uninstallation.md:1 f3cc8a1c1ca3459ab9d7e0d78b5ebad0 msgid "Uninstallation" msgstr "アンインストール" #: ../../uninstallation.md:3 aa4ccdaf9927460fb3c337548536e4f3 msgid "" "`make uninstall` in the top directory of source tree will uninstall the " "installed files if you installed from the source tree and it is left " "available. Setting the environment variable `PATH` may be necessary." msgstr "" "ソース ツリーからインストールし、それが利用可能なままになっている場合は、" "ソース ツリーの最上位ディレクトリにある `make uninstall` を実行するとイン" "ストールされたファイルがアンインストールされます。環境変数 `PATH` の設定" "が必要な場合があります。" pg_hint_plan-REL17_1_7_0/docs/make.bat000066400000000000000000000014401466301071500175340ustar00rootroot00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.https://www.sphinx-doc.org/ exit /b 1 ) if "%1" == "" goto help %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd pg_hint_plan-REL17_1_7_0/docs/requirements.in000066400000000000000000000004351466301071500212050ustar00rootroot00000000000000# RTD only supports sphinx up to 5.3.0 sphinx==5.3.0 # those are sphinx dependencies, but unfortunately RTD doesn't support the # latest versions, so we need to explicitly pin them sphinxcontrib-applehelp==1.0.2 sphinxcontrib-htmlhelp==2.0.0 sphinx_rtd_theme myst_parser sphinx-intl pg_hint_plan-REL17_1_7_0/docs/requirements.md000066400000000000000000000007431466301071500212010ustar00rootroot00000000000000# Requirements pg_hint_plan 1.7 requires PostgreSQL 17. PostgreSQL versions tested - Version 17 OS versions tested - CentOS 8.5 See also -------- ## References - [EXPLAIN](http://www.postgresql.org/docs/current/static/sql-explain.html) - [SET](http://www.postgresql.org/docs/current/static/sql-set.html) - [Server Config](http://www.postgresql.org/docs/current/static/runtime-config.html) - [Parallel Plans](http://www.postgresql.org/docs/current/static/parallel-plans.html) pg_hint_plan-REL17_1_7_0/docs/requirements.txt000066400000000000000000000033241466301071500214160ustar00rootroot00000000000000# # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # # pip-compile --resolver=backtracking requirements.in # alabaster==0.7.13 # via sphinx babel==2.12.1 # via # sphinx # sphinx-intl certifi>=2024.07.04 # via requests charset-normalizer==3.0.1 # via requests click==8.1.3 # via sphinx-intl docutils==0.19 # via # myst-parser # sphinx idna==3.7 # via requests imagesize==1.4.1 # via sphinx importlib-metadata==7.1.0 # via sphinx jinja2==3.1.4 # via # myst-parser # sphinx markdown-it-py==2.2.0 # via # mdit-py-plugins # myst-parser markupsafe==2.1.2 # via jinja2 mdit-py-plugins==0.3.4 # via myst-parser mdurl==0.1.2 # via markdown-it-py myst-parser==0.19.0 # via -r requirements.in packaging==23.0 # via sphinx pygments==2.16.1 # via sphinx pyyaml==6.0 # via myst-parser requests>=2.32.0 # via sphinx snowballstemmer==2.2.0 # via sphinx sphinx==5.3.0 # via # -r requirements.in # myst-parser # sphinx-intl # sphinx-rtd-theme sphinx-intl==2.1.0 # via -r requirements.in sphinx-rtd-theme==0.5.1 # via -r requirements.in sphinxcontrib-applehelp==1.0.2 # via # -r requirements.in # sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==2.0.0 # via # -r requirements.in # sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx urllib3>=1.26.19 # via requests zipp>=3.19.1 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: # setuptools pg_hint_plan-REL17_1_7_0/docs/synopsis.md000066400000000000000000000010671466301071500203450ustar00rootroot00000000000000# Synopsis `pg_hint_plan` makes it possible to tweak PostgreSQL execution plans using "hints" in SQL comments, as of `/*+ SeqScan(a) */`. PostgreSQL uses a cost-based optimizer, which utilizes data statistics, not static rules. The planner (optimizer) estimates costs of each possible execution plans for a SQL statement then the execution plan with the lowest cost is executed. The planner does its best to select the best execution plan, but is not always perfect, since it doesn't take into account some of the data properties or correlations between columns. pg_hint_plan-REL17_1_7_0/docs/uninstallation.md000066400000000000000000000004401466301071500215140ustar00rootroot00000000000000# Uninstallation `make uninstall` in the top directory of source tree will uninstall the installed files if you installed from the source tree and it is left available. Setting the environment variable `PATH` may be necessary. $ cd pg_hint_plan-1.x.x $ su $ make uninstall pg_hint_plan-REL17_1_7_0/expected/000077500000000000000000000000001466301071500170015ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/expected/R_sample.out000066400000000000000000000006531466301071500213000ustar00rootroot00000000000000 QUERY PLAN --------------------------------------------------------------------------- Merge Join (cost=xxx rows=100 width=29) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx rows=1000 width=15) -> Sort (cost=xxx rows=100 width=14) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx rows=100 width=14) (6 rows) pg_hint_plan-REL17_1_7_0/expected/base_plan.out000066400000000000000000000044161466301071500214630ustar00rootroot00000000000000SET search_path TO public; -- query type 1 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) -- query type 2 EXPLAIN (COSTS false) SELECT * FROM t1, t4 WHERE t1.val < 10; QUERY PLAN ----------------------------------------- Nested Loop -> Bitmap Heap Scan on t1 Recheck Cond: (val < 10) -> Bitmap Index Scan on t1_val Index Cond: (val < 10) -> Materialize -> Seq Scan on t4 (7 rows) -- query type 3 EXPLAIN (COSTS false) SELECT * FROM t3, t4 WHERE t3.id = t4.id AND t4.ctid = '(1,1)'; QUERY PLAN --------------------------------------------- Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 Filter: (ctid = '(1,1)'::tid) (7 rows) -- query type 4 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)'; QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (5 rows) -- query type 5 EXPLAIN (COSTS false) SELECT * FROM t1, t3 WHERE t1.val = t3.val; QUERY PLAN -------------------------------- Hash Join Hash Cond: (t1.val = t3.val) -> Seq Scan on t1 -> Hash -> Seq Scan on t3 (5 rows) -- query type 6 EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 Index Cond: (id = t1.id) (12 rows) pg_hint_plan-REL17_1_7_0/expected/hint_table.out000066400000000000000000000010741466301071500216450ustar00rootroot00000000000000-- Tests for the hint table LOAD 'pg_hint_plan'; -- Attempting to use the hint table without the extension created -- emits a WARNING. SET pg_hint_plan.enable_hint_table TO on; SELECT 1; WARNING: cannot use the hint table HINT: Run "CREATE EXTENSION pg_hint_plan" to create the hint table. ?column? ---------- 1 (1 row) SET pg_hint_plan.enable_hint_table TO off; CREATE EXTENSION pg_hint_plan; SET pg_hint_plan.enable_hint_table TO on; SELECT 1; ?column? ---------- 1 (1 row) SET pg_hint_plan.enable_hint_table TO off; DROP EXTENSION pg_hint_plan; pg_hint_plan-REL17_1_7_0/expected/init.out000066400000000000000000000340101466301071500204730ustar00rootroot00000000000000SET search_path TO public; CREATE EXTENSION pg_hint_plan; CREATE SCHEMA s0; CREATE TABLE t1 (id int PRIMARY KEY, val int); CREATE TABLE t2 (id int PRIMARY KEY, val int); CREATE TABLE t3 (id int PRIMARY KEY, val int); CREATE TABLE t4 (id int PRIMARY KEY, val int); CREATE TABLE t5 (id int PRIMARY KEY, val int); CREATE TABLE p1 (id int PRIMARY KEY, val int); CREATE TABLE p1_c1 (LIKE p1 INCLUDING ALL, CHECK (id <= 100)) INHERITS(p1); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p1_c2 (LIKE p1 INCLUDING ALL, CHECK (id > 100 AND id <= 200)) INHERITS(p1); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p1_c3 (LIKE p1 INCLUDING ALL, CHECK (id > 200 AND id <= 300)) INHERITS(p1); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p1_c4 (LIKE p1 INCLUDING ALL, CHECK (id > 300)) INHERITS(p1); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p1_c1_c1 (LIKE p1 INCLUDING ALL, CHECK (id <= 50)) INHERITS(p1_c1); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p1_c1_c2 (LIKE p1 INCLUDING ALL, CHECK (id > 50 AND id <= 100)) INHERITS(p1_c1); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p1_c3_c1 (LIKE p1 INCLUDING ALL, CHECK (id > 200 AND id <= 250)) INHERITS(p1_c3); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p1_c3_c2 (LIKE p1 INCLUDING ALL, CHECK (id > 250 AND id <= 300)) INHERITS(p1_c3); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p2 (id int PRIMARY KEY, val text); CREATE INDEX p2_id_val_idx ON p2 (id, val); CREATE UNIQUE INDEX p2_val_idx ON p2 (val); CREATE INDEX p2_ununi_id_val_idx ON p2 (val); CREATE INDEX p2_val_idx_1 ON p2 USING hash (val); CREATE INDEX p2_val_id_idx ON p2 (val, id); CREATE INDEX p2_val_idx2 ON p2 (val COLLATE "C"); CREATE INDEX p2_val_idx3 ON p2 (val varchar_ops); CREATE INDEX p2_val_idx4 ON p2 (val DESC NULLS LAST); CREATE INDEX p2_val_idx5 ON p2 (val NULLS FIRST); CREATE INDEX p2_expr ON p2 ((val < '120')); CREATE INDEX p2_expr2 ON p2 ((id * 2 < 120)); CREATE INDEX p2_val_idx6 ON p2 (val) WHERE val >= '50' AND val < '51'; CREATE INDEX p2_val_idx7 ON p2 (val) WHERE id < 120; CREATE TABLE p2_c1 (LIKE p2 INCLUDING ALL, CHECK (id <= 100)) INHERITS(p2); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p2_c2 (LIKE p2 INCLUDING ALL, CHECK (id > 100 AND id <= 200)) INHERITS(p2); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p2_c3 (LIKE p2 INCLUDING ALL, CHECK (id > 200 AND id <= 300)) INHERITS(p2); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p2_c4 (LIKE p2 INCLUDING ALL, CHECK (id > 300)) INHERITS(p2); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p2_c1_c1 (LIKE p2 INCLUDING ALL, CHECK (id <= 50)) INHERITS(p2_c1); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p2_c1_c2 (LIKE p2 INCLUDING ALL, CHECK (id > 50 AND id <= 100)) INHERITS(p2_c1); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p2_c3_c1 (LIKE p2 INCLUDING ALL, CHECK (id > 200 AND id <= 250)) INHERITS(p2_c3); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE p2_c3_c2 (LIKE p2 INCLUDING ALL, CHECK (id > 250 AND id <= 300)) INHERITS(p2_c3); NOTICE: merging column "id" with inherited definition NOTICE: merging column "val" with inherited definition CREATE TABLE s0.t1 (id int PRIMARY KEY, val int); INSERT INTO t1 SELECT i, i % 100 FROM (SELECT generate_series(1, 10000) i) t; INSERT INTO t2 SELECT i, i % 10 FROM (SELECT generate_series(1, 1000) i) t; INSERT INTO t3 SELECT i, i FROM (SELECT generate_series(1, 100) i) t; INSERT INTO t4 SELECT i, i FROM (SELECT generate_series(1, 10) i) t; INSERT INTO t5 SELECT i, i % 100 FROM (SELECT generate_series(1, 10000) i) t; INSERT INTO p1_c1_c1 SELECT i, i % 100 FROM (SELECT generate_series(1, 50) i) t; INSERT INTO p1_c1_c2 SELECT i, i % 100 FROM (SELECT generate_series(51, 100) i) t; INSERT INTO p1_c2 SELECT i, i % 100 FROM (SELECT generate_series(101, 200) i) t; INSERT INTO p1_c3_c1 SELECT i, i % 100 FROM (SELECT generate_series(201, 250) i) t; INSERT INTO p1_c3_c2 SELECT i, i % 100 FROM (SELECT generate_series(251, 300) i) t; INSERT INTO p1_c4 SELECT i, i % 100 FROM (SELECT generate_series(301, 400) i) t; INSERT INTO p2_c1_c1 SELECT i, i % 100 FROM (SELECT generate_series(1, 50) i) t; INSERT INTO p2_c1_c2 SELECT i, i % 100 FROM (SELECT generate_series(51, 100) i) t; INSERT INTO p2_c2 SELECT i, i % 100 FROM (SELECT generate_series(101, 200) i) t; INSERT INTO p2_c3_c1 SELECT i, i % 100 FROM (SELECT generate_series(201, 250) i) t; INSERT INTO p2_c3_c2 SELECT i, i % 100 FROM (SELECT generate_series(251, 300) i) t; INSERT INTO p2_c4 SELECT i, i % 100 FROM (SELECT generate_series(301, 400) i) t; CREATE INDEX t1_val ON t1 (val); CREATE INDEX t2_val ON t2 (val); CREATE INDEX t5_id1 ON t5 (id); CREATE INDEX t5_id2 ON t5 (id); CREATE INDEX t5_id3 ON t5 (id); CREATE INDEX t5_val ON t5 (val); DROP INDEX p2_c4_val_id_idx; CREATE INDEX p2_id2_val ON p2 (id, id, val); CREATE INDEX p2_c1_id2_val ON p2_c1 (id, id, val); CREATE INDEX p2_c2_id2_val ON p2_c2 (id, id, val); CREATE INDEX p2_val2_id ON p2 (val, id, val); CREATE INDEX t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ON t5 (id); CREATE INDEX p1_val1 ON p1 (val); CREATE INDEX p1_val2 ON p1 (val); CREATE INDEX p1_val3 ON p1 (val); CREATE INDEX p1_c1_val1 ON p1_c1 (val); CREATE INDEX p1_c1_val2 ON p1_c1 (val); CREATE INDEX p1_c1_val3 ON p1_c1 (val); CREATE INDEX p1_c1_c1_val1 ON p1_c1_c1 (val); CREATE INDEX p1_c1_c1_val2 ON p1_c1_c1 (val); CREATE INDEX p1_c1_c1_val3 ON p1_c1_c1 (val); CREATE INDEX p1_c1_c2_val1 ON p1_c1_c2 (val); CREATE INDEX p1_c1_c2_val2 ON p1_c1_c2 (val); CREATE INDEX p1_c1_c2_val3 ON p1_c1_c2 (val); CREATE INDEX p1_c2_val1 ON p1_c2 (val); CREATE INDEX p1_c2_val2 ON p1_c2 (val); CREATE INDEX p1_c2_val3 ON p1_c2 (val); CREATE INDEX p1_c3_val1 ON p1_c3 (val); CREATE INDEX p1_c3_val2 ON p1_c3 (val); CREATE INDEX p1_c3_val3 ON p1_c3 (val); CREATE INDEX p1_c3_c1_val1 ON p1_c3_c1 (val); CREATE INDEX p1_c3_c1_val2 ON p1_c3_c1 (val); CREATE INDEX p1_c3_c1_val3 ON p1_c3_c1 (val); CREATE INDEX p1_c3_c2_val1 ON p1_c3_c2 (val); CREATE INDEX p1_c3_c2_val2 ON p1_c3_c2 (val); CREATE INDEX p1_c3_c2_val3 ON p1_c3_c2 (val); CREATE INDEX p1_c4_val1 ON p1_c4 (val); CREATE INDEX p1_c4_val2 ON p1_c4 (val); CREATE INDEX p1_c4_val3 ON p1_c4 (val); ANALYZE t1; ANALYZE t2; ANALYZE t3; ANALYZE t4; ANALYZE t5; ANALYZE p1; ANALYZE p1_c1; ANALYZE p1_c2; ANALYZE p2; CREATE VIEW v1 AS SELECT id, val FROM t1; CREATE VIEW v2 AS SELECT t1.id t1_id, t1.val t1_val, t2.id t2_id, t2.val t2_val FROM t1, t2 WHERE t1.id = t2.id; CREATE VIEW v3 AS SELECT t_1.id t1_id, t_1.val t1_val, t_2.id t2_id, t_2.val t2_val FROM t1 t_1, t2 t_2 WHERE t_1.id = t_2.id; CREATE VIEW v4 AS SELECT v_2.t1_id, t_3.id FROM v2 v_2, t3 t_3 WHERE v_2.t1_id = t_3.id; /* * Utility function to retrieve a query ID from a query. * * This wraps the input query within an EXPLAIN (VERBOSE, FORMAT json) and * returns its query ID. */ CREATE FUNCTION get_query_id(text) RETURNS bigint LANGUAGE plpgsql AS $$ DECLARE query text; explain_output text; query_id bigint; BEGIN query = 'EXPLAIN (VERBOSE, FORMAT json) ' || $1; EXECUTE query INTO explain_output; SELECT INTO query_id ((explain_output::jsonb)->0->'Query Identifier')::bigint; return query_id; END; $$; /* * The following GUC parameters need the setting of the default value to * succeed in regression test. */ SELECT current_database() AS datname \gset /* Fix auto-tunable parameters */ ALTER DATABASE :"datname" SET effective_cache_size TO 16384; SET effective_cache_size TO 16384; CREATE VIEW settings AS SELECT name, setting, category FROM pg_settings WHERE category LIKE 'Query Tuning%' OR name = 'client_min_messages' ORDER BY category, name; SELECT * FROM settings; name | setting | category --------------------------------+-----------+------------------------------------------------- client_min_messages | notice | Client Connection Defaults / Statement Behavior geqo | on | Query Tuning / Genetic Query Optimizer geqo_effort | 5 | Query Tuning / Genetic Query Optimizer geqo_generations | 0 | Query Tuning / Genetic Query Optimizer geqo_pool_size | 0 | Query Tuning / Genetic Query Optimizer geqo_seed | 0 | Query Tuning / Genetic Query Optimizer geqo_selection_bias | 2 | Query Tuning / Genetic Query Optimizer geqo_threshold | 12 | Query Tuning / Genetic Query Optimizer constraint_exclusion | partition | Query Tuning / Other Planner Options cursor_tuple_fraction | 0.1 | Query Tuning / Other Planner Options default_statistics_target | 100 | Query Tuning / Other Planner Options from_collapse_limit | 8 | Query Tuning / Other Planner Options jit | on | Query Tuning / Other Planner Options join_collapse_limit | 8 | Query Tuning / Other Planner Options plan_cache_mode | auto | Query Tuning / Other Planner Options recursive_worktable_factor | 10 | Query Tuning / Other Planner Options cpu_index_tuple_cost | 0.005 | Query Tuning / Planner Cost Constants cpu_operator_cost | 0.0025 | Query Tuning / Planner Cost Constants cpu_tuple_cost | 0.01 | Query Tuning / Planner Cost Constants effective_cache_size | 16384 | Query Tuning / Planner Cost Constants jit_above_cost | 100000 | Query Tuning / Planner Cost Constants jit_inline_above_cost | 500000 | Query Tuning / Planner Cost Constants jit_optimize_above_cost | 500000 | Query Tuning / Planner Cost Constants min_parallel_index_scan_size | 64 | Query Tuning / Planner Cost Constants min_parallel_table_scan_size | 1024 | Query Tuning / Planner Cost Constants parallel_setup_cost | 1000 | Query Tuning / Planner Cost Constants parallel_tuple_cost | 0.1 | Query Tuning / Planner Cost Constants random_page_cost | 4 | Query Tuning / Planner Cost Constants seq_page_cost | 1 | Query Tuning / Planner Cost Constants enable_async_append | on | Query Tuning / Planner Method Configuration enable_bitmapscan | on | Query Tuning / Planner Method Configuration enable_gathermerge | on | Query Tuning / Planner Method Configuration enable_group_by_reordering | on | Query Tuning / Planner Method Configuration enable_hashagg | on | Query Tuning / Planner Method Configuration enable_hashjoin | on | Query Tuning / Planner Method Configuration enable_incremental_sort | on | Query Tuning / Planner Method Configuration enable_indexonlyscan | on | Query Tuning / Planner Method Configuration enable_indexscan | on | Query Tuning / Planner Method Configuration enable_material | on | Query Tuning / Planner Method Configuration enable_memoize | on | Query Tuning / Planner Method Configuration enable_mergejoin | on | Query Tuning / Planner Method Configuration enable_nestloop | on | Query Tuning / Planner Method Configuration enable_parallel_append | on | Query Tuning / Planner Method Configuration enable_parallel_hash | on | Query Tuning / Planner Method Configuration enable_partition_pruning | on | Query Tuning / Planner Method Configuration enable_partitionwise_aggregate | off | Query Tuning / Planner Method Configuration enable_partitionwise_join | off | Query Tuning / Planner Method Configuration enable_presorted_aggregate | on | Query Tuning / Planner Method Configuration enable_seqscan | on | Query Tuning / Planner Method Configuration enable_sort | on | Query Tuning / Planner Method Configuration enable_tidscan | on | Query Tuning / Planner Method Configuration (51 rows) -- EXPLAIN filtering -- -- A lot of tests rely on EXPLAIN being executed with costs enabled -- to check the validity of the plans generated with hints. -- -- This function takes in input a query, executes it and applies some -- filtering to ensure a stable output. See the tests calling this -- function to see how it can be used. -- -- If required, this can be extended with new operation modes. CREATE OR REPLACE FUNCTION explain_filter(text) RETURNS SETOF text LANGUAGE plpgsql AS $$ DECLARE ln text; BEGIN FOR ln IN EXECUTE $1 LOOP -- Replace cost values with some 'xxx' ln := regexp_replace(ln, 'cost=10{7}[.0-9]+ ', 'cost={inf}..{inf} '); ln := regexp_replace(ln, 'cost=[.0-9]+ ', 'cost=xxx..xxx '); -- Replace width with some 'xxx' ln := regexp_replace(ln, 'width=[0-9]+([^0-9])', 'width=xxx\1'); -- Filter foreign files ln := regexp_replace(ln, '^( +Foreign File: ).*$', '\1 (snip..)'); return next ln; END LOOP; END; $$; ANALYZE; pg_hint_plan-REL17_1_7_0/expected/oldextversions.out000066400000000000000000000147011466301071500226250ustar00rootroot00000000000000-- -- tests for upgrade paths -- CREATE EXTENSION pg_hint_plan VERSION "1.3.0"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.1"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.2"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.3"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.4"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.5"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.6"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.7"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.8"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.9"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.10"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.4"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.4.1"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.4.2"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.4.3"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.5"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.5.1"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.5.2"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.6.0"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.6.1"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) ALTER EXTENSION pg_hint_plan UPDATE TO "1.7.0"; \dx+ pg_hint_plan Objects in extension "pg_hint_plan" Object description --------------------------------- sequence hint_plan.hints_id_seq table hint_plan.hints type hint_plan.hints type hint_plan.hints[] (4 rows) \d hint_plan.hints Table "hint_plan.hints" Column | Type | Collation | Nullable | Default ------------------+---------+-----------+----------+---------------------------------- id | integer | | not null | generated by default as identity query_id | bigint | | not null | application_name | text | | not null | hints | text | | not null | Indexes: "hints_pkey" PRIMARY KEY, btree (id) "hints_id_and_app" UNIQUE, btree (query_id, application_name) DROP EXTENSION pg_hint_plan; pg_hint_plan-REL17_1_7_0/expected/pg_hint_plan.out000066400000000000000000011416221466301071500222030ustar00rootroot00000000000000SET search_path TO public; SET client_min_messages TO log; \set SHOW_CONTEXT always EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.val = t2.val; QUERY PLAN ------------------------------------------- Nested Loop -> Seq Scan on t2 -> Memoize Cache Key: t2.val Cache Mode: logical -> Index Scan using t1_val on t1 Index Cond: (val = t2.val) (7 rows) LOAD 'pg_hint_plan'; SET pg_hint_plan.debug_print TO on; SELECT setting <> 'off' FROM pg_settings WHERE name = 'compute_query_id'; ?column? ---------- t (1 row) SHOW pg_hint_plan.enable_hint_table; pg_hint_plan.enable_hint_table -------------------------------- off (1 row) /* query-id related test */ SET compute_query_id to off; SET pg_hint_plan.enable_hint_table to on; -- error ERROR: table hint is not activated because queryid is not available HINT: Set compute_query_id to on or auto to use hint table. SET compute_query_id to on; SET pg_hint_plan.enable_hint_table to on; SET compute_query_id to off; SELECT 1; -- gets warning WARNING: hint table feature is deactivated because queryid is not available HINT: Set compute_query_id to "auto" or "on" to use hint table. ?column? ---------- 1 (1 row) SELECT 1; -- not ?column? ---------- 1 (1 row) SET compute_query_id to on; SELECT 1; -- reactivated LOG: hint table feature is reactivated ?column? ---------- 1 (1 row) SET compute_query_id to off; SELECT 1; -- gets warning WARNING: hint table feature is deactivated because queryid is not available HINT: Set compute_query_id to "auto" or "on" to use hint table. ?column? ---------- 1 (1 row) SET pg_hint_plan.enable_hint_table to off; SET compute_query_id to on; SET pg_hint_plan.enable_hint_table to on; SELECT 1; -- no warning ?column? ---------- 1 (1 row) RESET compute_query_id; RESET pg_hint_plan.enable_hint_table; EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.val = t2.val; QUERY PLAN ------------------------------------------- Nested Loop -> Seq Scan on t2 -> Memoize Cache Key: t2.val Cache Mode: logical -> Index Scan using t1_val on t1 Index Cond: (val = t2.val) (7 rows) /*+ Test (t1 t2) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; INFO: pg_hint_plan: hint syntax error at or near " Test (t1 t2) " DETAIL: Unrecognized hint keyword "Test". QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) SET pg_hint_plan.enable_hint TO off; /*+ Test (t1 t2) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) SET pg_hint_plan.enable_hint TO on; /*Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) --+Set(enable_indexscan off) EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) /*+Set(enable_indexscan off) /* nest comment */ */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; INFO: pg_hint_plan: hint syntax error at or near "/*" DETAIL: Nested block comments are not supported. LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) EXPLAIN (COSTS false) /*+Set(enable_indexscan off)*/ SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+ Set(enable_indexscan off) Set(enable_hashjoin off) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: Set(enable_hashjoin off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Sort Sort Key: t1.id -> Seq Scan on t1 -> Sort Sort Key: t2.id -> Seq Scan on t2 (8 rows) /*+ Set ( enable_indexscan off ) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+ Set ( enable_indexscan off ) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+ Set(enable_indexscan off)Set(enable_nestloop off)Set(enable_mergejoin off) Set(enable_seqscan off) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: Set(enable_indexscan off) Set(enable_mergejoin off) Set(enable_nestloop off) Set(enable_seqscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Hash -> Index Scan using t2_pkey on t2 (5 rows) /*+Set(work_mem "1M")*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; INFO: invalid value for parameter "work_mem": "1M" HINT: Valid units for this parameter are "B", "kB", "MB", "GB", and "TB". LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(work_mem 1M) QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) /*+Set(work_mem "1MB")*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: Set(work_mem 1MB) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) /*+Set(work_mem TO "1MB")*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; INFO: pg_hint_plan: hint syntax error at or near "Set(work_mem TO "1MB")" DETAIL: Set hint requires name and value of GUC parameter. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(work_mem TO 1MB) QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) /*+SeqScan() */ SELECT 1; INFO: pg_hint_plan: hint syntax error at or near " " DETAIL: SeqScan hint requires a relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan() ?column? ---------- 1 (1 row) /*+SeqScan(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan(t1 t2) QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+SeqScan(t1)IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: SeqScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Index Scan using t2_pkey on t2 (5 rows) /*+BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Seq Scan on t1 -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (6 rows) /*+BitmapScan(t2)NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: NoSeqScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Index Scan using t1_pkey on t1 -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (6 rows) /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: NoIndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t4 WHERE t1.val < 10; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------- Nested Loop -> Seq Scan on t1 Filter: (val < 10) -> Materialize -> Seq Scan on t4 (5 rows) /*+TidScan(t4)*/ EXPLAIN (COSTS false) SELECT * FROM t3, t4 WHERE t3.id = t4.id AND t4.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t4) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------- Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Sort Sort Key: t4.id -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (7 rows) /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (5 rows) /*+ NestLoop() */ SELECT 1; INFO: pg_hint_plan: hint syntax error at or near " " DETAIL: NestLoop hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NestLoop() ?column? ---------- 1 (1 row) /*+ NestLoop(x) */ SELECT 1; INFO: pg_hint_plan: hint syntax error at or near " " DETAIL: NestLoop hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NestLoop(x) ?column? ---------- 1 (1 row) /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------- Nested Loop -> Seq Scan on t2 -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) (4 rows) /*+NoMergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: NoMergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+MergeJoin(t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t3 WHERE t1.val = t3.val; LOG: pg_hint_plan: used hint: MergeJoin(t1 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Merge Join Merge Cond: (t1.val = t3.val) -> Index Scan using t1_val on t1 -> Sort Sort Key: t3.val -> Seq Scan on t3 (6 rows) /*+NestLoop(t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t3 WHERE t1.val = t3.val; LOG: pg_hint_plan: used hint: NestLoop(t1 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Nested Loop -> Seq Scan on t3 -> Index Scan using t1_val on t1 Index Cond: (val = t3.val) (4 rows) /*+NoHashJoin(t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t3 WHERE t1.val = t3.val; LOG: pg_hint_plan: used hint: NoHashJoin(t1 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Nested Loop -> Seq Scan on t3 -> Index Scan using t1_val on t1 Index Cond: (val = t3.val) (4 rows) /*+MergeJoin(t4 t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2 t3 t4) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Merge Join Merge Cond: (t1.id = t3.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Materialize -> Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 (13 rows) /*+HashJoin(t3 t4 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; LOG: pg_hint_plan: used hint: HashJoin(t1 t2 t3 t4) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------- Hash Join Hash Cond: (t3.id = t1.id) -> Seq Scan on t3 -> Hash -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t4.id -> Seq Scan on t4 (13 rows) /*+NestLoop(t2 t3 t4 t1) IndexScan(t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; LOG: pg_hint_plan: used hint: IndexScan(t3) NestLoop(t1 t2 t3 t4) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 Index Cond: (id = t1.id) (12 rows) /*+NoNestLoop(t4 t1 t3 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; LOG: pg_hint_plan: used hint: NoNestLoop(t1 t2 t3 t4) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Merge Join Merge Cond: (t1.id = t3.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Materialize -> Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 (13 rows) /*+Leading( */ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Closing parenthesis is necessary. QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 Index Cond: (id = t1.id) (12 rows) /*+Leading( )*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; INFO: pg_hint_plan: hint syntax error at or near "Leading( )" DETAIL: Leading hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading() QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 Index Cond: (id = t1.id) (12 rows) /*+Leading( t3 )*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; INFO: pg_hint_plan: hint syntax error at or near "Leading( t3 )" DETAIL: Leading hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t3) QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 Index Cond: (id = t1.id) (12 rows) /*+Leading( t3 t4 )*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; LOG: pg_hint_plan: used hint: Leading(t3 t4) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Nested Loop -> Nested Loop -> Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t2_pkey on t2 Index Cond: (id = t3.id) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) (12 rows) /*+Leading(t3 t4 t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; LOG: pg_hint_plan: used hint: Leading(t3 t4 t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t3.id = t1.id) -> Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (12 rows) /*+Leading(t3 t4 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; LOG: pg_hint_plan: used hint: Leading(t3 t4 t1 t2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t3.id = t1.id) -> Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (12 rows) /*+Leading(t3 t4 t1 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; INFO: pg_hint_plan: hint syntax error at or near "Leading(t3 t4 t1 t2 t1)" DETAIL: Relation name "t1" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t3 t4 t1 t2 t1) QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 Index Cond: (id = t1.id) (12 rows) /*+Leading(t3 t4 t4)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; INFO: pg_hint_plan: hint syntax error at or near "Leading(t3 t4 t4)" DETAIL: Relation name "t4" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t3 t4 t4) QUERY PLAN -------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 Index Cond: (id = t1.id) (12 rows) EXPLAIN (COSTS false) SELECT * FROM t1, (VALUES(1,1),(2,2),(3,3)) AS t2(id,val) WHERE t1.id = t2.id; QUERY PLAN ----------------------------------------------- Nested Loop -> Values Scan on "*VALUES*" -> Index Scan using t1_pkey on t1 Index Cond: (id = "*VALUES*".column1) (4 rows) /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, (VALUES(1,1),(2,2),(3,3)) AS t2(id,val) WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: not used hint: HashJoin(t1 t2) duplication hint: error hint: QUERY PLAN ----------------------------------------------- Nested Loop -> Values Scan on "*VALUES*" -> Index Scan using t1_pkey on t1 Index Cond: (id = "*VALUES*".column1) (4 rows) /*+HashJoin(t1 *VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM t1, (VALUES(1,1),(2,2),(3,3)) AS t2(id,val) WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: HashJoin(*VALUES* t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------- Hash Join Hash Cond: (t1.id = "*VALUES*".column1) -> Seq Scan on t1 -> Hash -> Values Scan on "*VALUES*" (5 rows) /*+HashJoin(t1 *VALUES*) IndexScan(t1) IndexScan(*VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM t1, (VALUES(1,1),(2,2),(3,3)) AS t2(id,val) WHERE t1.id = t2.id; LOG: pg_hint_plan: used hint: IndexScan(t1) HashJoin(*VALUES* t1) not used hint: IndexScan(*VALUES*) duplication hint: error hint: QUERY PLAN ------------------------------------------- Hash Join Hash Cond: (t1.id = "*VALUES*".column1) -> Index Scan using t1_pkey on t1 -> Hash -> Values Scan on "*VALUES*" (5 rows) -- single table scan hint test EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); QUERY PLAN ------------------------------------------------------------------------ Index Only Scan using t1_pkey on t1 Index Cond: (id = (InitPlan 4).col1) InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_1 Index Cond: (id < 10) InitPlan 4 -> Result InitPlan 3 -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_2 Index Cond: (id < 10) (14 rows) /*+BitmapScan(v_1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); LOG: pg_hint_plan: used hint: BitmapScan(v_1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------ Index Only Scan using t1_pkey on t1 Index Cond: (id = (InitPlan 3).col1) InitPlan 1 -> Aggregate -> Bitmap Heap Scan on t1 v_1 Recheck Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) InitPlan 3 -> Result InitPlan 2 -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_2 Index Cond: (id < 10) (14 rows) /*+BitmapScan(v_2)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); LOG: pg_hint_plan: used hint: BitmapScan(v_2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------ Index Only Scan using t1_pkey on t1 Index Cond: (id = (InitPlan 3).col1) InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_1 Index Cond: (id < 10) InitPlan 3 -> Aggregate -> Bitmap Heap Scan on t1 v_2 Recheck Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) (14 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------ Bitmap Heap Scan on t1 Recheck Cond: (id = (InitPlan 4).col1) InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_1 Index Cond: (id < 10) InitPlan 4 -> Result InitPlan 3 -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_2 Index Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id = (InitPlan 4).col1) (16 rows) /*+BitmapScan(v_1)BitmapScan(v_2)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); LOG: pg_hint_plan: used hint: BitmapScan(v_1) BitmapScan(v_2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Index Only Scan using t1_pkey on t1 Index Cond: (id = (InitPlan 2).col1) InitPlan 1 -> Aggregate -> Bitmap Heap Scan on t1 v_1 Recheck Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) InitPlan 2 -> Aggregate -> Bitmap Heap Scan on t1 v_2 Recheck Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) (14 rows) /*+BitmapScan(v_1)BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); LOG: pg_hint_plan: used hint: BitmapScan(t1) BitmapScan(v_1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------ Bitmap Heap Scan on t1 Recheck Cond: (id = (InitPlan 3).col1) InitPlan 1 -> Aggregate -> Bitmap Heap Scan on t1 v_1 Recheck Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) InitPlan 3 -> Result InitPlan 2 -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_2 Index Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id = (InitPlan 3).col1) (16 rows) /*+BitmapScan(v_2)BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); LOG: pg_hint_plan: used hint: BitmapScan(t1) BitmapScan(v_2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------ Bitmap Heap Scan on t1 Recheck Cond: (id = (InitPlan 3).col1) InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_1 Index Cond: (id < 10) InitPlan 3 -> Aggregate -> Bitmap Heap Scan on t1 v_2 Recheck Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id = (InitPlan 3).col1) (16 rows) /*+BitmapScan(v_1)BitmapScan(v_2)BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); LOG: pg_hint_plan: used hint: BitmapScan(t1) BitmapScan(v_1) BitmapScan(v_2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (id = (InitPlan 2).col1) InitPlan 1 -> Aggregate -> Bitmap Heap Scan on t1 v_1 Recheck Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) InitPlan 2 -> Aggregate -> Bitmap Heap Scan on t1 v_2 Recheck Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) -> Bitmap Index Scan on t1_pkey Index Cond: (id = (InitPlan 2).col1) (16 rows) -- full scan hint pattern test EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (id < 10) (3 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Seq Scan on t1 Filter: ((id < 10) AND (ctid = '(1,1)'::tid)) (2 rows) /*+IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Index Scan using t1_pkey on t1 Index Cond: (id < 10) Filter: (ctid = '(1,1)'::tid) (3 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Bitmap Heap Scan on t1 Recheck Cond: (id < 10) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id < 10) (5 rows) /*+TidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (id < 10) (3 rows) /*+NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (id < 10) (3 rows) /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (id < 10) (3 rows) /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (id < 10) (3 rows) /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Index Scan using t1_pkey on t1 Index Cond: (id < 10) Filter: (ctid = '(1,1)'::tid) (3 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+SeqScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+SeqScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop -> Index Scan using t2_pkey on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Index Scan using t1_pkey on t1 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+IndexScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+IndexScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(t1) NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+BitmapScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+BitmapScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Index Scan using t2_pkey on t2 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+BitmapScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Index Scan using t2_pkey on t2 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+BitmapScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+BitmapScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+BitmapScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+BitmapScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+BitmapScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(t1) NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 Recheck Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (id = t2.id) (8 rows) /*+TidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+TidScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) (6 rows) /*+TidScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+TidScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+TidScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+TidScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+TidScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+TidScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+TidScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+NoSeqScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoSeqScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(t1) NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+NoIndexScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoIndexScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(t1) NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+NoBitmapScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (6 rows) /*+NoBitmapScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) SeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) IndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop -> Index Scan using t2_pkey on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.id = id) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id = t1.id) (8 rows) /*+NoTidScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) TidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) NoSeqScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) NoIndexScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) NoBitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) /*+NoTidScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) NoTidScan(t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Nested Loop -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id = t2.id) Filter: (ctid = '(1,1)'::tid) (6 rows) -- additional test EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)' AND t1.id < 10 AND t2.id < 10; QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (id < 10) -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) Filter: (id < 10) (8 rows) /*+BitmapScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)' AND t1.id < 10 AND t2.id < 10; LOG: pg_hint_plan: used hint: BitmapScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------- Nested Loop -> Bitmap Heap Scan on t2 Recheck Cond: (id < 10) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (id < 10) -> Bitmap Heap Scan on t1 Recheck Cond: ((id = t2.id) AND (id < 10)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: ((id = t2.id) AND (id < 10)) (11 rows) -- outer join test EXPLAIN (COSTS false) SELECT * FROM t1 FULL OUTER JOIN t2 ON (t1.id = t2.id); QUERY PLAN ------------------------------ Hash Full Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1 FULL OUTER JOIN t2 ON (t1.id = t2.id); LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------- Merge Full Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) -- Cannot work /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1 FULL OUTER JOIN t2 ON (t1.id = t2.id); LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Full Join Hash Cond: (t1.id = t2.id) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- inheritance tables test SET constraint_exclusion TO off; EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------------- Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c2 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c4 p1_5 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_6 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_7 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c1 p1_8 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c2 p1_9 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (19 rows) SET constraint_exclusion TO on; EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------------- Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (9 rows) SET constraint_exclusion TO off; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c2 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c4 p1_5 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_6 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_7 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c1 p1_8 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c2 p1_9 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (19 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p1_pkey on p1 p1_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_pkey on p1_c1 p1_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c2_pkey on p1_c2 p1_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c3_pkey on p1_c3 p1_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c4_pkey on p1_c4 p1_5 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1_6 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1_7 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c3_c1_pkey on p1_c3_c1 p1_8 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c3_c2_pkey on p1_c3_c2 p1_9 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (28 rows) /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Bitmap Heap Scan on p1 p1_1 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1 p1_2 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c2 p1_3 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c2_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c3 p1_4 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c3_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c4 p1_5 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c4_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1_c1 p1_6 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1_c2 p1_7 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_c2_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c3_c1 p1_8 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c3_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c3_c2 p1_9 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c3_c2_pkey Index Cond: ((id >= 50) AND (id <= 51)) (46 rows) /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(p1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Append -> Tid Scan on p1 p1_1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1 p1_2 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c2 p1_3 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c3 p1_4 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c4 p1_5 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1_c1 p1_6 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1_c2 p1_7 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c3_c1 p1_8 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c3_c2 p1_9 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) (28 rows) SET constraint_exclusion TO on; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (9 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p1_pkey on p1 p1_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_pkey on p1_c1 p1_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Bitmap Heap Scan on p1 p1_1 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1 p1_2 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1_c1 p1_3 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1_c2 p1_4 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_c2_pkey Index Cond: ((id >= 50) AND (id <= 51)) (21 rows) /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(p1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Append -> Tid Scan on p1 p1_1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1 p1_2 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1_c1 p1_3 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1_c2 p1_4 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) (13 rows) SET constraint_exclusion TO off; EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; QUERY PLAN ----------------------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c2 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c4 p1_5 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_6 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_7 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c1 p1_8 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c2 p1_9 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (25 rows) SET constraint_exclusion TO on; EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; QUERY PLAN ----------------------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (15 rows) SET constraint_exclusion TO off; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: SeqScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c2 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c4 p1_5 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_6 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_7 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c1 p1_8 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c2 p1_9 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (25 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Merge Append Sort Key: p1.id -> Index Scan using p1_pkey on p1 p1_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_pkey on p1_c1 p1_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c2_pkey on p1_c2 p1_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c3_pkey on p1_c3 p1_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c4_pkey on p1_c4 p1_5 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1_6 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1_7 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c3_c1_pkey on p1_c3_c1 p1_8 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c3_c2_pkey on p1_c3_c2 p1_9 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (33 rows) /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: BitmapScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Bitmap Heap Scan on p1 p1_1 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1 p1_2 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c2 p1_3 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c2_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c3 p1_4 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c3_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c4 p1_5 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c4_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1_c1 p1_6 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1_c2 p1_7 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_c2_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c3_c1 p1_8 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c3_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c3_c2 p1_9 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c3_c2_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (52 rows) /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: TidScan(p1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Tid Scan on p1 p1_1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1 p1_2 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c2 p1_3 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c3 p1_4 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c4 p1_5 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1_c1 p1_6 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1_c2 p1_7 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c3_c1 p1_8 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c3_c2 p1_9 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (34 rows) /*+NestLoop(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: NestLoop(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c2 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c4 p1_5 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_6 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_7 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c1 p1_8 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c2 p1_9 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Materialize -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (24 rows) /*+MergeJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: MergeJoin(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c2 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c4 p1_5 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_6 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_7 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c1 p1_8 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c2 p1_9 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (25 rows) /*+HashJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: HashJoin(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Hash Join Hash Cond: (p1.id = t1.id) -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c2 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c4 p1_5 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_6 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_7 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c1 p1_8 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c3_c2 p1_9 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (24 rows) SET constraint_exclusion TO on; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: SeqScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (15 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Merge Append Sort Key: p1.id -> Index Scan using p1_pkey on p1 p1_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_pkey on p1_c1 p1_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (18 rows) /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: BitmapScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Bitmap Heap Scan on p1 p1_1 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1 p1_2 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1_c1 p1_3 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_c1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Bitmap Heap Scan on p1_c1_c2 p1_4 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_c1_c2_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (27 rows) /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: TidScan(p1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Tid Scan on p1 p1_1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1 p1_2 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1_c1 p1_3 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Tid Scan on p1_c1_c2 p1_4 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (19 rows) /*+NestLoop(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: NestLoop(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Materialize -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (14 rows) /*+MergeJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: MergeJoin(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (15 rows) /*+HashJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: HashJoin(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------- Hash Join Hash Cond: (t1.id = p1.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Append -> Seq Scan on p1 p1_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1 p1_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c1 p1_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p1_c1_c2 p1_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (14 rows) SET constraint_exclusion TO off; EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (2 rows) SET constraint_exclusion TO on; EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (2 rows) SET constraint_exclusion TO off; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (2 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------- Index Scan using p1_pkey on p1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (3 rows) /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Bitmap Heap Scan on p1 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_pkey Index Cond: ((id >= 50) AND (id <= 51)) (5 rows) /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(p1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Tid Scan on p1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) (3 rows) /*+NestLoop(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: NestLoop(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (6 rows) /*+MergeJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: MergeJoin(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (8 rows) /*+HashJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: HashJoin(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Hash Join Hash Cond: (t1.id = p1.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (7 rows) SET constraint_exclusion TO on; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (2 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------- Index Scan using p1_pkey on p1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (3 rows) /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Bitmap Heap Scan on p1 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_pkey Index Cond: ((id >= 50) AND (id <= 51)) (5 rows) /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(p1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Tid Scan on p1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) (3 rows) /*+NestLoop(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: NestLoop(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (6 rows) /*+MergeJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: MergeJoin(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Sort Sort Key: p1.id -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (8 rows) /*+HashJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: HashJoin(p1 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Hash Join Hash Cond: (t1.id = p1.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (7 rows) SET constraint_exclusion TO off; EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; QUERY PLAN ----------------------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (6 rows) SET constraint_exclusion TO on; EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; QUERY PLAN ----------------------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (6 rows) SET constraint_exclusion TO off; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: SeqScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (6 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Index Scan using p1_pkey on p1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (7 rows) /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: BitmapScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Bitmap Heap Scan on p1 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (9 rows) /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: TidScan(p1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Tid Scan on p1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (7 rows) SET constraint_exclusion TO on; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: SeqScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Seq Scan on p1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (6 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Merge Join Merge Cond: (p1.id = t1.id) -> Index Scan using p1_pkey on p1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (7 rows) /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: BitmapScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Bitmap Heap Scan on p1 Recheck Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on p1_pkey Index Cond: ((id >= 50) AND (id <= 51)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (9 rows) /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; LOG: pg_hint_plan: used hint: TidScan(p1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Nested Loop Join Filter: (p1.id = t1.id) -> Tid Scan on p1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((id >= 50) AND (id <= 51)) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (7 rows) -- IndexScan is safe for unordered indexes CREATE TABLE ischk (a text, b tsvector) PARTITION BY LIST(a); CREATE TABLE ischk_d1 PARTITION OF ischk FOR VALUES IN (0); CREATE TABLE ischk_d2 PARTITION OF ischk FOR VALUES IN (1); CREATE INDEX ischk_idx ON ischk USING gin (b); /*+ IndexScan(ischk ischk_idx) */ EXPLAIN (COSTS false) SELECT * FROM ischk WHERE b = 'x'; LOG: available indexes for IndexScan(ischk_d1): ischk_d1_b_idx LOG: available indexes for IndexScan(ischk_d2): ischk_d2_b_idx LOG: pg_hint_plan: used hint: IndexScan(ischk ischk_idx) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Append -> Seq Scan on ischk_d1 ischk_1 Filter: (b = '''x'''::tsvector) -> Seq Scan on ischk_d2 ischk_2 Filter: (b = '''x'''::tsvector) (5 rows) DROP TABLE ischk; -- quote test /*+SeqScan("""t1 ) ")IndexScan("t 2 """)HashJoin("""t1 ) "T3"t 2 """)Leading("""t1 ) "T3"t 2 """)Set(application_name"a a a"" a A")*/ EXPLAIN (COSTS false) SELECT * FROM t1 """t1 ) ", t2 "t 2 """, t3 "T3" WHERE """t1 ) ".id = "t 2 """.id AND """t1 ) ".id = "T3".id; LOG: pg_hint_plan: used hint: SeqScan("""t1 ) ") IndexScan("t 2 """) HashJoin("""t1 ) " T3 "t 2 """) Leading("""t1 ) " T3 "t 2 """) Set(application_name "a a a"" a A") not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------- Hash Join Hash Cond: ("t 2 """.id = """t1 ) ".id) -> Index Scan using t2_pkey on t2 "t 2 """ -> Hash -> Hash Join Hash Cond: ("""t1 ) ".id = "T3".id) -> Seq Scan on t1 """t1 ) " -> Hash -> Seq Scan on t3 "T3" (9 rows) -- duplicate hint test /*+SeqScan(t1)SeqScan(t2)IndexScan(t1)IndexScan(t2)BitmapScan(t1)BitmapScan(t2)TidScan(t1)TidScan(t2)HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "SeqScan(t1)SeqScan(t2)IndexScan(t1)IndexScan(t2)BitmapScan(t1)BitmapScan(t2)TidScan(t1)TidScan(t2)HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "IndexScan(t1)IndexScan(t2)BitmapScan(t1)BitmapScan(t2)TidScan(t1)TidScan(t2)HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "BitmapScan(t1)BitmapScan(t2)TidScan(t1)TidScan(t2)HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "SeqScan(t2)IndexScan(t1)IndexScan(t2)BitmapScan(t1)BitmapScan(t2)TidScan(t1)TidScan(t2)HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "IndexScan(t2)BitmapScan(t1)BitmapScan(t2)TidScan(t1)TidScan(t2)HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "BitmapScan(t2)TidScan(t1)TidScan(t2)HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict join method hint. INFO: pg_hint_plan: hint syntax error at or near "NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict join method hint. INFO: pg_hint_plan: hint syntax error at or near "Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict set hint. INFO: pg_hint_plan: hint syntax error at or near "Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)" DETAIL: Conflict leading hint. LOG: pg_hint_plan: used hint: TidScan(t1) TidScan(t2) MergeJoin(t1 t2) Leading(t2 t1) Set(enable_mergejoin on) Set(enable_seqscan on) not used hint: duplication hint: SeqScan(t1) IndexScan(t1) BitmapScan(t1) SeqScan(t2) IndexScan(t2) BitmapScan(t2) HashJoin(t1 t2) NestLoop(t1 t2) Leading(t1 t2) Set(enable_seqscan off) error hint: QUERY PLAN ----------------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Sort Sort Key: t1.id -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: t2.id -> Tid Scan on t2 TID Cond: (ctid = '(1,1)'::tid) (10 rows) -- sub query Leading hint test SET from_collapse_limit TO 100; SET geqo_threshold TO 100; EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); QUERY PLAN ------------------------------------------------------------------------------ Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_2.id = t3_2.id) -> Merge Join Merge Cond: (t1_2.id = t2_2.id) -> Index Only Scan using t1_pkey on t1 t1_2 -> Index Only Scan using t2_pkey on t2 t2_2 -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t1_4.id = t3_4.id) -> Merge Join Merge Cond: (t1_4.id = t2_4.id) -> Index Only Scan using t1_pkey on t1 t1_4 -> Index Only Scan using t2_pkey on t2 t2_4 -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t1_5.id = t3_5.id) -> Merge Join Merge Cond: (t1_5.id = t2_5.id) -> Index Only Scan using t1_pkey on t1 t1_5 -> Index Only Scan using t2_pkey on t2 t2_5 -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 (51 rows) /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); LOG: pg_hint_plan: used hint: HashJoin(t1_1 t3_1) NestLoop(t1_2 t2_2) MergeJoin(t1_3 t3_3) NestLoop(t1_4 t2_4) NestLoop(t1_5 t2_5) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_2.id = t3_2.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_2 -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t1_4.id = t3_4.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_4 -> Index Only Scan using t1_pkey on t1 t1_4 Index Cond: (id = t2_4.id) -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t1_5.id = t3_5.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_5 -> Index Only Scan using t1_pkey on t1 t1_5 Index Cond: (id = t2_5.id) -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 (51 rows) /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(a t1_1 t1_2 t1_4 t1_5)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); LOG: pg_hint_plan: used hint: HashJoin(t1_1 t3_1) NestLoop(t1_2 t2_2) MergeJoin(t1_3 t3_3) NestLoop(t1_4 t2_4) NestLoop(t1_5 t2_5) not used hint: Leading(a t1_1 t1_2 t1_4 t1_5) duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_2.id = t3_2.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_2 -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t1_4.id = t3_4.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_4 -> Index Only Scan using t1_pkey on t1 t1_4 Index Cond: (id = t2_4.id) -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t1_5.id = t3_5.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_5 -> Index Only Scan using t1_pkey on t1 t1_5 Index Cond: (id = t2_5.id) -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 (51 rows) /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(a t3_2 t3_5 t2_2 c1_1 t3_4 t3_3 t2_3 t2_4 t1_3 t2_5 t1_2 t3_1 t1_4 t2_1 t1_5 t1_1)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); LOG: pg_hint_plan: used hint: HashJoin(t1_1 t3_1) NestLoop(t1_2 t2_2) MergeJoin(t1_3 t3_3) NestLoop(t1_4 t2_4) NestLoop(t1_5 t2_5) not used hint: Leading(a t3_2 t3_5 t2_2 c1_1 t3_4 t3_3 t2_3 t2_4 t1_3 t2_5 t1_2 t3_1 t1_4 t2_1 t1_5 t1_1) duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_2.id = t3_2.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_2 -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t1_4.id = t3_4.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_4 -> Index Only Scan using t1_pkey on t1 t1_4 Index Cond: (id = t2_4.id) -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t1_5.id = t3_5.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_5 -> Index Only Scan using t1_pkey on t1 t1_5 Index Cond: (id = t2_5.id) -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 (51 rows) /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(t3_5 t2_5 t1_5)Leading(t3_2 t2_2 t1_2)Leading(t3_4 t2_4 t1_4)Leading(c1_1 t3_3 t2_3 t1_3 t3_1 t2_1 t1_1)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); LOG: pg_hint_plan: used hint: Leading(t3_5 t2_5 t1_5) Leading(t3_2 t2_2 t1_2) Leading(t3_4 t2_4 t1_4) Leading(c1_1 t3_3 t2_3 t1_3 t3_1 t2_1 t1_1) not used hint: HashJoin(t1_1 t3_1) NestLoop(t1_2 t2_2) MergeJoin(t1_3 t3_3) NestLoop(t1_4 t2_4) NestLoop(t1_5 t2_5) duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------------------------ Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t2_2.id = t1_2.id) -> Merge Join Merge Cond: (t2_2.id = t3_2.id) -> Index Only Scan using t2_pkey on t2 t2_2 -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 -> Index Only Scan using t1_pkey on t1 t1_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t2_4.id = t1_4.id) -> Merge Join Merge Cond: (t2_4.id = t3_4.id) -> Index Only Scan using t2_pkey on t2 t2_4 -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Index Only Scan using t1_pkey on t1 t1_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t2_5.id = t1_5.id) -> Merge Join Merge Cond: (t2_5.id = t3_5.id) -> Index Only Scan using t2_pkey on t2 t2_5 -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 -> Index Only Scan using t1_pkey on t1 t1_5 -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) (51 rows) SET from_collapse_limit TO 1; EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); QUERY PLAN -------------------------------------------------------------------- Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_2.id = t3_2.id) -> Merge Join Merge Cond: (t1_2.id = t2_2.id) -> Index Only Scan using t1_pkey on t1 t1_2 -> Index Only Scan using t2_pkey on t2 t2_2 -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t1_4.id = t3_4.id) -> Merge Join Merge Cond: (t1_4.id = t2_4.id) -> Index Only Scan using t1_pkey on t1 t1_4 -> Index Only Scan using t2_pkey on t2 t2_4 -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t1_5.id = t3_5.id) -> Merge Join Merge Cond: (t1_5.id = t2_5.id) -> Index Only Scan using t1_pkey on t1 t1_5 -> Index Only Scan using t2_pkey on t2 t2_5 -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 (51 rows) /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); LOG: pg_hint_plan: used hint: HashJoin(t1_1 t3_1) NestLoop(t1_2 t2_2) MergeJoin(t1_3 t3_3) NestLoop(t1_4 t2_4) NestLoop(t1_5 t2_5) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------------------- Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_2.id = t3_2.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_2 -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t1_4.id = t3_4.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_4 -> Index Only Scan using t1_pkey on t1 t1_4 Index Cond: (id = t2_4.id) -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t1_5.id = t3_5.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_5 -> Index Only Scan using t1_pkey on t1 t1_5 Index Cond: (id = t2_5.id) -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 (51 rows) /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(a t1_1 t1_2 t1_4 t1_5)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); LOG: pg_hint_plan: used hint: HashJoin(t1_1 t3_1) NestLoop(t1_2 t2_2) MergeJoin(t1_3 t3_3) NestLoop(t1_4 t2_4) NestLoop(t1_5 t2_5) not used hint: Leading(a t1_1 t1_2 t1_4 t1_5) duplication hint: error hint: QUERY PLAN -------------------------------------------------------------------- Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_2.id = t3_2.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_2 -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t1_4.id = t3_4.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_4 -> Index Only Scan using t1_pkey on t1 t1_4 Index Cond: (id = t2_4.id) -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t1_5.id = t3_5.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_5 -> Index Only Scan using t1_pkey on t1 t1_5 Index Cond: (id = t2_5.id) -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 (51 rows) /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(a t3_2 t3_5 t2_2 c1_1 t3_4 t3_3 t2_3 t2_4 t1_3 t2_5 t1_2 t3_1 t1_4 t2_1 t1_5 t1_1)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); LOG: pg_hint_plan: used hint: HashJoin(t1_1 t3_1) NestLoop(t1_2 t2_2) MergeJoin(t1_3 t3_3) NestLoop(t1_4 t2_4) NestLoop(t1_5 t2_5) not used hint: Leading(a t3_2 t3_5 t2_2 c1_1 t3_4 t3_3 t2_3 t2_4 t1_3 t2_5 t1_2 t3_1 t1_4 t2_1 t1_5 t1_1) duplication hint: error hint: QUERY PLAN -------------------------------------------------------------------- Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_2.id = t3_2.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_2 -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t1_4.id = t3_4.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_4 -> Index Only Scan using t1_pkey on t1 t1_4 Index Cond: (id = t2_4.id) -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t1_5.id = t3_5.id) -> Nested Loop -> Index Only Scan using t2_pkey on t2 t2_5 -> Index Only Scan using t1_pkey on t1 t1_5 Index Cond: (id = t2_5.id) -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 (51 rows) /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(t3_5 t2_5 t1_5)Leading(t3_2 t2_2 t1_2)Leading(t3_4 t2_4 t1_4)Leading(c1_1 t3_3 t2_3 t1_3 t3_1 t2_1 t1_1)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); LOG: pg_hint_plan: used hint: MergeJoin(t1_3 t3_3) Leading(t3_5 t2_5 t1_5) Leading(t3_2 t2_2 t1_2) Leading(t3_4 t2_4 t1_4) Leading(c1_1 t3_3 t2_3 t1_3 t3_1 t2_1 t1_1) not used hint: HashJoin(t1_1 t3_1) NestLoop(t1_2 t2_2) NestLoop(t1_4 t2_4) NestLoop(t1_5 t2_5) duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------------ Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t2_2.id = t1_2.id) -> Merge Join Merge Cond: (t2_2.id = t3_2.id) -> Index Only Scan using t2_pkey on t2 t2_2 -> Sort Sort Key: t3_2.id -> Seq Scan on t3 t3_2 -> Index Only Scan using t1_pkey on t1 t1_2 InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (t2_4.id = t1_4.id) -> Merge Join Merge Cond: (t2_4.id = t3_4.id) -> Index Only Scan using t2_pkey on t2 t2_4 -> Sort Sort Key: t3_4.id -> Seq Scan on t3 t3_4 -> Index Only Scan using t1_pkey on t1 t1_4 -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = (InitPlan 2).col1) -> Seq Scan on t3 t3_3 Filter: (id = (InitPlan 2).col1) -> Aggregate Filter: (max(t1_5.id) = (InitPlan 2).col1) -> Merge Join Merge Cond: (t2_5.id = t1_5.id) -> Merge Join Merge Cond: (t2_5.id = t3_5.id) -> Index Only Scan using t2_pkey on t2 t2_5 -> Sort Sort Key: t3_5.id -> Seq Scan on t3 t3_5 -> Index Only Scan using t1_pkey on t1 t1_5 -> Seq Scan on t3 t3_1 Filter: (id = (InitPlan 2).col1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = (InitPlan 2).col1) -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = (InitPlan 2).col1) (51 rows) -- ambiguous error EXPLAIN (COSTS false) SELECT * FROM t1, s0.t1, t2 WHERE public.t1.id = s0.t1.id AND public.t1.id = t2.id; QUERY PLAN -------------------------------------------- Nested Loop -> Nested Loop -> Seq Scan on t1 t1_1 -> Index Scan using t1_pkey on t1 Index Cond: (id = t1_1.id) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (7 rows) /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, s0.t1, t2 WHERE public.t1.id = s0.t1.id AND public.t1.id = t2.id; INFO: pg_hint_plan: hint syntax error at or near "MergeJoin(t1 t2)" DETAIL: Relation name "t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: MergeJoin(t1 t2) QUERY PLAN -------------------------------------------- Nested Loop -> Nested Loop -> Seq Scan on t1 t1_1 -> Index Scan using t1_pkey on t1 Index Cond: (id = t1_1.id) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (7 rows) /*+Leading(t1 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, s0.t1, t2 WHERE public.t1.id = s0.t1.id AND public.t1.id = t2.id; INFO: pg_hint_plan: hint syntax error at or near "Leading(t1 t2 t1)" DETAIL: Relation name "t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t1 t2 t1) QUERY PLAN -------------------------------------------- Nested Loop -> Nested Loop -> Seq Scan on t1 t1_1 -> Index Scan using t1_pkey on t1 Index Cond: (id = t1_1.id) -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (7 rows) -- identifier length test EXPLAIN (COSTS false) SELECT * FROM t1 "123456789012345678901234567890123456789012345678901234567890123" JOIN t2 ON ("123456789012345678901234567890123456789012345678901234567890123".id = t2.id) JOIN t3 ON (t2.id = t3.id); QUERY PLAN -------------------------------------------------------------------------------------------------------------- Merge Join Merge Cond: ("123456789012345678901234567890123456789012345678901234567890123".id = t3.id) -> Merge Join Merge Cond: ("123456789012345678901234567890123456789012345678901234567890123".id = t2.id) -> Index Scan using t1_pkey on t1 "123456789012345678901234567890123456789012345678901234567890123" -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t3.id -> Seq Scan on t3 (9 rows) /*+ Leading(123456789012345678901234567890123456789012345678901234567890123 t2 t3) SeqScan(123456789012345678901234567890123456789012345678901234567890123) MergeJoin(123456789012345678901234567890123456789012345678901234567890123 t2) Set(123456789012345678901234567890123456789012345678901234567890123 1) */ EXPLAIN (COSTS false) SELECT * FROM t1 "123456789012345678901234567890123456789012345678901234567890123" JOIN t2 ON ("123456789012345678901234567890123456789012345678901234567890123".id = t2.id) JOIN t3 ON (t2.id = t3.id); INFO: unrecognized configuration parameter "123456789012345678901234567890123456789012345678901234567890123" LOG: pg_hint_plan: used hint: SeqScan(123456789012345678901234567890123456789012345678901234567890123) MergeJoin(123456789012345678901234567890123456789012345678901234567890123 t2) Leading(123456789012345678901234567890123456789012345678901234567890123 t2 t3) not used hint: duplication hint: error hint: Set(123456789012345678901234567890123456789012345678901234567890123 1) QUERY PLAN ---------------------------------------------------------------------------------------------------- Merge Join Merge Cond: ("123456789012345678901234567890123456789012345678901234567890123".id = t3.id) -> Merge Join Merge Cond: (t2.id = "123456789012345678901234567890123456789012345678901234567890123".id) -> Index Scan using t2_pkey on t2 -> Sort Sort Key: "123456789012345678901234567890123456789012345678901234567890123".id -> Seq Scan on t1 "123456789012345678901234567890123456789012345678901234567890123" -> Sort Sort Key: t3.id -> Seq Scan on t3 (11 rows) /*+ Leading(1234567890123456789012345678901234567890123456789012345678901234 t2 t3) SeqScan(1234567890123456789012345678901234567890123456789012345678901234) MergeJoin(1234567890123456789012345678901234567890123456789012345678901234 t2) Set(1234567890123456789012345678901234567890123456789012345678901234 1) Set(cursor_tuple_fraction 0.1234567890123456789012345678901234567890123456789012345678901234) */ EXPLAIN (COSTS false) SELECT * FROM t1 "1234567890123456789012345678901234567890123456789012345678901234" JOIN t2 ON ("1234567890123456789012345678901234567890123456789012345678901234".id = t2.id) JOIN t3 ON (t2.id = t3.id); NOTICE: identifier "1234567890123456789012345678901234567890123456789012345678901234" will be truncated to "123456789012345678901234567890123456789012345678901234567890123" NOTICE: identifier "1234567890123456789012345678901234567890123456789012345678901234" will be truncated to "123456789012345678901234567890123456789012345678901234567890123" NOTICE: identifier "1234567890123456789012345678901234567890123456789012345678901234" will be truncated to "123456789012345678901234567890123456789012345678901234567890123" NOTICE: identifier "1234567890123456789012345678901234567890123456789012345678901234" will be truncated to "123456789012345678901234567890123456789012345678901234567890123" NOTICE: identifier "1234567890123456789012345678901234567890123456789012345678901234" will be truncated to "123456789012345678901234567890123456789012345678901234567890123" NOTICE: identifier "1234567890123456789012345678901234567890123456789012345678901234" will be truncated to "123456789012345678901234567890123456789012345678901234567890123" INFO: unrecognized configuration parameter "123456789012345678901234567890123456789012345678901234567890123" LOG: pg_hint_plan: used hint: SeqScan(123456789012345678901234567890123456789012345678901234567890123) MergeJoin(123456789012345678901234567890123456789012345678901234567890123 t2) Leading(123456789012345678901234567890123456789012345678901234567890123 t2 t3) Set(cursor_tuple_fraction 0.1234567890123456789012345678901234567890123456789012345678901234) not used hint: duplication hint: error hint: Set(123456789012345678901234567890123456789012345678901234567890123 1) QUERY PLAN ---------------------------------------------------------------------------------------------------- Merge Join Merge Cond: ("123456789012345678901234567890123456789012345678901234567890123".id = t3.id) -> Merge Join Merge Cond: (t2.id = "123456789012345678901234567890123456789012345678901234567890123".id) -> Index Scan using t2_pkey on t2 -> Sort Sort Key: "123456789012345678901234567890123456789012345678901234567890123".id -> Seq Scan on t1 "123456789012345678901234567890123456789012345678901234567890123" -> Sort Sort Key: t3.id -> Seq Scan on t3 (11 rows) SET "123456789012345678901234567890123456789012345678901234567890123" TO 1; ERROR: unrecognized configuration parameter "123456789012345678901234567890123456789012345678901234567890123" SET "1234567890123456789012345678901234567890123456789012345678901234" TO 1; NOTICE: identifier "1234567890123456789012345678901234567890123456789012345678901234" will be truncated to "123456789012345678901234567890123456789012345678901234567890123" ERROR: unrecognized configuration parameter "123456789012345678901234567890123456789012345678901234567890123" SET cursor_tuple_fraction TO 1234567890123456789012345678901234567890123456789012345678901234; ERROR: 1.23457e+63 is outside the valid range for parameter "cursor_tuple_fraction" (0 .. 1) -- multi error /*+ Set(enable_seqscan 100)Set(seq_page_cost on)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; INFO: parameter "enable_seqscan" requires a Boolean value INFO: invalid value for parameter "seq_page_cost": "on" LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(enable_seqscan 100) Set(seq_page_cost on) QUERY PLAN -------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 (4 rows) -- debug log of candidate index to use IndexScan EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; QUERY PLAN ---------------------------------------------------------------------------------------- Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+IndexScan(t5 t5_id2)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; LOG: available indexes for IndexScan(t5): t5_id2 LOG: pg_hint_plan: used hint: IndexScan(t5 t5_id2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------- Index Scan using t5_id2 on t5 Index Cond: (id = 1) (2 rows) /*+IndexScan(t5 no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; LOG: available indexes for IndexScan(t5): LOG: pg_hint_plan: used hint: not used hint: IndexScan(t5 no_exist) duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------- Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+IndexScan(t5 t5_id1 t5_id2)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; LOG: available indexes for IndexScan(t5): t5_id2 t5_id1 LOG: pg_hint_plan: used hint: IndexScan(t5 t5_id1 t5_id2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------- Index Scan using t5_id2 on t5 Index Cond: (id = 1) (2 rows) /*+IndexScan(t5 no_exist t5_id2)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; LOG: available indexes for IndexScan(t5): t5_id2 LOG: pg_hint_plan: used hint: IndexScan(t5 no_exist t5_id2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------- Index Scan using t5_id2 on t5 Index Cond: (id = 1) (2 rows) /*+IndexScan(t5 no_exist5 no_exist2)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; LOG: available indexes for IndexScan(t5): LOG: pg_hint_plan: used hint: not used hint: IndexScan(t5 no_exist5 no_exist2) duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------- Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) -- outer inner EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; QUERY PLAN -------------------------------------------------------- Hash Join Hash Cond: (t3.val = t2.val) -> Seq Scan on t3 -> Hash -> Hash Join Hash Cond: (t2.id = t1.id) -> Seq Scan on t2 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (10 rows) /*+Leading((t1))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; INFO: pg_hint_plan: hint syntax error at or near "Leading((t1))" DETAIL: Leading hint requires two sets of relations when parentheses nests. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading((t1)) QUERY PLAN -------------------------------------------------------- Hash Join Hash Cond: (t3.val = t2.val) -> Seq Scan on t3 -> Hash -> Hash Join Hash Cond: (t2.id = t1.id) -> Seq Scan on t2 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (10 rows) /*+Leading((t1 t2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading((t1 t2)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t2.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 (9 rows) /*+Leading((t1 t2 t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; INFO: pg_hint_plan: hint syntax error at or near "Leading((t1 t2 t3))" DETAIL: Leading hint requires two sets of relations when parentheses nests. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading((t1 t2 t3)) QUERY PLAN -------------------------------------------------------- Hash Join Hash Cond: (t3.val = t2.val) -> Seq Scan on t3 -> Hash -> Hash Join Hash Cond: (t2.id = t1.id) -> Seq Scan on t2 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (10 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.id < 10; QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t2.id = t1.id) -> Seq Scan on t2 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (6 rows) /*+Leading((t1 t2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading((t1 t2)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------- Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 (6 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; QUERY PLAN -------------------------------------------------------- Hash Join Hash Cond: (t3.val = t2.val) -> Seq Scan on t3 -> Hash -> Hash Join Hash Cond: (t2.id = t1.id) -> Seq Scan on t2 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (10 rows) /*+Leading(((t1 t2) t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading(((t1 t2) t3)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t2.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 (9 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; QUERY PLAN -------------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t3.id = t4.id) -> Nested Loop Join Filter: (t1.val = t3.val) -> Index Scan using t3_pkey on t3 -> Materialize -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (14 rows) /*+Leading((((t1 t2) t3) t4))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading((((t1 t2) t3) t4)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Nested Loop -> Nested Loop Join Filter: (t1.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 -> Index Scan using t4_pkey on t4 Index Cond: (id = t3.id) (12 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; QUERY PLAN -------------------------------------------------------- Hash Join Hash Cond: (t3.val = t2.val) -> Seq Scan on t3 -> Hash -> Hash Join Hash Cond: (t2.id = t1.id) -> Seq Scan on t2 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (10 rows) /*+Leading(((t1 t2) t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading(((t1 t2) t3)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t2.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 (9 rows) /*+Leading((t1 (t2 t3)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading((t1 (t2 t3))) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Hash Join Hash Cond: (t2.val = t3.val) -> Seq Scan on t2 -> Hash -> Seq Scan on t3 (10 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; QUERY PLAN -------------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t3.id = t4.id) -> Nested Loop Join Filter: (t1.val = t3.val) -> Index Scan using t3_pkey on t3 -> Materialize -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (14 rows) /*+Leading(((t1 t2) (t3 t4)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading(((t1 t2) (t3 t4))) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t1.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 (14 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < ( SELECT t1_2.id FROM t1 t1_2, t2 t2_2 WHERE t1_2.id = t2_2.id AND t2_2.val > 100 ORDER BY t1_2.id LIMIT 1); QUERY PLAN -------------------------------------------------------------------- Hash Join Hash Cond: (t2.val = t3.val) InitPlan 1 -> Limit -> Sort Sort Key: t1_2.id -> Nested Loop -> Index Scan using t2_val on t2 t2_2 Index Cond: (val > 100) -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < (InitPlan 1).col1) -> Index Scan using t2_pkey on t2 -> Hash -> Seq Scan on t3 (18 rows) /*+Leading(((t1 t2) t3)) Leading(((t3 t1) t2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t1.val = t3.val AND t1.id < ( SELECT t1_2.id FROM t1 t1_2, t2 t2_2 WHERE t1_2.id = t2_2.id AND t2_2.val > 100 ORDER BY t1_2.id LIMIT 1); INFO: pg_hint_plan: hint syntax error at or near "Leading(((t1 t2) t3)) Leading(((t3 t1) t2))" DETAIL: Conflict leading hint. LOG: pg_hint_plan: used hint: Leading(((t3 t1) t2)) not used hint: duplication hint: Leading(((t1 t2) t3)) error hint: QUERY PLAN -------------------------------------------------------------------- Hash Join Hash Cond: (t1.id = t2.id) InitPlan 1 -> Limit -> Sort Sort Key: t1_2.id -> Nested Loop -> Index Scan using t2_val on t2 t2_2 Index Cond: (val > 100) -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Hash Join Hash Cond: (t3.val = t1.val) -> Seq Scan on t3 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < (InitPlan 1).col1) -> Hash -> Seq Scan on t2 (19 rows) /*+Leading(((t1 t2) t3)) Leading((t1_2 t2_2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < ( SELECT t1_2.id FROM t1 t1_2, t2 t2_2 WHERE t1_2.id = t2_2.id AND t2_2.val > 100 ORDER BY t1_2.id LIMIT 1); LOG: pg_hint_plan: used hint: Leading(((t1 t2) t3)) Leading((t1_2 t2_2)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------------- Hash Join Hash Cond: (t2.val = t3.val) InitPlan 1 -> Limit -> Merge Join Merge Cond: (t1_2.id = t2_2.id) -> Index Only Scan using t1_pkey on t1 t1_2 -> Sort Sort Key: t2_2.id -> Index Scan using t2_val on t2 t2_2 Index Cond: (val > 100) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < (InitPlan 1).col1) -> Index Scan using t2_pkey on t2 -> Hash -> Seq Scan on t3 (18 rows) /*+Leading(((((t1 t2) t3) t1_2) t2_2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < ( SELECT t1_2.id FROM t1 t1_2, t2 t2_2 WHERE t1_2.id = t2_2.id AND t2_2.val > 100 ORDER BY t1_2.id LIMIT 1); LOG: pg_hint_plan: used hint: not used hint: Leading(((((t1 t2) t3) t1_2) t2_2)) duplication hint: error hint: QUERY PLAN -------------------------------------------------------------------- Hash Join Hash Cond: (t2.val = t3.val) InitPlan 1 -> Limit -> Sort Sort Key: t1_2.id -> Nested Loop -> Index Scan using t2_val on t2 t2_2 Index Cond: (val > 100) -> Index Only Scan using t1_pkey on t1 t1_2 Index Cond: (id = t2_2.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < (InitPlan 1).col1) -> Index Scan using t2_pkey on t2 -> Hash -> Seq Scan on t3 (18 rows) -- Specified outer/inner leading hint and join method hint at the same time /*+Leading(((t1 t2) t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading(((t1 t2) t3)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t2.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 (9 rows) /*+Leading(((t1 t2) t3)) MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) Leading(((t1 t2) t3)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t2.val = t3.val) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Index Scan using t2_pkey on t2 -> Seq Scan on t3 (8 rows) /*+Leading(((t1 t2) t3)) MergeJoin(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2 t3) Leading(((t1 t2) t3)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Merge Join Merge Cond: (t2.val = t3.val) -> Sort Sort Key: t2.val -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Sort Sort Key: t3.val -> Seq Scan on t3 (13 rows) /*+Leading(((t1 t2) t3)) MergeJoin(t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading(((t1 t2) t3)) not used hint: MergeJoin(t1 t3) duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t2.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 (9 rows) EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; QUERY PLAN -------------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t3.id = t4.id) -> Nested Loop Join Filter: (t1.val = t3.val) -> Index Scan using t3_pkey on t3 -> Materialize -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t2_pkey on t2 Index Cond: (id = t1.id) (14 rows) /*+Leading(((t1 t2) t3)) MergeJoin(t3 t4)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading(((t1 t2) t3)) not used hint: MergeJoin(t3 t4) duplication hint: error hint: QUERY PLAN -------------------------------------------------- Nested Loop Join Filter: (t3.id = t4.id) -> Nested Loop Join Filter: (t1.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 -> Seq Scan on t4 (12 rows) /*+Leading(((t1 t2) t3)) MergeJoin(t1 t2 t3 t4)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2 t3 t4) Leading(((t1 t2) t3)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------- Merge Join Merge Cond: (t3.id = t4.id) -> Sort Sort Key: t3.id -> Nested Loop Join Filter: (t1.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 (16 rows) /*+ Leading ( ( t1 ( t2 t3 ) ) ) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading((t1 (t2 t3))) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Hash Join Hash Cond: (t2.val = t3.val) -> Seq Scan on t2 -> Hash -> Seq Scan on t3 (10 rows) /*+Leading((t1(t2 t3)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading((t1 (t2 t3))) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Hash Join Hash Cond: (t2.val = t3.val) -> Seq Scan on t2 -> Hash -> Seq Scan on t3 (10 rows) /*+Leading(("t1(t2" "t3)"))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: not used hint: Leading(("t1(t2" "t3)")) duplication hint: error hint: QUERY PLAN -------------------------------------------------------- Hash Join Hash Cond: (t3.val = t2.val) -> Seq Scan on t3 -> Hash -> Hash Join Hash Cond: (t2.id = t1.id) -> Seq Scan on t2 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (10 rows) /*+ Leading ( ( ( t1 t2 ) t3 ) ) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading(((t1 t2) t3)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t2.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 (9 rows) /*+Leading(((t1 t2)t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: Leading(((t1 t2) t3)) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t2.val = t3.val) -> Hash Join Hash Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) -> Hash -> Seq Scan on t2 -> Seq Scan on t3 (9 rows) /*+Leading(("(t1" "t2)t3"))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; LOG: pg_hint_plan: used hint: not used hint: Leading(("(t1" "t2)t3")) duplication hint: error hint: QUERY PLAN -------------------------------------------------------- Hash Join Hash Cond: (t3.val = t2.val) -> Seq Scan on t3 -> Hash -> Hash Join Hash Cond: (t2.id = t1.id) -> Seq Scan on t2 -> Hash -> Index Scan using t1_pkey on t1 Index Cond: (id < 10) (10 rows) /*+Leading((t1(t2(t3(t4 t5)))))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; LOG: pg_hint_plan: used hint: Leading((t1 (t2 (t3 (t4 t5))))) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Materialize -> Merge Join Merge Cond: (t2.id = t3.id) -> Index Scan using t2_pkey on t2 -> Materialize -> Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Materialize -> Merge Join Merge Cond: (t4.id = t5.id) -> Index Scan using t4_pkey on t4 -> Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 (16 rows) /*+Leading((t5(t4(t3(t2 t1)))))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; LOG: pg_hint_plan: used hint: Leading((t5 (t4 (t3 (t2 t1))))) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------------------------- Hash Join Hash Cond: (t5.id = t1.id) -> Seq Scan on t5 -> Hash -> Merge Join Merge Cond: (t4.id = t1.id) -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Materialize -> Merge Join Merge Cond: (t3.id = t1.id) -> Sort Sort Key: t3.id -> Seq Scan on t3 -> Materialize -> Merge Join Merge Cond: (t2.id = t1.id) -> Index Scan using t2_pkey on t2 -> Index Scan using t1_pkey on t1 (20 rows) /*+Leading(((((t1 t2)t3)t4)t5))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; LOG: pg_hint_plan: used hint: Leading(((((t1 t2) t3) t4) t5)) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t3.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t3.id -> Seq Scan on t3 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = t1.id) (17 rows) /*+Leading(((((t5 t4)t3)t2)t1))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; LOG: pg_hint_plan: used hint: Leading(((((t5 t4) t3) t2) t1)) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------- Nested Loop Join Filter: (t1.id = t2.id) -> Nested Loop Join Filter: (t2.id = t3.id) -> Merge Join Merge Cond: (t4.id = t3.id) -> Merge Join Merge Cond: (t5.id = t4.id) -> Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 -> Index Scan using t2_pkey on t2 Index Cond: (id = t5.id) -> Index Scan using t1_pkey on t1 Index Cond: (id = t5.id) (17 rows) /*+Leading(((t1 t2)(t3(t4 t5))))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; LOG: pg_hint_plan: used hint: Leading(((t1 t2) (t3 (t4 t5)))) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- Merge Join Merge Cond: (t1.id = t3.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Materialize -> Merge Join Merge Cond: (t3.id = t4.id) -> Index Scan using t3_pkey on t3 -> Materialize -> Merge Join Merge Cond: (t4.id = t5.id) -> Index Scan using t4_pkey on t4 -> Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 (15 rows) /*+Leading(((t5 t4)(t3(t2 t1))))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; LOG: pg_hint_plan: used hint: Leading(((t5 t4) (t3 (t2 t1)))) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------- Merge Join Merge Cond: (t4.id = t1.id) -> Merge Join Merge Cond: (t5.id = t4.id) -> Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Materialize -> Merge Join Merge Cond: (t3.id = t1.id) -> Sort Sort Key: t3.id -> Seq Scan on t3 -> Materialize -> Merge Join Merge Cond: (t2.id = t1.id) -> Index Scan using t2_pkey on t2 -> Index Scan using t1_pkey on t1 (19 rows) /*+Leading((((t1 t2)t3)(t4 t5)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; LOG: pg_hint_plan: used hint: Leading((((t1 t2) t3) (t4 t5))) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------- Merge Join Merge Cond: (t1.id = t4.id) -> Merge Join Merge Cond: (t1.id = t3.id) -> Merge Join Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t3.id -> Seq Scan on t3 -> Materialize -> Merge Join Merge Cond: (t4.id = t5.id) -> Index Scan using t4_pkey on t4 -> Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 (16 rows) /*+Leading((((t5 t4)t3)(t2 t1)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; LOG: pg_hint_plan: used hint: Leading((((t5 t4) t3) (t2 t1))) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------- Merge Join Merge Cond: (t3.id = t1.id) -> Merge Join Merge Cond: (t4.id = t3.id) -> Merge Join Merge Cond: (t5.id = t4.id) -> Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 -> Sort Sort Key: t4.id -> Seq Scan on t4 -> Index Scan using t3_pkey on t3 -> Materialize -> Merge Join Merge Cond: (t2.id = t1.id) -> Index Scan using t2_pkey on t2 -> Index Scan using t1_pkey on t1 (16 rows) -- inherite table test to specify the index's name EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1 p2_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c1 p2_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (9 rows) /*+IndexScan(p2 p2_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_pkey LOG: available indexes for IndexScan(p2_c1): p2_c1_pkey LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_pkey LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_pkey LOG: pg_hint_plan: used hint: IndexScan(p2 p2_pkey) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p2_pkey on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_pkey on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_pkey on p2_c1_c1 p2_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_pkey on p2_c1_c2 p2_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) /*+IndexScan(p2 p2_id_val_idx)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_id_val_idx LOG: available indexes for IndexScan(p2_c1): p2_c1_id_val_idx LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_id_val_idx LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_id_val_idx LOG: pg_hint_plan: used hint: IndexScan(p2 p2_id_val_idx) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------- Append -> Index Scan using p2_id_val_idx on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_id_val_idx on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_id_val_idx on p2_c1_c1 p2_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_id_val_idx on p2_c1_c2 p2_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) /*+IndexScan(p2 p2_val_id_idx)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_val_id_idx LOG: available indexes for IndexScan(p2_c1): p2_c1_val_id_idx LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_val_id_idx LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_val_id_idx LOG: pg_hint_plan: used hint: IndexScan(p2 p2_val_id_idx) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------- Append -> Index Scan using p2_val_id_idx on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_val_id_idx on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_val_id_idx on p2_c1_c1 p2_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_val_id_idx on p2_c1_c2 p2_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1 p2_2 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c2 p2_3 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3 p2_4 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c4 p2_5 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c1 p2_6 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_7 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3_c1 p2_8 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3_c2 p2_9 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) (19 rows) -- Inhibit parallel exection to avoid interfaring the hint set max_parallel_workers_per_gather to 0; /*+ IndexScan(p2 p2_val)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): LOG: available indexes for IndexScan(p2_c1): LOG: available indexes for IndexScan(p2_c2): LOG: available indexes for IndexScan(p2_c3): LOG: available indexes for IndexScan(p2_c4): LOG: available indexes for IndexScan(p2_c1_c1): LOG: available indexes for IndexScan(p2_c1_c2): LOG: available indexes for IndexScan(p2_c3_c1): LOG: available indexes for IndexScan(p2_c3_c2): LOG: pg_hint_plan: used hint: not used hint: IndexScan(p2 p2_val) duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1 p2_2 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c2 p2_3 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3 p2_4 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c4 p2_5 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c1 p2_6 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_7 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3_c1 p2_8 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3_c2 p2_9 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) (19 rows) /*+IndexScan(p2 p2_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_pkey LOG: available indexes for IndexScan(p2_c1): p2_c1_pkey LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_pkey LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_pkey LOG: pg_hint_plan: used hint: IndexScan(p2 p2_pkey) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p2_pkey on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_pkey on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_pkey on p2_c1_c1 p2_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_pkey on p2_c1_c2 p2_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) /*+IndexScan(p2 p2_id2_val)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_id2_val LOG: available indexes for IndexScan(p2_c1): p2_c1_id2_val LOG: available indexes for IndexScan(p2_c1_c1): LOG: available indexes for IndexScan(p2_c1_c2): LOG: pg_hint_plan: used hint: IndexScan(p2 p2_id2_val) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Append -> Index Scan using p2_id2_val on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_id2_val on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on p2_c1_c1 p2_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (11 rows) /*+IndexScan(p2 p2_val2_id)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_val2_id LOG: available indexes for IndexScan(p2_c1): LOG: available indexes for IndexScan(p2_c1_c1): LOG: available indexes for IndexScan(p2_c1_c2): LOG: pg_hint_plan: used hint: IndexScan(p2 p2_val2_id) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Append -> Index Scan using p2_val2_id on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on p2_c1 p2_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c1 p2_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (10 rows) /*+IndexScan(p2 p2_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_pkey LOG: available indexes for IndexScan(p2_c1): p2_c1_pkey LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_pkey LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_pkey LOG: pg_hint_plan: used hint: IndexScan(p2 p2_pkey) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p2_pkey on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_pkey on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_pkey on p2_c1_c1 p2_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_pkey on p2_c1_c2 p2_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) /*+IndexScan(p2 p2_c1_id_val_idx)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): LOG: available indexes for IndexScan(p2_c1): p2_c1_id_val_idx LOG: available indexes for IndexScan(p2_c1_c1): LOG: available indexes for IndexScan(p2_c1_c2): LOG: pg_hint_plan: used hint: IndexScan(p2 p2_c1_id_val_idx) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using p2_c1_id_val_idx on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on p2_c1_c1 p2_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (10 rows) /*+IndexScan(p2 no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): LOG: available indexes for IndexScan(p2_c1): LOG: available indexes for IndexScan(p2_c1_c1): LOG: available indexes for IndexScan(p2_c1_c2): LOG: pg_hint_plan: used hint: not used hint: IndexScan(p2 no_exist) duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1 p2_2 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c1 p2_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (9 rows) /*+IndexScan(p2 p2_pkey p2_c1_id_val_idx)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_pkey LOG: available indexes for IndexScan(p2_c1): p2_c1_id_val_idx p2_c1_pkey LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_pkey LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_pkey LOG: pg_hint_plan: used hint: IndexScan(p2 p2_pkey p2_c1_id_val_idx) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p2_pkey on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_id_val_idx on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_pkey on p2_c1_c1 p2_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_pkey on p2_c1_c2 p2_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) /*+IndexScan(p2 p2_pkey no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_pkey LOG: available indexes for IndexScan(p2_c1): p2_c1_pkey LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_pkey LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_pkey LOG: pg_hint_plan: used hint: IndexScan(p2 p2_pkey no_exist) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p2_pkey on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_pkey on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_pkey on p2_c1_c1 p2_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_pkey on p2_c1_c2 p2_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) /*+IndexScan(p2 p2_c1_id_val_idx no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): LOG: available indexes for IndexScan(p2_c1): p2_c1_id_val_idx LOG: available indexes for IndexScan(p2_c1_c1): LOG: available indexes for IndexScan(p2_c1_c2): LOG: pg_hint_plan: used hint: IndexScan(p2 p2_c1_id_val_idx no_exist) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Index Scan using p2_c1_id_val_idx on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on p2_c1_c1 p2_3 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_4 Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid)) (10 rows) /*+IndexScan(p2 p2_pkey p2_c1_id_val_idx no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_pkey LOG: available indexes for IndexScan(p2_c1): p2_c1_id_val_idx p2_c1_pkey LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_pkey LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_pkey LOG: pg_hint_plan: used hint: IndexScan(p2 p2_pkey p2_c1_id_val_idx no_exist) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p2_pkey on p2 p2_1 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_id_val_idx on p2_c1 p2_2 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_pkey on p2_c1_c1 p2_3 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_pkey on p2_c1_c2 p2_4 Index Cond: ((id >= 50) AND (id <= 51)) Filter: (ctid = '(1,1)'::tid) (13 rows) /*+IndexScan(p2 p2_val_idx)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_val_idx LOG: available indexes for IndexScan(p2_c1): p2_c1_val_idx LOG: available indexes for IndexScan(p2_c2): p2_c2_val_idx LOG: available indexes for IndexScan(p2_c3): p2_c3_val_idx LOG: available indexes for IndexScan(p2_c4): p2_c4_val_idx LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_val_idx LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_val_idx LOG: available indexes for IndexScan(p2_c3_c1): p2_c3_c1_val_idx LOG: available indexes for IndexScan(p2_c3_c2): p2_c3_c2_val_idx LOG: pg_hint_plan: used hint: IndexScan(p2 p2_val_idx) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Append -> Index Scan using p2_val_idx on p2 p2_1 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_val_idx on p2_c1 p2_2 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c2_val_idx on p2_c2 p2_3 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c3_val_idx on p2_c3 p2_4 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c4_val_idx on p2_c4 p2_5 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_val_idx on p2_c1_c1 p2_6 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_val_idx on p2_c1_c2 p2_7 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c3_c1_val_idx on p2_c3_c1 p2_8 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c3_c2_val_idx on p2_c3_c2 p2_9 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) (28 rows) /*+IndexScan(p2 p2_expr)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_expr LOG: available indexes for IndexScan(p2_c1): p2_c1_expr_idx LOG: available indexes for IndexScan(p2_c2): p2_c2_expr_idx LOG: available indexes for IndexScan(p2_c3): p2_c3_expr_idx LOG: available indexes for IndexScan(p2_c4): p2_c4_expr_idx LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_expr_idx LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_expr_idx LOG: available indexes for IndexScan(p2_c3_c1): p2_c3_c1_expr_idx LOG: available indexes for IndexScan(p2_c3_c2): p2_c3_c2_expr_idx LOG: pg_hint_plan: used hint: IndexScan(p2 p2_expr) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1 p2_2 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c2 p2_3 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3 p2_4 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c4 p2_5 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c1 p2_6 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_7 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3_c1 p2_8 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3_c2 p2_9 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) (19 rows) /*+IndexScan(p2 p2_val_idx6)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_val_idx6 LOG: available indexes for IndexScan(p2_c1): p2_c1_val_idx7 LOG: available indexes for IndexScan(p2_c2): p2_c2_val_idx7 LOG: available indexes for IndexScan(p2_c3): p2_c3_val_idx7 LOG: available indexes for IndexScan(p2_c4): p2_c4_val_idx7 LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_val_idx7 LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_val_idx7 LOG: available indexes for IndexScan(p2_c3_c1): p2_c3_c1_val_idx7 LOG: available indexes for IndexScan(p2_c3_c2): p2_c3_c2_val_idx7 LOG: pg_hint_plan: used hint: IndexScan(p2 p2_val_idx6) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1 p2_2 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c2 p2_3 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3 p2_4 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c4 p2_5 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c1 p2_6 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c1_c2 p2_7 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3_c1 p2_8 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) -> Seq Scan on p2_c3_c2 p2_9 Filter: ((val >= '50'::text) AND (val <= '51'::text) AND (ctid = '(1,1)'::tid)) (19 rows) /*+IndexScan(p2 p2_val_idx p2_val_idx6)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; LOG: available indexes for IndexScan(p2): p2_val_idx6 p2_val_idx LOG: available indexes for IndexScan(p2_c1): p2_c1_val_idx7 p2_c1_val_idx LOG: available indexes for IndexScan(p2_c2): p2_c2_val_idx7 p2_c2_val_idx LOG: available indexes for IndexScan(p2_c3): p2_c3_val_idx7 p2_c3_val_idx LOG: available indexes for IndexScan(p2_c4): p2_c4_val_idx7 p2_c4_val_idx LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_val_idx7 p2_c1_c1_val_idx LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_val_idx7 p2_c1_c2_val_idx LOG: available indexes for IndexScan(p2_c3_c1): p2_c3_c1_val_idx7 p2_c3_c1_val_idx LOG: available indexes for IndexScan(p2_c3_c2): p2_c3_c2_val_idx7 p2_c3_c2_val_idx LOG: pg_hint_plan: used hint: IndexScan(p2 p2_val_idx p2_val_idx6) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Append -> Index Scan using p2_val_idx on p2 p2_1 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_val_idx on p2_c1 p2_2 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c2_val_idx on p2_c2 p2_3 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c3_val_idx on p2_c3 p2_4 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c4_val_idx on p2_c4 p2_5 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c1_val_idx on p2_c1_c1 p2_6 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c1_c2_val_idx on p2_c1_c2 p2_7 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c3_c1_val_idx on p2_c3_c1 p2_8 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) -> Index Scan using p2_c3_c2_val_idx on p2_c3_c2 p2_9 Index Cond: ((val >= '50'::text) AND (val <= '51'::text)) Filter: (ctid = '(1,1)'::tid) (28 rows) -- regular expression -- ordinary table EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ IndexScanRegexp(t5 t5_[^i].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexScanRegexp(t5): t5_val t5_pkey LOG: pg_hint_plan: used hint: IndexScanRegexp(t5 t5_[^i].*) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------- Index Scan using t5_pkey on t5 Index Cond: (id = 1) (2 rows) /*+ IndexScanRegexp(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexScanRegexp(t5): t5_id3 t5_id2 t5_id1 LOG: pg_hint_plan: used hint: IndexScanRegexp(t5 t5_id[0-9].*) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------- Index Scan using t5_id3 on t5 Index Cond: (id = 1) (2 rows) /*+ IndexScanRegexp(t5 t5[^_].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexScanRegexp(t5): LOG: pg_hint_plan: used hint: not used hint: IndexScanRegexp(t5 t5[^_].*) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ IndexScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexScanRegexp(t5): LOG: pg_hint_plan: used hint: not used hint: IndexScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ IndexScan(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexScan(t5): LOG: pg_hint_plan: used hint: not used hint: IndexScan(t5 t5_id[0-9].*) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ IndexOnlyScanRegexp(t5 t5_[^i].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexOnlyScanRegexp(t5): t5_val t5_pkey LOG: pg_hint_plan: used hint: IndexOnlyScanRegexp(t5 t5_[^i].*) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Index Only Scan using t5_pkey on t5 Index Cond: (id = 1) (2 rows) /*+ IndexOnlyScanRegexp(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexOnlyScanRegexp(t5): t5_id3 t5_id2 t5_id1 LOG: pg_hint_plan: used hint: IndexOnlyScanRegexp(t5 t5_id[0-9].*) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Index Only Scan using t5_id3 on t5 Index Cond: (id = 1) (2 rows) /*+ IndexOnlyScanRegexp(t5 t5[^_].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexOnlyScanRegexp(t5): LOG: pg_hint_plan: used hint: not used hint: IndexOnlyScanRegexp(t5 t5[^_].*) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ IndexOnlyScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexOnlyScanRegexp(t5): LOG: pg_hint_plan: used hint: not used hint: IndexOnlyScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ IndexOnlyScan(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexOnlyScan(t5): LOG: pg_hint_plan: used hint: not used hint: IndexOnlyScan(t5 t5_id[0-9].*) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ BitmapScanRegexp(t5 t5_[^i].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for BitmapScanRegexp(t5): t5_val t5_pkey LOG: pg_hint_plan: used hint: BitmapScanRegexp(t5 t5_[^i].*) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Bitmap Heap Scan on t5 Recheck Cond: (id = 1) -> Bitmap Index Scan on t5_pkey Index Cond: (id = 1) (4 rows) /*+ BitmapScanRegexp(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for BitmapScanRegexp(t5): t5_id3 t5_id2 t5_id1 LOG: pg_hint_plan: used hint: BitmapScanRegexp(t5 t5_id[0-9].*) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Bitmap Heap Scan on t5 Recheck Cond: (id = 1) -> Bitmap Index Scan on t5_id3 Index Cond: (id = 1) (4 rows) /*+ BitmapScanRegexp(t5 t5[^_].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for BitmapScanRegexp(t5): LOG: pg_hint_plan: used hint: not used hint: BitmapScanRegexp(t5 t5[^_].*) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ BitmapScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for BitmapScanRegexp(t5): LOG: pg_hint_plan: used hint: not used hint: BitmapScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) /*+ BitmapScan(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for BitmapScan(t5): LOG: pg_hint_plan: used hint: not used hint: BitmapScan(t5 t5_id[0-9].*) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 Index Cond: (id = 1) (2 rows) -- Inheritance EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ IndexScanRegexp(p1 p1_.*[^0-9]$)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for IndexScanRegexp(p1): p1_pkey LOG: available indexes for IndexScanRegexp(p1_c1): p1_c1_pkey LOG: available indexes for IndexScanRegexp(p1_c2): p1_c2_pkey LOG: available indexes for IndexScanRegexp(p1_c3): p1_c3_pkey LOG: available indexes for IndexScanRegexp(p1_c4): p1_c4_pkey LOG: available indexes for IndexScanRegexp(p1_c1_c1): p1_c1_c1_pkey LOG: available indexes for IndexScanRegexp(p1_c1_c2): p1_c1_c2_pkey LOG: available indexes for IndexScanRegexp(p1_c3_c1): p1_c3_c1_pkey LOG: available indexes for IndexScanRegexp(p1_c3_c2): p1_c3_c2_pkey LOG: pg_hint_plan: used hint: IndexScanRegexp(p1 p1_.*[^0-9]$) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ IndexScanRegexp(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for IndexScanRegexp(p1): p1_val2 LOG: available indexes for IndexScanRegexp(p1_c1): p1_c1_val2 LOG: available indexes for IndexScanRegexp(p1_c2): p1_c2_val2 LOG: available indexes for IndexScanRegexp(p1_c3): p1_c3_val2 LOG: available indexes for IndexScanRegexp(p1_c4): p1_c4_val2 LOG: available indexes for IndexScanRegexp(p1_c1_c1): p1_c1_c1_val2 LOG: available indexes for IndexScanRegexp(p1_c1_c2): p1_c1_c2_val2 LOG: available indexes for IndexScanRegexp(p1_c3_c1): p1_c3_c1_val2 LOG: available indexes for IndexScanRegexp(p1_c3_c2): p1_c3_c2_val2 LOG: pg_hint_plan: used hint: IndexScanRegexp(p1 p1_.*val2.*) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Append -> Index Scan using p1_val2 on p1 p1_1 Index Cond: (val = 1) -> Index Scan using p1_c1_val2 on p1_c1 p1_2 Index Cond: (val = 1) -> Index Scan using p1_c2_val2 on p1_c2 p1_3 Index Cond: (val = 1) -> Index Scan using p1_c3_val2 on p1_c3 p1_4 Index Cond: (val = 1) -> Index Scan using p1_c4_val2 on p1_c4 p1_5 Index Cond: (val = 1) -> Index Scan using p1_c1_c1_val2 on p1_c1_c1 p1_6 Index Cond: (val = 1) -> Index Scan using p1_c1_c2_val2 on p1_c1_c2 p1_7 Index Cond: (val = 1) -> Index Scan using p1_c3_c1_val2 on p1_c3_c1 p1_8 Index Cond: (val = 1) -> Index Scan using p1_c3_c2_val2 on p1_c3_c2 p1_9 Index Cond: (val = 1) (19 rows) /*+ IndexScanRegexp(p1 p1[^_].*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for IndexScanRegexp(p1): LOG: available indexes for IndexScanRegexp(p1_c1): LOG: available indexes for IndexScanRegexp(p1_c2): LOG: available indexes for IndexScanRegexp(p1_c3): LOG: available indexes for IndexScanRegexp(p1_c4): LOG: available indexes for IndexScanRegexp(p1_c1_c1): LOG: available indexes for IndexScanRegexp(p1_c1_c2): LOG: available indexes for IndexScanRegexp(p1_c3_c1): LOG: available indexes for IndexScanRegexp(p1_c3_c2): LOG: pg_hint_plan: used hint: not used hint: IndexScanRegexp(p1 p1[^_].*) duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ IndexScan(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for IndexScan(p1): LOG: available indexes for IndexScan(p1_c1): LOG: available indexes for IndexScan(p1_c2): LOG: available indexes for IndexScan(p1_c3): LOG: available indexes for IndexScan(p1_c4): LOG: available indexes for IndexScan(p1_c1_c1): LOG: available indexes for IndexScan(p1_c1_c2): LOG: available indexes for IndexScan(p1_c3_c1): LOG: available indexes for IndexScan(p1_c3_c2): LOG: pg_hint_plan: used hint: not used hint: IndexScan(p1 p1_.*val2.*) duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ IndexOnlyScanRegexp(p1 p1_.*[^0-9]$)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for IndexOnlyScanRegexp(p1): p1_pkey LOG: available indexes for IndexOnlyScanRegexp(p1_c1): p1_c1_pkey LOG: available indexes for IndexOnlyScanRegexp(p1_c2): p1_c2_pkey LOG: available indexes for IndexOnlyScanRegexp(p1_c3): p1_c3_pkey LOG: available indexes for IndexOnlyScanRegexp(p1_c4): p1_c4_pkey LOG: available indexes for IndexOnlyScanRegexp(p1_c1_c1): p1_c1_c1_pkey LOG: available indexes for IndexOnlyScanRegexp(p1_c1_c2): p1_c1_c2_pkey LOG: available indexes for IndexOnlyScanRegexp(p1_c3_c1): p1_c3_c1_pkey LOG: available indexes for IndexOnlyScanRegexp(p1_c3_c2): p1_c3_c2_pkey LOG: pg_hint_plan: used hint: IndexOnlyScanRegexp(p1 p1_.*[^0-9]$) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ IndexOnlyScanRegexp(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for IndexOnlyScanRegexp(p1): p1_val2 LOG: available indexes for IndexOnlyScanRegexp(p1_c1): p1_c1_val2 LOG: available indexes for IndexOnlyScanRegexp(p1_c2): p1_c2_val2 LOG: available indexes for IndexOnlyScanRegexp(p1_c3): p1_c3_val2 LOG: available indexes for IndexOnlyScanRegexp(p1_c4): p1_c4_val2 LOG: available indexes for IndexOnlyScanRegexp(p1_c1_c1): p1_c1_c1_val2 LOG: available indexes for IndexOnlyScanRegexp(p1_c1_c2): p1_c1_c2_val2 LOG: available indexes for IndexOnlyScanRegexp(p1_c3_c1): p1_c3_c1_val2 LOG: available indexes for IndexOnlyScanRegexp(p1_c3_c2): p1_c3_c2_val2 LOG: pg_hint_plan: used hint: IndexOnlyScanRegexp(p1 p1_.*val2.*) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Append -> Index Only Scan using p1_val2 on p1 p1_1 Index Cond: (val = 1) -> Index Only Scan using p1_c1_val2 on p1_c1 p1_2 Index Cond: (val = 1) -> Index Only Scan using p1_c2_val2 on p1_c2 p1_3 Index Cond: (val = 1) -> Index Only Scan using p1_c3_val2 on p1_c3 p1_4 Index Cond: (val = 1) -> Index Only Scan using p1_c4_val2 on p1_c4 p1_5 Index Cond: (val = 1) -> Index Only Scan using p1_c1_c1_val2 on p1_c1_c1 p1_6 Index Cond: (val = 1) -> Index Only Scan using p1_c1_c2_val2 on p1_c1_c2 p1_7 Index Cond: (val = 1) -> Index Only Scan using p1_c3_c1_val2 on p1_c3_c1 p1_8 Index Cond: (val = 1) -> Index Only Scan using p1_c3_c2_val2 on p1_c3_c2 p1_9 Index Cond: (val = 1) (19 rows) /*+ IndexOnlyScanRegexp(p1 p1[^_].*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for IndexOnlyScanRegexp(p1): LOG: available indexes for IndexOnlyScanRegexp(p1_c1): LOG: available indexes for IndexOnlyScanRegexp(p1_c2): LOG: available indexes for IndexOnlyScanRegexp(p1_c3): LOG: available indexes for IndexOnlyScanRegexp(p1_c4): LOG: available indexes for IndexOnlyScanRegexp(p1_c1_c1): LOG: available indexes for IndexOnlyScanRegexp(p1_c1_c2): LOG: available indexes for IndexOnlyScanRegexp(p1_c3_c1): LOG: available indexes for IndexOnlyScanRegexp(p1_c3_c2): LOG: pg_hint_plan: used hint: not used hint: IndexOnlyScanRegexp(p1 p1[^_].*) duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ IndexOnlyScan(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for IndexOnlyScan(p1): LOG: available indexes for IndexOnlyScan(p1_c1): LOG: available indexes for IndexOnlyScan(p1_c2): LOG: available indexes for IndexOnlyScan(p1_c3): LOG: available indexes for IndexOnlyScan(p1_c4): LOG: available indexes for IndexOnlyScan(p1_c1_c1): LOG: available indexes for IndexOnlyScan(p1_c1_c2): LOG: available indexes for IndexOnlyScan(p1_c3_c1): LOG: available indexes for IndexOnlyScan(p1_c3_c2): LOG: pg_hint_plan: used hint: not used hint: IndexOnlyScan(p1 p1_.*val2.*) duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ BitmapScanRegexp(p1 p1_.*[^0-9]$)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for BitmapScanRegexp(p1): p1_pkey LOG: available indexes for BitmapScanRegexp(p1_c1): p1_c1_pkey LOG: available indexes for BitmapScanRegexp(p1_c2): p1_c2_pkey LOG: available indexes for BitmapScanRegexp(p1_c3): p1_c3_pkey LOG: available indexes for BitmapScanRegexp(p1_c4): p1_c4_pkey LOG: available indexes for BitmapScanRegexp(p1_c1_c1): p1_c1_c1_pkey LOG: available indexes for BitmapScanRegexp(p1_c1_c2): p1_c1_c2_pkey LOG: available indexes for BitmapScanRegexp(p1_c3_c1): p1_c3_c1_pkey LOG: available indexes for BitmapScanRegexp(p1_c3_c2): p1_c3_c2_pkey LOG: pg_hint_plan: used hint: BitmapScanRegexp(p1 p1_.*[^0-9]$) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ BitmapScanRegexp(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for BitmapScanRegexp(p1): p1_val2 LOG: available indexes for BitmapScanRegexp(p1_c1): p1_c1_val2 LOG: available indexes for BitmapScanRegexp(p1_c2): p1_c2_val2 LOG: available indexes for BitmapScanRegexp(p1_c3): p1_c3_val2 LOG: available indexes for BitmapScanRegexp(p1_c4): p1_c4_val2 LOG: available indexes for BitmapScanRegexp(p1_c1_c1): p1_c1_c1_val2 LOG: available indexes for BitmapScanRegexp(p1_c1_c2): p1_c1_c2_val2 LOG: available indexes for BitmapScanRegexp(p1_c3_c1): p1_c3_c1_val2 LOG: available indexes for BitmapScanRegexp(p1_c3_c2): p1_c3_c2_val2 LOG: pg_hint_plan: used hint: BitmapScanRegexp(p1 p1_.*val2.*) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Append -> Bitmap Heap Scan on p1 p1_1 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_val2 Index Cond: (val = 1) -> Bitmap Heap Scan on p1_c1 p1_2 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_c1_val2 Index Cond: (val = 1) -> Bitmap Heap Scan on p1_c2 p1_3 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_c2_val2 Index Cond: (val = 1) -> Bitmap Heap Scan on p1_c3 p1_4 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_c3_val2 Index Cond: (val = 1) -> Bitmap Heap Scan on p1_c4 p1_5 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_c4_val2 Index Cond: (val = 1) -> Bitmap Heap Scan on p1_c1_c1 p1_6 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_c1_c1_val2 Index Cond: (val = 1) -> Bitmap Heap Scan on p1_c1_c2 p1_7 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_c1_c2_val2 Index Cond: (val = 1) -> Bitmap Heap Scan on p1_c3_c1 p1_8 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_c3_c1_val2 Index Cond: (val = 1) -> Bitmap Heap Scan on p1_c3_c2 p1_9 Recheck Cond: (val = 1) -> Bitmap Index Scan on p1_c3_c2_val2 Index Cond: (val = 1) (37 rows) /*+ BitmapScanRegexp(p1 p1[^_].*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for BitmapScanRegexp(p1): LOG: available indexes for BitmapScanRegexp(p1_c1): LOG: available indexes for BitmapScanRegexp(p1_c2): LOG: available indexes for BitmapScanRegexp(p1_c3): LOG: available indexes for BitmapScanRegexp(p1_c4): LOG: available indexes for BitmapScanRegexp(p1_c1_c1): LOG: available indexes for BitmapScanRegexp(p1_c1_c2): LOG: available indexes for BitmapScanRegexp(p1_c3_c1): LOG: available indexes for BitmapScanRegexp(p1_c3_c2): LOG: pg_hint_plan: used hint: not used hint: BitmapScanRegexp(p1 p1[^_].*) duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) /*+ BitmapScan(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; LOG: available indexes for BitmapScan(p1): LOG: available indexes for BitmapScan(p1_c1): LOG: available indexes for BitmapScan(p1_c2): LOG: available indexes for BitmapScan(p1_c3): LOG: available indexes for BitmapScan(p1_c4): LOG: available indexes for BitmapScan(p1_c1_c1): LOG: available indexes for BitmapScan(p1_c1_c2): LOG: available indexes for BitmapScan(p1_c3_c1): LOG: available indexes for BitmapScan(p1_c3_c2): LOG: pg_hint_plan: used hint: not used hint: BitmapScan(p1 p1_.*val2.*) duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 Filter: (val = 1) -> Seq Scan on p1_c1 p1_2 Filter: (val = 1) -> Seq Scan on p1_c2 p1_3 Filter: (val = 1) -> Seq Scan on p1_c3 p1_4 Filter: (val = 1) -> Seq Scan on p1_c4 p1_5 Filter: (val = 1) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val = 1) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val = 1) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val = 1) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val = 1) (19 rows) -- Search from hint table SELECT get_query_id('SELECT * FROM t1 WHERE t1.id = 1') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); SELECT get_query_id('SELECT id FROM t1 WHERE t1.id = 1') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'IndexScan(t1)'); SET pg_hint_plan.enable_hint_table = on; EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (id = 1) (2 rows) SET pg_hint_plan.enable_hint_table = off; EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = 1; QUERY PLAN -------------------------------- Index Scan using t1_pkey on t1 Index Cond: (id = 1) (2 rows) TRUNCATE hint_plan.hints; VACUUM ANALYZE hint_plan.hints; -- plpgsql test EXPLAIN (COSTS false) SELECT id FROM t1 WHERE t1.id = 1; QUERY PLAN ------------------------------------- Index Only Scan using t1_pkey on t1 Index Cond: (id = 1) (2 rows) -- static function CREATE FUNCTION testfunc() RETURNS RECORD AS $$ DECLARE ret record; BEGIN SELECT /*+ SeqScan(t1) */ * INTO ret FROM t1 LIMIT 1; RETURN ret; END; $$ LANGUAGE plpgsql; SELECT testfunc(); LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: CONTEXT: SQL statement "SELECT /*+ SeqScan(t1) */ * FROM t1 LIMIT 1" PL/pgSQL function testfunc() line 5 at SQL statement testfunc ---------- (1,1) (1 row) -- dynamic function DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS void AS $$ BEGIN EXECUTE format('/*+ SeqScan(t1) */ SELECT * FROM t1'); END; $$ LANGUAGE plpgsql; SELECT testfunc(); LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: CONTEXT: SQL statement "/*+ SeqScan(t1) */ SELECT * FROM t1" PL/pgSQL function testfunc() line 3 at EXECUTE testfunc ---------- (1 row) -- This should not use SeqScan(t1) /*+ IndexScan(t1) */ SELECT * from t1 LIMIT 1; LOG: pg_hint_plan: used hint: IndexScan(t1) not used hint: duplication hint: error hint: id | val ----+----- 1 | 1 (1 row) -- Perform DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS void AS $$ BEGIN PERFORM 1, /*+ SeqScan(t1) */ * from t1; END; $$ LANGUAGE plpgsql; SELECT testfunc(); LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: CONTEXT: SQL statement "SELECT 1, /*+ SeqScan(t1) */ * from t1" PL/pgSQL function testfunc() line 3 at PERFORM testfunc ---------- (1 row) -- FOR loop DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS int AS $$ DECLARE sum int; v int; BEGIN sum := 0; FOR v IN SELECT /*+ SeqScan(t1) */ v FROM t1 ORDER BY id LOOP sum := sum + v; END LOOP; RETURN v; END; $$ LANGUAGE plpgsql; SELECT testfunc(); LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: CONTEXT: SQL statement "SELECT /*+ SeqScan(t1) */ v FROM t1 ORDER BY id" PL/pgSQL function testfunc() line 7 at FOR over SELECT rows testfunc ---------- (1 row) -- Dynamic FOR loop DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS int AS $$ DECLARE sum int; v int; i int; BEGIN sum := 0; FOR v IN EXECUTE 'SELECT /*+ SeqScan(t1) */ val FROM t1 ORDER BY id' LOOP sum := sum + v; END LOOP; RETURN v; END; $$ LANGUAGE plpgsql; SELECT testfunc(); LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: CONTEXT: SQL statement "SELECT /*+ SeqScan(t1) */ val FROM t1 ORDER BY id" PL/pgSQL function testfunc() line 8 at FOR over EXECUTE statement testfunc ---------- 0 (1 row) -- Cursor FOR loop DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS int AS $$ DECLARE ref CURSOR FOR SELECT /*+ SeqScan(t1) */ * FROM t1 ORDER BY id; rec record; sum int := 0; BEGIN FOR rec IN ref LOOP sum := sum + rec.val; END LOOP; RETURN sum; END; $$ LANGUAGE plpgsql; SELECT testfunc(); LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: CONTEXT: SQL statement "SELECT /*+ SeqScan(t1) */ * FROM t1 ORDER BY id" PL/pgSQL function testfunc() line 7 at FOR over cursor testfunc ---------- 495000 (1 row) -- RETURN QUERY DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS SETOF t1 AS $$ BEGIN RETURN QUERY SELECT /*+ SeqScan(t1) */ * FROM t1 ORDER BY id; END; $$ LANGUAGE plpgsql; SELECT * FROM testfunc() LIMIT 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: CONTEXT: SQL statement "SELECT /*+ SeqScan(t1) */ * FROM t1 ORDER BY id" PL/pgSQL function testfunc() line 3 at RETURN QUERY id | val ----+----- 1 | 1 (1 row) -- Test for error exit from inner SQL statement. DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS SETOF t1 AS $$ BEGIN RETURN QUERY SELECT /*+ SeqScan(t1) */ * FROM ttx ORDER BY id; END; $$ LANGUAGE plpgsql; SELECT * FROM testfunc() LIMIT 1; ERROR: relation "ttx" does not exist LINE 1: SELECT /*+ SeqScan(t1) */ * FROM ttx ORDER BY id ^ QUERY: SELECT /*+ SeqScan(t1) */ * FROM ttx ORDER BY id CONTEXT: PL/pgSQL function testfunc() line 3 at RETURN QUERY -- this should not use SeqScan(t1) hint. /*+ IndexScan(t1) */ SELECT * from t1 LIMIT 1; LOG: pg_hint_plan: used hint: IndexScan(t1) not used hint: duplication hint: error hint: id | val ----+----- 1 | 1 (1 row) DROP FUNCTION testfunc(); DROP EXTENSION pg_hint_plan; CREATE FUNCTION reset_stats_and_wait() RETURNS void AS $$ DECLARE rows int; BEGIN rows = 1; while rows > 0 LOOP PERFORM pg_stat_reset(); PERFORM pg_sleep(0.5); SELECT sum(seq_scan + idx_scan) from pg_stat_user_tables into rows; END LOOP; END; $$ LANGUAGE plpgsql; -- Dynamic query in pl/pgsql CREATE OR REPLACE FUNCTION dynsql1(x int) RETURNS int AS $$ DECLARE c int; BEGIN EXECUTE '/*+ IndexScan(t1) */ SELECT count(*) FROM t1 WHERE id < $1' INTO c USING x; RETURN c; END; $$ VOLATILE LANGUAGE plpgsql; vacuum analyze t1; SET pg_hint_plan.enable_hint = false; SELECT pg_sleep(1); pg_sleep ---------- (1 row) SELECT reset_stats_and_wait(); reset_stats_and_wait ---------------------- (1 row) SELECT dynsql1(9000); dynsql1 --------- 8999 (1 row) SELECT pg_sleep(1); pg_sleep ---------- (1 row) SELECT relname, seq_scan > 0 as seq_scan, idx_scan > 0 as idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 't1'; relname | seq_scan | idx_scan ---------+----------+---------- t1 | t | f (1 row) SET pg_hint_plan.enable_hint = true; SELECT reset_stats_and_wait(); reset_stats_and_wait ---------------------- (1 row) SELECT dynsql1(9000); LOG: pg_hint_plan: used hint: IndexScan(t1) not used hint: duplication hint: error hint: CONTEXT: SQL statement "/*+ IndexScan(t1) */ SELECT count(*) FROM t1 WHERE id < $1" PL/pgSQL function dynsql1(integer) line 4 at EXECUTE dynsql1 --------- 8999 (1 row) SELECT pg_sleep(1); pg_sleep ---------- (1 row) SELECT relname, seq_scan > 0 as seq_scan, idx_scan > 0 as idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 't1'; relname | seq_scan | idx_scan ---------+----------+---------- t1 | f | t (1 row) -- Looped dynamic query in pl/pgsql CREATE OR REPLACE FUNCTION dynsql2(x int, OUT r int) AS $$ DECLARE c text; s int; BEGIN r := 0; FOR c IN SELECT f.f FROM (VALUES ('p1_c1'), ('p1_c2')) f(f) LOOP FOR s IN EXECUTE '/*+ IndexScan(' || c || ' ' || c || '_pkey) */ SELECT sum(val) FROM ' || c || ' WHERE id < ' || x LOOP r := r + s; END LOOP; END LOOP; END; $$ VOLATILE LANGUAGE plpgsql; SET pg_hint_plan.enable_hint = false; SELECT reset_stats_and_wait(); reset_stats_and_wait ---------------------- (1 row) SELECT dynsql2(9000); dynsql2 --------- 9900 (1 row) SELECT pg_sleep(1); pg_sleep ---------- (1 row) -- one of the index scans happened while planning. SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND (relname = 'p1_c1' OR relname = 'p1_c2'); relname | seq_scan | idx_scan ---------+----------+---------- p1_c1 | 1 | 0 p1_c2 | 1 | 1 (2 rows) SET pg_hint_plan.enable_hint = true; SELECT reset_stats_and_wait(); reset_stats_and_wait ---------------------- (1 row) SELECT dynsql2(9000); LOG: available indexes for IndexScan(p1_c1): p1_c1_pkey CONTEXT: SQL statement "/*+ IndexScan(p1_c1 p1_c1_pkey) */ SELECT sum(val) FROM p1_c1 WHERE id < 9000" PL/pgSQL function dynsql2(integer) line 8 at FOR over EXECUTE statement LOG: available indexes for IndexScan(p1_c1_c1): p1_c1_c1_pkey CONTEXT: SQL statement "/*+ IndexScan(p1_c1 p1_c1_pkey) */ SELECT sum(val) FROM p1_c1 WHERE id < 9000" PL/pgSQL function dynsql2(integer) line 8 at FOR over EXECUTE statement LOG: available indexes for IndexScan(p1_c1_c2): p1_c1_c2_pkey CONTEXT: SQL statement "/*+ IndexScan(p1_c1 p1_c1_pkey) */ SELECT sum(val) FROM p1_c1 WHERE id < 9000" PL/pgSQL function dynsql2(integer) line 8 at FOR over EXECUTE statement LOG: pg_hint_plan: used hint: IndexScan(p1_c1 p1_c1_pkey) not used hint: duplication hint: error hint: CONTEXT: SQL statement "/*+ IndexScan(p1_c1 p1_c1_pkey) */ SELECT sum(val) FROM p1_c1 WHERE id < 9000" PL/pgSQL function dynsql2(integer) line 8 at FOR over EXECUTE statement LOG: available indexes for IndexScan(p1_c2): p1_c2_pkey CONTEXT: SQL statement "/*+ IndexScan(p1_c2 p1_c2_pkey) */ SELECT sum(val) FROM p1_c2 WHERE id < 9000" PL/pgSQL function dynsql2(integer) line 8 at FOR over EXECUTE statement LOG: pg_hint_plan: used hint: IndexScan(p1_c2 p1_c2_pkey) not used hint: duplication hint: error hint: CONTEXT: SQL statement "/*+ IndexScan(p1_c2 p1_c2_pkey) */ SELECT sum(val) FROM p1_c2 WHERE id < 9000" PL/pgSQL function dynsql2(integer) line 8 at FOR over EXECUTE statement dynsql2 --------- 9900 (1 row) SELECT pg_sleep(1); pg_sleep ---------- (1 row) -- the index scan happened while planning. SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND (relname = 'p1_c1' OR relname = 'p1_c2'); relname | seq_scan | idx_scan ---------+----------+---------- p1_c1 | 0 | 1 p1_c2 | 0 | 2 (2 rows) -- Subqueries on inheritance tables under UNION EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION ALL SELECT val::int FROM p2 WHERE id < 1000; QUERY PLAN --------------------------------------------- Append -> Append -> Seq Scan on p1 p1_1 Filter: (val < 1000) -> Seq Scan on p1_c1 p1_2 Filter: (val < 1000) -> Seq Scan on p1_c2 p1_3 Filter: (val < 1000) -> Seq Scan on p1_c3 p1_4 Filter: (val < 1000) -> Seq Scan on p1_c4 p1_5 Filter: (val < 1000) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val < 1000) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val < 1000) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val < 1000) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val < 1000) -> Result -> Append -> Seq Scan on p2 p2_1 Filter: (id < 1000) -> Seq Scan on p2_c1 p2_2 Filter: (id < 1000) -> Seq Scan on p2_c2 p2_3 Filter: (id < 1000) -> Seq Scan on p2_c3 p2_4 Filter: (id < 1000) -> Seq Scan on p2_c4 p2_5 Filter: (id < 1000) -> Seq Scan on p2_c1_c1 p2_6 Filter: (id < 1000) -> Seq Scan on p2_c1_c2 p2_7 Filter: (id < 1000) -> Seq Scan on p2_c3_c1 p2_8 Filter: (id < 1000) -> Seq Scan on p2_c3_c2 p2_9 Filter: (id < 1000) (40 rows) /*+ IndexScan(p1 p1_val2) */ EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION ALL SELECT val::int FROM p2 WHERE id < 1000; LOG: available indexes for IndexScan(p1): p1_val3 p1_val2 p1_val1 LOG: available indexes for IndexScan(p1_c1): p1_c1_val3 p1_c1_val2 p1_c1_val1 LOG: available indexes for IndexScan(p1_c2): p1_c2_val3 p1_c2_val2 p1_c2_val1 LOG: available indexes for IndexScan(p1_c3): p1_c3_val3 p1_c3_val2 p1_c3_val1 LOG: available indexes for IndexScan(p1_c4): p1_c4_val3 p1_c4_val2 p1_c4_val1 LOG: available indexes for IndexScan(p1_c1_c1): p1_c1_c1_val3 p1_c1_c1_val2 p1_c1_c1_val1 LOG: available indexes for IndexScan(p1_c1_c2): p1_c1_c2_val3 p1_c1_c2_val2 p1_c1_c2_val1 LOG: available indexes for IndexScan(p1_c3_c1): p1_c3_c1_val3 p1_c3_c1_val2 p1_c3_c1_val1 LOG: available indexes for IndexScan(p1_c3_c2): p1_c3_c2_val3 p1_c3_c2_val2 p1_c3_c2_val1 LOG: pg_hint_plan: used hint: IndexScan(p1 p1_val2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------- Append -> Append -> Index Scan using p1_val3 on p1 p1_1 Index Cond: (val < 1000) -> Index Scan using p1_c1_val3 on p1_c1 p1_2 Index Cond: (val < 1000) -> Index Scan using p1_c2_val3 on p1_c2 p1_3 Index Cond: (val < 1000) -> Index Scan using p1_c3_val3 on p1_c3 p1_4 Index Cond: (val < 1000) -> Index Scan using p1_c4_val3 on p1_c4 p1_5 Index Cond: (val < 1000) -> Index Scan using p1_c1_c1_val3 on p1_c1_c1 p1_6 Index Cond: (val < 1000) -> Index Scan using p1_c1_c2_val3 on p1_c1_c2 p1_7 Index Cond: (val < 1000) -> Index Scan using p1_c3_c1_val3 on p1_c3_c1 p1_8 Index Cond: (val < 1000) -> Index Scan using p1_c3_c2_val3 on p1_c3_c2 p1_9 Index Cond: (val < 1000) -> Result -> Append -> Seq Scan on p2 p2_1 Filter: (id < 1000) -> Seq Scan on p2_c1 p2_2 Filter: (id < 1000) -> Seq Scan on p2_c2 p2_3 Filter: (id < 1000) -> Seq Scan on p2_c3 p2_4 Filter: (id < 1000) -> Seq Scan on p2_c4 p2_5 Filter: (id < 1000) -> Seq Scan on p2_c1_c1 p2_6 Filter: (id < 1000) -> Seq Scan on p2_c1_c2 p2_7 Filter: (id < 1000) -> Seq Scan on p2_c3_c1 p2_8 Filter: (id < 1000) -> Seq Scan on p2_c3_c2 p2_9 Filter: (id < 1000) (40 rows) /*+ IndexScan(p1 p1_val2) IndexScan(p2 p2_id_val_idx) */ EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION ALL SELECT val::int FROM p2 WHERE id < 1000; LOG: available indexes for IndexScan(p1): p1_val3 p1_val2 p1_val1 LOG: available indexes for IndexScan(p1_c1): p1_c1_val3 p1_c1_val2 p1_c1_val1 LOG: available indexes for IndexScan(p1_c2): p1_c2_val3 p1_c2_val2 p1_c2_val1 LOG: available indexes for IndexScan(p1_c3): p1_c3_val3 p1_c3_val2 p1_c3_val1 LOG: available indexes for IndexScan(p1_c4): p1_c4_val3 p1_c4_val2 p1_c4_val1 LOG: available indexes for IndexScan(p1_c1_c1): p1_c1_c1_val3 p1_c1_c1_val2 p1_c1_c1_val1 LOG: available indexes for IndexScan(p1_c1_c2): p1_c1_c2_val3 p1_c1_c2_val2 p1_c1_c2_val1 LOG: available indexes for IndexScan(p1_c3_c1): p1_c3_c1_val3 p1_c3_c1_val2 p1_c3_c1_val1 LOG: available indexes for IndexScan(p1_c3_c2): p1_c3_c2_val3 p1_c3_c2_val2 p1_c3_c2_val1 LOG: available indexes for IndexScan(p2): p2_id_val_idx LOG: available indexes for IndexScan(p2_c1): p2_c1_id_val_idx LOG: available indexes for IndexScan(p2_c2): p2_c2_id_val_idx LOG: available indexes for IndexScan(p2_c3): p2_c3_id_val_idx LOG: available indexes for IndexScan(p2_c4): p2_c4_id_val_idx LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_id_val_idx LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_id_val_idx LOG: available indexes for IndexScan(p2_c3_c1): p2_c3_c1_id_val_idx LOG: available indexes for IndexScan(p2_c3_c2): p2_c3_c2_id_val_idx LOG: pg_hint_plan: used hint: IndexScan(p1 p1_val2) IndexScan(p2 p2_id_val_idx) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------- Append -> Append -> Index Scan using p1_val3 on p1 p1_1 Index Cond: (val < 1000) -> Index Scan using p1_c1_val3 on p1_c1 p1_2 Index Cond: (val < 1000) -> Index Scan using p1_c2_val3 on p1_c2 p1_3 Index Cond: (val < 1000) -> Index Scan using p1_c3_val3 on p1_c3 p1_4 Index Cond: (val < 1000) -> Index Scan using p1_c4_val3 on p1_c4 p1_5 Index Cond: (val < 1000) -> Index Scan using p1_c1_c1_val3 on p1_c1_c1 p1_6 Index Cond: (val < 1000) -> Index Scan using p1_c1_c2_val3 on p1_c1_c2 p1_7 Index Cond: (val < 1000) -> Index Scan using p1_c3_c1_val3 on p1_c3_c1 p1_8 Index Cond: (val < 1000) -> Index Scan using p1_c3_c2_val3 on p1_c3_c2 p1_9 Index Cond: (val < 1000) -> Result -> Append -> Index Scan using p2_id_val_idx on p2 p2_1 Index Cond: (id < 1000) -> Index Scan using p2_c1_id_val_idx on p2_c1 p2_2 Index Cond: (id < 1000) -> Index Scan using p2_c2_id_val_idx on p2_c2 p2_3 Index Cond: (id < 1000) -> Index Scan using p2_c3_id_val_idx on p2_c3 p2_4 Index Cond: (id < 1000) -> Index Scan using p2_c4_id_val_idx on p2_c4 p2_5 Index Cond: (id < 1000) -> Index Scan using p2_c1_c1_id_val_idx on p2_c1_c1 p2_6 Index Cond: (id < 1000) -> Index Scan using p2_c1_c2_id_val_idx on p2_c1_c2 p2_7 Index Cond: (id < 1000) -> Index Scan using p2_c3_c1_id_val_idx on p2_c3_c1 p2_8 Index Cond: (id < 1000) -> Index Scan using p2_c3_c2_id_val_idx on p2_c3_c2 p2_9 Index Cond: (id < 1000) (40 rows) -- union all case EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION SELECT val::int FROM p2 WHERE id < 1000; QUERY PLAN --------------------------------------------------- HashAggregate Group Key: p1.val -> Append -> Append -> Seq Scan on p1 p1_1 Filter: (val < 1000) -> Seq Scan on p1_c1 p1_2 Filter: (val < 1000) -> Seq Scan on p1_c2 p1_3 Filter: (val < 1000) -> Seq Scan on p1_c3 p1_4 Filter: (val < 1000) -> Seq Scan on p1_c4 p1_5 Filter: (val < 1000) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val < 1000) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val < 1000) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val < 1000) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val < 1000) -> Result -> Append -> Seq Scan on p2 p2_1 Filter: (id < 1000) -> Seq Scan on p2_c1 p2_2 Filter: (id < 1000) -> Seq Scan on p2_c2 p2_3 Filter: (id < 1000) -> Seq Scan on p2_c3 p2_4 Filter: (id < 1000) -> Seq Scan on p2_c4 p2_5 Filter: (id < 1000) -> Seq Scan on p2_c1_c1 p2_6 Filter: (id < 1000) -> Seq Scan on p2_c1_c2 p2_7 Filter: (id < 1000) -> Seq Scan on p2_c3_c1 p2_8 Filter: (id < 1000) -> Seq Scan on p2_c3_c2 p2_9 Filter: (id < 1000) (42 rows) /*+ IndexScan(p2 p2_id_val_idx) */ EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION SELECT val::int FROM p2 WHERE id < 1000; LOG: available indexes for IndexScan(p2): p2_id_val_idx LOG: available indexes for IndexScan(p2_c1): p2_c1_id_val_idx LOG: available indexes for IndexScan(p2_c2): p2_c2_id_val_idx LOG: available indexes for IndexScan(p2_c3): p2_c3_id_val_idx LOG: available indexes for IndexScan(p2_c4): p2_c4_id_val_idx LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_id_val_idx LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_id_val_idx LOG: available indexes for IndexScan(p2_c3_c1): p2_c3_c1_id_val_idx LOG: available indexes for IndexScan(p2_c3_c2): p2_c3_c2_id_val_idx LOG: pg_hint_plan: used hint: IndexScan(p2 p2_id_val_idx) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------- HashAggregate Group Key: p1.val -> Append -> Append -> Seq Scan on p1 p1_1 Filter: (val < 1000) -> Seq Scan on p1_c1 p1_2 Filter: (val < 1000) -> Seq Scan on p1_c2 p1_3 Filter: (val < 1000) -> Seq Scan on p1_c3 p1_4 Filter: (val < 1000) -> Seq Scan on p1_c4 p1_5 Filter: (val < 1000) -> Seq Scan on p1_c1_c1 p1_6 Filter: (val < 1000) -> Seq Scan on p1_c1_c2 p1_7 Filter: (val < 1000) -> Seq Scan on p1_c3_c1 p1_8 Filter: (val < 1000) -> Seq Scan on p1_c3_c2 p1_9 Filter: (val < 1000) -> Result -> Append -> Index Scan using p2_id_val_idx on p2 p2_1 Index Cond: (id < 1000) -> Index Scan using p2_c1_id_val_idx on p2_c1 p2_2 Index Cond: (id < 1000) -> Index Scan using p2_c2_id_val_idx on p2_c2 p2_3 Index Cond: (id < 1000) -> Index Scan using p2_c3_id_val_idx on p2_c3 p2_4 Index Cond: (id < 1000) -> Index Scan using p2_c4_id_val_idx on p2_c4 p2_5 Index Cond: (id < 1000) -> Index Scan using p2_c1_c1_id_val_idx on p2_c1_c1 p2_6 Index Cond: (id < 1000) -> Index Scan using p2_c1_c2_id_val_idx on p2_c1_c2 p2_7 Index Cond: (id < 1000) -> Index Scan using p2_c3_c1_id_val_idx on p2_c3_c1 p2_8 Index Cond: (id < 1000) -> Index Scan using p2_c3_c2_id_val_idx on p2_c3_c2 p2_9 Index Cond: (id < 1000) (42 rows) /*+ IndexScan(p1 p1_val2) IndexScan(p2 p2_id_val_idx) */ EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION SELECT val::int FROM p2 WHERE id < 1000; LOG: available indexes for IndexScan(p1): p1_val3 p1_val2 p1_val1 LOG: available indexes for IndexScan(p1_c1): p1_c1_val3 p1_c1_val2 p1_c1_val1 LOG: available indexes for IndexScan(p1_c2): p1_c2_val3 p1_c2_val2 p1_c2_val1 LOG: available indexes for IndexScan(p1_c3): p1_c3_val3 p1_c3_val2 p1_c3_val1 LOG: available indexes for IndexScan(p1_c4): p1_c4_val3 p1_c4_val2 p1_c4_val1 LOG: available indexes for IndexScan(p1_c1_c1): p1_c1_c1_val3 p1_c1_c1_val2 p1_c1_c1_val1 LOG: available indexes for IndexScan(p1_c1_c2): p1_c1_c2_val3 p1_c1_c2_val2 p1_c1_c2_val1 LOG: available indexes for IndexScan(p1_c3_c1): p1_c3_c1_val3 p1_c3_c1_val2 p1_c3_c1_val1 LOG: available indexes for IndexScan(p1_c3_c2): p1_c3_c2_val3 p1_c3_c2_val2 p1_c3_c2_val1 LOG: available indexes for IndexScan(p2): p2_id_val_idx LOG: available indexes for IndexScan(p2_c1): p2_c1_id_val_idx LOG: available indexes for IndexScan(p2_c2): p2_c2_id_val_idx LOG: available indexes for IndexScan(p2_c3): p2_c3_id_val_idx LOG: available indexes for IndexScan(p2_c4): p2_c4_id_val_idx LOG: available indexes for IndexScan(p2_c1_c1): p2_c1_c1_id_val_idx LOG: available indexes for IndexScan(p2_c1_c2): p2_c1_c2_id_val_idx LOG: available indexes for IndexScan(p2_c3_c1): p2_c3_c1_id_val_idx LOG: available indexes for IndexScan(p2_c3_c2): p2_c3_c2_id_val_idx LOG: pg_hint_plan: used hint: IndexScan(p1 p1_val2) IndexScan(p2 p2_id_val_idx) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------- HashAggregate Group Key: p1.val -> Append -> Append -> Index Scan using p1_val3 on p1 p1_1 Index Cond: (val < 1000) -> Index Scan using p1_c1_val3 on p1_c1 p1_2 Index Cond: (val < 1000) -> Index Scan using p1_c2_val3 on p1_c2 p1_3 Index Cond: (val < 1000) -> Index Scan using p1_c3_val3 on p1_c3 p1_4 Index Cond: (val < 1000) -> Index Scan using p1_c4_val3 on p1_c4 p1_5 Index Cond: (val < 1000) -> Index Scan using p1_c1_c1_val3 on p1_c1_c1 p1_6 Index Cond: (val < 1000) -> Index Scan using p1_c1_c2_val3 on p1_c1_c2 p1_7 Index Cond: (val < 1000) -> Index Scan using p1_c3_c1_val3 on p1_c3_c1 p1_8 Index Cond: (val < 1000) -> Index Scan using p1_c3_c2_val3 on p1_c3_c2 p1_9 Index Cond: (val < 1000) -> Result -> Append -> Index Scan using p2_id_val_idx on p2 p2_1 Index Cond: (id < 1000) -> Index Scan using p2_c1_id_val_idx on p2_c1 p2_2 Index Cond: (id < 1000) -> Index Scan using p2_c2_id_val_idx on p2_c2 p2_3 Index Cond: (id < 1000) -> Index Scan using p2_c3_id_val_idx on p2_c3 p2_4 Index Cond: (id < 1000) -> Index Scan using p2_c4_id_val_idx on p2_c4 p2_5 Index Cond: (id < 1000) -> Index Scan using p2_c1_c1_id_val_idx on p2_c1_c1 p2_6 Index Cond: (id < 1000) -> Index Scan using p2_c1_c2_id_val_idx on p2_c1_c2 p2_7 Index Cond: (id < 1000) -> Index Scan using p2_c3_c1_id_val_idx on p2_c3_c1 p2_8 Index Cond: (id < 1000) -> Index Scan using p2_c3_c2_id_val_idx on p2_c3_c2 p2_9 Index Cond: (id < 1000) (42 rows) -- -- Rows hint tests -- -- Explain result includes "Planning time" if COSTS is enabled, but -- this test needs it enabled for get rows count. So do tests via psql -- and grep -v the mutable line. -- Parse error check /*+ Rows() */ SELECT 1; INFO: pg_hint_plan: hint syntax error at or near " " DETAIL: Rows hint needs at least one relation followed by one correction term. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows() ?column? ---------- 1 (1 row) /*+ Rows(x) */ SELECT 1; INFO: pg_hint_plan: hint syntax error at or near " " DETAIL: Rows hint needs at least one relation followed by one correction term. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows() ?column? ---------- 1 (1 row) -- value types SELECT explain_filter(' EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) SELECT explain_filter(' /*+ Rows(t1 t2 #99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #99) not used hint: duplication hint: error hint: CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=99 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) SELECT explain_filter(' /*+ Rows(t1 t2 +99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); LOG: pg_hint_plan: used hint: Rows(t1 t2 +99) not used hint: duplication hint: error hint: CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1099 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) SELECT explain_filter(' /*+ Rows(t1 t2 -99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); LOG: pg_hint_plan: used hint: Rows(t1 t2 -99) not used hint: duplication hint: error hint: CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=901 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) SELECT explain_filter(' /*+ Rows(t1 t2 *99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); LOG: pg_hint_plan: used hint: Rows(t1 t2 *99) not used hint: duplication hint: error hint: CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=99000 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) SELECT explain_filter(' /*+ Rows(t1 t2 *0.01) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); LOG: pg_hint_plan: used hint: Rows(t1 t2 *0.01) not used hint: duplication hint: error hint: CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=10 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) SELECT explain_filter(' /*+ Rows(t1 t2 #aa) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); -- ERROR '); INFO: pg_hint_plan: hint syntax error at or near "aa" DETAIL: Rows hint requires valid number as rows estimation. CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 t2 #aa) CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) SELECT explain_filter(' /*+ Rows(t1 t2 /99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); -- ERROR '); INFO: pg_hint_plan: hint syntax error at or near "/99" DETAIL: Unrecognized rows value type notation. CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 t2 /99) CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) -- round up to 1 SELECT explain_filter(' /*+ Rows(t1 t2 -99999) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); WARNING: Force estimate to be at least one row, to avoid possible divide-by-zero when interpolating costs : Rows(t1 t2 -99999) CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement LOG: pg_hint_plan: used hint: Rows(t1 t2 -99999) not used hint: duplication hint: error hint: CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) (4 rows) -- complex join tree SELECT explain_filter(' EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); '); explain_filter ---------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=10 width=xxx) Merge Cond: (t1.id = t3.id) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t3.id -> Seq Scan on t3 (cost=xxx..xxx rows=100 width=xxx) (9 rows) SELECT explain_filter(' /*+ Rows(t1 t2 #22) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #22) not used hint: duplication hint: error hint: CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.id = t3.id) -> Merge Join (cost=xxx..xxx rows=22 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t3.id -> Seq Scan on t3 (cost=xxx..xxx rows=100 width=xxx) (9 rows) SELECT explain_filter(' /*+ Rows(t1 t3 *10) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); '); LOG: pg_hint_plan: used hint: Rows(t1 t3 *10) not used hint: duplication hint: error hint: CONTEXT: PL/pgSQL function explain_filter(text) line 5 at FOR over EXECUTE statement explain_filter ---------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.id = t3.id) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (t1.id = t2.id) -> Index Scan using t1_pkey on t1 (cost=xxx..xxx rows=10000 width=xxx) -> Index Scan using t2_pkey on t2 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t3.id -> Seq Scan on t3 (cost=xxx..xxx rows=100 width=xxx) (9 rows) -- Query with join RTE and outer-join relids /*+Leading(ft_1 ft_2 t1)*/ SELECT relname, seq_scan > 0 AS seq_scan, idx_scan > 0 AS idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 't1'; LOG: pg_hint_plan: used hint: not used hint: Leading(ft_1 ft_2 t1) duplication hint: error hint: relname | seq_scan | idx_scan ---------+----------+---------- t1 | f | f (1 row) -- hint error level set client_min_messages to 'DEBUG1'; /*+ SeqScan( */ SELECT 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Closing parenthesis is necessary. ?column? ---------- 1 (1 row) /*+ SeqScan(t1) */ SELECT * FROM t1 LIMIT 0; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: id | val ----+----- (0 rows) set pg_hint_plan.parse_messages to 'ERROR'; -- Force an error before running the planner hook, when forcing the Set hints. /*+ Set(work_mem "foo") */ SELECT 1; ERROR: invalid value for parameter "work_mem": "foo" /*+ SeqScan(t1) */ SELECT * FROM t1 LIMIT 0; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: id | val ----+----- (0 rows) set pg_hint_plan.message_level to 'DEBUG1'; set pg_hint_plan.parse_messages to 'NOTICE'; /*+ SeqScan( */ SELECT 1; NOTICE: pg_hint_plan: hint syntax error at or near "" DETAIL: Closing parenthesis is necessary. ?column? ---------- 1 (1 row) /*+ SeqScan(t1) */ SELECT * FROM t1 LIMIT 0; DEBUG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: id | val ----+----- (0 rows) -- all hint types together /*+ SeqScan(t1) MergeJoin(t1 t2) Leading(t1 t2) Rows(t1 t2 +10) Parallel(t1 8 hard) Set(random_page_cost 2.0)*/ EXPLAIN (costs off) SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); DEBUG: adjusted rows 1000 to 1010 DEBUG: pg_hint_plan: used hint: SeqScan(t1) MergeJoin(t1 t2) Leading(t1 t2) Set(random_page_cost 2.0) Rows(t1 t2 +10) Parallel(t1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t2.id = t1.id) -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t1.id -> Gather Workers Planned: 8 -> Parallel Seq Scan on t1 -> Index Scan using t3_pkey on t3 Index Cond: (id = t1.id) (11 rows) pg_hint_plan-REL17_1_7_0/expected/plpgsql.out000066400000000000000000001112421466301071500212150ustar00rootroot00000000000000-- -- Scenarios with various PL/pgsql functions -- SET search_path TO public; SET client_min_messages TO log; \set SHOW_CONTEXT always LOAD 'pg_hint_plan'; SET pg_hint_plan.debug_print TO on; SET compute_query_id = on; SHOW pg_hint_plan.enable_hint_table; pg_hint_plan.enable_hint_table -------------------------------- off (1 row) -- Internal handling of hints within plpgsql functions. -- This forces an exception, manipulating internally plpgsql_recurse_level. create or replace function test_hint_exception(level int) returns void language plpgsql as $$ begin level := level + 1; raise notice 'Execution of test_hint_exception at level %', level; if level > 1 then -- This triggers the exception below, ending execution. execute 'select ''x''::numeric'; end if; raise notice 'End of test_hint_exception at level %', level; execute 'select test_hint_exception(' || level || ')'; exception when others then end; $$; -- Having a transaction context is essential to mess up with the -- plpgsql_recurse_level. begin; select set_config('compute_query_id','off', true); set_config ------------ off (1 row) -- Show plan without hints explain (costs false) with test as (select 'z' val) select t1.val from test t1, test t2 where t1.val = t2.val; QUERY PLAN ---------------------------------- Nested Loop Join Filter: (t1.val = t2.val) CTE test -> Result -> CTE Scan on test t1 -> CTE Scan on test t2 (6 rows) -- Invoke function that internally throws an exception with two -- levels of nesting. select test_hint_exception(0); NOTICE: Execution of test_hint_exception at level 1 CONTEXT: PL/pgSQL function test_hint_exception(integer) line 4 at RAISE NOTICE: End of test_hint_exception at level 1 CONTEXT: PL/pgSQL function test_hint_exception(integer) line 9 at RAISE NOTICE: Execution of test_hint_exception at level 2 CONTEXT: PL/pgSQL function test_hint_exception(integer) line 4 at RAISE SQL statement "select test_hint_exception(1)" PL/pgSQL function test_hint_exception(integer) line 10 at EXECUTE test_hint_exception --------------------- (1 row) -- Show plan with hint, stored as an internal state of plpgsql_recurse_level. explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 'x' val) select t1.val from test t1, test t2 where t1.val = t2.val; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Merge Join Merge Cond: (t1.val = t2.val) CTE test -> Result -> Sort Sort Key: t1.val -> CTE Scan on test t1 -> Sort Sort Key: t2.val -> CTE Scan on test t2 (10 rows) -- This query should have the same plan as the first one, without hints. explain (costs false) with test as (select 'y' val) select t1.val from test t1, test t2 where t1.val = t2.val; QUERY PLAN ---------------------------------- Nested Loop Join Filter: (t1.val = t2.val) CTE test -> Result -> CTE Scan on test t1 -> CTE Scan on test t2 (6 rows) -- Again, with one level of nesting. select test_hint_exception(1); NOTICE: Execution of test_hint_exception at level 2 CONTEXT: PL/pgSQL function test_hint_exception(integer) line 4 at RAISE test_hint_exception --------------------- (1 row) -- Show plan with hint. explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 'x' val) select t1.val from test t1, test t2 where t1.val = t2.val; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Merge Join Merge Cond: (t1.val = t2.val) CTE test -> Result -> Sort Sort Key: t1.val -> CTE Scan on test t1 -> Sort Sort Key: t2.val -> CTE Scan on test t2 (10 rows) -- This query should have no hints. explain (costs false) with test as (select 'y' val) select t1.val from test t1, test t2 where t1.val = t2.val; QUERY PLAN ---------------------------------- Nested Loop Join Filter: (t1.val = t2.val) CTE test -> Result -> CTE Scan on test t1 -> CTE Scan on test t2 (6 rows) rollback; -- Still no hints used here. explain (costs false) with test as (select 'y' val) select t1.val from test t1, test t2 where t1.val = t2.val; QUERY PLAN ---------------------------------- Nested Loop Join Filter: (t1.val = t2.val) CTE test -> Result -> CTE Scan on test t1 -> CTE Scan on test t2 (6 rows) drop function test_hint_exception; -- Test hints with function using transactions internally. create table test_hint_tab (a int); -- Function called in a nested loop to check for hints. create function test_hint_queries(run int, level int) returns void language plpgsql as $$ declare c text; begin level := level + 1; -- Stopping at two levels of nesting should be sufficient.. if level > 2 then return; end if; -- Mix of queries with and without hints. The level is mixed in the -- query string to show it in the output generated. raise notice 'Execution % at level %, hash-join t2/t1 hint', run, level; execute 'explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select ' || level || ' val) select t1.val from test t1, test t2 where t1.val = t2.val;' into c; raise notice 'Execution % at level %, no hints', run, level; execute 'explain (costs false) with test as (select ' || level || ' val) select t1.val from test t1, test t2 where t1.val = t2.val;' into c; raise notice 'Execution % at level %, merge-join t1/t2 hint', run, level; execute 'explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select ' || level || ' val) select t1.val from test t1, test t2 where t1.val = t2.val;' into c; execute 'select test_hint_queries(' || run || ',' || level || ')'; end; $$; -- Entry point of this test. This executes the transaction -- commands while calling test_hint_queries in a nested loop. -- "mode" can be set to "before" or "after", to control the timing of -- the subtransaction commands launched in this procedure. create procedure test_hint_transaction(mode text) language plpgsql as $$ declare c text; begin for i in 0..3 loop if mode = 'before' then execute 'select test_hint_queries(' || i || ', 0)'; insert into test_hint_tab (a) values (i); end if; -- Mix commits and rollbacks. if i % 2 = 0 then commit; else rollback; end if; if mode = 'after' then execute 'select test_hint_queries(' || i || ', 0)'; insert into test_hint_tab (a) values (i); end if; end loop; end; $$; call test_hint_transaction('before'); NOTICE: Execution 0 at level 1, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 0 at level 1, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 0 at level 1, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 0 at level 2, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 0 at level 2, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 0 at level 2, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 1 at level 1, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 1 at level 1, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 1 at level 1, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 1 at level 2, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 1 at level 2, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 1 at level 2, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 2 at level 1, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 2 at level 1, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 2 at level 1, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 2 at level 2, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 2 at level 2, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 2 at level 2, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 3 at level 1, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 3 at level 1, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 3 at level 1, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 3 at level 2, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 3 at level 2, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE NOTICE: Execution 3 at level 2, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 7 at EXECUTE call test_hint_transaction('after'); NOTICE: Execution 0 at level 1, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 0 at level 1, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 0 at level 1, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 0 at level 2, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 0 at level 2, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 0 at level 2, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(0,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(0, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 1 at level 1, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 1 at level 1, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 1 at level 1, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 1 at level 2, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 1 at level 2, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 1 at level 2, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(1,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(1, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 2 at level 1, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 2 at level 1, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 2 at level 1, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 2 at level 2, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 2 at level 2, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 2 at level 2, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(2,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(2, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 3 at level 1, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 3 at level 1, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 3 at level 1, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 1 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 3 at level 2, hash-join t2/t1 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 11 at RAISE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 12 at EXECUTE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 3 at level 2, no hints CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 16 at RAISE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE NOTICE: Execution 3 at level 2, merge-join t1/t2 hint CONTEXT: PL/pgSQL function test_hint_queries(integer,integer) line 21 at RAISE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: CONTEXT: SQL statement "explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 2 val) select t1.val from test t1, test t2 where t1.val = t2.val;" PL/pgSQL function test_hint_queries(integer,integer) line 22 at EXECUTE SQL statement "select test_hint_queries(3,1)" PL/pgSQL function test_hint_queries(integer,integer) line 26 at EXECUTE SQL statement "select test_hint_queries(3, 0)" PL/pgSQL function test_hint_transaction(text) line 19 at EXECUTE table test_hint_tab; a --- 0 2 1 3 (4 rows) drop procedure test_hint_transaction; drop function test_hint_queries; drop table test_hint_tab; pg_hint_plan-REL17_1_7_0/expected/ut-A.out000066400000000000000000003543541466301071500203560ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; ---- ---- No.A-1-1 install ---- No.A-2-1 uninstall ---- -- No.A-1-1-3 CREATE EXTENSION pg_hint_plan; -- No.A-1-2-3 DROP EXTENSION pg_hint_plan; -- No.A-1-1-4 CREATE SCHEMA other_schema; CREATE EXTENSION pg_hint_plan SCHEMA other_schema; ERROR: extension "pg_hint_plan" must be installed in schema "hint_plan" CREATE EXTENSION pg_hint_plan; DROP SCHEMA other_schema; ---- ---- No. A-5-1 comment pattern ---- -- No. A-5-1-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-5-1-2 /* +SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-5-1-3 /*SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-5-1-4 --+SeqScan(t1) EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-5-1-5 /* /*+SeqScan(t1)*/ */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) ---- ---- No. A-5-2 hint position ---- -- No. A-5-2-1 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ----------------------------------- Index Only Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-5-2-2 EXPLAIN (COSTS false) SELECT c1, c2 AS c_2 /*+SeqScan(t1)*/ FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-5-2-3 EXPLAIN (COSTS false) SELECT c1 AS "c1"/*+SeqScan(t1)*/ FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-5-2-4 EXPLAIN (COSTS false) SELECT * /*+SeqScan(t1)*/ FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) ---- ---- No. A-6-1 hint's table definition ---- SET pg_hint_plan.enable_hint_table TO on; -- No. A-6-1-1 \d hint_plan.hints Table "hint_plan.hints" Column | Type | Collation | Nullable | Default ------------------+---------+-----------+----------+---------------------------------- id | integer | | not null | generated by default as identity query_id | bigint | | not null | application_name | text | | not null | hints | text | | not null | Indexes: "hints_pkey" PRIMARY KEY, btree (id) "hints_id_and_app" UNIQUE, btree (query_id, application_name) ---- ---- No. A-6-2 search condition ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-6-2-1 SELECT get_query_id('SELECT * FROM s1.t1 WHERE t1.c1 = 1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-6-2-2 INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', 'dummy_application_name', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) TRUNCATE hint_plan.hints; -- No. A-6-2-3 SELECT get_query_id('SELECT * FROM s1.t1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) TRUNCATE hint_plan.hints; ---- ---- No. A-6-3 number of constant ---- -- No. A-6-3-1 SELECT get_query_id('SELECT c1 FROM s1.t1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT c1 FROM s1.t1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------- Seq Scan on t1 (1 row) TRUNCATE hint_plan.hints; -- No. A-6-3-2 SELECT get_query_id('SELECT * FROM s1.t1 WHERE t1.c1 = 1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) TRUNCATE hint_plan.hints; -- No. A-6-3-3 SELECT get_query_id('SELECT * FROM s1.t1 WHERE t1.c1 = 1 OR t1.c1 = 2') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 OR t1.c1 = 0; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Seq Scan on t1 Filter: ((c1 = 1) OR (c1 = 0)) (2 rows) TRUNCATE hint_plan.hints; SET pg_hint_plan.enable_hint_table TO off; ---- ---- No. A-7-2 hint delimiter ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-7-2-1 -- No. A-7-2-2 -- No. A-7-2-3 -- No. A-7-2-4 -- No. A-7-2-5 -- No. A-7-2-6 -- No. A-7-2-7 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-8 /*+ Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-9 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off") */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-10 /*+ Set (enable_indexscan"off") Set (enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-11 /*+Set ( enable_indexscan"off")Set ( enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-12 /*+Set(enable_indexscan"off" ) Set(enable_bitmapscan"off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-13 /*+Set( enable_indexscan "off" )Set( enable_bitmapscan "off" )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-14 /*+ Set ( enable_indexscan "off" ) Set ( enable_bitmapscan "off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-15 /*+ Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-16 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off") */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-17 /*+ Set (enable_indexscan"off") Set (enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-18 /*+Set ( enable_indexscan"off")Set ( enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-19 /*+Set(enable_indexscan"off" ) Set(enable_bitmapscan"off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-20 /*+Set( enable_indexscan "off" )Set( enable_bitmapscan "off" )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-21 /*+ Set ( enable_indexscan "off" ) Set ( enable_bitmapscan "off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-22 /*+ Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-23 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off") */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-24 /*+ Set (enable_indexscan"off") Set (enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-25 /*+Set ( enable_indexscan"off")Set ( enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-26 /*+Set(enable_indexscan"off" ) Set(enable_bitmapscan"off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-27 /*+Set( enable_indexscan "off" )Set( enable_bitmapscan "off" )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-28 /*+ Set ( enable_indexscan "off" ) Set ( enable_bitmapscan "off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-29 /*+ Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-30 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off") */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-31 /*+ Set (enable_indexscan"off") Set (enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-32 /*+Set ( enable_indexscan"off")Set ( enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-33 /*+Set(enable_indexscan"off" ) Set(enable_bitmapscan"off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-34 /*+Set( enable_indexscan "off" )Set( enable_bitmapscan "off" )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-7-2-35 /*+ Set ( enable_indexscan "off" ) Set ( enable_bitmapscan "off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_bitmapscan off) Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) ---- ---- No. A-7-3 hint object pattern ---- No. A-9-2 message object pattern ---- -- No. A-7-3-1 -- No. A-9-2-1 /*+SeqScan(t)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t WHERE t.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 t Filter: (c1 = 1) (2 rows) /*+SeqScan(ttt)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ttt WHERE ttt.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(ttt) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 ttt Filter: (c1 = 1) (2 rows) /*+SeqScan("t")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t WHERE t.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 t Filter: (c1 = 1) (2 rows) /*+SeqScan("ttt")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ttt WHERE ttt.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(ttt) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 ttt Filter: (c1 = 1) (2 rows) -- No. A-7-3-2 -- No. A-9-2-2 /*+SeqScan(T)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "T" WHERE "T".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(T) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 "T" Filter: (c1 = 1) (2 rows) /*+SeqScan(TTT)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "TTT" WHERE "TTT".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(TTT) not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 "TTT" Filter: (c1 = 1) (2 rows) /*+SeqScan("T")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "T" WHERE "T".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(T) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 "T" Filter: (c1 = 1) (2 rows) /*+SeqScan("TTT")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "TTT" WHERE "TTT".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(TTT) not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 "TTT" Filter: (c1 = 1) (2 rows) -- No. A-7-3-3 -- No. A-9-2-3 /*+SeqScan(()*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "(" WHERE "(".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "()" DETAIL: Zero-length delimited string. QUERY PLAN ---------------------------------- Index Scan using t1_i1 on t1 "(" Index Cond: (c1 = 1) (2 rows) /*+SeqScan("(")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "(" WHERE "(".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan("(") not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 "(" Filter: (c1 = 1) (2 rows) -- No. A-7-3-4 -- No. A-9-2-4 /*+SeqScan())*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ")" WHERE ")".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near ")" DETAIL: SeqScan hint requires a relation. INFO: pg_hint_plan: hint syntax error at or near ")" DETAIL: Unrecognized hint keyword ")". LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan() QUERY PLAN ---------------------------------- Index Scan using t1_i1 on t1 ")" Index Cond: (c1 = 1) (2 rows) /*+SeqScan(")")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ")" WHERE ")".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(")") not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 ")" Filter: (c1 = 1) (2 rows) /*+SeqScan(")))")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ")))" WHERE ")))".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(")))") not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 ")))" Filter: (c1 = 1) (2 rows) -- No. A-7-3-5 -- No. A-9-2-5 /*+SeqScan(")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 """" WHERE """".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Unterminated quoted string. QUERY PLAN ----------------------------------- Index Scan using t1_i1 on t1 """" Index Cond: (c1 = 1) (2 rows) /*+SeqScan("""")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 """" WHERE """".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan("""") not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on t1 """" Filter: (c1 = 1) (2 rows) /*+SeqScan("""""""")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 """""""" WHERE """""""".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan("""""""") not used hint: duplication hint: error hint: QUERY PLAN ------------------------- Seq Scan on t1 """""""" Filter: (c1 = 1) (2 rows) -- No. A-7-3-6 -- No. A-9-2-6 /*+SeqScan( )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint requires a relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan() QUERY PLAN ---------------------------------- Index Scan using t1_i1 on t1 " " Index Cond: (c1 = 1) (2 rows) /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(" ") not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 " " Filter: (c1 = 1) (2 rows) /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(" ") not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 " " Filter: (c1 = 1) (2 rows) -- No. A-7-3-7 -- No. A-9-2-7 /*+SeqScan( )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint requires a relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan() QUERY PLAN ----------------------------------- Index Scan using t1_i1 on t1 " " Index Cond: (c1 = 1) (2 rows) /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(" ") not used hint: duplication hint: error hint: QUERY PLAN --------------------------- Seq Scan on t1 " " Filter: (c1 = 1) (2 rows) /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(" ") not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------- Seq Scan on t1 " " Filter: (c1 = 1) (2 rows) -- No. A-7-3-8 -- No. A-9-2-8 /*+SeqScan( )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint requires a relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan() QUERY PLAN -------------------------------- Index Scan using t1_i1 on t1 " " Index Cond: (c1 = 1) (3 rows) /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(" ") not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 " " Filter: (c1 = 1) (3 rows) /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(" ") not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 " " Filter: (c1 = 1) (5 rows) -- No. A-7-3-9 -- No. A-9-2-9 /*+SeqScan(Set)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "Set" WHERE "Set".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(Set) not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 "Set" Filter: (c1 = 1) (2 rows) /*+SeqScan("Set")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "Set" WHERE "Set".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(Set) not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 "Set" Filter: (c1 = 1) (2 rows) /*+SeqScan("Set SeqScan Leading")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "Set SeqScan Leading" WHERE "Set SeqScan Leading".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan("Set SeqScan Leading") not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------- Seq Scan on t1 "Set SeqScan Leading" Filter: (c1 = 1) (2 rows) -- No. A-7-3-10 -- No. A-9-2-10 /*+SeqScan(あ)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 あ WHERE あ.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(あ) not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on t1 "あ" Filter: (c1 = 1) (2 rows) /*+SeqScan(あいう)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 あいう WHERE あいう.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(あいう) not used hint: duplication hint: error hint: QUERY PLAN ------------------------- Seq Scan on t1 "あいう" Filter: (c1 = 1) (2 rows) /*+SeqScan("あ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 あ WHERE あ.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(あ) not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on t1 "あ" Filter: (c1 = 1) (2 rows) /*+SeqScan("あいう")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 あいう WHERE あいう.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(あいう) not used hint: duplication hint: error hint: QUERY PLAN ------------------------- Seq Scan on t1 "あいう" Filter: (c1 = 1) (2 rows) -- No. A-7-3-11 -- No. A-9-2-11 /*+SeqScan(/**/)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "/**/" WHERE "/**/".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "/**/" DETAIL: Nested block comments are not supported. INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint requires a relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan() QUERY PLAN ------------------------------------- Index Scan using t1_i1 on t1 "/**/" Index Cond: (c1 = 1) (2 rows) /*+SeqScan(/**//**//**/)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "/**//**//**/" WHERE "/**//**//**/".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "/**//**//**/" DETAIL: Nested block comments are not supported. INFO: pg_hint_plan: hint syntax error at or near "/**//**/" DETAIL: Nested block comments are not supported. INFO: pg_hint_plan: hint syntax error at or near "/**/" DETAIL: Nested block comments are not supported. INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint requires a relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan() QUERY PLAN --------------------------------------------- Index Scan using t1_i1 on t1 "/**//**//**/" Index Cond: (c1 = 1) (2 rows) -- No. A-7-3-12 -- No. A-9-2-12 /*+SeqScan("tT()"" Set/**/あ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "tT()"" Set/**/あ" WHERE "tT()"" Set/**/あ".c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "/**/" DETAIL: Nested block comments are not supported. LOG: pg_hint_plan: used hint: not used hint: SeqScan("tT()"" Setあ") duplication hint: error hint: QUERY PLAN ------------------------------------------ Index Scan using t1_i1 on t1 "tT()"" Set/**/あ" Index Cond: (c1 = 1) (3 rows) --" /*+SeqScan("tT()"" Setあ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "tT()"" Setあ" WHERE "tT()"" Setあ".c1 = 1; LOG: pg_hint_plan: used hint: SeqScan("tT()"" Setあ") not used hint: duplication hint: error hint: QUERY PLAN -------------------------- Seq Scan on t1 "tT()"" Setあ" Filter: (c1 = 1) (3 rows) -- No. A-7-3-13 -- No. A-9-2-13 /*+SeqScan(a123456789b123456789c123456789d123456789e123456789f123)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "123456789012345678901234567890123456789012345678901234" WHERE "123456789012345678901234567890123456789012345678901234".c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(a123456789b123456789c123456789d123456789e123456789f123) duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------- Index Scan using t1_i1 on t1 "123456789012345678901234567890123456789012345678901234" Index Cond: (c1 = 1) (2 rows) ---- ---- No. A-7-4 hint parse error ---- -- No. A-7-4-1 /*+Set(enable_indexscan off)Set enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)" DETAIL: Opening parenthesis is necessary. LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-7-4-2 /*+Set(enable_indexscan off)Set(enable_tidscan off Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "(enable_bitmapscan off)SeqScan(t1)" DETAIL: Zero-length delimited string. LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-7-4-3 /*+Set(enable_indexscan off)Set(enable_tidscan "off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Unterminated quoted string. LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-7-4-4 /*+Set(enable_indexscan off)SeqScan("")Set(enable_bitmapscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: pg_hint_plan: hint syntax error at or near ")Set(enable_bitmapscan off)" DETAIL: Zero-length delimited string. LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-7-4-5 /*+Set(enable_indexscan off)NoSet(enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "NoSet(enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)" DETAIL: Unrecognized hint keyword "NoSet". LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-7-4-6 /*+Set(enable_indexscan off)"Set"(enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: pg_hint_plan: hint syntax error at or near ""Set"(enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)" DETAIL: Unrecognized hint keyword ""Set"". LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-7-4-7 /*+Set(enable_indexscan off)Set(enable_tidscan /* value */off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "/*" DETAIL: Nested block comments are not supported. LOG: pg_hint_plan: used hint: SeqScan(t1) Set(enable_bitmapscan off) Set(enable_indexscan off) Set(enable_tidscan off) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) ---- ---- No. A-8-1 original GUC parameter ---- ---- Don't test postgresql itself. -- No. A-8-1-1 -- SET ROLE regress_super_user; -- SET pg_hint_plan.debug_print TO off; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- SET pg_hint_plan.enable_hint TO off; -- SET pg_hint_plan.debug_print TO on; -- SET pg_hint_plan.parse_messages TO error; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- RESET pg_hint_plan.enable_hint; -- RESET pg_hint_plan.debug_print; -- RESET pg_hint_plan.parse_messages; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- -- -- No. A-8-1-2 -- SET ROLE regress_normal_user; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- SET pg_hint_plan.enable_hint TO off; -- SET pg_hint_plan.debug_print TO on; -- SET pg_hint_plan.parse_messages TO error; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- RESET pg_hint_plan.enable_hint; -- RESET pg_hint_plan.debug_print; -- RESET pg_hint_plan.parse_messages; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- -- RESET ROLE; ---- ---- No. A-8-2 original GUC parameter pg_hint_plan.enable_hint ---- -- No. A-8-2-1 SET pg_hint_plan.debug_print TO off; SET pg_hint_plan.enable_hint TO on; SHOW pg_hint_plan.enable_hint; pg_hint_plan.enable_hint -------------------------- on (1 row) /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-8-2-2 SET pg_hint_plan.enable_hint TO off; SHOW pg_hint_plan.enable_hint; pg_hint_plan.enable_hint -------------------------- off (1 row) /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-8-2-3 -- Don't test PostgreSQL itself. -- SET pg_hint_plan.enable_hint TO DEFAULT; -- SHOW pg_hint_plan.enable_hint; -- /*+Set(enable_indexscan off)*/ -- EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-2-4 -- Don't test PostgreSQL itself -- SET pg_hint_plan.enable_hint TO enable; -- SHOW pg_hint_plan.enable_hint; ---- ---- No. A-8-3 original GUC parameter pg_hint_plan.debug_print ---- -- No. A-8-3-1 SET pg_hint_plan.enable_hint TO on; SHOW pg_hint_plan.enable_hint; pg_hint_plan.enable_hint -------------------------- on (1 row) SET pg_hint_plan.debug_print TO on; SHOW pg_hint_plan.debug_print; pg_hint_plan.debug_print -------------------------- on (1 row) /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-8-3-2 SET pg_hint_plan.debug_print TO off; SHOW pg_hint_plan.debug_print; pg_hint_plan.debug_print -------------------------- off (1 row) /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-8-3-3 SET pg_hint_plan.debug_print TO DEFAULT; SHOW pg_hint_plan.debug_print; pg_hint_plan.debug_print -------------------------- off (1 row) /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. A-8-3-4 SET pg_hint_plan.debug_print TO enable; ERROR: invalid value for parameter "pg_hint_plan.debug_print": "enable" HINT: Available values: off, on, detailed, verbose. SHOW pg_hint_plan.debug_print; pg_hint_plan.debug_print -------------------------- off (1 row) ---- ---- No. A-8-4 original GUC parameter pg_hint_plan.parse_messages ---- SET client_min_messages TO debug5; DEBUG: CommitTransaction(1) name: unnamed; blockState: STARTED; state: INPROGRESS, xid/subid/cid: 0/1/0 -- No. A-8-4-1 SET pg_hint_plan.parse_messages TO debug5; DEBUG: StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGRESS, xid/subid/cid: 0/1/0 DEBUG: CommitTransaction(1) name: unnamed; blockState: STARTED; state: INPROGRESS, xid/subid/cid: 0/1/0 SHOW pg_hint_plan.parse_messages; DEBUG: StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGRESS, xid/subid/cid: 0/1/0 DEBUG: CommitTransaction(1) name: unnamed; blockState: STARTED; state: INPROGRESS, xid/subid/cid: 0/1/0 pg_hint_plan.parse_messages ----------------------------- debug5 (1 row) /*+Set*/SELECT 1; DEBUG: StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGRESS, xid/subid/cid: 0/1/0 DEBUG: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. DEBUG: CommitTransaction(1) name: unnamed; blockState: STARTED; state: INPROGRESS, xid/subid/cid: 0/1/0 ?column? ---------- 1 (1 row) SET client_min_messages TO debug4; DEBUG: StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGRESS, xid/subid/cid: 0/1/0 /*+Set*/SELECT 1; ?column? ---------- 1 (1 row) -- No. A-8-4-2 SET pg_hint_plan.parse_messages TO debug4; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- debug4 (1 row) /*+Set*/SELECT 1; DEBUG: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) SET client_min_messages TO debug3; /*+Set*/SELECT 1; ?column? ---------- 1 (1 row) -- No. A-8-4-3 SET pg_hint_plan.parse_messages TO debug3; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- debug3 (1 row) /*+Set*/SELECT 1; DEBUG: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) SET client_min_messages TO debug2; /*+Set*/SELECT 1; ?column? ---------- 1 (1 row) -- No. A-8-4-4 SET pg_hint_plan.parse_messages TO debug2; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- debug (1 row) /*+Set*/SELECT 1; DEBUG: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) SET client_min_messages TO debug1; /*+Set*/SELECT 1; ?column? ---------- 1 (1 row) -- No. A-8-4-5 SET pg_hint_plan.parse_messages TO debug1; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- debug1 (1 row) /*+Set*/SELECT 1; DEBUG: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) SET client_min_messages TO log; /*+Set*/SELECT 1; ?column? ---------- 1 (1 row) -- No. A-8-4-6 SET pg_hint_plan.parse_messages TO log; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- log (1 row) /*+Set*/SELECT 1; LOG: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) SET client_min_messages TO info; /*+Set*/SELECT 1; ?column? ---------- 1 (1 row) -- No. A-8-4-7 SET pg_hint_plan.parse_messages TO info; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- info (1 row) /*+Set*/SELECT 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) SET client_min_messages TO notice; /*+Set*/SELECT 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) -- No. A-8-4-8 SET pg_hint_plan.parse_messages TO notice; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- notice (1 row) /*+Set*/SELECT 1; NOTICE: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) SET client_min_messages TO warning; /*+Set*/SELECT 1; ?column? ---------- 1 (1 row) -- No. A-8-4-9 SET pg_hint_plan.parse_messages TO warning; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- warning (1 row) /*+Set*/SELECT 1; WARNING: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) SET client_min_messages TO error; /*+Set*/SELECT 1; ?column? ---------- 1 (1 row) -- No. A-8-4-10 SET pg_hint_plan.parse_messages TO error; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- error (1 row) /*+Set*/SELECT 1; ERROR: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. SET client_min_messages TO error; /*+Set*/SELECT 1; ERROR: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. -- No. A-8-4-11 RESET client_min_messages; SET pg_hint_plan.parse_messages TO DEFAULT; SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- info (1 row) /*+Set*/SELECT 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Opening parenthesis is necessary. ?column? ---------- 1 (1 row) -- No. A-8-4-12 SET pg_hint_plan.parse_messages TO fatal; ERROR: invalid value for parameter "pg_hint_plan.parse_messages": "fatal" HINT: Available values: debug5, debug4, debug3, debug2, debug1, log, info, notice, warning, error. SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- info (1 row) -- No. A-8-4-13 SET pg_hint_plan.parse_messages TO panic; ERROR: invalid value for parameter "pg_hint_plan.parse_messages": "panic" HINT: Available values: debug5, debug4, debug3, debug2, debug1, log, info, notice, warning, error. SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- info (1 row) -- No. A-8-4-14 SET pg_hint_plan.parse_messages TO on; ERROR: invalid value for parameter "pg_hint_plan.parse_messages": "on" HINT: Available values: debug5, debug4, debug3, debug2, debug1, log, info, notice, warning, error. SHOW pg_hint_plan.parse_messages; pg_hint_plan.parse_messages ----------------------------- info (1 row) ---- ---- No. A-8-5 original GUC parameter pg_hint_plan.enable_hint_table ---- SELECT get_query_id('SELECT * FROM s1.t1 WHERE t1.c1 = 1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); -- No. A-8-5-1 SET pg_hint_plan.enable_hint_table TO on; SHOW pg_hint_plan.enable_hint_table; pg_hint_plan.enable_hint_table -------------------------------- on (1 row) EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-8-5-2 SET pg_hint_plan.enable_hint_table TO off; SHOW pg_hint_plan.enable_hint_table; pg_hint_plan.enable_hint_table -------------------------------- off (1 row) EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-8-5-3 SET pg_hint_plan.enable_hint_table TO DEFAULT; SHOW pg_hint_plan.enable_hint_table; pg_hint_plan.enable_hint_table -------------------------------- off (1 row) EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-8-5-4 SET pg_hint_plan.enable_hint_table TO enable; ERROR: parameter "pg_hint_plan.enable_hint_table" requires a Boolean value SHOW pg_hint_plan.enable_hint_table; pg_hint_plan.enable_hint_table -------------------------------- off (1 row) TRUNCATE hint_plan.hints; ---- ---- No. A-9-1 parse error message output ---- -- No. A-9-1-1 /*+"Set"(enable_indexscan on)*/SELECT 1; INFO: pg_hint_plan: hint syntax error at or near ""Set"(enable_indexscan on)" DETAIL: Unrecognized hint keyword ""Set"". ?column? ---------- 1 (1 row) /*+Set()(enable_indexscan on)*/SELECT 1; INFO: pg_hint_plan: hint syntax error at or near "Set()(enable_indexscan on)" DETAIL: Set hint requires name and value of GUC parameter. INFO: pg_hint_plan: hint syntax error at or near "(enable_indexscan on)" DETAIL: Unrecognized hint keyword "". ?column? ---------- 1 (1 row) /*+Set(enable_indexscan on*/SELECT 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Closing parenthesis is necessary. ?column? ---------- 1 (1 row) ---- ---- No. A-9-3 hint state output ---- SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; -- No. A-9-3-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. A-9-3-2 /*+SeqScan(no_table)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(no_table) duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-9-3-3 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) /*+TidScan(t1)BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "TidScan(t1)BitmapScan(t1)" DETAIL: Conflict scan method hint. LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: TidScan(t1) error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (5 rows) /*+TidScan(t1)BitmapScan(t1)IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "TidScan(t1)BitmapScan(t1)IndexScan(t1)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "BitmapScan(t1)IndexScan(t1)" DETAIL: Conflict scan method hint. LOG: pg_hint_plan: used hint: IndexScan(t1) not used hint: duplication hint: TidScan(t1) BitmapScan(t1) error hint: QUERY PLAN --------------------------------- Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) /*+TidScan(t1)BitmapScan(t1)IndexScan(t1)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "TidScan(t1)BitmapScan(t1)IndexScan(t1)SeqScan(t1)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "BitmapScan(t1)IndexScan(t1)SeqScan(t1)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "IndexScan(t1)SeqScan(t1)" DETAIL: Conflict scan method hint. LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: TidScan(t1) BitmapScan(t1) IndexScan(t1) error hint: QUERY PLAN ------------------------------------------------ Seq Scan on t1 Filter: ((c1 = 1) AND (ctid = '(1,1)'::tid)) (2 rows) -- No. A-9-3-4 /*+Set(enable_indexscan enable)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: parameter "enable_indexscan" requires a Boolean value LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(enable_indexscan enable) QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) ---- ---- No. A-10-1 hint state output ---- PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) DEALLOCATE p1; PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 < $1) (2 rows) DEALLOCATE p1; -- No. A-10-1-1 -- No. A-10-1-2 /*+SeqScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) DEALLOCATE p1; /*+BitmapScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < $1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < $1) (4 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < $1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < $1) (4 rows) DEALLOCATE p1; -- No. A-10-1-3 -- No. A-10-1-4 /*+SeqScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; EXPLAIN (COSTS false) EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; EXPLAIN (COSTS false) EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) DEALLOCATE p1; /*+BitmapScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < $1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < $1) (4 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; EXPLAIN (COSTS false) EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < $1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < $1) (4 rows) DEALLOCATE p1; -- No. A-10-1-5 -- No. A-10-1-6 PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) DEALLOCATE p1; PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 < $1) (2 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 < $1) (2 rows) DEALLOCATE p1; -- No. A-10-1-9 -- No. A-10-1-10 /*+SeqScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) DEALLOCATE p1; /*+BitmapScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < $1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < $1) (4 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < $1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < $1) (4 rows) DEALLOCATE p1; -- No. A-10-1-11 -- No. A-10-1-12 /*+SeqScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) DEALLOCATE p1; /*+BitmapScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < 1000) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < 1000) (4 rows) EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < $1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < $1) (4 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 < $1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 < $1) (4 rows) DEALLOCATE p1; -- No. A-10-1-13 -- No. A-10-1-14 PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) DEALLOCATE p1; PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); QUERY PLAN ----------------------- Seq Scan on t1 Filter: (c1 < 1000) (2 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 < $1) (2 rows) UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 < $1) (2 rows) DEALLOCATE p1; ---- ---- No. A-10-4 EXECUTE statement name error ---- -- No. A-10-4-1 EXECUTE p1; ERROR: prepared statement "p1" does not exist SHOW pg_hint_plan.debug_print; pg_hint_plan.debug_print -------------------------- on (1 row) ---- ---- No. A-11-5 EXECUTE statement name error ---- -- No. A-11-5-1 SELECT * FROM s1.t1 WHERE t1.c1 = 1; c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) /*+Set(enable_seqscan off)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_seqscan off) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) /*+SeqScan(t1)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) ---- ---- No. A-12-1 reset of global variable of core at the error ---- No. A-12-2 reset of global variable of original at the error ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)NestLoop(t1 t1)*/ PREPARE p1 AS SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; EXPLAIN (COSTS false) EXECUTE p1; INFO: pg_hint_plan: hint syntax error at or near "NestLoop(t1 t1)" DETAIL: Relation name "t1" is duplicated. LOG: pg_hint_plan: used hint: SeqScan(t1) MergeJoin(t1 t2) Set(enable_seqscan off) Set(geqo_threshold 100) not used hint: duplication hint: error hint: NestLoop(t1 t1) QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Sort Sort Key: t1.c1 -> Seq Scan on t1 -> Index Scan using t2_i1 on t2 (6 rows) -- No. A-12-1-1 -- No. A-12-2-1 SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | on enable_material | on enable_memoize | on enable_mergejoin | on enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) SET pg_hint_plan.parse_messages TO error; /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)NestLoop(t1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; ERROR: pg_hint_plan: hint syntax error at or near "NestLoop(t1 t1)" DETAIL: Relation name "t1" is duplicated. SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | on enable_material | on enable_memoize | on enable_mergejoin | on enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: SeqScan(t1) MergeJoin(t1 t2) Set(enable_seqscan off) Set(geqo_threshold 100) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Sort Sort Key: t1.c1 -> Seq Scan on t1 -> Index Scan using t2_i1 on t2 (6 rows) -- No. A-12-1-2 -- No. A-12-2-2 SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | on enable_material | on enable_memoize | on enable_mergejoin | on enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) SET pg_hint_plan.parse_messages TO error; /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)NestLoop(t1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; ERROR: pg_hint_plan: hint syntax error at or near "NestLoop(t1 t1)" DETAIL: Relation name "t1" is duplicated. SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | on enable_material | on enable_memoize | on enable_mergejoin | on enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Sort Sort Key: t1.c1 -> Seq Scan on t1 -> Index Scan using t2_i1 on t2 (6 rows) -- No. A-12-1-3 -- No. A-12-2-3 SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | on enable_material | on enable_memoize | on enable_mergejoin | on enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) SET pg_hint_plan.parse_messages TO error; EXPLAIN (COSTS false) EXECUTE p2; ERROR: prepared statement "p2" does not exist /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: SeqScan(t1) MergeJoin(t1 t2) Set(enable_seqscan off) Set(geqo_threshold 100) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Sort Sort Key: t1.c1 -> Seq Scan on t1 -> Index Scan using t2_i1 on t2 (6 rows) EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Sort Sort Key: t1.c1 -> Seq Scan on t1 -> Index Scan using t2_i1 on t2 (6 rows) SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | on enable_material | on enable_memoize | on enable_mergejoin | on enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) -- No. A-12-1-4 -- No. A-12-2-4 SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | on enable_material | on enable_memoize | on enable_mergejoin | on enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) SET pg_hint_plan.parse_messages TO error; EXPLAIN (COSTS false) EXECUTE p2; ERROR: prepared statement "p2" does not exist EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Sort Sort Key: t1.c1 -> Seq Scan on t1 -> Index Scan using t2_i1 on t2 (6 rows) SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | on enable_material | on enable_memoize | on enable_mergejoin | on enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) DEALLOCATE p1; SET pg_hint_plan.parse_messages TO LOG; ---- ---- No. A-12-3 effective range of the hint ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) -- No. A-12-3-1 SET enable_indexscan TO off; SET enable_mergejoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | off enable_material | on enable_memoize | on enable_mergejoin | off enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) /*+Set(enable_indexscan on)Set(geqo_threshold 100)IndexScan(t2)MergeJoin(t1 t2)Leading(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: IndexScan(t2) MergeJoin(t1 t2) Leading(t2 t1) Set(enable_indexscan on) Set(geqo_threshold 100) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t2_i1 on t2 (4 rows) SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | off enable_material | on enable_memoize | on enable_mergejoin | off enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- No. A-12-3-2 SET enable_indexscan TO off; SET enable_mergejoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | off enable_material | on enable_memoize | on enable_mergejoin | off enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) BEGIN; /*+Set(enable_indexscan on)Set(geqo_threshold 100)IndexScan(t2)MergeJoin(t1 t2)Leading(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: IndexScan(t2) MergeJoin(t1 t2) Leading(t2 t1) Set(enable_indexscan on) Set(geqo_threshold 100) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t2_i1 on t2 (4 rows) COMMIT; BEGIN; SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | off enable_material | on enable_memoize | on enable_mergejoin | off enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) COMMIT; -- No. A-12-3-3 SET enable_indexscan TO off; SET enable_mergejoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | log geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | off enable_material | on enable_memoize | on enable_mergejoin | off enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) /*+Set(enable_indexscan on)Set(geqo_threshold 100)IndexScan(t2)MergeJoin(t1 t2)Leading(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: IndexScan(t2) MergeJoin(t1 t2) Leading(t2 t1) Set(enable_indexscan on) Set(geqo_threshold 100) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t2_i1 on t2 (4 rows) \connect SET enable_indexscan TO off; SET enable_mergejoin TO off; LOAD 'pg_hint_plan'; SELECT name, setting FROM settings; name | setting --------------------------------+----------- client_min_messages | notice geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 constraint_exclusion | partition cursor_tuple_fraction | 0.1 default_statistics_target | 100 from_collapse_limit | 8 jit | on join_collapse_limit | 8 plan_cache_mode | auto recursive_worktable_factor | 10 cpu_index_tuple_cost | 0.005 cpu_operator_cost | 0.0025 cpu_tuple_cost | 0.01 effective_cache_size | 16384 jit_above_cost | 100000 jit_inline_above_cost | 500000 jit_optimize_above_cost | 500000 min_parallel_index_scan_size | 64 min_parallel_table_scan_size | 1024 parallel_setup_cost | 1000 parallel_tuple_cost | 0.1 random_page_cost | 4 seq_page_cost | 1 enable_async_append | on enable_bitmapscan | on enable_gathermerge | on enable_group_by_reordering | on enable_hashagg | on enable_hashjoin | on enable_incremental_sort | on enable_indexonlyscan | on enable_indexscan | off enable_material | on enable_memoize | on enable_mergejoin | off enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_presorted_aggregate | on enable_seqscan | on enable_sort | on enable_tidscan | on (51 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; RESET enable_indexscan; RESET enable_mergejoin; ---- ---- No. A-13 call planner recursively ---- CREATE OR REPLACE FUNCTION nested_planner(cnt int) RETURNS int AS $$ DECLARE new_cnt int; BEGIN RAISE NOTICE 'nested_planner(%)', cnt; /* 再帰終了の判断 */ IF cnt <= 1 THEN RETURN 0; END IF; SELECT /*+ IndexScan(t_1) */ nested_planner(cnt - 1) INTO new_cnt FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1 LIMIT 1; RETURN new_cnt; END; $$ LANGUAGE plpgsql IMMUTABLE; ---- ---- No. A-13-2 use hint of main query ---- --No.13-2-1 EXPLAIN (COSTS false) SELECT nested_planner(1) FROM s1.t1 t_1 ORDER BY t_1.c1; NOTICE: nested_planner(1) QUERY PLAN --------------------------------------- Index Only Scan using t1_i1 on t1 t_1 (1 row) /*+SeqScan(t_1)*/ EXPLAIN (COSTS false) SELECT nested_planner(1) FROM s1.t1 t_1 ORDER BY t_1.c1; NOTICE: nested_planner(1) LOG: pg_hint_plan: used hint: SeqScan(t_1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------- Sort Sort Key: c1 -> Seq Scan on t1 t_1 (3 rows) ---- ---- No. A-13-3 output number of times of debugging log ---- --No.13-3-1 EXPLAIN (COSTS false) SELECT nested_planner(1) FROM s1.t1 t_1 ORDER BY t_1.c1; NOTICE: nested_planner(1) QUERY PLAN --------------------------------------- Index Only Scan using t1_i1 on t1 t_1 (1 row) /*+SeqScan(t_2)*/ EXPLAIN (COSTS false) SELECT nested_planner(1) FROM s1.t1 t_1 ORDER BY t_1.c1; NOTICE: nested_planner(1) LOG: pg_hint_plan: used hint: not used hint: SeqScan(t_2) duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using t1_i1 on t1 t_1 (1 row) --No.13-3-2 EXPLAIN (COSTS false) SELECT nested_planner(2) FROM s1.t1 t_1 ORDER BY t_1.c1; NOTICE: nested_planner(2) NOTICE: nested_planner(1) LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using t1_i1 on t1 t_1 (1 row) /*+SeqScan(t_2)*/ EXPLAIN (COSTS false) SELECT nested_planner(2) FROM s1.t1 t_1 ORDER BY t_1.c1; NOTICE: nested_planner(2) NOTICE: nested_planner(1) LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: SeqScan(t_2) duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using t1_i1 on t1 t_1 (1 row) --No.13-3-3 -- -- Redefine not to use cached plan -- CREATE OR REPLACE FUNCTION nested_planner(cnt int) RETURNS int AS $$ DECLARE new_cnt int; BEGIN RAISE NOTICE 'nested_planner(%)', cnt; /* 再帰終了の判断 */ IF cnt <= 1 THEN RETURN 0; END IF; SELECT /*+ IndexScan(t_1) */ nested_planner(cnt - 1) INTO new_cnt FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1 LIMIT 1; RETURN new_cnt; END; $$ LANGUAGE plpgsql IMMUTABLE; -- The function called at the bottom desn't use a hint, the immediate -- caller level should restore its own hint. So, the first LOG from -- pg_hint_plan should use the IndexScan(t_1) hint EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1; NOTICE: nested_planner(5) NOTICE: nested_planner(4) NOTICE: nested_planner(3) NOTICE: nested_planner(2) NOTICE: nested_planner(1) LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using t1_i1 on t1 t_1 (1 row) -- The top level uses SeqScan(t_1), but the function should use only -- the hint in the function. /*+SeqScan(t_1) SeqScan(t_2)*/ EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1; NOTICE: nested_planner(5) NOTICE: nested_planner(4) NOTICE: nested_planner(3) NOTICE: nested_planner(2) NOTICE: nested_planner(1) LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: SeqScan(t_1) not used hint: SeqScan(t_2) duplication hint: error hint: QUERY PLAN -------------------------- Sort Sort Key: c1 -> Seq Scan on t1 t_1 (3 rows) ---- ---- No. A-13-4 output of debugging log on hint status ---- CREATE OR REPLACE FUNCTION recall_planner() RETURNS int AS $$ SELECT /*+ IndexScan(t_1) */t_1.c1 FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1 LIMIT 1; $$ LANGUAGE SQL IMMUTABLE; --No.13-4-1 -- recall_planner() is reduced to constant while planning using the -- hint defined in the function. Then the outer query is planned based -- on the following hint. pg_hint_plan shows the log for the function -- but the resulting explain output doesn't contain the corresponding -- plan. /*+HashJoin(t_1 t_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: HashJoin(t_1 t_2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------- Sort Sort Key: t_1.c1 -> Hash Join Hash Cond: (t_1.c1 = t_2.c1) -> Seq Scan on t1 t_1 -> Hash -> Seq Scan on t2 t_2 (7 rows) --No.13-4-2 --See description for No.13-4-1 /*+HashJoin(st_1 st_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 st_1 JOIN s1.t2 st_2 ON (st_1.c1 = st_2.c1) ORDER BY st_1.c1; LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: HashJoin(st_1 st_2) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------- Sort Sort Key: st_1.c1 -> Hash Join Hash Cond: (st_1.c1 = st_2.c1) -> Seq Scan on t1 st_1 -> Hash -> Seq Scan on t2 st_2 (7 rows) --No.13-4-3 --See description for No.13-4-1 /*+HashJoin(t_1 t_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 st_1 JOIN s1.t2 st_2 ON (st_1.c1 = st_2.c1) ORDER BY st_1.c1; LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: HashJoin(t_1 t_2) duplication hint: error hint: QUERY PLAN ---------------------------------------------- Merge Join Merge Cond: (st_1.c1 = st_2.c1) -> Index Only Scan using t1_i1 on t1 st_1 -> Sort Sort Key: st_2.c1 -> Seq Scan on t2 st_2 (6 rows) --No.13-4-4 --See description for No.13-4-1 /*+HashJoin(st_1 st_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: HashJoin(st_1 st_2) duplication hint: error hint: QUERY PLAN --------------------------------------------- Merge Join Merge Cond: (t_1.c1 = t_2.c1) -> Index Only Scan using t1_i1 on t1 t_1 -> Sort Sort Key: t_2.c1 -> Seq Scan on t2 t_2 (6 rows) --No.13-4-5 -- See description for No.13-4-1. No joins in ths plan, so -- pg_hint_plan doesn't complain on the wrongly written error hint. /*+HashJoin(t_1 t_1)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 ORDER BY t_1.c1; LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: HashJoin(t_1 t_1) duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using t1_i1 on t1 t_1 (1 row) --No.13-4-6 CREATE OR REPLACE FUNCTION recall_planner_one_t() RETURNS int AS $$ SELECT /*+ IndexScan(t_1) */t_1.c1 FROM s1.t1 t_1 ORDER BY t_1.c1 LIMIT 1; $$ LANGUAGE SQL IMMUTABLE; EXPLAIN (COSTS false) SELECT recall_planner_one_t() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Merge Join Merge Cond: (t_1.c1 = t_2.c1) -> Index Only Scan using t1_i1 on t1 t_1 -> Sort Sort Key: t_2.c1 -> Seq Scan on t2 t_2 (6 rows) /*+HashJoin(t_1 t_1)*/ EXPLAIN (COSTS false) SELECT recall_planner_one_t() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t_1 t_1)" DETAIL: Relation name "t_1" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(t_1 t_1) QUERY PLAN --------------------------------------------- Merge Join Merge Cond: (t_1.c1 = t_2.c1) -> Index Only Scan using t1_i1 on t1 t_1 -> Sort Sort Key: t_2.c1 -> Seq Scan on t2 t_2 (6 rows) DROP FUNCTION recall_planner_one_t(int); ERROR: function recall_planner_one_t(integer) does not exist --No.13-4-7 -- See description for No.13-4-1. Complains on the wrongly written hint. /*+HashJoin(t_1 t_1)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t_1 t_1)" DETAIL: Relation name "t_1" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(t_1 t_1) QUERY PLAN --------------------------------------------- Merge Join Merge Cond: (t_1.c1 = t_2.c1) -> Index Only Scan using t1_i1 on t1 t_1 -> Sort Sort Key: t_2.c1 -> Seq Scan on t2 t_2 (6 rows) --No.13-4-8 /*+MergeJoin(t_1 t_2)HashJoin(t_1 t_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; INFO: pg_hint_plan: hint syntax error at or near "MergeJoin(t_1 t_2)HashJoin(t_1 t_2)" DETAIL: Conflict join method hint. LOG: pg_hint_plan: used hint: IndexScan(t_1) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: HashJoin(t_1 t_2) not used hint: duplication hint: MergeJoin(t_1 t_2) error hint: QUERY PLAN -------------------------------------- Sort Sort Key: t_1.c1 -> Hash Join Hash Cond: (t_1.c1 = t_2.c1) -> Seq Scan on t1 t_1 -> Hash -> Seq Scan on t2 t_2 (7 rows) --No.14-1-1 plancache invalidation CREATE TABLE s1.tpc AS SELECT a FROM generate_series(0, 999) a; CREATE INDEX ON s1.tpc(a); PREPARE p1 AS SELECT * FROM s1.tpc WHERE a < 999; /*+ IndexScan(tpc) */PREPARE p2 AS SELECT * FROM s1.tpc WHERE a < 999; /*+ SeqScan(tpc) */PREPARE p3(int) AS SELECT * FROM s1.tpc WHERE a = $1; EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN --------------------- Seq Scan on tpc Filter: (a < 999) (2 rows) EXPLAIN (COSTS false) EXECUTE p2; LOG: pg_hint_plan: used hint: IndexScan(tpc) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Index Scan using tpc_a_idx on tpc Index Cond: (a < 999) (2 rows) EXPLAIN (COSTS false) EXECUTE p3(500); LOG: pg_hint_plan: used hint: SeqScan(tpc) not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on tpc Filter: (a = 500) (2 rows) -- The DROP invalidates the plan caches DROP TABLE s1.tpc; CREATE TABLE s1.tpc AS SELECT a FROM generate_series(0, 999) a; CREATE INDEX ON s1.tpc(a); EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN --------------------- Seq Scan on tpc Filter: (a < 999) (2 rows) EXPLAIN (COSTS false) EXECUTE p2; LOG: pg_hint_plan: used hint: IndexScan(tpc) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Index Scan using tpc_a_idx on tpc Index Cond: (a < 999) (2 rows) EXPLAIN (COSTS false) EXECUTE p3(500); LOG: pg_hint_plan: used hint: SeqScan(tpc) not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on tpc Filter: (a = 500) (2 rows) DEALLOCATE p1; DEALLOCATE p2; DEALLOCATE p3; DROP TABLE s1.tpc; --No.14-1-2 PREPARE query with array parameters PREPARE test_query(numeric[]) AS /*+ MergeJoin(t1 t2) */ WITH test AS (SELECT 1 AS x) SELECT t1.* FROM test t1, test t2 WHERE t1.x = ANY($1) AND t1.x = t2.x; EXPLAIN (COSTS false) EXECUTE test_query(array[1,2,3]); LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Merge Join Merge Cond: (t1.x = t2.x) CTE test -> Result -> Sort Sort Key: t1.x -> CTE Scan on test t1 Filter: ((x)::numeric = ANY ('{1,2,3}'::numeric[])) -> Sort Sort Key: t2.x -> CTE Scan on test t2 (11 rows) pg_hint_plan-REL17_1_7_0/expected/ut-G.out000066400000000000000000000762331466301071500203610ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; ---- ---- No. G-1-1 RULE definition table ---- -- No. G-1-1-1 EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (19 rows) /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t1.c1) -> Seq Scan on t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r1 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) (21 rows) EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r1_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (19 rows) /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (b1t1.c1 = b1t4.c1) -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t3.c1 = b1t1.c1) -> Seq Scan on t3 b1t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 b1t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 b1t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r1_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) (21 rows) -- No. G-1-1-2 EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (39 rows) /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t1.c1) -> Seq Scan on t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r2 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t1.c1) -> Seq Scan on t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r2 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) (43 rows) EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) (39 rows) /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (b1t1.c1 = b1t4.c1) -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t3.c1 = b1t1.c1) -> Seq Scan on t3 b1t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 b1t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 b1t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r2_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) Aggregate -> Nested Loop -> Hash Join Hash Cond: (b2t1.c1 = b2t4.c1) -> Hash Join Hash Cond: (b2t1.c1 = b2t2.c1) -> Hash Join Hash Cond: (b2t3.c1 = b2t1.c1) -> Seq Scan on t3 b2t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 b2t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 b2t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r2_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) (43 rows) -- No. G-1-1-3 EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (59 rows) /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t1.c1) -> Seq Scan on t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t1.c1) -> Seq Scan on t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t1.c1) -> Seq Scan on t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) (65 rows) EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) (59 rows) /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Set(enable_nestloop off) Set(enable_tidscan off) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (b1t1.c1 = b1t4.c1) -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t3.c1 = b1t1.c1) -> Seq Scan on t3 b1t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 b1t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 b1t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) Aggregate -> Nested Loop -> Hash Join Hash Cond: (b2t1.c1 = b2t4.c1) -> Hash Join Hash Cond: (b2t1.c1 = b2t2.c1) -> Hash Join Hash Cond: (b2t3.c1 = b2t1.c1) -> Seq Scan on t3 b2t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 b2t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 b2t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) Aggregate -> Nested Loop -> Hash Join Hash Cond: (b3t1.c1 = b3t4.c1) -> Hash Join Hash Cond: (b3t1.c1 = b3t2.c1) -> Hash Join Hash Cond: (b3t3.c1 = b3t1.c1) -> Seq Scan on t3 b3t3 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t1 b3t1 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Seq Scan on t4 b3t4 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) (65 rows) ---- ---- No. G-2-1 GUC parameter ---- -- No. G-2-1-3 /*+Set(1234567890123456789012345678901234567890123456789012345678901234 1)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; NOTICE: identifier "1234567890123456789012345678901234567890123456789012345678901234" will be truncated to "123456789012345678901234567890123456789012345678901234567890123" INFO: unrecognized configuration parameter "123456789012345678901234567890123456789012345678901234567890123" LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(123456789012345678901234567890123456789012345678901234567890123 1) c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) -- No. G-2-1-4 /*+Set(constraint_exclusion 1234567890123456789012345678901234567890123456789012345678901234)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: invalid value for parameter "constraint_exclusion": "1234567890123456789012345678901234567890123456789012345678901234" HINT: Available values: partition, on, off. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(constraint_exclusion 1234567890123456789012345678901234567890123456789012345678901234) c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) ---- ---- No. G-2-2 category of GUC parameter and role ---- -- No. G-2-2-1 SET ROLE regress_super_user; /*+Set(block_size 16384)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: parameter "block_size" cannot be changed LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(block_size 16384) c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) -- No. G-2-2-2 /*+Set(archive_mode off)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: parameter "archive_mode" cannot be changed without restarting the server LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(archive_mode off) c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) -- No. G-2-2-3 /*+Set(archive_timeout 0)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: parameter "archive_timeout" cannot be changed now LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(archive_timeout 0) c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) -- No. G-2-2-4 /*+Set(log_connections off)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: parameter "log_connections" cannot be set after connection start LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(log_connections off) c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) -- No. G-2-2-5 /*+Set(log_min_messages WARNING)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(log_min_messages WARNING) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) RESET ROLE; -- No. G-2-2-6 GRANT ALL ON SCHEMA s1 TO PUBLIC; GRANT SELECT ON ALL TABLES IN SCHEMA s1 TO regress_normal_user; SET ROLE regress_normal_user; /*+Set(log_min_messages WARNING)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; INFO: permission denied to set parameter "log_min_messages" LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Set(log_min_messages WARNING) c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) -- No. G-2-2-7 /*+Set(enable_seqscan on)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: Set(enable_seqscan on) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 ----+----+----+---- 1 | 1 | 1 | 1 (1 row) RESET ROLE; REVOKE SELECT ON ALL TABLES IN SCHEMA s1 FROM regress_normal_user; REVOKE ALL ON SCHEMA s1 FROM PUBLIC; ---- ---- No. G-2-3 conflict set hint ---- SET client_min_messages TO LOG; -- No. G-2-3-1 /*+Set(enable_indexscan on)Set(enable_indexscan off)*/ SELECT * FROM s1.t1 WHERE false; INFO: pg_hint_plan: hint syntax error at or near "Set(enable_indexscan on)Set(enable_indexscan off)" DETAIL: Conflict set hint. LOG: pg_hint_plan: used hint: Set(enable_indexscan off) not used hint: duplication hint: Set(enable_indexscan on) error hint: c1 | c2 | c3 | c4 ----+----+----+---- (0 rows) -- No. G-2-3-2 /*+Set(client_min_messages DEBUG5)Set(client_min_messages WARNING)Set(client_min_messages DEBUG2)*/ SELECT * FROM s1.t1 WHERE false; INFO: pg_hint_plan: hint syntax error at or near "Set(client_min_messages DEBUG5)Set(client_min_messages WARNING)Set(client_min_messages DEBUG2)" DETAIL: Conflict set hint. INFO: pg_hint_plan: hint syntax error at or near "Set(client_min_messages WARNING)Set(client_min_messages DEBUG2)" DETAIL: Conflict set hint. LOG: pg_hint_plan: used hint: Set(client_min_messages DEBUG2) not used hint: duplication hint: Set(client_min_messages DEBUG5) Set(client_min_messages WARNING) error hint: c1 | c2 | c3 | c4 ----+----+----+---- (0 rows) -- No. G-2-3-3 /*+Set(enable_indexscan on)Set(enable_indexscan o)*/ SELECT * FROM s1.t1 WHERE false; INFO: pg_hint_plan: hint syntax error at or near "Set(enable_indexscan on)Set(enable_indexscan o)" DETAIL: Conflict set hint. INFO: parameter "enable_indexscan" requires a Boolean value LOG: pg_hint_plan: used hint: not used hint: duplication hint: Set(enable_indexscan on) error hint: Set(enable_indexscan o) c1 | c2 | c3 | c4 ----+----+----+---- (0 rows) -- No. G-2-3-4 /*+Set(client_min_messages DEBUG5)Set(client_min_messages WARNING)Set(client_min_messages DEBU)*/ SELECT * FROM s1.t1 WHERE false; INFO: pg_hint_plan: hint syntax error at or near "Set(client_min_messages DEBUG5)Set(client_min_messages WARNING)Set(client_min_messages DEBU)" DETAIL: Conflict set hint. INFO: pg_hint_plan: hint syntax error at or near "Set(client_min_messages WARNING)Set(client_min_messages DEBU)" DETAIL: Conflict set hint. INFO: invalid value for parameter "client_min_messages": "DEBU" HINT: Available values: debug5, debug4, debug3, debug2, debug1, log, notice, warning, error. LOG: pg_hint_plan: used hint: not used hint: duplication hint: Set(client_min_messages DEBUG5) Set(client_min_messages WARNING) error hint: Set(client_min_messages DEBU) c1 | c2 | c3 | c4 ----+----+----+---- (0 rows) ---- ---- No. G-2-4 debug message ---- -- No. G-2-4-1 /*+SeqScan(a)IndexScan(a)SeqScan(c)NestLoop(a) */ SELECT * FROM s1.t1 a, s1.t2 b WHERE false; INFO: pg_hint_plan: hint syntax error at or near " " DETAIL: NestLoop hint requires at least two relations. INFO: pg_hint_plan: hint syntax error at or near "SeqScan(a)IndexScan(a)SeqScan(c)NestLoop(a) " DETAIL: Conflict scan method hint. LOG: pg_hint_plan: used hint: IndexScan(a) not used hint: SeqScan(c) duplication hint: SeqScan(a) error hint: NestLoop(a) c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+---- (0 rows) pg_hint_plan-REL17_1_7_0/expected/ut-J.out000066400000000000000000005376651466301071500203770ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; SET max_parallel_workers_per_gather TO 0; SET jit = off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) ---- ---- No. J-1-1 specified pattern of the object name ---- -- No. J-1-1-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- No. J-1-1-2 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; LOG: pg_hint_plan: used hint: not used hint: HashJoin(t1 t2) duplication hint: error hint: QUERY PLAN ---------------------------------------- Merge Join Merge Cond: (t_1.c1 = t_2.c1) -> Index Scan using t1_i1 on t1 t_1 -> Sort Sort Key: t_2.c1 -> Seq Scan on t2 t_2 (6 rows) -- No. J-1-1-3 /*+HashJoin(t_1 t_2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; LOG: pg_hint_plan: used hint: HashJoin(t_1 t_2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------- Hash Join Hash Cond: (t_1.c1 = t_2.c1) -> Seq Scan on t1 t_1 -> Hash -> Seq Scan on t2 t_2 (5 rows) ---- ---- No. J-1-2 specified schema name in the hint option ---- -- No. J-1-2-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- No. J-1-2-2 /*+HashJoin(s1.t1 s1.t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: not used hint: HashJoin(s1.t1 s1.t2) duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) ---- ---- No. J-1-3 table doesn't exist in the hint option ---- -- No. J-1-3-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- No. J-1-3-2 /*+HashJoin(t3 t4)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: not used hint: HashJoin(t3 t4) duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) ---- ---- No. J-1-4 conflict table name ---- -- No. J-1-4-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- No. J-1-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t1_1.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (6 rows) /*+HashJoin(t1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t1)" DETAIL: Relation name "t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(t1 t1) QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t1_1.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (6 rows) /*+HashJoin(s1.t1 s2.t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; LOG: pg_hint_plan: used hint: not used hint: HashJoin(s1.t1 s2.t1) duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t1_1.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (6 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = s2t1.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: s2t1.c1 -> Seq Scan on t1 s2t1 (6 rows) /*+HashJoin(t1 s2t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; LOG: pg_hint_plan: used hint: HashJoin(s2t1 t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Hash Join Hash Cond: (t1.c1 = s2t1.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t1 s2t1 (5 rows) -- No. J-1-4-3 EXPLAIN (COSTS false) SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_1.c1 = t2_1.c1) -> Index Only Scan using t1_i1 on t1 t1_1 -> Sort Sort Key: t2_1.c1 -> Seq Scan on t2 t2_1 -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (14 rows) /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) InitPlan 1 -> Aggregate -> Hash Join Hash Cond: (t1_1.c1 = t2_1.c1) -> Seq Scan on t1 t1_1 -> Hash -> Seq Scan on t2 t2_1 -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (12 rows) /*+NestLoop(st1 st2)HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT *, (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(st1 st2) HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------- Hash Join Hash Cond: (t1.c1 = t2.c1) InitPlan 1 -> Aggregate -> Nested Loop -> Seq Scan on t2 st2 -> Index Only Scan using t1_i1 on t1 st1 Index Cond: (c1 = st2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (11 rows) ---- ---- No. J-1-5 conflict table name ---- -- No. J-1-5-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- No. J-1-5-2 /*+HashJoin(t1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t1)" DETAIL: Relation name "t1" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(t1 t1) QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) -- No. J-1-5-3 /*+HashJoin(t1 t1)HashJoin(t2 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t1)HashJoin(t2 t2)" DETAIL: Relation name "t1" is duplicated. INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t2 t2)" DETAIL: Relation name "t2" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(t1 t1) HashJoin(t2 t2) QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) /*+HashJoin(t1 t2 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t2 t1 t2)" DETAIL: Relation name "t1" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(t1 t1 t2 t2) QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) ---- ---- No. J-1-6 object type for the hint ---- -- No. J-1-6-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- No. J-1-6-2 EXPLAIN (COSTS false) SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; QUERY PLAN ----------------------------------------- Hash Join Hash Cond: (t1.c1 = t2.c1) -> Append -> Seq Scan on p1 t1_1 -> Seq Scan on p1c1 t1_2 -> Seq Scan on p1c2 t1_3 -> Seq Scan on p1c3 t1_4 -> Hash -> Append -> Seq Scan on p1 t2_1 -> Seq Scan on p1c1 t2_2 -> Seq Scan on p1c2 t2_3 -> Seq Scan on p1c3 t2_4 (13 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Nested Loop -> Append -> Seq Scan on p1 t1_1 -> Seq Scan on p1c1 t1_2 -> Seq Scan on p1c2 t1_3 -> Seq Scan on p1c3 t1_4 -> Append -> Seq Scan on p1 t2_1 Filter: (t1.c1 = c1) -> Index Scan using p1c1_i on p1c1 t2_2 Index Cond: (c1 = t1.c1) -> Index Scan using p1c2_i on p1c2 t2_3 Index Cond: (c1 = t1.c1) -> Index Scan using p1c3_i on p1c3 t2_4 Index Cond: (c1 = t1.c1) (15 rows) -- No. J-1-6-3 EXPLAIN (COSTS false) SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; QUERY PLAN -------------------------------- Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on ul1 t1 -> Hash -> Seq Scan on ul1 t2 (5 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------- Nested Loop -> Seq Scan on ul1 t1 -> Index Scan using ul1_pkey on ul1 t2 Index Cond: (c1 = t1.c1) (4 rows) -- No. J-1-6-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); EXPLAIN (COSTS false) SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; QUERY PLAN -------------------------------- Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on tm1 t1 -> Hash -> Seq Scan on tm1 t2 (5 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Nested Loop -> Seq Scan on tm1 t1 -> Index Scan using tm1_c1_idx on tm1 t2 Index Cond: (c1 = t1.c1) (4 rows) -- No. J-1-6-5 EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class t1, pg_catalog.pg_class t2 WHERE t1.oid = t2.oid; QUERY PLAN ------------------------------------- Hash Join Hash Cond: (t1.oid = t2.oid) -> Seq Scan on pg_class t1 -> Hash -> Seq Scan on pg_class t2 (5 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class t1, pg_catalog.pg_class t2 WHERE t1.oid = t2.oid; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------- Nested Loop -> Seq Scan on pg_class t1 -> Index Scan using pg_class_oid_index on pg_class t2 Index Cond: (oid = t1.oid) (4 rows) -- No. J-1-6-6 -- refer ut-fdw.sql -- No. J-1-6-7 EXPLAIN (COSTS false) SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; QUERY PLAN -------------------------------- Nested Loop Join Filter: (t1.c1 = t2.c1) -> Function Scan on f1 t1 -> Function Scan on f1 t2 (4 rows) /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Function Scan on f1 t1 -> Hash -> Function Scan on f1 t2 (5 rows) -- No. J-1-6-8 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------------- Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" (5 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: not used hint: NestLoop(t1 t2) duplication hint: error hint: QUERY PLAN ------------------------------------------- Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" (5 rows) /*+NestLoop(*VALUES* t2)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(*VALUES* t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Nested Loop Join Filter: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Materialize -> Values Scan on "*VALUES*" (5 rows) -- No. J-1-6-9 EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = c1.c1; QUERY PLAN ---------------------------------------------------------- Nested Loop -> Aggregate -> Merge Join Merge Cond: (t1_1.c1 = t2.c1) -> Index Only Scan using t1_i1 on t1 t1_1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = (max(t1_1.c1))) (10 rows) /*+NestLoop(t1 t2)HashJoin(t1 c1)*/ EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = c1.c1; LOG: pg_hint_plan: used hint: HashJoin(c1 t1) NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------- Hash Join Hash Cond: (t1.c1 = (max(t1_1.c1))) -> Seq Scan on t1 -> Hash -> Aggregate -> Nested Loop -> Seq Scan on t2 -> Index Only Scan using t1_i1 on t1 t1_1 Index Cond: (c1 = t2.c1) (9 rows) -- No. J-1-6-10 EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 (5 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: not used hint: NestLoop(t1 t2) duplication hint: error hint: QUERY PLAN ------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 (5 rows) /*+NestLoop(v1t1 v1t1_)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1_ t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(v1t1 v1t1_) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Seq Scan on t1 v1t1 -> Index Scan using t1_i1 on t1 v1t1_ Index Cond: (c1 = v1t1.c1) (4 rows) -- No. J-1-6-11 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.c1 = (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1); QUERY PLAN ----------------------------------------------------------- Nested Loop InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (st1.c1 = st2.c1) -> Index Only Scan using t1_i1 on t1 st1 -> Sort Sort Key: st2.c1 -> Seq Scan on t2 st2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = (InitPlan 1).col1) -> Seq Scan on t2 Filter: (c1 = (InitPlan 1).col1) (13 rows) SELECT explain_filter(' /*+MergeJoin(t1 t2)NestLoop(st1 st2)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.c1 = (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1); '); LOG: pg_hint_plan: used hint: NestLoop(st1 st2) MergeJoin(t1 t2) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: NestLoop(st1 st2) MergeJoin(t1 t2) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: NestLoop(st1 st2) MergeJoin(t1 t2) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: NestLoop(st1 st2) MergeJoin(t1 t2) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: NestLoop(st1 st2) MergeJoin(t1 t2) duplication hint: error hint: explain_filter --------------------------------------------------------------------------------------------- Nested Loop (cost={inf}..{inf} rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 st2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 st1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = st2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = (InitPlan 1).col1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (c1 = (InitPlan 1).col1) (11 rows) -- -- There are cases where difference in the measured value and predicted value -- depending upon the version of PostgreSQL -- EXPLAIN (COSTS false) SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) /*+HashJoin(t1 st2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; LOG: pg_hint_plan: used hint: not used hint: HashJoin(st2 t1) duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) ---- ---- No. J-2-1 some complexity query blocks ---- -- No. J-2-1-1 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; QUERY PLAN ------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (47 rows) /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t4.c1 = b1t2.c1) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t2.c1 = b1t3.c1) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t3.c1 -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Hash Join Hash Cond: (b2t1.c1 = b2t3.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b2t3.c1 = b2t4.c1) -> Sort Sort Key: b2t3.c1 -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t4.c1 -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Hash Join Hash Cond: (bmt3.c1 = bmt1.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Sort Sort Key: bmt1.c1 -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (62 rows) -- No. J-2-1-2 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; QUERY PLAN ------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 3 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (63 rows) /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t4.c1 = b1t2.c1) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t2.c1 = b1t3.c1) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t3.c1 -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Hash Join Hash Cond: (b2t1.c1 = b2t3.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b2t3.c1 = b2t4.c1) -> Sort Sort Key: b2t3.c1 -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t4.c1 -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 3 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Hash Join Hash Cond: (b3t2.c1 = b3t1.c1) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b3t1.c1 = b3t4.c1) -> Sort Sort Key: b3t1.c1 -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b3t4.c1 -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Hash Join Hash Cond: (bmt3.c1 = bmt1.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Sort Sort Key: bmt1.c1 -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (83 rows) -- No. J-2-1-3 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (15 rows) /*+ Leading(bmt4 bmt3 bmt2 bmt1) MergeJoin(bmt4 bmt3)HashJoin(bmt4 bmt3 bmt2)NestLoop(bmt1 bmt2 bmt3 bmt4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: MergeJoin(bmt3 bmt4) HashJoin(bmt2 bmt3 bmt4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt4 bmt3 bmt2 bmt1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Hash Join Hash Cond: (bmt2.c1 = bmt3.c1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt3.c1 = bmt4.c1) -> Sort Sort Key: bmt3.c1 -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: bmt4.c1 -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) (20 rows) -- No. J-2-1-4 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = sbmt2.c1 AND sbmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (15 rows) /*+ Leading(bmt4 bmt3 bmt2 bmt1) MergeJoin(bmt4 bmt3)HashJoin(bmt4 bmt3 bmt2)NestLoop(bmt1 bmt2 bmt3 bmt4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = sbmt2.c1 AND sbmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: MergeJoin(bmt3 bmt4) HashJoin(bmt2 bmt3 bmt4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt4 bmt3 bmt2 bmt1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Hash Join Hash Cond: (bmt2.c1 = bmt3.c1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt3.c1 = bmt4.c1) -> Sort Sort Key: bmt3.c1 -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: bmt4.c1 -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) (20 rows) -- No. J-2-1-5 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) ; QUERY PLAN --------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1)) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (48 rows) /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t4.c1 = b1t2.c1) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t2.c1 = b1t3.c1) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t3.c1 -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Hash Join Hash Cond: (b2t1.c1 = b2t3.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b2t3.c1 = b2t4.c1) -> Sort Sort Key: b2t3.c1 -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t4.c1 -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Hash Join Hash Cond: (bmt3.c1 = bmt1.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Sort Sort Key: bmt1.c1 -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1)) -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (63 rows) -- No. J-2-1-6 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 3 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1) AND (c1 <> (InitPlan 3).col1)) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (64 rows) /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t4.c1 = b1t2.c1) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t2.c1 = b1t3.c1) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t3.c1 -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Hash Join Hash Cond: (b2t1.c1 = b2t3.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b2t3.c1 = b2t4.c1) -> Sort Sort Key: b2t3.c1 -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t4.c1 -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 3 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Hash Join Hash Cond: (b3t2.c1 = b3t1.c1) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b3t1.c1 = b3t4.c1) -> Sort Sort Key: b3t1.c1 -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b3t4.c1 -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Hash Join Hash Cond: (bmt3.c1 = bmt1.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Sort Sort Key: bmt1.c1 -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1) AND (c1 <> (InitPlan 3).col1)) -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (84 rows) -- No. J-2-1-7 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; QUERY PLAN ----------------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = (max(b2t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) (49 rows) /*+ Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(c2 c1)HashJoin(c2 c1 bmt1)NestLoop(c2 c1 bmt1 bmt2)MergeJoin(c2 c1 bmt1 bmt2 bmt3)HashJoin(c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(c1 c2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 c1 c2) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 c1 c2) MergeJoin(bmt1 bmt2 bmt3 c1 c2) HashJoin(bmt1 bmt2 bmt3 bmt4 c1 c2) Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- Aggregate -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt1.c1 = bmt3.c1) -> Sort Sort Key: bmt1.c1 -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Hash Join Hash Cond: (bmt1.c1 = (max(b1t1.c1))) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: ((max(b1t1.c1)) = (max(b2t1.c1))) -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t4.c1 = b1t2.c1) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t2.c1 = b1t3.c1) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t3.c1 -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b2t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Hash Join Hash Cond: (b2t1.c1 = b2t3.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b2t3.c1 = b2t4.c1) -> Sort Sort Key: b2t3.c1 -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t4.c1 -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: bmt3.c1 -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) (69 rows) -- No. J-2-1-8 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1 ; QUERY PLAN ----------------------------------------------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = (max(b3t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Merge Join Merge Cond: ((max(b1t1.c1)) = (max(b2t1.c1))) -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b2t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) (70 rows) /*+ Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(c3 c2)HashJoin(c3 c2 c1)NestLoop(c3 c2 c1 bmt1)MergeJoin(c3 c2 c1 bmt1 bmt2)HashJoin(c3 c2 c1 bmt1 bmt2 bmt3)NestLoop(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1 ; LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(c2 c3) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(c1 c2 c3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 c1 c2 c3) MergeJoin(bmt1 bmt2 c1 c2 c3) HashJoin(bmt1 bmt2 bmt3 c1 c2 c3) NestLoop(bmt1 bmt2 bmt3 bmt4 c1 c2 c3) Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Hash Join Hash Cond: (bmt3.c1 = bmt1.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Sort Sort Key: bmt1.c1 -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Hash Join Hash Cond: ((max(b2t1.c1)) = (max(b1t1.c1))) -> Merge Join Merge Cond: ((max(b2t1.c1)) = (max(b3t1.c1))) -> Sort Sort Key: (max(b2t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Hash Join Hash Cond: (b2t1.c1 = b2t3.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b2t3.c1 = b2t4.c1) -> Sort Sort Key: b2t3.c1 -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t4.c1 -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b3t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Hash Join Hash Cond: (b3t2.c1 = b3t1.c1) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b3t1.c1 = b3t4.c1) -> Sort Sort Key: b3t1.c1 -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b3t4.c1 -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t4.c1 = b1t2.c1) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t2.c1 = b1t3.c1) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t3.c1 -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (91 rows) ---- ---- No. J-2-2 the number of the tables per quiry block ---- -- No. J-2-2-1 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 4).col1) AND (c1 = 1)) -> Result One-Time Filter: ((InitPlan 5).col1 = 1) InitPlan 5 -> Limit -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (26 rows) /*+ Leading(c1 bmt1) HashJoin(bmt1 c1) HashJoin(b1t1 c1) HashJoin(b2t1 c1) HashJoin(b3t1 c1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; LOG: pg_hint_plan: used hint: HashJoin(bmt1 c1) Leading(c1 bmt1) not used hint: HashJoin(b1t1 c1) HashJoin(b2t1 c1) HashJoin(b3t1 c1) duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 4).col1) AND (c1 = 1)) -> Result One-Time Filter: ((InitPlan 5).col1 = 1) InitPlan 5 -> Limit -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (26 rows) -- No. J-2-2-2 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) (33 rows) /*+ Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) MergeJoin(c1 bmt2) HashJoin(c1 bmt1 bmt2) MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) MergeJoin(bmt2 c1) HashJoin(bmt1 bmt2 c1) Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Sort Sort Key: b2t1.c1 -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (b3t1.c1 = b3t2.c1) -> Sort Sort Key: b3t1.c1 -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b3t2.c1 -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Hash Join Hash Cond: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) -> Hash -> Merge Join Merge Cond: (bmt2.c1 = (max(b1t1.c1))) -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Sort Sort Key: b1t1.c1 -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) (50 rows) -- No. J-2-2-3 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (65 rows) /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) HashJoin(b1t4 b1t3) NestLoop(b1t4 b1t3 b1t2) MergeJoin(b1t4 b1t3 b1t2 b1t1) HashJoin(b2t4 b2t3) NestLoop(b2t4 b2t3 b2t2) MergeJoin(b2t4 b2t3 b2t2 b2t1) HashJoin(b3t4 b3t3) NestLoop(b3t4 b3t3 b3t2) MergeJoin(b3t4 b3t3 b3t2 b3t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: HashJoin(b1t3 b1t4) HashJoin(b2t3 b2t4) HashJoin(b3t3 b3t4) MergeJoin(bmt4 c1) NestLoop(b1t2 b1t3 b1t4) NestLoop(b2t2 b2t3 b2t4) NestLoop(b3t2 b3t3 b3t4) HashJoin(bmt3 bmt4 c1) MergeJoin(b1t1 b1t2 b1t3 b1t4) MergeJoin(b2t1 b2t2 b2t3 b2t4) MergeJoin(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt2 bmt3 bmt4 c1) MergeJoin(bmt1 bmt2 bmt3 bmt4 c1) Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (b2t2.c1 = b2t1.c1) -> Sort Sort Key: b2t2.c1 -> Nested Loop Join Filter: (b2t2.c1 = b2t3.c1) -> Hash Join Hash Cond: (b2t3.c1 = b2t4.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t1.c1 -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Merge Join Merge Cond: (b3t2.c1 = b3t1.c1) -> Sort Sort Key: b3t2.c1 -> Nested Loop Join Filter: (b3t2.c1 = b3t3.c1) -> Hash Join Hash Cond: (b3t3.c1 = b3t4.c1) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b3t1.c1 -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Merge Join Merge Cond: (bmt2.c1 = bmt1.c1) -> Sort Sort Key: bmt2.c1 -> Nested Loop Join Filter: (bmt2.c1 = bmt3.c1) -> Hash Join Hash Cond: (bmt3.c1 = bmt4.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt4.c1 = (max(b1t1.c1))) -> Sort Sort Key: bmt4.c1 -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Merge Join Merge Cond: (b1t2.c1 = b1t1.c1) -> Sort Sort Key: b1t2.c1 -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Hash Join Hash Cond: (b1t3.c1 = b1t4.c1) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t1.c1 -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: bmt1.c1 -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) (89 rows) -- No. J-2-2-4 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 3 -> Aggregate -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 3).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (44 rows) /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) MergeJoin(b1t4 b1t3) HashJoin(b1t4 b1t3 b1t2) NestLoop(b1t4 b1t3 b1t2 b1t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: MergeJoin(b1t3 b1t4) MergeJoin(bmt4 c1) HashJoin(b1t2 b1t3 b1t4) HashJoin(bmt3 bmt4 c1) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(bmt2 bmt3 bmt4 c1) MergeJoin(bmt1 bmt2 bmt3 bmt4 c1) Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 3 -> Aggregate -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Merge Join Merge Cond: (bmt2.c1 = bmt1.c1) -> Sort Sort Key: bmt2.c1 -> Nested Loop Join Filter: (bmt2.c1 = bmt3.c1) -> Hash Join Hash Cond: (bmt3.c1 = bmt4.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (bmt4.c1 = (max(b1t1.c1))) -> Sort Sort Key: bmt4.c1 -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join Hash Cond: (b1t2.c1 = b1t3.c1) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t3.c1 = b1t4.c1) -> Sort Sort Key: b1t3.c1 -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t4.c1 -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: bmt1.c1 -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 3).col1) (58 rows) ---- ---- No. J-2-3 RULE or VIEW ---- -- No. J-2-3-1 EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (19 rows) /*+ Leading(t4 t3 t2 t1 r1) MergeJoin(t4 t3 t2 t1 r1) HashJoin(t4 t3 t2 t1) NestLoop(t4 t3 t2) MergeJoin(t4 t3) */ EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: MergeJoin(t3 t4) NestLoop(t2 t3 t4) HashJoin(t1 t2 t3 t4) MergeJoin(r1 t1 t2 t3 t4) Leading(t4 t3 t2 t1 r1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Merge Join Merge Cond: (t3.c1 = t4.c1) -> Sort Sort Key: t3.c1 -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: t4.c1 -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on r1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (24 rows) EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r1_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (19 rows) /*+ Leading(b1t4 b1t3 b1t2 b1t1 r1_) MergeJoin(b1t4 b1t3 b1t2 b1t1 r1_) HashJoin(b1t4 b1t3 b1t2 b1t1) NestLoop(b1t4 b1t3 b1t2) MergeJoin(b1t4 b1t3) */ EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: MergeJoin(b1t3 b1t4) NestLoop(b1t2 b1t3 b1t4) HashJoin(b1t1 b1t2 b1t3 b1t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r1_) Leading(b1t4 b1t3 b1t2 b1t1 r1_) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Merge Join Merge Cond: (b1t3.c1 = b1t4.c1) -> Sort Sort Key: b1t3.c1 -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t4.c1 -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on r1_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (24 rows) -- No. J-2-3-2 EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (39 rows) /*+ Leading(t4 t3 t2 t1 r2) MergeJoin(t4 t3 t2 t1 r2) HashJoin(t4 t3 t2 t1) NestLoop(t4 t3 t2) MergeJoin(t4 t3) */ EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: MergeJoin(t3 t4) NestLoop(t2 t3 t4) HashJoin(t1 t2 t3 t4) MergeJoin(r2 t1 t2 t3 t4) Leading(t4 t3 t2 t1 r2) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: MergeJoin(t3 t4) NestLoop(t2 t3 t4) HashJoin(t1 t2 t3 t4) MergeJoin(r2 t1 t2 t3 t4) Leading(t4 t3 t2 t1 r2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Merge Join Merge Cond: (t3.c1 = t4.c1) -> Sort Sort Key: t3.c1 -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: t4.c1 -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Merge Join Merge Cond: (t3.c1 = t4.c1) -> Sort Sort Key: t3.c1 -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: t4.c1 -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (49 rows) EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) (39 rows) /*+ Leading(b1t1 b1t2 b1t3 b1t4 r2_) Leading(b2t1 b2t2 b2t3 b2t4 r2_) MergeJoin(b1t1 b1t2) HashJoin(b1t1 b1t2 b1t3) NestLoop(b1t1 b1t2 b1t3 b1t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r2_) MergeJoin(b2t1 b2t2) HashJoin(b2t1 b2t2 b2t3) NestLoop(b2t1 b2t2 b2t3 b2t4) MergeJoin(b2t1 b2t2 b2t3 b2t4 r2_) */ EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: MergeJoin(b1t1 b1t2) HashJoin(b1t1 b1t2 b1t3) NestLoop(b1t1 b1t2 b1t3 b1t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r2_) Leading(b1t1 b1t2 b1t3 b1t4 r2_) not used hint: MergeJoin(b2t1 b2t2) HashJoin(b2t1 b2t2 b2t3) NestLoop(b2t1 b2t2 b2t3 b2t4) MergeJoin(b2t1 b2t2 b2t3 b2t4 r2_) Leading(b2t1 b2t2 b2t3 b2t4 r2_) duplication hint: error hint: LOG: pg_hint_plan: used hint: MergeJoin(b2t1 b2t2) HashJoin(b2t1 b2t2 b2t3) NestLoop(b2t1 b2t2 b2t3 b2t4) MergeJoin(b2t1 b2t2 b2t3 b2t4 r2_) Leading(b2t1 b2t2 b2t3 b2t4 r2_) not used hint: MergeJoin(b1t1 b1t2) HashJoin(b1t1 b1t2 b1t3) NestLoop(b1t1 b1t2 b1t3 b1t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r2_) Leading(b1t1 b1t2 b1t3 b1t4 r2_) duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Hash Join Hash Cond: (b1t3.c1 = b1t1.c1) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Sort Sort Key: b1t1.c1 -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Hash Join Hash Cond: (b2t3.c1 = b2t1.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Sort Sort Key: b2t1.c1 -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (49 rows) -- No. J-2-3-3 EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (59 rows) /*+ Leading(t4 t3 t2 t1 r3) MergeJoin(t4 t3 t2 t1 r3) HashJoin(t4 t3 t2 t1) NestLoop(t4 t3 t2) MergeJoin(t4 t3) */ EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: MergeJoin(t3 t4) NestLoop(t2 t3 t4) HashJoin(t1 t2 t3 t4) MergeJoin(r3 t1 t2 t3 t4) Leading(t4 t3 t2 t1 r3) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: MergeJoin(t3 t4) NestLoop(t2 t3 t4) HashJoin(t1 t2 t3 t4) MergeJoin(r3 t1 t2 t3 t4) Leading(t4 t3 t2 t1 r3) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: MergeJoin(t3 t4) NestLoop(t2 t3 t4) HashJoin(t1 t2 t3 t4) MergeJoin(r3 t1 t2 t3 t4) Leading(t4 t3 t2 t1 r3) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Merge Join Merge Cond: (t3.c1 = t4.c1) -> Sort Sort Key: t3.c1 -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: t4.c1 -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Merge Join Merge Cond: (t3.c1 = t4.c1) -> Sort Sort Key: t3.c1 -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: t4.c1 -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Merge Join Merge Cond: (t3.c1 = t4.c1) -> Sort Sort Key: t3.c1 -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: t4.c1 -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (74 rows) EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) (59 rows) /*+ Leading(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b2t1 b2t2 b2t3 b2t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) MergeJoin(b1t1 b1t2) HashJoin(b1t1 b1t2 b1t3) NestLoop(b1t1 b1t2 b1t3 b1t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r3_) MergeJoin(b2t1 b2t2) HashJoin(b2t1 b2t2 b2t3) NestLoop(b2t1 b2t2 b2t3 b2t4) MergeJoin(b2t1 b2t2 b2t3 b2t4 r3_) MergeJoin(b3t1 b3t2) HashJoin(b3t1 b3t2 b3t3) NestLoop(b3t1 b3t2 b3t3 b3t4) MergeJoin(b3t1 b3t2 b3t3 b3t4 r3_) */ EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: MergeJoin(b1t1 b1t2) HashJoin(b1t1 b1t2 b1t3) NestLoop(b1t1 b1t2 b1t3 b1t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b1t1 b1t2 b1t3 b1t4 r3_) not used hint: MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) HashJoin(b2t1 b2t2 b2t3) HashJoin(b3t1 b3t2 b3t3) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) MergeJoin(b2t1 b2t2 b2t3 b2t4 r3_) MergeJoin(b3t1 b3t2 b3t3 b3t4 r3_) Leading(b2t1 b2t2 b2t3 b2t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) duplication hint: error hint: LOG: pg_hint_plan: used hint: MergeJoin(b2t1 b2t2) HashJoin(b2t1 b2t2 b2t3) NestLoop(b2t1 b2t2 b2t3 b2t4) MergeJoin(b2t1 b2t2 b2t3 b2t4 r3_) Leading(b2t1 b2t2 b2t3 b2t4 r3_) not used hint: MergeJoin(b1t1 b1t2) MergeJoin(b3t1 b3t2) HashJoin(b1t1 b1t2 b1t3) HashJoin(b3t1 b3t2 b3t3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b3t1 b3t2 b3t3 b3t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r3_) MergeJoin(b3t1 b3t2 b3t3 b3t4 r3_) Leading(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) duplication hint: error hint: LOG: pg_hint_plan: used hint: MergeJoin(b3t1 b3t2) HashJoin(b3t1 b3t2 b3t3) NestLoop(b3t1 b3t2 b3t3 b3t4) MergeJoin(b3t1 b3t2 b3t3 b3t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) not used hint: MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) HashJoin(b1t1 b1t2 b1t3) HashJoin(b2t1 b2t2 b2t3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r3_) MergeJoin(b2t1 b2t2 b2t3 b2t4 r3_) Leading(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b2t1 b2t2 b2t3 b2t4 r3_) duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Hash Join Hash Cond: (b1t3.c1 = b1t1.c1) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Sort Sort Key: b1t1.c1 -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Hash Join Hash Cond: (b2t3.c1 = b2t1.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Sort Sort Key: b2t1.c1 -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Hash Join Hash Cond: (b3t3.c1 = b3t1.c1) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Hash -> Merge Join Merge Cond: (b3t1.c1 = b3t2.c1) -> Sort Sort Key: b3t1.c1 -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: b3t2.c1 -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (74 rows) -- No. J-2-3-4 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; QUERY PLAN ------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 (5 rows) /*+HashJoin(v1t1 v1t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; INFO: pg_hint_plan: hint syntax error at or near "HashJoin(v1t1 v1t1)" DETAIL: Relation name "v1t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(v1t1 v1t1) QUERY PLAN ------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 (5 rows) -- No. J-2-3-5 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; QUERY PLAN ----------------------------------- Hash Join Hash Cond: (v1t1.c1 = v1t1_.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_ (5 rows) /*+NestLoop(v1t1 v1t1_)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; LOG: pg_hint_plan: used hint: NestLoop(v1t1 v1t1_) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Seq Scan on t1 v1t1 -> Index Scan using t1_i1 on t1 v1t1_ Index Cond: (c1 = v1t1.c1) (4 rows) ---- ---- No. J-2-4 VALUES clause ---- -- No. J-2-4-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; QUERY PLAN ------------------------------------ Nested Loop -> Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) -> Seq Scan on t2 Filter: (c1 = 1) (5 rows) /*+ Leading(t3 t1 t2) HashJoin(t3 t1)NestLoop(t3 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; LOG: pg_hint_plan: used hint: not used hint: HashJoin(t1 t3) NestLoop(t1 t2 t3) Leading(t3 t1 t2) duplication hint: error hint: QUERY PLAN ------------------------------------ Nested Loop -> Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) -> Seq Scan on t2 Filter: (c1 = 1) (5 rows) /*+ Leading(*VALUES* t1 t2) HashJoin(*VALUES* t1)NestLoop(*VALUES* t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; LOG: pg_hint_plan: used hint: HashJoin(*VALUES* t1) NestLoop(*VALUES* t1 t2) Leading(*VALUES* t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Nested Loop -> Hash Join Hash Cond: (t1.c1 = "*VALUES*".column1) -> Seq Scan on t1 -> Hash -> Values Scan on "*VALUES*" -> Index Scan using t2_i1 on t2 Index Cond: (c1 = t1.c1) (8 rows) -- No. J-2-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN ------------------------------------------------------- Nested Loop -> Nested Loop Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Materialize -> Values Scan on "*VALUES*_1" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (12 rows) /*+ Leading(t4 t3 t2 t1) NestLoop(t4 t3)HashJoin(t4 t3 t2)MergeJoin(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: not used hint: NestLoop(t3 t4) HashJoin(t2 t3 t4) MergeJoin(t1 t2 t3 t4) Leading(t4 t3 t2 t1) duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Nested Loop -> Nested Loop Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Materialize -> Values Scan on "*VALUES*_1" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (12 rows) /*+ Leading(*VALUES* t3 t2 t1) NestLoop(t4 t3)HashJoin(*VALUES* t3 t2)MergeJoin(*VALUES* t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near "HashJoin(*VALUES* t3 t2)MergeJoin(*VALUES* t3 t2 t1)" DETAIL: Relation name "*VALUES*" is ambiguous. INFO: pg_hint_plan: hint syntax error at or near "MergeJoin(*VALUES* t3 t2 t1)" DETAIL: Relation name "*VALUES*" is ambiguous. INFO: pg_hint_plan: hint syntax error at or near " Leading(*VALUES* t3 t2 t1) NestLoop(t4 t3)HashJoin(*VALUES* t3 t2)MergeJoin(*VALUES* t3 t2 t1)" DETAIL: Relation name "*VALUES*" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: NestLoop(t3 t4) duplication hint: error hint: HashJoin(*VALUES* t2 t3) MergeJoin(*VALUES* t1 t2 t3) Leading(*VALUES* t3 t2 t1) QUERY PLAN ------------------------------------------------------- Nested Loop -> Nested Loop Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Materialize -> Values Scan on "*VALUES*_1" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (12 rows) ---- ---- No. J-3-1 join method hint ---- -- No. J-3-1-1~6 SET enable_nestloop TO on; SET enable_mergejoin TO off; SET enable_hashjoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) SET enable_mergejoin TO on; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)';; QUERY PLAN ----------------------------------------- Nested Loop Join Filter: (t1.c1 = t2.c1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 (5 rows) /*+NoNestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)';; LOG: pg_hint_plan: used hint: NoNestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------- Merge Join Merge Cond: (t1.c1 = t2.c1) -> Sort Sort Key: t1.c1 -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) SET enable_mergejoin TO off; /*+NoHashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NoHashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) /*+NoMergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NoMergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) -- No. J-3-1-7~12 SET enable_nestloop TO off; SET enable_mergejoin TO off; SET enable_hashjoin TO on; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) /*+NoNestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NoNestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+NoHashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NoHashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) /*+NoMergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NoMergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) -- No. J-3-1-13~18 SET enable_nestloop TO off; SET enable_mergejoin TO on; SET enable_hashjoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) /*+NoNestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NoNestLoop(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) /*+NoHashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NoHashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) /*+NoMergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: NoMergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) SET enable_nestloop TO on; SET enable_mergejoin TO on; SET enable_hashjoin TO on; ---- ---- No. J-3-2 join inherit tables ---- EXPLAIN (COSTS false) SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; QUERY PLAN ----------------------------------------- Hash Join Hash Cond: (p2.c1 = p1.c1) -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2c1 p2_2 -> Seq Scan on p2c2 p2_3 -> Seq Scan on p2c3 p2_4 -> Seq Scan on p2c1c1 p2_5 -> Seq Scan on p2c1c2 p2_6 -> Seq Scan on p2c2c1 p2_7 -> Seq Scan on p2c2c2 p2_8 -> Seq Scan on p2c3c1 p2_9 -> Seq Scan on p2c3c2 p2_10 -> Hash -> Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1c1 p1_2 -> Seq Scan on p1c2 p1_3 -> Seq Scan on p1c3 p1_4 (19 rows) -- No. J-3-2-1 /*+MergeJoin(p1 p2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; LOG: pg_hint_plan: used hint: MergeJoin(p1 p2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Merge Join Merge Cond: (p1.c1 = p2.c1) -> Sort Sort Key: p1.c1 -> Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1c1 p1_2 -> Seq Scan on p1c2 p1_3 -> Seq Scan on p1c3 p1_4 -> Sort Sort Key: p2.c1 -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2c1 p2_2 -> Seq Scan on p2c2 p2_3 -> Seq Scan on p2c3 p2_4 -> Seq Scan on p2c1c1 p2_5 -> Seq Scan on p2c1c2 p2_6 -> Seq Scan on p2c2c1 p2_7 -> Seq Scan on p2c2c2 p2_8 -> Seq Scan on p2c3c1 p2_9 -> Seq Scan on p2c3c2 p2_10 (22 rows) -- No. J-3-2-2 /*+MergeJoin(p1c1 p2c1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; LOG: pg_hint_plan: used hint: not used hint: MergeJoin(p1c1 p2c1) duplication hint: error hint: QUERY PLAN ----------------------------------------- Hash Join Hash Cond: (p2.c1 = p1.c1) -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2c1 p2_2 -> Seq Scan on p2c2 p2_3 -> Seq Scan on p2c3 p2_4 -> Seq Scan on p2c1c1 p2_5 -> Seq Scan on p2c1c2 p2_6 -> Seq Scan on p2c2c1 p2_7 -> Seq Scan on p2c2c2 p2_8 -> Seq Scan on p2c3c1 p2_9 -> Seq Scan on p2c3c2 p2_10 -> Hash -> Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1c1 p1_2 -> Seq Scan on p1c2 p1_3 -> Seq Scan on p1c3 p1_4 (19 rows) ---- ---- No. J-3-2-2 join partitioned tables ---- EXPLAIN (COSTS false) SELECT * FROM s1.pt1, s1.p2 WHERE pt1.c1 = p2.c1; QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (p2.c1 = pt1.c1) -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2c1 p2_2 -> Seq Scan on p2c2 p2_3 -> Seq Scan on p2c3 p2_4 -> Seq Scan on p2c1c1 p2_5 -> Seq Scan on p2c1c2 p2_6 -> Seq Scan on p2c2c1 p2_7 -> Seq Scan on p2c2c2 p2_8 -> Seq Scan on p2c3c1 p2_9 -> Seq Scan on p2c3c2 p2_10 -> Hash -> Append -> Seq Scan on pt1_c1 pt1_1 -> Seq Scan on pt1_c2 pt1_2 -> Seq Scan on pt1_c3 pt1_3 (18 rows) /*+MergeJoin(pt1 p2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.pt1, s1.p2 WHERE pt1.c1 = p2.c1; LOG: pg_hint_plan: used hint: MergeJoin(p2 pt1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Merge Join Merge Cond: (pt1.c1 = p2.c1) -> Sort Sort Key: pt1.c1 -> Append -> Seq Scan on pt1_c1 pt1_1 -> Seq Scan on pt1_c2 pt1_2 -> Seq Scan on pt1_c3 pt1_3 -> Sort Sort Key: p2.c1 -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2c1 p2_2 -> Seq Scan on p2c2 p2_3 -> Seq Scan on p2c3 p2_4 -> Seq Scan on p2c1c1 p2_5 -> Seq Scan on p2c1c2 p2_6 -> Seq Scan on p2c2c1 p2_7 -> Seq Scan on p2c2c2 p2_8 -> Seq Scan on p2c3c1 p2_9 -> Seq Scan on p2c3c2 p2_10 (21 rows) /*+MergeJoin(pt1_c1 p2c1)*/ /* will ignored */ EXPLAIN (COSTS false) SELECT * FROM s1.pt1, s1.p2 WHERE pt1.c1 = p2.c1; LOG: pg_hint_plan: used hint: not used hint: MergeJoin(p2c1 pt1_c1) duplication hint: error hint: QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (p2.c1 = pt1.c1) -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2c1 p2_2 -> Seq Scan on p2c2 p2_3 -> Seq Scan on p2c3 p2_4 -> Seq Scan on p2c1c1 p2_5 -> Seq Scan on p2c1c2 p2_6 -> Seq Scan on p2c2c1 p2_7 -> Seq Scan on p2c2c2 p2_8 -> Seq Scan on p2c3c1 p2_9 -> Seq Scan on p2c3c2 p2_10 -> Hash -> Append -> Seq Scan on pt1_c1 pt1_1 -> Seq Scan on pt1_c2 pt1_2 -> Seq Scan on pt1_c3 pt1_3 (18 rows) ---- ---- No. J-3-3 conflict join method hint ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; QUERY PLAN ------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (6 rows) -- No. J-3-3-1 /*+HashJoin(t1 t2)NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t2)NestLoop(t1 t2)" DETAIL: Conflict join method hint. LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: HashJoin(t1 t2) error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) -- No. J-3-3-2 /*+MergeJoin(t1 t2)HashJoin(t1 t2)NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; INFO: pg_hint_plan: hint syntax error at or near "MergeJoin(t1 t2)HashJoin(t1 t2)NestLoop(t1 t2)" DETAIL: Conflict join method hint. INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t2)NestLoop(t1 t2)" DETAIL: Conflict join method hint. LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: MergeJoin(t1 t2) HashJoin(t1 t2) error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) -- No. J-3-3-3 /*+HashJoin(t1 t2)NestLoop(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t2)NestLoop(t2 t1)" DETAIL: Conflict join method hint. LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: HashJoin(t1 t2) error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) -- No. J-3-3-4 /*+MergeJoin(t2 t1)HashJoin(t1 t2)NestLoop(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; INFO: pg_hint_plan: hint syntax error at or near "MergeJoin(t2 t1)HashJoin(t1 t2)NestLoop(t2 t1)" DETAIL: Conflict join method hint. INFO: pg_hint_plan: hint syntax error at or near "HashJoin(t1 t2)NestLoop(t2 t1)" DETAIL: Conflict join method hint. LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: MergeJoin(t1 t2) HashJoin(t1 t2) error hint: QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on t2 -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (4 rows) ---- ---- No. J-3-4 hint state output ---- -- No. J-3-4-1 /*+NestLoop(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+---- (0 rows) -- No. J-3-4-2 /*+HashJoin(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+---- (0 rows) -- No. J-3-4-3 /*+MergeJoin(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+---- (0 rows) -- No. J-3-4-4 /*+NoNestLoop(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; LOG: pg_hint_plan: used hint: NoNestLoop(t1 t2) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+---- (0 rows) -- No. J-3-4-5 /*+NoHashJoin(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; LOG: pg_hint_plan: used hint: NoHashJoin(t1 t2) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+---- (0 rows) -- No. J-3-4-6 /*+NoMergeJoin(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; LOG: pg_hint_plan: used hint: NoMergeJoin(t1 t2) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+---- (0 rows) -- No. J-3-4-7 /*+NestLoop()*/ SELECT * FROM s1.t1 WHERE false; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NestLoop hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NestLoop() c1 | c2 | c3 | c4 ----+----+----+---- (0 rows) -- No. J-3-4-8 /*+NestLoop(t1)*/ SELECT * FROM s1.t1 WHERE false; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NestLoop hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NestLoop(t1) c1 | c2 | c3 | c4 ----+----+----+---- (0 rows) -- No. J-3-4-9 /*+NestLoop(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+---- (0 rows) -- No. J-3-4-10 /*+NestLoop(t1 t2 t3)*/ SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE false; LOG: pg_hint_plan: used hint: NestLoop(t1 t2 t3) not used hint: duplication hint: error hint: c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 | c1 | c2 | c3 | c4 ----+----+----+----+----+----+----+----+----+----+----+---- (0 rows) ---- ---- No. J-3-5 not used hint ---- -- No. J-3-5-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1 FULL OUTER JOIN s1.t2 ON (t1.c1 = t2.c1); QUERY PLAN ------------------------------ Hash Full Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 -> Hash -> Seq Scan on t2 (5 rows) SELECT explain_filter(' /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1 FULL OUTER JOIN s1.t2 ON (t1.c1 = t2.c1); '); LOG: pg_hint_plan: used hint: NestLoop(t1 t2) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------- Hash Full Join (cost={inf}..{inf} rows=1000 width=xxx) Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (5 rows) -- Memoize EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.val = t2.val and t2.id = t3.id; QUERY PLAN -------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t2.id = t3.id) -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t3.id -> Seq Scan on t3 -> Memoize Cache Key: t2.val Cache Mode: logical -> Index Scan using t1_val on t1 Index Cond: (val = t2.val) (12 rows) /*+ nomemoize(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.val = t2.val and t2.id = t3.id; -- doesn't work LOG: pg_hint_plan: used hint: NoMemoize(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t2.id = t3.id) -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t3.id -> Seq Scan on t3 -> Memoize Cache Key: t2.val Cache Mode: logical -> Index Scan using t1_val on t1 Index Cond: (val = t2.val) (12 rows) /*+ nomemoize(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.val = t2.val and t2.id = t3.id; LOG: pg_hint_plan: used hint: NoMemoize(t1 t2 t3) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Merge Join Merge Cond: (t1.val = t2.val) -> Index Scan using t1_val on t1 -> Sort Sort Key: t2.val -> Merge Join Merge Cond: (t2.id = t3.id) -> Index Scan using t2_pkey on t2 -> Sort Sort Key: t3.id -> Seq Scan on t3 (11 rows) pg_hint_plan-REL17_1_7_0/expected/ut-L.out000066400000000000000000005120221466301071500203550ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; SET max_parallel_workers_per_gather TO 0; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) ---- ---- No. L-1-1 specified pattern of the object name ---- -- No. L-1-1-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) (14 rows) -- No. L-1-1-2 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1, s1.t2 t_2, s1.t3 t_3, s1.t4 t_4 WHERE t_1.c1 = t_2.c1 AND t_1.c1 = t_3.c1 AND t_1.c1 = t_4.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(t4 t2 t3 t1) duplication hint: error hint: QUERY PLAN ---------------------------------------------------- Nested Loop -> Merge Join Merge Cond: (t_1.c1 = t_2.c1) -> Merge Join Merge Cond: (t_1.c1 = t_3.c1) -> Index Scan using t1_i1 on t1 t_1 -> Index Scan using t3_i1 on t3 t_3 -> Sort Sort Key: t_2.c1 -> Seq Scan on t2 t_2 -> Index Scan using t4_i1 on t4 t_4 Index Cond: (c1 = t_1.c1) (12 rows) -- No. L-1-1-3 /*+Leading(t_4 t_2 t_3 t_1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1, s1.t2 t_2, s1.t3 t_3, s1.t4 t_4 WHERE t_1.c1 = t_2.c1 AND t_1.c1 = t_3.c1 AND t_1.c1 = t_4.c1; LOG: pg_hint_plan: used hint: Leading(t_4 t_2 t_3 t_1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------- Merge Join Merge Cond: (t_1.c1 = t_2.c1) -> Index Scan using t1_i1 on t1 t_1 -> Sort Sort Key: t_2.c1 -> Nested Loop Join Filter: (t_2.c1 = t_3.c1) -> Hash Join Hash Cond: (t_4.c1 = t_2.c1) -> Seq Scan on t4 t_4 -> Hash -> Seq Scan on t2 t_2 -> Index Scan using t3_i1 on t3 t_3 Index Cond: (c1 = t_4.c1) (14 rows) ---- ---- No. L-1-2 specified schema name in the hint option ---- -- No. L-1-2-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) (14 rows) -- No. L-1-2-2 /*+Leading(s1.t4 s1.t2 s1.t3 s1.t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(s1.t4 s1.t2 s1.t3 s1.t1) duplication hint: error hint: QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) ---- ---- No. L-1-3 table doesn't exist in the hint option ---- -- No. L-1-3-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) (14 rows) -- No. L-1-3-2 /*+Leading(t5 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(t5 t2 t3 t1) duplication hint: error hint: QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) ---- ---- No. L-1-4 conflict table name ---- -- No. L-1-4-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) (14 rows) -- No. L-1-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2.t1.c1; QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t1_1.c1) -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Sort Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (14 rows) /*+Leading(t1 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2.t1.c1; INFO: pg_hint_plan: hint syntax error at or near "Leading(t1 t2 t3 t1)" DETAIL: Relation name "t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t1 t2 t3 t1) QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t1_1.c1) -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Sort Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (14 rows) /*+Leading(s1.t1 t2 t3 s2.t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2.t1.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(s1.t1 t2 t3 s2.t1) duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t1_1.c1) -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Sort Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (14 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 s2t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2t1.c1; QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = s2t1.c1) -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Sort Sort Key: s2t1.c1 -> Seq Scan on t1 s2t1 (14 rows) /*+Leading(s2t1 t1 t3 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 s2t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2t1.c1; LOG: pg_hint_plan: used hint: Leading(s2t1 t1 t3 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Nested Loop -> Merge Join Merge Cond: (t1.c1 = s2t1.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: s2t1.c1 -> Seq Scan on t1 s2t1 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (14 rows) -- No. L-1-4-3 EXPLAIN (COSTS false) SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN ------------------------------------------------------------------------ Nested Loop InitPlan 1 -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (t1_1.c1 = t2_1.c1) -> Merge Join Merge Cond: (t1_1.c1 = t3_1.c1) -> Index Only Scan using t1_i1 on t1 t1_1 -> Index Only Scan using t3_i1 on t3 t3_1 -> Sort Sort Key: t2_1.c1 -> Seq Scan on t2 t2_1 -> Index Only Scan using t4_i1 on t4 t4_1 Index Cond: (c1 = t1_1.c1) -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (26 rows) /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) InitPlan 1 -> Aggregate -> Merge Join Merge Cond: (t1_1.c1 = t2_1.c1) -> Index Only Scan using t1_i1 on t1 t1_1 -> Sort Sort Key: t2_1.c1 -> Nested Loop Join Filter: (t2_1.c1 = t3_1.c1) -> Hash Join Hash Cond: (t4_1.c1 = t2_1.c1) -> Seq Scan on t4 t4_1 -> Hash -> Seq Scan on t2 t2_1 -> Index Only Scan using t3_i1 on t3 t3_1 Index Cond: (c1 = t4_1.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) (30 rows) /*+Leading(st1 st2 st3 st4)Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT *, (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2, s1.t3 st3, s1.t4 st4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(st1 st2 st3 st4) Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------------------------------------------- Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) SubPlan 1 -> Aggregate -> Result One-Time Filter: ((t1.c1 = t2.c1) AND (t1.c1 = t3.c1) AND (t1.c1 = t4.c1)) -> Nested Loop -> Nested Loop -> Nested Loop -> Seq Scan on t1 st1 -> Materialize -> Seq Scan on t2 st2 -> Materialize -> Seq Scan on t3 st3 -> Materialize -> Seq Scan on t4 st4 (28 rows) ---- ---- No. L-1-5 conflict table name ---- -- No. L-1-5-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) (14 rows) -- No. L-1-5-2 /*+Leading(t4 t2 t3 t1 t4)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near "Leading(t4 t2 t3 t1 t4)" DETAIL: Relation name "t4" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t4 t2 t3 t1 t4) QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) /*+Leading(t4 t2 t3 t4)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near "Leading(t4 t2 t3 t4)" DETAIL: Relation name "t4" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t4 t2 t3 t4) QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) -- No. L-1-5-3 /*+Leading(t4 t2 t3 t1 t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near "Leading(t4 t2 t3 t1 t4 t2 t3 t1)" DETAIL: Relation name "t4" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t4 t2 t3 t1 t4 t2 t3 t1) QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) /*+Leading(t4 t2 t2 t4)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near "Leading(t4 t2 t2 t4)" DETAIL: Relation name "t2" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t4 t2 t2 t4) QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) ---- ---- No. L-1-6 object type for the hint ---- -- No. L-1-6-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) (14 rows) -- No. L-1-6-2 EXPLAIN (COSTS false) SELECT * FROM s1.p1 t1, s1.p1 t2, s1.p1 t3, s1.p1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN ----------------------------------------------------- Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t3.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Append -> Seq Scan on p1 t1_1 -> Seq Scan on p1c1 t1_2 -> Seq Scan on p1c2 t1_3 -> Seq Scan on p1c3 t1_4 -> Hash -> Append -> Seq Scan on p1 t2_1 -> Seq Scan on p1c1 t2_2 -> Seq Scan on p1c2 t2_3 -> Seq Scan on p1c3 t2_4 -> Hash -> Append -> Seq Scan on p1 t3_1 -> Seq Scan on p1c1 t3_2 -> Seq Scan on p1c2 t3_3 -> Seq Scan on p1c3 t3_4 -> Hash -> Append -> Seq Scan on p1 t4_1 -> Seq Scan on p1c1 t4_2 -> Seq Scan on p1c2 t4_3 -> Seq Scan on p1c3 t4_4 (29 rows) /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 t1, s1.p1 t2, s1.p1 t3, s1.p1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------- Hash Join Hash Cond: (t2.c1 = t1.c1) -> Hash Join Hash Cond: (t3.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t4.c1) -> Append -> Seq Scan on p1 t3_1 -> Seq Scan on p1c1 t3_2 -> Seq Scan on p1c2 t3_3 -> Seq Scan on p1c3 t3_4 -> Hash -> Append -> Seq Scan on p1 t4_1 -> Seq Scan on p1c1 t4_2 -> Seq Scan on p1c2 t4_3 -> Seq Scan on p1c3 t4_4 -> Hash -> Append -> Seq Scan on p1 t2_1 -> Seq Scan on p1c1 t2_2 -> Seq Scan on p1c2 t2_3 -> Seq Scan on p1c3 t2_4 -> Hash -> Append -> Seq Scan on p1 t1_1 -> Seq Scan on p1c1 t1_2 -> Seq Scan on p1c2 t1_3 -> Seq Scan on p1c3 t1_4 (29 rows) -- No. L-1-6-3 EXPLAIN (COSTS false) SELECT * FROM s1.ul1 t1, s1.ul1 t2, s1.ul1 t3, s1.ul1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t3.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on ul1 t1 -> Hash -> Seq Scan on ul1 t2 -> Hash -> Seq Scan on ul1 t3 -> Hash -> Seq Scan on ul1 t4 (13 rows) /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ul1 t1, s1.ul1 t2, s1.ul1 t3, s1.ul1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t2.c1 = t1.c1) -> Hash Join Hash Cond: (t3.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t4.c1) -> Seq Scan on ul1 t3 -> Hash -> Seq Scan on ul1 t4 -> Hash -> Seq Scan on ul1 t2 -> Hash -> Seq Scan on ul1 t1 (13 rows) -- No. L-1-6-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); EXPLAIN (COSTS false) SELECT * FROM tm1 t1, tm1 t2, tm1 t3, tm1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t1.c1 = t4.c1) -> Hash Join Hash Cond: (t1.c1 = t3.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on tm1 t1 -> Hash -> Seq Scan on tm1 t2 -> Hash -> Seq Scan on tm1 t3 -> Hash -> Seq Scan on tm1 t4 (13 rows) /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM tm1 t1, tm1 t2, tm1 t3, tm1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Hash Join Hash Cond: (t2.c1 = t1.c1) -> Hash Join Hash Cond: (t3.c1 = t2.c1) -> Hash Join Hash Cond: (t3.c1 = t4.c1) -> Seq Scan on tm1 t3 -> Hash -> Seq Scan on tm1 t4 -> Hash -> Seq Scan on tm1 t2 -> Hash -> Seq Scan on tm1 t1 (13 rows) -- No. L-1-6-5 EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class t1, pg_catalog.pg_class t2, pg_catalog.pg_class t3, pg_catalog.pg_class t4 WHERE t1.oid = t2.oid AND t1.oid = t3.oid AND t1.oid = t4.oid; QUERY PLAN ------------------------------------------------- Hash Join Hash Cond: (t1.oid = t4.oid) -> Hash Join Hash Cond: (t1.oid = t3.oid) -> Hash Join Hash Cond: (t1.oid = t2.oid) -> Seq Scan on pg_class t1 -> Hash -> Seq Scan on pg_class t2 -> Hash -> Seq Scan on pg_class t3 -> Hash -> Seq Scan on pg_class t4 (13 rows) /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class t1, pg_catalog.pg_class t2, pg_catalog.pg_class t3, pg_catalog.pg_class t4 WHERE t1.oid = t2.oid AND t1.oid = t3.oid AND t1.oid = t4.oid; LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Hash Join Hash Cond: (t2.oid = t1.oid) -> Hash Join Hash Cond: (t3.oid = t2.oid) -> Hash Join Hash Cond: (t3.oid = t4.oid) -> Seq Scan on pg_class t3 -> Hash -> Seq Scan on pg_class t4 -> Hash -> Seq Scan on pg_class t2 -> Hash -> Seq Scan on pg_class t1 (13 rows) -- No. L-1-6-6 -- refer ut-fdw.sql -- No. L-1-6-7 EXPLAIN (COSTS false) SELECT * FROM s1.f1() t1, s1.f1() t2, s1.f1() t3, s1.f1() t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Function Scan on f1 t1 -> Function Scan on f1 t2 -> Function Scan on f1 t3 -> Function Scan on f1 t4 (10 rows) /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.f1() t1, s1.f1() t2, s1.f1() t3, s1.f1() t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Nested Loop Join Filter: (t3.c1 = t4.c1) -> Function Scan on f1 t3 -> Function Scan on f1 t4 -> Function Scan on f1 t2 -> Function Scan on f1 t1 (10 rows) -- No. L-1-6-8 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t1 (c1, c2, c3, c4), s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN ------------------------------------------------------- Nested Loop Join Filter: (t4.c1 = "*VALUES*".column1) -> Nested Loop Join Filter: (t3.c1 = "*VALUES*".column1) -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t2.c1) -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t3.c1) (13 rows) /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t1 (c1, c2, c3, c4), s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(t4 t3 t2 t1) duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Nested Loop Join Filter: (t4.c1 = "*VALUES*".column1) -> Nested Loop Join Filter: (t3.c1 = "*VALUES*".column1) -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t2.c1) -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t3.c1) (13 rows) -- No. L-1-6-9 EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT st1.c1 FROM s1.t1 st1, s1.t1 st2, s1.t1 st3, s1.t1 st4 WHERE st1.c1 = st2.c1 AND st1.c1 = st3.c1 AND st1.c1 = st4.c1) SELECT * FROM c1 ct1, c1 ct2, c1 ct3, c1 ct4 WHERE ct1.c1 = ct2.c1 AND ct1.c1 = ct3.c1 AND ct1.c1 = ct4.c1; QUERY PLAN ---------------------------------------------------- Hash Join Hash Cond: (ct1.c1 = ct4.c1) CTE c1 -> Hash Join Hash Cond: (st1.c1 = st4.c1) -> Hash Join Hash Cond: (st1.c1 = st3.c1) -> Hash Join Hash Cond: (st1.c1 = st2.c1) -> Seq Scan on t1 st1 -> Hash -> Seq Scan on t1 st2 -> Hash -> Seq Scan on t1 st3 -> Hash -> Seq Scan on t1 st4 -> Hash Join Hash Cond: (ct1.c1 = ct3.c1) -> Hash Join Hash Cond: (ct1.c1 = ct2.c1) -> CTE Scan on c1 ct1 -> Hash -> CTE Scan on c1 ct2 -> Hash -> CTE Scan on c1 ct3 -> Hash -> CTE Scan on c1 ct4 (27 rows) /*+Leading(ct4 ct3 ct2 ct1)Leading(st4 st3 st2 st1)*/ EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT st1.c1 FROM s1.t1 st1, s1.t1 st2, s1.t1 st3, s1.t1 st4 WHERE st1.c1 = st2.c1 AND st1.c1 = st3.c1 AND st1.c1 = st4.c1) SELECT * FROM c1 ct1, c1 ct2, c1 ct3, c1 ct4 WHERE ct1.c1 = ct2.c1 AND ct1.c1 = ct3.c1 AND ct1.c1 = ct4.c1; LOG: pg_hint_plan: used hint: Leading(ct4 ct3 ct2 ct1) Leading(st4 st3 st2 st1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------- Hash Join Hash Cond: (ct2.c1 = ct1.c1) CTE c1 -> Hash Join Hash Cond: (st2.c1 = st1.c1) -> Hash Join Hash Cond: (st3.c1 = st2.c1) -> Hash Join Hash Cond: (st3.c1 = st4.c1) -> Seq Scan on t1 st3 -> Hash -> Seq Scan on t1 st4 -> Hash -> Seq Scan on t1 st2 -> Hash -> Seq Scan on t1 st1 -> Hash Join Hash Cond: (ct3.c1 = ct2.c1) -> Hash Join Hash Cond: (ct3.c1 = ct4.c1) -> CTE Scan on c1 ct3 -> Hash -> CTE Scan on c1 ct4 -> Hash -> CTE Scan on c1 ct2 -> Hash -> CTE Scan on c1 ct1 (27 rows) -- No. L-1-6-10 EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1 t2, s1.v1 t3, s1.v1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN ------------------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_3.c1) -> Hash Join Hash Cond: (v1t1.c1 = v1t1_2.c1) -> Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 -> Hash -> Seq Scan on t1 v1t1_2 -> Hash -> Seq Scan on t1 v1t1_3 (13 rows) /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1 t2, s1.v1 t3, s1.v1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(t4 t3 t2 t1) duplication hint: error hint: QUERY PLAN ------------------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_3.c1) -> Hash Join Hash Cond: (v1t1.c1 = v1t1_2.c1) -> Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 -> Hash -> Seq Scan on t1 v1t1_2 -> Hash -> Seq Scan on t1 v1t1_3 (13 rows) EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1_ t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN --------------------------------------------- Hash Join Hash Cond: (v1t1.c1 = t4.c1) -> Hash Join Hash Cond: (v1t1.c1 = v1t1_.c1) -> Hash Join Hash Cond: (t3.c1 = v1t1.c1) -> Seq Scan on t3 -> Hash -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_ -> Hash -> Seq Scan on t4 (13 rows) /*+Leading(t4 v1t1_ v1t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1_ t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(t4 v1t1_ v1t1 t3) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------- Hash Join Hash Cond: (v1t1.c1 = t3.c1) -> Hash Join Hash Cond: (v1t1_.c1 = v1t1.c1) -> Hash Join Hash Cond: (t4.c1 = v1t1_.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t1 v1t1_ -> Hash -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t3 (13 rows) -- No. L-1-6-11 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, (SELECT t4.c1 FROM s1.t4) st4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = st4.c1; QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Only Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) /*+Leading(st4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, (SELECT t4.c1 FROM s1.t4) st4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = st4.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(st4 t2 t3 t1) duplication hint: error hint: QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Only Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, (SELECT t4.c1 FROM s1.t4) st4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = st4.c1; LOG: pg_hint_plan: used hint: Leading(t4 t2 t3 t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t4.c1) (14 rows) ---- ---- No. L-2-1 some complexity query blocks ---- -- No. L-2-1-1 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; QUERY PLAN ------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (47 rows) /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; LOG: pg_hint_plan: used hint: Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t3.c1 = b2t4.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (47 rows) -- No. L-2-1-2 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; QUERY PLAN ------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 3 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (63 rows) /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; LOG: pg_hint_plan: used hint: Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t3.c1 = b2t4.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 3 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (63 rows) -- No. L-2-1-3 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (15 rows) /*+ Leading(bmt4 bmt3 bmt2 bmt1) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt2.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt3.c1 = bmt4.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) (15 rows) -- No. L-2-1-4 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = sbmt2.c1 AND sbmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (15 rows) /*+ Leading(bmt4 bmt3 bmt2 bmt1) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = sbmt2.c1 AND sbmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt2.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt3.c1 = bmt4.c1) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) (15 rows) -- No. L-2-1-5 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) ; QUERY PLAN --------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1)) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (48 rows) /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t3.c1 = b2t4.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1)) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (48 rows) -- No. L-2-1-6 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 3 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1) AND (c1 <> (InitPlan 3).col1)) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (64 rows) /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t3.c1 = b2t4.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 3 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1) AND (c1 <> (InitPlan 3).col1)) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (64 rows) -- No. L-2-1-7 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; QUERY PLAN ----------------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = (max(b2t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) (49 rows) /*+ Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; LOG: pg_hint_plan: used hint: Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Merge Join Merge Cond: ((max(b1t1.c1)) = (max(b2t1.c1))) -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b2t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t3.c1 = b2t4.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (53 rows) -- No. L-2-1-8 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1 ; QUERY PLAN ----------------------------------------------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = (max(b3t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Merge Join Merge Cond: ((max(b1t1.c1)) = (max(b2t1.c1))) -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b2t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) (70 rows) /*+ Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1 ; LOG: pg_hint_plan: used hint: Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: ((max(b1t1.c1)) = (max(b2t1.c1))) -> Merge Join Merge Cond: ((max(b2t1.c1)) = (max(b3t1.c1))) -> Sort Sort Key: (max(b2t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t3.c1 = b2t4.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Sort Sort Key: (max(b3t1.c1)) -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) (70 rows) ---- ---- No. L-2-2 the number of the tables per quiry block ---- -- No. L-2-2-1 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 4).col1) AND (c1 = 1)) -> Result (20 rows) /*+ Leading(c1 bmt1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; LOG: pg_hint_plan: used hint: Leading(c1 bmt1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 4).col1) AND (c1 = 1)) -> Result (20 rows) -- No. L-2-2-2 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) (33 rows) /*+ Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt2.c1 = (max(b1t1.c1))) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) (33 rows) -- No. L-2-2-3 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (65 rows) /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t2.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t3.c1 = b2t4.c1) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop Join Filter: (b3t2.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t3.c1 = b3t4.c1) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt2.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt3.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt4.c1 = (max(b1t1.c1))) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t3.c1 = b1t4.c1) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) (65 rows) -- No. L-2-2-4 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 3 -> Aggregate -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 3).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (44 rows) /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; LOG: pg_hint_plan: used hint: Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 3 -> Aggregate -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt2.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt3.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt4.c1 = (max(b1t1.c1))) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t3.c1 = b1t4.c1) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 3).col1) (44 rows) ---- ---- No. L-2-3 RULE or VIEW ---- -- No. L-2-3-1 EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (19 rows) /*+ Leading(t4 t3 t2 t1 r1) */ EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1 r1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Nested Loop Join Filter: (t3.c1 = t4.c1) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (19 rows) EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r1_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (19 rows) /*+ Leading(b1t1 b1t2 b1t3 b1t4 r1_) */ EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Leading(b1t1 b1t2 b1t3 b1t4 r1_) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r1_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (19 rows) -- No. L-2-3-2 EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (39 rows) /*+ Leading(t4 t3 t2 t1 r2) */ EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1 r2) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1 r2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Nested Loop Join Filter: (t3.c1 = t4.c1) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Nested Loop Join Filter: (t3.c1 = t4.c1) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (39 rows) EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) (39 rows) /*+ Leading(b1t1 b1t2 b1t3 b1t4 r2_) Leading(b2t1 b2t2 b2t3 b2t4 r2_) */ EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Leading(b1t1 b1t2 b1t3 b1t4 r2_) not used hint: Leading(b2t1 b2t2 b2t3 b2t4 r2_) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(b2t1 b2t2 b2t3 b2t4 r2_) not used hint: Leading(b1t1 b1t2 b1t3 b1t4 r2_) duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (39 rows) -- No. L-2-3-3 EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (59 rows) /*+ Leading(t4 t3 t2 t1 r3) */ EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1 r3) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1 r3) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(t4 t3 t2 t1 r3) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Nested Loop Join Filter: (t3.c1 = t4.c1) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Nested Loop Join Filter: (t3.c1 = t4.c1) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop Join Filter: (t2.c1 = t3.c1) -> Nested Loop Join Filter: (t3.c1 = t4.c1) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (59 rows) EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) (59 rows) /*+ Leading(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b2t1 b2t2 b2t3 b2t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) */ EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: Leading(b1t1 b1t2 b1t3 b1t4 r3_) not used hint: Leading(b2t1 b2t2 b2t3 b2t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(b2t1 b2t2 b2t3 b2t4 r3_) not used hint: Leading(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(b3t1 b3t2 b3t3 b3t4 r3_) not used hint: Leading(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b2t1 b2t2 b2t3 b2t4 r3_) duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) Aggregate -> Nested Loop -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (59 rows) -- No. L-2-3-4 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; QUERY PLAN ------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 (5 rows) /*+Leading(v1t1 v1t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; INFO: pg_hint_plan: hint syntax error at or near "Leading(v1t1 v1t1)" DETAIL: Relation name "v1t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(v1t1 v1t1) QUERY PLAN ------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 (5 rows) -- No. L-2-3-5 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; QUERY PLAN ----------------------------------- Hash Join Hash Cond: (v1t1.c1 = v1t1_.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_ (5 rows) /*+Leading(v1t1 v1t1_)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; LOG: pg_hint_plan: used hint: Leading(v1t1 v1t1_) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Hash Join Hash Cond: (v1t1.c1 = v1t1_.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_ (5 rows) ---- ---- No. L-2-4 VALUES clause ---- -- No. L-2-4-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; QUERY PLAN ------------------------------------------------- Nested Loop -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (8 rows) /*+ Leading(t3 t1 t2) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(t3 t1 t2) duplication hint: error hint: QUERY PLAN ------------------------------------------------- Nested Loop -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (8 rows) /*+ Leading(*VALUES* t1 t2) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; LOG: pg_hint_plan: used hint: Leading(*VALUES* t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------- Nested Loop -> Nested Loop -> Values Scan on "*VALUES*" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = "*VALUES*".column1) -> Index Scan using t2_i1 on t2 Index Cond: (c1 = t1.c1) (7 rows) -- No. L-2-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; QUERY PLAN ------------------------------------------------------- Nested Loop -> Nested Loop Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Materialize -> Values Scan on "*VALUES*_1" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (12 rows) /*+ Leading(t4 t3 t2 t1) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(t4 t3 t2 t1) duplication hint: error hint: QUERY PLAN ------------------------------------------------------- Nested Loop -> Nested Loop Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Materialize -> Values Scan on "*VALUES*_1" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (12 rows) /*+ Leading(*VALUES* t3 t2 t1) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near " Leading(*VALUES* t3 t2 t1) " DETAIL: Relation name "*VALUES*" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(*VALUES* t3 t2 t1) QUERY PLAN ------------------------------------------------------- Nested Loop -> Nested Loop Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 -> Hash -> Values Scan on "*VALUES*" -> Materialize -> Values Scan on "*VALUES*_1" -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t2.c1) (12 rows) ---- ---- No. L-3-1 leading the order of table joins ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) -- No. L-3-1-1 /*+Leading(t3 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; LOG: pg_hint_plan: used hint: Leading(t3 t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) -- No. L-3-1-2 /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; LOG: pg_hint_plan: used hint: Leading(t1 t2 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) (9 rows) ---- ---- No. L-3-2 GUC parameter to disable hints ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) -- No. L-3-2-1 Set geqo_threshold = 3; Set geqo_seed = 0; /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; LOG: pg_hint_plan: used hint: not used hint: Leading(t1 t2 t3) duplication hint: error hint: QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t3.c1 = t1.c1) -> Index Scan using t3_i1 on t3 -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) Reset geqo_threshold; -- No. L-3-2-2 Set geqo_threshold = 4; Set geqo_seed = 0; /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; LOG: pg_hint_plan: used hint: Leading(t1 t2 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) (9 rows) Reset geqo_threshold; -- No. L-3-2-3 Set from_collapse_limit = 2; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.v2 WHERE t1.c1 = v2.c1; QUERY PLAN ----------------------------------------------------- Hash Join Hash Cond: (t1.c1 = v2t1.c1) -> Seq Scan on t1 -> Hash -> Merge Join Merge Cond: (v2t1.c1 = v2t2.c1) -> Index Scan using t1_i1 on t1 v2t1 -> Sort Sort Key: v2t2.c1 -> Seq Scan on t2 v2t2 (10 rows) /*+Leading(t1 v2t1 v2t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.v2 WHERE t1.c1 = v2.c1; LOG: pg_hint_plan: used hint: Leading(t1 v2t1 v2t2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------- Hash Join Hash Cond: (t1.c1 = v2t1.c1) -> Seq Scan on t1 -> Hash -> Merge Join Merge Cond: (v2t1.c1 = v2t2.c1) -> Index Scan using t1_i1 on t1 v2t1 -> Sort Sort Key: v2t2.c1 -> Seq Scan on t2 v2t2 (10 rows) Reset from_collapse_limit; -- No. L-3-2-4 Set from_collapse_limit = 3; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.v2 WHERE t1.c1 = v2.c1; QUERY PLAN ----------------------------------------------- Merge Join Merge Cond: (v2t1.c1 = v2t2.c1) -> Merge Join Merge Cond: (t1.c1 = v2t1.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t1_i1 on t1 v2t1 -> Sort Sort Key: v2t2.c1 -> Seq Scan on t2 v2t2 (9 rows) /*+Leading(v2t1 v2t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.v2 WHERE t1.c1 = v2.c1; LOG: pg_hint_plan: used hint: Leading(v2t1 v2t2 t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------- Hash Join Hash Cond: (t1.c1 = v2t1.c1) -> Seq Scan on t1 -> Hash -> Merge Join Merge Cond: (v2t1.c1 = v2t2.c1) -> Index Scan using t1_i1 on t1 v2t1 -> Sort Sort Key: v2t2.c1 -> Seq Scan on t2 v2t2 (10 rows) Reset from_collapse_limit; -- No. L-3-2-5 Set join_collapse_limit = 2; EXPLAIN (COSTS false) SELECT * FROM s1.t3 JOIN s1.t2 ON (t3.c1 = t2.c1) JOIN s1.t1 ON (t1.c1 = t3.c1); QUERY PLAN ------------------------------------------ Hash Join Hash Cond: (t1.c1 = t3.c1) -> Seq Scan on t1 -> Hash -> Hash Join Hash Cond: (t3.c1 = t2.c1) -> Seq Scan on t3 -> Hash -> Seq Scan on t2 (9 rows) /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t3 JOIN s1.t2 ON (t3.c1 = t2.c1) JOIN s1.t1 ON (t1.c1 = t3.c1); LOG: pg_hint_plan: used hint: Leading(t1 t2 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Hash Join Hash Cond: (t1.c1 = t3.c1) -> Seq Scan on t1 -> Hash -> Hash Join Hash Cond: (t3.c1 = t2.c1) -> Seq Scan on t3 -> Hash -> Seq Scan on t2 (9 rows) Reset join_collapse_limit; -- No. L-3-2-6 Set join_collapse_limit = 3; EXPLAIN (COSTS false) SELECT * FROM s1.t3 JOIN s1.t2 ON (t3.c1 = t2.c1) JOIN s1.t1 ON (t1.c1 = t3.c1); QUERY PLAN ------------------------------------------ Nested Loop Join Filter: (t3.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) (10 rows) /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t3 JOIN s1.t2 ON (t3.c1 = t2.c1) JOIN s1.t1 ON (t1.c1 = t3.c1); LOG: pg_hint_plan: used hint: Leading(t1 t2 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop Join Filter: (t3.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) (10 rows) Reset join_collapse_limit; ---- ---- No. L-3-3 join between parents or between children ---- -- No. L-3-3-1 /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2c1 t1 JOIN s1.p2c2 t2 ON (t1.c1 = t2.c1) JOIN s1.p2c3 t3 ON (t1.c1 = t3.c1); LOG: pg_hint_plan: used hint: Leading(t1 t2 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Hash Join Hash Cond: (t1.c1 = t3.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Append -> Seq Scan on p2c1 t1_1 -> Seq Scan on p2c1c1 t1_2 -> Seq Scan on p2c1c2 t1_3 -> Hash -> Append -> Seq Scan on p2c2 t2_1 -> Seq Scan on p2c2c1 t2_2 -> Seq Scan on p2c2c2 t2_3 -> Hash -> Append -> Seq Scan on p2c3 t3_1 -> Seq Scan on p2c3c1 t3_2 -> Seq Scan on p2c3c2 t3_3 (18 rows) -- No. L-3-3-2 /*+Leading(p2c1c1 p2c2c1 p2c3c1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2c1 t1 JOIN s1.p2c2 t2 ON (t1.c1 = t2.c1) JOIN s1.p2c3 t3 ON (t1.c1 = t3.c1); LOG: pg_hint_plan: used hint: not used hint: Leading(p2c1c1 p2c2c1 p2c3c1) duplication hint: error hint: QUERY PLAN ------------------------------------------------- Hash Join Hash Cond: (t1.c1 = t3.c1) -> Hash Join Hash Cond: (t1.c1 = t2.c1) -> Append -> Seq Scan on p2c1 t1_1 -> Seq Scan on p2c1c1 t1_2 -> Seq Scan on p2c1c2 t1_3 -> Hash -> Append -> Seq Scan on p2c2 t2_1 -> Seq Scan on p2c2c1 t2_2 -> Seq Scan on p2c2c2 t2_3 -> Hash -> Append -> Seq Scan on p2c3 t3_1 -> Seq Scan on p2c3c1 t3_2 -> Seq Scan on p2c3c2 t3_3 (18 rows) ---- ---- No. L-3-4 conflict leading hint ---- -- No. L-3-4-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) /*+Leading(t2 t3 t1)Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); INFO: pg_hint_plan: hint syntax error at or near "Leading(t2 t3 t1)Leading(t1 t2 t3)" DETAIL: Conflict leading hint. LOG: pg_hint_plan: used hint: Leading(t1 t2 t3) not used hint: duplication hint: Leading(t2 t3 t1) error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) (9 rows) -- No. L-3-4-2 /*+Leading(t3 t1 t2)Leading(t2 t3 t1)Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); INFO: pg_hint_plan: hint syntax error at or near "Leading(t3 t1 t2)Leading(t2 t3 t1)Leading(t1 t2 t3)" DETAIL: Conflict leading hint. INFO: pg_hint_plan: hint syntax error at or near "Leading(t2 t3 t1)Leading(t1 t2 t3)" DETAIL: Conflict leading hint. LOG: pg_hint_plan: used hint: Leading(t1 t2 t3) not used hint: duplication hint: Leading(t3 t1 t2) Leading(t2 t3 t1) error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) (9 rows) -- No. L-3-4-3 /*+Leading(t2 t3 t1)Leading()*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); INFO: pg_hint_plan: hint syntax error at or near "Leading()" DETAIL: Leading hint requires at least two relations. LOG: pg_hint_plan: used hint: Leading(t2 t3 t1) not used hint: duplication hint: error hint: Leading() QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Hash Join Hash Cond: (t3.c1 = t2.c1) -> Seq Scan on t3 -> Hash -> Seq Scan on t2 (10 rows) -- No. L-3-4-4 /*+Leading(t3 t1 t2)Leading(t2 t3 t1)Leading()*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); INFO: pg_hint_plan: hint syntax error at or near "Leading()" DETAIL: Leading hint requires at least two relations. INFO: pg_hint_plan: hint syntax error at or near "Leading(t3 t1 t2)Leading(t2 t3 t1)Leading()" DETAIL: Conflict leading hint. LOG: pg_hint_plan: used hint: Leading(t2 t3 t1) not used hint: duplication hint: Leading(t3 t1 t2) error hint: Leading() QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Hash Join Hash Cond: (t3.c1 = t2.c1) -> Seq Scan on t3 -> Hash -> Seq Scan on t2 (10 rows) ---- ---- No. L-3-5 hint state output ---- -- No. L-3-5-1 /*+Leading()*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); INFO: pg_hint_plan: hint syntax error at or near "Leading()" DETAIL: Leading hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading() QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) -- No. L-3-5-2 /*+Leading(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); INFO: pg_hint_plan: hint syntax error at or near "Leading(t1)" DETAIL: Leading hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading(t1) QUERY PLAN ------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (9 rows) -- No. L-3-5-3 /*+Leading(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); LOG: pg_hint_plan: used hint: Leading(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) (9 rows) -- No. L-3-5-4 /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); LOG: pg_hint_plan: used hint: Leading(t1 t2 t3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t1.c1) (9 rows) ---- ---- No. L-3-6 specified Inner/Outer side ---- -- No. L-3-6-1 /*+Leading((t2))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near "Leading((t2))" DETAIL: Leading hint requires two sets of relations when parentheses nests. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading((t2)) QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) -- No. L-3-6-2 /*+Leading((t2 t3))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading((t2 t3)) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Index Scan using t2_i1 on t2 -> Index Scan using t3_i1 on t3 Index Cond: (c1 = t2.c1) -> Index Scan using t1_i1 on t1 Index Cond: (c1 = t3.c1) -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t3.c1) (12 rows) -- No. L-3-6-3 /*+Leading((t2 t3 t4))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near "Leading((t2 t3 t4))" DETAIL: Leading hint requires two sets of relations when parentheses nests. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Leading((t2 t3 t4)) QUERY PLAN ------------------------------------------------ Nested Loop -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Index Scan using t4_i1 on t4 Index Cond: (c1 = t1.c1) (12 rows) -- No. L-3-6-4 /*+Leading(((t1 t2) (t3 t4)))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading(((t1 t2) (t3 t4))) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Hash Join Hash Cond: (t1.c1 = t3.c1) -> Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 -> Hash -> Hash Join Hash Cond: (t3.c1 = t4.c1) -> Seq Scan on t3 -> Hash -> Seq Scan on t4 (14 rows) -- No. L-3-6-5 /*+Leading((((t1 t3) t4) t2)))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; INFO: pg_hint_plan: hint syntax error at or near ")" DETAIL: Unrecognized hint keyword ")". LOG: pg_hint_plan: used hint: Leading((((t1 t3) t4) t2)) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Merge Join Merge Cond: (t1.c1 = t4.c1) -> Merge Join Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 -> Index Scan using t3_i1 on t3 -> Index Scan using t4_i1 on t4 -> Sort Sort Key: t2.c1 -> Seq Scan on t2 (12 rows) -- No. L-3-6-6 /*+Leading((t1 (t3 (t4 t2))))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; LOG: pg_hint_plan: used hint: Leading((t1 (t3 (t4 t2)))) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------ Merge Join Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 -> Sort Sort Key: t2.c1 -> Hash Join Hash Cond: (t3.c1 = t2.c1) -> Seq Scan on t3 -> Hash -> Hash Join Hash Cond: (t4.c1 = t2.c1) -> Seq Scan on t4 -> Hash -> Seq Scan on t2 (14 rows) pg_hint_plan-REL17_1_7_0/expected/ut-R.out000066400000000000000000006611031466301071500203700ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET jit = off; SET search_path TO public; SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-1-1 specified pattern of the object name ---- -- No. R-1-1-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-1-2 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; '); LOG: pg_hint_plan: used hint: not used hint: Rows(t1 t2 #1) duplication hint: error hint: explain_filter ----------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t_1.c1 = t_2.c1) -> Index Scan using t1_i1 on t1 t_1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t_2.c1 -> Seq Scan on t2 t_2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-1-3 SELECT explain_filter(' /*+Rows(t_1 t_2 #1)*/ EXPLAIN SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; '); LOG: pg_hint_plan: used hint: Rows(t_1 t_2 #1) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t_1.c1 = t_2.c1) -> Index Scan using t1_i1 on t1 t_1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t_2.c1 -> Seq Scan on t2 t_2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-1-2 specified schema name in the hint option ---- -- No. R-1-2-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-2-2 SELECT explain_filter(' /*+Rows(s1.t1 s1.t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: not used hint: Rows(s1.t1 s1.t2 #1) duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-1-3 table doesn't exist in the hint option ---- -- No. R-1-3-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-3-2 SELECT explain_filter(' /*+Rows(t3 t4 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: not used hint: Rows(t3 t4 #1) duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-1-4 conflict table name ---- -- No. R-1-4-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-4-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t1_1.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t1 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; '); INFO: pg_hint_plan: hint syntax error at or near "Rows(t1 t1 #1)" DETAIL: Relation name "t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 t1 #1) explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t1_1.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(s1.t1 s2.t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; '); LOG: pg_hint_plan: used hint: not used hint: Rows(s1.t1 s2.t1 #1) duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t1_1.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t1_1.c1 -> Seq Scan on t1 t1_1 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = s2t1.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: s2t1.c1 -> Seq Scan on t1 s2t1 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t1 s2t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; '); LOG: pg_hint_plan: used hint: Rows(s2t1 t1 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = s2t1.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: s2t1.c1 -> Seq Scan on t1 s2t1 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-4-3 SELECT explain_filter(' EXPLAIN SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1_1.c1 = t2_1.c1) -> Index Only Scan using t1_i1 on t1 t1_1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2_1.c1 -> Seq Scan on t2 t2_1 (cost=xxx..xxx rows=100 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (14 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1_1.c1 = t2_1.c1) -> Index Only Scan using t1_i1 on t1 t1_1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2_1.c1 -> Seq Scan on t2 t2_1 (cost=xxx..xxx rows=100 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (14 rows) SELECT explain_filter(' /*+Rows(st1 st2 #1)Rows(t1 t2 #1)*/ EXPLAIN SELECT *, (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(st1 st2 #1) Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------ Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (st1.c1 = st2.c1) -> Index Only Scan using t1_i1 on t1 st1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: st2.c1 -> Seq Scan on t2 st2 (cost=xxx..xxx rows=100 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (14 rows) ---- ---- No. R-1-5 conflict table name ---- -- No. R-1-5-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-5-2 SELECT explain_filter(' /*+Rows(t1 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "Rows(t1 t1 #1)" DETAIL: Relation name "t1" is duplicated. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 t1 #1) explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-5-3 SELECT explain_filter(' /*+(t1 t1)(t2 t2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "(t1 t1)(t2 t2)" DETAIL: Unrecognized hint keyword "". explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; '); explain_filter ------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Scan using t3_i1 on t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (9 rows) SELECT explain_filter(' /*+(t1 t2 t1 t2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; '); INFO: pg_hint_plan: hint syntax error at or near "(t1 t2 t1 t2)" DETAIL: Unrecognized hint keyword "". explain_filter ------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (t1.c1 = t3.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Scan using t3_i1 on t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Scan using t4_i1 on t4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = t1.c1) (12 rows) ---- ---- No. R-1-6 object type for the hint ---- -- No. R-1-6-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-6-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; '); explain_filter ----------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=301 width=xxx) Hash Cond: (t1.c1 = t2.c1) -> Append (cost=xxx..xxx rows=301 width=xxx) -> Seq Scan on p1 t1_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p1c1 t1_2 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c2 t1_3 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c3 t1_4 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=301 width=xxx) -> Append (cost=xxx..xxx rows=301 width=xxx) -> Seq Scan on p1 t2_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p1c1 t2_2 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c2 t2_3 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c3 t2_4 (cost=xxx..xxx rows=100 width=xxx) (13 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (t1.c1 = t2.c1) -> Append (cost=xxx..xxx rows=301 width=xxx) -> Seq Scan on p1 t1_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p1c1 t1_2 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c2 t1_3 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c3 t1_4 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=301 width=xxx) -> Append (cost=xxx..xxx rows=301 width=xxx) -> Seq Scan on p1 t2_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p1c1 t2_2 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c2 t2_3 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c3 t2_4 (cost=xxx..xxx rows=100 width=xxx) (13 rows) -- No. R-1-6-3 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; '); explain_filter --------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on ul1 t1 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on ul1 t2 (cost=xxx..xxx rows=1130 width=xxx) (5 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter --------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on ul1 t1 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on ul1 t2 (cost=xxx..xxx rows=1130 width=xxx) (5 rows) -- No. R-1-6-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); SELECT explain_filter(' EXPLAIN SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; '); explain_filter --------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on tm1 t1 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on tm1 t2 (cost=xxx..xxx rows=1130 width=xxx) (5 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter --------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (t1.c1 = t2.c1) -> Seq Scan on tm1 t1 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on tm1 t2 (cost=xxx..xxx rows=1130 width=xxx) (5 rows) -- No. R-1-6-5 CREATE TEMP TABLE t_pg_class AS SELECT * from pg_class LIMIT 100; SELECT explain_filter(' EXPLAIN SELECT * FROM t_pg_class t1, t_pg_class t2 WHERE t1.oid = t2.oid; '); explain_filter --------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=450 width=xxx) Hash Cond: (t1.oid = t2.oid) -> Seq Scan on t_pg_class t1 (cost=xxx..xxx rows=300 width=xxx) -> Hash (cost=xxx..xxx rows=300 width=xxx) -> Seq Scan on t_pg_class t2 (cost=xxx..xxx rows=300 width=xxx) (5 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM t_pg_class t1, t_pg_class t2 WHERE t1.oid = t2.oid; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter --------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (t1.oid = t2.oid) -> Seq Scan on t_pg_class t1 (cost=xxx..xxx rows=300 width=xxx) -> Hash (cost=xxx..xxx rows=300 width=xxx) -> Seq Scan on t_pg_class t2 (cost=xxx..xxx rows=300 width=xxx) (5 rows) -- No. R-1-6-6 -- refer ut-fdw.sql -- No. R-1-6-7 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; '); explain_filter ---------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t2.c1) -> Function Scan on f1 t1 (cost=xxx..xxx rows=1 width=xxx) -> Function Scan on f1 t2 (cost=xxx..xxx rows=1 width=xxx) (4 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t2.c1) -> Function Scan on f1 t1 (cost=xxx..xxx rows=1 width=xxx) -> Function Scan on f1 t2 (cost=xxx..xxx rows=1 width=xxx) (4 rows) -- No. R-1-6-8 SELECT explain_filter(' EXPLAIN SELECT * FROM (VALUES(1,1,1,''1''), (2,2,2,''2''), (3,3,3,''3'')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=3 width=xxx) Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=3 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=3 width=xxx) (5 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM (VALUES(1,1,1,''1''), (2,2,2,''2''), (3,3,3,''3'')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: not used hint: Rows(t1 t2 #1) duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=3 width=xxx) Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=3 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=3 width=xxx) (5 rows) SELECT explain_filter(' /*+Rows(*VALUES* t2 #1)*/ EXPLAIN SELECT * FROM (VALUES(1,1,1,''1''), (2,2,2,''2''), (3,3,3,''3'')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(*VALUES* t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=3 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=3 width=xxx) (5 rows) -- No. R-1-6-9 SELECT explain_filter(' EXPLAIN WITH c1(c1) AS (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = c1.c1; '); explain_filter ----------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1_1.c1 = t2.c1) -> Index Only Scan using t1_i1 on t1 t1_1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = (max(t1_1.c1))) (10 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(t1 c1 +1)*/ EXPLAIN WITH c1(c1) AS (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = c1.c1; '); LOG: pg_hint_plan: used hint: Rows(c1 t1 +1) Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1_1.c1 = t2.c1) -> Index Only Scan using t1_i1 on t1 t1_1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = (max(t1_1.c1))) (10 rows) -- No. R-1-6-10 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------ Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 v1t1_1 (cost=xxx..xxx rows=1000 width=xxx) (5 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: not used hint: Rows(t1 t2 #1) duplication hint: error hint: explain_filter ------------------------------------------------------------------------ Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 v1t1_1 (cost=xxx..xxx rows=1000 width=xxx) (5 rows) SELECT explain_filter(' /*+Rows(v1t1 v1t1_ #1)*/ EXPLAIN SELECT * FROM s1.v1 t1, s1.v1_ t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(v1t1 v1t1_ #1) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (v1t1.c1 = v1t1_.c1) -> Seq Scan on t1 v1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 v1t1_ (cost=xxx..xxx rows=1000 width=xxx) (5 rows) -- No. R-1-6-11 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.c1 = (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1); '); explain_filter ------------------------------------------------------------------------------------------------ Nested Loop (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (st1.c1 = st2.c1) -> Index Only Scan using t1_i1 on t1 st1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: st2.c1 -> Seq Scan on t2 st2 (cost=xxx..xxx rows=100 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = (InitPlan 1).col1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (c1 = (InitPlan 1).col1) (13 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(st1 st2 #1)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.c1 = (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1); '); LOG: pg_hint_plan: used hint: Rows(st1 st2 #1) Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------ Nested Loop (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (st1.c1 = st2.c1) -> Index Only Scan using t1_i1 on t1 st1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: st2.c1 -> Seq Scan on t2 st2 (cost=xxx..xxx rows=100 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = (InitPlan 1).col1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (c1 = (InitPlan 1).col1) (13 rows) -- -- There are cases where difference in the measured value and predicted value -- depending upon the version of PostgreSQL -- SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t1 st2 #1)*/ EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; '); LOG: pg_hint_plan: used hint: not used hint: Rows(st2 t1 #1) duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-1-7 specified number of conditions ---- -- No. R-1-7-1 SELECT explain_filter(' /*+Rows(t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: Rows hint requires at least two relations. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 #1) explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-7-2 SELECT explain_filter(' /*+Rows(t1 t2 1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "1" DETAIL: Unrecognized rows value type notation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 t2 1) explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-1-7-3 SELECT explain_filter(' /*+Rows(t1 t2 #notrows)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "notrows" DETAIL: Rows hint requires valid number as rows estimation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 t2 #notrows) explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-2-1 some complexity query blocks ---- -- No. R-2-1-1 SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ;'); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) InitPlan 2 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (b2t3.c1 = b2t1.c1) -> Merge Join (cost=xxx..xxx rows=1130 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (43 rows) SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) Rows(bmt1 bmt2 #1)Rows(bmt1 bmt2 bmt3 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) */ EXPLAIN SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; '); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Rows(b1t2 b1t3 #1) Rows(b2t3 b2t4 #1) Rows(bmt1 bmt2 #1) Rows(b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t3 b2t4 #1) Rows(bmt1 bmt2 bmt3 #1) Rows(b1t1 b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t2 b2t3 b2t4 #1) Rows(bmt1 bmt2 bmt3 bmt4 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) InitPlan 2 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b2t1.c1 = b2t3.c1) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (43 rows) -- No. R-2-1-2 SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; '); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) InitPlan 2 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (b2t3.c1 = b2t1.c1) -> Merge Join (cost=xxx..xxx rows=1130 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) InitPlan 3 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b3t1.c1 = b3t2.c1) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (b3t1.c1 = b3t4.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t4_i1 on t4 b3t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t3_i1 on t3 b3t3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b3t1.c1) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (56 rows) SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) Rows(bmt1 bmt2 #1)Rows(bmt1 bmt2 bmt3 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) Rows(b3t4 b3t1 #1)Rows(b3t4 b3t1 b3t2 #1)Rows(b3t1 b3t2 b3t3 b3t4 #1) */ EXPLAIN SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ;'); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) Rows(b1t2 b1t3 #1) Rows(b2t3 b2t4 #1) Rows(b3t1 b3t4 #1) Rows(bmt1 bmt2 #1) Rows(b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t3 b2t4 #1) Rows(b3t1 b3t2 b3t4 #1) Rows(bmt1 bmt2 bmt3 #1) Rows(b1t1 b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t2 b2t3 b2t4 #1) Rows(b3t1 b3t2 b3t3 b3t4 #1) Rows(bmt1 bmt2 bmt3 bmt4 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) InitPlan 2 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b2t1.c1 = b2t3.c1) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) InitPlan 3 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b3t1.c1 = b3t2.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b3t1.c1 = b3t4.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t4_i1 on t4 b3t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t3_i1 on t3 b3t3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b3t1.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (56 rows) -- No. R-2-1-3 SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (bmt3.c1 = bmt2.c1) -> Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (bmt3.c1 = bmt4.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) (15 rows) SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt4 bmt3 #1)Rows(bmt4 bmt3 bmt2 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt3 bmt4 #1) Rows(bmt2 bmt3 bmt4 #1) Rows(bmt1 bmt2 bmt3 bmt4 #1) not used hint: duplication hint: error hint: explain_filter -------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt3.c1 = bmt4.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt3.c1) (13 rows) -- No. R-2-1-4 SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (bmt3.c1 = bmt2.c1) -> Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (bmt3.c1 = bmt4.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) (15 rows) SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt4 bmt3 #1)Rows(bmt4 bmt3 bmt2 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt3 bmt4 #1) Rows(bmt2 bmt3 bmt4 #1) Rows(bmt1 bmt2 bmt3 bmt4 #1) not used hint: duplication hint: error hint: explain_filter -------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt3.c1 = bmt4.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt3.c1) (13 rows) -- No. R-2-1-5 SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ); '); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) InitPlan 2 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (b2t3.c1 = b2t1.c1) -> Merge Join (cost=xxx..xxx rows=1130 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=998 width=xxx) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1)) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (44 rows) SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) Rows(bmt1 bmt2 #1)Rows(bmt1 bmt2 bmt3 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) ;'); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Rows(b1t2 b1t3 #1) Rows(b2t3 b2t4 #1) Rows(bmt1 bmt2 #1) Rows(b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t3 b2t4 #1) Rows(bmt1 bmt2 bmt3 #1) Rows(b1t1 b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t2 b2t3 b2t4 #1) Rows(bmt1 bmt2 bmt3 bmt4 #1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) InitPlan 2 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b2t1.c1 = b2t3.c1) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=998 width=xxx) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1)) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (44 rows) -- No. R-2-1-6 SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) ;'); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: explain_filter --------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) InitPlan 2 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (b2t3.c1 = b2t1.c1) -> Merge Join (cost=xxx..xxx rows=1130 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) InitPlan 3 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b3t1.c1 = b3t2.c1) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (b3t1.c1 = b3t4.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t4_i1 on t4 b3t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t3_i1 on t3 b3t3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b3t1.c1) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=997 width=xxx) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1) AND (c1 <> (InitPlan 3).col1)) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (57 rows) SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) Rows(bmt1 bmt2 #1)Rows(bmt1 bmt2 bmt3 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) Rows(b3t4 b3t1 #1)Rows(b3t4 b3t1 b3t2 #1)Rows(b3t1 b3t2 b3t3 b3t4 #1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) ;'); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(bmt1 bmt2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(bmt1 bmt2 bmt3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 bmt2 bmt3 bmt4) Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) Rows(b1t2 b1t3 #1) Rows(b2t3 b2t4 #1) Rows(b3t1 b3t4 #1) Rows(bmt1 bmt2 #1) Rows(b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t3 b2t4 #1) Rows(b3t1 b3t2 b3t4 #1) Rows(bmt1 bmt2 bmt3 #1) Rows(b1t1 b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t2 b2t3 b2t4 #1) Rows(b3t1 b3t2 b3t3 b3t4 #1) Rows(bmt1 bmt2 bmt3 bmt4 #1) not used hint: duplication hint: error hint: explain_filter --------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) InitPlan 2 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b2t1.c1 = b2t3.c1) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) InitPlan 3 -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b3t1.c1 = b3t2.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b3t1.c1 = b3t4.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t4_i1 on t4 b3t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t3_i1 on t3 b3t3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b3t1.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=997 width=xxx) Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1) AND (c1 <> (InitPlan 3).col1)) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (57 rows) -- No. R-2-1-7 SELECT explain_filter(' /*+ Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(c2 c1)HashJoin(c2 c1 bmt1)NestLoop(c2 c1 bmt1 bmt2)MergeJoin(c2 c1 bmt1 bmt2 bmt3)HashJoin(c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ;'); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(c1 c2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 c1 c2) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 c1 c2) MergeJoin(bmt1 bmt2 bmt3 c1 c2) HashJoin(bmt1 bmt2 bmt3 bmt4 c1 c2) Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (bmt3.c1 = bmt1.c1) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: bmt1.c1 -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt1.c1 = (max(b1t1.c1))) -> Seq Scan on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: ((max(b1t1.c1)) = (max(b2t1.c1))) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: (max(b1t1.c1)) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: (max(b2t1.c1)) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (b2t3.c1 = b2t1.c1) -> Merge Join (cost=xxx..xxx rows=1130 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (50 rows) SELECT explain_filter(' /*+ Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(c2 c1)HashJoin(c2 c1 bmt1)NestLoop(c2 c1 bmt1 bmt2)MergeJoin(c2 c1 bmt1 bmt2 bmt3)HashJoin(c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) Rows(c2 c1 #1)Rows(c2 c1 bmt1 #1)Rows(c2 c1 bmt1 bmt2 #1)Rows(c2 c1 bmt1 bmt2 bmt3 #1)Rows(c2 c1 bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1; '); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(c1 c2) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(bmt1 c1 c2) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(bmt1 bmt2 c1 c2) MergeJoin(bmt1 bmt2 bmt3 c1 c2) HashJoin(bmt1 bmt2 bmt3 bmt4 c1 c2) Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Rows(b1t2 b1t3 #1) Rows(b2t3 b2t4 #1) Rows(c1 c2 #1) Rows(b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t3 b2t4 #1) Rows(bmt1 c1 c2 #1) Rows(b1t1 b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t2 b2t3 b2t4 #1) Rows(bmt1 bmt2 c1 c2 #1) Rows(bmt1 bmt2 bmt3 c1 c2 #1) Rows(bmt1 bmt2 bmt3 bmt4 c1 c2 #1) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (bmt3.c1 = bmt1.c1) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: bmt1.c1 -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt1.c1 = (max(b1t1.c1))) -> Seq Scan on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: ((max(b1t1.c1)) = (max(b2t1.c1))) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: (max(b1t1.c1)) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: (max(b2t1.c1)) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b2t1.c1 = b2t3.c1) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (50 rows) -- No. R-2-1-8 SELECT explain_filter(' /*+ Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(c3 c2)HashJoin(c3 c2 c1)NestLoop(c3 c2 c1 bmt1)MergeJoin(c3 c2 c1 bmt1 bmt2)HashJoin(c3 c2 c1 bmt1 bmt2 bmt3)NestLoop(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1; '); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(c2 c3) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(c1 c2 c3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 c1 c2 c3) MergeJoin(bmt1 bmt2 c1 c2 c3) HashJoin(bmt1 bmt2 bmt3 c1 c2 c3) NestLoop(bmt1 bmt2 bmt3 bmt4 c1 c2 c3) Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: bmt1.c1 -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: ((max(b2t1.c1)) = (max(b1t1.c1))) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: ((max(b2t1.c1)) = (max(b3t1.c1))) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: (max(b2t1.c1)) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (b2t3.c1 = b2t1.c1) -> Merge Join (cost=xxx..xxx rows=1130 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: (max(b3t1.c1)) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b3t1.c1 = b3t2.c1) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (b3t1.c1 = b3t4.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t4_i1 on t4 b3t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t3_i1 on t3 b3t3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b3t1.c1) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = (max(b2t1.c1))) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (67 rows) SELECT explain_filter(' /*+ Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(c3 c2)HashJoin(c3 c2 c1)NestLoop(c3 c2 c1 bmt1)MergeJoin(c3 c2 c1 bmt1 bmt2)HashJoin(c3 c2 c1 bmt1 bmt2 bmt3)NestLoop(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) Rows(c3 c2 #1)Rows(c3 c2 c1 #1)Rows(c3 c2 c1 bmt1 #1)Rows(c3 c2 c1 bmt1 bmt2 #1)Rows(c3 c2 c1 bmt1 bmt2 bmt3 #1)Rows(c3 c2 c1 bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) Rows(b3t4 b3t1 #1)Rows(b3t4 b3t1 b3t2 #1)Rows(b3t1 b3t2 b3t3 b3t4 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1; '); LOG: pg_hint_plan: used hint: MergeJoin(b1t2 b1t3) MergeJoin(b2t3 b2t4) MergeJoin(b3t1 b3t4) MergeJoin(c2 c3) HashJoin(b1t2 b1t3 b1t4) HashJoin(b2t1 b2t3 b2t4) HashJoin(b3t1 b3t2 b3t4) HashJoin(c1 c2 c3) NestLoop(b1t1 b1t2 b1t3 b1t4) NestLoop(b2t1 b2t2 b2t3 b2t4) NestLoop(b3t1 b3t2 b3t3 b3t4) NestLoop(bmt1 c1 c2 c3) MergeJoin(bmt1 bmt2 c1 c2 c3) HashJoin(bmt1 bmt2 bmt3 c1 c2 c3) NestLoop(bmt1 bmt2 bmt3 bmt4 c1 c2 c3) Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) Rows(b1t2 b1t3 #1) Rows(b2t3 b2t4 #1) Rows(b3t1 b3t4 #1) Rows(c2 c3 #1) Rows(b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t3 b2t4 #1) Rows(b3t1 b3t2 b3t4 #1) Rows(c1 c2 c3 #1) Rows(b1t1 b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t2 b2t3 b2t4 #1) Rows(b3t1 b3t2 b3t3 b3t4 #1) Rows(bmt1 c1 c2 c3 #1) Rows(bmt1 bmt2 c1 c2 c3 #1) Rows(bmt1 bmt2 bmt3 c1 c2 c3 #1) Rows(bmt1 bmt2 bmt3 bmt4 c1 c2 c3 #1) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (bmt3.c1 = bmt1.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: bmt1.c1 -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: ((max(b2t1.c1)) = (max(b1t1.c1))) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: ((max(b2t1.c1)) = (max(b3t1.c1))) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: (max(b2t1.c1)) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b2t1.c1 = b2t3.c1) -> Seq Scan on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t3.c1 = b2t4.c1) -> Index Only Scan using t3_i1 on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t1.c1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: (max(b3t1.c1)) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b3t1.c1 = b3t2.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b3t1.c1 = b3t4.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t4_i1 on t4 b3t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t3_i1 on t3 b3t3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b3t1.c1) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b1t4.c1 = b1t2.c1) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t3.c1 = b1t2.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = (max(b2t1.c1))) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (67 rows) ---- ---- No. R-2-2 the number of the tables per quiry block ---- -- No. R-2-2-1 SELECT explain_filter(' /*+ Leading(c1 bmt1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1 WHERE b1t1.c1 = 1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.c1 = 1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1 WHERE b3t1.c1 = 1 ); '); LOG: pg_hint_plan: used hint: not used hint: Leading(c1 bmt1) duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) InitPlan 2 -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) Filter: (c1 <> (InitPlan 2).col1) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) (12 rows) SELECT explain_filter(' /*+ Leading(c1 bmt1) Rows(bmt1 c1 #1) Rows(b1t1 c1 #1) Rows(b2t1 c1 #1) Rows(b3t1 c1 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1 WHERE b1t1.c1 = 1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.c1 = 1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1 WHERE b3t1.c1 = 1 ); '); LOG: pg_hint_plan: used hint: not used hint: Leading(c1 bmt1) Rows(b1t1 c1 #1) Rows(b2t1 c1 #1) Rows(b3t1 c1 #1) Rows(bmt1 c1 #1) duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) InitPlan 2 -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) Filter: (c1 <> (InitPlan 2).col1) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) (12 rows) -- No. R-2-2-2 SELECT explain_filter(' /*+ Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) MergeJoin(c1 bmt2) HashJoin(c1 bmt1 bmt2) MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.c1 = b1t2.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.c1 = b2t2.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.c1 = b3t2.c1 ); '); LOG: pg_hint_plan: used hint: MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) not used hint: MergeJoin(bmt2 c1) HashJoin(bmt1 bmt2 c1) Leading(c1 bmt2 bmt1) duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) InitPlan 1 -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b2t1.c1 = b2t2.c1) -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 (cost=xxx..xxx rows=100 width=xxx) InitPlan 2 -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b3t1.c1 = b3t2.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b3t2.c1 -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=100 width=xxx) -> Nested Loop (cost={inf}..{inf} rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b1t1.c1 = b1t2.c1) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t1.c1) Filter: (c1 <> (InitPlan 2).col1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t1.c1) (28 rows) SELECT explain_filter(' /*+ Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) MergeJoin(c1 bmt2) HashJoin(c1 bmt1 bmt2) MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) Rows(c1 bmt2 #1) Rows(c1 bmt1 bmt2 #1) Rows(b1t1 b1t2 #1) Rows(b2t1 b2t2 #1) Rows(b3t1 b3t2 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.c1 = b1t2.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.c1 = b2t2.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.c1 = b3t2.c1 ) ; '); LOG: pg_hint_plan: used hint: MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) Rows(b1t1 b1t2 #1) Rows(b2t1 b2t2 #1) Rows(b3t1 b3t2 #1) not used hint: MergeJoin(bmt2 c1) HashJoin(bmt1 bmt2 c1) Leading(c1 bmt2 bmt1) Rows(bmt2 c1 #1) Rows(bmt1 bmt2 c1 #1) duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) InitPlan 1 -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t1.c1 = b2t2.c1) -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 (cost=xxx..xxx rows=100 width=xxx) InitPlan 2 -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b3t1.c1 = b3t2.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b3t2.c1 -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=100 width=xxx) -> Nested Loop (cost={inf}..{inf} rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t1.c1 = b1t2.c1) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t1.c1) Filter: (c1 <> (InitPlan 2).col1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t1.c1) (28 rows) -- No. R-2-2-3 SELECT explain_filter(' /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) HashJoin(b1t4 b1t3) NestLoop(b1t4 b1t3 b1t2) MergeJoin(b1t4 b1t3 b1t2 b1t1) HashJoin(b2t4 b2t3) NestLoop(b2t4 b2t3 b2t2) MergeJoin(b2t4 b2t3 b2t2 b2t1) HashJoin(b3t4 b3t3) NestLoop(b3t4 b3t3 b3t2) MergeJoin(b3t4 b3t3 b3t2 b3t1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ); '); LOG: pg_hint_plan: used hint: HashJoin(b1t3 b1t4) HashJoin(b2t3 b2t4) HashJoin(b3t3 b3t4) NestLoop(b1t2 b1t3 b1t4) NestLoop(b2t2 b2t3 b2t4) NestLoop(b3t2 b3t3 b3t4) MergeJoin(b1t1 b1t2 b1t3 b1t4) MergeJoin(b2t1 b2t2 b2t3 b2t4) MergeJoin(b3t1 b3t2 b3t3 b3t4) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) not used hint: MergeJoin(bmt4 c1) HashJoin(bmt3 bmt4 c1) NestLoop(bmt2 bmt3 bmt4 c1) MergeJoin(bmt1 bmt2 bmt3 bmt4 c1) Leading(c1 bmt4 bmt3 bmt2 bmt1) duplication hint: error hint: explain_filter -------------------------------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt4.c1) InitPlan 1 -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b2t1.c1 = b2t2.c1) -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b2t2.c1 -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (b2t3.c1 = b2t4.c1) -> Seq Scan on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t3.c1) InitPlan 2 -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b3t1.c1 = b3t2.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b3t2.c1 -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (b3t3.c1 = b3t4.c1) -> Seq Scan on t3 b3t3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 b3t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b3t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b3t3.c1) -> Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop (cost={inf}..{inf} rows=100 width=xxx) Join Filter: (bmt1.c1 = b1t1.c1) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (b1t1.c1 = b1t2.c1) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: b1t2.c1 -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (b1t3.c1 = b1t4.c1) -> Seq Scan on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b1t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) Filter: (c1 <> (InitPlan 2).col1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt3.c1) (58 rows) SELECT explain_filter(' /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) HashJoin(b1t4 b1t3) NestLoop(b1t4 b1t3 b1t2) MergeJoin(b1t4 b1t3 b1t2 b1t1) HashJoin(b2t4 b2t3) NestLoop(b2t4 b2t3 b2t2) MergeJoin(b2t4 b2t3 b2t2 b2t1) HashJoin(b3t4 b3t3) NestLoop(b3t4 b3t3 b3t2) MergeJoin(b3t4 b3t3 b3t2 b3t1) Rows(c1 bmt4 #1) Rows(c1 bmt4 bmt3 #1) Rows(c1 bmt4 bmt3 bmt2 #1) Rows(c1 bmt4 bmt3 bmt2 bmt1 #1) Rows(b1t4 b1t3 #1) Rows(b1t4 b1t3 b1t2 #1) Rows(b1t4 b1t3 b1t2 b1t1 #1) Rows(b2t4 b2t3 #1) Rows(b2t4 b2t3 b2t2 #1) Rows(b2t4 b2t3 b2t2 b2t1 #1) Rows(b3t4 b3t3 #1) Rows(b3t4 b3t3 b3t2 #1) Rows(b3t4 b3t3 b3t2 b3t1 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ); '); LOG: pg_hint_plan: used hint: HashJoin(b1t3 b1t4) HashJoin(b2t3 b2t4) HashJoin(b3t3 b3t4) NestLoop(b1t2 b1t3 b1t4) NestLoop(b2t2 b2t3 b2t4) NestLoop(b3t2 b3t3 b3t4) MergeJoin(b1t1 b1t2 b1t3 b1t4) MergeJoin(b2t1 b2t2 b2t3 b2t4) MergeJoin(b3t1 b3t2 b3t3 b3t4) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) Rows(b1t3 b1t4 #1) Rows(b2t3 b2t4 #1) Rows(b3t3 b3t4 #1) Rows(b1t2 b1t3 b1t4 #1) Rows(b2t2 b2t3 b2t4 #1) Rows(b3t2 b3t3 b3t4 #1) Rows(b1t1 b1t2 b1t3 b1t4 #1) Rows(b2t1 b2t2 b2t3 b2t4 #1) Rows(b3t1 b3t2 b3t3 b3t4 #1) not used hint: MergeJoin(bmt4 c1) HashJoin(bmt3 bmt4 c1) NestLoop(bmt2 bmt3 bmt4 c1) MergeJoin(bmt1 bmt2 bmt3 bmt4 c1) Leading(c1 bmt4 bmt3 bmt2 bmt1) Rows(bmt4 c1 #1) Rows(bmt3 bmt4 c1 #1) Rows(bmt2 bmt3 bmt4 c1 #1) Rows(bmt1 bmt2 bmt3 bmt4 c1 #1) duplication hint: error hint: explain_filter -------------------------------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt4.c1) InitPlan 1 -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t1.c1 = b2t2.c1) -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b2t2.c1 -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b2t3.c1 = b2t4.c1) -> Seq Scan on t3 b2t3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 b2t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b2t3.c1) InitPlan 2 -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b3t1.c1 = b3t2.c1) -> Index Only Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b3t2.c1 -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b3t3.c1 = b3t4.c1) -> Seq Scan on t3 b3t3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 b3t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b3t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b3t3.c1) -> Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop (cost={inf}..{inf} rows=100 width=xxx) Join Filter: (bmt1.c1 = b1t1.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t1.c1 = b1t2.c1) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b1t2.c1 -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b1t3.c1 = b1t4.c1) -> Seq Scan on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t2_i1 on t2 b1t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) Filter: (c1 <> (InitPlan 2).col1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt3.c1) (58 rows) -- No. R-2-2-4 SELECT explain_filter(' /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) MergeJoin(b1t4 b1t3) HashJoin(b1t4 b1t3 b1t2) NestLoop(b1t4 b1t3 b1t2 b1t1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1 ); '); LOG: pg_hint_plan: used hint: MergeJoin(b1t3 b1t4) HashJoin(b1t2 b1t3 b1t4) NestLoop(b1t1 b1t2 b1t3 b1t4) Leading(b1t4 b1t3 b1t2 b1t1) not used hint: MergeJoin(bmt4 c1) HashJoin(bmt3 bmt4 c1) NestLoop(bmt2 bmt3 bmt4 c1) MergeJoin(bmt1 bmt2 bmt3 bmt4 c1) Leading(c1 bmt4 bmt3 bmt2 bmt1) duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt4.c1) InitPlan 1 -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) InitPlan 2 -> Seq Scan on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop (cost={inf}..{inf} rows=100 width=xxx) Join Filter: (bmt2.c1 = b1t1.c1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Materialize (cost=xxx..xxx rows=100 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (b1t3.c1 = b1t2.c1) -> Merge Join (cost=xxx..xxx rows=1130 width=xxx) Merge Cond: (b1t3.c1 = b1t4.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) Filter: (c1 <> (InitPlan 2).col1) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt3.c1) (34 rows) SELECT explain_filter(' /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) MergeJoin(b1t4 b1t3) HashJoin(b1t4 b1t3 b1t2) NestLoop(b1t4 b1t3 b1t2 b1t1) Rows(c1 bmt4 #1) Rows(c1 bmt4 bmt3 #1) Rows(c1 bmt4 bmt3 bmt2 #1) Rows(c1 bmt4 bmt3 bmt2 bmt1 #1) Rows(b1t4 b1t3 #1) Rows(b1t4 b1t3 b1t2 #1) Rows(b1t4 b1t3 b1t2 b1t1 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1 ); '); LOG: pg_hint_plan: used hint: MergeJoin(b1t3 b1t4) HashJoin(b1t2 b1t3 b1t4) NestLoop(b1t1 b1t2 b1t3 b1t4) Leading(b1t4 b1t3 b1t2 b1t1) Rows(b1t3 b1t4 #1) Rows(b1t2 b1t3 b1t4 #1) Rows(b1t1 b1t2 b1t3 b1t4 #1) not used hint: MergeJoin(bmt4 c1) HashJoin(bmt3 bmt4 c1) NestLoop(bmt2 bmt3 bmt4 c1) MergeJoin(bmt1 bmt2 bmt3 bmt4 c1) Leading(c1 bmt4 bmt3 bmt2 bmt1) Rows(bmt4 c1 #1) Rows(bmt3 bmt4 c1 #1) Rows(bmt2 bmt3 bmt4 c1 #1) Rows(bmt1 bmt2 bmt3 bmt4 c1 #1) duplication hint: error hint: explain_filter ----------------------------------------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt4.c1) InitPlan 1 -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) InitPlan 2 -> Seq Scan on t1 b3t1 (cost=xxx..xxx rows=1000 width=xxx) -> Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop (cost={inf}..{inf} rows=100 width=xxx) Join Filter: (bmt2.c1 = b1t1.c1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Materialize (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (b1t3.c1 = b1t2.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t3.c1 = b1t4.c1) -> Index Only Scan using t3_i1 on t3 b1t3 (cost=xxx..xxx rows=1130 width=xxx) -> Index Only Scan using t4_i1 on t4 b1t4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) Filter: (c1 <> (InitPlan 2).col1) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t3.c1) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt3.c1) (34 rows) ---- ---- No. R-2-3 RULE or VIEW ---- -- No. R-2-3-1 SELECT explain_filter(' /*+ Leading(r1 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r1 t1 t2 t3 t4) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r1 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) (20 rows) SELECT explain_filter(' /*+ Leading(r1 t1 t2 t3 t4) Rows(r1 t1 t2 t3 t4 #2) Rows(r1 t1 t2 t3 #2) Rows(r1 t1 t2 #2) Rows(r1 t1 #2) */ EXPLAIN UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r1 t1 t2 t3 t4) Rows(r1 t1 #2) Rows(r1 t1 t2 #2) Rows(r1 t1 t2 t3 #2) Rows(r1 t1 t2 t3 t4 #2) not used hint: duplication hint: error hint: explain_filter -------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t2.c1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r1 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) (18 rows) SELECT explain_filter(' /*+ Leading(r1_ b1t1 b1t2 b1t3 b1t4) */ EXPLAIN UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r1_ b1t1 b1t2 b1t3 b1t4) not used hint: duplication hint: error hint: explain_filter --------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t1.c1 = b1t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r1_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) (20 rows) SELECT explain_filter(' /*+ Leading(r1_ b1t1 b1t2 b1t3 b1t4) Rows(r1_ b1t1 b1t2 b1t3 b1t4 #2) Rows(r1_ b1t1 b1t2 b1t3 #2) Rows(r1_ b1t1 b1t2 #2) Rows(r1_ b1t1 #2) */ EXPLAIN UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r1_ b1t1 b1t2 b1t3 b1t4) Rows(b1t1 r1_ #2) Rows(b1t1 b1t2 r1_ #2) Rows(b1t1 b1t2 b1t3 r1_ #2) Rows(b1t1 b1t2 b1t3 b1t4 r1_ #2) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t4.c1) -> Tid Scan on t4 b1t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t3.c1) -> Tid Scan on t3 b1t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r1_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) (18 rows) -- No. R-2-3-2 SELECT explain_filter(' /*+ Leading(r2 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r2 t1 t2 t3 t4) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r2 t1 t2 t3 t4) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r2 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r2 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) (41 rows) SELECT explain_filter(' /*+ Leading(r2 t1 t2 t3 t4) Rows(r2 t1 t2 t3 t4 #2) Rows(r2 t1 t2 t3 #2) Rows(r2 t1 t2 #2) Rows(r2 t1 #2) */ EXPLAIN UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r2 t1 t2 t3 t4) Rows(r2 t1 #2) Rows(r2 t1 t2 #2) Rows(r2 t1 t2 t3 #2) Rows(r2 t1 t2 t3 t4 #2) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r2 t1 t2 t3 t4) Rows(r2 t1 #2) Rows(r2 t1 t2 #2) Rows(r2 t1 t2 t3 #2) Rows(r2 t1 t2 t3 t4 #2) not used hint: duplication hint: error hint: explain_filter -------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t2.c1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r2 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t2.c1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r2 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) (37 rows) SELECT explain_filter(' /*+ Leading(r2_ b1t1 b1t2 b1t3 b1t4) Leading(r2_ b2t1 b2t2 b2t3 b2t4) */ EXPLAIN UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r2_ b1t1 b1t2 b1t3 b1t4) not used hint: Leading(r2_ b2t1 b2t2 b2t3 b2t4) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r2_ b2t1 b2t2 b2t3 b2t4) not used hint: Leading(r2_ b1t1 b1t2 b1t3 b1t4) duplication hint: error hint: explain_filter --------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t1.c1 = b1t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r2_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b2t1.c1 = b2t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t1.c1 = b2t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r2_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) (41 rows) SELECT explain_filter(' /*+ Leading(r2_ b1t1 b1t2 b1t3 b1t4) Leading(r2_ b2t1 b2t2 b2t3 b2t4) Rows(r2_ b1t1 #2) Rows(r2_ b1t1 b1t2 #2) Rows(r2_ b1t1 b1t2 b1t3 #2) Rows(r2_ b1t1 b1t2 b1t3 b1t4 #2) Rows(r2_ b2t1 #2) Rows(r2_ b2t1 b2t2 #2) Rows(r2_ b2t1 b2t2 b2t3 #2) Rows(r2_ b2t1 b2t2 b2t3 b2t4 #2) */ EXPLAIN UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r2_ b1t1 b1t2 b1t3 b1t4) Rows(b1t1 r2_ #2) Rows(b1t1 b1t2 r2_ #2) Rows(b1t1 b1t2 b1t3 r2_ #2) Rows(b1t1 b1t2 b1t3 b1t4 r2_ #2) not used hint: Leading(r2_ b2t1 b2t2 b2t3 b2t4) Rows(b2t1 r2_ #2) Rows(b2t1 b2t2 r2_ #2) Rows(b2t1 b2t2 b2t3 r2_ #2) Rows(b2t1 b2t2 b2t3 b2t4 r2_ #2) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r2_ b2t1 b2t2 b2t3 b2t4) Rows(b2t1 r2_ #2) Rows(b2t1 b2t2 r2_ #2) Rows(b2t1 b2t2 b2t3 r2_ #2) Rows(b2t1 b2t2 b2t3 b2t4 r2_ #2) not used hint: Leading(r2_ b1t1 b1t2 b1t3 b1t4) Rows(b1t1 r2_ #2) Rows(b1t1 b1t2 r2_ #2) Rows(b1t1 b1t2 b1t3 r2_ #2) Rows(b1t1 b1t2 b1t3 b1t4 r2_ #2) duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t4.c1) -> Tid Scan on t4 b1t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t3.c1) -> Tid Scan on t3 b1t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r2_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b2t1.c1 = b2t4.c1) -> Tid Scan on t4 b2t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b2t1.c1 = b2t3.c1) -> Tid Scan on t3 b2t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b2t1.c1 = b2t2.c1) -> Seq Scan on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r2_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) (37 rows) -- No. R-2-3-3 SELECT explain_filter(' /*+ Leading(r3 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r3 t1 t2 t3 t4) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r3 t1 t2 t3 t4) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r3 t1 t2 t3 t4) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) (62 rows) SELECT explain_filter(' /*+ Leading(r3 t1 t2 t3 t4) Rows(r3 t1 t2 t3 t4 #2) Rows(r3 t1 t2 t3 #2) Rows(r3 t1 t2 #2) Rows(r3 t1 #2) */ EXPLAIN UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r3 t1 t2 t3 t4) Rows(r3 t1 #2) Rows(r3 t1 t2 #2) Rows(r3 t1 t2 t3 #2) Rows(r3 t1 t2 t3 t4 #2) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r3 t1 t2 t3 t4) Rows(r3 t1 #2) Rows(r3 t1 t2 #2) Rows(r3 t1 t2 t3 #2) Rows(r3 t1 t2 t3 t4 #2) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r3 t1 t2 t3 t4) Rows(r3 t1 #2) Rows(r3 t1 t2 #2) Rows(r3 t1 t2 t3 #2) Rows(r3 t1 t2 t3 t4 #2) not used hint: duplication hint: error hint: explain_filter -------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t2.c1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r3 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t2.c1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r3 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t4.c1) -> Tid Scan on t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t3.c1) -> Tid Scan on t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (t1.c1 = t2.c1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r3 (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) (56 rows) SELECT explain_filter(' /*+ Leading(r3_ b1t1 b1t2 b1t3 b1t4) Leading(r3_ b2t1 b2t2 b2t3 b2t4) Leading(r3_ b3t1 b3t2 b3t3 b3t4) */ EXPLAIN UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r3_ b1t1 b1t2 b1t3 b1t4) not used hint: Leading(r3_ b2t1 b2t2 b2t3 b2t4) Leading(r3_ b3t1 b3t2 b3t3 b3t4) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r3_ b2t1 b2t2 b2t3 b2t4) not used hint: Leading(r3_ b1t1 b1t2 b1t3 b1t4) Leading(r3_ b3t1 b3t2 b3t3 b3t4) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r3_ b3t1 b3t2 b3t3 b3t4) not used hint: Leading(r3_ b1t1 b1t2 b1t3 b1t4) Leading(r3_ b2t1 b2t2 b2t3 b2t4) duplication hint: error hint: explain_filter --------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b1t1.c1 = b1t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b1t1.c1 = b1t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b2t1.c1 = b2t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b2t1.c1 = b2t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (b3t1.c1 = b3t3.c1) -> Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (b3t1.c1 = b3t2.c1) -> Nested Loop (cost=xxx..xxx rows=6 width=xxx) -> Index Scan using t1_i1 on t1 b3t1 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) -> Sort (cost=xxx..xxx rows=1 width=xxx) Sort Key: b3t2.c1 -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) (62 rows) SELECT explain_filter(' /*+ Leading(r3_ b1t1 b1t2 b1t3 b1t4) Leading(r3_ b2t1 b2t2 b2t3 b2t4) Leading(r3_ b3t1 b3t2 b3t3 b3t4) Rows(r3_ b1t1 #2) Rows(r3_ b1t1 b1t2 #2) Rows(r3_ b1t1 b1t2 b1t3 #2) Rows(r3_ b1t1 b1t2 b1t3 b1t4 #2) Rows(r3_ b2t1 #2) Rows(r3_ b2t1 b2t2 #2) Rows(r3_ b2t1 b2t2 b2t3 #2) Rows(r3_ b2t1 b2t2 b2t3 b2t4 #2) Rows(r3_ b3t1 #2) Rows(r3_ b3t1 b3t2 #2) Rows(r3_ b3t1 b3t2 b3t3 #2) Rows(r3_ b3t1 b3t2 b3t3 b3t4 #2) */ EXPLAIN UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1; '); LOG: pg_hint_plan: used hint: Leading(r3_ b1t1 b1t2 b1t3 b1t4) Rows(b1t1 r3_ #2) Rows(b1t1 b1t2 r3_ #2) Rows(b1t1 b1t2 b1t3 r3_ #2) Rows(b1t1 b1t2 b1t3 b1t4 r3_ #2) not used hint: Leading(r3_ b2t1 b2t2 b2t3 b2t4) Leading(r3_ b3t1 b3t2 b3t3 b3t4) Rows(b2t1 r3_ #2) Rows(b3t1 r3_ #2) Rows(b2t1 b2t2 r3_ #2) Rows(b3t1 b3t2 r3_ #2) Rows(b2t1 b2t2 b2t3 r3_ #2) Rows(b3t1 b3t2 b3t3 r3_ #2) Rows(b2t1 b2t2 b2t3 b2t4 r3_ #2) Rows(b3t1 b3t2 b3t3 b3t4 r3_ #2) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r3_ b2t1 b2t2 b2t3 b2t4) Rows(b2t1 r3_ #2) Rows(b2t1 b2t2 r3_ #2) Rows(b2t1 b2t2 b2t3 r3_ #2) Rows(b2t1 b2t2 b2t3 b2t4 r3_ #2) not used hint: Leading(r3_ b1t1 b1t2 b1t3 b1t4) Leading(r3_ b3t1 b3t2 b3t3 b3t4) Rows(b1t1 r3_ #2) Rows(b3t1 r3_ #2) Rows(b1t1 b1t2 r3_ #2) Rows(b3t1 b3t2 r3_ #2) Rows(b1t1 b1t2 b1t3 r3_ #2) Rows(b3t1 b3t2 b3t3 r3_ #2) Rows(b1t1 b1t2 b1t3 b1t4 r3_ #2) Rows(b3t1 b3t2 b3t3 b3t4 r3_ #2) duplication hint: error hint: LOG: pg_hint_plan: used hint: Leading(r3_ b3t1 b3t2 b3t3 b3t4) Rows(b3t1 r3_ #2) Rows(b3t1 b3t2 r3_ #2) Rows(b3t1 b3t2 b3t3 r3_ #2) Rows(b3t1 b3t2 b3t3 b3t4 r3_ #2) not used hint: Leading(r3_ b1t1 b1t2 b1t3 b1t4) Leading(r3_ b2t1 b2t2 b2t3 b2t4) Rows(b1t1 r3_ #2) Rows(b2t1 r3_ #2) Rows(b1t1 b1t2 r3_ #2) Rows(b2t1 b2t2 r3_ #2) Rows(b1t1 b1t2 b1t3 r3_ #2) Rows(b2t1 b2t2 b2t3 r3_ #2) Rows(b1t1 b1t2 b1t3 b1t4 r3_ #2) Rows(b2t1 b2t2 b2t3 b2t4 r3_ #2) duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t4.c1) -> Tid Scan on t4 b1t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t3.c1) -> Tid Scan on t3 b1t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b1t1.c1 = b1t2.c1) -> Seq Scan on t2 b1t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b2t1.c1 = b2t4.c1) -> Tid Scan on t4 b2t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b2t1.c1 = b2t3.c1) -> Tid Scan on t3 b2t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b2t1.c1 = b2t2.c1) -> Seq Scan on t2 b2t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b3t1.c1 = b3t4.c1) -> Tid Scan on t4 b3t4 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b3t1.c1 = b3t3.c1) -> Tid Scan on t3 b3t3 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) Join Filter: (b3t1.c1 = b3t2.c1) -> Seq Scan on t2 b3t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (ctid = '(1,1)'::tid) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Tid Scan on t1 b3t1 (cost=xxx..xxx rows=1 width=xxx) TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on r3_ (cost=xxx..xxx rows=6 width=xxx) Filter: (c1 = 1) (56 rows) -- No. R-2-3-4 SELECT explain_filter(' /*+HashJoin(v1t1 v1t1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "HashJoin(v1t1 v1t1)" DETAIL: Relation name "v1t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(v1t1 v1t1) explain_filter ------------------------------------------------------------------------ Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 v1t1_1 (cost=xxx..xxx rows=1000 width=xxx) (5 rows) SELECT explain_filter(' /*+HashJoin(v1t1 v1t1)Rows(v1t1 v1t1 #1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "HashJoin(v1t1 v1t1)Rows(v1t1 v1t1 #1)" DETAIL: Relation name "v1t1" is ambiguous. INFO: pg_hint_plan: hint syntax error at or near "Rows(v1t1 v1t1 #1)" DETAIL: Relation name "v1t1" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: HashJoin(v1t1 v1t1) Rows(v1t1 v1t1 #1) explain_filter ------------------------------------------------------------------------ Hash Join (cost=xxx..xxx rows=1000 width=xxx) Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Hash (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 v1t1_1 (cost=xxx..xxx rows=1000 width=xxx) (5 rows) -- No. R-2-3-5 SELECT explain_filter(' /*+NestLoop(v1t1 v1t1_)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; '); LOG: pg_hint_plan: used hint: NestLoop(v1t1 v1t1_) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1000 width=xxx) -> Seq Scan on t1 v1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Scan using t1_i1 on t1 v1t1_ (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = v1t1.c1) (4 rows) SELECT explain_filter(' /*+NestLoop(v1t1 v1t1_)Rows(v1t1 v1t1_ #1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; '); LOG: pg_hint_plan: used hint: NestLoop(v1t1 v1t1_) Rows(v1t1 v1t1_ #1) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on t1 v1t1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Scan using t1_i1 on t1 v1t1_ (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = v1t1.c1) (4 rows) ---- ---- No. R-2-4 VALUES clause ---- -- No. R-2-4-1 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; '); explain_filter ------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=2 width=xxx) Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=2 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = t2.c1) (8 rows) SELECT explain_filter(' /*+ Leading(t3 t1 t2) Rows(t3 t1 #2)Rows(t3 t1 t2 #2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; '); LOG: pg_hint_plan: used hint: not used hint: Leading(t3 t1 t2) Rows(t1 t3 #2) Rows(t1 t2 t3 #2) duplication hint: error hint: explain_filter ------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Hash Join (cost=xxx..xxx rows=2 width=xxx) Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=2 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = t2.c1) (8 rows) SELECT explain_filter(' /*+ Leading(*VALUES* t1 t2) Rows(*VALUES* t1 #2)Rows(*VALUES* t1 t2 #20)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; '); LOG: pg_hint_plan: used hint: Leading(*VALUES* t1 t2) Rows(*VALUES* t1 #2) Rows(*VALUES* t1 t2 #20) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=20 width=xxx) -> Nested Loop (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=2 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = "*VALUES*".column1) -> Index Scan using t2_i1 on t2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = t1.c1) (7 rows) -- No. R-2-4-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; '); explain_filter ------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join (cost=xxx..xxx rows=2 width=xxx) Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=2 width=xxx) -> Materialize (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*_1" (cost=xxx..xxx rows=2 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = t2.c1) (12 rows) SELECT explain_filter(' /*+ Leading(t4 t3 t2 t1) Rows(t4 t3 #2) Rows(t4 t3 t2 #2)Rows(t4 t3 t2 t1 #2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; '); LOG: pg_hint_plan: used hint: not used hint: Leading(t4 t3 t2 t1) Rows(t3 t4 #2) Rows(t2 t3 t4 #2) Rows(t1 t2 t3 t4 #2) duplication hint: error hint: explain_filter ------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join (cost=xxx..xxx rows=2 width=xxx) Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=2 width=xxx) -> Materialize (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*_1" (cost=xxx..xxx rows=2 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = t2.c1) (12 rows) SELECT explain_filter(' /*+ Leading(*VALUES* t3 t2 t1) Rows(t4 t3 #2)Rows(*VALUES* t3 t2 #2)Rows(*VALUES* t3 t2 t1 #2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; '); INFO: pg_hint_plan: hint syntax error at or near "Rows(*VALUES* t3 t2 #2)Rows(*VALUES* t3 t2 t1 #2)" DETAIL: Relation name "*VALUES*" is ambiguous. INFO: pg_hint_plan: hint syntax error at or near "Rows(*VALUES* t3 t2 t1 #2)" DETAIL: Relation name "*VALUES*" is ambiguous. INFO: pg_hint_plan: hint syntax error at or near " Leading(*VALUES* t3 t2 t1) Rows(t4 t3 #2)Rows(*VALUES* t3 t2 #2)Rows(*VALUES* t3 t2 t1 #2)" DETAIL: Relation name "*VALUES*" is ambiguous. LOG: pg_hint_plan: used hint: not used hint: Rows(t3 t4 #2) duplication hint: error hint: Leading(*VALUES* t3 t2 t1) Rows(*VALUES* t2 t3 #2) Rows(*VALUES* t1 t2 t3 #2) explain_filter ------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t2.c1 = "*VALUES*_1".column1) -> Hash Join (cost=xxx..xxx rows=2 width=xxx) Hash Cond: (t2.c1 = "*VALUES*".column1) -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) -> Hash (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*" (cost=xxx..xxx rows=2 width=xxx) -> Materialize (cost=xxx..xxx rows=2 width=xxx) -> Values Scan on "*VALUES*_1" (cost=xxx..xxx rows=2 width=xxx) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = t2.c1) (12 rows) ---- ---- No. R-2-5 ---- -- No. R-2-5-1 SELECT explain_filter(' EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); explain_filter ----------------------------------------------------------------------------------------------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) -> Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (13 rows) SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt1 bmt2 bmt3 bmt4 *0.7) */ EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt1 bmt2 bmt3 bmt4 *0.7) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=70 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (bmt3.c1 = bmt2.c1) -> Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (bmt3.c1 = bmt4.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) (14 rows) -- No. R-2-5-2 SELECT explain_filter(' EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); explain_filter ----------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (12 rows) SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt4 bmt3 *0.6) */ EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt3 bmt4 *0.6) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=60 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=60 width=xxx) Sort Key: bmt2.c1 -> Hash Join (cost=xxx..xxx rows=60 width=xxx) Hash Cond: (bmt3.c1 = bmt2.c1) -> Hash Join (cost=xxx..xxx rows=678 width=xxx) Hash Cond: (bmt3.c1 = bmt4.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) (14 rows) -- No. R-2-5-3 SELECT explain_filter(' EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); explain_filter ----------------------------------------------------------------------------------------------- Nested Loop (cost=xxx..xxx rows=100 width=xxx) -> Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join (cost=xxx..xxx rows=1000 width=xxx) Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Index Only Scan using t3_i1 on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) -> Index Only Scan using t4_i1 on t4 bmt4 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = bmt1.c1) (12 rows) SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt4 bmt1 *0.5) */ EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); LOG: pg_hint_plan: used hint: Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt1 bmt4 *0.5) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=50 width=xxx) Merge Cond: (bmt1.c1 = bmt2.c1) -> Index Only Scan using t1_i1 on t1 bmt1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: bmt2.c1 -> Hash Join (cost=xxx..xxx rows=100 width=xxx) Hash Cond: (bmt3.c1 = bmt2.c1) -> Hash Join (cost=xxx..xxx rows=1130 width=xxx) Hash Cond: (bmt3.c1 = bmt4.c1) -> Seq Scan on t3 bmt3 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=1130 width=xxx) -> Seq Scan on t4 bmt4 (cost=xxx..xxx rows=1130 width=xxx) -> Hash (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on t2 bmt2 (cost=xxx..xxx rows=100 width=xxx) (14 rows) ---- ---- No. R-3-1 abusolute value ---- -- No. R-3-1-1 SELECT explain_filter(' /*+Rows(t1 t2 #0)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); WARNING: Force estimate to be at least one row, to avoid possible divide-by-zero when interpolating costs : Rows(t1 t2 #0) LOG: pg_hint_plan: used hint: Rows(t1 t2 #0) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-3-1-2 SELECT explain_filter(' /*+Rows(t1 t2 #5)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 #5) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=5 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-3-2 increase or decrease value ---- -- No. R-3-2-1 SELECT explain_filter(' /*+Rows(t1 t2 +1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 +1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=101 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-3-2-2 SELECT explain_filter(' /*+Rows(t1 t2 -1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 -1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=99 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-3-2-3 SELECT explain_filter(' /*+Rows(t1 t2 -1000)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); WARNING: Force estimate to be at least one row, to avoid possible divide-by-zero when interpolating costs : Rows(t1 t2 -1000) LOG: pg_hint_plan: used hint: Rows(t1 t2 -1000) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-3-3 multiple ---- -- No. R-3-3-1 SELECT explain_filter(' /*+Rows(t1 t2 *0)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); WARNING: Force estimate to be at least one row, to avoid possible divide-by-zero when interpolating costs : Rows(t1 t2 *0) LOG: pg_hint_plan: used hint: Rows(t1 t2 *0) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-3-3-2 SELECT explain_filter(' /*+Rows(t1 t2 *2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 *2) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=200 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-3-3-3 SELECT explain_filter(' /*+Rows(t1 t2 *0.1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); LOG: pg_hint_plan: used hint: Rows(t1 t2 *0.1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=10 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-3-4 join inherit tables ---- -- No. R-3-4-1 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; '); explain_filter ----------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=301 width=xxx) Hash Cond: (p2.c1 = p1.c1) -> Append (cost=xxx..xxx rows=304 width=xxx) -> Seq Scan on p2 p2_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c1 p2_2 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c2 p2_3 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c3 p2_4 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c1c1 p2_5 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c1c2 p2_6 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c2c1 p2_7 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c2c2 p2_8 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c3c1 p2_9 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c3c2 p2_10 (cost=xxx..xxx rows=50 width=xxx) -> Hash (cost=xxx..xxx rows=301 width=xxx) -> Append (cost=xxx..xxx rows=301 width=xxx) -> Seq Scan on p1 p1_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p1c1 p1_2 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c2 p1_3 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c3 p1_4 (cost=xxx..xxx rows=100 width=xxx) (19 rows) SELECT explain_filter(' /*+Rows(p1 p2 #1)*/ EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; '); LOG: pg_hint_plan: used hint: Rows(p1 p2 #1) not used hint: duplication hint: error hint: explain_filter ----------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=1 width=xxx) Hash Cond: (p2.c1 = p1.c1) -> Append (cost=xxx..xxx rows=304 width=xxx) -> Seq Scan on p2 p2_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c1 p2_2 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c2 p2_3 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c3 p2_4 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c1c1 p2_5 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c1c2 p2_6 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c2c1 p2_7 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c2c2 p2_8 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c3c1 p2_9 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c3c2 p2_10 (cost=xxx..xxx rows=50 width=xxx) -> Hash (cost=xxx..xxx rows=301 width=xxx) -> Append (cost=xxx..xxx rows=301 width=xxx) -> Seq Scan on p1 p1_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p1c1 p1_2 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c2 p1_3 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c3 p1_4 (cost=xxx..xxx rows=100 width=xxx) (19 rows) -- No. R-3-4-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; '); explain_filter ----------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=301 width=xxx) Hash Cond: (p2.c1 = p1.c1) -> Append (cost=xxx..xxx rows=304 width=xxx) -> Seq Scan on p2 p2_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c1 p2_2 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c2 p2_3 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c3 p2_4 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c1c1 p2_5 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c1c2 p2_6 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c2c1 p2_7 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c2c2 p2_8 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c3c1 p2_9 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c3c2 p2_10 (cost=xxx..xxx rows=50 width=xxx) -> Hash (cost=xxx..xxx rows=301 width=xxx) -> Append (cost=xxx..xxx rows=301 width=xxx) -> Seq Scan on p1 p1_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p1c1 p1_2 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c2 p1_3 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c3 p1_4 (cost=xxx..xxx rows=100 width=xxx) (19 rows) SELECT explain_filter(' /*+Rows(p1c1 p2c1 #1)*/ EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; '); LOG: pg_hint_plan: used hint: not used hint: Rows(p1c1 p2c1 #1) duplication hint: error hint: explain_filter ----------------------------------------------------------------------------- Hash Join (cost=xxx..xxx rows=301 width=xxx) Hash Cond: (p2.c1 = p1.c1) -> Append (cost=xxx..xxx rows=304 width=xxx) -> Seq Scan on p2 p2_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c1 p2_2 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c2 p2_3 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c3 p2_4 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p2c1c1 p2_5 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c1c2 p2_6 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c2c1 p2_7 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c2c2 p2_8 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c3c1 p2_9 (cost=xxx..xxx rows=50 width=xxx) -> Seq Scan on p2c3c2 p2_10 (cost=xxx..xxx rows=50 width=xxx) -> Hash (cost=xxx..xxx rows=301 width=xxx) -> Append (cost=xxx..xxx rows=301 width=xxx) -> Seq Scan on p1 p1_1 (cost=xxx..xxx rows=1 width=xxx) -> Seq Scan on p1c1 p1_2 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c2 p1_3 (cost=xxx..xxx rows=100 width=xxx) -> Seq Scan on p1c3 p1_4 (cost=xxx..xxx rows=100 width=xxx) (19 rows) ---- ---- No. R-3-5 conflict join method hint ---- -- No. R-3-5-1 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "Rows(t1 t2 #1)Rows(t1 t2 #1)" DETAIL: Conflict rows hint. LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: Rows(t1 t2 #1) error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-3-5-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(t1 t2 #1)Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "Rows(t1 t2 #1)Rows(t1 t2 #1)Rows(t1 t2 #1)" DETAIL: Conflict rows hint. INFO: pg_hint_plan: hint syntax error at or near "Rows(t1 t2 #1)Rows(t1 t2 #1)" DETAIL: Conflict rows hint. LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: Rows(t1 t2 #1) Rows(t1 t2 #1) error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-3-5-3 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(t2 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "Rows(t1 t2 #1)Rows(t2 t1 #1)" DETAIL: Conflict rows hint. LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: Rows(t1 t2 #1) error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) -- No. R-3-5-4 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t2 t1 #1)Rows(t1 t2 #1)Rows(t2 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); INFO: pg_hint_plan: hint syntax error at or near "Rows(t2 t1 #1)Rows(t1 t2 #1)Rows(t2 t1 #1)" DETAIL: Conflict rows hint. INFO: pg_hint_plan: hint syntax error at or near "Rows(t1 t2 #1)Rows(t2 t1 #1)" DETAIL: Conflict rows hint. LOG: pg_hint_plan: used hint: Rows(t1 t2 #1) not used hint: duplication hint: Rows(t1 t2 #1) Rows(t1 t2 #1) error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) ---- ---- No. R-3-6 hint state output ---- -- No. R-3-6-1 SET client_min_messages TO DEBUG1; SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) SELECT explain_filter(' /*+Rows(t1 t2 +1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); DEBUG: adjusted rows 100 to 101 LOG: pg_hint_plan: used hint: Rows(t1 t2 +1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------------------------- Merge Join (cost=xxx..xxx rows=101 width=xxx) Merge Cond: (t1.c1 = t2.c1) -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1000 width=xxx) -> Sort (cost=xxx..xxx rows=100 width=xxx) Sort Key: t2.c1 -> Seq Scan on t2 (cost=xxx..xxx rows=100 width=xxx) (6 rows) pg_hint_plan-REL17_1_7_0/expected/ut-S.out000066400000000000000000006207551466301071500204010ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; SET max_parallel_workers_per_gather TO 0; SET jit = off; EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; QUERY PLAN --------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c3 < 10) -> Bitmap Index Scan on t1_i Index Cond: (c3 < 10) (4 rows) EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) ---- ---- No. S-1-1 specified pattern of the object name ---- -- No. S-1-1-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. S-1-1-2 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1 WHERE t_1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(t1) duplication hint: error hint: QUERY PLAN ---------------------------------- Index Scan using t1_i1 on t1 t_1 Index Cond: (c1 = 1) (2 rows) -- No. S-1-1-3 /*+SeqScan(t_1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1 WHERE t_1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t_1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 t_1 Filter: (c1 = 1) (2 rows) ---- ---- No. S-1-2 specified schema name in the hint option ---- -- No. S-1-2-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. S-1-2-2 /*+SeqScan(s1.t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(s1.t1) duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) ---- ---- No. S-1-3 table doesn't exist in the hint option ---- -- No. S-1-3-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. S-1-3-2 /*+SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(t2) duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) ---- ---- No. S-1-4 conflict table name ---- -- No. S-1-4-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = 1 AND t1.c1 = t2.c1; QUERY PLAN ------------------------------------ Nested Loop -> Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) -> Seq Scan on t2 Filter: (c1 = 1) (5 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = 1 AND t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------- Nested Loop -> Seq Scan on t1 Filter: (c1 = 1) -> Seq Scan on t2 Filter: (c1 = 1) (5 rows) -- No. S-1-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = 1 AND s1.t1.c1 = s2.t1.c1; QUERY PLAN ------------------------------------ Nested Loop -> Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) -> Seq Scan on t1 t1_1 Filter: (c1 = 1) (5 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = 1 AND s1.t1.c1 = s2.t1.c1; LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) -> Bitmap Heap Scan on t1 t1_1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = 1) (9 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = 1 AND s1.t1.c1 = s2t1.c1; LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------- Nested Loop -> Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) -> Seq Scan on t1 s2t1 Filter: (c1 = 1) (7 rows) /*+BitmapScan(s2t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = 1 AND s1.t1.c1 = s2t1.c1; LOG: pg_hint_plan: used hint: BitmapScan(s2t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) -> Bitmap Heap Scan on t1 s2t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = 1) (7 rows) -- No. S-1-4-3 EXPLAIN (COSTS false) SELECT (SELECT max(c1) FROM s1.t1 WHERE s1.t1.c1 = 1) FROM s1.t1 WHERE s1.t1.c1 = 1; QUERY PLAN -------------------------------------------------------------- Index Only Scan using t1_i1 on t1 Index Cond: (c1 = 1) InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Only Scan using t1_i1 on t1 t1_1 Index Cond: (c1 = 1) (8 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(c1) FROM s1.t1 WHERE s1.t1.c1 = 1) FROM s1.t1 WHERE s1.t1.c1 = 1; LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) InitPlan 2 -> Result InitPlan 1 -> Limit -> Bitmap Heap Scan on t1 t1_1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (12 rows) /*+BitmapScan(t11)*/ EXPLAIN (COSTS false) SELECT (SELECT max(c1) FROM s1.t1 t11 WHERE t11.c1 = 1) FROM s1.t1 t12 WHERE t12.c1 = 1; LOG: pg_hint_plan: used hint: BitmapScan(t11) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------- Index Only Scan using t1_i1 on t1 t12 Index Cond: (c1 = 1) InitPlan 2 -> Result InitPlan 1 -> Limit -> Bitmap Heap Scan on t1 t11 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (10 rows) /*+BitmapScan(t12)*/ EXPLAIN (COSTS false) SELECT (SELECT max(c1) FROM s1.t1 t11 WHERE t11.c1 = 1) FROM s1.t1 t12 WHERE t12.c1 = 1; LOG: pg_hint_plan: used hint: BitmapScan(t12) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------- Bitmap Heap Scan on t1 t12 Recheck Cond: (c1 = 1) InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Only Scan using t1_i1 on t1 t11 Index Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (10 rows) ---- ---- No. S-1-5 object type for the hint ---- -- No. S-1-5-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. S-1-5-2 EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE p1.c1 = 1; QUERY PLAN ----------------------------- Append -> Seq Scan on p1 p1_1 Filter: (c1 = 1) -> Seq Scan on p1c1 p1_2 Filter: (c1 = 1) (5 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE p1.c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Append -> Index Scan using p1_i on p1 p1_1 Index Cond: (c1 = 1) -> Index Scan using p1c1_i on p1c1 p1_2 Index Cond: (c1 = 1) (5 rows) -- No. S-1-5-3 EXPLAIN (COSTS false) SELECT * FROM s1.ul1 WHERE ul1.c1 = 1; QUERY PLAN ---------------------------------- Index Scan using ul1_pkey on ul1 Index Cond: (c1 = 1) (2 rows) /*+SeqScan(ul1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ul1 WHERE ul1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(ul1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on ul1 Filter: (c1 = 1) (2 rows) -- No. S-1-5-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); EXPLAIN (COSTS false) SELECT * FROM tm1 WHERE tm1.c1 = 1; QUERY PLAN ------------------------------------ Index Scan using tm1_c1_idx on tm1 Index Cond: (c1 = 1) (2 rows) /*+SeqScan(tm1)*/ EXPLAIN (COSTS false) SELECT * FROM tm1 WHERE tm1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(tm1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on tm1 Filter: (c1 = 1) (2 rows) -- No. S-1-5-5 EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class WHERE oid = 1; QUERY PLAN ------------------------------------------------- Index Scan using pg_class_oid_index on pg_class Index Cond: (oid = '1'::oid) (2 rows) /*+SeqScan(pg_class)*/ EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class WHERE oid = 1; LOG: pg_hint_plan: used hint: SeqScan(pg_class) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------- Seq Scan on pg_class Filter: (oid = '1'::oid) (2 rows) -- No. S-1-5-6 -- refer ut-fdw.sql -- No. S-1-5-7 EXPLAIN (COSTS false) SELECT * FROM s1.f1() AS ft1 WHERE ft1.c1 = 1; QUERY PLAN ------------------------- Function Scan on f1 ft1 Filter: (c1 = 1) (2 rows) /*+SeqScan(ft1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.f1() AS ft1 WHERE ft1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(ft1) duplication hint: error hint: QUERY PLAN ------------------------- Function Scan on f1 ft1 Filter: (c1 = 1) (2 rows) -- No. S-1-5-8 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS val1 (c1, c2, c3, c4) WHERE val1.c1 = 1; QUERY PLAN --------------------------- Values Scan on "*VALUES*" Filter: (column1 = 1) (2 rows) /*+SeqScan(val1)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS val1 (c1, c2, c3, c4) WHERE val1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(val1) duplication hint: error hint: QUERY PLAN --------------------------- Values Scan on "*VALUES*" Filter: (column1 = 1) (2 rows) /*+SeqScan(*VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS val1 (c1, c2, c3, c4) WHERE val1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(*VALUES*) duplication hint: error hint: QUERY PLAN --------------------------- Values Scan on "*VALUES*" Filter: (column1 = 1) (2 rows) -- No. S-1-5-9 EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT max(c1) FROM s1.t1 WHERE t1.c1 = 1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = 1 AND t1.c1 = c1.c1; QUERY PLAN ------------------------------------------------------------ Nested Loop -> Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) -> Result One-Time Filter: ((InitPlan 1).col1 = 1) InitPlan 1 -> Limit -> Index Only Scan using t1_i1 on t1 t1_1 Index Cond: (c1 = 1) (9 rows) /*+SeqScan(c1)*/ EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT max(c1) FROM s1.t1 WHERE t1.c1 = 1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = 1 AND t1.c1 = c1.c1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(c1) duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Nested Loop -> Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) -> Result One-Time Filter: ((InitPlan 1).col1 = 1) InitPlan 1 -> Limit -> Index Only Scan using t1_i1 on t1 t1_1 Index Cond: (c1 = 1) (9 rows) -- No. S-1-5-10 EXPLAIN (COSTS false) SELECT * FROM s1.v1 WHERE v1.c1 = 1; QUERY PLAN ----------------------------------- Index Scan using t1_i1 on t1 v1t1 Index Cond: (c1 = 1) (2 rows) /*+SeqScan(v1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 WHERE v1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(v1) duplication hint: error hint: QUERY PLAN ----------------------------------- Index Scan using t1_i1 on t1 v1t1 Index Cond: (c1 = 1) (2 rows) -- No. S-1-5-11 EXPLAIN (COSTS false) SELECT * FROM (SELECT * FROM s1.t1 WHERE t1.c1 = 1) AS s1 WHERE s1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+SeqScan(s1)*/ EXPLAIN (COSTS false) SELECT * FROM (SELECT * FROM s1.t1 WHERE t1.c1 = 1) AS s1 WHERE s1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(s1) duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) ---- ---- No. S-2-1 some complexity query blocks ---- -- No. S-2-1-1 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; QUERY PLAN ------------------------------------------------------------------------ Aggregate InitPlan 1 -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Merge Join Merge Cond: (b1t1.c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 b1t1 -> Index Only Scan using t3_i1 on t3 b1t3 -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 -> Index Only Scan using t4_i1 on t4 b1t4 Index Cond: (c1 = b1t1.c1) -> Nested Loop -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 -> Index Only Scan using t3_i1 on t3 bmt3 -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 -> Index Only Scan using t4_i1 on t4 bmt4 Index Cond: (c1 = bmt1.c1) (27 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Seq Scan on t1 b1t1 -> Hash -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Nested Loop -> Seq Scan on t2 b1t2 -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t4.c1) -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 -> Hash -> Nested Loop -> Hash Join Hash Cond: (bmt1.c1 = bmt2.c1) -> Seq Scan on t1 bmt1 -> Hash -> Index Scan using t2_pkey on t2 bmt2 -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt1.c1 = c1) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt1.c1) (31 rows) -- No. S-2-1-2 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; QUERY PLAN ------------------------------------------------------------------------ Aggregate InitPlan 1 -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Merge Join Merge Cond: (b1t1.c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 b1t1 -> Index Only Scan using t3_i1 on t3 b1t3 -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 -> Index Only Scan using t4_i1 on t4 b1t4 Index Cond: (c1 = b1t1.c1) InitPlan 2 -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Merge Join Merge Cond: (b2t1.c1 = b2t3.c1) -> Index Only Scan using t1_i1 on t1 b2t1 -> Index Only Scan using t3_i1 on t3 b2t3 -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 -> Index Only Scan using t4_i1 on t4 b2t4 Index Cond: (c1 = b2t1.c1) -> Nested Loop -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 -> Index Only Scan using t3_i1 on t3 bmt3 -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 -> Index Only Scan using t4_i1 on t4 bmt4 Index Cond: (c1 = bmt1.c1) (41 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b2t4): t4_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Seq Scan on t1 b1t1 -> Hash -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Nested Loop -> Seq Scan on t2 b1t2 -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t4.c1) InitPlan 2 -> Aggregate -> Hash Join Hash Cond: (b2t3.c1 = b2t1.c1) -> Seq Scan on t3 b2t3 -> Hash -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Index Scan using t4_pkey on t4 b2t4 -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = b2t4.c1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = b2t4.c1) -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 -> Hash -> Nested Loop -> Hash Join Hash Cond: (bmt1.c1 = bmt2.c1) -> Seq Scan on t1 bmt1 -> Hash -> Index Scan using t2_pkey on t2 bmt2 -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt1.c1 = c1) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt1.c1) (48 rows) -- No. S-2-1-3 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, (SELECT * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = sbmt4.c1; QUERY PLAN ---------------------------------------------------------------- Aggregate -> Nested Loop -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 -> Index Only Scan using t3_i1 on t3 bmt3 -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 -> Index Only Scan using t4_i1 on t4 bmt4 Index Cond: (c1 = bmt1.c1) (13 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, (SELECT * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = sbmt4.c1; LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------- Aggregate -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 -> Hash -> Nested Loop -> Hash Join Hash Cond: (bmt1.c1 = bmt2.c1) -> Seq Scan on t1 bmt1 -> Hash -> Index Scan using t2_pkey on t2 bmt2 -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt1.c1 = c1) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt1.c1) (15 rows) -- No. S-2-1-4 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT * FROM s1.t3 bmt3) sbmt3, (SELECT * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; QUERY PLAN ---------------------------------------------------------------- Aggregate -> Nested Loop -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 -> Index Only Scan using t3_i1 on t3 bmt3 -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 -> Index Only Scan using t4_i1 on t4 bmt4 Index Cond: (c1 = bmt1.c1) (13 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT * FROM s1.t3 bmt3) sbmt3, (SELECT * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------- Aggregate -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 -> Hash -> Nested Loop -> Hash Join Hash Cond: (bmt1.c1 = bmt2.c1) -> Seq Scan on t1 bmt1 -> Hash -> Index Scan using t2_pkey on t2 bmt2 -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt1.c1 = c1) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt1.c1) (15 rows) -- No. S-2-1-5 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) ; QUERY PLAN ------------------------------------------------------------------------ Aggregate InitPlan 1 -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Merge Join Merge Cond: (b1t1.c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 b1t1 -> Index Only Scan using t3_i1 on t3 b1t3 -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 -> Index Only Scan using t4_i1 on t4 b1t4 Index Cond: (c1 = b1t1.c1) -> Nested Loop -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 Filter: (c1 <> (InitPlan 1).col1) -> Index Only Scan using t3_i1 on t3 bmt3 -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 -> Index Only Scan using t4_i1 on t4 bmt4 Index Cond: (c1 = bmt1.c1) (28 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) ; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Seq Scan on t1 b1t1 -> Hash -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Nested Loop -> Seq Scan on t2 b1t2 -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t4.c1) -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 -> Hash -> Nested Loop -> Hash Join Hash Cond: (bmt1.c1 = bmt2.c1) -> Seq Scan on t1 bmt1 Filter: (c1 <> (InitPlan 1).col1) -> Hash -> Index Scan using t2_pkey on t2 bmt2 -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt1.c1 = c1) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt1.c1) (32 rows) -- No. S-2-1-6 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) ; QUERY PLAN --------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Merge Join Merge Cond: (b1t1.c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 b1t1 -> Index Only Scan using t3_i1 on t3 b1t3 -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 -> Index Only Scan using t4_i1 on t4 b1t4 Index Cond: (c1 = b1t1.c1) InitPlan 2 -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Merge Join Merge Cond: (b2t1.c1 = b2t3.c1) -> Index Only Scan using t1_i1 on t1 b2t1 -> Index Only Scan using t3_i1 on t3 b2t3 -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 -> Index Only Scan using t4_i1 on t4 b2t4 Index Cond: (c1 = b2t1.c1) -> Nested Loop -> Merge Join Merge Cond: (bmt1.c1 = bmt2.c1) -> Merge Join Merge Cond: (bmt1.c1 = bmt3.c1) -> Index Only Scan using t1_i1 on t1 bmt1 Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1)) -> Index Only Scan using t3_i1 on t3 bmt3 -> Sort Sort Key: bmt2.c1 -> Seq Scan on t2 bmt2 -> Index Only Scan using t4_i1 on t4 bmt4 Index Cond: (c1 = bmt1.c1) (42 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) ; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b2t4): t4_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Seq Scan on t1 b1t1 -> Hash -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Nested Loop -> Seq Scan on t2 b1t2 -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t4.c1) InitPlan 2 -> Aggregate -> Hash Join Hash Cond: (b2t3.c1 = b2t1.c1) -> Seq Scan on t3 b2t3 -> Hash -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Index Scan using t4_pkey on t4 b2t4 -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = b2t4.c1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = b2t4.c1) -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 -> Hash -> Nested Loop -> Hash Join Hash Cond: (bmt1.c1 = bmt2.c1) -> Seq Scan on t1 bmt1 Filter: ((c1 <> (InitPlan 1).col1) AND (c1 <> (InitPlan 2).col1)) -> Hash -> Index Scan using t2_pkey on t2 bmt2 -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt1.c1 = c1) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt1.c1) (49 rows) -- No. S-2-1-7 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 ; QUERY PLAN ---------------------------------------------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop -> Nested Loop -> Hash Join Hash Cond: (bmt2.c1 = (max(b1t1.c1))) -> Seq Scan on t2 bmt2 -> Hash -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Merge Join Merge Cond: (b1t1.c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 b1t1 -> Index Only Scan using t3_i1 on t3 b1t3 -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 -> Index Only Scan using t4_i1 on t4 b1t4 Index Cond: (c1 = b1t1.c1) -> Index Only Scan using t1_i1 on t1 bmt1 Index Cond: (c1 = bmt2.c1) -> Index Only Scan using t3_i1 on t3 bmt3 Index Cond: (c1 = bmt1.c1) -> Index Only Scan using t4_i1 on t4 bmt4 Index Cond: (c1 = bmt1.c1) (27 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 ; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------------------------------ Aggregate -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 -> Hash -> Nested Loop -> Merge Join Merge Cond: (bmt1.c1 = (max(b1t1.c1))) -> Sort Sort Key: bmt1.c1 -> Hash Join Hash Cond: (bmt1.c1 = bmt2.c1) -> Seq Scan on t1 bmt1 -> Hash -> Index Scan using t2_pkey on t2 bmt2 -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Seq Scan on t1 b1t1 -> Hash -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Nested Loop -> Seq Scan on t2 b1t2 -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t4.c1) -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt1.c1 = c1) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt1.c1) (36 rows) -- No. S-2-1-8 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; QUERY PLAN ---------------------------------------------------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (bmt1.c1 = (max(b2t1.c1))) -> Nested Loop -> Nested Loop -> Nested Loop -> Hash Join Hash Cond: (bmt2.c1 = (max(b1t1.c1))) -> Seq Scan on t2 bmt2 -> Hash -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b1t1.c1 = b1t2.c1) -> Merge Join Merge Cond: (b1t1.c1 = b1t3.c1) -> Index Only Scan using t1_i1 on t1 b1t1 -> Index Only Scan using t3_i1 on t3 b1t3 -> Sort Sort Key: b1t2.c1 -> Seq Scan on t2 b1t2 -> Index Only Scan using t4_i1 on t4 b1t4 Index Cond: (c1 = b1t1.c1) -> Index Only Scan using t1_i1 on t1 bmt1 Index Cond: (c1 = bmt2.c1) -> Index Only Scan using t3_i1 on t3 bmt3 Index Cond: (c1 = bmt1.c1) -> Index Only Scan using t4_i1 on t4 bmt4 Index Cond: (c1 = bmt1.c1) -> Aggregate -> Nested Loop -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Merge Join Merge Cond: (b2t1.c1 = b2t3.c1) -> Index Only Scan using t1_i1 on t1 b2t1 -> Index Only Scan using t3_i1 on t3 b2t3 -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 -> Index Only Scan using t4_i1 on t4 b2t4 Index Cond: (c1 = b2t1.c1) (42 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b2t4): t4_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Aggregate -> Hash Join Hash Cond: (bmt4.c1 = bmt1.c1) -> Seq Scan on t4 bmt4 -> Hash -> Nested Loop -> Nested Loop -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Merge Join Merge Cond: ((max(b1t1.c1)) = (max(b2t1.c1))) -> Sort Sort Key: (max(b1t1.c1)) -> Aggregate -> Hash Join Hash Cond: (b1t1.c1 = b1t2.c1) -> Seq Scan on t1 b1t1 -> Hash -> Nested Loop Join Filter: (b1t2.c1 = b1t3.c1) -> Nested Loop -> Seq Scan on t2 b1t2 -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t4.c1) -> Sort Sort Key: (max(b2t1.c1)) -> Aggregate -> Hash Join Hash Cond: (b2t3.c1 = b2t1.c1) -> Seq Scan on t3 b2t3 -> Hash -> Merge Join Merge Cond: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Index Scan using t4_pkey on t4 b2t4 -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = b2t4.c1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = b2t4.c1) -> Sort Sort Key: b2t2.c1 -> Seq Scan on t2 b2t2 -> Seq Scan on t1 bmt1 -> Index Scan using t2_pkey on t2 bmt2 Index Cond: (c1 = bmt1.c1) -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt1.c1 = c1) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt1.c1) (53 rows) ---- ---- No. S-2-2 the number of the tables per quiry block ---- -- No. S-2-2-1 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> (InitPlan 4).col1) AND (c1 = 1)) -> Result (20 rows) /*+SeqScan(bmt1) TidScan(b1t1) BitmapScan(b2t1 t1_pkey) IndexScan(b3t1 t1_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b3t1): t1_pkey LOG: available indexes for IndexScan(b3t1): t1_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) BitmapScan(b2t1 t1_pkey) IndexScan(b3t1 t1_pkey) SeqScan(bmt1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------------------ Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Index Scan using t1_pkey on t1 b3t1 Index Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Nested Loop -> Seq Scan on t1 bmt1 Filter: ((c1 <> (InitPlan 4).col1) AND (ctid = '(1,1)'::tid) AND (c1 = 1)) -> Result (21 rows) -- No. S-2-2-2 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Nested Loop -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) (32 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey) TidScan(b1t1)SeqScan(b1t2) BitmapScan(b2t1 t1_pkey)TidScan(b2t2) IndexScan(b3t1 t1_pkey)BitmapScan(b3t2 t2_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b3t1): t1_pkey LOG: available indexes for BitmapScan(b3t2): t2_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) BitmapScan(b2t1 t1_pkey) TidScan(b2t2) IndexScan(b3t1 t1_pkey) BitmapScan(b3t2 t2_pkey) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop -> Tid Scan on t2 b2t2 TID Cond: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = b2t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = b2t2.c1) InitPlan 2 -> Aggregate -> Nested Loop -> Index Scan using t1_pkey on t1 b3t1 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 b3t2 Recheck Cond: (b3t1.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (c1 = b3t1.c1) -> Nested Loop -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Seq Scan on t1 bmt1 Filter: ((c1 <> (InitPlan 2).col1) AND (ctid = '(1,1)'::tid)) -> Index Scan using t2_pkey on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) (35 rows) -- No. S-2-2-3 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 2).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (65 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) IndexScan(b3t1 t1_pkey)BitmapScan(b3t2 t2_pkey)TidScan(b3t3)SeqScan(b3t4) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b2t4): t4_pkey LOG: available indexes for IndexScan(b3t1): t1_pkey LOG: available indexes for BitmapScan(b3t2): t2_pkey LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) IndexScan(b3t1 t1_pkey) BitmapScan(b3t2 t2_pkey) TidScan(b3t3) SeqScan(b3t4) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t2.c1 = b2t3.c1) -> Tid Scan on t2 b2t2 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t3 b2t3 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = b2t3.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = b2t3.c1) -> Index Scan using t4_pkey on t4 b2t4 Index Cond: (c1 = b2t2.c1) Filter: (ctid = '(1,1)'::tid) InitPlan 2 -> Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t3.c1 = b3t4.c1) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t4 b3t4 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 b3t1 Index Cond: (c1 = b3t4.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 b3t2 Recheck Cond: (c1 = b3t3.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (c1 = b3t3.c1) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Seq Scan on t1 bmt1 Filter: ((c1 <> (InitPlan 2).col1) AND (ctid = '(1,1)'::tid)) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 bmt2 Index Cond: (c1 = bmt4.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt2.c1) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) (80 rows) -- No. S-2-2-4 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; QUERY PLAN ----------------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) InitPlan 3 -> Aggregate -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 <> (InitPlan 3).col1) -> Seq Scan on t2 bmt2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 bmt3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (44 rows) /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey) IndexScan(b3t1 t1_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b3t1): t1_pkey LOG: available indexes for IndexScan(b3t1): t1_pkey LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: available indexes for IndexScan(bmt2): t2_pkey LOG: available indexes for BitmapScan(bmt3): t3_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey) IndexScan(b3t1 t1_pkey) SeqScan(bmt1) IndexScan(bmt2 t2_pkey) BitmapScan(bmt3 t3_pkey) TidScan(bmt4) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Index Scan Backward using t1_pkey on t1 b3t1 Filter: (ctid = '(1,1)'::tid) -> Nested Loop Join Filter: (bmt1.c1 = (max(b1t1.c1))) -> Nested Loop Join Filter: (bmt1.c1 = bmt3.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt2.c1) -> Nested Loop Join Filter: (bmt1.c1 = bmt4.c1) -> Seq Scan on t1 bmt1 Filter: ((c1 <> (InitPlan 4).col1) AND (ctid = '(1,1)'::tid)) -> Tid Scan on t4 bmt4 TID Cond: (ctid = '(1,1)'::tid) -> Index Scan using t2_pkey on t2 bmt2 Index Cond: (c1 = bmt4.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t3 bmt3 Recheck Cond: (bmt2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t3_pkey Index Cond: (c1 = bmt2.c1) -> Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) (55 rows) ---- ---- No. S-2-3 RULE or VIEW ---- -- No. S-2-3-1 EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (19 rows) /*+TidScan(t1)SeqScan(t2)IndexScan(t3 t3_pkey)BitmapScan(t4 t4_pkey) SeqScan(r1)*/ EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(t3): t3_pkey LOG: available indexes for BitmapScan(t4): t4_pkey LOG: pg_hint_plan: used hint: SeqScan(r1) TidScan(t1) SeqScan(t2) IndexScan(t3 t3_pkey) BitmapScan(t4 t4_pkey) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Seq Scan on r1 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 Index Cond: (c1 = t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 Recheck Cond: (t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = t2.c1) (22 rows) EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r1_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) (19 rows) /*+TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) SeqScan(r1_)*/ EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) SeqScan(r1_) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Seq Scan on r1_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) (22 rows) -- No. S-2-3-2 EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r2 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (39 rows) /*+TidScan(t1)SeqScan(t2)IndexScan(t3 t3_pkey)BitmapScan(t4 t4_pkey) SeqScan(r2)*/ EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(t3): t3_pkey LOG: available indexes for BitmapScan(t4): t4_pkey LOG: pg_hint_plan: used hint: SeqScan(r2) TidScan(t1) SeqScan(t2) IndexScan(t3 t3_pkey) BitmapScan(t4 t4_pkey) not used hint: duplication hint: error hint: LOG: available indexes for IndexScan(t3): t3_pkey LOG: available indexes for BitmapScan(t4): t4_pkey LOG: pg_hint_plan: used hint: SeqScan(r2) TidScan(t1) SeqScan(t2) IndexScan(t3 t3_pkey) BitmapScan(t4 t4_pkey) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Seq Scan on r2 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 Index Cond: (c1 = t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 Recheck Cond: (t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = t2.c1) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Seq Scan on r2 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 Index Cond: (c1 = t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 Recheck Cond: (t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = t2.c1) (45 rows) EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Tid Scan on r2_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) (39 rows) /*+TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) SeqScan(r2_)*/ EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) SeqScan(r2_) not used hint: BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) duplication hint: error hint: LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b2t4): t4_pkey LOG: pg_hint_plan: used hint: BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) SeqScan(r2_) not used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Seq Scan on r2_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t2.c1 = b2t3.c1) -> Nested Loop -> Seq Scan on r2_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t2 b2t2 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t3 b2t3 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = b2t3.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = b2t3.c1) -> Index Scan using t4_pkey on t4 b2t4 Index Cond: (c1 = b2t2.c1) Filter: (ctid = '(1,1)'::tid) (45 rows) -- No. S-2-3-3 EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Tid Scan on r3 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 TID Cond: (ctid = '(1,1)'::tid) (59 rows) /*+TidScan(t1)SeqScan(t2)IndexScan(t3 t3_pkey)BitmapScan(t4 t4_pkey) SeqScan(r3)*/ EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(t3): t3_pkey LOG: available indexes for BitmapScan(t4): t4_pkey LOG: pg_hint_plan: used hint: SeqScan(r3) TidScan(t1) SeqScan(t2) IndexScan(t3 t3_pkey) BitmapScan(t4 t4_pkey) not used hint: duplication hint: error hint: LOG: available indexes for IndexScan(t3): t3_pkey LOG: available indexes for BitmapScan(t4): t4_pkey LOG: pg_hint_plan: used hint: SeqScan(r3) TidScan(t1) SeqScan(t2) IndexScan(t3 t3_pkey) BitmapScan(t4 t4_pkey) not used hint: duplication hint: error hint: LOG: available indexes for IndexScan(t3): t3_pkey LOG: available indexes for BitmapScan(t4): t4_pkey LOG: pg_hint_plan: used hint: SeqScan(r3) TidScan(t1) SeqScan(t2) IndexScan(t3 t3_pkey) BitmapScan(t4 t4_pkey) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Seq Scan on r3 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 Index Cond: (c1 = t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 Recheck Cond: (t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = t2.c1) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Seq Scan on r3 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 Index Cond: (c1 = t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 Recheck Cond: (t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = t2.c1) Aggregate -> Nested Loop Join Filter: (t1.c1 = t4.c1) -> Nested Loop Join Filter: (t1.c1 = t3.c1) -> Nested Loop Join Filter: (t1.c1 = t2.c1) -> Nested Loop -> Seq Scan on r3 Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 Index Cond: (c1 = t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 Recheck Cond: (t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = t2.c1) (68 rows) EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------- Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b1t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b1t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t3.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b2t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b2t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b2t4 TID Cond: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t4.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop -> Tid Scan on r3_ TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b3t2 Filter: (ctid = '(1,1)'::tid) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Tid Scan on t4 b3t4 TID Cond: (ctid = '(1,1)'::tid) (59 rows) /*+TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) IndexScan(b3t1 t1_pkey)BitmapScan(b3t2 t2_pkey)TidScan(b3t3)SeqScan(b3t4) SeqScan(r3_)*/ EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(b1t3): t3_pkey LOG: available indexes for BitmapScan(b1t4): t4_pkey LOG: pg_hint_plan: used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) SeqScan(r3_) not used hint: BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) IndexScan(b3t1 t1_pkey) BitmapScan(b3t2 t2_pkey) TidScan(b3t3) SeqScan(b3t4) duplication hint: error hint: LOG: available indexes for BitmapScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b2t4): t4_pkey LOG: pg_hint_plan: used hint: BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) SeqScan(r3_) not used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) IndexScan(b3t1 t1_pkey) BitmapScan(b3t2 t2_pkey) TidScan(b3t3) SeqScan(b3t4) duplication hint: error hint: LOG: available indexes for IndexScan(b3t1): t1_pkey LOG: available indexes for BitmapScan(b3t2): t2_pkey LOG: pg_hint_plan: used hint: IndexScan(b3t1 t1_pkey) BitmapScan(b3t2 t2_pkey) TidScan(b3t3) SeqScan(b3t4) SeqScan(r3_) not used hint: TidScan(b1t1) SeqScan(b1t2) IndexScan(b1t3 t3_pkey) BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey) TidScan(b2t2) SeqScan(b2t3) IndexScan(b2t4 t4_pkey) duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------ Aggregate -> Nested Loop Join Filter: (b1t1.c1 = b1t4.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t3.c1) -> Nested Loop Join Filter: (b1t1.c1 = b1t2.c1) -> Nested Loop -> Seq Scan on r3_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t2 b1t2 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t3_pkey on t3 b1t3 Index Cond: (c1 = b1t2.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t4 b1t4 Recheck Cond: (b1t2.c1 = c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t4_pkey Index Cond: (c1 = b1t2.c1) Aggregate -> Nested Loop Join Filter: (b2t1.c1 = b2t4.c1) -> Nested Loop Join Filter: (b2t1.c1 = b2t2.c1) -> Nested Loop Join Filter: (b2t2.c1 = b2t3.c1) -> Nested Loop -> Seq Scan on r3_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t2 b2t2 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t3 b2t3 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: (c1 = b2t3.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = b2t3.c1) -> Index Scan using t4_pkey on t4 b2t4 Index Cond: (c1 = b2t2.c1) Filter: (ctid = '(1,1)'::tid) Aggregate -> Nested Loop Join Filter: (b3t1.c1 = b3t2.c1) -> Nested Loop Join Filter: (b3t1.c1 = b3t3.c1) -> Nested Loop Join Filter: (b3t3.c1 = b3t4.c1) -> Nested Loop -> Seq Scan on r3_ Filter: ((ctid = '(1,1)'::tid) AND (c1 = 1)) -> Tid Scan on t3 b3t3 TID Cond: (ctid = '(1,1)'::tid) -> Seq Scan on t4 b3t4 Filter: (ctid = '(1,1)'::tid) -> Index Scan using t1_pkey on t1 b3t1 Index Cond: (c1 = b3t4.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 b3t2 Recheck Cond: (c1 = b3t3.c1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t2_pkey Index Cond: (c1 = b3t3.c1) (68 rows) -- No. S-2-3-4 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; QUERY PLAN ------------------------------------ Hash Join Hash Cond: (v1t1.c1 = v1t1_1.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_1 (5 rows) /*+BitmapScan(v1t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; LOG: pg_hint_plan: used hint: BitmapScan(v1t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Index Scan using t1_i1 on t1 v1t1 -> Bitmap Heap Scan on t1 v1t1_1 Recheck Cond: (v1t1.c1 = c1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = v1t1.c1) (6 rows) -- No. S-2-3-5 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; QUERY PLAN ----------------------------------- Hash Join Hash Cond: (v1t1.c1 = v1t1_.c1) -> Seq Scan on t1 v1t1 -> Hash -> Seq Scan on t1 v1t1_ (5 rows) /*+SeqScan(v1t1)BitmapScan(v1t1_)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; LOG: pg_hint_plan: used hint: SeqScan(v1t1) BitmapScan(v1t1_) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------ Nested Loop -> Seq Scan on t1 v1t1 -> Bitmap Heap Scan on t1 v1t1_ Recheck Cond: (v1t1.c1 = c1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = v1t1.c1) (6 rows) ---- ---- No. S-2-4 VALUES clause ---- -- No. S-2-4-1 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1')) AS t1 (c1) WHERE t1.c1 = 1; QUERY PLAN ------------ Result (1 row) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1')) AS t1 (c1) WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(t1) duplication hint: error hint: QUERY PLAN ------------ Result (1 row) /*+SeqScan(*VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1')) AS t1 (c1) WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(*VALUES*) duplication hint: error hint: QUERY PLAN ------------ Result (1 row) -- No. S-2-4-2 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t2 (c1, c2) WHERE t1.c1 = t2.c1; QUERY PLAN ---------------------------------------------------------- Hash Join Hash Cond: ("*VALUES*".column1 = "*VALUES*_1".column1) -> Values Scan on "*VALUES*" -> Hash -> Values Scan on "*VALUES*_1" (5 rows) /*+SeqScan(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t2 (c1, c2) WHERE t1.c1 = t2.c1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan(t1 t2) QUERY PLAN ---------------------------------------------------------- Hash Join Hash Cond: ("*VALUES*".column1 = "*VALUES*_1".column1) -> Values Scan on "*VALUES*" -> Hash -> Values Scan on "*VALUES*_1" (5 rows) /*+SeqScan(*VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t2 (c1, c2) WHERE t1.c1 = t2.c1; LOG: pg_hint_plan: used hint: not used hint: SeqScan(*VALUES*) duplication hint: error hint: QUERY PLAN ---------------------------------------------------------- Hash Join Hash Cond: ("*VALUES*".column1 = "*VALUES*_1".column1) -> Values Scan on "*VALUES*" -> Hash -> Values Scan on "*VALUES*_1" (5 rows) ---- ---- No. S-3-1 scan method hint ---- -- No. S-3-1-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) -- No. S-3-1-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN -------------------- Seq Scan on t1 Filter: (c1 = 1) (2 rows) -- No. S-3-1-3 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-1-4 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) /*+IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; LOG: pg_hint_plan: used hint: IndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-1-5 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; QUERY PLAN --------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c3 < 10) -> Bitmap Index Scan on t1_i Index Cond: (c3 < 10) (4 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c3 < 10) -> Bitmap Index Scan on t1_i Index Cond: (c3 < 10) (4 rows) -- No. S-3-1-6 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: BitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. S-3-1-7 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) /*+TidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-1-8 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid IN ('(1,1)', '(2,2)', '(3,3)'); QUERY PLAN ------------------------------------------------------------- Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) Filter: (ctid = ANY ('{"(1,1)","(2,2)","(3,3)"}'::tid[])) (3 rows) /*+TidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid IN ('(1,1)', '(2,2)', '(3,3)'); LOG: pg_hint_plan: used hint: TidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------- Tid Scan on t1 TID Cond: (ctid = ANY ('{"(1,1)","(2,2)","(3,3)"}'::tid[])) Filter: (c1 = 1) (3 rows) -- No. S-3-1-9 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) /*+NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; LOG: pg_hint_plan: used hint: NoSeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-1-10 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: NoSeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-1-11 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: NoIndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t1_i1 Index Cond: (c1 = 1) (4 rows) -- No. S-3-1-12 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; LOG: pg_hint_plan: used hint: NoIndexScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) -- No. S-3-1-13 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; QUERY PLAN --------------------------------- Bitmap Heap Scan on t1 Recheck Cond: (c3 < 10) -> Bitmap Index Scan on t1_i Index Cond: (c3 < 10) (4 rows) /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on t1 Filter: (c3 < 10) (2 rows) -- No. S-3-1-14 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: NoBitmapScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-1-15 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; QUERY PLAN ----------------------------------- Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) -- No. S-3-1-16 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: NoTidScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-1-17 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ----------------------------------- Index Only Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+IndexOnlyScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: IndexOnlyScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Index Only Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-1-18 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 >= 1; QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) /*+IndexOnlyScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 >= 1; LOG: pg_hint_plan: used hint: IndexOnlyScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Index Only Scan using t1_i1 on t1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-1-19 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ----------------------------------- Index Only Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) /*+NoIndexOnlyScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; LOG: pg_hint_plan: used hint: NoIndexOnlyScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-1-20 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 >= 1; QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) /*+NoIndexOnlyScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 >= 1; LOG: pg_hint_plan: used hint: NoIndexOnlyScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------- Seq Scan on t1 Filter: (c1 >= 1) (2 rows) ---- ---- No. S-3-3 index name specified ---- EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c2 = 1) (3 rows) SET enable_tidscan TO off; EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; QUERY PLAN --------------------------------- Index Scan using ti1_i4 on ti1 Index Cond: (c2 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) SET enable_indexscan TO off; EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; QUERY PLAN ----------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c2 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_i4 Index Cond: (c2 = 1) (5 rows) RESET enable_tidscan; RESET enable_indexscan; EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE ti1.c2 >= 1; QUERY PLAN --------------------- Seq Scan on ti1 Filter: (c2 >= 1) (2 rows) -- No. S-3-3-1 /*+IndexScan(ti1 ti1_i3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_i3 LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_i3) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Index Scan using ti1_i3 on ti1 Index Cond: (c2 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) -- No. S-3-3-2 /*+IndexScan(ti1 ti1_i3 ti1_i2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_i3 ti1_i2 LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_i3 ti1_i2) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Index Scan using ti1_i3 on ti1 Index Cond: (c2 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) -- No. S-3-3-3 /*+IndexScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_i4 ti1_i3 ti1_i2 ti1_i1 LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Index Scan using ti1_i4 on ti1 Index Cond: (c2 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) -- No. S-3-3-4 /*+BitmapScan(ti1 ti1_i3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_i3 LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_i3) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c2 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_i3 Index Cond: (c2 = 1) (5 rows) -- No. S-3-3-5 /*+BitmapScan(ti1 ti1_i3 ti1_i2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_i3 ti1_i2 LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_i3 ti1_i2) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c2 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_i3 Index Cond: (c2 = 1) (5 rows) -- No. S-3-3-6 /*+BitmapScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_i4 ti1_i3 ti1_i2 ti1_i1 LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c2 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_i4 Index Cond: (c2 = 1) (5 rows) -- No. S-3-3-7 /*+IndexOnlyScan(ti1 ti1_i3)*/ EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE ti1.c2 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_i3 LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_i3) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Index Only Scan using ti1_i3 on ti1 Index Cond: (c2 >= 1) (2 rows) -- No. S-3-3-8 /*+IndexOnlyScan(ti1 ti1_i3 ti1_i2)*/ EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE ti1.c2 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_i3 ti1_i2 LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_i3 ti1_i2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Index Only Scan using ti1_i2 on ti1 Index Cond: (c2 >= 1) (2 rows) -- No. S-3-3-9 /*+IndexOnlyScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1)*/ EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE ti1.c2 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_i4 ti1_i3 ti1_i2 ti1_i1 LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Index Only Scan using ti1_i1 on ti1 Index Cond: (c2 >= 1) (2 rows) ---- ---- No. S-3-4 index type ---- \d s1.ti1 Table "s1.ti1" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- c1 | integer | | not null | c2 | integer | | | c3 | integer | | | c4 | text | | | Indexes: "ti1_pkey" PRIMARY KEY, btree (c1) "ti1_btree" btree (c1) "ti1_c2_key" UNIQUE CONSTRAINT, btree (c2) "ti1_expr" btree ((c1 < 100)) "ti1_gin" gin (c1) "ti1_gist" gist (c1) "ti1_hash" hash (c1) "ti1_i1" btree (c2) "ti1_i2" btree (c2, c4) "ti1_i3" btree (c2, c4, c4) "ti1_i4" btree (c2, c4, c4, c4) "ti1_multi" btree (c1, c2, c3, c4) "ti1_pred" btree (lower(c4)) "ti1_ts" gin (to_tsvector('english'::regconfig, c4)) "ti1_uniq" UNIQUE, btree (c1) EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 < 100) AND (c2 = 1) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-1 /*+IndexScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_btree LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_btree) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Index Scan using ti1_btree on ti1 Index Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-2 /*+IndexScan(ti1 ti1_hash)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_hash LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_hash) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-3 /*+IndexScan(ti1 ti1_gist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_gist LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_gist) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Index Scan using ti1_gist on ti1 Index Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-4 /*+IndexScan(ti1 ti1_gin)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_gin LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_gin) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 < 100) AND (c2 = 1) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-5 /*+IndexScan(ti1 ti1_expr)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_expr LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_expr) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Index Scan using ti1_expr on ti1 Index Cond: ((c1 < 100) = true) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-6 /*+IndexScan(ti1 ti1_pred)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_pred LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_pred) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- Index Scan using ti1_pred on ti1 Index Cond: (lower(c4) = '1'::text) Filter: ((c1 < 100) AND (c2 = 1) AND (ctid = '(1,1)'::tid) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-7 /*+IndexScan(ti1 ti1_uniq)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_uniq LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_uniq) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Index Scan using ti1_uniq on ti1 Index Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-8 /*+IndexScan(ti1 ti1_multi)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_multi LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_multi) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- Index Scan using ti1_multi on ti1 Index Cond: ((c1 < 100) AND (c2 = 1)) Filter: ((ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-9 /*+IndexScan(ti1 ti1_ts)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_ts LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_ts) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 < 100) AND (c2 = 1) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-10 /*+IndexScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_pkey LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_pkey) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Index Scan using ti1_pkey on ti1 Index Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-11 /*+IndexScan(ti1 ti1_c2_key)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_c2_key LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_c2_key) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------ Index Scan using ti1_c2_key on ti1 Index Cond: (c2 = 1) Filter: ((c1 < 100) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) (3 rows) -- No. S-3-4-12 /*+BitmapScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_btree LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_btree) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_btree Index Cond: (c1 < 100) (5 rows) -- No. S-3-4-13 /*+BitmapScan(ti1 ti1_hash)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_hash LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_hash) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_hash Index Cond: (c1 = 100) (5 rows) -- No. S-3-4-14 /*+BitmapScan(ti1 ti1_gist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_gist LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_gist) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_gist Index Cond: (c1 < 100) (5 rows) -- No. S-3-4-15 /*+BitmapScan(ti1 ti1_gin)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_gin LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_gin) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_gin Index Cond: (c1 < 100) (5 rows) -- No. S-3-4-16 /*+BitmapScan(ti1 ti1_expr)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_expr LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_expr) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_expr Index Cond: ((c1 < 100) = true) (5 rows) -- No. S-3-4-17 /*+BitmapScan(ti1 ti1_pred)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_pred LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_pred) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (lower(c4) = '1'::text) Filter: ((c1 < 100) AND (c2 = 1) AND (ctid = '(1,1)'::tid) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_pred Index Cond: (lower(c4) = '1'::text) (5 rows) -- No. S-3-4-18 /*+BitmapScan(ti1 ti1_uniq)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_uniq LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_uniq) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_uniq Index Cond: (c1 < 100) (5 rows) -- No. S-3-4-19 /*+BitmapScan(ti1 ti1_multi)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_multi LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_multi) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: ((c1 < 100) AND (c2 = 1)) Filter: ((ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_multi Index Cond: ((c1 < 100) AND (c2 = 1)) (5 rows) -- No. S-3-4-20 /*+BitmapScan(ti1 ti1_ts)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_ts LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_ts) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery) Filter: ((c1 < 100) AND (c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text)) -> Bitmap Index Scan on ti1_ts Index Cond: (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery) (5 rows) -- No. S-3-4-21 /*+BitmapScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_pkey LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_pkey) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 < 100) Filter: ((c2 = 1) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_pkey Index Cond: (c1 < 100) (5 rows) -- No. S-3-4-22 /*+BitmapScan(ti1 ti1_c2_key)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_c2_key LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_c2_key) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------ Bitmap Heap Scan on ti1 Recheck Cond: (c2 = 1) Filter: ((c1 < 100) AND (ctid = '(1,1)'::tid) AND (lower(c4) = '1'::text) AND (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery)) -> Bitmap Index Scan on ti1_c2_key Index Cond: (c2 = 1) (5 rows) -- No. S-3-4-23 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; QUERY PLAN --------------------- Seq Scan on ti1 Filter: (c1 >= 1) (2 rows) /*+IndexOnlyScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_btree LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_btree) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------- Index Only Scan using ti1_btree on ti1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-4-24 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; QUERY PLAN ---------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 1) (2 rows) /*+IndexOnlyScan(ti1 ti1_hash)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_hash LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_hash) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-4-25 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 < 1; QUERY PLAN --------------------------------------- Index Only Scan using ti1_uniq on ti1 Index Cond: (c1 < 1) (2 rows) /*+IndexOnlyScan(ti1 ti1_gist)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 < 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_gist LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_gist) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using ti1_gist on ti1 Index Cond: (c1 < 1) (2 rows) -- No. S-3-4-26 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; QUERY PLAN ---------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 1) (2 rows) /*+IndexOnlyScan(ti1 ti1_gin)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_gin LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_gin) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on ti1_gin Index Cond: (c1 = 1) (4 rows) -- No. S-3-4-27 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 < 100; QUERY PLAN --------------------------------------- Index Only Scan using ti1_uniq on ti1 Index Cond: (c1 < 100) (2 rows) /*+IndexOnlyScan(ti1 ti1_expr)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 < 100; LOG: available indexes for IndexOnlyScan(ti1): ti1_expr LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_expr) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Index Scan using ti1_expr on ti1 Index Cond: ((c1 < 100) = true) (2 rows) -- No. S-3-4-28 EXPLAIN (COSTS false) SELECT c4 FROM s1.ti1 WHERE lower(c4) >= '1'; QUERY PLAN ------------------------------------ Seq Scan on ti1 Filter: (lower(c4) >= '1'::text) (2 rows) /*+IndexOnlyScan(ti1 ti1_pred)*/ EXPLAIN (COSTS false) SELECT c4 FROM s1.ti1 WHERE lower(c4) >= '1'; LOG: available indexes for IndexOnlyScan(ti1): ti1_pred LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_pred) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------- Index Scan using ti1_pred on ti1 Index Cond: (lower(c4) >= '1'::text) (2 rows) -- No. S-3-4-29 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; QUERY PLAN --------------------- Seq Scan on ti1 Filter: (c1 >= 1) (2 rows) /*+IndexOnlyScan(ti1 ti1_uniq)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_uniq LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_uniq) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using ti1_uniq on ti1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-4-30 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; QUERY PLAN --------------------- Seq Scan on ti1 Filter: (c1 >= 1) (2 rows) /*+IndexOnlyScan(ti1 ti1_multi)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_multi LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_multi) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------- Index Only Scan using ti1_multi on ti1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-4-31 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE to_tsvector('english', c4) @@ 'a & b'; QUERY PLAN ----------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery) -> Bitmap Index Scan on ti1_ts Index Cond: (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery) (4 rows) /*+IndexOnlyScan(ti1 ti1_ts)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE to_tsvector('english', c4) @@ 'a & b'; LOG: available indexes for IndexOnlyScan(ti1): ti1_ts LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_ts) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery) -> Bitmap Index Scan on ti1_ts Index Cond: (to_tsvector('english'::regconfig, c4) @@ '''a'' & ''b'''::tsquery) (4 rows) -- No. S-3-4-32 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; QUERY PLAN --------------------- Seq Scan on ti1 Filter: (c1 >= 1) (2 rows) /*+IndexOnlyScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_pkey LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_pkey) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using ti1_pkey on ti1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-4-33 EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE c2 >= 1; QUERY PLAN --------------------- Seq Scan on ti1 Filter: (c2 >= 1) (2 rows) /*+IndexOnlyScan(ti1 ti1_c2_key)*/ EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE c2 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_c2_key LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_c2_key) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Index Only Scan using ti1_c2_key on ti1 Index Cond: (c2 >= 1) (2 rows) ---- ---- No. S-3-5 not used index ---- -- No. S-3-5-1 SELECT explain_filter(' /*+IndexScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; '); LOG: available indexes for IndexScan(ti1): ti1_pred LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_pred) not used hint: duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: IndexScan(ti1 ti1_pred) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: IndexScan(ti1 ti1_pred) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: IndexScan(ti1 ti1_pred) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: IndexScan(ti1 ti1_pred) duplication hint: error hint: explain_filter ------------------------------------------------------- Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 100) (2 rows) -- No. S-3-5-2 SELECT explain_filter(' /*+BitmapScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; '); LOG: available indexes for BitmapScan(ti1): ti1_pred LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_pred) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------- Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 100) (2 rows) -- No. S-3-5-3 SELECT explain_filter(' /*+IndexOnlyScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT c1 FROM s1.ti1 WHERE c1 = 100; '); LOG: available indexes for IndexOnlyScan(ti1): ti1_pred LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_pred) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------- Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 100) (2 rows) -- No. S-3-5-4 SELECT explain_filter(' /*+IndexScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; '); LOG: available indexes for IndexScan(ti1): LOG: pg_hint_plan: used hint: not used hint: IndexScan(ti1 not_exist) duplication hint: error hint: explain_filter -------------------------------------------------------------------- Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 100) (2 rows) -- No. S-3-5-5 SELECT explain_filter(' /*+BitmapScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; '); LOG: available indexes for BitmapScan(ti1): LOG: pg_hint_plan: used hint: not used hint: BitmapScan(ti1 not_exist) duplication hint: error hint: explain_filter -------------------------------------------------------------------- Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 100) (2 rows) -- No. S-3-5-6 SELECT explain_filter(' /*+IndexOnlyScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT c1 FROM s1.ti1 WHERE c1 = 100; '); LOG: available indexes for IndexOnlyScan(ti1): LOG: pg_hint_plan: used hint: not used hint: IndexOnlyScan(ti1 not_exist) duplication hint: error hint: explain_filter -------------------------------------------------------------------- Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 100) (2 rows) -- No. S-3-5-7 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) SELECT explain_filter(' /*+TidScan(t1)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1 WHERE t1.c1 = 1; '); LOG: pg_hint_plan: used hint: TidScan(t1) not used hint: duplication hint: error hint: explain_filter ------------------------------------------------------ Seq Scan on t1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 1) (2 rows) ---- ---- No. S-3-6 query structure ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)'; QUERY PLAN ----------------------------------------------- Hash Join Hash Cond: (t2.c1 = t1.c1) -> Seq Scan on t2 -> Hash -> Tid Scan on t1 TID Cond: (ctid = '(1,1)'::tid) (6 rows) -- No. S-3-6-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE c1 = 100; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 Filter: (c1 = 100) (2 rows) -- No. S-3-6-2 /*+SeqScan(t1)BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) BitmapScan(t2) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------- Nested Loop -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) -> Bitmap Heap Scan on t2 Recheck Cond: (t1.c1 = c1) -> Bitmap Index Scan on t2_i1 Index Cond: (c1 = t1.c1) (7 rows) -- No. S-3-6-3 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Hash Join Hash Cond: (t2.c1 = t1.c1) -> Seq Scan on t2 -> Hash -> Seq Scan on t1 Filter: (ctid = '(1,1)'::tid) (6 rows) ---- ---- No. S-3-7 number of tables in a query block ---- -- No. S-3-7-1 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 WHERE b4t1.c1 = 1); QUERY PLAN -------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Only Scan using t1_i1 on t1 b2t1 Index Cond: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Index Only Scan using t1_i1 on t1 b4t1 Index Cond: (c1 = 1) -> Index Only Scan using t1_i1 on t1 b3t1 Index Cond: (c1 = (InitPlan 4).col1) (15 rows) /*+SeqScan(b1t1)IndexScan(b2t1 t1_pkey)BitmapScan(b3t1 t1_pkey)TidScan(b4t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 WHERE b4t1.c1 = 1); LOG: available indexes for IndexScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b2t1): t1_pkey LOG: available indexes for BitmapScan(b3t1): t1_pkey LOG: pg_hint_plan: used hint: IndexScan(b2t1 t1_pkey) BitmapScan(b3t1 t1_pkey) TidScan(b4t1) not used hint: SeqScan(b1t1) duplication hint: error hint: QUERY PLAN ----------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Scan using t1_pkey on t1 b2t1 Index Cond: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Seq Scan on t1 b4t1 Filter: (c1 = 1) -> Bitmap Heap Scan on t1 b3t1 Recheck Cond: (c1 = (InitPlan 4).col1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = (InitPlan 4).col1) (17 rows) -- No. S-3-7-2 EXPLAIN (COSTS false) WITH cte1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 JOIN s1.t2 b1t2 ON(b1t1.c1 = b1t2.c1) WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 JOIN s1.t2 b2t2 ON(b2t1.c1 = b2t2.c1) WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 JOIN s1.t2 b3t2 ON(b3t1.c1 = b3t2.c1) JOIN cte1 ON(b3t1.c1 = cte1.c1) WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 JOIN s1.t2 b4t2 ON(b4t1.c1 = b4t2.c1) WHERE b4t1.c1 = 1); QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop -> Index Only Scan using t1_i1 on t1 b2t1 Index Cond: (c1 = 1) -> Seq Scan on t2 b2t2 Filter: (c1 = 1) InitPlan 2 -> Aggregate -> Nested Loop -> Index Only Scan using t1_i1 on t1 b4t1 Index Cond: (c1 = 1) -> Seq Scan on t2 b4t2 Filter: (c1 = 1) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_i1 on t1 b3t1 Index Cond: (c1 = (InitPlan 2).col1) -> Seq Scan on t2 b3t2 Filter: (c1 = (InitPlan 2).col1) -> Aggregate Filter: (max(b1t1.c1) = (InitPlan 2).col1) -> Nested Loop -> Index Only Scan using t1_i1 on t1 b1t1 Index Cond: (c1 = 1) -> Seq Scan on t2 b1t2 Filter: (c1 = 1) (28 rows) /*+SeqScan(b1t1)IndexScan(b2t1 t1_pkey)BitmapScan(b3t1 t1_pkey)TidScan(b4t1) TidScan(b1t2)SeqScan(b2t2)IndexScan(b3t2 t2_pkey)BitmapScan(b4t2 t2_pkey) */ EXPLAIN (COSTS false) WITH cte1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 JOIN s1.t2 b1t2 ON(b1t1.c1 = b1t2.c1) WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 JOIN s1.t2 b2t2 ON(b2t1.c1 = b2t2.c1) WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 JOIN s1.t2 b3t2 ON(b3t1.c1 = b3t2.c1) JOIN cte1 ON(b3t1.c1 = cte1.c1) WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 JOIN s1.t2 b4t2 ON(b4t1.c1 = b4t2.c1) WHERE b4t1.c1 = 1); LOG: available indexes for IndexScan(b2t1): t1_pkey LOG: available indexes for BitmapScan(b4t2): t2_pkey LOG: available indexes for BitmapScan(b3t1): t1_pkey LOG: available indexes for IndexScan(b3t2): t2_pkey LOG: pg_hint_plan: used hint: SeqScan(b1t1) TidScan(b1t2) IndexScan(b2t1 t1_pkey) SeqScan(b2t2) BitmapScan(b3t1 t1_pkey) IndexScan(b3t2 t2_pkey) TidScan(b4t1) BitmapScan(b4t2 t2_pkey) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 1 -> Aggregate -> Nested Loop -> Index Scan using t1_pkey on t1 b2t1 Index Cond: (c1 = 1) -> Seq Scan on t2 b2t2 Filter: (c1 = 1) InitPlan 2 -> Aggregate -> Nested Loop -> Seq Scan on t1 b4t1 Filter: (c1 = 1) -> Bitmap Heap Scan on t2 b4t2 Recheck Cond: (c1 = 1) -> Bitmap Index Scan on t2_pkey Index Cond: (c1 = 1) -> Nested Loop -> Nested Loop -> Bitmap Heap Scan on t1 b3t1 Recheck Cond: (c1 = (InitPlan 2).col1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = (InitPlan 2).col1) -> Index Scan using t2_pkey on t2 b3t2 Index Cond: (c1 = (InitPlan 2).col1) -> Aggregate Filter: (max(b1t1.c1) = (InitPlan 2).col1) -> Nested Loop -> Seq Scan on t1 b1t1 Filter: (c1 = 1) -> Seq Scan on t2 b1t2 Filter: (c1 = 1) (32 rows) -- No. S-3-7-3 EXPLAIN (COSTS false) WITH cte1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 JOIN s1.t2 b1t2 ON(b1t1.c1 = b1t2.c1) WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 JOIN s1.t2 b3t2 ON(b3t1.c1 = b3t2.c1) JOIN cte1 ON(b3t1.c1 = cte1.c1) WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 WHERE b4t1.c1 = 1); QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Only Scan using t1_i1 on t1 b2t1 Index Cond: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Index Only Scan using t1_i1 on t1 b4t1 Index Cond: (c1 = 1) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_i1 on t1 b3t1 Index Cond: (c1 = (InitPlan 4).col1) -> Seq Scan on t2 b3t2 Filter: (c1 = (InitPlan 4).col1) -> Aggregate Filter: (max(b1t1.c1) = (InitPlan 4).col1) -> Nested Loop -> Index Only Scan using t1_i1 on t1 b1t1 Index Cond: (c1 = 1) -> Seq Scan on t2 b1t2 Filter: (c1 = 1) (26 rows) /*+SeqScan(b1t1)IndexScan(b2t1 t1_pkey)BitmapScan(b3t1 t1_pkey)TidScan(b4t1) TidScan(b1t2)IndexScan(b3t2 t2_pkey) */ EXPLAIN (COSTS false) WITH cte1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 JOIN s1.t2 b1t2 ON(b1t1.c1 = b1t2.c1) WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 JOIN s1.t2 b3t2 ON(b3t1.c1 = b3t2.c1) JOIN cte1 ON(b3t1.c1 = cte1.c1) WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 WHERE b4t1.c1 = 1); LOG: available indexes for IndexScan(b2t1): t1_pkey LOG: available indexes for IndexScan(b2t1): t1_pkey LOG: available indexes for BitmapScan(b3t1): t1_pkey LOG: available indexes for IndexScan(b3t2): t2_pkey LOG: pg_hint_plan: used hint: SeqScan(b1t1) TidScan(b1t2) IndexScan(b2t1 t1_pkey) BitmapScan(b3t1 t1_pkey) IndexScan(b3t2 t2_pkey) TidScan(b4t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------- Aggregate InitPlan 2 -> Result InitPlan 1 -> Limit -> Index Scan using t1_pkey on t1 b2t1 Index Cond: (c1 = 1) InitPlan 4 -> Result InitPlan 3 -> Limit -> Seq Scan on t1 b4t1 Filter: (c1 = 1) -> Nested Loop -> Nested Loop -> Bitmap Heap Scan on t1 b3t1 Recheck Cond: (c1 = (InitPlan 4).col1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = (InitPlan 4).col1) -> Index Scan using t2_pkey on t2 b3t2 Index Cond: (c1 = (InitPlan 4).col1) -> Aggregate Filter: (max(b1t1.c1) = (InitPlan 4).col1) -> Nested Loop -> Seq Scan on t1 b1t1 Filter: (c1 = 1) -> Seq Scan on t2 b1t2 Filter: (c1 = 1) (28 rows) ---- ---- No. S-3-8 inheritance table select/update type ---- -- No. S-3-8-1 EXPLAIN (COSTS false) SELECT * FROM ONLY s1.p1 WHERE c1 = 1; QUERY PLAN -------------------- Seq Scan on p1 Filter: (c1 = 1) (2 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY s1.p1 WHERE c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------- Index Scan using p1_i on p1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-8-2 EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; QUERY PLAN ----------------------------- Append -> Seq Scan on p1 p1_1 Filter: (c1 = 1) -> Seq Scan on p1c1 p1_2 Filter: (c1 = 1) (5 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Append -> Index Scan using p1_i on p1 p1_1 Index Cond: (c1 = 1) -> Index Scan using p1c1_i on p1c1 p1_2 Index Cond: (c1 = 1) (5 rows) -- No. S-3-8-3 EXPLAIN (COSTS false) UPDATE ONLY s1.p1 SET c4 = c4 WHERE c1 = 1; QUERY PLAN -------------------------- Update on p1 -> Seq Scan on p1 Filter: (c1 = 1) (3 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) UPDATE ONLY s1.p1 SET c4 = c4 WHERE c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Update on p1 -> Index Scan using p1_i on p1 Index Cond: (c1 = 1) (3 rows) /*+IndexScan(p1 p1_pkey)*/ EXPLAIN (COSTS false) UPDATE ONLY s1.p1 SET c4 = c4 WHERE c1 = 1; LOG: available indexes for IndexScan(p1): p1_pkey LOG: pg_hint_plan: used hint: IndexScan(p1 p1_pkey) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------- Update on p1 -> Index Scan using p1_pkey on p1 Index Cond: (c1 = 1) (3 rows) -- No. S-3-8-4 EXPLAIN (COSTS false) UPDATE s1.p1 SET c4 = c4 WHERE c1 = 1; QUERY PLAN ----------------------------------- Update on p1 Update on p1 p1_1 Update on p1c1 p1_2 -> Append -> Seq Scan on p1 p1_1 Filter: (c1 = 1) -> Seq Scan on p1c1 p1_2 Filter: (c1 = 1) (8 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) UPDATE s1.p1 SET c4 = c4 WHERE c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------------- Update on p1 Update on p1 p1_1 Update on p1c1 p1_2 -> Append -> Index Scan using p1_i on p1 p1_1 Index Cond: (c1 = 1) -> Index Scan using p1c1_i on p1c1 p1_2 Index Cond: (c1 = 1) (8 rows) /*+IndexScan(p1 p1_pkey)*/ EXPLAIN (COSTS false) UPDATE s1.p1 SET c4 = c4 WHERE c1 = 1; LOG: available indexes for IndexScan(p1): p1_pkey LOG: available indexes for IndexScan(p1c1): p1c1_pkey LOG: pg_hint_plan: used hint: IndexScan(p1 p1_pkey) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------------- Update on p1 Update on p1 p1_1 Update on p1c1 p1_2 -> Append -> Index Scan using p1_pkey on p1 p1_1 Index Cond: (c1 = 1) -> Index Scan using p1c1_pkey on p1c1 p1_2 Index Cond: (c1 = 1) (8 rows) ---- ---- No. S-3-9 inheritance table number ---- -- No. S-3-9-1 EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; QUERY PLAN ----------------------------- Append -> Seq Scan on p1 p1_1 Filter: (c1 = 1) -> Seq Scan on p1c1 p1_2 Filter: (c1 = 1) (5 rows) /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Append -> Index Scan using p1_i on p1 p1_1 Index Cond: (c1 = 1) -> Index Scan using p1c1_i on p1c1 p1_2 Index Cond: (c1 = 1) (5 rows) -- No. S-3-9-2 EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; QUERY PLAN ------------------------------- Append -> Seq Scan on p2 p2_1 Filter: (c1 = 1) -> Seq Scan on p2c1 p2_2 Filter: (c1 = 1) -> Seq Scan on p2c1c1 p2_3 Filter: (c1 = 1) (7 rows) /*+IndexScan(p2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Append -> Index Scan using p2_i on p2 p2_1 Index Cond: (c1 = 1) -> Index Scan using p2c1_i on p2c1 p2_2 Index Cond: (c1 = 1) -> Index Scan using p2c1c1_i on p2c1c1 p2_3 Index Cond: (c1 = 1) (7 rows) ---- ---- No. S-3-10 inheritance table specified table ---- EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; QUERY PLAN ------------------------------- Append -> Seq Scan on p2 p2_1 Filter: (c1 = 1) -> Seq Scan on p2c1 p2_2 Filter: (c1 = 1) -> Seq Scan on p2c1c1 p2_3 Filter: (c1 = 1) (7 rows) -- No. S-3-10-1 /*+IndexScan(p2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Append -> Index Scan using p2_i on p2 p2_1 Index Cond: (c1 = 1) -> Index Scan using p2c1_i on p2c1 p2_2 Index Cond: (c1 = 1) -> Index Scan using p2c1c1_i on p2c1c1 p2_3 Index Cond: (c1 = 1) (7 rows) -- No. S-3-10-2 /*+IndexScan(p2c1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; LOG: pg_hint_plan: used hint: IndexScan(p2c1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Append -> Seq Scan on p2 p2_1 Filter: (c1 = 1) -> Index Scan using p2c1_i on p2c1 p2_2 Index Cond: (c1 = 1) -> Seq Scan on p2c1c1 p2_3 Filter: (c1 = 1) (7 rows) -- No. S-3-10-3 SELECT explain_filter(' EXPLAIN SELECT c4 FROM s1.p1 WHERE c2 * 2 < 100 AND c1 < 10; '); explain_filter --------------------------------------------------------------- Append (cost=xxx..xxx rows=4 width=xxx) -> Seq Scan on p1 p1_1 (cost=xxx..xxx rows=1 width=xxx) Filter: ((c1 < 10) AND ((c2 * 2) < 100)) -> Seq Scan on p1c1 p1_2 (cost=xxx..xxx rows=3 width=xxx) Filter: ((c1 < 10) AND ((c2 * 2) < 100)) (5 rows) SELECT explain_filter(' /*+IndexScan(p1 p1_parent)*/ EXPLAIN SELECT c4 FROM s1.p1 WHERE c2 * 2 < 100 AND c1 < 10; '); LOG: available indexes for IndexScan(p1): p1_parent LOG: available indexes for IndexScan(p1c1): p1c1_c4_expr_idx LOG: pg_hint_plan: used hint: IndexScan(p1 p1_parent) not used hint: duplication hint: error hint: explain_filter ---------------------------------------------------------------------------------------- Append (cost=xxx..xxx rows=4 width=xxx) -> Index Scan using p1_parent on p1 p1_1 (cost=xxx..xxx rows=1 width=xxx) Filter: ((c2 * 2) < 100) -> Index Scan using p1c1_c4_expr_idx on p1c1 p1_2 (cost=xxx..xxx rows=3 width=xxx) Filter: ((c2 * 2) < 100) (5 rows) -- No. S-3-10-4 SELECT explain_filter(' /*+IndexScan(p1 p1_i2)*/ EXPLAIN SELECT c2 FROM s1.p1 WHERE c2 = 1; '); LOG: available indexes for IndexScan(p1): p1_i2 LOG: available indexes for IndexScan(p1c1): LOG: available indexes for IndexScan(p1c2): LOG: available indexes for IndexScan(p1c3): LOG: pg_hint_plan: used hint: IndexScan(p1 p1_i2) not used hint: duplication hint: error hint: explain_filter --------------------------------------------------------------------------- Append (cost=xxx..xxx rows=4 width=xxx) -> Index Scan using p1_i2 on p1 p1_1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c2 = 1) -> Seq Scan on p1c1 p1_2 (cost=xxx..xxx rows=1 width=xxx) Filter: (c2 = 1) -> Seq Scan on p1c2 p1_3 (cost=xxx..xxx rows=1 width=xxx) Filter: (c2 = 1) -> Seq Scan on p1c3 p1_4 (cost=xxx..xxx rows=1 width=xxx) Filter: (c2 = 1) (9 rows) -- No. S-3-10-5 SELECT explain_filter(' /*+IndexScan(p2 p2c1_pkey)*/ EXPLAIN (COSTS true) SELECT * FROM s1.p2 WHERE c1 = 1; '); LOG: available indexes for IndexScan(p2): LOG: available indexes for IndexScan(p2c1): p2c1_pkey LOG: available indexes for IndexScan(p2c1c1): LOG: pg_hint_plan: used hint: IndexScan(p2 p2c1_pkey) not used hint: duplication hint: error hint: explain_filter --------------------------------------------------------------------------------- Append (cost=xxx..xxx rows=3 width=xxx) -> Seq Scan on p2 p2_1 (cost=xxx..xxx rows=1 width=xxx) Filter: (c1 = 1) -> Index Scan using p2c1_pkey on p2c1 p2_2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) -> Seq Scan on p2c1c1 p2_3 (cost=xxx..xxx rows=1 width=xxx) Filter: (c1 = 1) (7 rows) ---- ---- No. S-3-12 specified same table ---- -- No. S-3-12-1 /*+IndexScan(ti1) BitmapScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "IndexScan(ti1) BitmapScan(ti1)" DETAIL: Conflict scan method hint. LOG: pg_hint_plan: used hint: BitmapScan(ti1) not used hint: duplication hint: IndexScan(ti1) error hint: QUERY PLAN ------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_hash Index Cond: (c1 = 1) (5 rows) -- No. S-3-12-2 /*+IndexScan(ti1 ti1_pkey) BitmapScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "IndexScan(ti1 ti1_pkey) BitmapScan(ti1 ti1_btree)" DETAIL: Conflict scan method hint. LOG: available indexes for BitmapScan(ti1): ti1_btree LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_btree) not used hint: duplication hint: IndexScan(ti1 ti1_pkey) error hint: QUERY PLAN -------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_btree Index Cond: (c1 = 1) (5 rows) -- No. S-3-12-3 /*+BitmapScan(ti1) IndexScan(ti1) BitmapScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "BitmapScan(ti1) IndexScan(ti1) BitmapScan(ti1)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "IndexScan(ti1) BitmapScan(ti1)" DETAIL: Conflict scan method hint. LOG: pg_hint_plan: used hint: BitmapScan(ti1) not used hint: duplication hint: BitmapScan(ti1) IndexScan(ti1) error hint: QUERY PLAN ------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_hash Index Cond: (c1 = 1) (5 rows) -- No. S-3-12-4 /*+BitmapScan(ti1 ti1_hash) IndexScan(ti1 ti1_pkey) BitmapScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "BitmapScan(ti1 ti1_hash) IndexScan(ti1 ti1_pkey) BitmapScan(ti1 ti1_btree)" DETAIL: Conflict scan method hint. INFO: pg_hint_plan: hint syntax error at or near "IndexScan(ti1 ti1_pkey) BitmapScan(ti1 ti1_btree)" DETAIL: Conflict scan method hint. LOG: available indexes for BitmapScan(ti1): ti1_btree LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_btree) not used hint: duplication hint: BitmapScan(ti1 ti1_hash) IndexScan(ti1 ti1_pkey) error hint: QUERY PLAN -------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_btree Index Cond: (c1 = 1) (5 rows) ---- ---- No. S-3-13 message output of hint ---- -- No. S-3-13-1 /*+SeqScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: SeqScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Seq Scan on ti1 Filter: ((c1 = 1) AND (ctid = '(1,1)'::tid)) (2 rows) -- No. S-3-13-2 /*+SeqScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan(ti1 ti1_pkey) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-3 /*+SeqScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: SeqScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: SeqScan(ti1 ti1_pkey ti1_btree) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-4 /*+IndexScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: IndexScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) -- No. S-3-13-5 /*+IndexScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_pkey LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_pkey) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Index Scan using ti1_pkey on ti1 Index Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) -- No. S-3-13-6 /*+IndexScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for IndexScan(ti1): ti1_btree ti1_pkey LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_pkey ti1_btree) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Index Scan using ti1_btree on ti1 Index Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) -- No. S-3-13-7 /*+BitmapScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: BitmapScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_hash Index Cond: (c1 = 1) (5 rows) -- No. S-3-13-8 /*+BitmapScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_pkey LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_pkey) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_pkey Index Cond: (c1 = 1) (5 rows) -- No. S-3-13-9 /*+BitmapScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: available indexes for BitmapScan(ti1): ti1_btree ti1_pkey LOG: pg_hint_plan: used hint: BitmapScan(ti1 ti1_pkey ti1_btree) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------- Bitmap Heap Scan on ti1 Recheck Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on ti1_btree Index Cond: (c1 = 1) (5 rows) -- No. S-3-13-10 /*+TidScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: TidScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-11 /*+TidScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: TidScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: TidScan(ti1 ti1_pkey) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-12 /*+TidScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: TidScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: TidScan(ti1 ti1_pkey ti1_btree) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-13 /*+NoSeqScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoSeqScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-14 /*+NoSeqScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoSeqScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoSeqScan(ti1 ti1_pkey) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-15 /*+NoSeqScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoSeqScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoSeqScan(ti1 ti1_pkey ti1_btree) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-16 /*+NoIndexScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoIndexScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-17 /*+NoIndexScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoIndexScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoIndexScan(ti1 ti1_pkey) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-18 /*+NoIndexScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoIndexScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoIndexScan(ti1 ti1_pkey ti1_btree) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-19 /*+NoBitmapScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoBitmapScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-20 /*+NoBitmapScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoBitmapScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoBitmapScan(ti1 ti1_pkey) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-21 /*+NoBitmapScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoBitmapScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoBitmapScan(ti1 ti1_pkey ti1_btree) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-22 /*+NoTidScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; LOG: pg_hint_plan: used hint: NoTidScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 1) Filter: (ctid = '(1,1)'::tid) (3 rows) -- No. S-3-13-23 /*+NoTidScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoTidScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoTidScan(ti1 ti1_pkey) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-24 /*+NoTidScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoTidScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoTidScan(ti1 ti1_pkey ti1_btree) QUERY PLAN ----------------------------------- Tid Scan on ti1 TID Cond: (ctid = '(1,1)'::tid) Filter: (c1 = 1) (3 rows) -- No. S-3-13-25 /*+IndexOnlyScan(ti1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using ti1_uniq on ti1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-13-26 /*+IndexOnlyScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_pkey LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_pkey) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------- Index Only Scan using ti1_pkey on ti1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-13-27 /*+IndexOnlyScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; LOG: available indexes for IndexOnlyScan(ti1): ti1_btree ti1_pkey LOG: pg_hint_plan: used hint: IndexOnlyScan(ti1 ti1_pkey ti1_btree) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------- Index Only Scan using ti1_btree on ti1 Index Cond: (c1 >= 1) (2 rows) -- No. S-3-13-28 /*+NoIndexOnlyScan(ti1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; LOG: pg_hint_plan: used hint: NoIndexOnlyScan(ti1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-13-29 /*+NoIndexOnlyScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoIndexOnlyScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoIndexOnlyScan(ti1 ti1_pkey) QUERY PLAN ---------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 1) (2 rows) -- No. S-3-13-30 /*+NoIndexOnlyScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; INFO: pg_hint_plan: hint syntax error at or near "" DETAIL: NoIndexOnlyScan hint accepts only one relation. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: NoIndexOnlyScan(ti1 ti1_pkey ti1_btree) QUERY PLAN ---------------------------------- Index Scan using ti1_hash on ti1 Index Cond: (c1 = 1) (2 rows) ---- ---- No. S-3-14 regular expression ---- EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; QUERY PLAN -------------------------------- Index Scan using ti1_i4 on ti1 Index Cond: (c2 = 1) (2 rows) -- No. S-3-14-1 /*+IndexScanRegexp(ti1 ti1_.*_key)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScanRegexp(ti1): ti1_c2_key LOG: pg_hint_plan: used hint: IndexScanRegexp(ti1 ti1_.*_key) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------ Index Scan using ti1_c2_key on ti1 Index Cond: (c2 = 1) (2 rows) -- No. S-3-14-2 /*+IndexScanRegexp(ti1 ti1_i.)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScanRegexp(ti1): ti1_i4 ti1_i3 ti1_i2 ti1_i1 LOG: pg_hint_plan: used hint: IndexScanRegexp(ti1 ti1_i.) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------- Index Scan using ti1_i4 on ti1 Index Cond: (c2 = 1) (2 rows) -- No. S-3-14-3 /*+IndexScanRegexp(ti1 no.*_exist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScanRegexp(ti1): LOG: pg_hint_plan: used hint: not used hint: IndexScanRegexp(ti1 no.*_exist) duplication hint: error hint: QUERY PLAN -------------------------------- Index Scan using ti1_i4 on ti1 Index Cond: (c2 = 1) (2 rows) -- No. S-3-14-4 /*+IndexScanRegexp(p1 .*pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; LOG: available indexes for IndexScanRegexp(p1): p1_pkey LOG: available indexes for IndexScanRegexp(p1c1): p1c1_pkey LOG: pg_hint_plan: used hint: IndexScanRegexp(p1 .*pkey) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------------- Append -> Index Scan using p1_pkey on p1 p1_1 Index Cond: (c1 = 1) -> Index Scan using p1c1_pkey on p1c1 p1_2 Index Cond: (c1 = 1) (5 rows) -- No. S-3-14-5 /*+IndexScanRegexp(p1 p1.*i)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; LOG: available indexes for IndexScanRegexp(p1): p1_i2 p1_i LOG: available indexes for IndexScanRegexp(p1c1): p1c1_i p1c1_c4_expr_idx LOG: pg_hint_plan: used hint: IndexScanRegexp(p1 p1.*i) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------------------- Append -> Index Scan using p1_i on p1 p1_1 Index Cond: (c1 = 1) -> Index Scan using p1c1_i on p1c1 p1_2 Index Cond: (c1 = 1) (5 rows) -- No. S-3-14-6 /*+IndexScanRegexp(p1 no.*_exist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; LOG: available indexes for IndexScanRegexp(p1): LOG: available indexes for IndexScanRegexp(p1c1): LOG: pg_hint_plan: used hint: not used hint: IndexScanRegexp(p1 no.*_exist) duplication hint: error hint: QUERY PLAN ----------------------------- Append -> Seq Scan on p1 p1_1 Filter: (c1 = 1) -> Seq Scan on p1c1 p1_2 Filter: (c1 = 1) (5 rows) ---- ---- No. S-3-15 message output of index candidate ---- -- No. S-3-15-1 /*+IndexScan(ti1 ti1_i1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScan(ti1): ti1_i1 LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_i1) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------- Index Scan using ti1_i1 on ti1 Index Cond: (c2 = 1) (2 rows) -- No. S-3-15-2 /*+IndexScan(ti1 not_exist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScan(ti1): LOG: pg_hint_plan: used hint: not used hint: IndexScan(ti1 not_exist) duplication hint: error hint: QUERY PLAN -------------------------------- Index Scan using ti1_i4 on ti1 Index Cond: (c2 = 1) (2 rows) -- No. S-3-15-3 /*+IndexScan(ti1 ti1_i1 ti1_i2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScan(ti1): ti1_i2 ti1_i1 LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_i1 ti1_i2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------- Index Scan using ti1_i2 on ti1 Index Cond: (c2 = 1) (2 rows) -- No. S-3-15-4 /*+IndexScan(ti1 ti1_i1 not_exist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScan(ti1): ti1_i1 LOG: pg_hint_plan: used hint: IndexScan(ti1 ti1_i1 not_exist) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------- Index Scan using ti1_i1 on ti1 Index Cond: (c2 = 1) (2 rows) -- No. S-3-15-5 /*+IndexScan(ti1 not_exist1 not_exist2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScan(ti1): LOG: pg_hint_plan: used hint: not used hint: IndexScan(ti1 not_exist1 not_exist2) duplication hint: error hint: QUERY PLAN -------------------------------- Index Scan using ti1_i4 on ti1 Index Cond: (c2 = 1) (2 rows) pg_hint_plan-REL17_1_7_0/expected/ut-T.out000066400000000000000000000043061466301071500203660ustar00rootroot00000000000000-- ut-T: tests for table hints -- This test is focusing on hint retrieval from table LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; -- This hint affects queries with an equivalent query ID when executed as -- a subquery. SET pg_hint_plan.enable_hint_table TO on; SELECT get_query_id('SELECT * FROM t1 WHERE id = 1;') AS query_id \gset INSERT INTO hint_plan.hints VALUES (DEFAULT, :'query_id', '', 'SeqScan(t1)'); PREPARE p1 AS SELECT * FROM t1 WHERE id = 100; -- These queries uses IndexScan without hints SET pg_hint_plan.enable_hint_table to off; EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id = 100; QUERY PLAN -------------------------------- Index Scan using t1_pkey on t1 Index Cond: (id = 100) (2 rows) EXPLAIN (COSTS false) EXECUTE p1; QUERY PLAN -------------------------------- Index Scan using t1_pkey on t1 Index Cond: (id = 100) (2 rows) DEALLOCATE p1; PREPARE p1 AS SELECT * FROM t1 WHERE id = 100; EXPLAIN (COSTS false) CREATE TABLE ct1 AS EXECUTE p1; QUERY PLAN -------------------------------- Index Scan using t1_pkey on t1 Index Cond: (id = 100) (2 rows) DEALLOCATE p1; PREPARE p1 AS SELECT * FROM t1 WHERE id = 100; -- Forced to use SeqScan by table hints SET pg_hint_plan.enable_hint_table to on; EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id = 100; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 Filter: (id = 100) (2 rows) EXPLAIN (COSTS false) EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 Filter: (id = 100) (2 rows) DEALLOCATE p1; PREPARE p1 AS SELECT * FROM t1 WHERE id = 100; EXPLAIN (COSTS false) CREATE TABLE ct1 AS EXECUTE p1; LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: duplication hint: error hint: QUERY PLAN ---------------------- Seq Scan on t1 Filter: (id = 100) (2 rows) DEALLOCATE p1; SET pg_hint_plan.enable_hint_table to off; DELETE FROM hint_plan.hints; pg_hint_plan-REL17_1_7_0/expected/ut-W.out000066400000000000000000001337361466301071500204030ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; -- Queries on ordinary tables with default setting EXPLAIN (COSTS false) SELECT * FROM s1.t1; QUERY PLAN ---------------- Seq Scan on t1 (1 row) -- Note that parallel is not enforced on a single relation without -- the GUCs related to parallelism reset. /*+Parallel(t1 5 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1; LOG: pg_hint_plan: used hint: Parallel(t1 5 hard) not used hint: duplication hint: error hint: QUERY PLAN ---------------- Seq Scan on t1 (1 row) -- Still it works for multiple relations. /*+Parallel(t11 5 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 as t11, s1.t1 as t12; LOG: pg_hint_plan: used hint: Parallel(t11 5 hard) not used hint: duplication hint: error hint: QUERY PLAN ----------------------------------------- Nested Loop -> Seq Scan on t1 t12 -> Gather Workers Planned: 5 -> Parallel Seq Scan on t1 t11 (5 rows) SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET max_parallel_workers_per_gather to DEFAULT; /*+Parallel(t1 8)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1; LOG: pg_hint_plan: used hint: Parallel(t1 8 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------- Gather Workers Planned: 2 -> Parallel Seq Scan on t1 (3 rows) /*+Parallel(t1 8 soft)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1; LOG: pg_hint_plan: used hint: Parallel(t1 8 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------- Gather Workers Planned: 2 -> Parallel Seq Scan on t1 (3 rows) /*+Parallel(t1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1; LOG: pg_hint_plan: used hint: Parallel(t1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------- Gather Workers Planned: 8 -> Parallel Seq Scan on t1 (3 rows) /*+Parallel(t1 4 hard) */ /* to be gather merge*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ORDER BY s1.t1.c1 LIMIT 4; LOG: pg_hint_plan: used hint: Parallel(t1 4 hard) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------------- Limit -> Gather Merge Workers Planned: 4 -> Parallel Index Scan using t1_i1 on t1 (4 rows) -- Queries on inheritance tables SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET enable_parallel_append to false; /*+Parallel(p1 8)*/ EXPLAIN (COSTS false) SELECT * FROM p1; LOG: pg_hint_plan: used hint: Parallel(p1 8 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 1 -> Append -> Parallel Seq Scan on p1 p1_1 -> Parallel Seq Scan on p1_c1 p1_2 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 (12 rows) SET enable_parallel_append to true; /*+Parallel(p1 8)*/ EXPLAIN (COSTS false) SELECT * FROM p1; LOG: pg_hint_plan: used hint: Parallel(p1 8 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 2 -> Parallel Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 (12 rows) SET parallel_setup_cost to DEFAULT; SET parallel_tuple_cost to DEFAULT; SET min_parallel_table_scan_size to DEFAULT; SET min_parallel_index_scan_size to DEFAULT; SET enable_parallel_append to false; /*+Parallel(p1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; LOG: pg_hint_plan: used hint: Parallel(p1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 8 -> Append -> Parallel Seq Scan on p1 p1_1 -> Parallel Seq Scan on p1_c1 p1_2 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 (12 rows) SET enable_parallel_append to true; /*+Parallel(p1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; LOG: pg_hint_plan: used hint: Parallel(p1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 8 -> Parallel Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 (12 rows) -- hinting on children doesn't work (changed as of pg_hint_plan 10) SET enable_parallel_append to false; /*+Parallel(p1_c1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; LOG: pg_hint_plan: used hint: Parallel(p1_c1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c2 p1_3 -> Seq Scan on p1_c3 p1_4 -> Seq Scan on p1_c4 p1_5 -> Seq Scan on p1_c1_c1 p1_6 -> Seq Scan on p1_c1_c2 p1_7 -> Seq Scan on p1_c3_c1 p1_8 -> Seq Scan on p1_c3_c2 p1_9 (10 rows) SET enable_parallel_append to true; /*+Parallel(p1_c1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; LOG: pg_hint_plan: used hint: Parallel(p1_c1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c2 p1_3 -> Seq Scan on p1_c3 p1_4 -> Seq Scan on p1_c4 p1_5 -> Seq Scan on p1_c1_c1 p1_6 -> Seq Scan on p1_c1_c2 p1_7 -> Seq Scan on p1_c3_c1 p1_8 -> Seq Scan on p1_c3_c2 p1_9 (10 rows) -- Joins EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; QUERY PLAN ------------------------------------------ Hash Join Hash Cond: (p1_c1_c1.id = p2_c1_c1.id) -> Seq Scan on p1_c1_c1 -> Hash -> Seq Scan on p2_c1_c1 (5 rows) /*+Parallel(p1_c1_c1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; LOG: pg_hint_plan: used hint: Parallel(p1_c1_c1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Hash Join Hash Cond: (p2_c1_c1.id = p1_c1_c1.id) -> Seq Scan on p2_c1_c1 -> Hash -> Gather Workers Planned: 8 -> Parallel Seq Scan on p1_c1_c1 (7 rows) SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; /*+Parallel(p1_c1_c1 8 soft) Parallel(p2_c1_c1 0)*/ EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; LOG: pg_hint_plan: used hint: Parallel(p1_c1_c1 8 soft) Parallel(p2_c1_c1 0 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 1 -> Hash Join Hash Cond: (p1_c1_c1.id = p2_c1_c1.id) -> Parallel Seq Scan on p1_c1_c1 -> Hash -> Seq Scan on p2_c1_c1 (7 rows) /*+Parallel(p1_c1_c1 8 hard) Parallel(p2_c1_c1 0)*/ EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; LOG: pg_hint_plan: used hint: Parallel(p1_c1_c1 8 hard) Parallel(p2_c1_c1 0 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 8 -> Hash Join Hash Cond: (p1_c1_c1.id = p2_c1_c1.id) -> Parallel Seq Scan on p1_c1_c1 -> Hash -> Seq Scan on p2_c1_c1 (7 rows) /*+Parallel(p1_c1_c1 8 hard) Parallel(p2_c1_c1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; LOG: pg_hint_plan: used hint: Parallel(p1_c1_c1 8 hard) Parallel(p2_c1_c1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------- Gather Workers Planned: 8 -> Parallel Hash Join Hash Cond: (p1_c1_c1.id = p2_c1_c1.id) -> Parallel Seq Scan on p1_c1_c1 -> Parallel Hash -> Parallel Seq Scan on p2_c1_c1 (7 rows) -- Joins on inheritance tables SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET enable_parallel_append to false; /*+Parallel(p1 8)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: Parallel(p1 8 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Gather Workers Planned: 1 -> Parallel Hash Join Hash Cond: (p1.id = p2.id) -> Append -> Parallel Seq Scan on p1 p1_1 -> Parallel Seq Scan on p1_c1 p1_2 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 -> Parallel Hash -> Append -> Parallel Seq Scan on p2 p2_1 -> Parallel Seq Scan on p2_c1 p2_2 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 (25 rows) SET enable_parallel_append to true; /*+Parallel(p1 8)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: Parallel(p1 8 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Gather Workers Planned: 2 -> Parallel Hash Join Hash Cond: (p1.id = p2.id) -> Parallel Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 -> Parallel Hash -> Parallel Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 (25 rows) SET enable_parallel_append to false; /*+Parallel(p1 8)Parallel(p2 0)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: Parallel(p1 8 soft) Parallel(p2 0 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------ Gather Workers Planned: 1 -> Hash Join Hash Cond: (p1.id = p2.id) -> Append -> Parallel Seq Scan on p1 p1_1 -> Parallel Seq Scan on p1_c1 p1_2 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 -> Hash -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c2 p2_3 -> Seq Scan on p2_c3 p2_4 -> Seq Scan on p2_c4 p2_5 -> Seq Scan on p2_c1_c1 p2_6 -> Seq Scan on p2_c1_c2 p2_7 -> Seq Scan on p2_c3_c1 p2_8 -> Seq Scan on p2_c3_c2 p2_9 (25 rows) SET enable_parallel_append to true; /*+Parallel(p1 8)Parallel(p2 0)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: Parallel(p1 8 soft) Parallel(p2 0 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------ Gather Workers Planned: 2 -> Parallel Hash Join Hash Cond: (p1.id = p2.id) -> Parallel Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 -> Parallel Hash -> Parallel Append -> Seq Scan on p2_c2 p2_3 -> Seq Scan on p2_c4 p2_5 -> Seq Scan on p2_c1_c1 p2_6 -> Seq Scan on p2_c1_c2 p2_7 -> Seq Scan on p2_c3_c1 p2_8 -> Seq Scan on p2_c3_c2 p2_9 -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c3 p2_4 (25 rows) SET parallel_setup_cost to DEFAULT; SET parallel_tuple_cost to DEFAULT; SET min_parallel_table_scan_size to DEFAULT; SET min_parallel_index_scan_size to DEFAULT; /*+Parallel(p2 8 soft)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: Parallel(p2 8 soft) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------------------- Hash Join Hash Cond: (p1.id = p2.id) -> Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c2 p1_3 -> Seq Scan on p1_c3 p1_4 -> Seq Scan on p1_c4 p1_5 -> Seq Scan on p1_c1_c1 p1_6 -> Seq Scan on p1_c1_c2 p1_7 -> Seq Scan on p1_c3_c1 p1_8 -> Seq Scan on p1_c3_c2 p1_9 -> Hash -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c2 p2_3 -> Seq Scan on p2_c3 p2_4 -> Seq Scan on p2_c4 p2_5 -> Seq Scan on p2_c1_c1 p2_6 -> Seq Scan on p2_c1_c2 p2_7 -> Seq Scan on p2_c3_c1 p2_8 -> Seq Scan on p2_c3_c2 p2_9 (23 rows) /*+Parallel(p2 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: Parallel(p2 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Gather Workers Planned: 8 -> Parallel Hash Join Hash Cond: (p2.id = p1.id) -> Parallel Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 -> Parallel Hash -> Parallel Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 (25 rows) -- Number of workers results to the largest number SET enable_parallel_append to false; /*+Parallel(p2 8 hard) Parallel(p1 5 hard) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: Parallel(p1 5 hard) Parallel(p2 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Gather Workers Planned: 8 -> Parallel Hash Join Hash Cond: (p1.id = p2.id) -> Append -> Parallel Seq Scan on p1 p1_1 -> Parallel Seq Scan on p1_c1 p1_2 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 -> Parallel Hash -> Append -> Parallel Seq Scan on p2 p2_1 -> Parallel Seq Scan on p2_c1 p2_2 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 (25 rows) SET enable_parallel_append to true; /*+Parallel(p2 8 hard) Parallel(p1 5 hard) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: Parallel(p1 5 hard) Parallel(p2 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Gather Workers Planned: 8 -> Parallel Hash Join Hash Cond: (p2.id = p1.id) -> Parallel Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 -> Parallel Hash -> Parallel Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 (25 rows) -- Mixture with scan hints -- p1 can be parallel SET enable_parallel_append to false; /*+Parallel(p1 8 hard) IndexScan(p2) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: IndexScan(p2) Parallel(p1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Hash Join Hash Cond: (p2.id = p1.id) -> Append -> Index Scan using p2_id2_val on p2 p2_1 -> Index Scan using p2_c1_id2_val on p2_c1 p2_2 -> Index Scan using p2_c2_id2_val on p2_c2 p2_3 -> Index Scan using p2_c3_id_val_idx on p2_c3 p2_4 -> Index Scan using p2_c4_id_val_idx on p2_c4 p2_5 -> Index Scan using p2_c1_c1_id_val_idx on p2_c1_c1 p2_6 -> Index Scan using p2_c1_c2_id_val_idx on p2_c1_c2 p2_7 -> Index Scan using p2_c3_c1_id_val_idx on p2_c3_c1 p2_8 -> Index Scan using p2_c3_c2_id_val_idx on p2_c3_c2 p2_9 -> Hash -> Gather Workers Planned: 8 -> Append -> Parallel Seq Scan on p1 p1_1 -> Parallel Seq Scan on p1_c1 p1_2 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 (25 rows) SET enable_parallel_append to true; /*+Parallel(p1 8 hard) IndexScan(p2) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: IndexScan(p2) Parallel(p1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------------- Hash Join Hash Cond: (p2.id = p1.id) -> Append -> Index Scan using p2_id2_val on p2 p2_1 -> Index Scan using p2_c1_id2_val on p2_c1 p2_2 -> Index Scan using p2_c2_id2_val on p2_c2 p2_3 -> Index Scan using p2_c3_id_val_idx on p2_c3 p2_4 -> Index Scan using p2_c4_id_val_idx on p2_c4 p2_5 -> Index Scan using p2_c1_c1_id_val_idx on p2_c1_c1 p2_6 -> Index Scan using p2_c1_c2_id_val_idx on p2_c1_c2 p2_7 -> Index Scan using p2_c3_c1_id_val_idx on p2_c3_c1 p2_8 -> Index Scan using p2_c3_c2_id_val_idx on p2_c3_c2 p2_9 -> Hash -> Gather Workers Planned: 8 -> Parallel Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 (25 rows) -- Parallel sequential scan SET enable_parallel_append to false; /*+Parallel(p1 8 hard) SeqScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: SeqScan(p1) Parallel(p1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Gather Workers Planned: 8 -> Parallel Hash Join Hash Cond: (p1.id = p2.id) -> Append -> Parallel Seq Scan on p1 p1_1 -> Parallel Seq Scan on p1_c1 p1_2 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 -> Parallel Hash -> Append -> Parallel Seq Scan on p2 p2_1 -> Parallel Seq Scan on p2_c1 p2_2 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 (25 rows) SET enable_parallel_append to true; /*+Parallel(p1 8 hard) SeqScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: SeqScan(p1) Parallel(p1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------------------ Gather Workers Planned: 8 -> Parallel Hash Join Hash Cond: (p1.id = p2.id) -> Parallel Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c3 p1_4 -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 -> Parallel Hash -> Parallel Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 (25 rows) -- Parallel index scan SET enable_parallel_append to false; /*+Parallel(p1 8 hard) IndexScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: IndexScan(p1) Parallel(p1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------- Gather Workers Planned: 8 -> Parallel Hash Join Hash Cond: (p1.id = p2.id) -> Append -> Parallel Index Scan using p1_pkey on p1 p1_1 -> Parallel Index Scan using p1_c1_pkey on p1_c1 p1_2 -> Parallel Index Scan using p1_c2_pkey on p1_c2 p1_3 -> Parallel Index Scan using p1_c3_pkey on p1_c3 p1_4 -> Parallel Index Scan using p1_c4_pkey on p1_c4 p1_5 -> Parallel Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1_6 -> Parallel Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1_7 -> Parallel Index Scan using p1_c3_c1_pkey on p1_c3_c1 p1_8 -> Parallel Index Scan using p1_c3_c2_pkey on p1_c3_c2 p1_9 -> Parallel Hash -> Append -> Parallel Seq Scan on p2 p2_1 -> Parallel Seq Scan on p2_c1 p2_2 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 (25 rows) SET enable_parallel_append to true; /*+Parallel(p1 8 hard) IndexScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: IndexScan(p1) Parallel(p1 8 hard) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------- Gather Workers Planned: 8 -> Parallel Hash Join Hash Cond: (p1.id = p2.id) -> Parallel Append -> Parallel Index Scan using p1_pkey on p1 p1_1 -> Parallel Index Scan using p1_c1_pkey on p1_c1 p1_2 -> Parallel Index Scan using p1_c2_pkey on p1_c2 p1_3 -> Parallel Index Scan using p1_c3_pkey on p1_c3 p1_4 -> Parallel Index Scan using p1_c4_pkey on p1_c4 p1_5 -> Parallel Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1_6 -> Parallel Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1_7 -> Parallel Index Scan using p1_c3_c1_pkey on p1_c3_c1 p1_8 -> Parallel Index Scan using p1_c3_c2_pkey on p1_c3_c2 p1_9 -> Parallel Hash -> Parallel Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c3 p2_4 -> Parallel Seq Scan on p2_c2 p2_3 -> Parallel Seq Scan on p2_c4 p2_5 -> Parallel Seq Scan on p2_c1_c1 p2_6 -> Parallel Seq Scan on p2_c1_c2 p2_7 -> Parallel Seq Scan on p2_c3_c1 p2_8 -> Parallel Seq Scan on p2_c3_c2 p2_9 (25 rows) -- This hint doesn't turn on parallel, so the Parallel hint is ignored set max_parallel_workers_per_gather TO 0; /*+Parallel(p1 0 hard) IndexScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; LOG: pg_hint_plan: used hint: IndexScan(p1) not used hint: Parallel(p1 0 hard) duplication hint: error hint: QUERY PLAN ------------------------------------------------------------- Hash Join Hash Cond: (p1.id = p2.id) -> Append -> Index Scan using p1_pkey on p1 p1_1 -> Index Scan using p1_c1_pkey on p1_c1 p1_2 -> Index Scan using p1_c2_pkey on p1_c2 p1_3 -> Index Scan using p1_c3_pkey on p1_c3 p1_4 -> Index Scan using p1_c4_pkey on p1_c4 p1_5 -> Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1_6 -> Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1_7 -> Index Scan using p1_c3_c1_pkey on p1_c3_c1 p1_8 -> Index Scan using p1_c3_c2_pkey on p1_c3_c2 p1_9 -> Hash -> Append -> Seq Scan on p2 p2_1 -> Seq Scan on p2_c1 p2_2 -> Seq Scan on p2_c2 p2_3 -> Seq Scan on p2_c3 p2_4 -> Seq Scan on p2_c4 p2_5 -> Seq Scan on p2_c1_c1 p2_6 -> Seq Scan on p2_c1_c2 p2_7 -> Seq Scan on p2_c3_c1 p2_8 -> Seq Scan on p2_c3_c2 p2_9 (23 rows) -- Parallel on UNION EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; QUERY PLAN --------------------------------- Append -> Seq Scan on p1 -> Seq Scan on p1_c1 p1_1 -> Seq Scan on p1_c2 p1_2 -> Seq Scan on p1_c3 p1_3 -> Seq Scan on p1_c4 p1_4 -> Seq Scan on p1_c1_c1 p1_5 -> Seq Scan on p1_c1_c2 p1_6 -> Seq Scan on p1_c3_c1 p1_7 -> Seq Scan on p1_c3_c2 p1_8 -> Seq Scan on p2 -> Seq Scan on p2_c1 p2_1 -> Seq Scan on p2_c2 p2_2 -> Seq Scan on p2_c3 p2_3 -> Seq Scan on p2_c4 p2_4 -> Seq Scan on p2_c1_c1 p2_5 -> Seq Scan on p2_c1_c2 p2_6 -> Seq Scan on p2_c3_c1 p2_7 -> Seq Scan on p2_c3_c2 p2_8 (19 rows) -- parallel hinting on any relation enables parallel SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET max_parallel_workers_per_gather to 0; /*+Parallel(p1 8) */ EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; LOG: pg_hint_plan: used hint: Parallel(p1 8 soft) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 1 -> Parallel Append -> Parallel Seq Scan on p2_c2 p2_2 -> Parallel Seq Scan on p2_c4 p2_4 -> Parallel Seq Scan on p2_c1_c1 p2_5 -> Parallel Seq Scan on p2_c1_c2 p2_6 -> Parallel Seq Scan on p2_c3_c1 p2_7 -> Parallel Seq Scan on p2_c3_c2 p2_8 -> Parallel Seq Scan on p1 -> Parallel Seq Scan on p1_c1 p1_1 -> Parallel Seq Scan on p1_c2 p1_2 -> Parallel Seq Scan on p1_c3 p1_3 -> Parallel Seq Scan on p1_c4 p1_4 -> Parallel Seq Scan on p1_c1_c1 p1_5 -> Parallel Seq Scan on p1_c1_c2 p1_6 -> Parallel Seq Scan on p1_c3_c1 p1_7 -> Parallel Seq Scan on p1_c3_c2 p1_8 -> Parallel Seq Scan on p2 -> Parallel Seq Scan on p2_c1 p2_1 -> Parallel Seq Scan on p2_c3 p2_3 (21 rows) -- set hint has the same effect /*+Set(max_parallel_workers_per_gather 1)*/ EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; LOG: pg_hint_plan: used hint: Set(max_parallel_workers_per_gather 1) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 1 -> Parallel Append -> Parallel Seq Scan on p1_c2 p1_2 -> Parallel Seq Scan on p1_c4 p1_4 -> Parallel Seq Scan on p2_c2 p2_2 -> Parallel Seq Scan on p2_c4 p2_4 -> Parallel Seq Scan on p1_c1_c1 p1_5 -> Parallel Seq Scan on p1_c1_c2 p1_6 -> Parallel Seq Scan on p1_c3_c1 p1_7 -> Parallel Seq Scan on p1_c3_c2 p1_8 -> Parallel Seq Scan on p2_c1_c1 p2_5 -> Parallel Seq Scan on p2_c1_c2 p2_6 -> Parallel Seq Scan on p2_c3_c1 p2_7 -> Parallel Seq Scan on p2_c3_c2 p2_8 -> Parallel Seq Scan on p1 -> Parallel Seq Scan on p1_c1 p1_1 -> Parallel Seq Scan on p1_c3 p1_3 -> Parallel Seq Scan on p2 -> Parallel Seq Scan on p2_c1 p2_1 -> Parallel Seq Scan on p2_c3 p2_3 (21 rows) -- applies largest number of workers on merged parallel paths SET parallel_setup_cost to DEFAULT; SET parallel_tuple_cost to DEFAULT; SET min_parallel_table_scan_size to DEFAULT; SET min_parallel_index_scan_size to DEFAULT; SET max_parallel_workers_per_gather to 8; /*+Parallel(p1 5 hard)Parallel(p2 6 hard) */ EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; LOG: pg_hint_plan: used hint: Parallel(p1 5 hard) Parallel(p2 6 hard) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------------ Gather Workers Planned: 6 -> Parallel Append -> Seq Scan on p1 -> Seq Scan on p1_c1 p1_1 -> Seq Scan on p1_c3 p1_3 -> Seq Scan on p2 -> Seq Scan on p2_c1 p2_1 -> Seq Scan on p2_c3 p2_3 -> Parallel Seq Scan on p1_c2 p1_2 -> Parallel Seq Scan on p1_c4 p1_4 -> Parallel Seq Scan on p1_c1_c1 p1_5 -> Parallel Seq Scan on p1_c1_c2 p1_6 -> Parallel Seq Scan on p1_c3_c1 p1_7 -> Parallel Seq Scan on p1_c3_c2 p1_8 -> Parallel Seq Scan on p2_c2 p2_2 -> Parallel Seq Scan on p2_c4 p2_4 -> Parallel Seq Scan on p2_c1_c1 p2_5 -> Parallel Seq Scan on p2_c1_c2 p2_6 -> Parallel Seq Scan on p2_c3_c1 p2_7 -> Parallel Seq Scan on p2_c3_c2 p2_8 (21 rows) -- On empty tables, parallel hints can only be enforced for index scans -- and not sequential scans. Adding a single row allows a parallel -- hint to be enforced on a sequential scan. It is a bit weird that -- having no rows controls how parallel workers are triggered, but -- at the same time we have nothing to query, and this is an old -- historical (and accidental) behavior. /*+Parallel(t5 4 hard) Parallel(t6 2 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t5 NATURAL JOIN s1.t6; LOG: pg_hint_plan: used hint: Parallel(t5 4 hard) Parallel(t6 2 hard) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------- Nested Loop Join Filter: ((t5.c1 = t6.c1) AND (t6.c2 = t5.c2) AND (t6.c3 = t5.c3) AND (t6.c4 = t5.c4)) -> Seq Scan on t5 -> Seq Scan on t6 (4 rows) /*+Parallel(t5 4 hard) Parallel(t6 2 hard) NoSeqScan(t5) NoSeqScan(t6) */ EXPLAIN (COSTS false) SELECT * FROM s1.t5 NATURAL JOIN s1.t6; LOG: pg_hint_plan: used hint: NoSeqScan(t5) NoSeqScan(t6) Parallel(t5 4 hard) Parallel(t6 2 hard) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------- Nested Loop Join Filter: ((t5.c1 = t6.c1) AND (t6.c2 = t5.c2) AND (t6.c3 = t5.c3) AND (t6.c4 = t5.c4)) -> Gather Workers Planned: 4 -> Parallel Index Scan using t5_pkey on t5 -> Gather Workers Planned: 2 -> Parallel Index Scan using t6_pkey on t6 (8 rows) INSERT INTO s1.t5 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 1) i) t; INSERT INTO s1.t6 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 1) i) t; ANALYZE s1.t5; ANALYZE s1.t6; /*+Parallel(t5 4 hard) Parallel(t6 2 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t5 NATURAL JOIN s1.t6; LOG: pg_hint_plan: used hint: Parallel(t5 4 hard) Parallel(t6 2 hard) not used hint: duplication hint: error hint: QUERY PLAN ---------------------------------------------------------------------------------------------- Nested Loop Join Filter: ((t5.c1 = t6.c1) AND (t6.c2 = t5.c2) AND (t6.c3 = t5.c3) AND (t6.c4 = t5.c4)) -> Gather Workers Planned: 4 -> Parallel Seq Scan on t5 -> Gather Workers Planned: 2 -> Parallel Seq Scan on t6 (8 rows) -- Negative hints SET enable_indexscan to DEFAULT; SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET max_parallel_workers_per_gather to 5; EXPLAIN (COSTS false) SELECT * FROM p1; QUERY PLAN ------------------------------------------------ Gather Workers Planned: 4 -> Parallel Append -> Parallel Seq Scan on p1_c2 p1_3 -> Parallel Seq Scan on p1_c4 p1_5 -> Parallel Seq Scan on p1_c1_c1 p1_6 -> Parallel Seq Scan on p1_c1_c2 p1_7 -> Parallel Seq Scan on p1_c3_c1 p1_8 -> Parallel Seq Scan on p1_c3_c2 p1_9 -> Parallel Seq Scan on p1 p1_1 -> Parallel Seq Scan on p1_c1 p1_2 -> Parallel Seq Scan on p1_c3 p1_4 (12 rows) SET enable_parallel_append to false; /*+Parallel(p1 0 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; LOG: pg_hint_plan: used hint: Parallel(p1 0 hard) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c2 p1_3 -> Seq Scan on p1_c3 p1_4 -> Seq Scan on p1_c4 p1_5 -> Seq Scan on p1_c1_c1 p1_6 -> Seq Scan on p1_c1_c2 p1_7 -> Seq Scan on p1_c3_c1 p1_8 -> Seq Scan on p1_c3_c2 p1_9 (10 rows) SET enable_parallel_append to true; /*+Parallel(p1 0 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; LOG: pg_hint_plan: used hint: Parallel(p1 0 hard) not used hint: duplication hint: error hint: QUERY PLAN --------------------------------- Append -> Seq Scan on p1 p1_1 -> Seq Scan on p1_c1 p1_2 -> Seq Scan on p1_c2 p1_3 -> Seq Scan on p1_c3 p1_4 -> Seq Scan on p1_c4 p1_5 -> Seq Scan on p1_c1_c1 p1_6 -> Seq Scan on p1_c1_c2 p1_7 -> Seq Scan on p1_c3_c1 p1_8 -> Seq Scan on p1_c3_c2 p1_9 (10 rows) -- Errors /*+Parallel(p1 100x hard)Parallel(p1 -1000 hard)Parallel(p1 1000000 hard) Parallel(p1 8 hoge)Parallel(p1)Parallel(p1 100 soft x)*/ EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; INFO: pg_hint_plan: hint syntax error at or near "100x" DETAIL: number of workers must be a number: Parallel INFO: pg_hint_plan: hint syntax error at or near "-1000" DETAIL: number of workers must be greater than zero: Parallel INFO: pg_hint_plan: hint syntax error at or near "1000000" DETAIL: number of workers = 1000000 is larger than max_worker_processes(8): Parallel INFO: pg_hint_plan: hint syntax error at or near "hoge" DETAIL: enforcement must be soft or hard: Parallel INFO: pg_hint_plan: hint syntax error at or near ")" DETAIL: wrong number of arguments (1): Parallel INFO: pg_hint_plan: hint syntax error at or near ")" DETAIL: wrong number of arguments (4): Parallel LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Parallel(p1 100x hard) Parallel(p1 -1000 hard) Parallel(p1 1000000 hard) Parallel(p1 8 soft) Parallel() Parallel() QUERY PLAN ------------------------------------------------ Gather Workers Planned: 1 -> Parallel Append -> Parallel Seq Scan on p1_c2 p1_2 -> Parallel Seq Scan on p1_c4 p1_4 -> Parallel Seq Scan on p2_c2 p2_2 -> Parallel Seq Scan on p2_c4 p2_4 -> Parallel Seq Scan on p1_c1_c1 p1_5 -> Parallel Seq Scan on p1_c1_c2 p1_6 -> Parallel Seq Scan on p1_c3_c1 p1_7 -> Parallel Seq Scan on p1_c3_c2 p1_8 -> Parallel Seq Scan on p2_c1_c1 p2_5 -> Parallel Seq Scan on p2_c1_c2 p2_6 -> Parallel Seq Scan on p2_c3_c1 p2_7 -> Parallel Seq Scan on p2_c3_c2 p2_8 -> Parallel Seq Scan on p1 -> Parallel Seq Scan on p1_c1 p1_1 -> Parallel Seq Scan on p1_c3 p1_3 -> Parallel Seq Scan on p2 -> Parallel Seq Scan on p2_c1 p2_1 -> Parallel Seq Scan on p2_c3 p2_3 (21 rows) -- Hints on unhintable relations are just ignored SELECT explain_filter(' /*+Parallel(p1 5 hard) Parallel(s1 3 hard) IndexScan(ft1) SeqScan(cte1) IndexScan(t) IndexScan(*VALUES*) */ EXPLAIN (COSTS false) SELECT id FROM p1_c1_c1 as s1 TABLESAMPLE SYSTEM(10) UNION ALL SELECT id FROM ft1 UNION ALL (WITH cte1 AS (SELECT id FROM p1 WHERE id % 2 = 0) SELECT id FROM cte1) UNION ALL SELECT x FROM (VALUES (1), (2), (3)) t(x); '); LOG: pg_hint_plan: used hint: Parallel(p1 5 hard) not used hint: IndexScan(*VALUES*) SeqScan(cte1) IndexScan(ft1) IndexScan(t) Parallel(s1 3 hard) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: IndexScan(*VALUES*) SeqScan(cte1) IndexScan(ft1) IndexScan(t) Parallel(p1 5 hard) Parallel(s1 3 hard) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: IndexScan(*VALUES*) SeqScan(cte1) IndexScan(ft1) IndexScan(t) Parallel(p1 5 hard) Parallel(s1 3 hard) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: IndexScan(*VALUES*) SeqScan(cte1) IndexScan(ft1) IndexScan(t) Parallel(p1 5 hard) Parallel(s1 3 hard) duplication hint: error hint: LOG: pg_hint_plan: used hint: not used hint: IndexScan(*VALUES*) SeqScan(cte1) IndexScan(ft1) IndexScan(t) Parallel(p1 5 hard) Parallel(s1 3 hard) duplication hint: error hint: explain_filter ------------------------------------------------------ Gather Workers Planned: 1 Single Copy: true -> Parallel Append -> Sample Scan on p1_c1_c1 s1 Sampling: system ('10'::real) -> Foreign Scan on ft1 Foreign File: (snip..) -> Values Scan on "*VALUES*" -> Parallel Append -> Seq Scan on p1 p1_1 Filter: ((id % 2) = 0) -> Seq Scan on p1_c1 p1_2 Filter: ((id % 2) = 0) -> Seq Scan on p1_c3 p1_4 Filter: ((id % 2) = 0) -> Parallel Seq Scan on p1_c2 p1_3 Filter: ((id % 2) = 0) -> Parallel Seq Scan on p1_c4 p1_5 Filter: ((id % 2) = 0) -> Parallel Seq Scan on p1_c1_c1 p1_6 Filter: ((id % 2) = 0) -> Parallel Seq Scan on p1_c1_c2 p1_7 Filter: ((id % 2) = 0) -> Parallel Seq Scan on p1_c3_c1 p1_8 Filter: ((id % 2) = 0) -> Parallel Seq Scan on p1_c3_c2 p1_9 Filter: ((id % 2) = 0) (28 rows) pg_hint_plan-REL17_1_7_0/expected/ut-fdw.out000066400000000000000000000102501466301071500207360ustar00rootroot00000000000000-- directory paths and dlsuffix are passed to us in environment variables \getenv abs_srcdir PG_ABS_SRCDIR \set filename :abs_srcdir '/data/data.csv' LOAD 'pg_hint_plan'; SET search_path TO public; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET pg_hint_plan.enable_hint TO on; CREATE EXTENSION file_fdw; CREATE SERVER file_server FOREIGN DATA WRAPPER file_fdw; CREATE USER MAPPING FOR PUBLIC SERVER file_server; CREATE FOREIGN TABLE ft1 (id int, val int) SERVER file_server OPTIONS (format 'csv', filename :'filename'); -- foreign table test SELECT * FROM ft1; id | val ----+----- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 (10 rows) \t SELECT explain_filter(' EXPLAIN (COSTS false) SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); Nested Loop Join Filter: (t1.c1 = ft_1.id) -> Nested Loop Join Filter: (ft_1.id = ft_2.id) -> Foreign Scan on ft1 ft_1 Foreign File: (snip..) -> Foreign Scan on ft1 ft_2 Foreign File: (snip..) -> Index Scan using t1_i1 on t1 Index Cond: (c1 = ft_2.id) ---- ---- No. S-1-5 object type for the hint ---- -- No. S-1-5-6 SELECT explain_filter(' /*+SeqScan(t1)SeqScan(ft_1)SeqScan(ft_2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); LOG: pg_hint_plan: used hint: SeqScan(t1) not used hint: SeqScan(ft_1) SeqScan(ft_2) duplication hint: error hint: Nested Loop Join Filter: (t1.c1 = ft_2.id) -> Hash Join Hash Cond: (t1.c1 = ft_1.id) -> Seq Scan on t1 -> Hash -> Foreign Scan on ft1 ft_1 Foreign File: (snip..) -> Foreign Scan on ft1 ft_2 Foreign File: (snip..) ---- ---- No. J-1-6 object type for the hint ---- -- No. J-1-6-6 SELECT explain_filter(' /*+MergeJoin(ft_1 ft_2)Leading(ft_1 ft_2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); LOG: pg_hint_plan: used hint: MergeJoin(ft_1 ft_2) Leading(ft_1 ft_2 t1) not used hint: duplication hint: error hint: Nested Loop Join Filter: (t1.c1 = ft_1.id) -> Merge Join Merge Cond: (ft_1.id = ft_2.id) -> Sort Sort Key: ft_1.id -> Foreign Scan on ft1 ft_1 Foreign File: (snip..) -> Sort Sort Key: ft_2.id -> Foreign Scan on ft1 ft_2 Foreign File: (snip..) -> Index Scan using t1_i1 on t1 Index Cond: (c1 = ft_2.id) ---- ---- No. L-1-6 object type for the hint ---- -- No. L-1-6-6 SELECT explain_filter(' /*+Leading(ft_1 ft_2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); LOG: pg_hint_plan: used hint: Leading(ft_1 ft_2 t1) not used hint: duplication hint: error hint: Nested Loop Join Filter: (t1.c1 = ft_1.id) -> Nested Loop Join Filter: (ft_1.id = ft_2.id) -> Foreign Scan on ft1 ft_1 Foreign File: (snip..) -> Foreign Scan on ft1 ft_2 Foreign File: (snip..) -> Index Scan using t1_i1 on t1 Index Cond: (c1 = ft_2.id) ---- ---- No. R-1-6 object type for the hint ---- -- No. R-1-6-6 SELECT explain_filter(' /*+Rows(ft_1 ft_2 #1)Leading(ft_1 ft_2 t1)*/ EXPLAIN SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); LOG: pg_hint_plan: used hint: Leading(ft_1 ft_2 t1) Rows(ft_1 ft_2 #1) not used hint: duplication hint: error hint: Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (t1.c1 = ft_1.id) -> Nested Loop (cost=xxx..xxx rows=1 width=xxx) Join Filter: (ft_1.id = ft_2.id) -> Foreign Scan on ft1 ft_1 (cost=xxx..xxx rows=1 width=xxx) Foreign File: (snip..) Foreign File Size: 42 b -> Foreign Scan on ft1 ft_2 (cost=xxx..xxx rows=1 width=xxx) Foreign File: (snip..) Foreign File Size: 42 b -> Index Scan using t1_i1 on t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = ft_2.id) pg_hint_plan-REL17_1_7_0/expected/ut-fini.out000066400000000000000000000001561466301071500211070ustar00rootroot00000000000000DROP ROLE IF EXISTS regress_super_user; DROP ROLE IF EXISTS regress_normal_user; DROP EXTENSION pg_hint_plan; pg_hint_plan-REL17_1_7_0/expected/ut-init.out000066400000000000000000000303031466301071500211220ustar00rootroot00000000000000SET search_path TO public; CREATE EXTENSION btree_gist; CREATE EXTENSION btree_gin; CREATE ROLE regress_super_user SUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION CONNECTION LIMIT 1; CREATE ROLE regress_normal_user NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION CONNECTION LIMIT 1; CREATE SCHEMA s1; CREATE SCHEMA s2; CREATE TABLE s1.t1 (c1 int, c2 int, c3 int, c4 text, PRIMARY KEY (c1)); CREATE TABLE s1.t2 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.t3 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.t4 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.t5 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.t6 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s2.t1 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.p1 (LIKE s1.t1 INCLUDING ALL); CREATE UNIQUE INDEX p1_parent ON s1.p1 USING btree (c4 COLLATE "C" varchar_ops ASC NULLS LAST, (c1 * 2 < 100)) WHERE c1 < 10; CREATE TABLE s1.p2 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.p1c1 (LIKE s1.p1 INCLUDING ALL, CHECK (c1 <= 100)) INHERITS(s1.p1); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition CREATE TABLE s1.p1c2 (LIKE s1.p1 INCLUDING ALL, CHECK (c1 > 100 AND c1 <= 200)) INHERITS(s1.p1); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition CREATE TABLE s1.p1c3 (LIKE s1.p1 INCLUDING ALL, CHECK (c1 > 200)) INHERITS(s1.p1); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition CREATE TABLE s1.p2c1 (LIKE s1.p2 INCLUDING ALL, CHECK (c1 <= 100)) INHERITS(s1.p2); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition CREATE TABLE s1.p2c2 (LIKE s1.p2 INCLUDING ALL, CHECK (c1 > 100 AND c1 <= 200)) INHERITS(s1.p2); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition CREATE TABLE s1.p2c3 (LIKE s1.p2 INCLUDING ALL, CHECK (c1 > 200)) INHERITS(s1.p2); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition CREATE TABLE s1.p2c1c1 (LIKE s1.p2c1 INCLUDING ALL, CHECK (c1 <= 50)) INHERITS(s1.p2c1); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition NOTICE: merging constraint "p2c1_c1_check" with inherited definition CREATE TABLE s1.p2c1c2 (LIKE s1.p2c1 INCLUDING ALL, CHECK (c1 > 50 AND c1 <= 100)) INHERITS(s1.p2c1); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition NOTICE: merging constraint "p2c1_c1_check" with inherited definition CREATE TABLE s1.p2c2c1 (LIKE s1.p2c2 INCLUDING ALL, CHECK (c1 > 100 AND c1 <= 150)) INHERITS(s1.p2c2); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition NOTICE: merging constraint "p2c2_c1_check" with inherited definition CREATE TABLE s1.p2c2c2 (LIKE s1.p2c2 INCLUDING ALL, CHECK (c1 > 150 AND c1 <= 200)) INHERITS(s1.p2c2); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition NOTICE: merging constraint "p2c2_c1_check" with inherited definition CREATE TABLE s1.p2c3c1 (LIKE s1.p2c3 INCLUDING ALL, CHECK (c1 > 200 AND c1 <= 250)) INHERITS(s1.p2c3); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition NOTICE: merging constraint "p2c3_c1_check" with inherited definition CREATE TABLE s1.p2c3c2 (LIKE s1.p2c3 INCLUDING ALL, CHECK (c1 > 250)) INHERITS(s1.p2c3); NOTICE: merging column "c1" with inherited definition NOTICE: merging column "c2" with inherited definition NOTICE: merging column "c3" with inherited definition NOTICE: merging column "c4" with inherited definition NOTICE: merging constraint "p2c3_c1_check" with inherited definition CREATE TABLE s1.r1 (LIKE s1.t1); CREATE TABLE s1.r2 (LIKE s1.t1); CREATE TABLE s1.r3 (LIKE s1.t1); CREATE TABLE s1.r4 (LIKE s1.t1); CREATE TABLE s1.r5 (LIKE s1.t1); CREATE TABLE s1.r1_ (LIKE s1.t1); CREATE TABLE s1.r2_ (LIKE s1.t1); CREATE TABLE s1.r3_ (LIKE s1.t1); CREATE TABLE s1.ti1 (c1 int, c2 int, c3 int, c4 text, PRIMARY KEY (c1), UNIQUE (c2)); CREATE TABLE s1.pt1 (c1 int, c2 int, c3 int, c4 int) PARTITION BY RANGE (c1); CREATE TABLE s1.pt1_c1 PARTITION OF s1.pt1 FOR VALUES FROM (MINVALUE) TO (101); CREATE TABLE s1.pt1_c2 PARTITION OF s1.pt1 FOR VALUES FROM (101) TO (201); CREATE TABLE s1.pt1_c3 PARTITION OF s1.pt1 FOR VALUES FROM (201) TO (MAXVALUE); CREATE UNLOGGED TABLE s1.ul1 (LIKE s1.t1 INCLUDING ALL); INSERT INTO s1.t1 SELECT i, i, i % 100, i FROM (SELECT generate_series(1, 1000) i) t; INSERT INTO s1.t2 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 100) i) t; INSERT INTO s2.t1 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 100) i) t; INSERT INTO s1.p1c1 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 100) i) t; INSERT INTO s1.p1c2 SELECT i, i, i % 10, i FROM (SELECT generate_series(101, 200) i) t; INSERT INTO s1.p1c3 SELECT i, i, i % 10, i FROM (SELECT generate_series(201, 300) i) t; INSERT INTO s1.p2c1c1 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 50) i) t; INSERT INTO s1.p2c1c2 SELECT i, i, i % 10, i FROM (SELECT generate_series(51, 100) i) t; INSERT INTO s1.p2c2c1 SELECT i, i, i % 10, i FROM (SELECT generate_series(101, 150) i) t; INSERT INTO s1.p2c2c2 SELECT i, i, i % 10, i FROM (SELECT generate_series(151, 200) i) t; INSERT INTO s1.p2c3c1 SELECT i, i, i % 10, i FROM (SELECT generate_series(201, 250) i) t; INSERT INTO s1.p2c3c2 SELECT i, i, i % 10, i FROM (SELECT generate_series(251, 300) i) t; INSERT INTO s1.ti1 SELECT i, i, i % 100, i FROM (SELECT generate_series(1, 1000) i) t; INSERT INTO s1.pt1 SELECT i, i, i % 10, i FROM (SELECT generate_series(0, 300) i) t; CREATE INDEX t1_i ON s1.t1 (c3); CREATE INDEX t1_i1 ON s1.t1 (c1); CREATE INDEX t2_i1 ON s1.t2 (c1); CREATE INDEX t3_i1 ON s1.t3 (c1); CREATE INDEX t4_i1 ON s1.t4 (c1); CREATE INDEX p1_i ON s1.p1 (c1); CREATE INDEX p2_i ON s1.p2 (c1); CREATE INDEX p1_i2 ON s1.p1 (c2); CREATE INDEX p1c1_i ON s1.p1c1 (c1); CREATE INDEX p1c2_i ON s1.p1c2 (c1); CREATE INDEX p1c3_i ON s1.p1c3 (c1); CREATE INDEX p2c1_i ON s1.p2c1 (c1); CREATE INDEX p2c2_i ON s1.p2c2 (c1); CREATE INDEX p2c3_i ON s1.p2c3 (c1); CREATE INDEX p2c1c1_i ON s1.p2c1c1 (c1); CREATE INDEX p2c1c2_i ON s1.p2c1c2 (c1); CREATE INDEX p2c2c1_i ON s1.p2c2c1 (c1); CREATE INDEX p2c2c2_i ON s1.p2c2c2 (c1); CREATE INDEX p2c3c1_i ON s1.p2c3c1 (c1); CREATE INDEX p2c3c2_i ON s1.p2c3c2 (c1); CREATE INDEX ti1_i1 ON s1.ti1 (c2); CREATE INDEX ti1_i2 ON s1.ti1 (c2, c4); CREATE INDEX ti1_i3 ON s1.ti1 (c2, c4, c4); CREATE INDEX ti1_i4 ON s1.ti1 (c2, c4, c4, c4); CREATE INDEX ti1_btree ON s1.ti1 USING btree (c1); CREATE INDEX ti1_hash ON s1.ti1 USING hash (c1); CREATE INDEX ti1_gist ON s1.ti1 USING gist (c1); CREATE INDEX ti1_gin ON s1.ti1 USING gin (c1); CREATE INDEX ti1_expr ON s1.ti1 ((c1 < 100)); CREATE INDEX ti1_pred ON s1.ti1 (lower(c4)); CREATE UNIQUE INDEX ti1_uniq ON s1.ti1 (c1); CREATE INDEX ti1_multi ON s1.ti1 (c1, c2, c3, c4); CREATE INDEX ti1_ts ON s1.ti1 USING gin(to_tsvector('english', c4)); CREATE INDEX pt1_c1_c2_i ON s1.pt1_c1(c2); CREATE INDEX pt1_c1_c3_i ON s1.pt1_c1(c3); CREATE INDEX pt1_c2_c2_i ON s1.pt1_c2(c2); CREATE INDEX pt1_c2_c3_i ON s1.pt1_c2(c3); CREATE INDEX pt1_c3_c2_i ON s1.pt1_c3(c2); CREATE INDEX pt1_c3_c3_i ON s1.pt1_c3(c3); CREATE VIEW s1.v1 AS SELECT v1t1.c1, v1t1.c2, v1t1.c3, v1t1.c4 FROM s1.t1 v1t1; CREATE VIEW s1.v1_ AS SELECT v1t1_.c1, v1t1_.c2, v1t1_.c3, v1t1_.c4 FROM s1.t1 v1t1_; CREATE VIEW s1.v2 AS SELECT v2t1.c1, v2t1.c2, v2t1.c3, v2t1.c4 FROM s1.t1 v2t1 JOIN s1.t2 v2t2 ON(v2t1.c1 = v2t2.c1); CREATE VIEW s1.v3 AS SELECT v3t1.c1, v3t1.c2, v3t1.c3, v3t1.c4 FROM s1.t1 v3t1 JOIN s1.t2 v3t2 ON(v3t1.c1 = v3t2.c1) JOIN s1.t3 v3t3 ON(v3t1.c1 = v3t3.c1); ANALYZE s1.t1; ANALYZE s1.t2; ANALYZE s2.t1; ANALYZE s1.p1; ANALYZE s1.p2; ANALYZE s1.p1c1; ANALYZE s1.p1c2; ANALYZE s1.p1c3; ANALYZE s1.p2c1c1; ANALYZE s1.p2c1c2; ANALYZE s1.p2c2c1; ANALYZE s1.p2c2c2; ANALYZE s1.p2c3c1; ANALYZE s1.p2c3c2; ANALYZE s1.ti1; ANALYZE s1.pt1; ANALYZE s1.t5; ANALYZE s1.t6; CREATE FUNCTION s1.f1 () RETURNS s1.t1 AS $$ VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3') $$ LANGUAGE sql; CREATE RULE r1 AS ON UPDATE TO s1.r1 DO INSTEAD ( SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; ); CREATE RULE r2 AS ON UPDATE TO s1.r2 DO INSTEAD ( SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; ); CREATE RULE r3 AS ON UPDATE TO s1.r3 DO INSTEAD ( SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; ); CREATE RULE r1_ AS ON UPDATE TO s1.r1_ DO INSTEAD ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)'; ); CREATE RULE r2_ AS ON UPDATE TO s1.r2_ DO INSTEAD ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)'; SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)'; ); CREATE RULE r3_ AS ON UPDATE TO s1.r3_ DO INSTEAD ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)'; SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)'; SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)'; ); pg_hint_plan-REL17_1_7_0/make_join_rel.c000066400000000000000000000300331466301071500201410ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * make_join_rel.c * Routines copied from PostgreSQL core distribution with some * modifications. * * src/backend/optimizer/path/joinrels.c * * This file contains the following functions from corresponding files. * * static functions: * make_join_rel() * populate_joinrel_with_paths() * * Portions Copyright (c) 2013-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- */ /* * adjust_rows: tweak estimated row numbers according to the hint. */ static double adjust_rows(double rows, RowsHint *hint) { double result = 0.0; /* keep compiler quiet */ if (hint->value_type == RVT_ABSOLUTE) result = hint->rows; else if (hint->value_type == RVT_ADD) result = rows + hint->rows; else if (hint->value_type == RVT_SUB) result = rows - hint->rows; else if (hint->value_type == RVT_MULTI) result = rows * hint->rows; else Assert(false); /* unrecognized rows value type */ hint->base.state = HINT_STATE_USED; if (result < 1.0) ereport(WARNING, (errmsg("Force estimate to be at least one row, to avoid possible divide-by-zero when interpolating costs : %s", hint->base.hint_str))); result = clamp_row_est(result); elog(DEBUG1, "adjusted rows %d to %d", (int) rows, (int) result); return result; } /* * make_join_rel * Find or create a join RelOptInfo that represents the join of * the two given rels, and add to it path information for paths * created with the two rels as outer and inner rel. * (The join rel may already contain paths generated from other * pairs of rels that add up to the same set of base rels.) * * NB: will return NULL if attempted join is not valid. This can happen * when working with outer joins, or with IN or EXISTS clauses that have been * turned into joins. */ RelOptInfo * make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2) { Relids joinrelids; SpecialJoinInfo *sjinfo; bool reversed; List *pushed_down_joins = NIL; SpecialJoinInfo sjinfo_data; RelOptInfo *joinrel; List *restrictlist; /* We should never try to join two overlapping sets of rels. */ Assert(!bms_overlap(rel1->relids, rel2->relids)); /* Construct Relids set that identifies the joinrel (without OJ as yet). */ joinrelids = bms_union(rel1->relids, rel2->relids); /* Check validity and determine join type. */ if (!join_is_legal(root, rel1, rel2, joinrelids, &sjinfo, &reversed)) { /* invalid join path */ bms_free(joinrelids); return NULL; } /* * Add outer join relid(s) to form the canonical relids. Any added outer * joins besides sjinfo itself are appended to pushed_down_joins. */ joinrelids = add_outer_joins_to_relids(root, joinrelids, sjinfo, &pushed_down_joins); /* Swap rels if needed to match the join info. */ if (reversed) { RelOptInfo *trel = rel1; rel1 = rel2; rel2 = trel; } /* * If it's a plain inner join, then we won't have found anything in * join_info_list. Make up a SpecialJoinInfo so that selectivity * estimation functions will know what's being joined. */ if (sjinfo == NULL) { sjinfo = &sjinfo_data; init_dummy_sjinfo(sjinfo, rel1->relids, rel2->relids); } /* * Find or build the join RelOptInfo, and compute the restrictlist that * goes with this particular joining. */ joinrel = build_join_rel(root, joinrelids, rel1, rel2, sjinfo, pushed_down_joins, &restrictlist); /* !!! START: HERE IS THE PART WHICH IS ADDED FOR PG_HINT_PLAN !!! */ { RowsHint *rows_hint = NULL; int i; RowsHint *justforme = NULL; RowsHint *domultiply = NULL; /* Search for applicable rows hint for this join node */ for (i = 0; i < current_hint_state->num_hints[HINT_TYPE_ROWS]; i++) { rows_hint = current_hint_state->rows_hints[i]; /* * Skip this rows_hint if it is invalid from the first or it * doesn't target any join rels. */ if (!rows_hint->joinrelids || rows_hint->base.state == HINT_STATE_ERROR) continue; if (bms_equal(joinrelids, rows_hint->joinrelids)) { /* * This joinrel is just the target of this rows_hint, so tweak * rows estimation according to the hint. */ justforme = rows_hint; } else if (!(bms_is_subset(rows_hint->joinrelids, rel1->relids) || bms_is_subset(rows_hint->joinrelids, rel2->relids)) && bms_is_subset(rows_hint->joinrelids, joinrelids) && rows_hint->value_type == RVT_MULTI) { /* * If the rows_hint's target relids is not a subset of both of * component rels and is a subset of this joinrel, ths hint's * targets spread over both component rels. This menas that * this hint has been never applied so far and this joinrel is * the first (and only) chance to fire in current join tree. * Only the multiplication hint has the cumulative nature so we * apply only RVT_MULTI in this way. */ domultiply = rows_hint; } } if (justforme) { /* * If a hint just for me is found, no other adjust method is * useles, but this cannot be more than twice becuase this joinrel * is already adjusted by this hint. */ if (justforme->base.state == HINT_STATE_NOTUSED) joinrel->rows = adjust_rows(joinrel->rows, justforme); } else { if (domultiply) { /* * If we have multiple routes up to this joinrel which are not * applicable this hint, this multiply hint will applied more * than twice. But there's no means to know of that, * re-estimate the row number of this joinrel always just * before applying the hint. This is a bit different from * normal planner behavior but it doesn't harm so much. */ set_joinrel_size_estimates(root, joinrel, rel1, rel2, sjinfo, restrictlist); joinrel->rows = adjust_rows(joinrel->rows, domultiply); } } } /* !!! END: HERE IS THE PART WHICH IS ADDED FOR PG_HINT_PLAN !!! */ /* * If we've already proven this join is empty, we needn't consider any * more paths for it. */ if (is_dummy_rel(joinrel)) { bms_free(joinrelids); return joinrel; } /* Add paths to the join relation. */ populate_joinrel_with_paths(root, rel1, rel2, joinrel, sjinfo, restrictlist); bms_free(joinrelids); return joinrel; } /* * populate_joinrel_with_paths * Add paths to the given joinrel for given pair of joining relations. The * SpecialJoinInfo provides details about the join and the restrictlist * contains the join clauses and the other clauses applicable for given pair * of the joining relations. */ static void populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, RelOptInfo *joinrel, SpecialJoinInfo *sjinfo, List *restrictlist) { /* * Consider paths using each rel as both outer and inner. Depending on * the join type, a provably empty outer or inner rel might mean the join * is provably empty too; in which case throw away any previously computed * paths and mark the join as dummy. (We do it this way since it's * conceivable that dummy-ness of a multi-element join might only be * noticeable for certain construction paths.) * * Also, a provably constant-false join restriction typically means that * we can skip evaluating one or both sides of the join. We do this by * marking the appropriate rel as dummy. For outer joins, a * constant-false restriction that is pushed down still means the whole * join is dummy, while a non-pushed-down one means that no inner rows * will join so we can treat the inner rel as dummy. * * We need only consider the jointypes that appear in join_info_list, plus * JOIN_INNER. */ switch (sjinfo->jointype) { case JOIN_INNER: if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || restriction_is_constant_false(restrictlist, joinrel, false)) { mark_dummy_rel(joinrel); break; } add_paths_to_joinrel(root, joinrel, rel1, rel2, JOIN_INNER, sjinfo, restrictlist); add_paths_to_joinrel(root, joinrel, rel2, rel1, JOIN_INNER, sjinfo, restrictlist); break; case JOIN_LEFT: if (is_dummy_rel(rel1) || restriction_is_constant_false(restrictlist, joinrel, true)) { mark_dummy_rel(joinrel); break; } if (restriction_is_constant_false(restrictlist, joinrel, false) && bms_is_subset(rel2->relids, sjinfo->syn_righthand)) mark_dummy_rel(rel2); add_paths_to_joinrel(root, joinrel, rel1, rel2, JOIN_LEFT, sjinfo, restrictlist); add_paths_to_joinrel(root, joinrel, rel2, rel1, JOIN_RIGHT, sjinfo, restrictlist); break; case JOIN_FULL: if ((is_dummy_rel(rel1) && is_dummy_rel(rel2)) || restriction_is_constant_false(restrictlist, joinrel, true)) { mark_dummy_rel(joinrel); break; } add_paths_to_joinrel(root, joinrel, rel1, rel2, JOIN_FULL, sjinfo, restrictlist); add_paths_to_joinrel(root, joinrel, rel2, rel1, JOIN_FULL, sjinfo, restrictlist); /* * If there are join quals that aren't mergeable or hashable, we * may not be able to build any valid plan. Complain here so that * we can give a somewhat-useful error message. (Since we have no * flexibility of planning for a full join, there's no chance of * succeeding later with another pair of input rels.) */ if (joinrel->pathlist == NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("FULL JOIN is only supported with merge-joinable or hash-joinable join conditions"))); break; case JOIN_SEMI: /* * We might have a normal semijoin, or a case where we don't have * enough rels to do the semijoin but can unique-ify the RHS and * then do an innerjoin (see comments in join_is_legal). In the * latter case we can't apply JOIN_SEMI joining. */ if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) && bms_is_subset(sjinfo->min_righthand, rel2->relids)) { if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || restriction_is_constant_false(restrictlist, joinrel, false)) { mark_dummy_rel(joinrel); break; } add_paths_to_joinrel(root, joinrel, rel1, rel2, JOIN_SEMI, sjinfo, restrictlist); } /* * If we know how to unique-ify the RHS and one input rel is * exactly the RHS (not a superset) we can consider unique-ifying * it and then doing a regular join. (The create_unique_path * check here is probably redundant with what join_is_legal did, * but if so the check is cheap because it's cached. So test * anyway to be sure.) */ if (bms_equal(sjinfo->syn_righthand, rel2->relids) && create_unique_path(root, rel2, rel2->cheapest_total_path, sjinfo) != NULL) { if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || restriction_is_constant_false(restrictlist, joinrel, false)) { mark_dummy_rel(joinrel); break; } add_paths_to_joinrel(root, joinrel, rel1, rel2, JOIN_UNIQUE_INNER, sjinfo, restrictlist); add_paths_to_joinrel(root, joinrel, rel2, rel1, JOIN_UNIQUE_OUTER, sjinfo, restrictlist); } break; case JOIN_ANTI: if (is_dummy_rel(rel1) || restriction_is_constant_false(restrictlist, joinrel, true)) { mark_dummy_rel(joinrel); break; } if (restriction_is_constant_false(restrictlist, joinrel, false) && bms_is_subset(rel2->relids, sjinfo->syn_righthand)) mark_dummy_rel(rel2); add_paths_to_joinrel(root, joinrel, rel1, rel2, JOIN_ANTI, sjinfo, restrictlist); add_paths_to_joinrel(root, joinrel, rel2, rel1, JOIN_RIGHT_ANTI, sjinfo, restrictlist); break; default: /* other values not expected here */ elog(ERROR, "unrecognized join type: %d", (int) sjinfo->jointype); break; } /* Apply partitionwise join technique, if possible. */ try_partitionwise_join(root, rel1, rel2, joinrel, sjinfo, restrictlist); } pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.0--1.3.1.sql000066400000000000000000000006641466301071500216160ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.0--1.3.1.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.1'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.0.sql000066400000000000000000000012541466301071500210770ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.0.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "CREATE EXTENSION pg_hint_plan" to load this file. \quit CREATE TABLE hint_plan.hints ( id serial NOT NULL, norm_query_string text NOT NULL, application_name text NOT NULL, hints text NOT NULL, PRIMARY KEY (id) ); CREATE UNIQUE INDEX hints_norm_and_app ON hint_plan.hints ( norm_query_string, application_name ); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.1--1.3.2.sql000066400000000000000000000006641466301071500216200ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.1--1.3.2.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.2'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.10--1.4.sql000066400000000000000000000006611466301071500215360ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.10--1.4.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.4'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.2--1.3.3.sql000066400000000000000000000006641466301071500216220ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.2--1.3.3.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.3'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.3--1.3.4.sql000066400000000000000000000006641466301071500216240ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.3--1.3.4.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.4'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.4--1.3.5.sql000066400000000000000000000006641466301071500216260ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.4--1.3.5.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.5'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.5--1.3.6.sql000066400000000000000000000006641466301071500216300ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.5--1.3.6.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.6'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.6--1.3.7.sql000066400000000000000000000006641466301071500216320ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.6--1.3.7.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.7'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.7--1.3.8.sql000066400000000000000000000006641466301071500216340ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.7--1.3.8.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.8'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.8--1.3.9.sql000066400000000000000000000006641466301071500216360ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.8--1.3.9.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.9'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.3.9--1.3.10.sql000066400000000000000000000006661466301071500217110ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.9--1.3.10.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.3.10'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.4--1.4.1.sql000066400000000000000000000006621466301071500214600ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.4--1.4.1.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.4.1'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.4.1--1.4.2.sql000066400000000000000000000006641466301071500216220ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.4.1--1.4.2.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.4.2'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.4.2--1.4.3.sql000066400000000000000000000006641466301071500216240ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.4.2--1.4.3.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.4.3'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.4.3--1.5.sql000066400000000000000000000006611466301071500214620ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.4.3--1.5.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.5'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.5--1.5.1.sql000066400000000000000000000006631466301071500214630ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.5--1.5.1.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.5.1'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.5.1--1.5.2.sql000066400000000000000000000006651466301071500216250ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.5.1--1.5.2.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.5.2'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.5.2--1.6.0.sql000066400000000000000000000006651466301071500216250ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.5.2--1.6.0.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.6.0'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints',''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq',''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.6.0--1.6.1.sql000066400000000000000000000006671466301071500216270ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.6.0--1.6.1.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.6.1'" to load this file. \quit SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints', ''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq', ''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan--1.6.1--1.7.0.sql000066400000000000000000000015221466301071500216170ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.6.1--1.7.0.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION pg_hint_plan UPDATE TO '1.7.0'" to load this file. \quit -- Hint table uses query IDs since 1.7.0, so drop the old one that depends -- on query strings and re-create it. DROP TABLE hint_plan.hints; CREATE TABLE hint_plan.hints ( id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, query_id bigint NOT NULL, application_name text NOT NULL, hints text NOT NULL ); CREATE UNIQUE INDEX hints_id_and_app ON hint_plan.hints (query_id, application_name); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints', ''); SELECT pg_catalog.pg_extension_config_dump('hint_plan.hints_id_seq', ''); GRANT SELECT ON hint_plan.hints TO PUBLIC; GRANT USAGE ON SCHEMA hint_plan TO PUBLIC; pg_hint_plan-REL17_1_7_0/pg_hint_plan.c000066400000000000000000003670351466301071500200240ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * pg_hint_plan.c * hinting on how to execute a query for PostgreSQL * * Copyright (c) 2012-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION * *------------------------------------------------------------------------- */ #include #include "postgres.h" #include "access/genam.h" #include "access/heapam.h" #include "access/relation.h" #include "catalog/namespace.h" #include "catalog/pg_collation.h" #include "catalog/pg_index.h" #include "catalog/pg_proc.h" #include "commands/prepare.h" #include "commands/proclang.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" #include "nodes/params.h" #include "optimizer/appendinfo.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/geqo.h" #include "optimizer/joininfo.h" #include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/plancat.h" #include "optimizer/planner.h" #include "optimizer/prep.h" #include "optimizer/restrictinfo.h" #include "parser/analyze.h" #include "parser/parsetree.h" #include "parser/scansup.h" #include "partitioning/partbounds.h" #include "tcop/utility.h" #include "utils/builtins.h" #include "utils/float.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" #include "utils/snapmgr.h" #include "utils/syscache.h" #include "catalog/pg_class.h" #include "executor/spi.h" #include "catalog/pg_type.h" #include "plpgsql.h" /* Owner scanner */ #include "query_scan.h" /* PostgreSQL */ #include "access/htup_details.h" #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif #define BLOCK_COMMENT_START "/*" #define BLOCK_COMMENT_END "*/" #define HINT_COMMENT_KEYWORD "+" #define HINT_START BLOCK_COMMENT_START HINT_COMMENT_KEYWORD #define HINT_END BLOCK_COMMENT_END /* hint keywords */ #define HINT_SEQSCAN "SeqScan" #define HINT_INDEXSCAN "IndexScan" #define HINT_INDEXSCANREGEXP "IndexScanRegexp" #define HINT_BITMAPSCAN "BitmapScan" #define HINT_BITMAPSCANREGEXP "BitmapScanRegexp" #define HINT_TIDSCAN "TidScan" #define HINT_NOSEQSCAN "NoSeqScan" #define HINT_NOINDEXSCAN "NoIndexScan" #define HINT_NOBITMAPSCAN "NoBitmapScan" #define HINT_NOTIDSCAN "NoTidScan" #define HINT_INDEXONLYSCAN "IndexOnlyScan" #define HINT_INDEXONLYSCANREGEXP "IndexOnlyScanRegexp" #define HINT_NOINDEXONLYSCAN "NoIndexOnlyScan" #define HINT_PARALLEL "Parallel" #define HINT_NESTLOOP "NestLoop" #define HINT_MERGEJOIN "MergeJoin" #define HINT_HASHJOIN "HashJoin" #define HINT_NONESTLOOP "NoNestLoop" #define HINT_NOMERGEJOIN "NoMergeJoin" #define HINT_NOHASHJOIN "NoHashJoin" #define HINT_LEADING "Leading" #define HINT_SET "Set" #define HINT_ROWS "Rows" #define HINT_MEMOIZE "Memoize" #define HINT_NOMEMOIZE "NoMemoize" #define HINT_ARRAY_DEFAULT_INITSIZE 8 #define hint_ereport(str, detail) hint_parse_ereport(str, detail) #define hint_parse_ereport(str, detail) \ do { \ ereport(pg_hint_plan_parse_message_level, \ (errmsg("pg_hint_plan: hint syntax error at or near \"%s\"", (str)), \ errdetail detail)); \ } while(0) #define skip_space(str) \ while (isspace(*str)) \ str++; enum { ENABLE_SEQSCAN = 0x01, ENABLE_INDEXSCAN = 0x02, ENABLE_BITMAPSCAN = 0x04, ENABLE_TIDSCAN = 0x08, ENABLE_INDEXONLYSCAN = 0x10 } SCAN_TYPE_BITS; enum { ENABLE_NESTLOOP = 0x01, ENABLE_MERGEJOIN = 0x02, ENABLE_HASHJOIN = 0x04, ENABLE_MEMOIZE = 0x08 } JOIN_TYPE_BITS; #define ENABLE_ALL_SCAN (ENABLE_SEQSCAN | ENABLE_INDEXSCAN | \ ENABLE_BITMAPSCAN | ENABLE_TIDSCAN | \ ENABLE_INDEXONLYSCAN) #define ENABLE_ALL_JOIN (ENABLE_NESTLOOP | ENABLE_MERGEJOIN | ENABLE_HASHJOIN) #define DISABLE_ALL_SCAN 0 #define DISABLE_ALL_JOIN 0 /* hint keyword of enum type*/ typedef enum HintKeyword { HINT_KEYWORD_SEQSCAN, HINT_KEYWORD_INDEXSCAN, HINT_KEYWORD_INDEXSCANREGEXP, HINT_KEYWORD_BITMAPSCAN, HINT_KEYWORD_BITMAPSCANREGEXP, HINT_KEYWORD_TIDSCAN, HINT_KEYWORD_NOSEQSCAN, HINT_KEYWORD_NOINDEXSCAN, HINT_KEYWORD_NOBITMAPSCAN, HINT_KEYWORD_NOTIDSCAN, HINT_KEYWORD_INDEXONLYSCAN, HINT_KEYWORD_INDEXONLYSCANREGEXP, HINT_KEYWORD_NOINDEXONLYSCAN, HINT_KEYWORD_NESTLOOP, HINT_KEYWORD_MERGEJOIN, HINT_KEYWORD_HASHJOIN, HINT_KEYWORD_NONESTLOOP, HINT_KEYWORD_NOMERGEJOIN, HINT_KEYWORD_NOHASHJOIN, HINT_KEYWORD_LEADING, HINT_KEYWORD_SET, HINT_KEYWORD_ROWS, HINT_KEYWORD_PARALLEL, HINT_KEYWORD_MEMOIZE, HINT_KEYWORD_NOMEMOIZE, HINT_KEYWORD_UNRECOGNIZED } HintKeyword; #define SCAN_HINT_ACCEPTS_INDEX_NAMES(kw) \ (kw == HINT_KEYWORD_INDEXSCAN || \ kw == HINT_KEYWORD_INDEXSCANREGEXP || \ kw == HINT_KEYWORD_INDEXONLYSCAN || \ kw == HINT_KEYWORD_INDEXONLYSCANREGEXP || \ kw == HINT_KEYWORD_BITMAPSCAN || \ kw == HINT_KEYWORD_BITMAPSCANREGEXP) typedef struct Hint Hint; typedef struct HintState HintState; typedef Hint *(*HintCreateFunction) (const char *hint_str, const char *keyword, HintKeyword hint_keyword); typedef void (*HintDeleteFunction) (Hint *hint); typedef void (*HintDescFunction) (Hint *hint, StringInfo buf, bool nolf); typedef int (*HintCmpFunction) (const Hint *a, const Hint *b); typedef const char *(*HintParseFunction) (Hint *hint, const char *str); /* hint types */ typedef enum HintType { HINT_TYPE_SCAN_METHOD, HINT_TYPE_JOIN_METHOD, HINT_TYPE_LEADING, HINT_TYPE_SET, HINT_TYPE_ROWS, HINT_TYPE_PARALLEL, HINT_TYPE_MEMOIZE, NUM_HINT_TYPE } HintType; typedef enum HintTypeBitmap { HINT_BM_SCAN_METHOD = 1, HINT_BM_PARALLEL = 2 } HintTypeBitmap; static const char *HintTypeName[] = { "scan method", "join method", "leading", "set", "rows", "parallel", "memoize" }; StaticAssertDecl(sizeof(HintTypeName) / sizeof(char *) == NUM_HINT_TYPE, "HintTypeName and HintType don't match"); /* hint status */ typedef enum HintStatus { HINT_STATE_NOTUSED = 0, /* specified relation not used in query */ HINT_STATE_USED, /* hint is used */ HINT_STATE_DUPLICATION, /* specified hint duplication */ HINT_STATE_ERROR /* execute error (parse error does not include * it) */ } HintStatus; #define hint_state_enabled(hint) ((hint)->base.state == HINT_STATE_NOTUSED || \ (hint)->base.state == HINT_STATE_USED) /* These variables are used only when debug_level > 1*/ static unsigned int qno = 0; static unsigned int msgqno = 0; static char qnostr[32]; static const char *current_hint_str = NULL; /* * We can utilize in-core generated jumble state in post_parse_analyze_hook. * On the other hand there's a case where we're forced to get hints in * planner_hook, where we don't have a jumble state. If we a query had not a * hint, we need to try to retrieve hints twice or more for one query, which is * the quite common case. To avoid such case, this variables is set true when * we *try* hint retrieval. */ static bool current_hint_retrieved = false; /* common data for all hints. */ struct Hint { const char *hint_str; /* must not do pfree */ const char *keyword; /* must not do pfree */ HintKeyword hint_keyword; HintType type; HintStatus state; HintDeleteFunction delete_func; HintDescFunction desc_func; HintCmpFunction cmp_func; HintParseFunction parse_func; }; /* scan method hints */ typedef struct ScanMethodHint { Hint base; char *relname; List *indexnames; bool regexp; unsigned char enforce_mask; } ScanMethodHint; typedef struct ParentIndexInfo { bool indisunique; Oid method; List *column_names; char *expression_str; Oid *indcollation; Oid *opclass; int16 *indoption; char *indpred_str; } ParentIndexInfo; /* join method hints */ typedef struct JoinMethodHint { Hint base; int nrels; int inner_nrels; char **relnames; unsigned char enforce_mask; Relids joinrelids; Relids inner_joinrelids; } JoinMethodHint; /* join order hints */ typedef struct OuterInnerRels { char *relation; List *outer_inner_pair; } OuterInnerRels; typedef struct LeadingHint { Hint base; List *relations; /* relation names specified in Leading hint */ OuterInnerRels *outer_inner; } LeadingHint; /* change a run-time parameter hints */ typedef struct SetHint { Hint base; char *name; /* name of variable */ char *value; List *words; } SetHint; /* rows hints */ typedef enum RowsValueType { RVT_ABSOLUTE, /* Rows(... #1000) */ RVT_ADD, /* Rows(... +1000) */ RVT_SUB, /* Rows(... -1000) */ RVT_MULTI, /* Rows(... *1.2) */ } RowsValueType; typedef struct RowsHint { Hint base; int nrels; int inner_nrels; char **relnames; Relids joinrelids; Relids inner_joinrelids; char *rows_str; RowsValueType value_type; double rows; } RowsHint; /* parallel hints */ typedef struct ParallelHint { Hint base; char *relname; char *nworkers_str; /* original string of nworkers */ int nworkers; /* num of workers specified by Worker */ bool force_parallel; /* force parallel scan */ } ParallelHint; /* * Describes a context of hint processing. */ struct HintState { char *hint_str; /* original hint string */ /* all hint */ int nall_hints; /* # of valid all hints */ int max_all_hints; /* # of slots for all hints */ Hint **all_hints; /* parsed all hints */ /* # of each hints */ int num_hints[NUM_HINT_TYPE]; /* for scan method hints */ ScanMethodHint **scan_hints; /* parsed scan hints */ /* Initial values of parameters */ int init_scan_mask; /* enable_* mask */ int init_nworkers; /* max_parallel_workers_per_gather */ /* min_parallel_table_scan_size*/ int init_min_para_tablescan_size; /* min_parallel_index_scan_size*/ int init_min_para_indexscan_size; double init_paratup_cost; /* parallel_tuple_cost */ double init_parasetup_cost;/* parallel_setup_cost */ PlannerInfo *current_root; /* PlannerInfo for the followings */ Index parent_relid; /* inherit parent of table relid */ ScanMethodHint *parent_scan_hint; /* scan hint for the parent */ ParallelHint *parent_parallel_hint; /* parallel hint for the parent */ List *parent_index_infos; /* list of parent table's index */ JoinMethodHint **join_hints; /* parsed join hints */ int init_join_mask; /* initial value join parameter */ List **join_hint_level; List **memoize_hint_level; LeadingHint **leading_hint; /* parsed Leading hints */ SetHint **set_hints; /* parsed Set hints */ GucContext context; /* which GUC parameters can we set? */ RowsHint **rows_hints; /* parsed Rows hints */ ParallelHint **parallel_hints; /* parsed Parallel hints */ JoinMethodHint **memoize_hints; /* parsed Memoize hints */ }; /* * Describes a hint parser module which is bound with particular hint keyword. */ typedef struct HintParser { char *keyword; HintCreateFunction create_func; HintKeyword hint_keyword; } HintParser; static bool enable_hint_table_check(bool *newval, void **extra, GucSource source); static void assign_enable_hint_table(bool newval, void *extra); /* Module callbacks */ void _PG_init(void); static void push_hint(HintState *hstate); static void pop_hint(void); static void pg_hint_plan_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate); static PlannedStmt *pg_hint_plan_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams); static RelOptInfo *pg_hint_plan_join_search(PlannerInfo *root, int levels_needed, List *initial_rels); /* Scan method hint callbacks */ static Hint *ScanMethodHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword); static void ScanMethodHintDelete(ScanMethodHint *hint); static void ScanMethodHintDesc(ScanMethodHint *hint, StringInfo buf, bool nolf); static int ScanMethodHintCmp(const ScanMethodHint *a, const ScanMethodHint *b); static const char *ScanMethodHintParse(ScanMethodHint *hint, const char *str); /* Join method hint callbacks */ static Hint *JoinMethodHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword); static void JoinMethodHintDelete(JoinMethodHint *hint); static void JoinMethodHintDesc(JoinMethodHint *hint, StringInfo buf, bool nolf); static int JoinMethodHintCmp(const JoinMethodHint *a, const JoinMethodHint *b); static const char *JoinMethodHintParse(JoinMethodHint *hint, const char *str); /* Leading hint callbacks */ static Hint *LeadingHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword); static void LeadingHintDelete(LeadingHint *hint); static void LeadingHintDesc(LeadingHint *hint, StringInfo buf, bool nolf); static int LeadingHintCmp(const LeadingHint *a, const LeadingHint *b); static const char *LeadingHintParse(LeadingHint *hint, const char *str); /* Set hint callbacks */ static Hint *SetHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword); static void SetHintDelete(SetHint *hint); static void SetHintDesc(SetHint *hint, StringInfo buf, bool nolf); static int SetHintCmp(const SetHint *a, const SetHint *b); static const char *SetHintParse(SetHint *hint, const char *str); /* Rows hint callbacks */ static Hint *RowsHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword); static void RowsHintDelete(RowsHint *hint); static void RowsHintDesc(RowsHint *hint, StringInfo buf, bool nolf); static int RowsHintCmp(const RowsHint *a, const RowsHint *b); static const char *RowsHintParse(RowsHint *hint, const char *str); /* Parallel hint callbacks */ static Hint *ParallelHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword); static void ParallelHintDelete(ParallelHint *hint); static void ParallelHintDesc(ParallelHint *hint, StringInfo buf, bool nolf); static int ParallelHintCmp(const ParallelHint *a, const ParallelHint *b); static const char *ParallelHintParse(ParallelHint *hint, const char *str); static Hint *MemoizeHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword); static void quote_value(StringInfo buf, const char *value); static const char *parse_quoted_value(const char *str, char **word, bool truncate); RelOptInfo *pg_hint_plan_standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels); void pg_hint_plan_join_search_one_level(PlannerInfo *root, int level); void pg_hint_plan_set_rel_pathlist(PlannerInfo * root, RelOptInfo *rel, Index rti, RangeTblEntry *rte); static void create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel); static void make_rels_by_clause_joins(PlannerInfo *root, RelOptInfo *old_rel, List *other_rels, int first_rel_idx); static void make_rels_by_clauseless_joins(PlannerInfo *root, RelOptInfo *old_rel, List *other_rels); static bool has_join_restriction(PlannerInfo *root, RelOptInfo *rel); static void set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte); static void free_child_join_sjinfo(SpecialJoinInfo *sjinfo); RelOptInfo *pg_hint_plan_make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2); static int set_config_option_noerror(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel); static void setup_scan_method_enforcement(ScanMethodHint *scanhint, HintState *state); static int set_config_int32_option(const char *name, int32 value, GucContext context); static int set_config_double_option(const char *name, double value, GucContext context); /* GUC variables */ static bool pg_hint_plan_enable_hint = true; static int debug_level = 0; static int pg_hint_plan_parse_message_level = INFO; static int pg_hint_plan_debug_message_level = LOG; /* Default is off, to keep backward compatibility. */ static bool pg_hint_plan_enable_hint_table = false; static int plpgsql_recurse_level = 0; /* PLpgSQL recursion level */ static int recurse_level = 0; /* recursion level incl. direct SPI calls */ static int hint_inhibit_level = 0; /* Inhibit hinting if this is above 0 */ /* (This could not be above 1) */ static int max_hint_nworkers = -1; /* Maximum nworkers of Workers hints */ static bool hint_table_deactivated = false; static const struct config_enum_entry parse_messages_level_options[] = { {"debug", DEBUG2, true}, {"debug5", DEBUG5, false}, {"debug4", DEBUG4, false}, {"debug3", DEBUG3, false}, {"debug2", DEBUG2, false}, {"debug1", DEBUG1, false}, {"log", LOG, false}, {"info", INFO, false}, {"notice", NOTICE, false}, {"warning", WARNING, false}, {"error", ERROR, false}, /* * {"fatal", FATAL, true}, * {"panic", PANIC, true}, */ {NULL, 0, false} }; static const struct config_enum_entry parse_debug_level_options[] = { {"off", 0, false}, {"on", 1, false}, {"detailed", 2, false}, {"verbose", 3, false}, {"0", 0, true}, {"1", 1, true}, {"2", 2, true}, {"3", 3, true}, {"no", 0, true}, {"yes", 1, true}, {"false", 0, true}, {"true", 1, true}, {NULL, 0, false} }; /* Saved hook values in case of unload */ static post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL; static planner_hook_type prev_planner = NULL; static join_search_hook_type prev_join_search = NULL; static set_rel_pathlist_hook_type prev_set_rel_pathlist = NULL; static needs_fmgr_hook_type prev_needs_fmgr_hook = NULL; static fmgr_hook_type prev_fmgr_hook = NULL; static ExecutorEnd_hook_type prev_ExecutorEnd = NULL; /* Hold reference to currently active hint */ static HintState *current_hint_state = NULL; /* * Reference to OID of PL/pgsql language, saved on first lookup at a * PL function. */ static Oid pg_hint_plan_pgpg_oid = InvalidOid; /* * List of hint contexts. We treat the head of the list as the Top of the * context stack, so current_hint_state always points the first element of this * list. */ static List *HintStateStack = NIL; static const HintParser parsers[] = { {HINT_SEQSCAN, ScanMethodHintCreate, HINT_KEYWORD_SEQSCAN}, {HINT_INDEXSCAN, ScanMethodHintCreate, HINT_KEYWORD_INDEXSCAN}, {HINT_INDEXSCANREGEXP, ScanMethodHintCreate, HINT_KEYWORD_INDEXSCANREGEXP}, {HINT_BITMAPSCAN, ScanMethodHintCreate, HINT_KEYWORD_BITMAPSCAN}, {HINT_BITMAPSCANREGEXP, ScanMethodHintCreate, HINT_KEYWORD_BITMAPSCANREGEXP}, {HINT_TIDSCAN, ScanMethodHintCreate, HINT_KEYWORD_TIDSCAN}, {HINT_NOSEQSCAN, ScanMethodHintCreate, HINT_KEYWORD_NOSEQSCAN}, {HINT_NOINDEXSCAN, ScanMethodHintCreate, HINT_KEYWORD_NOINDEXSCAN}, {HINT_NOBITMAPSCAN, ScanMethodHintCreate, HINT_KEYWORD_NOBITMAPSCAN}, {HINT_NOTIDSCAN, ScanMethodHintCreate, HINT_KEYWORD_NOTIDSCAN}, {HINT_INDEXONLYSCAN, ScanMethodHintCreate, HINT_KEYWORD_INDEXONLYSCAN}, {HINT_INDEXONLYSCANREGEXP, ScanMethodHintCreate, HINT_KEYWORD_INDEXONLYSCANREGEXP}, {HINT_NOINDEXONLYSCAN, ScanMethodHintCreate, HINT_KEYWORD_NOINDEXONLYSCAN}, {HINT_NESTLOOP, JoinMethodHintCreate, HINT_KEYWORD_NESTLOOP}, {HINT_MERGEJOIN, JoinMethodHintCreate, HINT_KEYWORD_MERGEJOIN}, {HINT_HASHJOIN, JoinMethodHintCreate, HINT_KEYWORD_HASHJOIN}, {HINT_NONESTLOOP, JoinMethodHintCreate, HINT_KEYWORD_NONESTLOOP}, {HINT_NOMERGEJOIN, JoinMethodHintCreate, HINT_KEYWORD_NOMERGEJOIN}, {HINT_NOHASHJOIN, JoinMethodHintCreate, HINT_KEYWORD_NOHASHJOIN}, {HINT_LEADING, LeadingHintCreate, HINT_KEYWORD_LEADING}, {HINT_SET, SetHintCreate, HINT_KEYWORD_SET}, {HINT_ROWS, RowsHintCreate, HINT_KEYWORD_ROWS}, {HINT_PARALLEL, ParallelHintCreate, HINT_KEYWORD_PARALLEL}, {HINT_MEMOIZE, MemoizeHintCreate, HINT_KEYWORD_MEMOIZE}, {HINT_NOMEMOIZE, MemoizeHintCreate, HINT_KEYWORD_NOMEMOIZE}, {NULL, NULL, HINT_KEYWORD_UNRECOGNIZED} }; static bool pg_hint_plan_is_plpgsql_function(Oid funcoid) { HeapTuple procTuple; Form_pg_proc procStruct; bool result; procTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid)); if (!HeapTupleIsValid(procTuple)) return false; procStruct = (Form_pg_proc) GETSTRUCT(procTuple); if (!OidIsValid(pg_hint_plan_pgpg_oid)) pg_hint_plan_pgpg_oid = get_language_oid("plpgsql", false); result = (procStruct->prolang == pg_hint_plan_pgpg_oid); ReleaseSysCache(procTuple); return result; } /* * Used as needs_fmgr_hook. All plpgsql functions needs this hook to properly * track the nested depth of plpgsql calls. */ static bool pg_hint_plan_needs_fmgr_hook(Oid funcoid) { if (prev_needs_fmgr_hook && (*prev_needs_fmgr_hook)(funcoid)) return true; return pg_hint_plan_is_plpgsql_function(funcoid); } static void pg_hint_plan_fmgr_hook(FmgrHookEventType event, FmgrInfo *flinfo, Datum *private) { if (prev_fmgr_hook) (*prev_fmgr_hook) (event, flinfo, private); switch (event) { case FHET_START: plpgsql_recurse_level++; Assert(plpgsql_recurse_level > 0); break; case FHET_END: case FHET_ABORT: /* may be an exception */ plpgsql_recurse_level--; Assert(plpgsql_recurse_level >= 0); break; default: break; } return; } /* * pg_hint_ExecutorEnd * * Force a hint to be retrieved when we are at the top of a PL recursion * level. This can become necessary to handle hints in queries executed * in the extended protocol, where the executor can be executed multiple * times in a portal, but it could be possible to fail the hint retrieval. */ static void pg_hint_ExecutorEnd(QueryDesc *queryDesc) { if (plpgsql_recurse_level == 0) current_hint_retrieved = false; if (prev_ExecutorEnd) prev_ExecutorEnd(queryDesc); else standard_ExecutorEnd(queryDesc); } /* * Module load callbacks */ void _PG_init(void) { /* Define custom GUC variables. */ DefineCustomBoolVariable("pg_hint_plan.enable_hint", "Force planner to use plans specified in the hint comment preceding to the query.", NULL, &pg_hint_plan_enable_hint, true, PGC_USERSET, 0, NULL, NULL, NULL); DefineCustomEnumVariable("pg_hint_plan.debug_print", "Logs results of hint parsing.", NULL, &debug_level, false, parse_debug_level_options, PGC_USERSET, 0, NULL, NULL, NULL); DefineCustomEnumVariable("pg_hint_plan.parse_messages", "Message level of parse errors.", NULL, &pg_hint_plan_parse_message_level, INFO, parse_messages_level_options, PGC_USERSET, 0, NULL, NULL, NULL); DefineCustomEnumVariable("pg_hint_plan.message_level", "Message level of debug messages.", NULL, &pg_hint_plan_debug_message_level, LOG, parse_messages_level_options, PGC_USERSET, 0, NULL, NULL, NULL); DefineCustomBoolVariable("pg_hint_plan.enable_hint_table", "Let pg_hint_plan look up the hint table.", NULL, &pg_hint_plan_enable_hint_table, false, PGC_USERSET, 0, enable_hint_table_check, assign_enable_hint_table, NULL); EmitWarningsOnPlaceholders("pg_hint_plan"); /* Install hooks. */ prev_post_parse_analyze_hook = post_parse_analyze_hook; post_parse_analyze_hook = pg_hint_plan_post_parse_analyze; prev_planner = planner_hook; planner_hook = pg_hint_plan_planner; prev_join_search = join_search_hook; join_search_hook = pg_hint_plan_join_search; prev_set_rel_pathlist = set_rel_pathlist_hook; set_rel_pathlist_hook = pg_hint_plan_set_rel_pathlist; prev_fmgr_hook = fmgr_hook; fmgr_hook = pg_hint_plan_fmgr_hook; prev_needs_fmgr_hook = needs_fmgr_hook; needs_fmgr_hook = pg_hint_plan_needs_fmgr_hook; prev_ExecutorEnd = ExecutorEnd_hook; ExecutorEnd_hook = pg_hint_ExecutorEnd; } static bool enable_hint_table_check(bool *newval, void **extra, GucSource source) { if (*newval) { EnableQueryId(); if (!IsQueryIdEnabled()) { GUC_check_errmsg("table hint is not activated because queryid is not available"); GUC_check_errhint("Set compute_query_id to on or auto to use hint table."); return false; } } return true; } static void assign_enable_hint_table(bool newval, void *extra) { if (!newval) hint_table_deactivated = false; } /* * create and delete functions the hint object */ static Hint * ScanMethodHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword) { ScanMethodHint *hint; hint = palloc0(sizeof(ScanMethodHint)); hint->base.hint_str = hint_str; hint->base.keyword = keyword; hint->base.hint_keyword = hint_keyword; hint->base.type = HINT_TYPE_SCAN_METHOD; hint->base.state = HINT_STATE_NOTUSED; hint->base.delete_func = (HintDeleteFunction) ScanMethodHintDelete; hint->base.desc_func = (HintDescFunction) ScanMethodHintDesc; hint->base.cmp_func = (HintCmpFunction) ScanMethodHintCmp; hint->base.parse_func = (HintParseFunction) ScanMethodHintParse; hint->relname = NULL; hint->indexnames = NIL; hint->regexp = false; hint->enforce_mask = 0; return (Hint *) hint; } static void ScanMethodHintDelete(ScanMethodHint *hint) { if (!hint) return; if (hint->relname) pfree(hint->relname); list_free_deep(hint->indexnames); pfree(hint); } static Hint * JoinMethodHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword) { JoinMethodHint *hint; hint = palloc0(sizeof(JoinMethodHint)); hint->base.hint_str = hint_str; hint->base.keyword = keyword; hint->base.hint_keyword = hint_keyword; hint->base.type = HINT_TYPE_JOIN_METHOD; hint->base.state = HINT_STATE_NOTUSED; hint->base.delete_func = (HintDeleteFunction) JoinMethodHintDelete; hint->base.desc_func = (HintDescFunction) JoinMethodHintDesc; hint->base.cmp_func = (HintCmpFunction) JoinMethodHintCmp; hint->base.parse_func = (HintParseFunction) JoinMethodHintParse; hint->nrels = 0; hint->inner_nrels = 0; hint->relnames = NULL; hint->enforce_mask = 0; hint->joinrelids = NULL; hint->inner_joinrelids = NULL; return (Hint *) hint; } static void JoinMethodHintDelete(JoinMethodHint *hint) { if (!hint) return; if (hint->relnames) { int i; for (i = 0; i < hint->nrels; i++) pfree(hint->relnames[i]); pfree(hint->relnames); } bms_free(hint->joinrelids); bms_free(hint->inner_joinrelids); pfree(hint); } static Hint * LeadingHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword) { LeadingHint *hint; hint = palloc0(sizeof(LeadingHint)); hint->base.hint_str = hint_str; hint->base.keyword = keyword; hint->base.hint_keyword = hint_keyword; hint->base.type = HINT_TYPE_LEADING; hint->base.state = HINT_STATE_NOTUSED; hint->base.delete_func = (HintDeleteFunction)LeadingHintDelete; hint->base.desc_func = (HintDescFunction) LeadingHintDesc; hint->base.cmp_func = (HintCmpFunction) LeadingHintCmp; hint->base.parse_func = (HintParseFunction) LeadingHintParse; hint->relations = NIL; hint->outer_inner = NULL; return (Hint *) hint; } static void LeadingHintDelete(LeadingHint *hint) { if (!hint) return; list_free_deep(hint->relations); if (hint->outer_inner) pfree(hint->outer_inner); pfree(hint); } static Hint * SetHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword) { SetHint *hint; hint = palloc0(sizeof(SetHint)); hint->base.hint_str = hint_str; hint->base.keyword = keyword; hint->base.hint_keyword = hint_keyword; hint->base.type = HINT_TYPE_SET; hint->base.state = HINT_STATE_NOTUSED; hint->base.delete_func = (HintDeleteFunction) SetHintDelete; hint->base.desc_func = (HintDescFunction) SetHintDesc; hint->base.cmp_func = (HintCmpFunction) SetHintCmp; hint->base.parse_func = (HintParseFunction) SetHintParse; hint->name = NULL; hint->value = NULL; hint->words = NIL; return (Hint *) hint; } static void SetHintDelete(SetHint *hint) { if (!hint) return; if (hint->name) pfree(hint->name); if (hint->value) pfree(hint->value); if (hint->words) list_free(hint->words); pfree(hint); } static Hint * RowsHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword) { RowsHint *hint; hint = palloc0(sizeof(RowsHint)); hint->base.hint_str = hint_str; hint->base.keyword = keyword; hint->base.hint_keyword = hint_keyword; hint->base.type = HINT_TYPE_ROWS; hint->base.state = HINT_STATE_NOTUSED; hint->base.delete_func = (HintDeleteFunction) RowsHintDelete; hint->base.desc_func = (HintDescFunction) RowsHintDesc; hint->base.cmp_func = (HintCmpFunction) RowsHintCmp; hint->base.parse_func = (HintParseFunction) RowsHintParse; hint->nrels = 0; hint->inner_nrels = 0; hint->relnames = NULL; hint->joinrelids = NULL; hint->inner_joinrelids = NULL; hint->rows_str = NULL; hint->value_type = RVT_ABSOLUTE; hint->rows = 0; return (Hint *) hint; } static void RowsHintDelete(RowsHint *hint) { if (!hint) return; if (hint->relnames) { int i; for (i = 0; i < hint->nrels; i++) pfree(hint->relnames[i]); pfree(hint->relnames); } bms_free(hint->joinrelids); bms_free(hint->inner_joinrelids); pfree(hint); } static Hint * ParallelHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword) { ParallelHint *hint; hint = palloc0(sizeof(ParallelHint)); hint->base.hint_str = hint_str; hint->base.keyword = keyword; hint->base.hint_keyword = hint_keyword; hint->base.type = HINT_TYPE_PARALLEL; hint->base.state = HINT_STATE_NOTUSED; hint->base.delete_func = (HintDeleteFunction) ParallelHintDelete; hint->base.desc_func = (HintDescFunction) ParallelHintDesc; hint->base.cmp_func = (HintCmpFunction) ParallelHintCmp; hint->base.parse_func = (HintParseFunction) ParallelHintParse; hint->relname = NULL; hint->nworkers = 0; hint->nworkers_str = "0"; return (Hint *) hint; } static void ParallelHintDelete(ParallelHint *hint) { if (!hint) return; if (hint->relname) pfree(hint->relname); pfree(hint); } static Hint * MemoizeHintCreate(const char *hint_str, const char *keyword, HintKeyword hint_keyword) { /* * MemoizeHintCreate shares the same struct with JoinMethodHint and the * only difference is the hint type. */ JoinMethodHint *hint = (JoinMethodHint *)JoinMethodHintCreate(hint_str, keyword, hint_keyword); hint->base.type = HINT_TYPE_MEMOIZE; return (Hint *) hint; } static HintState * HintStateCreate(void) { HintState *hstate; hstate = palloc0(sizeof(HintState)); hstate->hint_str = NULL; hstate->nall_hints = 0; hstate->max_all_hints = 0; hstate->all_hints = NULL; memset(hstate->num_hints, 0, sizeof(hstate->num_hints)); hstate->scan_hints = NULL; hstate->init_scan_mask = 0; hstate->init_nworkers = 0; hstate->init_min_para_tablescan_size = 0; hstate->init_min_para_indexscan_size = 0; hstate->init_paratup_cost = 0; hstate->init_parasetup_cost = 0; hstate->current_root = NULL; hstate->parent_relid = 0; hstate->parent_scan_hint = NULL; hstate->parent_parallel_hint = NULL; hstate->parent_index_infos = NIL; hstate->join_hints = NULL; hstate->init_join_mask = 0; hstate->join_hint_level = NULL; hstate->memoize_hint_level = NULL; hstate->leading_hint = NULL; hstate->context = superuser() ? PGC_SUSET : PGC_USERSET; hstate->set_hints = NULL; hstate->rows_hints = NULL; hstate->parallel_hints = NULL; return hstate; } static void HintStateDelete(HintState *hstate) { int i; if (!hstate) return; if (hstate->hint_str) pfree(hstate->hint_str); for (i = 0; i < hstate->nall_hints ; i++) hstate->all_hints[i]->delete_func(hstate->all_hints[i]); if (hstate->all_hints) pfree(hstate->all_hints); if (hstate->parent_index_infos) list_free(hstate->parent_index_infos); /* * We have another few or dozen of palloced block in the struct, but don't * bother completely clean up all of them since they will be cleaned-up at * the end of this query. */ } /* * Copy given value into buf, with quoting with '"' if necessary. */ static void quote_value(StringInfo buf, const char *value) { bool need_quote = false; const char *str; for (str = value; *str != '\0'; str++) { if (isspace(*str) || *str == '(' || *str == ')' || *str == '"') { need_quote = true; appendStringInfoCharMacro(buf, '"'); break; } } for (str = value; *str != '\0'; str++) { if (*str == '"') appendStringInfoCharMacro(buf, '"'); appendStringInfoCharMacro(buf, *str); } if (need_quote) appendStringInfoCharMacro(buf, '"'); } static void ScanMethodHintDesc(ScanMethodHint *hint, StringInfo buf, bool nolf) { ListCell *l; appendStringInfo(buf, "%s(", hint->base.keyword); if (hint->relname != NULL) { quote_value(buf, hint->relname); foreach(l, hint->indexnames) { appendStringInfoCharMacro(buf, ' '); quote_value(buf, (char *) lfirst(l)); } } appendStringInfoString(buf, ")"); if (!nolf) appendStringInfoChar(buf, '\n'); } static void JoinMethodHintDesc(JoinMethodHint *hint, StringInfo buf, bool nolf) { int i; appendStringInfo(buf, "%s(", hint->base.keyword); if (hint->relnames != NULL) { quote_value(buf, hint->relnames[0]); for (i = 1; i < hint->nrels; i++) { appendStringInfoCharMacro(buf, ' '); quote_value(buf, hint->relnames[i]); } } appendStringInfoString(buf, ")"); if (!nolf) appendStringInfoChar(buf, '\n'); } static void OuterInnerDesc(OuterInnerRels *outer_inner, StringInfo buf) { if (outer_inner->relation == NULL) { bool is_first; ListCell *l; is_first = true; appendStringInfoCharMacro(buf, '('); foreach(l, outer_inner->outer_inner_pair) { if (is_first) is_first = false; else appendStringInfoCharMacro(buf, ' '); OuterInnerDesc(lfirst(l), buf); } appendStringInfoCharMacro(buf, ')'); } else quote_value(buf, outer_inner->relation); } static void LeadingHintDesc(LeadingHint *hint, StringInfo buf, bool nolf) { appendStringInfo(buf, "%s(", HINT_LEADING); if (hint->outer_inner == NULL) { ListCell *l; bool is_first; is_first = true; foreach(l, hint->relations) { if (is_first) is_first = false; else appendStringInfoCharMacro(buf, ' '); quote_value(buf, (char *) lfirst(l)); } } else OuterInnerDesc(hint->outer_inner, buf); appendStringInfoString(buf, ")"); if (!nolf) appendStringInfoChar(buf, '\n'); } static void SetHintDesc(SetHint *hint, StringInfo buf, bool nolf) { bool is_first = true; ListCell *l; appendStringInfo(buf, "%s(", HINT_SET); foreach(l, hint->words) { if (is_first) is_first = false; else appendStringInfoCharMacro(buf, ' '); quote_value(buf, (char *) lfirst(l)); } appendStringInfo(buf, ")"); if (!nolf) appendStringInfoChar(buf, '\n'); } static void RowsHintDesc(RowsHint *hint, StringInfo buf, bool nolf) { int i; appendStringInfo(buf, "%s(", hint->base.keyword); if (hint->relnames != NULL) { quote_value(buf, hint->relnames[0]); for (i = 1; i < hint->nrels; i++) { appendStringInfoCharMacro(buf, ' '); quote_value(buf, hint->relnames[i]); } } if (hint->rows_str != NULL) appendStringInfo(buf, " %s", hint->rows_str); appendStringInfoString(buf, ")"); if (!nolf) appendStringInfoChar(buf, '\n'); } static void ParallelHintDesc(ParallelHint *hint, StringInfo buf, bool nolf) { appendStringInfo(buf, "%s(", hint->base.keyword); if (hint->relname != NULL) { quote_value(buf, hint->relname); /* number of workers */ appendStringInfoCharMacro(buf, ' '); quote_value(buf, hint->nworkers_str); /* application mode of num of workers */ appendStringInfoCharMacro(buf, ' '); appendStringInfoString(buf, (hint->force_parallel ? "hard" : "soft")); } appendStringInfoString(buf, ")"); if (!nolf) appendStringInfoChar(buf, '\n'); } /* * Append string which represents all hints in a given state to buf, with * preceding title with them. */ static void desc_hint_in_state(HintState *hstate, StringInfo buf, const char *title, HintStatus state, bool nolf) { int i, nshown; appendStringInfo(buf, "%s:", title); if (!nolf) appendStringInfoChar(buf, '\n'); nshown = 0; for (i = 0; i < hstate->nall_hints; i++) { if (hstate->all_hints[i]->state != state) continue; hstate->all_hints[i]->desc_func(hstate->all_hints[i], buf, nolf); nshown++; } if (nolf && nshown == 0) appendStringInfoString(buf, "(none)"); } /* * Dump contents of given hstate to server log with log level LOG. */ static void HintStateDump(HintState *hstate) { StringInfoData buf; if (!hstate) { elog(pg_hint_plan_debug_message_level, "pg_hint_plan:\nno hint"); return; } initStringInfo(&buf); appendStringInfoString(&buf, "pg_hint_plan:\n"); desc_hint_in_state(hstate, &buf, "used hint", HINT_STATE_USED, false); desc_hint_in_state(hstate, &buf, "not used hint", HINT_STATE_NOTUSED, false); desc_hint_in_state(hstate, &buf, "duplication hint", HINT_STATE_DUPLICATION, false); desc_hint_in_state(hstate, &buf, "error hint", HINT_STATE_ERROR, false); ereport(pg_hint_plan_debug_message_level, (errmsg ("%s", buf.data))); pfree(buf.data); } static void HintStateDump2(HintState *hstate) { StringInfoData buf; if (!hstate) { elog(pg_hint_plan_debug_message_level, "pg_hint_plan%s: HintStateDump: no hint", qnostr); return; } initStringInfo(&buf); appendStringInfo(&buf, "pg_hint_plan%s: HintStateDump: ", qnostr); desc_hint_in_state(hstate, &buf, "{used hints", HINT_STATE_USED, true); desc_hint_in_state(hstate, &buf, "}, {not used hints", HINT_STATE_NOTUSED, true); desc_hint_in_state(hstate, &buf, "}, {duplicate hints", HINT_STATE_DUPLICATION, true); desc_hint_in_state(hstate, &buf, "}, {error hints", HINT_STATE_ERROR, true); appendStringInfoChar(&buf, '}'); ereport(pg_hint_plan_debug_message_level, (errmsg("%s", buf.data), errhidestmt(true), errhidecontext(true))); pfree(buf.data); } /* * compare functions */ static int RelnameCmp(const void *a, const void *b) { const char *relnamea = *((const char **) a); const char *relnameb = *((const char **) b); return strcmp(relnamea, relnameb); } static int ScanMethodHintCmp(const ScanMethodHint *a, const ScanMethodHint *b) { return RelnameCmp(&a->relname, &b->relname); } static int JoinMethodHintCmp(const JoinMethodHint *a, const JoinMethodHint *b) { int i; if (a->nrels != b->nrels) return a->nrels - b->nrels; for (i = 0; i < a->nrels; i++) { int result; if ((result = RelnameCmp(&a->relnames[i], &b->relnames[i])) != 0) return result; } return 0; } static int LeadingHintCmp(const LeadingHint *a, const LeadingHint *b) { return 0; } static int SetHintCmp(const SetHint *a, const SetHint *b) { return strcmp(a->name, b->name); } static int RowsHintCmp(const RowsHint *a, const RowsHint *b) { int i; if (a->nrels != b->nrels) return a->nrels - b->nrels; for (i = 0; i < a->nrels; i++) { int result; if ((result = RelnameCmp(&a->relnames[i], &b->relnames[i])) != 0) return result; } return 0; } static int ParallelHintCmp(const ParallelHint *a, const ParallelHint *b) { return RelnameCmp(&a->relname, &b->relname); } static int HintCmp(const void *a, const void *b) { const Hint *hinta = *((const Hint **) a); const Hint *hintb = *((const Hint **) b); if (hinta->type != hintb->type) return hinta->type - hintb->type; if (hinta->state == HINT_STATE_ERROR) return -1; if (hintb->state == HINT_STATE_ERROR) return 1; return hinta->cmp_func(hinta, hintb); } /* * Returns byte offset of hint b from hint a. If hint a was specified before * b, positive value is returned. */ static int HintCmpWithPos(const void *a, const void *b) { const Hint *hinta = *((const Hint **) a); const Hint *hintb = *((const Hint **) b); int result; result = HintCmp(a, b); if (result == 0) result = hinta->hint_str - hintb->hint_str; return result; } /* * parse functions */ static const char * parse_keyword(const char *str, StringInfo buf) { skip_space(str); while (!isspace(*str) && *str != '(' && *str != '\0') appendStringInfoCharMacro(buf, *str++); return str; } static const char * skip_parenthesis(const char *str, char parenthesis) { skip_space(str); if (*str != parenthesis) { if (parenthesis == '(') hint_ereport(str, ("Opening parenthesis is necessary.")); else if (parenthesis == ')') hint_ereport(str, ("Closing parenthesis is necessary.")); return NULL; } str++; return str; } /* * Parse a token from str, and store malloc'd copy into word. A token can be * quoted with '"'. Return value is pointer to unparsed portion of original * string, or NULL if an error occurred. * * Parsed token is truncated within NAMEDATALEN-1 bytes, when truncate is true. */ static const char * parse_quoted_value(const char *str, char **word, bool truncate) { StringInfoData buf; bool in_quote; /* Skip leading spaces. */ skip_space(str); initStringInfo(&buf); if (*str == '"') { str++; in_quote = true; } else in_quote = false; while (true) { if (in_quote) { /* Double quotation must be closed. */ if (*str == '\0') { pfree(buf.data); hint_ereport(str, ("Unterminated quoted string.")); return NULL; } /* * Skip escaped double quotation. * * We don't allow slash-asterisk and asterisk-slash (delimiters of * block comments) to be an object name, so users must specify * alias for such object names. * * Those special names can be allowed if we care escaped slashes * and asterisks, but we don't. */ if (*str == '"') { str++; if (*str != '"') break; } } else if (isspace(*str) || *str == '(' || *str == ')' || *str == '"' || *str == '\0') break; appendStringInfoCharMacro(&buf, *str++); } if (buf.len == 0) { hint_ereport(str, ("Zero-length delimited string.")); pfree(buf.data); return NULL; } /* Truncate name if it's too long */ if (truncate) truncate_identifier(buf.data, strlen(buf.data), true); *word = buf.data; return str; } static OuterInnerRels * OuterInnerRelsCreate(char *name, List *outer_inner_list) { OuterInnerRels *outer_inner; outer_inner = palloc0(sizeof(OuterInnerRels)); outer_inner->relation = name; outer_inner->outer_inner_pair = outer_inner_list; return outer_inner; } static const char * parse_parentheses_Leading_in(const char *str, OuterInnerRels **outer_inner) { List *outer_inner_pair = NIL; if ((str = skip_parenthesis(str, '(')) == NULL) return NULL; skip_space(str); /* Store words in parentheses into outer_inner_list. */ while(*str != ')' && *str != '\0') { OuterInnerRels *outer_inner_rels; if (*str == '(') { str = parse_parentheses_Leading_in(str, &outer_inner_rels); if (str == NULL) break; } else { char *name; if ((str = parse_quoted_value(str, &name, true)) == NULL) break; else outer_inner_rels = OuterInnerRelsCreate(name, NIL); } outer_inner_pair = lappend(outer_inner_pair, outer_inner_rels); skip_space(str); } if (str == NULL || (str = skip_parenthesis(str, ')')) == NULL) { list_free(outer_inner_pair); return NULL; } *outer_inner = OuterInnerRelsCreate(NULL, outer_inner_pair); return str; } static const char * parse_parentheses_Leading(const char *str, List **name_list, OuterInnerRels **outer_inner) { char *name; bool truncate = true; if ((str = skip_parenthesis(str, '(')) == NULL) return NULL; skip_space(str); if (*str =='(') { if ((str = parse_parentheses_Leading_in(str, outer_inner)) == NULL) return NULL; } else { /* Store words in parentheses into name_list. */ while(*str != ')' && *str != '\0') { if ((str = parse_quoted_value(str, &name, truncate)) == NULL) { list_free(*name_list); return NULL; } *name_list = lappend(*name_list, name); skip_space(str); } } if ((str = skip_parenthesis(str, ')')) == NULL) return NULL; return str; } static const char * parse_parentheses(const char *str, List **name_list, HintKeyword keyword) { char *name; bool truncate = true; if ((str = skip_parenthesis(str, '(')) == NULL) return NULL; skip_space(str); /* Store words in parentheses into name_list. */ while(*str != ')' && *str != '\0') { if ((str = parse_quoted_value(str, &name, truncate)) == NULL) { list_free(*name_list); return NULL; } *name_list = lappend(*name_list, name); skip_space(str); if (keyword == HINT_KEYWORD_INDEXSCANREGEXP || keyword == HINT_KEYWORD_INDEXONLYSCANREGEXP || keyword == HINT_KEYWORD_BITMAPSCANREGEXP || keyword == HINT_KEYWORD_SET) { truncate = false; } } if ((str = skip_parenthesis(str, ')')) == NULL) return NULL; return str; } static void parse_hints(HintState *hstate, Query *parse, const char *str) { StringInfoData buf; char *head; initStringInfo(&buf); while (*str != '\0') { const HintParser *parser; /* in error message, we output the comment including the keyword. */ head = (char *) str; /* parse only the keyword of the hint. */ resetStringInfo(&buf); str = parse_keyword(str, &buf); for (parser = parsers; parser->keyword != NULL; parser++) { char *keyword = parser->keyword; Hint *hint; if (pg_strcasecmp(buf.data, keyword) != 0) continue; hint = parser->create_func(head, keyword, parser->hint_keyword); /* parser of each hint does parse in a parenthesis. */ if ((str = hint->parse_func(hint, str)) == NULL) { hint->delete_func(hint); pfree(buf.data); return; } /* * Add hint information into all_hints array. If we don't have * enough space, double the array. */ if (hstate->nall_hints == 0) { hstate->max_all_hints = HINT_ARRAY_DEFAULT_INITSIZE; hstate->all_hints = (Hint **) palloc0(sizeof(Hint *) * hstate->max_all_hints); } else if (hstate->nall_hints == hstate->max_all_hints) { hstate->max_all_hints *= 2; hstate->all_hints = (Hint **) repalloc(hstate->all_hints, sizeof(Hint *) * hstate->max_all_hints); } hstate->all_hints[hstate->nall_hints] = hint; hstate->nall_hints++; skip_space(str); break; } if (parser->keyword == NULL) { hint_ereport(head, ("Unrecognized hint keyword \"%s\".", buf.data)); pfree(buf.data); return; } } pfree(buf.data); } /* * Get hints from table by client-supplied query ID and application name. */ static const char * get_hints_from_table(uint64 queryId, const char *client_application) { const char *search_query = "SELECT hints " " FROM hint_plan.hints " " WHERE query_id = $1 " " AND ( application_name = $2 " " OR application_name = '' ) " " ORDER BY application_name DESC"; static SPIPlanPtr plan = NULL; char *hints = NULL; Oid argtypes[2] = { INT8OID, TEXTOID }; Datum values[2]; char nulls[2] = {' ', ' '}; text *app; Oid namespaceId; bool hints_table_found = false; /* * Make sure that hint_plan.hints is found before we attempt to look for * a hint. */ namespaceId = LookupExplicitNamespace("hint_plan", true); if (OidIsValid(namespaceId) && OidIsValid(get_relname_relid("hints", namespaceId))) hints_table_found = true; if (!hints_table_found) { ereport(WARNING, (errmsg ("cannot use the hint table"), errhint("Run \"CREATE EXTENSION pg_hint_plan\" to create the hint table."))); return NULL; } PG_TRY(); { bool snapshot_set = false; hint_inhibit_level++; if (!ActiveSnapshotSet()) { PushActiveSnapshot(GetTransactionSnapshot()); snapshot_set = true; } SPI_connect(); if (plan == NULL) { SPIPlanPtr p; p = SPI_prepare(search_query, 2, argtypes); plan = SPI_saveplan(p); SPI_freeplan(p); } app = cstring_to_text(client_application); values[0] = Int64GetDatum(queryId); values[1] = PointerGetDatum(app); SPI_execute_plan(plan, values, nulls, true, 1); if (SPI_processed > 0) { char *buf; hints = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1); /* * Here we use SPI_palloc to ensure that hints string is valid even * after SPI_finish call. We can't use simple palloc because it * allocates memory in SPI's context and that context is deleted in * SPI_finish. */ buf = SPI_palloc(strlen(hints) + 1); strcpy(buf, hints); hints = buf; } SPI_finish(); if (snapshot_set) PopActiveSnapshot(); hint_inhibit_level--; } PG_CATCH(); { hint_inhibit_level--; PG_RE_THROW(); } PG_END_TRY(); return hints; } /* * Get hints from the head block comment in client-supplied query string. * * The extracted hint is palloc()'d in TopMemoryContext. */ static const char * get_hints_from_comment(const char *p) { QueryScanState sstate; StringInfo query_buf; char *result = NULL; if (p == NULL) return NULL; sstate = query_scan_create(); query_buf = makeStringInfo(); query_scan_setup(sstate, p, strlen(p), 0, standard_conforming_strings, pg_hint_plan_parse_message_level); for (;;) { QueryScanResult sr = query_scan(sstate, query_buf); if (sr == QUERY_SCAN_EOL) break; } query_scan_finish(sstate); /* Get a copy of the hint extracted, if any */ if (query_buf->len > 0) result = MemoryContextStrdup(TopMemoryContext, query_buf->data); pfree(query_buf->data); pfree(query_buf); return result; } /* * Parse hints that got, create hint struct from parse tree and parse hints. */ static HintState * create_hintstate(Query *parse, const char *hints) { const char *p; int i; HintState *hstate; if (hints == NULL) return NULL; /* -1 means that no Parallel hint is specified. */ max_hint_nworkers = -1; p = hints; hstate = HintStateCreate(); hstate->hint_str = (char *) hints; /* parse each hint. */ parse_hints(hstate, parse, p); /* When nothing specified a hint, we free HintState and returns NULL. */ if (hstate->nall_hints == 0) { HintStateDelete(hstate); return NULL; } /* Sort hints in order of original position. */ qsort(hstate->all_hints, hstate->nall_hints, sizeof(Hint *), HintCmpWithPos); /* Count number of hints per hint-type. */ for (i = 0; i < hstate->nall_hints; i++) { Hint *cur_hint = hstate->all_hints[i]; hstate->num_hints[cur_hint->type]++; } /* * If an object (or a set of objects) has multiple hints of same hint-type, * only the last hint is valid and others are ignored in planning. * Hints except the last are marked as 'duplicated' to remember the order. */ for (i = 0; i < hstate->nall_hints - 1; i++) { Hint *cur_hint = hstate->all_hints[i]; Hint *next_hint = hstate->all_hints[i + 1]; /* * Leading hint is marked as 'duplicated' in transform_join_hints. */ if (cur_hint->type == HINT_TYPE_LEADING && next_hint->type == HINT_TYPE_LEADING) continue; /* * Note that we need to pass addresses of hint pointers, because * HintCmp is designed to sort array of Hint* by qsort. */ if (HintCmp(&cur_hint, &next_hint) == 0) { hint_ereport(cur_hint->hint_str, ("Conflict %s hint.", HintTypeName[cur_hint->type])); cur_hint->state = HINT_STATE_DUPLICATION; } } /* * Make sure that per-type array pointers point proper position in the * array which consists of all hints. */ hstate->scan_hints = (ScanMethodHint **) hstate->all_hints; hstate->join_hints = (JoinMethodHint **) (hstate->scan_hints + hstate->num_hints[HINT_TYPE_SCAN_METHOD]); hstate->leading_hint = (LeadingHint **) (hstate->join_hints + hstate->num_hints[HINT_TYPE_JOIN_METHOD]); hstate->set_hints = (SetHint **) (hstate->leading_hint + hstate->num_hints[HINT_TYPE_LEADING]); hstate->rows_hints = (RowsHint **) (hstate->set_hints + hstate->num_hints[HINT_TYPE_SET]); hstate->parallel_hints = (ParallelHint **) (hstate->rows_hints + hstate->num_hints[HINT_TYPE_ROWS]); hstate->memoize_hints = (JoinMethodHint **) (hstate->parallel_hints + hstate->num_hints[HINT_TYPE_PARALLEL]); return hstate; } /* * Parse inside of parentheses of scan-method hints. */ static const char * ScanMethodHintParse(ScanMethodHint *hint, const char *str) { const char *keyword = hint->base.keyword; HintKeyword hint_keyword = hint->base.hint_keyword; List *name_list = NIL; int length; if ((str = parse_parentheses(str, &name_list, hint_keyword)) == NULL) return NULL; /* Parse relation name and index name(s) if given hint accepts. */ length = list_length(name_list); /* at least twp parameters required */ if (length < 1) { hint_ereport(str, ("%s hint requires a relation.", hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; return str; } hint->relname = linitial(name_list); hint->indexnames = list_delete_first(name_list); /* check whether the hint accepts index name(s) */ if (length > 1 && !SCAN_HINT_ACCEPTS_INDEX_NAMES(hint_keyword)) { hint_ereport(str, ("%s hint accepts only one relation.", hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; return str; } /* Set a bit for specified hint. */ switch (hint_keyword) { case HINT_KEYWORD_SEQSCAN: hint->enforce_mask = ENABLE_SEQSCAN; break; case HINT_KEYWORD_INDEXSCAN: hint->enforce_mask = ENABLE_INDEXSCAN; break; case HINT_KEYWORD_INDEXSCANREGEXP: hint->enforce_mask = ENABLE_INDEXSCAN; hint->regexp = true; break; case HINT_KEYWORD_BITMAPSCAN: hint->enforce_mask = ENABLE_BITMAPSCAN; break; case HINT_KEYWORD_BITMAPSCANREGEXP: hint->enforce_mask = ENABLE_BITMAPSCAN; hint->regexp = true; break; case HINT_KEYWORD_TIDSCAN: hint->enforce_mask = ENABLE_TIDSCAN; break; case HINT_KEYWORD_NOSEQSCAN: hint->enforce_mask = ENABLE_ALL_SCAN ^ ENABLE_SEQSCAN; break; case HINT_KEYWORD_NOINDEXSCAN: hint->enforce_mask = ENABLE_ALL_SCAN ^ ENABLE_INDEXSCAN; break; case HINT_KEYWORD_NOBITMAPSCAN: hint->enforce_mask = ENABLE_ALL_SCAN ^ ENABLE_BITMAPSCAN; break; case HINT_KEYWORD_NOTIDSCAN: hint->enforce_mask = ENABLE_ALL_SCAN ^ ENABLE_TIDSCAN; break; case HINT_KEYWORD_INDEXONLYSCAN: hint->enforce_mask = ENABLE_INDEXSCAN | ENABLE_INDEXONLYSCAN; break; case HINT_KEYWORD_INDEXONLYSCANREGEXP: hint->enforce_mask = ENABLE_INDEXSCAN | ENABLE_INDEXONLYSCAN; hint->regexp = true; break; case HINT_KEYWORD_NOINDEXONLYSCAN: hint->enforce_mask = ENABLE_ALL_SCAN ^ ENABLE_INDEXONLYSCAN; break; default: hint_ereport(str, ("Unrecognized hint keyword \"%s\".", keyword)); return NULL; break; } return str; } static const char * JoinMethodHintParse(JoinMethodHint *hint, const char *str) { const char *keyword = hint->base.keyword; HintKeyword hint_keyword = hint->base.hint_keyword; List *name_list = NIL; if ((str = parse_parentheses(str, &name_list, hint_keyword)) == NULL) return NULL; hint->nrels = list_length(name_list); if (hint->nrels > 0) { ListCell *l; int i = 0; /* * Transform relation names from list to array to sort them with qsort * after. */ hint->relnames = palloc0(sizeof(char *) * hint->nrels); foreach (l, name_list) { hint->relnames[i] = lfirst(l); i++; } } list_free(name_list); /* A join hint requires at least two relations */ if (hint->nrels < 2) { hint_ereport(str, ("%s hint requires at least two relations.", hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; return str; } /* Sort hints in alphabetical order of relation names. */ qsort(hint->relnames, hint->nrels, sizeof(char *), RelnameCmp); switch (hint_keyword) { case HINT_KEYWORD_NESTLOOP: hint->enforce_mask = ENABLE_NESTLOOP; break; case HINT_KEYWORD_MERGEJOIN: hint->enforce_mask = ENABLE_MERGEJOIN; break; case HINT_KEYWORD_HASHJOIN: hint->enforce_mask = ENABLE_HASHJOIN; break; case HINT_KEYWORD_NONESTLOOP: hint->enforce_mask = ENABLE_ALL_JOIN ^ ENABLE_NESTLOOP; break; case HINT_KEYWORD_NOMERGEJOIN: hint->enforce_mask = ENABLE_ALL_JOIN ^ ENABLE_MERGEJOIN; break; case HINT_KEYWORD_NOHASHJOIN: hint->enforce_mask = ENABLE_ALL_JOIN ^ ENABLE_HASHJOIN; break; case HINT_KEYWORD_MEMOIZE: case HINT_KEYWORD_NOMEMOIZE: /* nothing to do here */ break; default: hint_ereport(str, ("Unrecognized hint keyword \"%s\".", keyword)); return NULL; break; } return str; } static bool OuterInnerPairCheck(OuterInnerRels *outer_inner) { ListCell *l; if (outer_inner->outer_inner_pair == NIL) { if (outer_inner->relation) return true; else return false; } if (list_length(outer_inner->outer_inner_pair) == 2) { foreach(l, outer_inner->outer_inner_pair) { if (!OuterInnerPairCheck(lfirst(l))) return false; } } else return false; return true; } static List * OuterInnerList(OuterInnerRels *outer_inner) { List *outer_inner_list = NIL; ListCell *l; OuterInnerRels *outer_inner_rels; foreach(l, outer_inner->outer_inner_pair) { outer_inner_rels = (OuterInnerRels *)(lfirst(l)); if (outer_inner_rels->relation != NULL) outer_inner_list = lappend(outer_inner_list, outer_inner_rels->relation); else outer_inner_list = list_concat(outer_inner_list, OuterInnerList(outer_inner_rels)); } return outer_inner_list; } static const char * LeadingHintParse(LeadingHint *hint, const char *str) { List *name_list = NIL; OuterInnerRels *outer_inner = NULL; if ((str = parse_parentheses_Leading(str, &name_list, &outer_inner)) == NULL) return NULL; if (outer_inner != NULL) name_list = OuterInnerList(outer_inner); hint->relations = name_list; hint->outer_inner = outer_inner; /* A Leading hint requires at least two relations */ if ( hint->outer_inner == NULL && list_length(hint->relations) < 2) { hint_ereport(hint->base.hint_str, ("%s hint requires at least two relations.", HINT_LEADING)); hint->base.state = HINT_STATE_ERROR; } else if (hint->outer_inner != NULL && !OuterInnerPairCheck(hint->outer_inner)) { hint_ereport(hint->base.hint_str, ("%s hint requires two sets of relations when parentheses nests.", HINT_LEADING)); hint->base.state = HINT_STATE_ERROR; } return str; } static const char * SetHintParse(SetHint *hint, const char *str) { List *name_list = NIL; if ((str = parse_parentheses(str, &name_list, hint->base.hint_keyword)) == NULL) return NULL; hint->words = name_list; /* We need both name and value to set GUC parameter. */ if (list_length(name_list) == 2) { hint->name = linitial(name_list); hint->value = lsecond(name_list); } else { hint_ereport(hint->base.hint_str, ("%s hint requires name and value of GUC parameter.", HINT_SET)); hint->base.state = HINT_STATE_ERROR; } return str; } static const char * RowsHintParse(RowsHint *hint, const char *str) { HintKeyword hint_keyword = hint->base.hint_keyword; List *name_list = NIL; char *rows_str; char *end_ptr; ListCell *l; int i = 0; if ((str = parse_parentheses(str, &name_list, hint_keyword)) == NULL) return NULL; /* Last element must be rows specification */ hint->nrels = list_length(name_list) - 1; if (hint->nrels < 1) { hint_ereport(str, ("%s hint needs at least one relation followed by one correction term.", hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; return str; } /* * Transform relation names from list to array to sort them with qsort * after. */ hint->relnames = palloc0(sizeof(char *) * hint->nrels); foreach (l, name_list) { if (hint->nrels <= i) break; hint->relnames[i] = lfirst(l); i++; } /* Retieve rows estimation */ rows_str = list_nth(name_list, hint->nrels); hint->rows_str = rows_str; /* store as-is for error logging */ if (rows_str[0] == '#') { hint->value_type = RVT_ABSOLUTE; rows_str++; } else if (rows_str[0] == '+') { hint->value_type = RVT_ADD; rows_str++; } else if (rows_str[0] == '-') { hint->value_type = RVT_SUB; rows_str++; } else if (rows_str[0] == '*') { hint->value_type = RVT_MULTI; rows_str++; } else { hint_ereport(rows_str, ("Unrecognized rows value type notation.")); hint->base.state = HINT_STATE_ERROR; return str; } hint->rows = strtod(rows_str, &end_ptr); if (*end_ptr) { hint_ereport(rows_str, ("%s hint requires valid number as rows estimation.", hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; return str; } /* A join hint requires at least two relations */ if (hint->nrels < 2) { hint_ereport(str, ("%s hint requires at least two relations.", hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; return str; } list_free(name_list); /* Sort relnames in alphabetical order. */ qsort(hint->relnames, hint->nrels, sizeof(char *), RelnameCmp); return str; } static const char * ParallelHintParse(ParallelHint *hint, const char *str) { HintKeyword hint_keyword = hint->base.hint_keyword; List *name_list = NIL; int length; char *end_ptr; int nworkers; bool force_parallel = false; if ((str = parse_parentheses(str, &name_list, hint_keyword)) == NULL) return NULL; /* Parse relation name and index name(s) if given hint accepts. */ length = list_length(name_list); if (length < 2 || length > 3) { hint_ereport(")", ("wrong number of arguments (%d): %s", length, hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; return str; } hint->relname = linitial(name_list); /* The second parameter is number of workers */ hint->nworkers_str = list_nth(name_list, 1); nworkers = strtod(hint->nworkers_str, &end_ptr); if (*end_ptr || nworkers < 0 || nworkers > max_worker_processes) { if (*end_ptr) hint_ereport(hint->nworkers_str, ("number of workers must be a number: %s", hint->base.keyword)); else if (nworkers < 0) hint_ereport(hint->nworkers_str, ("number of workers must be greater than zero: %s", hint->base.keyword)); else if (nworkers > max_worker_processes) hint_ereport(hint->nworkers_str, ("number of workers = %d is larger than max_worker_processes(%d): %s", nworkers, max_worker_processes, hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; } hint->nworkers = nworkers; /* optional third parameter is specified */ if (length == 3) { const char *modeparam = (const char *)list_nth(name_list, 2); if (pg_strcasecmp(modeparam, "hard") == 0) force_parallel = true; else if (pg_strcasecmp(modeparam, "soft") != 0) { hint_ereport(modeparam, ("enforcement must be soft or hard: %s", hint->base.keyword)); hint->base.state = HINT_STATE_ERROR; } } hint->force_parallel = force_parallel; if (hint->base.state != HINT_STATE_ERROR && nworkers > max_hint_nworkers) max_hint_nworkers = nworkers; return str; } /* * set GUC parameter functions */ static int get_current_scan_mask(void) { int mask = 0; if (enable_seqscan) mask |= ENABLE_SEQSCAN; if (enable_indexscan) mask |= ENABLE_INDEXSCAN; if (enable_bitmapscan) mask |= ENABLE_BITMAPSCAN; if (enable_tidscan) mask |= ENABLE_TIDSCAN; if (enable_indexonlyscan) mask |= ENABLE_INDEXONLYSCAN; return mask; } static int get_current_join_mask(void) { int mask = 0; if (enable_nestloop) mask |= ENABLE_NESTLOOP; if (enable_mergejoin) mask |= ENABLE_MERGEJOIN; if (enable_hashjoin) mask |= ENABLE_HASHJOIN; if (enable_memoize) mask |= ENABLE_MEMOIZE; return mask; } /* * Sets GUC parameters without throwing exception. Returns false if something * wrong. */ static int set_config_option_noerror(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel) { int result = 0; MemoryContext ccxt = CurrentMemoryContext; PG_TRY(); { result = set_config_option(name, value, context, source, action, changeVal, 0, false); } PG_CATCH(); { ErrorData *errdata; /* Save error info */ MemoryContextSwitchTo(ccxt); errdata = CopyErrorData(); FlushErrorState(); ereport(elevel, (errcode(errdata->sqlerrcode), errmsg("%s", errdata->message), errdata->detail ? errdetail("%s", errdata->detail) : 0, errdata->hint ? errhint("%s", errdata->hint) : 0)); msgqno = qno; /* Don't bother checking debug_level > 1*/ FreeErrorData(errdata); } PG_END_TRY(); return result; } /* * Sets GUC parameter of int32 type without throwing exceptions. Returns false * if something wrong. */ static int set_config_int32_option(const char *name, int32 value, GucContext context) { char buf[16]; /* enough for int32 */ if (snprintf(buf, 16, "%d", value) < 0) { ereport(pg_hint_plan_parse_message_level, (errmsg ("Failed to convert integer to string: %d", value))); return false; } return set_config_option_noerror(name, buf, context, PGC_S_SESSION, GUC_ACTION_SAVE, true, pg_hint_plan_parse_message_level); } /* * Sets GUC parameter of double type without throwing exceptions. Returns false * if something wrong. */ static int set_config_double_option(const char *name, double value, GucContext context) { char *buf = float8out_internal(value); int result; result = set_config_option_noerror(name, buf, context, PGC_S_SESSION, GUC_ACTION_SAVE, true, pg_hint_plan_parse_message_level); pfree(buf); return result; } /* setup scan method enforcement according to given options */ static void setup_guc_enforcement(SetHint **options, int noptions, GucContext context) { int i; for (i = 0; i < noptions; i++) { SetHint *hint = options[i]; int result; if (!hint_state_enabled(hint)) continue; result = set_config_option_noerror(hint->name, hint->value, context, PGC_S_SESSION, GUC_ACTION_SAVE, true, pg_hint_plan_parse_message_level); if (result != 0) hint->base.state = HINT_STATE_USED; else hint->base.state = HINT_STATE_ERROR; } return; } /* * Setup parallel execution environment. * * If hint is not NULL, set up using it, elsewise reset to initial environment. */ static void setup_parallel_plan_enforcement(ParallelHint *hint, HintState *state) { if (hint) { hint->base.state = HINT_STATE_USED; set_config_int32_option("max_parallel_workers_per_gather", hint->nworkers, state->context); } else set_config_int32_option("max_parallel_workers_per_gather", state->init_nworkers, state->context); /* force means that enforce parallel as far as possible */ if (hint && hint->force_parallel && hint->nworkers > 0) { set_config_double_option("parallel_tuple_cost", 0.0, state->context); set_config_double_option("parallel_setup_cost", 0.0, state->context); set_config_int32_option("min_parallel_table_scan_size", 0, state->context); set_config_int32_option("min_parallel_index_scan_size", 0, state->context); } else { set_config_double_option("parallel_tuple_cost", state->init_paratup_cost, state->context); set_config_double_option("parallel_setup_cost", state->init_parasetup_cost, state->context); set_config_int32_option("min_parallel_table_scan_size", state->init_min_para_tablescan_size, state->context); set_config_int32_option("min_parallel_index_scan_size", state->init_min_para_indexscan_size, state->context); } } #define SET_CONFIG_OPTION(name, type_bits) \ set_config_option_noerror((name), \ (mask & (type_bits)) ? "true" : "false", \ context, PGC_S_SESSION, GUC_ACTION_SAVE, true, ERROR) /* * Setup GUC environment to enforce scan methods. If scanhint is NULL, reset * GUCs to the saved state in state. */ static void setup_scan_method_enforcement(ScanMethodHint *scanhint, HintState *state) { unsigned char enforce_mask = state->init_scan_mask; GucContext context = state->context; unsigned char mask; if (scanhint) { enforce_mask = scanhint->enforce_mask; scanhint->base.state = HINT_STATE_USED; } if (enforce_mask == ENABLE_SEQSCAN || enforce_mask == ENABLE_INDEXSCAN || enforce_mask == ENABLE_BITMAPSCAN || enforce_mask == ENABLE_TIDSCAN || enforce_mask == (ENABLE_INDEXSCAN | ENABLE_INDEXONLYSCAN) ) mask = enforce_mask; else mask = enforce_mask & current_hint_state->init_scan_mask; SET_CONFIG_OPTION("enable_seqscan", ENABLE_SEQSCAN); SET_CONFIG_OPTION("enable_indexscan", ENABLE_INDEXSCAN); SET_CONFIG_OPTION("enable_bitmapscan", ENABLE_BITMAPSCAN); SET_CONFIG_OPTION("enable_tidscan", ENABLE_TIDSCAN); SET_CONFIG_OPTION("enable_indexonlyscan", ENABLE_INDEXONLYSCAN); } static void set_join_config_options(unsigned char enforce_mask, bool set_memoize, GucContext context) { unsigned char mask; if (enforce_mask == ENABLE_NESTLOOP || enforce_mask == ENABLE_MERGEJOIN || enforce_mask == ENABLE_HASHJOIN) mask = enforce_mask; else mask = enforce_mask & current_hint_state->init_join_mask; SET_CONFIG_OPTION("enable_nestloop", ENABLE_NESTLOOP); SET_CONFIG_OPTION("enable_mergejoin", ENABLE_MERGEJOIN); SET_CONFIG_OPTION("enable_hashjoin", ENABLE_HASHJOIN); if (set_memoize) SET_CONFIG_OPTION("enable_memoize", ENABLE_MEMOIZE); /* * Hash join may be rejected for the reason of estimated memory usage. Try * getting rid of that limitation. */ if (enforce_mask == ENABLE_HASHJOIN) { char buf[32]; int new_multipler; /* See final_cost_hashjoin(). */ new_multipler = MAX_KILOBYTES / work_mem; /* See guc.c for the upper limit */ if (new_multipler >= 1000) new_multipler = 1000; if (new_multipler > hash_mem_multiplier) { snprintf(buf, sizeof(buf), UINT64_FORMAT, (uint64)new_multipler); set_config_option_noerror("hash_mem_multiplier", buf, context, PGC_S_SESSION, GUC_ACTION_SAVE, true, ERROR); } } } /* * Push a hint into hint stack which is implemented with List struct. Head of * list is top of stack. */ static void push_hint(HintState *hstate) { /* Prepend new hint to the list means pushing to stack. */ HintStateStack = lcons(hstate, HintStateStack); /* Pushed hint is the one which should be used hereafter. */ current_hint_state = hstate; } /* Pop a hint from hint stack. Popped hint is automatically discarded. */ static void pop_hint(void) { /* Hint stack must not be empty. */ if(HintStateStack == NIL) elog(ERROR, "hint stack is empty"); /* * Take a hint at the head from the list, and free it. Switch * current_hint_state to point new head (NULL if the list is empty). */ HintStateStack = list_delete_first(HintStateStack); HintStateDelete(current_hint_state); if(HintStateStack == NIL) current_hint_state = NULL; else current_hint_state = (HintState *) lfirst(list_head(HintStateStack)); } /* * Retrieve and store hint string from given query or from the hint table. */ static void get_current_hint_string(Query *query, const char *query_str, JumbleState *jstate) { MemoryContext oldcontext; /* We shouldn't get here for internal queries. */ Assert (hint_inhibit_level == 0); /* We shouldn't get here if hint is disabled. */ Assert (pg_hint_plan_enable_hint); /* Do not anything if we have already tried to get hints for this query. */ if (current_hint_retrieved) return; /* No way to retrieve hints from empty string. */ if (!query_str) return; /* Don't parse the current query hereafter */ current_hint_retrieved = true; /* Make sure trashing old hint string */ if (current_hint_str) { pfree((void *)current_hint_str); current_hint_str = NULL; } /* increment the query number */ qnostr[0] = 0; if (debug_level > 1) snprintf(qnostr, sizeof(qnostr), "[qno=0x%x]", qno++); /* search the hint table for a hint if requested */ if (pg_hint_plan_enable_hint_table) { if (!IsQueryIdEnabled()) { /* * compute_query_id was turned off while enable_hint_table is * on. Do not go ahead and complain once until it is turned on * again. */ if (!hint_table_deactivated) ereport(WARNING, (errmsg ("hint table feature is deactivated because queryid is not available"), errhint("Set compute_query_id to \"auto\" or \"on\" to use hint table."))); hint_table_deactivated = true; return; } if (hint_table_deactivated) { ereport(LOG, (errmsg ("hint table feature is reactivated"))); hint_table_deactivated = false; } /* * Find a hint for the query. The result should be in * TopMemoryContext. */ oldcontext = MemoryContextSwitchTo(TopMemoryContext); current_hint_str = get_hints_from_table(query->queryId, application_name); MemoryContextSwitchTo(oldcontext); if (debug_level > 1) { if (current_hint_str) ereport(pg_hint_plan_debug_message_level, (errmsg("pg_hint_plan[qno=0x%x]: " "hints from table: \"%s\": " "query_id=\"%lld\", " "application name =\"%s\"", qno, current_hint_str, (long long) query->queryId, application_name), errhidestmt(msgqno != qno), errhidecontext(msgqno != qno))); else ereport(pg_hint_plan_debug_message_level, (errmsg("pg_hint_plan[qno=0x%x]: " "no match found in table: " "application name = \"%s\", " "query_id=\"%lld\"", qno, application_name, (long long) query->queryId), errhidestmt(msgqno != qno), errhidecontext(msgqno != qno))); msgqno = qno; } /* return if we have hint string here */ if (current_hint_str) return; } /* get hints from the comment */ current_hint_str = get_hints_from_comment(query_str); if (debug_level > 1) { if (debug_level == 2 && query_str && debug_query_string && strcmp(query_str, debug_query_string)) ereport(pg_hint_plan_debug_message_level, (errmsg("hints in comment=\"%s\"", current_hint_str ? current_hint_str : "(none)"), errhidestmt(msgqno != qno), errhidecontext(msgqno != qno))); else ereport(pg_hint_plan_debug_message_level, (errmsg("hints in comment=\"%s\", query=\"%s\", debug_query_string=\"%s\"", current_hint_str ? current_hint_str : "(none)", query_str ? query_str : "(none)", debug_query_string ? debug_query_string : "(none)"), errhidestmt(msgqno != qno), errhidecontext(msgqno != qno))); msgqno = qno; } } /* * Retrieve hint string from the current query. */ static void pg_hint_plan_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate) { if (prev_post_parse_analyze_hook) prev_post_parse_analyze_hook(pstate, query, jstate); if (!pg_hint_plan_enable_hint || hint_inhibit_level > 0) return; /* always retrieve hint from the top-level query string */ if (plpgsql_recurse_level == 0) current_hint_retrieved = false; /* * Query jumbling is possible with utility queries in PostgreSQL 16 and * newer versions, hence just leave in this case. There could be a point * in providing hints for some cases, like a CTAS or a matview creation, * but that should not matter much in practice compared to SELECT and DML * queries, and nobody has made a case for these now. So let's just * ignore the case entirely for now. */ if (query->utilityStmt) return; /* * Jumble state is required when hint table is used. This is the only * chance to have one already generated in-core. If it's not the case, no * use to do the work now and pg_hint_plan_planner() will do the all work. */ if (jstate) get_current_hint_string(query, pstate->p_sourcetext, jstate); } /* * Read and set up hint information */ static PlannedStmt * pg_hint_plan_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams) { int save_nestlevel; PlannedStmt *result; HintState *hstate; const char *prev_hint_str = NULL; /* * Use standard planner if pg_hint_plan is disabled or current nesting * depth is nesting depth of SPI calls. Other hook functions try to change * plan with current_hint_state if any, so set it to NULL. */ if (!pg_hint_plan_enable_hint || hint_inhibit_level > 0) { if (debug_level > 1) { ereport(pg_hint_plan_debug_message_level, (errmsg ("pg_hint_plan%s: planner: enable_hint=%d," " hint_inhibit_level=%d", qnostr, pg_hint_plan_enable_hint, hint_inhibit_level), errhidestmt(msgqno != qno))); msgqno = qno; } goto standard_planner_proc; } /* * SQL commands invoked in plpgsql functions may also have hints. In that * case override the upper level hint by the new hint. */ if (plpgsql_recurse_level > 0) { const char *tmp_hint_str = current_hint_str; /* don't let get_current_hint_string free this string */ current_hint_str = NULL; current_hint_retrieved = false; get_current_hint_string(parse, query_string, NULL); if (current_hint_str == NULL) current_hint_str = tmp_hint_str; else if (tmp_hint_str != NULL) pfree((void *)tmp_hint_str); } else get_current_hint_string(parse, query_string, NULL); /* No hints, go the normal way */ if (!current_hint_str) goto standard_planner_proc; /* parse the hint into hint state struct */ hstate = create_hintstate(parse, pstrdup(current_hint_str)); /* run standard planner if we're given with no valid hints */ if (!hstate) { /* forget invalid hint string */ if (current_hint_str) { pfree((void *)current_hint_str); current_hint_str = NULL; } goto standard_planner_proc; } /* * Push new hint struct to the hint stack to disable previous hint context. * There should be no ERROR-level failures until we begin the * PG_TRY/PG_CATCH block below to ensure a consistent stack handling all * the time. */ push_hint(hstate); /* Set scan enforcement here. */ save_nestlevel = NewGUCNestLevel(); /* * The planner call below may replace current_hint_str. Store and restore * it so that the subsequent planning in the upper level doesn't get * confused. */ recurse_level++; prev_hint_str = current_hint_str; current_hint_str = NULL; /* * Use PG_TRY mechanism to recover GUC parameters and current_hint_state to * the state when this planner started when error occurred in planner. We * do this here to minimize the window where the hints currently pushed on * the stack could not be popped out of it. */ PG_TRY(); { /* Apply Set hints, then save it as the initial state */ setup_guc_enforcement(current_hint_state->set_hints, current_hint_state->num_hints[HINT_TYPE_SET], current_hint_state->context); current_hint_state->init_scan_mask = get_current_scan_mask(); current_hint_state->init_join_mask = get_current_join_mask(); current_hint_state->init_min_para_tablescan_size = min_parallel_table_scan_size; current_hint_state->init_min_para_indexscan_size = min_parallel_index_scan_size; current_hint_state->init_paratup_cost = parallel_tuple_cost; current_hint_state->init_parasetup_cost = parallel_setup_cost; /* * max_parallel_workers_per_gather should be non-zero here if Workers * hint is specified. */ if (max_hint_nworkers > 0 && max_parallel_workers_per_gather < 1) set_config_int32_option("max_parallel_workers_per_gather", 1, current_hint_state->context); current_hint_state->init_nworkers = max_parallel_workers_per_gather; if (debug_level > 1) { ereport(pg_hint_plan_debug_message_level, (errhidestmt(msgqno != qno), errmsg("pg_hint_plan%s: planner", qnostr))); msgqno = qno; } if (prev_planner) result = (*prev_planner) (parse, query_string, cursorOptions, boundParams); else result = standard_planner(parse, query_string, cursorOptions, boundParams); current_hint_str = prev_hint_str; recurse_level--; } PG_CATCH(); { /* * Rollback changes of GUC parameters, and pop current hint context * from hint stack to rewind the state. current_hint_str will be freed * by context deletion. */ current_hint_str = prev_hint_str; recurse_level--; AtEOXact_GUC(true, save_nestlevel); pop_hint(); PG_RE_THROW(); } PG_END_TRY(); /* * current_hint_str is useless after planning of the top-level query. * There's a case where the caller has multiple queries. This causes hint * parsing multiple times for the same string but we don't have a simple * and reliable way to distinguish that case from the case where of * separate queries. */ if (recurse_level < 1) current_hint_retrieved = false; /* Print hint in debug mode. */ if (debug_level == 1) HintStateDump(current_hint_state); else if (debug_level > 1) HintStateDump2(current_hint_state); /* * Rollback changes of GUC parameters, and pop current hint context from * hint stack to rewind the state. */ AtEOXact_GUC(true, save_nestlevel); pop_hint(); return result; standard_planner_proc: if (debug_level > 1) { ereport(pg_hint_plan_debug_message_level, (errhidestmt(msgqno != qno), errmsg("pg_hint_plan%s: planner: no valid hint", qnostr))); msgqno = qno; } current_hint_state = NULL; if (prev_planner) result = (*prev_planner) (parse, query_string, cursorOptions, boundParams); else result = standard_planner(parse, query_string, cursorOptions, boundParams); /* The upper-level planner still needs the current hint state */ if (HintStateStack != NIL) current_hint_state = (HintState *) lfirst(list_head(HintStateStack)); return result; } /* * Find scan method hint to be applied to the given relation * */ static ScanMethodHint * find_scan_hint(PlannerInfo *root, Index relid) { RelOptInfo *rel; RangeTblEntry *rte; ScanMethodHint *real_name_hint = NULL; ScanMethodHint *alias_hint = NULL; int i; /* This should not be a join rel */ Assert(relid > 0); rel = root->simple_rel_array[relid]; /* * This function is called for any RelOptInfo or its inheritance parent if * any. If we are called from inheritance planner, the RelOptInfo for the * parent of target child relation is not set in the planner info. * * Otherwise we should check that the reloptinfo is base relation or * inheritance children. */ if (rel && rel->reloptkind != RELOPT_BASEREL && rel->reloptkind != RELOPT_OTHER_MEMBER_REL) return NULL; /* * This is baserel or appendrel children. We can refer to RangeTblEntry. */ rte = root->simple_rte_array[relid]; Assert(rte); /* We don't hint on other than relation and foreign tables */ if (rte->rtekind != RTE_RELATION || rte->relkind == RELKIND_FOREIGN_TABLE) return NULL; /* Find scan method hint, which matches given names, from the list. */ for (i = 0; i < current_hint_state->num_hints[HINT_TYPE_SCAN_METHOD]; i++) { ScanMethodHint *hint = current_hint_state->scan_hints[i]; /* We ignore disabled hints. */ if (!hint_state_enabled(hint)) continue; if (!alias_hint && RelnameCmp(&rte->eref->aliasname, &hint->relname) == 0) alias_hint = hint; /* check the real name for appendrel children */ if (!real_name_hint && rel && rel->reloptkind == RELOPT_OTHER_MEMBER_REL) { char *realname = get_rel_name(rte->relid); if (realname && RelnameCmp(&realname, &hint->relname) == 0) real_name_hint = hint; } /* No more match expected, break */ if(alias_hint && real_name_hint) break; } /* real name match precedes alias match */ if (real_name_hint) return real_name_hint; return alias_hint; } static ParallelHint * find_parallel_hint(PlannerInfo *root, Index relid) { RelOptInfo *rel; RangeTblEntry *rte; ParallelHint *real_name_hint = NULL; ParallelHint *alias_hint = NULL; int i; /* This should not be a join rel */ Assert(relid > 0); rel = root->simple_rel_array[relid]; /* * Parallel planning is appliable only on base relation, which has * RelOptInfo. */ if (!rel) return NULL; /* * We have set root->glob->parallelModeOK if needed. What we should do here * is just following the decision of planner. */ if (!rel->consider_parallel) return NULL; /* * This is baserel or appendrel children. We can refer to RangeTblEntry. */ rte = root->simple_rte_array[relid]; Assert(rte); /* Find parallel method hint, which matches given names, from the list. */ for (i = 0; i < current_hint_state->num_hints[HINT_TYPE_PARALLEL]; i++) { ParallelHint *hint = current_hint_state->parallel_hints[i]; /* We ignore disabled hints. */ if (!hint_state_enabled(hint)) continue; if (!alias_hint && RelnameCmp(&rte->eref->aliasname, &hint->relname) == 0) alias_hint = hint; /* check the real name for appendrel children */ if (!real_name_hint && rel && rel->reloptkind == RELOPT_OTHER_MEMBER_REL) { char *realname = get_rel_name(rte->relid); if (realname && RelnameCmp(&realname, &hint->relname) == 0) real_name_hint = hint; } /* No more match expected, break */ if(alias_hint && real_name_hint) break; } /* real name match precedes alias match */ if (real_name_hint) return real_name_hint; return alias_hint; } /* * regexeq * * Returns TRUE on match, FALSE on no match. * * s1 --- the data to match against * s2 --- the pattern * * Because we copy s1 to NameData, make the size of s1 less than NAMEDATALEN. */ static bool regexpeq(const char *s1, const char *s2) { NameData name; text *regexp; Datum result; strcpy(name.data, s1); regexp = cstring_to_text(s2); result = DirectFunctionCall2Coll(nameregexeq, DEFAULT_COLLATION_OID, NameGetDatum(&name), PointerGetDatum(regexp)); return DatumGetBool(result); } /* * Filter out indexes instructed in the hint as not to be used. * * This routine is used in relationship with the scan method enforcement, and * it returns true to allow the follow-up scan method to be enforced, and false * to prevent the scan enforcement. Currently, this code will not enforce * the scan enforcement if *all* the indexes available to a relation have been * discarded. */ static bool restrict_indexes(PlannerInfo *root, ScanMethodHint *hint, RelOptInfo *rel, bool using_parent_hint) { ListCell *cell; StringInfoData buf; RangeTblEntry *rte = root->simple_rte_array[rel->relid]; Oid relationObjectId = rte->relid; List *unused_indexes = NIL; bool restrict_result; /* * We delete all the IndexOptInfo list and prevent you from being usable by * a scan. */ if (hint->enforce_mask == ENABLE_SEQSCAN || hint->enforce_mask == ENABLE_TIDSCAN) { list_free_deep(rel->indexlist); rel->indexlist = NIL; hint->base.state = HINT_STATE_USED; return true; } /* * When a list of indexes is not specified, we just use all indexes. */ if (hint->indexnames == NIL) return true; /* * Leaving only an specified index, we delete it from a IndexOptInfo list * other than it. However, if none of the specified indexes are available, * then we keep all the indexes and skip enforcing the scan method. i.e., * we skip the scan hint altogether for the relation. */ if (debug_level > 0) initStringInfo(&buf); foreach (cell, rel->indexlist) { IndexOptInfo *info = (IndexOptInfo *) lfirst(cell); char *indexname = get_rel_name(info->indexoid); ListCell *l; bool use_index = false; foreach(l, hint->indexnames) { char *hintname = (char *) lfirst(l); bool result; if (hint->regexp) result = regexpeq(indexname, hintname); else result = RelnameCmp(&indexname, &hintname) == 0; if (result) { use_index = true; if (debug_level > 0) { appendStringInfoCharMacro(&buf, ' '); quote_value(&buf, indexname); } break; } } /* * Apply index restriction of parent hint to children. Since index * inheritance is not explicitly described we should search for an * children's index with the same definition to that of the parent. */ if (using_parent_hint && !use_index) { foreach(l, current_hint_state->parent_index_infos) { int i; HeapTuple ht_idx; ParentIndexInfo *p_info = (ParentIndexInfo *)lfirst(l); /* * we check the 'same' index by comparing uniqueness, access * method and index key columns. */ if (p_info->indisunique != info->unique || p_info->method != info->relam || list_length(p_info->column_names) != info->ncolumns) continue; /* Check if index key columns match */ for (i = 0; i < info->ncolumns; i++) { char *c_attname = NULL; char *p_attname = NULL; p_attname = list_nth(p_info->column_names, i); /* * if both of the key of the same position are expressions, * ignore them for now and check later. */ if (info->indexkeys[i] == 0 && !p_attname) continue; /* deny if one is expression while another is not */ if (info->indexkeys[i] == 0 || !p_attname) break; c_attname = get_attname(relationObjectId, info->indexkeys[i], false); /* deny if any of column attributes don't match */ if (strcmp(p_attname, c_attname) != 0 || p_info->indcollation[i] != info->indexcollations[i] || p_info->opclass[i] != info->opcintype[i]) break; /* * Compare index ordering if this index is ordered. * * We already confirmed that this and the parent indexes * share the same column set (actually only the length of * the column set is compard, though.) and index access * method. So if this index is unordered, the parent can be * assumed to be be unodered. Thus no need to bother * checking the parent's orderedness. */ if (info->sortopfamily != NULL && (((p_info->indoption[i] & INDOPTION_DESC) != 0) != info->reverse_sort[i] || ((p_info->indoption[i] & INDOPTION_NULLS_FIRST) != 0) != info->nulls_first[i])) break; } /* deny this if any difference found */ if (i != info->ncolumns) continue; /* check on key expressions */ if ((p_info->expression_str && (info->indexprs != NIL)) || (p_info->indpred_str && (info->indpred != NIL))) { /* fetch the index of this child */ ht_idx = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(info->indexoid)); /* check expressions if both expressions are available */ if (p_info->expression_str && !heap_attisnull(ht_idx, Anum_pg_index_indexprs, NULL)) { Datum exprsDatum; bool isnull; Datum result; /* * to change the expression's parameter of child's * index to strings */ exprsDatum = SysCacheGetAttr(INDEXRELID, ht_idx, Anum_pg_index_indexprs, &isnull); result = DirectFunctionCall2(pg_get_expr, exprsDatum, ObjectIdGetDatum( relationObjectId)); /* deny if expressions don't match */ if (strcmp(p_info->expression_str, text_to_cstring(DatumGetTextP(result))) != 0) { /* Clean up */ ReleaseSysCache(ht_idx); continue; } } /* compare index predicates */ if (p_info->indpred_str && !heap_attisnull(ht_idx, Anum_pg_index_indpred, NULL)) { Datum predDatum; bool isnull; Datum result; predDatum = SysCacheGetAttr(INDEXRELID, ht_idx, Anum_pg_index_indpred, &isnull); result = DirectFunctionCall2(pg_get_expr, predDatum, ObjectIdGetDatum( relationObjectId)); if (strcmp(p_info->indpred_str, text_to_cstring(DatumGetTextP(result))) != 0) { /* Clean up */ ReleaseSysCache(ht_idx); continue; } } /* Clean up */ ReleaseSysCache(ht_idx); } else if (p_info->expression_str || (info->indexprs != NIL)) continue; else if (p_info->indpred_str || (info->indpred != NIL)) continue; use_index = true; /* to log the candidate of index */ if (debug_level > 0) { appendStringInfoCharMacro(&buf, ' '); quote_value(&buf, indexname); } break; } } if (!use_index) unused_indexes = lappend_oid(unused_indexes, info->indexoid); pfree(indexname); } /* * Update the list of indexes available to the IndexOptInfo based on what * has been discarded previously. * * If the hint has no matching indexes, skip applying the hinted scan * method. For example if an IndexScan hint does not have any matching * indexes, we should not enforce an enable_indexscan. */ if (list_length(unused_indexes) < list_length(rel->indexlist)) { foreach (cell, unused_indexes) { Oid final_oid = lfirst_oid(cell); ListCell *l; foreach (l, rel->indexlist) { IndexOptInfo *info = (IndexOptInfo *) lfirst(l); if (info->indexoid == final_oid) rel->indexlist = foreach_delete_current(rel->indexlist, l); } } restrict_result = true; } else restrict_result = false; list_free(unused_indexes); if (debug_level > 0) { StringInfoData rel_buf; char *disprelname = ""; /* * If this hint targetted the parent, use the real name of this * child. Otherwise use hint specification. */ if (using_parent_hint) disprelname = get_rel_name(rte->relid); else disprelname = hint->relname; initStringInfo(&rel_buf); quote_value(&rel_buf, disprelname); ereport(pg_hint_plan_debug_message_level, (errmsg("available indexes for %s(%s):%s", hint->base.keyword, rel_buf.data, buf.data))); pfree(buf.data); pfree(rel_buf.data); } return restrict_result; } /* * Return information of index definition. */ static ParentIndexInfo * get_parent_index_info(Oid indexoid, Oid relid) { ParentIndexInfo *p_info = palloc0(sizeof(ParentIndexInfo)); Relation indexRelation; Form_pg_index index; char *attname; int i; indexRelation = index_open(indexoid, RowExclusiveLock); index = indexRelation->rd_index; p_info->indisunique = index->indisunique; p_info->method = indexRelation->rd_rel->relam; p_info->column_names = NIL; p_info->indcollation = (Oid *) palloc0(sizeof(Oid) * index->indnatts); p_info->opclass = (Oid *) palloc0(sizeof(Oid) * index->indnatts); p_info->indoption = (int16 *) palloc0(sizeof(Oid) * index->indnatts); /* * Collect relation attribute names of index columns for index * identification, not index attribute names. NULL means expression index * columns. */ for (i = 0; i < index->indnatts; i++) { attname = get_attname(relid, index->indkey.values[i], true); p_info->column_names = lappend(p_info->column_names, attname); p_info->indcollation[i] = indexRelation->rd_indcollation[i]; p_info->opclass[i] = indexRelation->rd_opcintype[i]; p_info->indoption[i] = indexRelation->rd_indoption[i]; } /* * to check to match the expression's parameter of index with child indexes */ p_info->expression_str = NULL; if(!heap_attisnull(indexRelation->rd_indextuple, Anum_pg_index_indexprs, NULL)) { Datum exprsDatum; bool isnull; Datum result; exprsDatum = SysCacheGetAttr(INDEXRELID, indexRelation->rd_indextuple, Anum_pg_index_indexprs, &isnull); result = DirectFunctionCall2(pg_get_expr, exprsDatum, ObjectIdGetDatum(relid)); p_info->expression_str = text_to_cstring(DatumGetTextP(result)); } /* * to check to match the predicate's parameter of index with child indexes */ p_info->indpred_str = NULL; if(!heap_attisnull(indexRelation->rd_indextuple, Anum_pg_index_indpred, NULL)) { Datum predDatum; bool isnull; Datum result; predDatum = SysCacheGetAttr(INDEXRELID, indexRelation->rd_indextuple, Anum_pg_index_indpred, &isnull); result = DirectFunctionCall2(pg_get_expr, predDatum, ObjectIdGetDatum(relid)); p_info->indpred_str = text_to_cstring(DatumGetTextP(result)); } index_close(indexRelation, NoLock); return p_info; } /* * cancel hint enforcement */ static void reset_hint_enforcement(void) { setup_scan_method_enforcement(NULL, current_hint_state); setup_parallel_plan_enforcement(NULL, current_hint_state); } /* * Set planner guc parameters according to corresponding scan hints. Returns * bitmap of HintTypeBitmap. If shint or phint is not NULL, set used hint * there respectively. */ static int setup_hint_enforcement(PlannerInfo *root, RelOptInfo *rel, ScanMethodHint **rshint, ParallelHint **rphint) { Index new_parent_relid = 0; ListCell *l; ScanMethodHint *shint = NULL; ParallelHint *phint = NULL; bool inhparent = root->simple_rte_array[rel->relid]->inh; Oid relationObjectId = root->simple_rte_array[rel->relid]->relid; int ret = 0; /* reset returns if requested */ if (rshint != NULL) *rshint = NULL; if (rphint != NULL) *rphint = NULL; /* * We could register the parent relation of the following children here * when inhparent == true but inheritnce planner doesn't call this function * for parents. Since we cannot distinguish who called this function we * cannot do other than always seeking the parent regardless of who called * this function. */ if (inhparent) { /* set up only parallel hints for parent relation */ phint = find_parallel_hint(root, rel->relid); if (phint) { setup_parallel_plan_enforcement(phint, current_hint_state); if (rphint) *rphint = phint; ret |= HINT_BM_PARALLEL; return ret; } if (debug_level > 1) ereport(pg_hint_plan_debug_message_level, (errhidestmt(true), errmsg ("pg_hint_plan%s: setup_hint_enforcement" " skipping inh parent: relation=%u(%s), inhparent=%d," " current_hint_state=%p, hint_inhibit_level=%d", qnostr, relationObjectId, get_rel_name(relationObjectId), inhparent, current_hint_state, hint_inhibit_level))); return 0; } if (bms_num_members(rel->top_parent_relids) == 1) { new_parent_relid = bms_next_member(rel->top_parent_relids, -1); current_hint_state->current_root = root; Assert(new_parent_relid > 0); } else { /* This relation doesn't have a parent. Cancel current_hint_state. */ current_hint_state->parent_relid = 0; current_hint_state->parent_scan_hint = NULL; current_hint_state->parent_parallel_hint = NULL; } if (new_parent_relid > 0) { /* * Here we found a new parent for the current relation. Scan continues * hint to other childrens of this parent so remember it to avoid * redundant setup cost. */ current_hint_state->parent_relid = new_parent_relid; /* Find hints for the parent */ current_hint_state->parent_scan_hint = find_scan_hint(root, current_hint_state->parent_relid); current_hint_state->parent_parallel_hint = find_parallel_hint(root, current_hint_state->parent_relid); /* * If hint is found for the parent, apply it for this child instead * of its own. */ if (current_hint_state->parent_scan_hint) { ScanMethodHint * pshint = current_hint_state->parent_scan_hint; /* Apply index mask in the same manner to the parent. */ if (pshint->indexnames) { Oid parentrel_oid; Relation parent_rel; parentrel_oid = root->simple_rte_array[current_hint_state->parent_relid]->relid; parent_rel = table_open(parentrel_oid, NoLock); /* Search the parent relation for indexes match the hint spec */ foreach(l, RelationGetIndexList(parent_rel)) { Oid indexoid = lfirst_oid(l); char *indexname = get_rel_name(indexoid); ListCell *lc; ParentIndexInfo *parent_index_info; foreach(lc, pshint->indexnames) { if (RelnameCmp(&indexname, &lfirst(lc)) == 0) break; } if (!lc) continue; parent_index_info = get_parent_index_info(indexoid, parentrel_oid); current_hint_state->parent_index_infos = lappend(current_hint_state->parent_index_infos, parent_index_info); } table_close(parent_rel, NoLock); } } } shint = find_scan_hint(root, rel->relid); if (!shint) shint = current_hint_state->parent_scan_hint; if (shint) { bool using_parent_hint = (shint == current_hint_state->parent_scan_hint); bool restrict_result; ret |= HINT_BM_SCAN_METHOD; /* restrict unwanted indexes */ restrict_result = restrict_indexes(root, shint, rel, using_parent_hint); /* * Setup scan enforcement environment * * This has to be called after restrict_indexes(), that may decide to * skip the scan method enforcement depending on the index restrictions * applied. */ if (restrict_result) setup_scan_method_enforcement(shint, current_hint_state); if (debug_level > 1) { char *additional_message = ""; if (shint == current_hint_state->parent_scan_hint) additional_message = " by parent hint"; ereport(pg_hint_plan_debug_message_level, (errhidestmt(true), errmsg ("pg_hint_plan%s: setup_hint_enforcement" " index deletion%s:" " relation=%u(%s), inhparent=%d, " "current_hint_state=%p," " hint_inhibit_level=%d, scanmask=0x%x", qnostr, additional_message, relationObjectId, get_rel_name(relationObjectId), inhparent, current_hint_state, hint_inhibit_level, shint->enforce_mask))); } } /* Do the same for parallel plan enforcement */ phint = find_parallel_hint(root, rel->relid); if (!phint) phint = current_hint_state->parent_parallel_hint; setup_parallel_plan_enforcement(phint, current_hint_state); if (phint) ret |= HINT_BM_PARALLEL; /* Nothing to apply. Reset the scan mask to intial state */ if (!shint && !phint) { if (debug_level > 1) ereport(pg_hint_plan_debug_message_level, (errhidestmt (true), errmsg ("pg_hint_plan%s: setup_hint_enforcement" " no hint applied:" " relation=%u(%s), inhparent=%d, current_hint=%p," " hint_inhibit_level=%d, scanmask=0x%x", qnostr, relationObjectId, get_rel_name(relationObjectId), inhparent, current_hint_state, hint_inhibit_level, current_hint_state->init_scan_mask))); setup_scan_method_enforcement(NULL, current_hint_state); return ret; } if (rshint != NULL) *rshint = shint; if (rphint != NULL) *rphint = phint; return ret; } /* * Return index of relation which matches given aliasname, or 0 if not found. * If same aliasname was used multiple times in a query, return -1. */ static int find_relid_aliasname(PlannerInfo *root, char *aliasname, List *initial_rels, const char *str) { int i; Index found = 0; for (i = 1; i < root->simple_rel_array_size; i++) { ListCell *l; if (root->simple_rel_array[i] == NULL) continue; Assert(i == root->simple_rel_array[i]->relid); if (RelnameCmp(&aliasname, &root->simple_rte_array[i]->eref->aliasname) != 0) continue; foreach(l, initial_rels) { RelOptInfo *rel = (RelOptInfo *) lfirst(l); if (rel->reloptkind == RELOPT_BASEREL) { if (rel->relid != i) continue; } else { Assert(rel->reloptkind == RELOPT_JOINREL); if (!bms_is_member(i, rel->relids)) continue; } if (found != 0) { hint_ereport(str, ("Relation name \"%s\" is ambiguous.", aliasname)); return -1; } found = i; break; } } return found; } /* * Return join hint which matches given joinrelids. */ static JoinMethodHint * find_join_hint(Relids joinrelids) { List *join_hint; ListCell *l; join_hint = current_hint_state->join_hint_level[bms_num_members(joinrelids)]; foreach(l, join_hint) { JoinMethodHint *hint = (JoinMethodHint *) lfirst(l); if (bms_equal(joinrelids, hint->joinrelids)) return hint; } return NULL; } /* * Return memoize hint which matches given joinrelids. */ static JoinMethodHint * find_memoize_hint(Relids joinrelids) { List *join_hint; ListCell *l; join_hint = current_hint_state->memoize_hint_level[bms_num_members(joinrelids)]; foreach(l, join_hint) { JoinMethodHint *hint = (JoinMethodHint *) lfirst(l); if (bms_equal(joinrelids, hint->joinrelids)) return hint; } return NULL; } static Relids OuterInnerJoinCreate(OuterInnerRels *outer_inner, LeadingHint *leading_hint, PlannerInfo *root, List *initial_rels, HintState *hstate, int nbaserel) { OuterInnerRels *outer_rels; OuterInnerRels *inner_rels; Relids outer_relids; Relids inner_relids; Relids join_relids; JoinMethodHint *hint; if (outer_inner->relation != NULL) { return bms_make_singleton( find_relid_aliasname(root, outer_inner->relation, initial_rels, leading_hint->base.hint_str)); } outer_rels = linitial(outer_inner->outer_inner_pair); inner_rels = llast(outer_inner->outer_inner_pair); outer_relids = OuterInnerJoinCreate(outer_rels, leading_hint, root, initial_rels, hstate, nbaserel); inner_relids = OuterInnerJoinCreate(inner_rels, leading_hint, root, initial_rels, hstate, nbaserel); join_relids = bms_add_members(outer_relids, inner_relids); /* * join_relids may include outer-join relids since PostgreSQL 16, so * filter them out as hints can only handle base relations. */ join_relids = bms_intersect(join_relids, root->all_baserels); if (bms_num_members(join_relids) > nbaserel) return join_relids; /* * If we don't have join method hint, create new one for the * join combination with all join methods are enabled. */ hint = find_join_hint(join_relids); if (hint == NULL) { /* * Here relnames is not set, since Relids bitmap is sufficient to * control paths of this query afterward. */ hint = (JoinMethodHint *) JoinMethodHintCreate( leading_hint->base.hint_str, HINT_LEADING, HINT_KEYWORD_LEADING); hint->base.state = HINT_STATE_USED; hint->nrels = bms_num_members(join_relids); hint->enforce_mask = ENABLE_ALL_JOIN; hint->joinrelids = bms_copy(join_relids); hint->inner_nrels = bms_num_members(inner_relids); hint->inner_joinrelids = bms_copy(inner_relids); hstate->join_hint_level[hint->nrels] = lappend(hstate->join_hint_level[hint->nrels], hint); } else { hint->inner_nrels = bms_num_members(inner_relids); hint->inner_joinrelids = bms_copy(inner_relids); } return join_relids; } static Relids create_bms_of_relids(Hint *base, PlannerInfo *root, List *initial_rels, int nrels, char **relnames) { int relid; Relids relids = NULL; int j; char *relname; for (j = 0; j < nrels; j++) { relname = relnames[j]; relid = find_relid_aliasname(root, relname, initial_rels, base->hint_str); if (relid == -1) base->state = HINT_STATE_ERROR; /* * the aliasname is not found(relid == 0) or same aliasname was used * multiple times in a query(relid == -1) */ if (relid <= 0) { relids = NULL; break; } if (bms_is_member(relid, relids)) { hint_ereport(base->hint_str, ("Relation name \"%s\" is duplicated.", relname)); base->state = HINT_STATE_ERROR; break; } relids = bms_add_member(relids, relid); } return relids; } /* * Transform join method hint into handy form. * * - create bitmap of relids from alias names, to make it easier to check * whether a join path matches a join method hint. * - add join method hints which are necessary to enforce join order * specified by Leading hint */ static bool transform_join_hints(HintState *hstate, PlannerInfo *root, int nbaserel, List *initial_rels, JoinMethodHint **join_method_hints) { int i; int relid; Relids joinrelids; int njoinrels; ListCell *l; char *relname; LeadingHint *lhint = NULL; /* * Create bitmap of relids from alias names for each join method hint. * Bitmaps are more handy than strings in join searching. */ for (i = 0; i < hstate->num_hints[HINT_TYPE_JOIN_METHOD]; i++) { JoinMethodHint *hint = hstate->join_hints[i]; if (!hint_state_enabled(hint) || hint->nrels > nbaserel) continue; hint->joinrelids = create_bms_of_relids(&(hint->base), root, initial_rels, hint->nrels, hint->relnames); if (hint->joinrelids == NULL || hint->base.state == HINT_STATE_ERROR) continue; hstate->join_hint_level[hint->nrels] = lappend(hstate->join_hint_level[hint->nrels], hint); } /* ditto for memoize hints */ for (i = 0; i < hstate->num_hints[HINT_TYPE_MEMOIZE]; i++) { JoinMethodHint *hint = hstate->join_hints[i]; if (!hint_state_enabled(hint) || hint->nrels > nbaserel) continue; hint->joinrelids = create_bms_of_relids(&(hint->base), root, initial_rels, hint->nrels, hint->relnames); if (hint->joinrelids == NULL || hint->base.state == HINT_STATE_ERROR) continue; hstate->memoize_hint_level[hint->nrels] = lappend(hstate->memoize_hint_level[hint->nrels], hint); } /* * Create bitmap of relids from alias names for each rows hint. * Bitmaps are more handy than strings in join searching. */ for (i = 0; i < hstate->num_hints[HINT_TYPE_ROWS]; i++) { RowsHint *hint = hstate->rows_hints[i]; if (!hint_state_enabled(hint) || hint->nrels > nbaserel) continue; hint->joinrelids = create_bms_of_relids(&(hint->base), root, initial_rels, hint->nrels, hint->relnames); } /* Do nothing if no Leading hint was supplied. */ if (hstate->num_hints[HINT_TYPE_LEADING] == 0) return false; /* * Decide whether to use Leading hint */ for (i = 0; i < hstate->num_hints[HINT_TYPE_LEADING]; i++) { LeadingHint *leading_hint = (LeadingHint *)hstate->leading_hint[i]; Relids relids; if (leading_hint->base.state == HINT_STATE_ERROR) continue; relid = 0; relids = NULL; foreach(l, leading_hint->relations) { relname = (char *)lfirst(l);; relid = find_relid_aliasname(root, relname, initial_rels, leading_hint->base.hint_str); if (relid == -1) leading_hint->base.state = HINT_STATE_ERROR; if (relid <= 0) break; if (bms_is_member(relid, relids)) { hint_ereport(leading_hint->base.hint_str, ("Relation name \"%s\" is duplicated.", relname)); leading_hint->base.state = HINT_STATE_ERROR; break; } relids = bms_add_member(relids, relid); } if (relid <= 0 || leading_hint->base.state == HINT_STATE_ERROR) continue; if (lhint != NULL) { hint_ereport(lhint->base.hint_str, ("Conflict %s hint.", HintTypeName[lhint->base.type])); lhint->base.state = HINT_STATE_DUPLICATION; } leading_hint->base.state = HINT_STATE_USED; lhint = leading_hint; } /* check to exist Leading hint marked with 'used'. */ if (lhint == NULL) return false; /* * We need join method hints which fit specified join order in every join * level. For example, Leading(A B C) virtually requires following join * method hints, if no join method hint supplied: * - level 1: none * - level 2: NestLoop(A B), MergeJoin(A B), HashJoin(A B) * - level 3: NestLoop(A B C), MergeJoin(A B C), HashJoin(A B C) * * If we already have join method hint which fits specified join order in * that join level, we leave it as-is and don't add new hints. */ joinrelids = NULL; njoinrels = 0; if (lhint->outer_inner == NULL) { foreach(l, lhint->relations) { JoinMethodHint *hint; relname = (char *)lfirst(l); /* * Find relid of the relation which has given name. If we have the * name given in Leading hint multiple times in the join, nothing to * do. */ relid = find_relid_aliasname(root, relname, initial_rels, hstate->hint_str); /* Create bitmap of relids for current join level. */ joinrelids = bms_add_member(joinrelids, relid); njoinrels++; /* We never have join method hint for single relation. */ if (njoinrels < 2) continue; /* * If we don't have join method hint, create new one for the * join combination with all join methods are enabled. */ hint = find_join_hint(joinrelids); if (hint == NULL) { /* * Here relnames is not set, since Relids bitmap is sufficient * to control paths of this query afterward. */ hint = (JoinMethodHint *) JoinMethodHintCreate( lhint->base.hint_str, HINT_LEADING, HINT_KEYWORD_LEADING); hint->base.state = HINT_STATE_USED; hint->nrels = njoinrels; hint->enforce_mask = ENABLE_ALL_JOIN; hint->joinrelids = bms_copy(joinrelids); } join_method_hints[njoinrels] = hint; if (njoinrels >= nbaserel) break; } bms_free(joinrelids); if (njoinrels < 2) return false; /* * Delete all join hints which have different combination from Leading * hint. */ for (i = 2; i <= njoinrels; i++) { list_free(hstate->join_hint_level[i]); hstate->join_hint_level[i] = lappend(NIL, join_method_hints[i]); } } else { joinrelids = OuterInnerJoinCreate(lhint->outer_inner, lhint, root, initial_rels, hstate, nbaserel); njoinrels = bms_num_members(joinrelids); Assert(njoinrels >= 2); /* * Delete all join hints which have different combination from Leading * hint. */ for (i = 2;i <= njoinrels; i++) { if (hstate->join_hint_level[i] != NIL) { foreach (l, hstate->join_hint_level[i]) { JoinMethodHint *hint = (JoinMethodHint *)lfirst(l); if (hint->inner_nrels == 0 && !(bms_intersect(hint->joinrelids, joinrelids) == NULL || bms_equal(bms_union(hint->joinrelids, joinrelids), hint->joinrelids))) { hstate->join_hint_level[i] = foreach_delete_current(hstate->join_hint_level[i], l); } } } } bms_free(joinrelids); } if (hint_state_enabled(lhint)) { set_join_config_options(DISABLE_ALL_JOIN, false, current_hint_state->context); return true; } return false; } /* * wrapper of make_join_rel() * * call make_join_rel() after changing enable_* parameters according to given * hints. */ static RelOptInfo * make_join_rel_wrapper(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2) { Relids joinrelids; JoinMethodHint *join_hint; JoinMethodHint *memoize_hint; RelOptInfo *rel; int save_nestlevel; joinrelids = bms_union(rel1->relids, rel2->relids); /* * joinrelids may include outer-join relids since PostgreSQL 16, so * filter them out as hints can only handle base relations. */ joinrelids = bms_intersect(joinrelids, root->all_baserels); join_hint = find_join_hint(joinrelids); memoize_hint = find_memoize_hint(joinrelids); bms_free(joinrelids); /* reject non-matching hints */ if (join_hint && join_hint->inner_nrels != 0) join_hint = NULL; if (memoize_hint && memoize_hint->inner_nrels != 0) memoize_hint = NULL; if (join_hint || memoize_hint) { save_nestlevel = NewGUCNestLevel(); if (join_hint) set_join_config_options(join_hint->enforce_mask, false, current_hint_state->context); if (memoize_hint) { bool memoize = memoize_hint->base.hint_keyword == HINT_KEYWORD_MEMOIZE; set_config_option_noerror("enable_memoize", memoize ? "true" : "false", current_hint_state->context, PGC_S_SESSION, GUC_ACTION_SAVE, true, ERROR); } } /* do the work */ rel = pg_hint_plan_make_join_rel(root, rel1, rel2); /* Restore the GUC variables we set above. */ if (join_hint || memoize_hint) { if (join_hint) join_hint->base.state = HINT_STATE_USED; if (memoize_hint) memoize_hint->base.state = HINT_STATE_USED; AtEOXact_GUC(true, save_nestlevel); } return rel; } /* * TODO : comment */ static void add_paths_to_joinrel_wrapper(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, SpecialJoinInfo *sjinfo, List *restrictlist) { Relids joinrelids; JoinMethodHint *join_hint; JoinMethodHint *memoize_hint; int save_nestlevel; joinrelids = bms_union(outerrel->relids, innerrel->relids); /* * joinrelids may include outer-join relids since PostgreSQL 16, so * filter them out as hints can only handle base relations. */ joinrelids = bms_intersect(joinrelids, root->all_baserels); join_hint = find_join_hint(joinrelids); memoize_hint = find_memoize_hint(joinrelids); bms_free(joinrelids); /* reject the found hints if they don't match this join */ if (join_hint && join_hint->inner_nrels == 0) join_hint = NULL; if (memoize_hint && memoize_hint->inner_nrels == 0) memoize_hint = NULL; /* set up configuration if needed */ if (join_hint || memoize_hint) { save_nestlevel = NewGUCNestLevel(); if (join_hint) { if (bms_equal(join_hint->inner_joinrelids, innerrel->relids)) set_join_config_options(join_hint->enforce_mask, false, current_hint_state->context); else set_join_config_options(DISABLE_ALL_JOIN, false, current_hint_state->context); } if (memoize_hint) { bool memoize = memoize_hint->base.hint_keyword == HINT_KEYWORD_MEMOIZE; set_config_option_noerror("enable_memoize", memoize ? "true" : "false", current_hint_state->context, PGC_S_SESSION, GUC_ACTION_SAVE, true, ERROR); } } /* generate paths */ add_paths_to_joinrel(root, joinrel, outerrel, innerrel, jointype, sjinfo, restrictlist); /* restore GUC variables */ if (join_hint || memoize_hint) { if (join_hint) join_hint->base.state = HINT_STATE_USED; if (memoize_hint) memoize_hint->base.state = HINT_STATE_USED; AtEOXact_GUC(true, save_nestlevel); } } static int get_num_baserels(List *initial_rels) { int nbaserel = 0; ListCell *l; foreach(l, initial_rels) { RelOptInfo *rel = (RelOptInfo *) lfirst(l); if (rel->reloptkind == RELOPT_BASEREL) nbaserel++; else if (rel->reloptkind ==RELOPT_JOINREL) nbaserel+= bms_num_members(rel->relids); else { /* other values not expected here */ elog(ERROR, "unrecognized reloptkind type: %d", rel->reloptkind); } } return nbaserel; } static RelOptInfo * pg_hint_plan_join_search(PlannerInfo *root, int levels_needed, List *initial_rels) { JoinMethodHint **join_method_hints; int nbaserel; RelOptInfo *rel; int i; bool leading_hint_enable; /* * Use standard planner (or geqo planner) if pg_hint_plan is disabled or no * valid hint is supplied or current nesting depth is nesting depth of SPI * calls. */ if (!current_hint_state || hint_inhibit_level > 0) { if (prev_join_search) return (*prev_join_search) (root, levels_needed, initial_rels); else if (enable_geqo && levels_needed >= geqo_threshold) return geqo(root, levels_needed, initial_rels); else return standard_join_search(root, levels_needed, initial_rels); } /* * In the case using GEQO, only scan method hints and Set hints have * effect. Join method and join order is not controllable by hints. */ if (enable_geqo && levels_needed >= geqo_threshold) return geqo(root, levels_needed, initial_rels); nbaserel = get_num_baserels(initial_rels); current_hint_state->join_hint_level = palloc0(sizeof(List *) * (nbaserel + 1)); join_method_hints = palloc0(sizeof(JoinMethodHint *) * (nbaserel + 1)); current_hint_state->memoize_hint_level = palloc0(sizeof(List *) * (nbaserel + 1)); leading_hint_enable = transform_join_hints(current_hint_state, root, nbaserel, initial_rels, join_method_hints); rel = pg_hint_plan_standard_join_search(root, levels_needed, initial_rels); /* * Adjust number of parallel workers of the result rel to the largest * number of the component paths. */ if (current_hint_state->num_hints[HINT_TYPE_PARALLEL] > 0) { ListCell *lc; int nworkers = 0; foreach (lc, initial_rels) { ListCell *lcp; RelOptInfo *initrel = (RelOptInfo *) lfirst(lc); foreach (lcp, initrel->partial_pathlist) { Path *path = (Path *) lfirst(lcp); if (nworkers < path-> parallel_workers) nworkers = path-> parallel_workers; } } foreach (lc, rel->partial_pathlist) { Path *path = (Path *) lfirst(lc); if (path->parallel_safe && path->parallel_workers < nworkers) path->parallel_workers = nworkers; } } for (i = 2; i <= nbaserel; i++) { list_free(current_hint_state->join_hint_level[i]); /* free Leading hint only */ if (join_method_hints[i] != NULL && join_method_hints[i]->enforce_mask == ENABLE_ALL_JOIN) JoinMethodHintDelete(join_method_hints[i]); } pfree(current_hint_state->join_hint_level); pfree(join_method_hints); if (leading_hint_enable) set_join_config_options(current_hint_state->init_join_mask, true, current_hint_state->context); return rel; } /* * Force number of wokers if instructed by hint */ void pg_hint_plan_set_rel_pathlist(PlannerInfo * root, RelOptInfo *rel, Index rti, RangeTblEntry *rte) { ParallelHint *phint; ListCell *l; int found_hints; /* call the previous hook */ if (prev_set_rel_pathlist) prev_set_rel_pathlist(root, rel, rti, rte); /* Nothing to do if no hint available */ if (current_hint_state == NULL) return; /* Don't touch dummy rels. */ if (IS_DUMMY_REL(rel)) return; /* * We can accept only plain relations, foreign tables and table saples are * also unacceptable. See set_rel_pathlist. */ if ((rel->rtekind != RTE_RELATION && rel->rtekind != RTE_SUBQUERY)|| rte->relkind == RELKIND_FOREIGN_TABLE || rte->tablesample != NULL) return; /* * Even though UNION ALL node doesn't have particular name so usually it is * unhintable, turn on parallel when it contains parallel nodes. */ if (rel->rtekind == RTE_SUBQUERY) { ListCell *lc; bool inhibit_nonparallel = false; if (rel->partial_pathlist == NIL) return; foreach(lc, rel->partial_pathlist) { ListCell *lcp; Node *path = (Node *) lfirst(lc); AppendPath *apath; int parallel_workers = 0; if (!IsA(path, AppendPath)) continue; apath = (AppendPath *) path; foreach (lcp, apath->subpaths) { Path *spath = (Path *) lfirst(lcp); if (spath->parallel_aware && parallel_workers < spath->parallel_workers) parallel_workers = spath->parallel_workers; } apath->path.parallel_workers = parallel_workers; inhibit_nonparallel = true; } if (inhibit_nonparallel) { ListCell *lcr; foreach(lcr, rel->pathlist) { Path *path = (Path *) lfirst(lcr); if (path->startup_cost < disable_cost) { path->startup_cost += disable_cost; path->total_cost += disable_cost; } } } return; } /* We cannot handle if this requires an outer */ if (rel->lateral_relids) return; /* Return if this relation gets no enfocement */ if ((found_hints = setup_hint_enforcement(root, rel, NULL, &phint)) == 0) return; /* Here, we regenerate paths with the current hint restriction */ if (found_hints & HINT_BM_SCAN_METHOD || found_hints & HINT_BM_PARALLEL) { /* * When hint is specified on non-parent relations, discard existing * paths and regenerate based on the hint considered. Otherwise we * already have hinted childx paths then just adjust the number of * planned number of workers. */ if (root->simple_rte_array[rel->relid]->inh) { /* enforce number of workers if requested */ if (phint && phint->force_parallel) { if (phint->nworkers == 0) { list_free_deep(rel->partial_pathlist); rel->partial_pathlist = NIL; } else { /* prioritize partial paths */ foreach (l, rel->partial_pathlist) { Path *ppath = (Path *) lfirst(l); if (ppath->parallel_safe) { ppath->parallel_workers = phint->nworkers; ppath->startup_cost = 0; ppath->total_cost = 0; } } /* disable non-partial paths */ foreach (l, rel->pathlist) { Path *ppath = (Path *) lfirst(l); if (ppath->startup_cost < disable_cost) { ppath->startup_cost += disable_cost; ppath->total_cost += disable_cost; } } } } } else { /* Just discard all the paths considered so far */ list_free_deep(rel->pathlist); rel->pathlist = NIL; list_free_deep(rel->partial_pathlist); rel->partial_pathlist = NIL; /* Regenerate paths with the current enforcement */ set_plain_rel_pathlist(root, rel, rte); /* Additional work to enforce parallel query execution */ if (phint && phint->nworkers > 0) { /* * For Parallel Append to be planned properly, we shouldn't set * the costs of non-partial paths to disable-value. Lower the * priority of non-parallel paths by setting partial path costs * to 0 instead. */ foreach (l, rel->partial_pathlist) { Path *path = (Path *) lfirst(l); path->startup_cost = 0; path->total_cost = 0; } /* enforce number of workers if requested */ if (phint->force_parallel) { foreach (l, rel->partial_pathlist) { Path *ppath = (Path *) lfirst(l); if (ppath->parallel_safe) ppath->parallel_workers = phint->nworkers; } } /* * Generate gather paths. However, if this is an inheritance * child, skip it. */ if (rel->reloptkind == RELOPT_BASEREL && !bms_equal(rel->relids, root->all_baserels)) generate_useful_gather_paths(root, rel, false); } } } reset_hint_enforcement(); } /* include core static functions */ static void populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, RelOptInfo *joinrel, SpecialJoinInfo *sjinfo, List *restrictlist); #define standard_join_search pg_hint_plan_standard_join_search #define join_search_one_level pg_hint_plan_join_search_one_level #define make_join_rel make_join_rel_wrapper #include "core.c" #undef make_join_rel #define make_join_rel pg_hint_plan_make_join_rel #define add_paths_to_joinrel add_paths_to_joinrel_wrapper #include "make_join_rel.c" pg_hint_plan-REL17_1_7_0/pg_hint_plan.control000066400000000000000000000002061466301071500212420ustar00rootroot00000000000000# pg_hint_plan extension comment = 'optimizer hints for PostgreSQL' default_version = '1.7.0' relocatable = false schema = hint_plan pg_hint_plan-REL17_1_7_0/query_scan.h000066400000000000000000000024001466301071500175160ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * query_scan.h * lexical scanner for SQL commands * * This lexer can be used to extra hints from query contents, taking into * account what the backend would consider as values, for example. * * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * query_scan.h * *------------------------------------------------------------------------- */ #ifndef QUERY_SCAN_H #define QUERY_SCAN_H #include "lib/stringinfo.h" /* Abstract type for lexer's internal state */ typedef struct QueryScanStateData *QueryScanState; /* Termination states for query_scan() */ typedef enum { QUERY_SCAN_INCOMPLETE, /* end of line, SQL statement incomplete */ QUERY_SCAN_EOL /* end of line, SQL possibly complete */ } QueryScanResult; extern QueryScanState query_scan_create(void); extern void query_scan_setup(QueryScanState state, const char *line, int line_len, int encoding, bool std_strings, int elevel); extern void query_scan_finish(QueryScanState state); extern QueryScanResult query_scan(QueryScanState state, StringInfo query_buf); #endif /* QUERY_SCAN_H */ pg_hint_plan-REL17_1_7_0/query_scan.l000066400000000000000000000725731466301071500175440ustar00rootroot00000000000000%top{ /*------------------------------------------------------------------------- * * query_scan.l * lexical scanner for SQL commands * * This code is mainly concerned with determining where query hints are * located and where the end of a SQL statement is: we are looking for * semicolons that are not within quotes, comments, or parentheses. * The most reliable way to handle this is to borrow the backend's flex * lexer rules, lock, stock, and barrel. The rules below are (except for * a few) the same as the backend's, but their actions are just ECHO * whereas the backend's actions generally do other things. * * XXX The rules in this file must be kept in sync with the backend lexer!!! * * XXX Avoid creating backtracking cases --- see the backend lexer for info. * * See query_scan_int.h for additional details. * * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION * query_scan.l * *------------------------------------------------------------------------- */ #include "postgres.h" #include "query_scan.h" #include "mb/pg_wchar.h" #include "query_scan_int.h" } %{ /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ #undef fprintf #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) static void fprintf_to_ereport(const char *fmt, const char *msg) { ereport(ERROR, (errmsg_internal("%s", msg))); } /* * We must have a typedef YYSTYPE for yylex's first argument, but this lexer * doesn't presently make use of that argument, so just declare it as int. */ typedef int YYSTYPE; /* * Set the type of yyextra; we use it as a pointer back to the containing * QueryScanState. */ #define YY_EXTRA_TYPE QueryScanState /* Return values from yylex() */ #define LEXRES_EOL 0 /* end of input */ #define ECHO query_scan_emit(cur_state, yytext, yyleng) %} %option reentrant %option bison-bridge %option 8bit %option never-interactive %option nodefault %option noinput %option nounput %option noyywrap %option warn %option prefix="query_yy" /* * All of the following definitions and rules should exactly match with * upstream PostgreSQL's src/backend/parser/scan.l so far as the flex * patterns are concerned. The rule bodies are just ECHO as opposed to what * the backend does, however. (But be sure to duplicate code that affects * the lexing process, such as BEGIN() and yyless().) */ /* * OK, here is a short description of lex/flex rules behavior. * The longest pattern which matches an input string is always chosen. * For equal-length patterns, the first occurring in the rules list is chosen. * INITIAL is the starting state, to which all non-conditional rules apply. * Exclusive states change parsing rules while the state is active. When in * an exclusive state, only those rules defined for that state apply. * * We use exclusive states for quoted strings, extended comments, * and to eliminate parsing troubles for numeric strings. * Exclusive states: * bit string literal * extended C-style comments * delimited identifiers (double-quoted identifiers) * hexadecimal byte string * Query hints as C-style comments * standard quoted strings * quote stop (detect continued strings) * extended quoted strings (support backslash escape sequences) * $foo$ quoted strings * quoted identifier with Unicode escapes * quoted string with Unicode escapes * * Note: we intentionally don't mimic the backend's state; we have * no need to distinguish it from state, and no good way to get out * of it in error cases. The backend just throws yyerror() in those * cases, but that's not an option here. */ %x xb %x xc %x xd %x xh %x xhint %x xq %x xqs %x xe %x xdolq %x xui %x xus /* * In order to make the world safe for Windows and Mac clients as well as * Unix ones, we accept either \n or \r as a newline. A DOS-style \r\n * sequence will be seen as two successive newlines, but that doesn't cause * any problems. Comments that start with -- and extend to the next * newline are treated as equivalent to a single whitespace character. * * NOTE a fine point: if there is no newline following --, we will absorb * everything to the end of the input as a comment. This is correct. Older * versions of Postgres failed to recognize -- as a comment if the input * did not end with a newline. * * non_newline_space tracks all the other space characters except newlines. * * XXX if you change the set of whitespace characters, fix scanner_isspace() * to agree. */ space [ \t\n\r\f\v] non_newline_space [ \t\f\v] newline [\n\r] non_newline [^\n\r] comment ("--"{non_newline}*) whitespace ({space}+|{comment}) /* * SQL requires at least one newline in the whitespace separating * string literals that are to be concatenated. Silly, but who are we * to argue? Note that {whitespace_with_newline} should not have * after * it, whereas {whitespace} should generally have a * after it... */ special_whitespace ({space}+|{comment}{newline}) non_newline_whitespace ({non_newline_space}|{comment}) whitespace_with_newline ({non_newline_whitespace}*{newline}{special_whitespace}*) quote ' /* If we see {quote} then {quotecontinue}, the quoted string continues */ quotecontinue {whitespace_with_newline}{quote} /* * {quotecontinuefail} is needed to avoid lexer backup when we fail to match * {quotecontinue}. It might seem that this could just be {whitespace}*, * but if there's a dash after {whitespace_with_newline}, it must be consumed * to see if there's another dash --- which would start a {comment} and thus * allow continuation of the {quotecontinue} token. */ quotecontinuefail {whitespace}*"-"? /* Bit string * It is tempting to scan the string for only those characters * which are allowed. However, this leads to silently swallowed * characters if illegal characters are included in the string. * For example, if xbinside is [01] then B'ABCD' is interpreted * as a zero-length string, and the ABCD' is lost! * Better to pass the string forward and let the input routines * validate the contents. */ xbstart [bB]{quote} xbinside [^']* /* Hexadecimal byte string */ xhstart [xX]{quote} xhinside [^']* /* National character */ xnstart [nN]{quote} /* Quoted string that allows backslash escapes */ xestart [eE]{quote} xeinside [^\\']+ xeescape [\\][^0-7] xeoctesc [\\][0-7]{1,3} xehexesc [\\]x[0-9A-Fa-f]{1,2} xeunicode [\\](u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8}) xeunicodefail [\\](u[0-9A-Fa-f]{0,3}|U[0-9A-Fa-f]{0,7}) /* Extended quote * xqdouble implements embedded quote, '''' */ xqstart {quote} xqdouble {quote}{quote} xqinside [^']+ /* $foo$ style quotes ("dollar quoting") * The quoted string starts with $foo$ where "foo" is an optional string * in the form of an identifier, except that it may not contain "$", * and extends to the first occurrence of an identical string. * There is *no* processing of the quoted text. * * {dolqfailed} is an error rule to avoid scanner backup when {dolqdelim} * fails to match its trailing "$". */ dolq_start [A-Za-z\200-\377_] dolq_cont [A-Za-z\200-\377_0-9] dolqdelim \$({dolq_start}{dolq_cont}*)?\$ dolqfailed \${dolq_start}{dolq_cont}* dolqinside [^$]+ /* Double quote * Allows embedded spaces and other special characters into identifiers. */ dquote \" xdstart {dquote} xdstop {dquote} xddouble {dquote}{dquote} xdinside [^"]+ /* Quoted identifier with Unicode escapes */ xuistart [uU]&{dquote} /* Quoted string with Unicode escapes */ xusstart [uU]&{quote} /* error rule to avoid backup */ xufailed [uU]& /* * Query hints as C-style comments * * This should take priority to C-style comments, while the inside and end * can match the rules cited below. */ xhintstart \/\*\+ /* C-style comments * * The "extended comment" syntax closely resembles allowable operator syntax. * The tricky part here is to get lex to recognize a string starting with * slash-star as a comment, when interpreting it as an operator would produce * a longer match --- remember lex will prefer a longer match! Also, if we * have something like plus-slash-star, lex will think this is a 3-character * operator whereas we want to see it as a + operator and a comment start. * The solution is two-fold: * 1. append {op_chars}* to xcstart so that it matches as much text as * {operator} would. Then the tie-breaker (first matching rule of same * length) ensures xcstart wins. We put back the extra stuff with yyless() * in case it contains a star-slash that should terminate the comment. * 2. In the operator rule, check for slash-star within the operator, and * if found throw it back with yyless(). This handles the plus-slash-star * problem. * Dash-dash comments have similar interactions with the operator rule. */ xcstart \/\*{op_chars}* xcstop \*+\/ xcinside [^*/]+ ident_start [A-Za-z\200-\377_] ident_cont [A-Za-z\200-\377_0-9\$] identifier {ident_start}{ident_cont}* /* Assorted special-case operators and operator-like tokens */ typecast "::" dot_dot \.\. colon_equals ":=" /* * These operator-like tokens (unlike the above ones) also match the {operator} * rule, which means that they might be overridden by a longer match if they * are followed by a comment start or a + or - character. Accordingly, if you * add to this list, you must also add corresponding code to the {operator} * block to return the correct token in such cases. (This is not needed in * query_scan.l since the token value is ignored there.) */ equals_greater "=>" less_equals "<=" greater_equals ">=" less_greater "<>" not_equals "!=" /* * "self" is the set of chars that should be returned as single-character * tokens. "op_chars" is the set of chars that can make up "Op" tokens, * which can be one or more characters long (but if a single-char token * appears in the "self" set, it is not to be returned as an Op). Note * that the sets overlap, but each has some chars that are not in the other. * * If you change either set, adjust the character lists appearing in the * rule for "operator"! */ self [,()\[\].;\:\+\-\*\/\%\^\<\>\=] op_chars [\~\!\@\#\^\&\|\`\?\+\-\*\/\%\<\>\=] operator {op_chars}+ /* * Numbers * * Unary minus is not part of a number here. Instead we pass it separately to * the parser, and there it gets coerced via doNegate(). * * {numericfail} is used because we would like "1..10" to lex as 1, dot_dot, 10. * * {realfail} is added to prevent the need for scanner * backup when the {real} rule fails to match completely. */ decdigit [0-9] hexdigit [0-9A-Fa-f] octdigit [0-7] bindigit [0-1] decinteger {decdigit}(_?{decdigit})* hexinteger 0[xX](_?{hexdigit})+ octinteger 0[oO](_?{octdigit})+ bininteger 0[bB](_?{bindigit})+ hexfail 0[xX]_? octfail 0[oO]_? binfail 0[bB]_? numeric (({decinteger}\.{decinteger}?)|(\.{decinteger})) numericfail {decdigit}+\.\. real ({decinteger}|{numeric})[Ee][-+]?{decinteger} realfail ({decinteger}|{numeric})[Ee][-+] decinteger_junk {decinteger}{ident_start} hexinteger_junk {hexinteger}{ident_start} octinteger_junk {octinteger}{ident_start} bininteger_junk {bininteger}{ident_start} numeric_junk {numeric}{ident_start} real_junk {real}{ident_start} /* Positional parameters don't accept underscores. */ param \${decdigit}+ param_junk \${decdigit}+{ident_start} other . /* * Dollar quoted strings are totally opaque, and no escaping is done on them. * Other quoted strings must allow some special characters such as single-quote * and newline. * Embedded single-quotes are implemented both in the SQL standard * style of two adjacent single quotes "''" and in the Postgres/Java style * of escaped-quote "\'". * Other embedded escaped characters are matched explicitly and the leading * backslash is dropped from the string. * Note that xcstart must appear before operator, as explained above! * Also whitespace (comment) must appear before operator. */ %% %{ /* Declare some local variables inside yylex(), for convenience */ QueryScanState cur_state = yyextra; /* * Force flex into the state indicated by start_state. This has a * couple of purposes: it lets some of the functions below set a new * starting state without ugly direct access to flex variables, and it * allows us to transition from one flex lexer to another so that we * can lex different parts of the source string using separate lexers. */ BEGIN(cur_state->start_state); %} {whitespace} { /* * Note that the whitespace rule includes both true * whitespace and single-line ("--" style) comments. * We suppress whitespace until we have collected some * non-whitespace data. (This interacts with some * decisions in MainLoop(); see there for details.) */ } {xhintstart} { /* Fail hard if there are more than one hint */ if (cur_state->xhintnum > 0) query_yyerror(ERROR, yytext, "Multiple hints are not supported.");\ /* * Increment the hint counter as well as the comment * to be able to correctly ignore the contents in * nested contents. */ (cur_state->xhintnum)++; (cur_state->xcdepth)++; /* Put back any characters past slash-star-plus; see above */ yyless(3); BEGIN(xhint); } { {xcstart} { (cur_state->xcdepth)++; query_yyerror(cur_state->elevel, yytext, "Nested block comments are not supported."); /* Put back any characters past slash-star; see above */ yyless(2); } {xcinside} { /* * Print the contents of the hint into the output buffer. * Ignore if we are in a comment. */ if (cur_state->xcdepth == 1) ECHO; } {xcstop} { if (cur_state->xcdepth > 0) (cur_state->xcdepth)--; if (cur_state->xcdepth <= 0) BEGIN(INITIAL); } {op_chars} { /* Special set of characters that can be authorized in hints */ if (cur_state->xcdepth == 1) ECHO; } \*+ { /* Special character that can be authorized in hints */ if (cur_state->xcdepth == 1) ECHO; } } /* */ {xcstart} { cur_state->xcdepth = 0; BEGIN(xc); /* Put back any characters past slash-star; see above */ yyless(2); /* ignore */ } { {xcstart} { (cur_state->xcdepth)++; BEGIN(xc); /* Put back any characters past slash-star; see above */ yyless(2); /* ignore */ } {xcstop} { if (cur_state->xcdepth <= 0) BEGIN(INITIAL); else (cur_state->xcdepth)--; /* ignore */ } {xcinside} { /* ignore */ } {op_chars} { /* ignore */ } \*+ { /* ignore */ } } /* */ {xbstart} { BEGIN(xb); /* ignore */ } {xhinside} | {xbinside} { /* ignore */ } {xhstart} { /* Hexadecimal bit type. * At some point we should simply pass the string * forward to the parser and label it there. * In the meantime, place a leading "x" on the string * to mark it for the input routine as a hex string. */ BEGIN(xh); /* ignore */ } {xnstart} { yyless(1); /* eat only 'n' this time */ /* ignore */ } {xqstart} { if (cur_state->std_strings) BEGIN(xq); else BEGIN(xe); /* ignore */ } {xestart} { BEGIN(xe); /* ignore */ } {xusstart} { BEGIN(xus); /* ignore */ } {quote} { /* * When we are scanning a quoted string and see an end * quote, we must look ahead for a possible continuation. * If we don't see one, we know the end quote was in fact * the end of the string. To reduce the lexer table size, * we use a single "xqs" state to do the lookahead for all * types of strings. */ cur_state->state_before_str_stop = YYSTATE; BEGIN(xqs); /* ignore */ } {quotecontinue} { /* * Found a quote continuation, so return to the in-quote * state and continue scanning the literal. Nothing is * added to the literal's contents. */ BEGIN(cur_state->state_before_str_stop); /* ignore */ } {quotecontinuefail} | {other} { /* * Failed to see a quote continuation. Throw back * everything after the end quote, and handle the string * according to the state we were in previously. */ yyless(0); BEGIN(INITIAL); /* There's nothing to echo ... */ } {xqdouble} { /* ignore */ } {xqinside} { /* ignore */ } {xeinside} { /* ignore */ } {xeunicode} { /* ignore */ } {xeunicodefail} { /* ignore */ } {xeescape} { /* ignore */ } {xeoctesc} { /* ignore */ } {xehexesc} { /* ignore */ } . { /* This is only needed for \ just before EOF */ /* ignore */ } {dolqdelim} { cur_state->dolqstart = pstrdup(yytext); BEGIN(xdolq); /* ignore */ } {dolqfailed} { /* throw back all but the initial "$" */ yyless(1); /* ignore */ } {dolqdelim} { if (strcmp(yytext, cur_state->dolqstart) == 0) { pfree(cur_state->dolqstart); cur_state->dolqstart = NULL; BEGIN(INITIAL); } else { /* * When we fail to match $...$ to dolqstart, transfer * the $... part to the output, but put back the final * $ for rescanning. Consider $delim$...$junk$delim$ */ yyless(yyleng - 1); } /* ignore */ } {dolqinside} { /* ignore */ } {dolqfailed} { /* ignore */ } . { /* This is only needed for $ inside the quoted text */ /* ignore */ } {xdstart} { BEGIN(xd); /* ignore */ } {xuistart} { BEGIN(xui); /* ignore */ } {xdstop} { BEGIN(INITIAL); /* ignore */ } {dquote} { BEGIN(INITIAL); /* ignore */ } {xddouble} { /* ignore */ } {xdinside} { /* ignore */ } {xufailed} { /* throw back all but the initial u/U */ yyless(1); /* ignore */ } {typecast} { /* ignore */ } {dot_dot} { /* ignore */ } {colon_equals} { /* ignore */ } {equals_greater} { /* ignore */ } {less_equals} { /* ignore */ } {greater_equals} { /* ignore */ } {less_greater} { /* ignore */ } {not_equals} { /* ignore */ } {self} { /* ignore */ } {operator} { /* * Check for embedded slash-star or dash-dash; those * are comment starts, so operator must stop there. * Note that slash-star or dash-dash at the first * character will match a prior rule, not this one. */ int nchars = yyleng; char *slashstar = strstr(yytext, "/*"); char *dashdash = strstr(yytext, "--"); if (slashstar && dashdash) { /* if both appear, take the first one */ if (slashstar > dashdash) slashstar = dashdash; } else if (!slashstar) slashstar = dashdash; if (slashstar) nchars = slashstar - yytext; /* * For SQL compatibility, '+' and '-' cannot be the * last char of a multi-char operator unless the operator * contains chars that are not in SQL operators. * The idea is to lex '=-' as two operators, but not * to forbid operator names like '?-' that could not be * sequences of SQL operators. */ if (nchars > 1 && (yytext[nchars - 1] == '+' || yytext[nchars - 1] == '-')) { int ic; for (ic = nchars - 2; ic >= 0; ic--) { char c = yytext[ic]; if (c == '~' || c == '!' || c == '@' || c == '#' || c == '^' || c == '&' || c == '|' || c == '`' || c == '?' || c == '%') break; } if (ic < 0) { /* * didn't find a qualifying character, so remove * all trailing [+-] */ do { nchars--; } while (nchars > 1 && (yytext[nchars - 1] == '+' || yytext[nchars - 1] == '-')); } } if (nchars < yyleng) { /* Strip the unwanted chars from the token */ yyless(nchars); } /* ignore */ } {param} { /* ignore */ } {param_junk} { /* ignore */ } {decinteger} { /* ignore */ } {hexinteger} { /* ignore */ } {octinteger} { /* ignore */ } {bininteger} { /* ignore */ } {hexfail} { /* ignore */ } {octfail} { /* ignore */ } {binfail} { /* ignore */ } {numeric} { /* ignore */ } {numericfail} { /* throw back the .., and treat as integer */ yyless(yyleng - 2); /* ignore */ } {real} { /* ignore */ } {realfail} { /* ignore */ } {decinteger_junk} { /* ignore */ } {hexinteger_junk} { /* ignore */ } {octinteger_junk} { /* ignore */ } {bininteger_junk} { /* ignore */ } {numeric_junk} { /* ignore */ } {real_junk} { /* ignore */ } {identifier} { /* * We need to track if we are inside a BEGIN .. END block * in a function definition, so that semicolons contained * therein don't terminate the whole statement. Short of * writing a full parser here, the following heuristic * should work. First, we track whether the beginning of * the statement matches CREATE [OR REPLACE] * {FUNCTION|PROCEDURE} */ if (cur_state->identifier_count == 0) memset(cur_state->identifiers, 0, sizeof(cur_state->identifiers)); if (pg_strcasecmp(yytext, "create") == 0 || pg_strcasecmp(yytext, "function") == 0 || pg_strcasecmp(yytext, "procedure") == 0 || pg_strcasecmp(yytext, "or") == 0 || pg_strcasecmp(yytext, "replace") == 0) { if (cur_state->identifier_count < sizeof(cur_state->identifiers)) cur_state->identifiers[cur_state->identifier_count] = pg_tolower((unsigned char) yytext[0]); } cur_state->identifier_count++; if (cur_state->identifiers[0] == 'c' && (cur_state->identifiers[1] == 'f' || cur_state->identifiers[1] == 'p' || (cur_state->identifiers[1] == 'o' && cur_state->identifiers[2] == 'r' && (cur_state->identifiers[3] == 'f' || cur_state->identifiers[3] == 'p'))) && cur_state->paren_depth == 0) { if (pg_strcasecmp(yytext, "begin") == 0) cur_state->begin_depth++; else if (pg_strcasecmp(yytext, "case") == 0) { /* * CASE also ends with END. We only need to track * this if we are already inside a BEGIN. */ if (cur_state->begin_depth >= 1) cur_state->begin_depth++; } else if (pg_strcasecmp(yytext, "end") == 0) { if (cur_state->begin_depth > 0) cur_state->begin_depth--; } } /* ignore */ } {other} { /* ignore */ } <> { cur_state->start_state = YY_START; return LEXRES_EOL; /* end of input reached */ } %% /* LCOV_EXCL_STOP */ /* * Create a lexer working state struct. */ QueryScanState query_scan_create(void) { QueryScanState state; state = (QueryScanStateData *) palloc0(sizeof(QueryScanStateData)); yylex_init(&state->scanner); yyset_extra(state, state->scanner); /* Set up various fields */ state->start_state = INITIAL; state->elevel = INFO; state->paren_depth = 0; state->xcdepth = 0; /* not really necessary */ state->xhintnum = 0; if (state->dolqstart) pfree(state->dolqstart); state->dolqstart = NULL; state->identifier_count = 0; state->begin_depth = 0; return state; } /* * Set up to perform lexing of the given input line. * * The text at *line, extending for line_len bytes, will be scanned by * subsequent calls to the query_scan routines. query_scan_finish should * be called when scanning is complete. Note that the lexer retains * a pointer to the storage at *line --- this string must not be altered * or freed until after query_scan_finish is called. * * encoding is the libpq identifier for the character encoding in use, * and std_strings says whether standard_conforming_strings is on. */ void query_scan_setup(QueryScanState state, const char *line, int line_len, int encoding, bool std_strings, int elevel) { /* Mustn't be scanning already */ Assert(state->scanbufhandle == NULL); /* elevel for reports */ state->elevel = elevel; /* Do we need to hack the character set encoding? */ state->encoding = encoding; state->safe_encoding = pg_valid_server_encoding_id(encoding); /* Save standard-strings flag as well */ state->std_strings = std_strings; /* Set up flex input buffer with appropriate translation and padding */ state->scanbufhandle = query_scan_prepare_buffer(state, line, line_len, &state->scanbuf); state->scanline = line; /* Set lookaside data in case we have to map unsafe encoding */ state->curline = state->scanbuf; state->refline = state->scanline; } /* * Do lexical analysis of SQL command text. * * The text previously passed to query_scan_setup is scanned, and appended * (possibly with transformation) to query_buf. * * The return value indicates the condition that stopped scanning: * * QUERY_SCAN_INCOMPLETE: the end of the line was reached, but we have an * incomplete SQL command. * * QUERY_SCAN_EOL: the end of the line was reached, and there is no lexical * reason to consider the command incomplete. The caller may or may not * choose to send it. * * In the QUERY_SCAN_INCOMPLETE and QUERY_SCAN_EOL cases, query_scan_finish() * should be called next, then the cycle may be repeated with a fresh input * line. */ QueryScanResult query_scan(QueryScanState state, StringInfo query_buf) { QueryScanResult result; int lexresult; /* Must be scanning already */ Assert(state->scanbufhandle != NULL); /* Set current output target */ state->output_buf = query_buf; yy_switch_to_buffer(state->scanbufhandle, state->scanner); /* And lex. */ lexresult = yylex(NULL, state->scanner); /* * Check termination state and return appropriate result info. */ switch (lexresult) { case LEXRES_EOL: /* end of input */ switch (state->start_state) { case INITIAL: case xqs: /* we treat this like INITIAL */ if (state->paren_depth > 0) { result = QUERY_SCAN_INCOMPLETE; } else if (state->begin_depth > 0) { result = QUERY_SCAN_INCOMPLETE; } else { /* the resulting query may be empty if there are no hints */ result = QUERY_SCAN_EOL; } break; case xb: case xc: case xd: case xh: case xhint: case xe: case xq: case xdolq: case xui: case xus: result = QUERY_SCAN_INCOMPLETE; break; default: /* can't get here */ elog(ERROR, "invalid YY_START"); } break; default: /* can't get here */ elog(ERROR, "invalid yylex result\n"); } return result; } /* * Clean up after scanning a string. This flushes any unread input and * releases resources (but not the QueryScanState itself). Note however * that this does not reset the lexer scan state. * * It is legal to call this when not scanning anything (makes it easier * to deal with error recovery). */ void query_scan_finish(QueryScanState state) { /* Done with the outer scan buffer, too */ if (state->scanbufhandle) yy_delete_buffer(state->scanbufhandle, state->scanner); state->scanbufhandle = NULL; if (state->scanbuf) pfree(state->scanbuf); state->scanbuf = NULL; yylex_destroy(state->scanner); pfree(state); } /* * Set up a flex input buffer to scan the given data. We always make a * copy of the data. If working in an unsafe encoding, the copy has * multibyte sequences replaced by FFs to avoid fooling the lexer rules. * * NOTE SIDE EFFECT: the new buffer is made the active flex input buffer. */ YY_BUFFER_STATE query_scan_prepare_buffer(QueryScanState state, const char *txt, int len, char **txtcopy) { char *newtxt; /* Flex wants two \0 characters after the actual data */ newtxt = palloc(len + 2); *txtcopy = newtxt; newtxt[len] = newtxt[len + 1] = YY_END_OF_BUFFER_CHAR; if (state->safe_encoding) memcpy(newtxt, txt, len); else { /* Gotta do it the hard way */ int i = 0; while (i < len) { int thislen = pg_encoding_mblen(state->encoding, txt + i); /* first byte should always be okay... */ newtxt[i] = txt[i]; i++; while (--thislen > 0 && i < len) newtxt[i++] = (char) 0xFF; } } return yy_scan_buffer(newtxt, len + 2, state->scanner); } void query_yyerror(int elevel, const char *txt, const char *message) { ereport(elevel, errmsg("pg_hint_plan: hint syntax error at or near \"%s\"", txt), errdetail("%s", message)); } /* * query_scan_emit() --- body for ECHO macro * * NB: this must be used for ALL and ONLY the text copied from the flex * input data. If you pass it something that is not part of the yytext * string, you are making a mistake. Internally generated text can be * appended directly to state->output_buf. */ void query_scan_emit(QueryScanState state, const char *txt, int len) { StringInfo output_buf = state->output_buf; if (state->safe_encoding) appendBinaryStringInfo(output_buf, txt, len); else { /* Gotta do it the hard way */ const char *reference = state->refline; int i; reference += (txt - state->curline); for (i = 0; i < len; i++) { char ch = txt[i]; if (ch == (char) 0xFF) ch = reference[i]; appendStringInfoChar(output_buf, ch); } } } pg_hint_plan-REL17_1_7_0/query_scan_int.h000066400000000000000000000120651466301071500204000ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * query_scan_int.h * lexical scanner internal declarations * * This file declares the QueryScanStateData structure used by query_scan.l. * * One difficult aspect of this code is that we need to work in multibyte * encodings that are not ASCII-safe. A "safe" encoding is one in which each * byte of a multibyte character has the high bit set (it's >= 0x80). Since * all our lexing rules treat all high-bit-set characters alike, we don't * really need to care whether such a byte is part of a sequence or not. * In an "unsafe" encoding, we still expect the first byte of a multibyte * sequence to be >= 0x80, but later bytes might not be. If we scan such * a sequence as-is, the lexing rules could easily be fooled into matching * such bytes to ordinary ASCII characters. Our solution for this is to * substitute 0xFF for each non-first byte within the data presented to flex. * The flex rules will then pass the FF's through unmolested. The * query_scan_emit() subroutine is responsible for looking back to the * original string and replacing FF's with the corresponding original bytes. * * Another interesting thing we do here is scan different parts of the same * input with physically separate flex lexers (ie, lexers written in separate * .l files). We can get away with this because the only part of the * persistent state of a flex lexer that depends on its parsing rule tables * is the start state number, which is easy enough to manage --- usually, * in fact, we just need to set it to INITIAL when changing lexers. But to * make that work at all, we must use re-entrant lexers, so that all the * relevant state is in the yyscan_t attached to the QueryScanState; * if we were using lexers with separate static state we would soon end up * with dangling buffer pointers in one or the other. Also note that this * is unlikely to work very nicely if the lexers aren't all built with the * same flex version, or if they don't use the same flex options. * * * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * query_scan_int.h * *------------------------------------------------------------------------- */ #ifndef QUERY_SCAN_INT_H #define QUERY_SCAN_INT_H #include "query_scan.h" /* * These are just to allow this file to be compilable standalone for header * validity checking; in actual use, this file should always be included * from the body of a flex file, where these symbols are already defined. */ #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void *yyscan_t; #endif /* * All working state of the lexer must be stored in QueryScanStateData * between calls. This allows us to have multiple open lexer operations, * which is needed for nested include files. The lexer itself is not * recursive, but it must be re-entrant. */ typedef struct QueryScanStateData { yyscan_t scanner; /* Flex's state for this QueryScanState */ StringInfo output_buf; /* current output buffer */ int elevel; /* level of reports generated at parsing */ /* * These variables always refer to the outer buffer, never to any stacked * variable-expansion buffer. */ YY_BUFFER_STATE scanbufhandle; char *scanbuf; /* start of outer-level input buffer */ const char *scanline; /* current input line at outer level */ /* safe_encoding, curline, refline are used by emit() to replace FFs */ int encoding; /* encoding being used now */ bool safe_encoding; /* is current encoding "safe"? */ bool std_strings; /* are string literals standard? */ const char *curline; /* actual flex input string for cur buf */ const char *refline; /* original data for cur buffer */ /* * All this state lives across successive input lines. start_state is * adopted by yylex() on entry, and updated with its finishing state on * exit. */ int start_state; /* yylex's starting/finishing state */ int state_before_str_stop; /* start cond. before end quote */ int paren_depth; /* depth of nesting in parentheses */ int xcdepth; /* depth of nesting in slash-star comments */ char *dolqstart; /* current $foo$ quote start string */ int xhintnum; /* number of query hints found */ /* * State to track boundaries of BEGIN ... END blocks in function * definitions, so that semicolons do not send query too early. */ int identifier_count; /* identifiers since start of statement */ char identifiers[4]; /* records the first few identifiers */ int begin_depth; /* depth of begin/end pairs */ } QueryScanStateData; extern YY_BUFFER_STATE query_scan_prepare_buffer(QueryScanState state, const char *txt, int len, char **txtcopy); extern void query_yyerror(int elevel, const char *txt, const char *message); extern void query_scan_emit(QueryScanState state, const char *txt, int len); #endif /* QUERY_SCAN_INT_H */ pg_hint_plan-REL17_1_7_0/sql/000077500000000000000000000000001466301071500157775ustar00rootroot00000000000000pg_hint_plan-REL17_1_7_0/sql/base_plan.sql000066400000000000000000000011241466301071500204420ustar00rootroot00000000000000SET search_path TO public; -- query type 1 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; -- query type 2 EXPLAIN (COSTS false) SELECT * FROM t1, t4 WHERE t1.val < 10; -- query type 3 EXPLAIN (COSTS false) SELECT * FROM t3, t4 WHERE t3.id = t4.id AND t4.ctid = '(1,1)'; -- query type 4 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)'; -- query type 5 EXPLAIN (COSTS false) SELECT * FROM t1, t3 WHERE t1.val = t3.val; -- query type 6 EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; pg_hint_plan-REL17_1_7_0/sql/hint_table.sql000066400000000000000000000006031466301071500206300ustar00rootroot00000000000000-- Tests for the hint table LOAD 'pg_hint_plan'; -- Attempting to use the hint table without the extension created -- emits a WARNING. SET pg_hint_plan.enable_hint_table TO on; SELECT 1; SET pg_hint_plan.enable_hint_table TO off; CREATE EXTENSION pg_hint_plan; SET pg_hint_plan.enable_hint_table TO on; SELECT 1; SET pg_hint_plan.enable_hint_table TO off; DROP EXTENSION pg_hint_plan; pg_hint_plan-REL17_1_7_0/sql/init.sql000066400000000000000000000174221466301071500174710ustar00rootroot00000000000000SET search_path TO public; CREATE EXTENSION pg_hint_plan; CREATE SCHEMA s0; CREATE TABLE t1 (id int PRIMARY KEY, val int); CREATE TABLE t2 (id int PRIMARY KEY, val int); CREATE TABLE t3 (id int PRIMARY KEY, val int); CREATE TABLE t4 (id int PRIMARY KEY, val int); CREATE TABLE t5 (id int PRIMARY KEY, val int); CREATE TABLE p1 (id int PRIMARY KEY, val int); CREATE TABLE p1_c1 (LIKE p1 INCLUDING ALL, CHECK (id <= 100)) INHERITS(p1); CREATE TABLE p1_c2 (LIKE p1 INCLUDING ALL, CHECK (id > 100 AND id <= 200)) INHERITS(p1); CREATE TABLE p1_c3 (LIKE p1 INCLUDING ALL, CHECK (id > 200 AND id <= 300)) INHERITS(p1); CREATE TABLE p1_c4 (LIKE p1 INCLUDING ALL, CHECK (id > 300)) INHERITS(p1); CREATE TABLE p1_c1_c1 (LIKE p1 INCLUDING ALL, CHECK (id <= 50)) INHERITS(p1_c1); CREATE TABLE p1_c1_c2 (LIKE p1 INCLUDING ALL, CHECK (id > 50 AND id <= 100)) INHERITS(p1_c1); CREATE TABLE p1_c3_c1 (LIKE p1 INCLUDING ALL, CHECK (id > 200 AND id <= 250)) INHERITS(p1_c3); CREATE TABLE p1_c3_c2 (LIKE p1 INCLUDING ALL, CHECK (id > 250 AND id <= 300)) INHERITS(p1_c3); CREATE TABLE p2 (id int PRIMARY KEY, val text); CREATE INDEX p2_id_val_idx ON p2 (id, val); CREATE UNIQUE INDEX p2_val_idx ON p2 (val); CREATE INDEX p2_ununi_id_val_idx ON p2 (val); CREATE INDEX p2_val_idx_1 ON p2 USING hash (val); CREATE INDEX p2_val_id_idx ON p2 (val, id); CREATE INDEX p2_val_idx2 ON p2 (val COLLATE "C"); CREATE INDEX p2_val_idx3 ON p2 (val varchar_ops); CREATE INDEX p2_val_idx4 ON p2 (val DESC NULLS LAST); CREATE INDEX p2_val_idx5 ON p2 (val NULLS FIRST); CREATE INDEX p2_expr ON p2 ((val < '120')); CREATE INDEX p2_expr2 ON p2 ((id * 2 < 120)); CREATE INDEX p2_val_idx6 ON p2 (val) WHERE val >= '50' AND val < '51'; CREATE INDEX p2_val_idx7 ON p2 (val) WHERE id < 120; CREATE TABLE p2_c1 (LIKE p2 INCLUDING ALL, CHECK (id <= 100)) INHERITS(p2); CREATE TABLE p2_c2 (LIKE p2 INCLUDING ALL, CHECK (id > 100 AND id <= 200)) INHERITS(p2); CREATE TABLE p2_c3 (LIKE p2 INCLUDING ALL, CHECK (id > 200 AND id <= 300)) INHERITS(p2); CREATE TABLE p2_c4 (LIKE p2 INCLUDING ALL, CHECK (id > 300)) INHERITS(p2); CREATE TABLE p2_c1_c1 (LIKE p2 INCLUDING ALL, CHECK (id <= 50)) INHERITS(p2_c1); CREATE TABLE p2_c1_c2 (LIKE p2 INCLUDING ALL, CHECK (id > 50 AND id <= 100)) INHERITS(p2_c1); CREATE TABLE p2_c3_c1 (LIKE p2 INCLUDING ALL, CHECK (id > 200 AND id <= 250)) INHERITS(p2_c3); CREATE TABLE p2_c3_c2 (LIKE p2 INCLUDING ALL, CHECK (id > 250 AND id <= 300)) INHERITS(p2_c3); CREATE TABLE s0.t1 (id int PRIMARY KEY, val int); INSERT INTO t1 SELECT i, i % 100 FROM (SELECT generate_series(1, 10000) i) t; INSERT INTO t2 SELECT i, i % 10 FROM (SELECT generate_series(1, 1000) i) t; INSERT INTO t3 SELECT i, i FROM (SELECT generate_series(1, 100) i) t; INSERT INTO t4 SELECT i, i FROM (SELECT generate_series(1, 10) i) t; INSERT INTO t5 SELECT i, i % 100 FROM (SELECT generate_series(1, 10000) i) t; INSERT INTO p1_c1_c1 SELECT i, i % 100 FROM (SELECT generate_series(1, 50) i) t; INSERT INTO p1_c1_c2 SELECT i, i % 100 FROM (SELECT generate_series(51, 100) i) t; INSERT INTO p1_c2 SELECT i, i % 100 FROM (SELECT generate_series(101, 200) i) t; INSERT INTO p1_c3_c1 SELECT i, i % 100 FROM (SELECT generate_series(201, 250) i) t; INSERT INTO p1_c3_c2 SELECT i, i % 100 FROM (SELECT generate_series(251, 300) i) t; INSERT INTO p1_c4 SELECT i, i % 100 FROM (SELECT generate_series(301, 400) i) t; INSERT INTO p2_c1_c1 SELECT i, i % 100 FROM (SELECT generate_series(1, 50) i) t; INSERT INTO p2_c1_c2 SELECT i, i % 100 FROM (SELECT generate_series(51, 100) i) t; INSERT INTO p2_c2 SELECT i, i % 100 FROM (SELECT generate_series(101, 200) i) t; INSERT INTO p2_c3_c1 SELECT i, i % 100 FROM (SELECT generate_series(201, 250) i) t; INSERT INTO p2_c3_c2 SELECT i, i % 100 FROM (SELECT generate_series(251, 300) i) t; INSERT INTO p2_c4 SELECT i, i % 100 FROM (SELECT generate_series(301, 400) i) t; CREATE INDEX t1_val ON t1 (val); CREATE INDEX t2_val ON t2 (val); CREATE INDEX t5_id1 ON t5 (id); CREATE INDEX t5_id2 ON t5 (id); CREATE INDEX t5_id3 ON t5 (id); CREATE INDEX t5_val ON t5 (val); DROP INDEX p2_c4_val_id_idx; CREATE INDEX p2_id2_val ON p2 (id, id, val); CREATE INDEX p2_c1_id2_val ON p2_c1 (id, id, val); CREATE INDEX p2_c2_id2_val ON p2_c2 (id, id, val); CREATE INDEX p2_val2_id ON p2 (val, id, val); CREATE INDEX t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ON t5 (id); CREATE INDEX p1_val1 ON p1 (val); CREATE INDEX p1_val2 ON p1 (val); CREATE INDEX p1_val3 ON p1 (val); CREATE INDEX p1_c1_val1 ON p1_c1 (val); CREATE INDEX p1_c1_val2 ON p1_c1 (val); CREATE INDEX p1_c1_val3 ON p1_c1 (val); CREATE INDEX p1_c1_c1_val1 ON p1_c1_c1 (val); CREATE INDEX p1_c1_c1_val2 ON p1_c1_c1 (val); CREATE INDEX p1_c1_c1_val3 ON p1_c1_c1 (val); CREATE INDEX p1_c1_c2_val1 ON p1_c1_c2 (val); CREATE INDEX p1_c1_c2_val2 ON p1_c1_c2 (val); CREATE INDEX p1_c1_c2_val3 ON p1_c1_c2 (val); CREATE INDEX p1_c2_val1 ON p1_c2 (val); CREATE INDEX p1_c2_val2 ON p1_c2 (val); CREATE INDEX p1_c2_val3 ON p1_c2 (val); CREATE INDEX p1_c3_val1 ON p1_c3 (val); CREATE INDEX p1_c3_val2 ON p1_c3 (val); CREATE INDEX p1_c3_val3 ON p1_c3 (val); CREATE INDEX p1_c3_c1_val1 ON p1_c3_c1 (val); CREATE INDEX p1_c3_c1_val2 ON p1_c3_c1 (val); CREATE INDEX p1_c3_c1_val3 ON p1_c3_c1 (val); CREATE INDEX p1_c3_c2_val1 ON p1_c3_c2 (val); CREATE INDEX p1_c3_c2_val2 ON p1_c3_c2 (val); CREATE INDEX p1_c3_c2_val3 ON p1_c3_c2 (val); CREATE INDEX p1_c4_val1 ON p1_c4 (val); CREATE INDEX p1_c4_val2 ON p1_c4 (val); CREATE INDEX p1_c4_val3 ON p1_c4 (val); ANALYZE t1; ANALYZE t2; ANALYZE t3; ANALYZE t4; ANALYZE t5; ANALYZE p1; ANALYZE p1_c1; ANALYZE p1_c2; ANALYZE p2; CREATE VIEW v1 AS SELECT id, val FROM t1; CREATE VIEW v2 AS SELECT t1.id t1_id, t1.val t1_val, t2.id t2_id, t2.val t2_val FROM t1, t2 WHERE t1.id = t2.id; CREATE VIEW v3 AS SELECT t_1.id t1_id, t_1.val t1_val, t_2.id t2_id, t_2.val t2_val FROM t1 t_1, t2 t_2 WHERE t_1.id = t_2.id; CREATE VIEW v4 AS SELECT v_2.t1_id, t_3.id FROM v2 v_2, t3 t_3 WHERE v_2.t1_id = t_3.id; /* * Utility function to retrieve a query ID from a query. * * This wraps the input query within an EXPLAIN (VERBOSE, FORMAT json) and * returns its query ID. */ CREATE FUNCTION get_query_id(text) RETURNS bigint LANGUAGE plpgsql AS $$ DECLARE query text; explain_output text; query_id bigint; BEGIN query = 'EXPLAIN (VERBOSE, FORMAT json) ' || $1; EXECUTE query INTO explain_output; SELECT INTO query_id ((explain_output::jsonb)->0->'Query Identifier')::bigint; return query_id; END; $$; /* * The following GUC parameters need the setting of the default value to * succeed in regression test. */ SELECT current_database() AS datname \gset /* Fix auto-tunable parameters */ ALTER DATABASE :"datname" SET effective_cache_size TO 16384; SET effective_cache_size TO 16384; CREATE VIEW settings AS SELECT name, setting, category FROM pg_settings WHERE category LIKE 'Query Tuning%' OR name = 'client_min_messages' ORDER BY category, name; SELECT * FROM settings; -- EXPLAIN filtering -- -- A lot of tests rely on EXPLAIN being executed with costs enabled -- to check the validity of the plans generated with hints. -- -- This function takes in input a query, executes it and applies some -- filtering to ensure a stable output. See the tests calling this -- function to see how it can be used. -- -- If required, this can be extended with new operation modes. CREATE OR REPLACE FUNCTION explain_filter(text) RETURNS SETOF text LANGUAGE plpgsql AS $$ DECLARE ln text; BEGIN FOR ln IN EXECUTE $1 LOOP -- Replace cost values with some 'xxx' ln := regexp_replace(ln, 'cost=10{7}[.0-9]+ ', 'cost={inf}..{inf} '); ln := regexp_replace(ln, 'cost=[.0-9]+ ', 'cost=xxx..xxx '); -- Replace width with some 'xxx' ln := regexp_replace(ln, 'width=[0-9]+([^0-9])', 'width=xxx\1'); -- Filter foreign files ln := regexp_replace(ln, '^( +Foreign File: ).*$', '\1 (snip..)'); return next ln; END LOOP; END; $$; ANALYZE; pg_hint_plan-REL17_1_7_0/sql/oldextversions.sql000066400000000000000000000026701466301071500216150ustar00rootroot00000000000000-- -- tests for upgrade paths -- CREATE EXTENSION pg_hint_plan VERSION "1.3.0"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.1"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.2"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.3"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.4"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.5"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.6"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.7"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.8"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.9"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.10"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.4"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.4.1"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.4.2"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.4.3"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.5"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.5.1"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.5.2"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.6.0"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.6.1"; \dx+ pg_hint_plan ALTER EXTENSION pg_hint_plan UPDATE TO "1.7.0"; \dx+ pg_hint_plan \d hint_plan.hints DROP EXTENSION pg_hint_plan; pg_hint_plan-REL17_1_7_0/sql/pg_hint_plan.sql000066400000000000000000001634641466301071500212000ustar00rootroot00000000000000SET search_path TO public; SET client_min_messages TO log; \set SHOW_CONTEXT always EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.val = t2.val; LOAD 'pg_hint_plan'; SET pg_hint_plan.debug_print TO on; SELECT setting <> 'off' FROM pg_settings WHERE name = 'compute_query_id'; SHOW pg_hint_plan.enable_hint_table; /* query-id related test */ SET compute_query_id to off; SET pg_hint_plan.enable_hint_table to on; -- error SET compute_query_id to on; SET pg_hint_plan.enable_hint_table to on; SET compute_query_id to off; SELECT 1; -- gets warning SELECT 1; -- not SET compute_query_id to on; SELECT 1; -- reactivated SET compute_query_id to off; SELECT 1; -- gets warning SET pg_hint_plan.enable_hint_table to off; SET compute_query_id to on; SET pg_hint_plan.enable_hint_table to on; SELECT 1; -- no warning RESET compute_query_id; RESET pg_hint_plan.enable_hint_table; EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.val = t2.val; /*+ Test (t1 t2) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; SET pg_hint_plan.enable_hint TO off; /*+ Test (t1 t2) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; SET pg_hint_plan.enable_hint TO on; /*Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; --+Set(enable_indexscan off) EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+Set(enable_indexscan off) /* nest comment */ */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; EXPLAIN (COSTS false) /*+Set(enable_indexscan off)*/ SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+ Set(enable_indexscan off) Set(enable_hashjoin off) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+ Set ( enable_indexscan off ) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+ Set ( enable_indexscan off ) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+ Set(enable_indexscan off)Set(enable_nestloop off)Set(enable_mergejoin off) Set(enable_seqscan off) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+Set(work_mem "1M")*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+Set(work_mem "1MB")*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+Set(work_mem TO "1MB")*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+SeqScan() */ SELECT 1; /*+SeqScan(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+SeqScan(t1)IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+BitmapScan(t2)NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t4 WHERE t1.val < 10; /*+TidScan(t4)*/ EXPLAIN (COSTS false) SELECT * FROM t3, t4 WHERE t3.id = t4.id AND t4.ctid = '(1,1)'; /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)'; /*+ NestLoop() */ SELECT 1; /*+ NestLoop(x) */ SELECT 1; /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+NoMergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; /*+MergeJoin(t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t3 WHERE t1.val = t3.val; /*+NestLoop(t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t3 WHERE t1.val = t3.val; /*+NoHashJoin(t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t3 WHERE t1.val = t3.val; /*+MergeJoin(t4 t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+HashJoin(t3 t4 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+NestLoop(t2 t3 t4 t1) IndexScan(t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+NoNestLoop(t4 t1 t3 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+Leading( */ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+Leading( )*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+Leading( t3 )*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+Leading( t3 t4 )*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+Leading(t3 t4 t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+Leading(t3 t4 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+Leading(t3 t4 t1 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; /*+Leading(t3 t4 t4)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id; EXPLAIN (COSTS false) SELECT * FROM t1, (VALUES(1,1),(2,2),(3,3)) AS t2(id,val) WHERE t1.id = t2.id; /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, (VALUES(1,1),(2,2),(3,3)) AS t2(id,val) WHERE t1.id = t2.id; /*+HashJoin(t1 *VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM t1, (VALUES(1,1),(2,2),(3,3)) AS t2(id,val) WHERE t1.id = t2.id; /*+HashJoin(t1 *VALUES*) IndexScan(t1) IndexScan(*VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM t1, (VALUES(1,1),(2,2),(3,3)) AS t2(id,val) WHERE t1.id = t2.id; -- single table scan hint test EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); /*+BitmapScan(v_1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); /*+BitmapScan(v_2)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); /*+BitmapScan(v_1)BitmapScan(v_2)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); /*+BitmapScan(v_1)BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); /*+BitmapScan(v_2)BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); /*+BitmapScan(v_1)BitmapScan(v_2)BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10); -- full scan hint pattern test EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; /*+IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; /*+TidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; /*+NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)'; EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+SeqScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+IndexScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+BitmapScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+TidScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoSeqScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoIndexScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoBitmapScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1) SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1) IndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1) TidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1) NoSeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1) NoIndexScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1) NoBitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; /*+NoTidScan(t1) NoTidScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; -- additional test EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)' AND t1.id < 10 AND t2.id < 10; /*+BitmapScan(t1) BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)' AND t1.id < 10 AND t2.id < 10; -- outer join test EXPLAIN (COSTS false) SELECT * FROM t1 FULL OUTER JOIN t2 ON (t1.id = t2.id); /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1 FULL OUTER JOIN t2 ON (t1.id = t2.id); -- Cannot work /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1 FULL OUTER JOIN t2 ON (t1.id = t2.id); -- inheritance tables test SET constraint_exclusion TO off; EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; SET constraint_exclusion TO on; EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; SET constraint_exclusion TO off; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; SET constraint_exclusion TO on; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; SET constraint_exclusion TO off; EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO on; EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO off; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+NestLoop(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+MergeJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+HashJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO on; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+NestLoop(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+MergeJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+HashJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO off; EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; SET constraint_exclusion TO on; EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; SET constraint_exclusion TO off; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+NestLoop(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+MergeJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+HashJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO on; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1 WHERE id >= 50 AND id <= 51 AND p1.ctid = '(1,1)'; /*+NestLoop(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+MergeJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+HashJoin(p1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO off; EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO on; EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO off; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; SET constraint_exclusion TO on; /*+SeqScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+BitmapScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; /*+TidScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10; -- IndexScan is safe for unordered indexes CREATE TABLE ischk (a text, b tsvector) PARTITION BY LIST(a); CREATE TABLE ischk_d1 PARTITION OF ischk FOR VALUES IN (0); CREATE TABLE ischk_d2 PARTITION OF ischk FOR VALUES IN (1); CREATE INDEX ischk_idx ON ischk USING gin (b); /*+ IndexScan(ischk ischk_idx) */ EXPLAIN (COSTS false) SELECT * FROM ischk WHERE b = 'x'; DROP TABLE ischk; -- quote test /*+SeqScan("""t1 ) ")IndexScan("t 2 """)HashJoin("""t1 ) "T3"t 2 """)Leading("""t1 ) "T3"t 2 """)Set(application_name"a a a"" a A")*/ EXPLAIN (COSTS false) SELECT * FROM t1 """t1 ) ", t2 "t 2 """, t3 "T3" WHERE """t1 ) ".id = "t 2 """.id AND """t1 ) ".id = "T3".id; -- duplicate hint test /*+SeqScan(t1)SeqScan(t2)IndexScan(t1)IndexScan(t2)BitmapScan(t1)BitmapScan(t2)TidScan(t1)TidScan(t2)HashJoin(t1 t2)NestLoop(t2 t1)MergeJoin(t1 t2)Leading(t1 t2)Leading(t2 t1)Set(enable_seqscan off)Set(enable_mergejoin on)Set(enable_seqscan on)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)'; -- sub query Leading hint test SET from_collapse_limit TO 100; SET geqo_threshold TO 100; EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(a t1_1 t1_2 t1_4 t1_5)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(a t3_2 t3_5 t2_2 c1_1 t3_4 t3_3 t2_3 t2_4 t1_3 t2_5 t1_2 t3_1 t1_4 t2_1 t1_5 t1_1)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(t3_5 t2_5 t1_5)Leading(t3_2 t2_2 t1_2)Leading(t3_4 t2_4 t1_4)Leading(c1_1 t3_3 t2_3 t1_3 t3_1 t2_1 t1_1)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); SET from_collapse_limit TO 1; EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(a t1_1 t1_2 t1_4 t1_5)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(a t3_2 t3_5 t2_2 c1_1 t3_4 t3_3 t2_3 t2_4 t1_3 t2_5 t1_2 t3_1 t1_4 t2_1 t1_5 t1_1)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); /*+HashJoin(t1_1 t3_1)MergeJoin(t1_3 t3_3)NestLoop(t1_2 t2_2)NestLoop(t1_4 t2_4)NestLoop(t1_5 t2_5)Leading(t3_5 t2_5 t1_5)Leading(t3_2 t2_2 t1_2)Leading(t3_4 t2_4 t1_4)Leading(c1_1 t3_3 t2_3 t1_3 t3_1 t2_1 t1_1)*/ EXPLAIN (COSTS false) WITH c1_1(id) AS ( SELECT max(t1_5.id) FROM t1 t1_5, t2 t2_5, t3 t3_5 WHERE t1_5.id = t2_5.id AND t2_5.id = t3_5.id ) SELECT t1_1.id, ( SELECT max(t1_2.id) FROM t1 t1_2, t2 t2_2, t3 t3_2 WHERE t1_2.id = t2_2.id AND t2_2.id = t3_2.id ) FROM t1 t1_1, t2 t2_1, t3 t3_1, ( SELECT t1_3.id FROM t1 t1_3, t2 t2_3, t3 t3_3 WHERE t1_3.id = t2_3.id AND t2_3.id = t3_3.id ) v1_1(id), c1_1 WHERE t1_1.id = t2_1.id AND t2_1.id = t3_1.id AND t2_1.id = v1_1.id AND v1_1.id = c1_1.id AND t1_1.id = ( SELECT max(t1_4.id) FROM t1 t1_4, t2 t2_4, t3 t3_4 WHERE t1_4.id = t2_4.id AND t2_4.id = t3_4.id ); -- ambiguous error EXPLAIN (COSTS false) SELECT * FROM t1, s0.t1, t2 WHERE public.t1.id = s0.t1.id AND public.t1.id = t2.id; /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, s0.t1, t2 WHERE public.t1.id = s0.t1.id AND public.t1.id = t2.id; /*+Leading(t1 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM t1, s0.t1, t2 WHERE public.t1.id = s0.t1.id AND public.t1.id = t2.id; -- identifier length test EXPLAIN (COSTS false) SELECT * FROM t1 "123456789012345678901234567890123456789012345678901234567890123" JOIN t2 ON ("123456789012345678901234567890123456789012345678901234567890123".id = t2.id) JOIN t3 ON (t2.id = t3.id); /*+ Leading(123456789012345678901234567890123456789012345678901234567890123 t2 t3) SeqScan(123456789012345678901234567890123456789012345678901234567890123) MergeJoin(123456789012345678901234567890123456789012345678901234567890123 t2) Set(123456789012345678901234567890123456789012345678901234567890123 1) */ EXPLAIN (COSTS false) SELECT * FROM t1 "123456789012345678901234567890123456789012345678901234567890123" JOIN t2 ON ("123456789012345678901234567890123456789012345678901234567890123".id = t2.id) JOIN t3 ON (t2.id = t3.id); /*+ Leading(1234567890123456789012345678901234567890123456789012345678901234 t2 t3) SeqScan(1234567890123456789012345678901234567890123456789012345678901234) MergeJoin(1234567890123456789012345678901234567890123456789012345678901234 t2) Set(1234567890123456789012345678901234567890123456789012345678901234 1) Set(cursor_tuple_fraction 0.1234567890123456789012345678901234567890123456789012345678901234) */ EXPLAIN (COSTS false) SELECT * FROM t1 "1234567890123456789012345678901234567890123456789012345678901234" JOIN t2 ON ("1234567890123456789012345678901234567890123456789012345678901234".id = t2.id) JOIN t3 ON (t2.id = t3.id); SET "123456789012345678901234567890123456789012345678901234567890123" TO 1; SET "1234567890123456789012345678901234567890123456789012345678901234" TO 1; SET cursor_tuple_fraction TO 1234567890123456789012345678901234567890123456789012345678901234; -- multi error /*+ Set(enable_seqscan 100)Set(seq_page_cost on)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id; -- debug log of candidate index to use IndexScan EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; /*+IndexScan(t5 t5_id2)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; /*+IndexScan(t5 no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; /*+IndexScan(t5 t5_id1 t5_id2)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; /*+IndexScan(t5 no_exist t5_id2)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; /*+IndexScan(t5 no_exist5 no_exist2)*/ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; -- outer inner EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading((t1))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading((t1 t2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading((t1 t2 t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.id < 10; /*+Leading((t1 t2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.id < 10; EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2) t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; /*+Leading((((t1 t2) t3) t4))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2) t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading((t1 (t2 t3)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2) (t3 t4)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < ( SELECT t1_2.id FROM t1 t1_2, t2 t2_2 WHERE t1_2.id = t2_2.id AND t2_2.val > 100 ORDER BY t1_2.id LIMIT 1); /*+Leading(((t1 t2) t3)) Leading(((t3 t1) t2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t1.val = t3.val AND t1.id < ( SELECT t1_2.id FROM t1 t1_2, t2 t2_2 WHERE t1_2.id = t2_2.id AND t2_2.val > 100 ORDER BY t1_2.id LIMIT 1); /*+Leading(((t1 t2) t3)) Leading((t1_2 t2_2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < ( SELECT t1_2.id FROM t1 t1_2, t2 t2_2 WHERE t1_2.id = t2_2.id AND t2_2.val > 100 ORDER BY t1_2.id LIMIT 1); /*+Leading(((((t1 t2) t3) t1_2) t2_2))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < ( SELECT t1_2.id FROM t1 t1_2, t2 t2_2 WHERE t1_2.id = t2_2.id AND t2_2.val > 100 ORDER BY t1_2.id LIMIT 1); -- Specified outer/inner leading hint and join method hint at the same time /*+Leading(((t1 t2) t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2) t3)) MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2) t3)) MergeJoin(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2) t3)) MergeJoin(t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2) t3)) MergeJoin(t3 t4)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2) t3)) MergeJoin(t1 t2 t3 t4)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4 WHERE t1.id = t2.id AND t3.id = t4.id AND t1.val = t3.val AND t1.id < 10; /*+ Leading ( ( t1 ( t2 t3 ) ) ) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading((t1(t2 t3)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading(("t1(t2" "t3)"))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+ Leading ( ( ( t1 t2 ) t3 ) ) */ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading(((t1 t2)t3))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading(("(t1" "t2)t3"))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.val = t3.val AND t1.id < 10; /*+Leading((t1(t2(t3(t4 t5)))))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; /*+Leading((t5(t4(t3(t2 t1)))))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; /*+Leading(((((t1 t2)t3)t4)t5))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; /*+Leading(((((t5 t4)t3)t2)t1))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; /*+Leading(((t1 t2)(t3(t4 t5))))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; /*+Leading(((t5 t4)(t3(t2 t1))))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; /*+Leading((((t1 t2)t3)(t4 t5)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; /*+Leading((((t5 t4)t3)(t2 t1)))*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3, t4, t5 WHERE t1.id = t2.id AND t1.id = t3.id AND t1.id = t4.id AND t1.id = t5.id; -- inherite table test to specify the index's name EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_id_val_idx)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_val_id_idx)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; -- Inhibit parallel exection to avoid interfaring the hint set max_parallel_workers_per_gather to 0; /*+ IndexScan(p2 p2_val)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_id2_val)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_val2_id)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_c1_id_val_idx)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_pkey p2_c1_id_val_idx)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_pkey no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_c1_id_val_idx no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_pkey p2_c1_id_val_idx no_exist)*/ EXPLAIN (COSTS false) SELECT * FROM p2 WHERE id >= 50 AND id <= 51 AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_val_idx)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_expr)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_val_idx6)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; /*+IndexScan(p2 p2_val_idx p2_val_idx6)*/ EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)'; -- regular expression -- ordinary table EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexScanRegexp(t5 t5_[^i].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexScanRegexp(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexScanRegexp(t5 t5[^_].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexScan(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexOnlyScanRegexp(t5 t5_[^i].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexOnlyScanRegexp(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexOnlyScanRegexp(t5 t5[^_].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexOnlyScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ IndexOnlyScan(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ BitmapScanRegexp(t5 t5_[^i].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ BitmapScanRegexp(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ BitmapScanRegexp(t5 t5[^_].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ BitmapScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; /*+ BitmapScan(t5 t5_id[0-9].*)*/ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; -- Inheritance EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ IndexScanRegexp(p1 p1_.*[^0-9]$)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ IndexScanRegexp(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ IndexScanRegexp(p1 p1[^_].*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ IndexScan(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ IndexOnlyScanRegexp(p1 p1_.*[^0-9]$)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ IndexOnlyScanRegexp(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ IndexOnlyScanRegexp(p1 p1[^_].*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ IndexOnlyScan(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ BitmapScanRegexp(p1 p1_.*[^0-9]$)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ BitmapScanRegexp(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ BitmapScanRegexp(p1 p1[^_].*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; /*+ BitmapScan(p1 p1_.*val2.*)*/ EXPLAIN (COSTS false) SELECT val FROM p1 WHERE val = 1; -- Search from hint table SELECT get_query_id('SELECT * FROM t1 WHERE t1.id = 1') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); SELECT get_query_id('SELECT id FROM t1 WHERE t1.id = 1') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'IndexScan(t1)'); SET pg_hint_plan.enable_hint_table = on; EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = 1; SET pg_hint_plan.enable_hint_table = off; EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = 1; TRUNCATE hint_plan.hints; VACUUM ANALYZE hint_plan.hints; -- plpgsql test EXPLAIN (COSTS false) SELECT id FROM t1 WHERE t1.id = 1; -- static function CREATE FUNCTION testfunc() RETURNS RECORD AS $$ DECLARE ret record; BEGIN SELECT /*+ SeqScan(t1) */ * INTO ret FROM t1 LIMIT 1; RETURN ret; END; $$ LANGUAGE plpgsql; SELECT testfunc(); -- dynamic function DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS void AS $$ BEGIN EXECUTE format('/*+ SeqScan(t1) */ SELECT * FROM t1'); END; $$ LANGUAGE plpgsql; SELECT testfunc(); -- This should not use SeqScan(t1) /*+ IndexScan(t1) */ SELECT * from t1 LIMIT 1; -- Perform DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS void AS $$ BEGIN PERFORM 1, /*+ SeqScan(t1) */ * from t1; END; $$ LANGUAGE plpgsql; SELECT testfunc(); -- FOR loop DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS int AS $$ DECLARE sum int; v int; BEGIN sum := 0; FOR v IN SELECT /*+ SeqScan(t1) */ v FROM t1 ORDER BY id LOOP sum := sum + v; END LOOP; RETURN v; END; $$ LANGUAGE plpgsql; SELECT testfunc(); -- Dynamic FOR loop DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS int AS $$ DECLARE sum int; v int; i int; BEGIN sum := 0; FOR v IN EXECUTE 'SELECT /*+ SeqScan(t1) */ val FROM t1 ORDER BY id' LOOP sum := sum + v; END LOOP; RETURN v; END; $$ LANGUAGE plpgsql; SELECT testfunc(); -- Cursor FOR loop DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS int AS $$ DECLARE ref CURSOR FOR SELECT /*+ SeqScan(t1) */ * FROM t1 ORDER BY id; rec record; sum int := 0; BEGIN FOR rec IN ref LOOP sum := sum + rec.val; END LOOP; RETURN sum; END; $$ LANGUAGE plpgsql; SELECT testfunc(); -- RETURN QUERY DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS SETOF t1 AS $$ BEGIN RETURN QUERY SELECT /*+ SeqScan(t1) */ * FROM t1 ORDER BY id; END; $$ LANGUAGE plpgsql; SELECT * FROM testfunc() LIMIT 1; -- Test for error exit from inner SQL statement. DROP FUNCTION testfunc(); CREATE FUNCTION testfunc() RETURNS SETOF t1 AS $$ BEGIN RETURN QUERY SELECT /*+ SeqScan(t1) */ * FROM ttx ORDER BY id; END; $$ LANGUAGE plpgsql; SELECT * FROM testfunc() LIMIT 1; -- this should not use SeqScan(t1) hint. /*+ IndexScan(t1) */ SELECT * from t1 LIMIT 1; DROP FUNCTION testfunc(); DROP EXTENSION pg_hint_plan; CREATE FUNCTION reset_stats_and_wait() RETURNS void AS $$ DECLARE rows int; BEGIN rows = 1; while rows > 0 LOOP PERFORM pg_stat_reset(); PERFORM pg_sleep(0.5); SELECT sum(seq_scan + idx_scan) from pg_stat_user_tables into rows; END LOOP; END; $$ LANGUAGE plpgsql; -- Dynamic query in pl/pgsql CREATE OR REPLACE FUNCTION dynsql1(x int) RETURNS int AS $$ DECLARE c int; BEGIN EXECUTE '/*+ IndexScan(t1) */ SELECT count(*) FROM t1 WHERE id < $1' INTO c USING x; RETURN c; END; $$ VOLATILE LANGUAGE plpgsql; vacuum analyze t1; SET pg_hint_plan.enable_hint = false; SELECT pg_sleep(1); SELECT reset_stats_and_wait(); SELECT dynsql1(9000); SELECT pg_sleep(1); SELECT relname, seq_scan > 0 as seq_scan, idx_scan > 0 as idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 't1'; SET pg_hint_plan.enable_hint = true; SELECT reset_stats_and_wait(); SELECT dynsql1(9000); SELECT pg_sleep(1); SELECT relname, seq_scan > 0 as seq_scan, idx_scan > 0 as idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 't1'; -- Looped dynamic query in pl/pgsql CREATE OR REPLACE FUNCTION dynsql2(x int, OUT r int) AS $$ DECLARE c text; s int; BEGIN r := 0; FOR c IN SELECT f.f FROM (VALUES ('p1_c1'), ('p1_c2')) f(f) LOOP FOR s IN EXECUTE '/*+ IndexScan(' || c || ' ' || c || '_pkey) */ SELECT sum(val) FROM ' || c || ' WHERE id < ' || x LOOP r := r + s; END LOOP; END LOOP; END; $$ VOLATILE LANGUAGE plpgsql; SET pg_hint_plan.enable_hint = false; SELECT reset_stats_and_wait(); SELECT dynsql2(9000); SELECT pg_sleep(1); -- one of the index scans happened while planning. SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND (relname = 'p1_c1' OR relname = 'p1_c2'); SET pg_hint_plan.enable_hint = true; SELECT reset_stats_and_wait(); SELECT dynsql2(9000); SELECT pg_sleep(1); -- the index scan happened while planning. SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND (relname = 'p1_c1' OR relname = 'p1_c2'); -- Subqueries on inheritance tables under UNION EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION ALL SELECT val::int FROM p2 WHERE id < 1000; /*+ IndexScan(p1 p1_val2) */ EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION ALL SELECT val::int FROM p2 WHERE id < 1000; /*+ IndexScan(p1 p1_val2) IndexScan(p2 p2_id_val_idx) */ EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION ALL SELECT val::int FROM p2 WHERE id < 1000; -- union all case EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION SELECT val::int FROM p2 WHERE id < 1000; /*+ IndexScan(p2 p2_id_val_idx) */ EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION SELECT val::int FROM p2 WHERE id < 1000; /*+ IndexScan(p1 p1_val2) IndexScan(p2 p2_id_val_idx) */ EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 UNION SELECT val::int FROM p2 WHERE id < 1000; -- -- Rows hint tests -- -- Explain result includes "Planning time" if COSTS is enabled, but -- this test needs it enabled for get rows count. So do tests via psql -- and grep -v the mutable line. -- Parse error check /*+ Rows() */ SELECT 1; /*+ Rows(x) */ SELECT 1; -- value types SELECT explain_filter(' EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); SELECT explain_filter(' /*+ Rows(t1 t2 #99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); SELECT explain_filter(' /*+ Rows(t1 t2 +99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); SELECT explain_filter(' /*+ Rows(t1 t2 -99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); SELECT explain_filter(' /*+ Rows(t1 t2 *99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); SELECT explain_filter(' /*+ Rows(t1 t2 *0.01) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); SELECT explain_filter(' /*+ Rows(t1 t2 #aa) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); -- ERROR '); SELECT explain_filter(' /*+ Rows(t1 t2 /99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); -- ERROR '); -- round up to 1 SELECT explain_filter(' /*+ Rows(t1 t2 -99999) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); '); -- complex join tree SELECT explain_filter(' EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); '); SELECT explain_filter(' /*+ Rows(t1 t2 #22) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); '); SELECT explain_filter(' /*+ Rows(t1 t3 *10) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); '); -- Query with join RTE and outer-join relids /*+Leading(ft_1 ft_2 t1)*/ SELECT relname, seq_scan > 0 AS seq_scan, idx_scan > 0 AS idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 't1'; -- hint error level set client_min_messages to 'DEBUG1'; /*+ SeqScan( */ SELECT 1; /*+ SeqScan(t1) */ SELECT * FROM t1 LIMIT 0; set pg_hint_plan.parse_messages to 'ERROR'; -- Force an error before running the planner hook, when forcing the Set hints. /*+ Set(work_mem "foo") */ SELECT 1; /*+ SeqScan(t1) */ SELECT * FROM t1 LIMIT 0; set pg_hint_plan.message_level to 'DEBUG1'; set pg_hint_plan.parse_messages to 'NOTICE'; /*+ SeqScan( */ SELECT 1; /*+ SeqScan(t1) */ SELECT * FROM t1 LIMIT 0; -- all hint types together /*+ SeqScan(t1) MergeJoin(t1 t2) Leading(t1 t2) Rows(t1 t2 +10) Parallel(t1 8 hard) Set(random_page_cost 2.0)*/ EXPLAIN (costs off) SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); pg_hint_plan-REL17_1_7_0/sql/plpgsql.sql000066400000000000000000000106771466301071500202150ustar00rootroot00000000000000-- -- Scenarios with various PL/pgsql functions -- SET search_path TO public; SET client_min_messages TO log; \set SHOW_CONTEXT always LOAD 'pg_hint_plan'; SET pg_hint_plan.debug_print TO on; SET compute_query_id = on; SHOW pg_hint_plan.enable_hint_table; -- Internal handling of hints within plpgsql functions. -- This forces an exception, manipulating internally plpgsql_recurse_level. create or replace function test_hint_exception(level int) returns void language plpgsql as $$ begin level := level + 1; raise notice 'Execution of test_hint_exception at level %', level; if level > 1 then -- This triggers the exception below, ending execution. execute 'select ''x''::numeric'; end if; raise notice 'End of test_hint_exception at level %', level; execute 'select test_hint_exception(' || level || ')'; exception when others then end; $$; -- Having a transaction context is essential to mess up with the -- plpgsql_recurse_level. begin; select set_config('compute_query_id','off', true); -- Show plan without hints explain (costs false) with test as (select 'z' val) select t1.val from test t1, test t2 where t1.val = t2.val; -- Invoke function that internally throws an exception with two -- levels of nesting. select test_hint_exception(0); -- Show plan with hint, stored as an internal state of plpgsql_recurse_level. explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 'x' val) select t1.val from test t1, test t2 where t1.val = t2.val; -- This query should have the same plan as the first one, without hints. explain (costs false) with test as (select 'y' val) select t1.val from test t1, test t2 where t1.val = t2.val; -- Again, with one level of nesting. select test_hint_exception(1); -- Show plan with hint. explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select 'x' val) select t1.val from test t1, test t2 where t1.val = t2.val; -- This query should have no hints. explain (costs false) with test as (select 'y' val) select t1.val from test t1, test t2 where t1.val = t2.val; rollback; -- Still no hints used here. explain (costs false) with test as (select 'y' val) select t1.val from test t1, test t2 where t1.val = t2.val; drop function test_hint_exception; -- Test hints with function using transactions internally. create table test_hint_tab (a int); -- Function called in a nested loop to check for hints. create function test_hint_queries(run int, level int) returns void language plpgsql as $$ declare c text; begin level := level + 1; -- Stopping at two levels of nesting should be sufficient.. if level > 2 then return; end if; -- Mix of queries with and without hints. The level is mixed in the -- query string to show it in the output generated. raise notice 'Execution % at level %, hash-join t2/t1 hint', run, level; execute 'explain (costs false) with test /*+ HashJoin(t2 t1) */ as (select ' || level || ' val) select t1.val from test t1, test t2 where t1.val = t2.val;' into c; raise notice 'Execution % at level %, no hints', run, level; execute 'explain (costs false) with test as (select ' || level || ' val) select t1.val from test t1, test t2 where t1.val = t2.val;' into c; raise notice 'Execution % at level %, merge-join t1/t2 hint', run, level; execute 'explain (costs false) with test /*+ MergeJoin(t1 t2) */ as (select ' || level || ' val) select t1.val from test t1, test t2 where t1.val = t2.val;' into c; execute 'select test_hint_queries(' || run || ',' || level || ')'; end; $$; -- Entry point of this test. This executes the transaction -- commands while calling test_hint_queries in a nested loop. -- "mode" can be set to "before" or "after", to control the timing of -- the subtransaction commands launched in this procedure. create procedure test_hint_transaction(mode text) language plpgsql as $$ declare c text; begin for i in 0..3 loop if mode = 'before' then execute 'select test_hint_queries(' || i || ', 0)'; insert into test_hint_tab (a) values (i); end if; -- Mix commits and rollbacks. if i % 2 = 0 then commit; else rollback; end if; if mode = 'after' then execute 'select test_hint_queries(' || i || ', 0)'; insert into test_hint_tab (a) values (i); end if; end loop; end; $$; call test_hint_transaction('before'); call test_hint_transaction('after'); table test_hint_tab; drop procedure test_hint_transaction; drop function test_hint_queries; drop table test_hint_tab; pg_hint_plan-REL17_1_7_0/sql/ut-A.sql000066400000000000000000001046171466301071500173370ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; ---- ---- No.A-1-1 install ---- No.A-2-1 uninstall ---- -- No.A-1-1-3 CREATE EXTENSION pg_hint_plan; -- No.A-1-2-3 DROP EXTENSION pg_hint_plan; -- No.A-1-1-4 CREATE SCHEMA other_schema; CREATE EXTENSION pg_hint_plan SCHEMA other_schema; CREATE EXTENSION pg_hint_plan; DROP SCHEMA other_schema; ---- ---- No. A-5-1 comment pattern ---- -- No. A-5-1-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-5-1-2 /* +SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-5-1-3 /*SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-5-1-4 --+SeqScan(t1) EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-5-1-5 /* /*+SeqScan(t1)*/ */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. A-5-2 hint position ---- -- No. A-5-2-1 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; -- No. A-5-2-2 EXPLAIN (COSTS false) SELECT c1, c2 AS c_2 /*+SeqScan(t1)*/ FROM s1.t1 WHERE t1.c1 = 1; -- No. A-5-2-3 EXPLAIN (COSTS false) SELECT c1 AS "c1"/*+SeqScan(t1)*/ FROM s1.t1 WHERE t1.c1 = 1; -- No. A-5-2-4 EXPLAIN (COSTS false) SELECT * /*+SeqScan(t1)*/ FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. A-6-1 hint's table definition ---- SET pg_hint_plan.enable_hint_table TO on; -- No. A-6-1-1 \d hint_plan.hints ---- ---- No. A-6-2 search condition ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-6-2-1 SELECT get_query_id('SELECT * FROM s1.t1 WHERE t1.c1 = 1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-6-2-2 INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', 'dummy_application_name', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; TRUNCATE hint_plan.hints; -- No. A-6-2-3 SELECT get_query_id('SELECT * FROM s1.t1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; TRUNCATE hint_plan.hints; ---- ---- No. A-6-3 number of constant ---- -- No. A-6-3-1 SELECT get_query_id('SELECT c1 FROM s1.t1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT c1 FROM s1.t1; TRUNCATE hint_plan.hints; -- No. A-6-3-2 SELECT get_query_id('SELECT * FROM s1.t1 WHERE t1.c1 = 1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; TRUNCATE hint_plan.hints; -- No. A-6-3-3 SELECT get_query_id('SELECT * FROM s1.t1 WHERE t1.c1 = 1 OR t1.c1 = 2') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 OR t1.c1 = 0; TRUNCATE hint_plan.hints; SET pg_hint_plan.enable_hint_table TO off; ---- ---- No. A-7-2 hint delimiter ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-1 -- No. A-7-2-2 -- No. A-7-2-3 -- No. A-7-2-4 -- No. A-7-2-5 -- No. A-7-2-6 -- No. A-7-2-7 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-8 /*+ Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-9 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off") */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-10 /*+ Set (enable_indexscan"off") Set (enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-11 /*+Set ( enable_indexscan"off")Set ( enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-12 /*+Set(enable_indexscan"off" ) Set(enable_bitmapscan"off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-13 /*+Set( enable_indexscan "off" )Set( enable_bitmapscan "off" )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-14 /*+ Set ( enable_indexscan "off" ) Set ( enable_bitmapscan "off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-15 /*+ Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-16 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off") */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-17 /*+ Set (enable_indexscan"off") Set (enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-18 /*+Set ( enable_indexscan"off")Set ( enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-19 /*+Set(enable_indexscan"off" ) Set(enable_bitmapscan"off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-20 /*+Set( enable_indexscan "off" )Set( enable_bitmapscan "off" )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-21 /*+ Set ( enable_indexscan "off" ) Set ( enable_bitmapscan "off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-22 /*+ Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-23 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off") */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-24 /*+ Set (enable_indexscan"off") Set (enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-25 /*+Set ( enable_indexscan"off")Set ( enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-26 /*+Set(enable_indexscan"off" ) Set(enable_bitmapscan"off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-27 /*+Set( enable_indexscan "off" )Set( enable_bitmapscan "off" )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-28 /*+ Set ( enable_indexscan "off" ) Set ( enable_bitmapscan "off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-29 /*+ Set(enable_indexscan"off")Set(enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-30 /*+Set(enable_indexscan"off")Set(enable_bitmapscan"off") */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-31 /*+ Set (enable_indexscan"off") Set (enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-32 /*+Set ( enable_indexscan"off")Set ( enable_bitmapscan"off")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-33 /*+Set(enable_indexscan"off" ) Set(enable_bitmapscan"off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-34 /*+Set( enable_indexscan "off" )Set( enable_bitmapscan "off" )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-2-35 /*+ Set ( enable_indexscan "off" ) Set ( enable_bitmapscan "off" ) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. A-7-3 hint object pattern ---- No. A-9-2 message object pattern ---- -- No. A-7-3-1 -- No. A-9-2-1 /*+SeqScan(t)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t WHERE t.c1 = 1; /*+SeqScan(ttt)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ttt WHERE ttt.c1 = 1; /*+SeqScan("t")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t WHERE t.c1 = 1; /*+SeqScan("ttt")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ttt WHERE ttt.c1 = 1; -- No. A-7-3-2 -- No. A-9-2-2 /*+SeqScan(T)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "T" WHERE "T".c1 = 1; /*+SeqScan(TTT)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "TTT" WHERE "TTT".c1 = 1; /*+SeqScan("T")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "T" WHERE "T".c1 = 1; /*+SeqScan("TTT")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "TTT" WHERE "TTT".c1 = 1; -- No. A-7-3-3 -- No. A-9-2-3 /*+SeqScan(()*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "(" WHERE "(".c1 = 1; /*+SeqScan("(")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "(" WHERE "(".c1 = 1; -- No. A-7-3-4 -- No. A-9-2-4 /*+SeqScan())*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ")" WHERE ")".c1 = 1; /*+SeqScan(")")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ")" WHERE ")".c1 = 1; /*+SeqScan(")))")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ")))" WHERE ")))".c1 = 1; -- No. A-7-3-5 -- No. A-9-2-5 /*+SeqScan(")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 """" WHERE """".c1 = 1; /*+SeqScan("""")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 """" WHERE """".c1 = 1; /*+SeqScan("""""""")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 """""""" WHERE """""""".c1 = 1; -- No. A-7-3-6 -- No. A-9-2-6 /*+SeqScan( )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; -- No. A-7-3-7 -- No. A-9-2-7 /*+SeqScan( )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; -- No. A-7-3-8 -- No. A-9-2-8 /*+SeqScan( )*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; /*+SeqScan(" ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 " " WHERE " ".c1 = 1; -- No. A-7-3-9 -- No. A-9-2-9 /*+SeqScan(Set)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "Set" WHERE "Set".c1 = 1; /*+SeqScan("Set")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "Set" WHERE "Set".c1 = 1; /*+SeqScan("Set SeqScan Leading")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "Set SeqScan Leading" WHERE "Set SeqScan Leading".c1 = 1; -- No. A-7-3-10 -- No. A-9-2-10 /*+SeqScan(あ)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 あ WHERE あ.c1 = 1; /*+SeqScan(あいう)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 あいう WHERE あいう.c1 = 1; /*+SeqScan("あ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 あ WHERE あ.c1 = 1; /*+SeqScan("あいう")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 あいう WHERE あいう.c1 = 1; -- No. A-7-3-11 -- No. A-9-2-11 /*+SeqScan(/**/)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "/**/" WHERE "/**/".c1 = 1; /*+SeqScan(/**//**//**/)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "/**//**//**/" WHERE "/**//**//**/".c1 = 1; -- No. A-7-3-12 -- No. A-9-2-12 /*+SeqScan("tT()"" Set/**/あ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "tT()"" Set/**/あ" WHERE "tT()"" Set/**/あ".c1 = 1; --" /*+SeqScan("tT()"" Setあ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "tT()"" Setあ" WHERE "tT()"" Setあ".c1 = 1; -- No. A-7-3-13 -- No. A-9-2-13 /*+SeqScan(a123456789b123456789c123456789d123456789e123456789f123)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "123456789012345678901234567890123456789012345678901234" WHERE "123456789012345678901234567890123456789012345678901234".c1 = 1; ---- ---- No. A-7-4 hint parse error ---- -- No. A-7-4-1 /*+Set(enable_indexscan off)Set enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-4-2 /*+Set(enable_indexscan off)Set(enable_tidscan off Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-4-3 /*+Set(enable_indexscan off)Set(enable_tidscan "off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-4-4 /*+Set(enable_indexscan off)SeqScan("")Set(enable_bitmapscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-4-5 /*+Set(enable_indexscan off)NoSet(enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-4-6 /*+Set(enable_indexscan off)"Set"(enable_tidscan off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-7-4-7 /*+Set(enable_indexscan off)Set(enable_tidscan /* value */off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. A-8-1 original GUC parameter ---- ---- Don't test postgresql itself. -- No. A-8-1-1 -- SET ROLE regress_super_user; -- SET pg_hint_plan.debug_print TO off; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- SET pg_hint_plan.enable_hint TO off; -- SET pg_hint_plan.debug_print TO on; -- SET pg_hint_plan.parse_messages TO error; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- RESET pg_hint_plan.enable_hint; -- RESET pg_hint_plan.debug_print; -- RESET pg_hint_plan.parse_messages; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- -- -- No. A-8-1-2 -- SET ROLE regress_normal_user; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- SET pg_hint_plan.enable_hint TO off; -- SET pg_hint_plan.debug_print TO on; -- SET pg_hint_plan.parse_messages TO error; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- RESET pg_hint_plan.enable_hint; -- RESET pg_hint_plan.debug_print; -- RESET pg_hint_plan.parse_messages; -- SHOW pg_hint_plan.enable_hint; -- SHOW pg_hint_plan.debug_print; -- SHOW pg_hint_plan.parse_messages; -- -- RESET ROLE; ---- ---- No. A-8-2 original GUC parameter pg_hint_plan.enable_hint ---- -- No. A-8-2-1 SET pg_hint_plan.debug_print TO off; SET pg_hint_plan.enable_hint TO on; SHOW pg_hint_plan.enable_hint; /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-2-2 SET pg_hint_plan.enable_hint TO off; SHOW pg_hint_plan.enable_hint; /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-2-3 -- Don't test PostgreSQL itself. -- SET pg_hint_plan.enable_hint TO DEFAULT; -- SHOW pg_hint_plan.enable_hint; -- /*+Set(enable_indexscan off)*/ -- EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-2-4 -- Don't test PostgreSQL itself -- SET pg_hint_plan.enable_hint TO enable; -- SHOW pg_hint_plan.enable_hint; ---- ---- No. A-8-3 original GUC parameter pg_hint_plan.debug_print ---- -- No. A-8-3-1 SET pg_hint_plan.enable_hint TO on; SHOW pg_hint_plan.enable_hint; SET pg_hint_plan.debug_print TO on; SHOW pg_hint_plan.debug_print; /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-3-2 SET pg_hint_plan.debug_print TO off; SHOW pg_hint_plan.debug_print; /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-3-3 SET pg_hint_plan.debug_print TO DEFAULT; SHOW pg_hint_plan.debug_print; /*+Set(enable_indexscan off)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-3-4 SET pg_hint_plan.debug_print TO enable; SHOW pg_hint_plan.debug_print; ---- ---- No. A-8-4 original GUC parameter pg_hint_plan.parse_messages ---- SET client_min_messages TO debug5; -- No. A-8-4-1 SET pg_hint_plan.parse_messages TO debug5; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO debug4; /*+Set*/SELECT 1; -- No. A-8-4-2 SET pg_hint_plan.parse_messages TO debug4; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO debug3; /*+Set*/SELECT 1; -- No. A-8-4-3 SET pg_hint_plan.parse_messages TO debug3; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO debug2; /*+Set*/SELECT 1; -- No. A-8-4-4 SET pg_hint_plan.parse_messages TO debug2; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO debug1; /*+Set*/SELECT 1; -- No. A-8-4-5 SET pg_hint_plan.parse_messages TO debug1; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO log; /*+Set*/SELECT 1; -- No. A-8-4-6 SET pg_hint_plan.parse_messages TO log; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO info; /*+Set*/SELECT 1; -- No. A-8-4-7 SET pg_hint_plan.parse_messages TO info; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO notice; /*+Set*/SELECT 1; -- No. A-8-4-8 SET pg_hint_plan.parse_messages TO notice; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO warning; /*+Set*/SELECT 1; -- No. A-8-4-9 SET pg_hint_plan.parse_messages TO warning; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO error; /*+Set*/SELECT 1; -- No. A-8-4-10 SET pg_hint_plan.parse_messages TO error; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; SET client_min_messages TO error; /*+Set*/SELECT 1; -- No. A-8-4-11 RESET client_min_messages; SET pg_hint_plan.parse_messages TO DEFAULT; SHOW pg_hint_plan.parse_messages; /*+Set*/SELECT 1; -- No. A-8-4-12 SET pg_hint_plan.parse_messages TO fatal; SHOW pg_hint_plan.parse_messages; -- No. A-8-4-13 SET pg_hint_plan.parse_messages TO panic; SHOW pg_hint_plan.parse_messages; -- No. A-8-4-14 SET pg_hint_plan.parse_messages TO on; SHOW pg_hint_plan.parse_messages; ---- ---- No. A-8-5 original GUC parameter pg_hint_plan.enable_hint_table ---- SELECT get_query_id('SELECT * FROM s1.t1 WHERE t1.c1 = 1;') AS query_id \gset INSERT INTO hint_plan.hints (query_id, application_name, hints) VALUES (:'query_id', '', 'SeqScan(t1)'); -- No. A-8-5-1 SET pg_hint_plan.enable_hint_table TO on; SHOW pg_hint_plan.enable_hint_table; EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-5-2 SET pg_hint_plan.enable_hint_table TO off; SHOW pg_hint_plan.enable_hint_table; EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-5-3 SET pg_hint_plan.enable_hint_table TO DEFAULT; SHOW pg_hint_plan.enable_hint_table; EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-8-5-4 SET pg_hint_plan.enable_hint_table TO enable; SHOW pg_hint_plan.enable_hint_table; TRUNCATE hint_plan.hints; ---- ---- No. A-9-1 parse error message output ---- -- No. A-9-1-1 /*+"Set"(enable_indexscan on)*/SELECT 1; /*+Set()(enable_indexscan on)*/SELECT 1; /*+Set(enable_indexscan on*/SELECT 1; ---- ---- No. A-9-3 hint state output ---- SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; -- No. A-9-3-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-9-3-2 /*+SeqScan(no_table)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-9-3-3 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; /*+TidScan(t1)BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; /*+TidScan(t1)BitmapScan(t1)IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; /*+TidScan(t1)BitmapScan(t1)IndexScan(t1)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; -- No. A-9-3-4 /*+Set(enable_indexscan enable)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. A-10-1 hint state output ---- PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; EXPLAIN (COSTS false) EXECUTE p1; DEALLOCATE p1; PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); DEALLOCATE p1; -- No. A-10-1-1 -- No. A-10-1-2 /*+SeqScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1; UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1; DEALLOCATE p1; /*+BitmapScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); DEALLOCATE p1; -- No. A-10-1-3 -- No. A-10-1-4 /*+SeqScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; EXPLAIN (COSTS false) EXECUTE p1; UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; EXPLAIN (COSTS false) EXECUTE p1; DEALLOCATE p1; /*+BitmapScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; EXPLAIN (COSTS false) EXECUTE p1 (1000); DEALLOCATE p1; -- No. A-10-1-5 -- No. A-10-1-6 PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1; UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1; DEALLOCATE p1; PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); EXPLAIN (COSTS false) EXECUTE p1 (1000); UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) EXECUTE p1 (1000); DEALLOCATE p1; -- No. A-10-1-9 -- No. A-10-1-10 /*+SeqScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; DEALLOCATE p1; /*+BitmapScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); DEALLOCATE p1; -- No. A-10-1-11 -- No. A-10-1-12 /*+SeqScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; DEALLOCATE p1; /*+BitmapScan(t1)*/ PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); DEALLOCATE p1; -- No. A-10-1-13 -- No. A-10-1-14 PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1; DEALLOCATE p1; PREPARE p1 AS SELECT * FROM s1.t1 WHERE t1.c1 < $1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); UPDATE pg_catalog.pg_class SET relpages = relpages WHERE relname = 't1'; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) CREATE TABLE test AS EXECUTE p1 (1000); DEALLOCATE p1; ---- ---- No. A-10-4 EXECUTE statement name error ---- -- No. A-10-4-1 EXECUTE p1; SHOW pg_hint_plan.debug_print; ---- ---- No. A-11-5 EXECUTE statement name error ---- -- No. A-11-5-1 SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+Set(enable_seqscan off)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+SeqScan(t1)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. A-12-1 reset of global variable of core at the error ---- No. A-12-2 reset of global variable of original at the error ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)NestLoop(t1 t1)*/ PREPARE p1 AS SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; EXPLAIN (COSTS false) EXECUTE p1; -- No. A-12-1-1 -- No. A-12-2-1 SELECT name, setting FROM settings; SET pg_hint_plan.parse_messages TO error; /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)NestLoop(t1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SELECT name, setting FROM settings; /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. A-12-1-2 -- No. A-12-2-2 SELECT name, setting FROM settings; SET pg_hint_plan.parse_messages TO error; /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)NestLoop(t1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SELECT name, setting FROM settings; EXPLAIN (COSTS false) EXECUTE p1; -- No. A-12-1-3 -- No. A-12-2-3 SELECT name, setting FROM settings; SET pg_hint_plan.parse_messages TO error; EXPLAIN (COSTS false) EXECUTE p2; /*+Set(enable_seqscan off)Set(geqo_threshold 100)SeqScan(t1)MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; EXPLAIN (COSTS false) EXECUTE p1; SELECT name, setting FROM settings; -- No. A-12-1-4 -- No. A-12-2-4 SELECT name, setting FROM settings; SET pg_hint_plan.parse_messages TO error; EXPLAIN (COSTS false) EXECUTE p2; EXPLAIN (COSTS false) EXECUTE p1; SELECT name, setting FROM settings; DEALLOCATE p1; SET pg_hint_plan.parse_messages TO LOG; ---- ---- No. A-12-3 effective range of the hint ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. A-12-3-1 SET enable_indexscan TO off; SET enable_mergejoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SELECT name, setting FROM settings; /*+Set(enable_indexscan on)Set(geqo_threshold 100)IndexScan(t2)MergeJoin(t1 t2)Leading(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SELECT name, setting FROM settings; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. A-12-3-2 SET enable_indexscan TO off; SET enable_mergejoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SELECT name, setting FROM settings; BEGIN; /*+Set(enable_indexscan on)Set(geqo_threshold 100)IndexScan(t2)MergeJoin(t1 t2)Leading(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; COMMIT; BEGIN; SELECT name, setting FROM settings; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; COMMIT; -- No. A-12-3-3 SET enable_indexscan TO off; SET enable_mergejoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SELECT name, setting FROM settings; /*+Set(enable_indexscan on)Set(geqo_threshold 100)IndexScan(t2)MergeJoin(t1 t2)Leading(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \connect SET enable_indexscan TO off; SET enable_mergejoin TO off; LOAD 'pg_hint_plan'; SELECT name, setting FROM settings; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; RESET enable_indexscan; RESET enable_mergejoin; ---- ---- No. A-13 call planner recursively ---- CREATE OR REPLACE FUNCTION nested_planner(cnt int) RETURNS int AS $$ DECLARE new_cnt int; BEGIN RAISE NOTICE 'nested_planner(%)', cnt; /* 再帰終了の判断 */ IF cnt <= 1 THEN RETURN 0; END IF; SELECT /*+ IndexScan(t_1) */ nested_planner(cnt - 1) INTO new_cnt FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1 LIMIT 1; RETURN new_cnt; END; $$ LANGUAGE plpgsql IMMUTABLE; ---- ---- No. A-13-2 use hint of main query ---- --No.13-2-1 EXPLAIN (COSTS false) SELECT nested_planner(1) FROM s1.t1 t_1 ORDER BY t_1.c1; /*+SeqScan(t_1)*/ EXPLAIN (COSTS false) SELECT nested_planner(1) FROM s1.t1 t_1 ORDER BY t_1.c1; ---- ---- No. A-13-3 output number of times of debugging log ---- --No.13-3-1 EXPLAIN (COSTS false) SELECT nested_planner(1) FROM s1.t1 t_1 ORDER BY t_1.c1; /*+SeqScan(t_2)*/ EXPLAIN (COSTS false) SELECT nested_planner(1) FROM s1.t1 t_1 ORDER BY t_1.c1; --No.13-3-2 EXPLAIN (COSTS false) SELECT nested_planner(2) FROM s1.t1 t_1 ORDER BY t_1.c1; /*+SeqScan(t_2)*/ EXPLAIN (COSTS false) SELECT nested_planner(2) FROM s1.t1 t_1 ORDER BY t_1.c1; --No.13-3-3 -- -- Redefine not to use cached plan -- CREATE OR REPLACE FUNCTION nested_planner(cnt int) RETURNS int AS $$ DECLARE new_cnt int; BEGIN RAISE NOTICE 'nested_planner(%)', cnt; /* 再帰終了の判断 */ IF cnt <= 1 THEN RETURN 0; END IF; SELECT /*+ IndexScan(t_1) */ nested_planner(cnt - 1) INTO new_cnt FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1 LIMIT 1; RETURN new_cnt; END; $$ LANGUAGE plpgsql IMMUTABLE; -- The function called at the bottom desn't use a hint, the immediate -- caller level should restore its own hint. So, the first LOG from -- pg_hint_plan should use the IndexScan(t_1) hint EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1; -- The top level uses SeqScan(t_1), but the function should use only -- the hint in the function. /*+SeqScan(t_1) SeqScan(t_2)*/ EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1; ---- ---- No. A-13-4 output of debugging log on hint status ---- CREATE OR REPLACE FUNCTION recall_planner() RETURNS int AS $$ SELECT /*+ IndexScan(t_1) */t_1.c1 FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1 LIMIT 1; $$ LANGUAGE SQL IMMUTABLE; --No.13-4-1 -- recall_planner() is reduced to constant while planning using the -- hint defined in the function. Then the outer query is planned based -- on the following hint. pg_hint_plan shows the log for the function -- but the resulting explain output doesn't contain the corresponding -- plan. /*+HashJoin(t_1 t_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; --No.13-4-2 --See description for No.13-4-1 /*+HashJoin(st_1 st_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 st_1 JOIN s1.t2 st_2 ON (st_1.c1 = st_2.c1) ORDER BY st_1.c1; --No.13-4-3 --See description for No.13-4-1 /*+HashJoin(t_1 t_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 st_1 JOIN s1.t2 st_2 ON (st_1.c1 = st_2.c1) ORDER BY st_1.c1; --No.13-4-4 --See description for No.13-4-1 /*+HashJoin(st_1 st_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; --No.13-4-5 -- See description for No.13-4-1. No joins in ths plan, so -- pg_hint_plan doesn't complain on the wrongly written error hint. /*+HashJoin(t_1 t_1)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 ORDER BY t_1.c1; --No.13-4-6 CREATE OR REPLACE FUNCTION recall_planner_one_t() RETURNS int AS $$ SELECT /*+ IndexScan(t_1) */t_1.c1 FROM s1.t1 t_1 ORDER BY t_1.c1 LIMIT 1; $$ LANGUAGE SQL IMMUTABLE; EXPLAIN (COSTS false) SELECT recall_planner_one_t() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; /*+HashJoin(t_1 t_1)*/ EXPLAIN (COSTS false) SELECT recall_planner_one_t() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; DROP FUNCTION recall_planner_one_t(int); --No.13-4-7 -- See description for No.13-4-1. Complains on the wrongly written hint. /*+HashJoin(t_1 t_1)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; --No.13-4-8 /*+MergeJoin(t_1 t_2)HashJoin(t_1 t_2)*/ EXPLAIN (COSTS false) SELECT recall_planner() FROM s1.t1 t_1 JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1) ORDER BY t_1.c1; --No.14-1-1 plancache invalidation CREATE TABLE s1.tpc AS SELECT a FROM generate_series(0, 999) a; CREATE INDEX ON s1.tpc(a); PREPARE p1 AS SELECT * FROM s1.tpc WHERE a < 999; /*+ IndexScan(tpc) */PREPARE p2 AS SELECT * FROM s1.tpc WHERE a < 999; /*+ SeqScan(tpc) */PREPARE p3(int) AS SELECT * FROM s1.tpc WHERE a = $1; EXPLAIN (COSTS false) EXECUTE p1; EXPLAIN (COSTS false) EXECUTE p2; EXPLAIN (COSTS false) EXECUTE p3(500); -- The DROP invalidates the plan caches DROP TABLE s1.tpc; CREATE TABLE s1.tpc AS SELECT a FROM generate_series(0, 999) a; CREATE INDEX ON s1.tpc(a); EXPLAIN (COSTS false) EXECUTE p1; EXPLAIN (COSTS false) EXECUTE p2; EXPLAIN (COSTS false) EXECUTE p3(500); DEALLOCATE p1; DEALLOCATE p2; DEALLOCATE p3; DROP TABLE s1.tpc; --No.14-1-2 PREPARE query with array parameters PREPARE test_query(numeric[]) AS /*+ MergeJoin(t1 t2) */ WITH test AS (SELECT 1 AS x) SELECT t1.* FROM test t1, test t2 WHERE t1.x = ANY($1) AND t1.x = t2.x; EXPLAIN (COSTS false) EXECUTE test_query(array[1,2,3]); pg_hint_plan-REL17_1_7_0/sql/ut-G.sql000066400000000000000000000066771466301071500173540ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; ---- ---- No. G-1-1 RULE definition table ---- -- No. G-1-1-1 EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. G-1-1-2 EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. G-1-1-3 EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Set(enable_tidscan off)Set(enable_nestloop off) */ EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; ---- ---- No. G-2-1 GUC parameter ---- -- No. G-2-1-3 /*+Set(1234567890123456789012345678901234567890123456789012345678901234 1)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. G-2-1-4 /*+Set(constraint_exclusion 1234567890123456789012345678901234567890123456789012345678901234)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. G-2-2 category of GUC parameter and role ---- -- No. G-2-2-1 SET ROLE regress_super_user; /*+Set(block_size 16384)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. G-2-2-2 /*+Set(archive_mode off)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. G-2-2-3 /*+Set(archive_timeout 0)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. G-2-2-4 /*+Set(log_connections off)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. G-2-2-5 /*+Set(log_min_messages WARNING)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; RESET ROLE; -- No. G-2-2-6 GRANT ALL ON SCHEMA s1 TO PUBLIC; GRANT SELECT ON ALL TABLES IN SCHEMA s1 TO regress_normal_user; SET ROLE regress_normal_user; /*+Set(log_min_messages WARNING)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. G-2-2-7 /*+Set(enable_seqscan on)*/ SELECT * FROM s1.t1 WHERE t1.c1 = 1; RESET ROLE; REVOKE SELECT ON ALL TABLES IN SCHEMA s1 FROM regress_normal_user; REVOKE ALL ON SCHEMA s1 FROM PUBLIC; ---- ---- No. G-2-3 conflict set hint ---- SET client_min_messages TO LOG; -- No. G-2-3-1 /*+Set(enable_indexscan on)Set(enable_indexscan off)*/ SELECT * FROM s1.t1 WHERE false; -- No. G-2-3-2 /*+Set(client_min_messages DEBUG5)Set(client_min_messages WARNING)Set(client_min_messages DEBUG2)*/ SELECT * FROM s1.t1 WHERE false; -- No. G-2-3-3 /*+Set(enable_indexscan on)Set(enable_indexscan o)*/ SELECT * FROM s1.t1 WHERE false; -- No. G-2-3-4 /*+Set(client_min_messages DEBUG5)Set(client_min_messages WARNING)Set(client_min_messages DEBU)*/ SELECT * FROM s1.t1 WHERE false; ---- ---- No. G-2-4 debug message ---- -- No. G-2-4-1 /*+SeqScan(a)IndexScan(a)SeqScan(c)NestLoop(a) */ SELECT * FROM s1.t1 a, s1.t2 b WHERE false; pg_hint_plan-REL17_1_7_0/sql/ut-J.sql000066400000000000000000001113071466301071500173420ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; SET max_parallel_workers_per_gather TO 0; SET jit = off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; ---- ---- No. J-1-1 specified pattern of the object name ---- -- No. J-1-1-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-1-1-2 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; -- No. J-1-1-3 /*+HashJoin(t_1 t_2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; ---- ---- No. J-1-2 specified schema name in the hint option ---- -- No. J-1-2-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-1-2-2 /*+HashJoin(s1.t1 s1.t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; ---- ---- No. J-1-3 table doesn't exist in the hint option ---- -- No. J-1-3-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-1-3-2 /*+HashJoin(t3 t4)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; ---- ---- No. J-1-4 conflict table name ---- -- No. J-1-4-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-1-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; /*+HashJoin(t1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; /*+HashJoin(s1.t1 s2.t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; /*+HashJoin(t1 s2t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; -- No. J-1-4-3 EXPLAIN (COSTS false) SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NestLoop(st1 st2)HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT *, (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; ---- ---- No. J-1-5 conflict table name ---- -- No. J-1-5-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-1-5-2 /*+HashJoin(t1 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-1-5-3 /*+HashJoin(t1 t1)HashJoin(t2 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; /*+HashJoin(t1 t2 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; ---- ---- No. J-1-6 object type for the hint ---- -- No. J-1-6-1 /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-1-6-2 EXPLAIN (COSTS false) SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; -- No. J-1-6-3 EXPLAIN (COSTS false) SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; -- No. J-1-6-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); EXPLAIN (COSTS false) SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; -- No. J-1-6-5 EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class t1, pg_catalog.pg_class t2 WHERE t1.oid = t2.oid; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class t1, pg_catalog.pg_class t2 WHERE t1.oid = t2.oid; -- No. J-1-6-6 -- refer ut-fdw.sql -- No. J-1-6-7 EXPLAIN (COSTS false) SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; -- No. J-1-6-8 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; /*+NestLoop(*VALUES* t2)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; -- No. J-1-6-9 EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = c1.c1; /*+NestLoop(t1 t2)HashJoin(t1 c1)*/ EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = c1.c1; -- No. J-1-6-10 EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; /*+NestLoop(v1t1 v1t1_)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1_ t2 WHERE t1.c1 = t2.c1; -- No. J-1-6-11 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.c1 = (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1); SELECT explain_filter(' /*+MergeJoin(t1 t2)NestLoop(st1 st2)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.c1 = (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1); '); -- -- There are cases where difference in the measured value and predicted value -- depending upon the version of PostgreSQL -- EXPLAIN (COSTS false) SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; /*+HashJoin(t1 st2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; ---- ---- No. J-2-1 some complexity query blocks ---- -- No. J-2-1-1 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; -- No. J-2-1-2 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; -- No. J-2-1-3 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; /*+ Leading(bmt4 bmt3 bmt2 bmt1) MergeJoin(bmt4 bmt3)HashJoin(bmt4 bmt3 bmt2)NestLoop(bmt1 bmt2 bmt3 bmt4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; -- No. J-2-1-4 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = sbmt2.c1 AND sbmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; /*+ Leading(bmt4 bmt3 bmt2 bmt1) MergeJoin(bmt4 bmt3)HashJoin(bmt4 bmt3 bmt2)NestLoop(bmt1 bmt2 bmt3 bmt4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = sbmt2.c1 AND sbmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; -- No. J-2-1-5 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) ; /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) ; -- No. J-2-1-6 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; -- No. J-2-1-7 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; /*+ Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(c2 c1)HashJoin(c2 c1 bmt1)NestLoop(c2 c1 bmt1 bmt2)MergeJoin(c2 c1 bmt1 bmt2 bmt3)HashJoin(c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; -- No. J-2-1-8 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1 ; /*+ Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(c3 c2)HashJoin(c3 c2 c1)NestLoop(c3 c2 c1 bmt1)MergeJoin(c3 c2 c1 bmt1 bmt2)HashJoin(c3 c2 c1 bmt1 bmt2 bmt3)NestLoop(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1 ; ---- ---- No. J-2-2 the number of the tables per quiry block ---- -- No. J-2-2-1 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; /*+ Leading(c1 bmt1) HashJoin(bmt1 c1) HashJoin(b1t1 c1) HashJoin(b2t1 c1) HashJoin(b3t1 c1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; -- No. J-2-2-2 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; /*+ Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) MergeJoin(c1 bmt2) HashJoin(c1 bmt1 bmt2) MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; -- No. J-2-2-3 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) HashJoin(b1t4 b1t3) NestLoop(b1t4 b1t3 b1t2) MergeJoin(b1t4 b1t3 b1t2 b1t1) HashJoin(b2t4 b2t3) NestLoop(b2t4 b2t3 b2t2) MergeJoin(b2t4 b2t3 b2t2 b2t1) HashJoin(b3t4 b3t3) NestLoop(b3t4 b3t3 b3t2) MergeJoin(b3t4 b3t3 b3t2 b3t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; -- No. J-2-2-4 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) MergeJoin(b1t4 b1t3) HashJoin(b1t4 b1t3 b1t2) NestLoop(b1t4 b1t3 b1t2 b1t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; ---- ---- No. J-2-3 RULE or VIEW ---- -- No. J-2-3-1 EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(t4 t3 t2 t1 r1) MergeJoin(t4 t3 t2 t1 r1) HashJoin(t4 t3 t2 t1) NestLoop(t4 t3 t2) MergeJoin(t4 t3) */ EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(b1t4 b1t3 b1t2 b1t1 r1_) MergeJoin(b1t4 b1t3 b1t2 b1t1 r1_) HashJoin(b1t4 b1t3 b1t2 b1t1) NestLoop(b1t4 b1t3 b1t2) MergeJoin(b1t4 b1t3) */ EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. J-2-3-2 EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(t4 t3 t2 t1 r2) MergeJoin(t4 t3 t2 t1 r2) HashJoin(t4 t3 t2 t1) NestLoop(t4 t3 t2) MergeJoin(t4 t3) */ EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(b1t1 b1t2 b1t3 b1t4 r2_) Leading(b2t1 b2t2 b2t3 b2t4 r2_) MergeJoin(b1t1 b1t2) HashJoin(b1t1 b1t2 b1t3) NestLoop(b1t1 b1t2 b1t3 b1t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r2_) MergeJoin(b2t1 b2t2) HashJoin(b2t1 b2t2 b2t3) NestLoop(b2t1 b2t2 b2t3 b2t4) MergeJoin(b2t1 b2t2 b2t3 b2t4 r2_) */ EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. J-2-3-3 EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(t4 t3 t2 t1 r3) MergeJoin(t4 t3 t2 t1 r3) HashJoin(t4 t3 t2 t1) NestLoop(t4 t3 t2) MergeJoin(t4 t3) */ EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b2t1 b2t2 b2t3 b2t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) MergeJoin(b1t1 b1t2) HashJoin(b1t1 b1t2 b1t3) NestLoop(b1t1 b1t2 b1t3 b1t4) MergeJoin(b1t1 b1t2 b1t3 b1t4 r3_) MergeJoin(b2t1 b2t2) HashJoin(b2t1 b2t2 b2t3) NestLoop(b2t1 b2t2 b2t3 b2t4) MergeJoin(b2t1 b2t2 b2t3 b2t4 r3_) MergeJoin(b3t1 b3t2) HashJoin(b3t1 b3t2 b3t3) NestLoop(b3t1 b3t2 b3t3 b3t4) MergeJoin(b3t1 b3t2 b3t3 b3t4 r3_) */ EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. J-2-3-4 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; /*+HashJoin(v1t1 v1t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; -- No. J-2-3-5 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; /*+NestLoop(v1t1 v1t1_)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; ---- ---- No. J-2-4 VALUES clause ---- -- No. J-2-4-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; /*+ Leading(t3 t1 t2) HashJoin(t3 t1)NestLoop(t3 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; /*+ Leading(*VALUES* t1 t2) HashJoin(*VALUES* t1)NestLoop(*VALUES* t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; -- No. J-2-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+ Leading(t4 t3 t2 t1) NestLoop(t4 t3)HashJoin(t4 t3 t2)MergeJoin(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+ Leading(*VALUES* t3 t2 t1) NestLoop(t4 t3)HashJoin(*VALUES* t3 t2)MergeJoin(*VALUES* t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; ---- ---- No. J-3-1 join method hint ---- -- No. J-3-1-1~6 SET enable_nestloop TO on; SET enable_mergejoin TO off; SET enable_hashjoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SET enable_mergejoin TO on; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)';; /*+NoNestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)';; SET enable_mergejoin TO off; /*+NoHashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NoMergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-3-1-7~12 SET enable_nestloop TO off; SET enable_mergejoin TO off; SET enable_hashjoin TO on; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NoNestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NoHashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NoMergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-3-1-13~18 SET enable_nestloop TO off; SET enable_mergejoin TO on; SET enable_hashjoin TO off; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+HashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+MergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NoNestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NoHashJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; /*+NoMergeJoin(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; SET enable_nestloop TO on; SET enable_mergejoin TO on; SET enable_hashjoin TO on; ---- ---- No. J-3-2 join inherit tables ---- EXPLAIN (COSTS false) SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; -- No. J-3-2-1 /*+MergeJoin(p1 p2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; -- No. J-3-2-2 /*+MergeJoin(p1c1 p2c1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; ---- ---- No. J-3-2-2 join partitioned tables ---- EXPLAIN (COSTS false) SELECT * FROM s1.pt1, s1.p2 WHERE pt1.c1 = p2.c1; /*+MergeJoin(pt1 p2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.pt1, s1.p2 WHERE pt1.c1 = p2.c1; /*+MergeJoin(pt1_c1 p2c1)*/ /* will ignored */ EXPLAIN (COSTS false) SELECT * FROM s1.pt1, s1.p2 WHERE pt1.c1 = p2.c1; ---- ---- No. J-3-3 conflict join method hint ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-3-3-1 /*+HashJoin(t1 t2)NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-3-3-2 /*+MergeJoin(t1 t2)HashJoin(t1 t2)NestLoop(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-3-3-3 /*+HashJoin(t1 t2)NestLoop(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; -- No. J-3-3-4 /*+MergeJoin(t2 t1)HashJoin(t1 t2)NestLoop(t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; ---- ---- No. J-3-4 hint state output ---- -- No. J-3-4-1 /*+NestLoop(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; -- No. J-3-4-2 /*+HashJoin(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; -- No. J-3-4-3 /*+MergeJoin(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; -- No. J-3-4-4 /*+NoNestLoop(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; -- No. J-3-4-5 /*+NoHashJoin(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; -- No. J-3-4-6 /*+NoMergeJoin(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; -- No. J-3-4-7 /*+NestLoop()*/ SELECT * FROM s1.t1 WHERE false; -- No. J-3-4-8 /*+NestLoop(t1)*/ SELECT * FROM s1.t1 WHERE false; -- No. J-3-4-9 /*+NestLoop(t1 t2)*/ SELECT * FROM s1.t1, s1.t2 WHERE false; -- No. J-3-4-10 /*+NestLoop(t1 t2 t3)*/ SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE false; ---- ---- No. J-3-5 not used hint ---- -- No. J-3-5-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1 FULL OUTER JOIN s1.t2 ON (t1.c1 = t2.c1); SELECT explain_filter(' /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1 FULL OUTER JOIN s1.t2 ON (t1.c1 = t2.c1); '); -- Memoize EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.val = t2.val and t2.id = t3.id; /*+ nomemoize(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.val = t2.val and t2.id = t3.id; -- doesn't work /*+ nomemoize(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM t1, t2, t3 WHERE t1.val = t2.val and t2.id = t3.id; pg_hint_plan-REL17_1_7_0/sql/ut-L.sql000066400000000000000000001057701466301071500173530ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; SET max_parallel_workers_per_gather TO 0; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; ---- ---- No. L-1-1 specified pattern of the object name ---- -- No. L-1-1-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-1-2 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1, s1.t2 t_2, s1.t3 t_3, s1.t4 t_4 WHERE t_1.c1 = t_2.c1 AND t_1.c1 = t_3.c1 AND t_1.c1 = t_4.c1; -- No. L-1-1-3 /*+Leading(t_4 t_2 t_3 t_1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1, s1.t2 t_2, s1.t3 t_3, s1.t4 t_4 WHERE t_1.c1 = t_2.c1 AND t_1.c1 = t_3.c1 AND t_1.c1 = t_4.c1; ---- ---- No. L-1-2 specified schema name in the hint option ---- -- No. L-1-2-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-2-2 /*+Leading(s1.t4 s1.t2 s1.t3 s1.t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; ---- ---- No. L-1-3 table doesn't exist in the hint option ---- -- No. L-1-3-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-3-2 /*+Leading(t5 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; ---- ---- No. L-1-4 conflict table name ---- -- No. L-1-4-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2.t1.c1; /*+Leading(t1 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2.t1.c1; /*+Leading(s1.t1 t2 t3 s2.t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2.t1.c1; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 s2t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2t1.c1; /*+Leading(s2t1 t1 t3 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s2.t1 s2t1 WHERE s1.t1.c1 = t2.c1 AND s1.t1.c1 = t3.c1 AND s1.t1.c1 = s2t1.c1; -- No. L-1-4-3 EXPLAIN (COSTS false) SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(st1 st2 st3 st4)Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT *, (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2, s1.t3 st3, s1.t4 st4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; ---- ---- No. L-1-5 conflict table name ---- -- No. L-1-5-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-5-2 /*+Leading(t4 t2 t3 t1 t4)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t2 t3 t4)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-5-3 /*+Leading(t4 t2 t3 t1 t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t2 t2 t4)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; ---- ---- No. L-1-6 object type for the hint ---- -- No. L-1-6-1 /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-6-2 EXPLAIN (COSTS false) SELECT * FROM s1.p1 t1, s1.p1 t2, s1.p1 t3, s1.p1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 t1, s1.p1 t2, s1.p1 t3, s1.p1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-6-3 EXPLAIN (COSTS false) SELECT * FROM s1.ul1 t1, s1.ul1 t2, s1.ul1 t3, s1.ul1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ul1 t1, s1.ul1 t2, s1.ul1 t3, s1.ul1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-6-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); EXPLAIN (COSTS false) SELECT * FROM tm1 t1, tm1 t2, tm1 t3, tm1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM tm1 t1, tm1 t2, tm1 t3, tm1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-6-5 EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class t1, pg_catalog.pg_class t2, pg_catalog.pg_class t3, pg_catalog.pg_class t4 WHERE t1.oid = t2.oid AND t1.oid = t3.oid AND t1.oid = t4.oid; /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class t1, pg_catalog.pg_class t2, pg_catalog.pg_class t3, pg_catalog.pg_class t4 WHERE t1.oid = t2.oid AND t1.oid = t3.oid AND t1.oid = t4.oid; -- No. L-1-6-6 -- refer ut-fdw.sql -- No. L-1-6-7 EXPLAIN (COSTS false) SELECT * FROM s1.f1() t1, s1.f1() t2, s1.f1() t3, s1.f1() t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.f1() t1, s1.f1() t2, s1.f1() t3, s1.f1() t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-6-8 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t1 (c1, c2, c3, c4), s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t1 (c1, c2, c3, c4), s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-6-9 EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT st1.c1 FROM s1.t1 st1, s1.t1 st2, s1.t1 st3, s1.t1 st4 WHERE st1.c1 = st2.c1 AND st1.c1 = st3.c1 AND st1.c1 = st4.c1) SELECT * FROM c1 ct1, c1 ct2, c1 ct3, c1 ct4 WHERE ct1.c1 = ct2.c1 AND ct1.c1 = ct3.c1 AND ct1.c1 = ct4.c1; /*+Leading(ct4 ct3 ct2 ct1)Leading(st4 st3 st2 st1)*/ EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT st1.c1 FROM s1.t1 st1, s1.t1 st2, s1.t1 st3, s1.t1 st4 WHERE st1.c1 = st2.c1 AND st1.c1 = st3.c1 AND st1.c1 = st4.c1) SELECT * FROM c1 ct1, c1 ct2, c1 ct3, c1 ct4 WHERE ct1.c1 = ct2.c1 AND ct1.c1 = ct3.c1 AND ct1.c1 = ct4.c1; -- No. L-1-6-10 EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1 t2, s1.v1 t3, s1.v1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 t3 t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1 t2, s1.v1 t3, s1.v1 t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1_ t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+Leading(t4 v1t1_ v1t1 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 t1, s1.v1_ t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-1-6-11 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, (SELECT t4.c1 FROM s1.t4) st4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = st4.c1; /*+Leading(st4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, (SELECT t4.c1 FROM s1.t4) st4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = st4.c1; /*+Leading(t4 t2 t3 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, (SELECT t4.c1 FROM s1.t4) st4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = st4.c1; ---- ---- No. L-2-1 some complexity query blocks ---- -- No. L-2-1-1 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; -- No. L-2-1-2 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' ; -- No. L-2-1-3 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; /*+ Leading(bmt4 bmt3 bmt2 bmt1) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; -- No. L-2-1-4 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = sbmt2.c1 AND sbmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; /*+ Leading(bmt4 bmt3 bmt2 bmt1) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = sbmt2.c1 AND sbmt2.ctid = '(1,1)' AND bmt1.c1 = sbmt3.c1 AND sbmt3.ctid = '(1,1)' AND bmt1.c1 = sbmt4.c1 AND sbmt4.ctid = '(1,1)'; -- No. L-2-1-5 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) ; /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) ; -- No. L-2-1-6 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; -- No. L-2-1-7 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; /*+ Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; -- No. L-2-1-8 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1 ; /*+ Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1 ; ---- ---- No. L-2-2 the number of the tables per quiry block ---- -- No. L-2-2-1 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; /*+ Leading(c1 bmt1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; -- No. L-2-2-2 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; /*+ Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; -- No. L-2-2-3 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; -- No. L-2-2-4 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; ---- ---- No. L-2-3 RULE or VIEW ---- -- No. L-2-3-1 EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(t4 t3 t2 t1 r1) */ EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(b1t1 b1t2 b1t3 b1t4 r1_) */ EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. L-2-3-2 EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(t4 t3 t2 t1 r2) */ EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(b1t1 b1t2 b1t3 b1t4 r2_) Leading(b2t1 b2t2 b2t3 b2t4 r2_) */ EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. L-2-3-3 EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(t4 t3 t2 t1 r3) */ EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+ Leading(b1t1 b1t2 b1t3 b1t4 r3_) Leading(b2t1 b2t2 b2t3 b2t4 r3_) Leading(b3t1 b3t2 b3t3 b3t4 r3_) */ EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. L-2-3-4 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; /*+Leading(v1t1 v1t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; -- No. L-2-3-5 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; /*+Leading(v1t1 v1t1_)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; ---- ---- No. L-2-4 VALUES clause ---- -- No. L-2-4-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; /*+ Leading(t3 t1 t2) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; /*+ Leading(*VALUES* t1 t2) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; -- No. L-2-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+ Leading(t4 t3 t2 t1) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; /*+ Leading(*VALUES* t3 t2 t1) */ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; ---- ---- No. L-3-1 leading the order of table joins ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; -- No. L-3-1-1 /*+Leading(t3 t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; -- No. L-3-1-2 /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; ---- ---- No. L-3-2 GUC parameter to disable hints ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; -- No. L-3-2-1 Set geqo_threshold = 3; Set geqo_seed = 0; /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; Reset geqo_threshold; -- No. L-3-2-2 Set geqo_threshold = 4; Set geqo_seed = 0; /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; Reset geqo_threshold; -- No. L-3-2-3 Set from_collapse_limit = 2; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.v2 WHERE t1.c1 = v2.c1; /*+Leading(t1 v2t1 v2t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.v2 WHERE t1.c1 = v2.c1; Reset from_collapse_limit; -- No. L-3-2-4 Set from_collapse_limit = 3; EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.v2 WHERE t1.c1 = v2.c1; /*+Leading(v2t1 v2t2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.v2 WHERE t1.c1 = v2.c1; Reset from_collapse_limit; -- No. L-3-2-5 Set join_collapse_limit = 2; EXPLAIN (COSTS false) SELECT * FROM s1.t3 JOIN s1.t2 ON (t3.c1 = t2.c1) JOIN s1.t1 ON (t1.c1 = t3.c1); /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t3 JOIN s1.t2 ON (t3.c1 = t2.c1) JOIN s1.t1 ON (t1.c1 = t3.c1); Reset join_collapse_limit; -- No. L-3-2-6 Set join_collapse_limit = 3; EXPLAIN (COSTS false) SELECT * FROM s1.t3 JOIN s1.t2 ON (t3.c1 = t2.c1) JOIN s1.t1 ON (t1.c1 = t3.c1); /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t3 JOIN s1.t2 ON (t3.c1 = t2.c1) JOIN s1.t1 ON (t1.c1 = t3.c1); Reset join_collapse_limit; ---- ---- No. L-3-3 join between parents or between children ---- -- No. L-3-3-1 /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2c1 t1 JOIN s1.p2c2 t2 ON (t1.c1 = t2.c1) JOIN s1.p2c3 t3 ON (t1.c1 = t3.c1); -- No. L-3-3-2 /*+Leading(p2c1c1 p2c2c1 p2c3c1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2c1 t1 JOIN s1.p2c2 t2 ON (t1.c1 = t2.c1) JOIN s1.p2c3 t3 ON (t1.c1 = t3.c1); ---- ---- No. L-3-4 conflict leading hint ---- -- No. L-3-4-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); /*+Leading(t2 t3 t1)Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); -- No. L-3-4-2 /*+Leading(t3 t1 t2)Leading(t2 t3 t1)Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); -- No. L-3-4-3 /*+Leading(t2 t3 t1)Leading()*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); -- No. L-3-4-4 /*+Leading(t3 t1 t2)Leading(t2 t3 t1)Leading()*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); ---- ---- No. L-3-5 hint state output ---- -- No. L-3-5-1 /*+Leading()*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); -- No. L-3-5-2 /*+Leading(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); -- No. L-3-5-3 /*+Leading(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); -- No. L-3-5-4 /*+Leading(t1 t2 t3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 JOIN s1.t2 ON (t1.c1 = t2.c1) JOIN s1.t3 ON (t1.c1 = t3.c1); ---- ---- No. L-3-6 specified Inner/Outer side ---- -- No. L-3-6-1 /*+Leading((t2))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-3-6-2 /*+Leading((t2 t3))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-3-6-3 /*+Leading((t2 t3 t4))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-3-6-4 /*+Leading(((t1 t2) (t3 t4)))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-3-6-5 /*+Leading((((t1 t3) t4) t2)))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; -- No. L-3-6-6 /*+Leading((t1 (t3 (t4 t2))))*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; pg_hint_plan-REL17_1_7_0/sql/ut-R.sql000066400000000000000000001120041466301071500173450ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET jit = off; SET search_path TO public; SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-1-1 specified pattern of the object name ---- -- No. R-1-1-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-1-2 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; '); -- No. R-1-1-3 SELECT explain_filter(' /*+Rows(t_1 t_2 #1)*/ EXPLAIN SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; '); ---- ---- No. R-1-2 specified schema name in the hint option ---- -- No. R-1-2-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-2-2 SELECT explain_filter(' /*+Rows(s1.t1 s1.t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-1-3 table doesn't exist in the hint option ---- -- No. R-1-3-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-3-2 SELECT explain_filter(' /*+Rows(t3 t4 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-1-4 conflict table name ---- -- No. R-1-4-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-4-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; '); SELECT explain_filter(' /*+Rows(t1 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; '); SELECT explain_filter(' /*+Rows(s1.t1 s2.t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; '); SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; '); SELECT explain_filter(' /*+Rows(t1 s2t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; '); -- No. R-1-4-3 SELECT explain_filter(' EXPLAIN SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT *, (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(st1 st2 #1)Rows(t1 t2 #1)*/ EXPLAIN SELECT *, (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-1-5 conflict table name ---- -- No. R-1-5-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-5-2 SELECT explain_filter(' /*+Rows(t1 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-5-3 SELECT explain_filter(' /*+(t1 t1)(t2 t2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; '); SELECT explain_filter(' /*+(t1 t2 t1 t2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; '); ---- ---- No. R-1-6 object type for the hint ---- -- No. R-1-6-1 SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-6-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-6-3 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-6-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); SELECT explain_filter(' EXPLAIN SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-6-5 CREATE TEMP TABLE t_pg_class AS SELECT * from pg_class LIMIT 100; SELECT explain_filter(' EXPLAIN SELECT * FROM t_pg_class t1, t_pg_class t2 WHERE t1.oid = t2.oid; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM t_pg_class t1, t_pg_class t2 WHERE t1.oid = t2.oid; '); -- No. R-1-6-6 -- refer ut-fdw.sql -- No. R-1-6-7 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-6-8 SELECT explain_filter(' EXPLAIN SELECT * FROM (VALUES(1,1,1,''1''), (2,2,2,''2''), (3,3,3,''3'')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM (VALUES(1,1,1,''1''), (2,2,2,''2''), (3,3,3,''3'')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(*VALUES* t2 #1)*/ EXPLAIN SELECT * FROM (VALUES(1,1,1,''1''), (2,2,2,''2''), (3,3,3,''3'')) AS t1 (c1, c2, c3, c4), s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-6-9 SELECT explain_filter(' EXPLAIN WITH c1(c1) AS (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = c1.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(t1 c1 +1)*/ EXPLAIN WITH c1(c1) AS (SELECT max(t1.c1) FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = c1.c1; '); -- No. R-1-6-10 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(v1t1 v1t1_ #1)*/ EXPLAIN SELECT * FROM s1.v1 t1, s1.v1_ t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-6-11 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.c1 = (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1); '); SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(st1 st2 #1)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.c1 = (SELECT max(st1.c1) FROM s1.t1 st1, s1.t2 st2 WHERE st1.c1 = st2.c1); '); -- -- There are cases where difference in the measured value and predicted value -- depending upon the version of PostgreSQL -- SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; '); SELECT explain_filter(' /*+Rows(t1 st2 #1)*/ EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; '); ---- ---- No. R-1-7 specified number of conditions ---- -- No. R-1-7-1 SELECT explain_filter(' /*+Rows(t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-7-2 SELECT explain_filter(' /*+Rows(t1 t2 1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-1-7-3 SELECT explain_filter(' /*+Rows(t1 t2 #notrows)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-2-1 some complexity query blocks ---- -- No. R-2-1-1 SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ;'); SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) Rows(bmt1 bmt2 #1)Rows(bmt1 bmt2 bmt3 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) */ EXPLAIN SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; '); -- No. R-2-1-2 SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; '); SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) Rows(bmt1 bmt2 #1)Rows(bmt1 bmt2 bmt3 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) Rows(b3t4 b3t1 #1)Rows(b3t4 b3t1 b3t2 #1)Rows(b3t1 b3t2 b3t3 b3t4 #1) */ EXPLAIN SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ), ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ;'); -- No. R-2-1-3 SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt4 bmt3 #1)Rows(bmt4 bmt3 bmt2 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); -- No. R-2-1-4 SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt4 bmt3 #1)Rows(bmt4 bmt3 bmt2 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); -- No. R-2-1-5 SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ); '); SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) Rows(bmt1 bmt2 #1)Rows(bmt1 bmt2 bmt3 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) ;'); -- No. R-2-1-6 SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) ;'); SELECT explain_filter(' /*+ Leading(bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(bmt1 bmt2)HashJoin(bmt1 bmt2 bmt3)NestLoop(bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) Rows(bmt1 bmt2 #1)Rows(bmt1 bmt2 bmt3 #1)Rows(bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) Rows(b3t4 b3t1 #1)Rows(b3t4 b3t1 b3t2 #1)Rows(b3t1 b3t2 b3t3 b3t4 #1) */ EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) ;'); -- No. R-2-1-7 SELECT explain_filter(' /*+ Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(c2 c1)HashJoin(c2 c1 bmt1)NestLoop(c2 c1 bmt1 bmt2)MergeJoin(c2 c1 bmt1 bmt2 bmt3)HashJoin(c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) */ EXPLAIN WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ;'); SELECT explain_filter(' /*+ Leading(c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) MergeJoin(c2 c1)HashJoin(c2 c1 bmt1)NestLoop(c2 c1 bmt1 bmt2)MergeJoin(c2 c1 bmt1 bmt2 bmt3)HashJoin(c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) Rows(c2 c1 #1)Rows(c2 c1 bmt1 #1)Rows(c2 c1 bmt1 bmt2 #1)Rows(c2 c1 bmt1 bmt2 bmt3 #1)Rows(c2 c1 bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1; '); -- No. R-2-1-8 SELECT explain_filter(' /*+ Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(c3 c2)HashJoin(c3 c2 c1)NestLoop(c3 c2 c1 bmt1)MergeJoin(c3 c2 c1 bmt1 bmt2)HashJoin(c3 c2 c1 bmt1 bmt2 bmt3)NestLoop(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) */ EXPLAIN WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1; '); SELECT explain_filter(' /*+ Leading(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) Leading(b1t2 b1t3 b1t4 b1t1) Leading(b2t3 b2t4 b2t1 b2t2) Leading(b3t4 b3t1 b3t2 b3t3) MergeJoin(c3 c2)HashJoin(c3 c2 c1)NestLoop(c3 c2 c1 bmt1)MergeJoin(c3 c2 c1 bmt1 bmt2)HashJoin(c3 c2 c1 bmt1 bmt2 bmt3)NestLoop(c3 c2 c1 bmt1 bmt2 bmt3 bmt4) MergeJoin(b1t2 b1t3)HashJoin(b1t2 b1t3 b1t4)NestLoop(b1t2 b1t3 b1t4 b1t1) MergeJoin(b2t3 b2t4)HashJoin(b2t3 b2t4 b2t1)NestLoop(b2t3 b2t4 b2t1 b2t2) MergeJoin(b3t4 b3t1)HashJoin(b3t4 b3t1 b3t2)NestLoop(b3t1 b3t2 b3t3 b3t4) Rows(c3 c2 #1)Rows(c3 c2 c1 #1)Rows(c3 c2 c1 bmt1 #1)Rows(c3 c2 c1 bmt1 bmt2 #1)Rows(c3 c2 c1 bmt1 bmt2 bmt3 #1)Rows(c3 c2 c1 bmt1 bmt2 bmt3 bmt4 #1) Rows(b1t2 b1t3 #1)Rows(b1t2 b1t3 b1t4 #1)Rows(b1t2 b1t3 b1t4 b1t1 #1) Rows(b2t3 b2t4 #1)Rows(b2t3 b2t4 b2t1 #1)Rows(b2t3 b2t4 b2t1 b2t2 #1) Rows(b3t4 b3t1 #1)Rows(b3t4 b3t1 b3t2 #1)Rows(b3t1 b3t2 b3t3 b3t4 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) , c3 (c1) AS ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2, c3 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 AND bmt1.c1 = c3.c1; '); ---- ---- No. R-2-2 the number of the tables per quiry block ---- -- No. R-2-2-1 SELECT explain_filter(' /*+ Leading(c1 bmt1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1 WHERE b1t1.c1 = 1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.c1 = 1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1 WHERE b3t1.c1 = 1 ); '); SELECT explain_filter(' /*+ Leading(c1 bmt1) Rows(bmt1 c1 #1) Rows(b1t1 c1 #1) Rows(b2t1 c1 #1) Rows(b3t1 c1 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1 WHERE b1t1.c1 = 1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.c1 = 1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1 WHERE b3t1.c1 = 1 ); '); -- No. R-2-2-2 SELECT explain_filter(' /*+ Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) MergeJoin(c1 bmt2) HashJoin(c1 bmt1 bmt2) MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.c1 = b1t2.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.c1 = b2t2.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.c1 = b3t2.c1 ); '); SELECT explain_filter(' /*+ Leading(c1 bmt2 bmt1) Leading(b1t2 b1t1) Leading(b2t2 b2t1) Leading(b3t2 b3t1) MergeJoin(c1 bmt2) HashJoin(c1 bmt1 bmt2) MergeJoin(b1t1 b1t2) MergeJoin(b2t1 b2t2) MergeJoin(b3t1 b3t2) Rows(c1 bmt2 #1) Rows(c1 bmt1 bmt2 #1) Rows(b1t1 b1t2 #1) Rows(b2t1 b2t2 #1) Rows(b3t1 b3t2 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.c1 = b1t2.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.c1 = b2t2.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.c1 = b3t2.c1 ) ; '); -- No. R-2-2-3 SELECT explain_filter(' /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) HashJoin(b1t4 b1t3) NestLoop(b1t4 b1t3 b1t2) MergeJoin(b1t4 b1t3 b1t2 b1t1) HashJoin(b2t4 b2t3) NestLoop(b2t4 b2t3 b2t2) MergeJoin(b2t4 b2t3 b2t2 b2t1) HashJoin(b3t4 b3t3) NestLoop(b3t4 b3t3 b3t2) MergeJoin(b3t4 b3t3 b3t2 b3t1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ); '); SELECT explain_filter(' /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) Leading(b2t4 b2t3 b2t2 b2t1) Leading(b3t4 b3t3 b3t2 b3t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) HashJoin(b1t4 b1t3) NestLoop(b1t4 b1t3 b1t2) MergeJoin(b1t4 b1t3 b1t2 b1t1) HashJoin(b2t4 b2t3) NestLoop(b2t4 b2t3 b2t2) MergeJoin(b2t4 b2t3 b2t2 b2t1) HashJoin(b3t4 b3t3) NestLoop(b3t4 b3t3 b3t2) MergeJoin(b3t4 b3t3 b3t2 b3t1) Rows(c1 bmt4 #1) Rows(c1 bmt4 bmt3 #1) Rows(c1 bmt4 bmt3 bmt2 #1) Rows(c1 bmt4 bmt3 bmt2 bmt1 #1) Rows(b1t4 b1t3 #1) Rows(b1t4 b1t3 b1t2 #1) Rows(b1t4 b1t3 b1t2 b1t1 #1) Rows(b2t4 b2t3 #1) Rows(b2t4 b2t3 b2t2 #1) Rows(b2t4 b2t3 b2t2 b2t1 #1) Rows(b3t4 b3t3 #1) Rows(b3t4 b3t3 b3t2 #1) Rows(b3t4 b3t3 b3t2 b3t1 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.c1 = b3t2.c1 AND b3t1.c1 = b3t3.c1 AND b3t1.c1 = b3t4.c1 ); '); -- No. R-2-2-4 SELECT explain_filter(' /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) MergeJoin(b1t4 b1t3) HashJoin(b1t4 b1t3 b1t2) NestLoop(b1t4 b1t3 b1t2 b1t1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1 ); '); SELECT explain_filter(' /*+ Leading(c1 bmt4 bmt3 bmt2 bmt1) Leading(b1t4 b1t3 b1t2 b1t1) MergeJoin(c1 bmt4) HashJoin(c1 bmt4 bmt3) NestLoop(c1 bmt4 bmt3 bmt2) MergeJoin(c1 bmt4 bmt3 bmt2 bmt1) MergeJoin(b1t4 b1t3) HashJoin(b1t4 b1t3 b1t2) NestLoop(b1t4 b1t3 b1t2 b1t1) Rows(c1 bmt4 #1) Rows(c1 bmt4 bmt3 #1) Rows(c1 bmt4 bmt3 bmt2 #1) Rows(c1 bmt4 bmt3 bmt2 bmt1 #1) Rows(b1t4 b1t3 #1) Rows(b1t4 b1t3 b1t2 #1) Rows(b1t4 b1t3 b1t2 b1t1 #1) */ EXPLAIN WITH c1 (c1) AS ( SELECT b1t1.c1 FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT bmt1.c1, ( SELECT b2t1.c1 FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT b3t1.c1 FROM s1.t1 b3t1 ); '); ---- ---- No. R-2-3 RULE or VIEW ---- -- No. R-2-3-1 SELECT explain_filter(' /*+ Leading(r1 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r1 t1 t2 t3 t4) Rows(r1 t1 t2 t3 t4 #2) Rows(r1 t1 t2 t3 #2) Rows(r1 t1 t2 #2) Rows(r1 t1 #2) */ EXPLAIN UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r1_ b1t1 b1t2 b1t3 b1t4) */ EXPLAIN UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r1_ b1t1 b1t2 b1t3 b1t4) Rows(r1_ b1t1 b1t2 b1t3 b1t4 #2) Rows(r1_ b1t1 b1t2 b1t3 #2) Rows(r1_ b1t1 b1t2 #2) Rows(r1_ b1t1 #2) */ EXPLAIN UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1; '); -- No. R-2-3-2 SELECT explain_filter(' /*+ Leading(r2 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r2 t1 t2 t3 t4) Rows(r2 t1 t2 t3 t4 #2) Rows(r2 t1 t2 t3 #2) Rows(r2 t1 t2 #2) Rows(r2 t1 #2) */ EXPLAIN UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r2_ b1t1 b1t2 b1t3 b1t4) Leading(r2_ b2t1 b2t2 b2t3 b2t4) */ EXPLAIN UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r2_ b1t1 b1t2 b1t3 b1t4) Leading(r2_ b2t1 b2t2 b2t3 b2t4) Rows(r2_ b1t1 #2) Rows(r2_ b1t1 b1t2 #2) Rows(r2_ b1t1 b1t2 b1t3 #2) Rows(r2_ b1t1 b1t2 b1t3 b1t4 #2) Rows(r2_ b2t1 #2) Rows(r2_ b2t1 b2t2 #2) Rows(r2_ b2t1 b2t2 b2t3 #2) Rows(r2_ b2t1 b2t2 b2t3 b2t4 #2) */ EXPLAIN UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1; '); -- No. R-2-3-3 SELECT explain_filter(' /*+ Leading(r3 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r3 t1 t2 t3 t4) Rows(r3 t1 t2 t3 t4 #2) Rows(r3 t1 t2 t3 #2) Rows(r3 t1 t2 #2) Rows(r3 t1 #2) */ EXPLAIN UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r3_ b1t1 b1t2 b1t3 b1t4) Leading(r3_ b2t1 b2t2 b2t3 b2t4) Leading(r3_ b3t1 b3t2 b3t3 b3t4) */ EXPLAIN UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1; '); SELECT explain_filter(' /*+ Leading(r3_ b1t1 b1t2 b1t3 b1t4) Leading(r3_ b2t1 b2t2 b2t3 b2t4) Leading(r3_ b3t1 b3t2 b3t3 b3t4) Rows(r3_ b1t1 #2) Rows(r3_ b1t1 b1t2 #2) Rows(r3_ b1t1 b1t2 b1t3 #2) Rows(r3_ b1t1 b1t2 b1t3 b1t4 #2) Rows(r3_ b2t1 #2) Rows(r3_ b2t1 b2t2 #2) Rows(r3_ b2t1 b2t2 b2t3 #2) Rows(r3_ b2t1 b2t2 b2t3 b2t4 #2) Rows(r3_ b3t1 #2) Rows(r3_ b3t1 b3t2 #2) Rows(r3_ b3t1 b3t2 b3t3 #2) Rows(r3_ b3t1 b3t2 b3t3 b3t4 #2) */ EXPLAIN UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1; '); -- No. R-2-3-4 SELECT explain_filter(' /*+HashJoin(v1t1 v1t1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; '); SELECT explain_filter(' /*+HashJoin(v1t1 v1t1)Rows(v1t1 v1t1 #1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; '); -- No. R-2-3-5 SELECT explain_filter(' /*+NestLoop(v1t1 v1t1_)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; '); SELECT explain_filter(' /*+NestLoop(v1t1 v1t1_)Rows(v1t1 v1t1_ #1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; '); ---- ---- No. R-2-4 VALUES clause ---- -- No. R-2-4-1 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; '); SELECT explain_filter(' /*+ Leading(t3 t1 t2) Rows(t3 t1 #2)Rows(t3 t1 t2 #2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; '); SELECT explain_filter(' /*+ Leading(*VALUES* t1 t2) Rows(*VALUES* t1 #2)Rows(*VALUES* t1 t2 #20)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; '); -- No. R-2-4-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; '); SELECT explain_filter(' /*+ Leading(t4 t3 t2 t1) Rows(t4 t3 #2) Rows(t4 t3 t2 #2)Rows(t4 t3 t2 t1 #2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; '); SELECT explain_filter(' /*+ Leading(*VALUES* t3 t2 t1) Rows(t4 t3 #2)Rows(*VALUES* t3 t2 #2)Rows(*VALUES* t3 t2 t1 #2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2, (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t3 (c1, c2, c3, c4), (VALUES(1,1,1,''1''), (2,2,2,''2'')) AS t4 (c1, c2, c3, c4) WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1 AND t1.c1 = t4.c1; '); ---- ---- No. R-2-5 ---- -- No. R-2-5-1 SELECT explain_filter(' EXPLAIN SELECT max(bmt1.c1) FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt1 bmt2 bmt3 bmt4 *0.7) */ EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); -- No. R-2-5-2 SELECT explain_filter(' EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt4 bmt3 *0.6) */ EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); -- No. R-2-5-3 SELECT explain_filter(' EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); SELECT explain_filter(' /*+ Leading(bmt4 bmt3 bmt2 bmt1) Rows(bmt4 bmt1 *0.5) */ EXPLAIN SELECT bmt1.c1 FROM s1.t1 bmt1, (SELECT ctid, * FROM s1.t2 bmt2) sbmt2, (SELECT ctid, * FROM s1.t3 bmt3) sbmt3, (SELECT ctid, * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = sbmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; '); ---- ---- No. R-3-1 abusolute value ---- -- No. R-3-1-1 SELECT explain_filter(' /*+Rows(t1 t2 #0)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-3-1-2 SELECT explain_filter(' /*+Rows(t1 t2 #5)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-3-2 increase or decrease value ---- -- No. R-3-2-1 SELECT explain_filter(' /*+Rows(t1 t2 +1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-3-2-2 SELECT explain_filter(' /*+Rows(t1 t2 -1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-3-2-3 SELECT explain_filter(' /*+Rows(t1 t2 -1000)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-3-3 multiple ---- -- No. R-3-3-1 SELECT explain_filter(' /*+Rows(t1 t2 *0)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-3-3-2 SELECT explain_filter(' /*+Rows(t1 t2 *2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-3-3-3 SELECT explain_filter(' /*+Rows(t1 t2 *0.1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-3-4 join inherit tables ---- -- No. R-3-4-1 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; '); SELECT explain_filter(' /*+Rows(p1 p2 #1)*/ EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; '); -- No. R-3-4-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; '); SELECT explain_filter(' /*+Rows(p1c1 p2c1 #1)*/ EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; '); ---- ---- No. R-3-5 conflict join method hint ---- -- No. R-3-5-1 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-3-5-2 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(t1 t2 #1)Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-3-5-3 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 #1)Rows(t2 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); -- No. R-3-5-4 SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t2 t1 #1)Rows(t1 t2 #1)Rows(t2 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); ---- ---- No. R-3-6 hint state output ---- -- No. R-3-6-1 SET client_min_messages TO DEBUG1; SELECT explain_filter(' EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); SELECT explain_filter(' /*+Rows(t1 t2 +1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; '); pg_hint_plan-REL17_1_7_0/sql/ut-S.sql000066400000000000000000001277671466301071500173740ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; SET max_parallel_workers_per_gather TO 0; SET jit = off; EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; ---- ---- No. S-1-1 specified pattern of the object name ---- -- No. S-1-1-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-1-1-2 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1 WHERE t_1.c1 = 1; -- No. S-1-1-3 /*+SeqScan(t_1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 t_1 WHERE t_1.c1 = 1; ---- ---- No. S-1-2 specified schema name in the hint option ---- -- No. S-1-2-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-1-2-2 /*+SeqScan(s1.t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. S-1-3 table doesn't exist in the hint option ---- -- No. S-1-3-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-1-3-2 /*+SeqScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; ---- ---- No. S-1-4 conflict table name ---- -- No. S-1-4-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = 1 AND t1.c1 = t2.c1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = 1 AND t1.c1 = t2.c1; -- No. S-1-4-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = 1 AND s1.t1.c1 = s2.t1.c1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = 1 AND s1.t1.c1 = s2.t1.c1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = 1 AND s1.t1.c1 = s2t1.c1; /*+BitmapScan(s2t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = 1 AND s1.t1.c1 = s2t1.c1; -- No. S-1-4-3 EXPLAIN (COSTS false) SELECT (SELECT max(c1) FROM s1.t1 WHERE s1.t1.c1 = 1) FROM s1.t1 WHERE s1.t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT (SELECT max(c1) FROM s1.t1 WHERE s1.t1.c1 = 1) FROM s1.t1 WHERE s1.t1.c1 = 1; /*+BitmapScan(t11)*/ EXPLAIN (COSTS false) SELECT (SELECT max(c1) FROM s1.t1 t11 WHERE t11.c1 = 1) FROM s1.t1 t12 WHERE t12.c1 = 1; /*+BitmapScan(t12)*/ EXPLAIN (COSTS false) SELECT (SELECT max(c1) FROM s1.t1 t11 WHERE t11.c1 = 1) FROM s1.t1 t12 WHERE t12.c1 = 1; ---- ---- No. S-1-5 object type for the hint ---- -- No. S-1-5-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-1-5-2 EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE p1.c1 = 1; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE p1.c1 = 1; -- No. S-1-5-3 EXPLAIN (COSTS false) SELECT * FROM s1.ul1 WHERE ul1.c1 = 1; /*+SeqScan(ul1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ul1 WHERE ul1.c1 = 1; -- No. S-1-5-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); EXPLAIN (COSTS false) SELECT * FROM tm1 WHERE tm1.c1 = 1; /*+SeqScan(tm1)*/ EXPLAIN (COSTS false) SELECT * FROM tm1 WHERE tm1.c1 = 1; -- No. S-1-5-5 EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class WHERE oid = 1; /*+SeqScan(pg_class)*/ EXPLAIN (COSTS false) SELECT * FROM pg_catalog.pg_class WHERE oid = 1; -- No. S-1-5-6 -- refer ut-fdw.sql -- No. S-1-5-7 EXPLAIN (COSTS false) SELECT * FROM s1.f1() AS ft1 WHERE ft1.c1 = 1; /*+SeqScan(ft1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.f1() AS ft1 WHERE ft1.c1 = 1; -- No. S-1-5-8 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS val1 (c1, c2, c3, c4) WHERE val1.c1 = 1; /*+SeqScan(val1)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS val1 (c1, c2, c3, c4) WHERE val1.c1 = 1; /*+SeqScan(*VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3')) AS val1 (c1, c2, c3, c4) WHERE val1.c1 = 1; -- No. S-1-5-9 EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT max(c1) FROM s1.t1 WHERE t1.c1 = 1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = 1 AND t1.c1 = c1.c1; /*+SeqScan(c1)*/ EXPLAIN (COSTS false) WITH c1(c1) AS (SELECT max(c1) FROM s1.t1 WHERE t1.c1 = 1) SELECT * FROM s1.t1, c1 WHERE t1.c1 = 1 AND t1.c1 = c1.c1; -- No. S-1-5-10 EXPLAIN (COSTS false) SELECT * FROM s1.v1 WHERE v1.c1 = 1; /*+SeqScan(v1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 WHERE v1.c1 = 1; -- No. S-1-5-11 EXPLAIN (COSTS false) SELECT * FROM (SELECT * FROM s1.t1 WHERE t1.c1 = 1) AS s1 WHERE s1.c1 = 1; /*+SeqScan(s1)*/ EXPLAIN (COSTS false) SELECT * FROM (SELECT * FROM s1.t1 WHERE t1.c1 = 1) AS s1 WHERE s1.c1 = 1; ---- ---- No. S-2-1 some complexity query blocks ---- -- No. S-2-1-1 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; -- No. S-2-1-2 EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1), ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 ; -- No. S-2-1-3 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, (SELECT * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = sbmt4.c1; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, (SELECT * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = sbmt4.c1; -- No. S-2-1-4 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT * FROM s1.t3 bmt3) sbmt3, (SELECT * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, (SELECT * FROM s1.t3 bmt3) sbmt3, (SELECT * FROM s1.t4 bmt4) sbmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = sbmt3.c1 AND bmt1.c1 = sbmt4.c1; -- No. S-2-1-5 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) ; -- No. S-2-1-6 EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) */ EXPLAIN (COSTS false) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 <> ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) AND bmt1.c1 <> ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) ; -- No. S-2-1-7 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 ; -- No. S-2-1-8 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.c1 = b1t2.c1 AND b1t1.c1 = b1t3.c1 AND b1t1.c1 = b1t4.c1 ) , c2 (c1) AS ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.c1 = b2t2.c1 AND b2t1.c1 = b2t3.c1 AND b2t1.c1 = b2t4.c1 ) SELECT max(bmt1.c1) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4 , c1, c2 WHERE bmt1.c1 = bmt2.c1 AND bmt1.c1 = bmt3.c1 AND bmt1.c1 = bmt4.c1 AND bmt1.c1 = c1.c1 AND bmt1.c1 = c2.c1 ; ---- ---- No. S-2-2 the number of the tables per quiry block ---- -- No. S-2-2-1 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; /*+SeqScan(bmt1) TidScan(b1t1) BitmapScan(b2t1 t1_pkey) IndexScan(b3t1 t1_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = 1 ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = 1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = 1 ) ; -- No. S-2-2-2 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey) TidScan(b1t1)SeqScan(b1t2) BitmapScan(b2t1 t1_pkey)TidScan(b2t2) IndexScan(b3t1 t1_pkey)BitmapScan(b3t2 t2_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' ) ; -- No. S-2-2-3 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) IndexScan(b3t1 t1_pkey)BitmapScan(b3t2 t2_pkey)TidScan(b3t3)SeqScan(b3t4) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)' ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)' ) ; -- No. S-2-2-4 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; /*+SeqScan(bmt1)IndexScan(bmt2 t2_pkey)BitmapScan(bmt3 t3_pkey)TidScan(bmt4) TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey) IndexScan(b3t1 t1_pkey) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)' ) SELECT max(bmt1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = 1 ) FROM s1.t1 bmt1, s1.t2 bmt2, s1.t3 bmt3, s1.t4 bmt4, c1 WHERE bmt1.ctid = '(1,1)' AND bmt1.c1 = bmt2.c1 AND bmt2.ctid = '(1,1)' AND bmt1.c1 = bmt3.c1 AND bmt3.ctid = '(1,1)' AND bmt1.c1 = bmt4.c1 AND bmt4.ctid = '(1,1)' AND bmt1.c1 = c1.c1 AND bmt1.c1 <> ( SELECT max(b3t1.c1) FROM s1.t1 b3t1 WHERE b3t1.ctid = '(1,1)' ) ; ---- ---- No. S-2-3 RULE or VIEW ---- -- No. S-2-3-1 EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+TidScan(t1)SeqScan(t2)IndexScan(t3 t3_pkey)BitmapScan(t4 t4_pkey) SeqScan(r1)*/ EXPLAIN (COSTS false) UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) SeqScan(r1_)*/ EXPLAIN (COSTS false) UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-2-3-2 EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+TidScan(t1)SeqScan(t2)IndexScan(t3 t3_pkey)BitmapScan(t4 t4_pkey) SeqScan(r2)*/ EXPLAIN (COSTS false) UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) SeqScan(r2_)*/ EXPLAIN (COSTS false) UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-2-3-3 EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+TidScan(t1)SeqScan(t2)IndexScan(t3 t3_pkey)BitmapScan(t4 t4_pkey) SeqScan(r3)*/ EXPLAIN (COSTS false) UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; /*+TidScan(b1t1)SeqScan(b1t2)IndexScan(b1t3 t3_pkey)BitmapScan(b1t4 t4_pkey) BitmapScan(b2t1 t1_pkey)TidScan(b2t2)SeqScan(b2t3)IndexScan(b2t4 t4_pkey) IndexScan(b3t1 t1_pkey)BitmapScan(b3t2 t2_pkey)TidScan(b3t3)SeqScan(b3t4) SeqScan(r3_)*/ EXPLAIN (COSTS false) UPDATE s1.r3_ SET c1 = c1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-2-3-4 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; /*+BitmapScan(v1t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; -- No. S-2-3-5 EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; /*+SeqScan(v1t1)BitmapScan(v1t1_)*/ EXPLAIN (COSTS false) SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; ---- ---- No. S-2-4 VALUES clause ---- -- No. S-2-4-1 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1')) AS t1 (c1) WHERE t1.c1 = 1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1')) AS t1 (c1) WHERE t1.c1 = 1; /*+SeqScan(*VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1')) AS t1 (c1) WHERE t1.c1 = 1; -- No. S-2-4-2 EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t2 (c1, c2) WHERE t1.c1 = t2.c1; /*+SeqScan(t1 t2)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t2 (c1, c2) WHERE t1.c1 = t2.c1; /*+SeqScan(*VALUES*)*/ EXPLAIN (COSTS false) SELECT * FROM (VALUES(1,1,1,'1'), (3,3,3,'3')) AS t1 (c1, c2, c3, c4), (VALUES(1,1,1,'1'), (2,2,2,'2')) AS t2 (c1, c2) WHERE t1.c1 = t2.c1; ---- ---- No. S-3-1 scan method hint ---- -- No. S-3-1-1 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; -- No. S-3-1-2 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-3 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-4 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; /*+IndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; -- No. S-3-1-5 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; -- No. S-3-1-6 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+BitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-7 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; /*+TidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; -- No. S-3-1-8 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid IN ('(1,1)', '(2,2)', '(3,3)'); /*+TidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid IN ('(1,1)', '(2,2)', '(3,3)'); -- No. S-3-1-9 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; /*+NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; -- No. S-3-1-10 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+NoSeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-11 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-12 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; /*+NoIndexScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 >= 1; -- No. S-3-1-13 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c3 < 10; -- No. S-3-1-14 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+NoBitmapScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-15 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1 AND t1.ctid = '(1,1)'; -- No. S-3-1-16 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; /*+NoTidScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-17 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; /*+IndexOnlyScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-18 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 >= 1; /*+IndexOnlyScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 >= 1; -- No. S-3-1-19 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; /*+NoIndexOnlyScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 = 1; -- No. S-3-1-20 EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 >= 1; /*+NoIndexOnlyScan(t1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.t1 WHERE t1.c1 >= 1; ---- ---- No. S-3-3 index name specified ---- EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; SET enable_tidscan TO off; EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; SET enable_indexscan TO off; EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; RESET enable_tidscan; RESET enable_indexscan; EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE ti1.c2 >= 1; -- No. S-3-3-1 /*+IndexScan(ti1 ti1_i3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; -- No. S-3-3-2 /*+IndexScan(ti1 ti1_i3 ti1_i2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; -- No. S-3-3-3 /*+IndexScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; -- No. S-3-3-4 /*+BitmapScan(ti1 ti1_i3)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; -- No. S-3-3-5 /*+BitmapScan(ti1 ti1_i3 ti1_i2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; -- No. S-3-3-6 /*+BitmapScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE ti1.c2 = 1 AND ctid = '(1,1)'; -- No. S-3-3-7 /*+IndexOnlyScan(ti1 ti1_i3)*/ EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE ti1.c2 >= 1; -- No. S-3-3-8 /*+IndexOnlyScan(ti1 ti1_i3 ti1_i2)*/ EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE ti1.c2 >= 1; -- No. S-3-3-9 /*+IndexOnlyScan(ti1 ti1_i4 ti1_i3 ti1_i2 ti1_i1)*/ EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE ti1.c2 >= 1; ---- ---- No. S-3-4 index type ---- \d s1.ti1 EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-1 /*+IndexScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-2 /*+IndexScan(ti1 ti1_hash)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-3 /*+IndexScan(ti1 ti1_gist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-4 /*+IndexScan(ti1 ti1_gin)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-5 /*+IndexScan(ti1 ti1_expr)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-6 /*+IndexScan(ti1 ti1_pred)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-7 /*+IndexScan(ti1 ti1_uniq)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-8 /*+IndexScan(ti1 ti1_multi)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-9 /*+IndexScan(ti1 ti1_ts)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-10 /*+IndexScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-11 /*+IndexScan(ti1 ti1_c2_key)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-12 /*+BitmapScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-13 /*+BitmapScan(ti1 ti1_hash)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-14 /*+BitmapScan(ti1 ti1_gist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-15 /*+BitmapScan(ti1 ti1_gin)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-16 /*+BitmapScan(ti1 ti1_expr)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-17 /*+BitmapScan(ti1 ti1_pred)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-18 /*+BitmapScan(ti1 ti1_uniq)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-19 /*+BitmapScan(ti1 ti1_multi)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-20 /*+BitmapScan(ti1 ti1_ts)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-21 /*+BitmapScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-22 /*+BitmapScan(ti1 ti1_c2_key)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)'; -- No. S-3-4-23 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; /*+IndexOnlyScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; -- No. S-3-4-24 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; /*+IndexOnlyScan(ti1 ti1_hash)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; -- No. S-3-4-25 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 < 1; /*+IndexOnlyScan(ti1 ti1_gist)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 < 1; -- No. S-3-4-26 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; /*+IndexOnlyScan(ti1 ti1_gin)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; -- No. S-3-4-27 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 < 100; /*+IndexOnlyScan(ti1 ti1_expr)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 < 100; -- No. S-3-4-28 EXPLAIN (COSTS false) SELECT c4 FROM s1.ti1 WHERE lower(c4) >= '1'; /*+IndexOnlyScan(ti1 ti1_pred)*/ EXPLAIN (COSTS false) SELECT c4 FROM s1.ti1 WHERE lower(c4) >= '1'; -- No. S-3-4-29 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; /*+IndexOnlyScan(ti1 ti1_uniq)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; -- No. S-3-4-30 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; /*+IndexOnlyScan(ti1 ti1_multi)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; -- No. S-3-4-31 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE to_tsvector('english', c4) @@ 'a & b'; /*+IndexOnlyScan(ti1 ti1_ts)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE to_tsvector('english', c4) @@ 'a & b'; -- No. S-3-4-32 EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; /*+IndexOnlyScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; -- No. S-3-4-33 EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE c2 >= 1; /*+IndexOnlyScan(ti1 ti1_c2_key)*/ EXPLAIN (COSTS false) SELECT c2 FROM s1.ti1 WHERE c2 >= 1; ---- ---- No. S-3-5 not used index ---- -- No. S-3-5-1 SELECT explain_filter(' /*+IndexScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; '); -- No. S-3-5-2 SELECT explain_filter(' /*+BitmapScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; '); -- No. S-3-5-3 SELECT explain_filter(' /*+IndexOnlyScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT c1 FROM s1.ti1 WHERE c1 = 100; '); -- No. S-3-5-4 SELECT explain_filter(' /*+IndexScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; '); -- No. S-3-5-5 SELECT explain_filter(' /*+BitmapScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; '); -- No. S-3-5-6 SELECT explain_filter(' /*+IndexOnlyScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT c1 FROM s1.ti1 WHERE c1 = 100; '); -- No. S-3-5-7 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; SELECT explain_filter(' /*+TidScan(t1)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1 WHERE t1.c1 = 1; '); ---- ---- No. S-3-6 query structure ---- EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)'; -- No. S-3-6-1 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE c1 = 100; -- No. S-3-6-2 /*+SeqScan(t1)BitmapScan(t2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)'; -- No. S-3-6-3 /*+SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1 AND t1.ctid = '(1,1)'; ---- ---- No. S-3-7 number of tables in a query block ---- -- No. S-3-7-1 EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 WHERE b4t1.c1 = 1); /*+SeqScan(b1t1)IndexScan(b2t1 t1_pkey)BitmapScan(b3t1 t1_pkey)TidScan(b4t1) */ EXPLAIN (COSTS false) WITH c1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 WHERE b4t1.c1 = 1); -- No. S-3-7-2 EXPLAIN (COSTS false) WITH cte1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 JOIN s1.t2 b1t2 ON(b1t1.c1 = b1t2.c1) WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 JOIN s1.t2 b2t2 ON(b2t1.c1 = b2t2.c1) WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 JOIN s1.t2 b3t2 ON(b3t1.c1 = b3t2.c1) JOIN cte1 ON(b3t1.c1 = cte1.c1) WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 JOIN s1.t2 b4t2 ON(b4t1.c1 = b4t2.c1) WHERE b4t1.c1 = 1); /*+SeqScan(b1t1)IndexScan(b2t1 t1_pkey)BitmapScan(b3t1 t1_pkey)TidScan(b4t1) TidScan(b1t2)SeqScan(b2t2)IndexScan(b3t2 t2_pkey)BitmapScan(b4t2 t2_pkey) */ EXPLAIN (COSTS false) WITH cte1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 JOIN s1.t2 b1t2 ON(b1t1.c1 = b1t2.c1) WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 JOIN s1.t2 b2t2 ON(b2t1.c1 = b2t2.c1) WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 JOIN s1.t2 b3t2 ON(b3t1.c1 = b3t2.c1) JOIN cte1 ON(b3t1.c1 = cte1.c1) WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 JOIN s1.t2 b4t2 ON(b4t1.c1 = b4t2.c1) WHERE b4t1.c1 = 1); -- No. S-3-7-3 EXPLAIN (COSTS false) WITH cte1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 JOIN s1.t2 b1t2 ON(b1t1.c1 = b1t2.c1) WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 JOIN s1.t2 b3t2 ON(b3t1.c1 = b3t2.c1) JOIN cte1 ON(b3t1.c1 = cte1.c1) WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 WHERE b4t1.c1 = 1); /*+SeqScan(b1t1)IndexScan(b2t1 t1_pkey)BitmapScan(b3t1 t1_pkey)TidScan(b4t1) TidScan(b1t2)IndexScan(b3t2 t2_pkey) */ EXPLAIN (COSTS false) WITH cte1 (c1) AS ( SELECT max(b1t1.c1) FROM s1.t1 b1t1 JOIN s1.t2 b1t2 ON(b1t1.c1 = b1t2.c1) WHERE b1t1.c1 = 1) SELECT max(b3t1.c1), ( SELECT max(b2t1.c1) FROM s1.t1 b2t1 WHERE b2t1.c1 = 1 ) FROM s1.t1 b3t1 JOIN s1.t2 b3t2 ON(b3t1.c1 = b3t2.c1) JOIN cte1 ON(b3t1.c1 = cte1.c1) WHERE b3t1.c1 = ( SELECT max(b4t1.c1) FROM s1.t1 b4t1 WHERE b4t1.c1 = 1); ---- ---- No. S-3-8 inheritance table select/update type ---- -- No. S-3-8-1 EXPLAIN (COSTS false) SELECT * FROM ONLY s1.p1 WHERE c1 = 1; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM ONLY s1.p1 WHERE c1 = 1; -- No. S-3-8-2 EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; -- No. S-3-8-3 EXPLAIN (COSTS false) UPDATE ONLY s1.p1 SET c4 = c4 WHERE c1 = 1; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) UPDATE ONLY s1.p1 SET c4 = c4 WHERE c1 = 1; /*+IndexScan(p1 p1_pkey)*/ EXPLAIN (COSTS false) UPDATE ONLY s1.p1 SET c4 = c4 WHERE c1 = 1; -- No. S-3-8-4 EXPLAIN (COSTS false) UPDATE s1.p1 SET c4 = c4 WHERE c1 = 1; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) UPDATE s1.p1 SET c4 = c4 WHERE c1 = 1; /*+IndexScan(p1 p1_pkey)*/ EXPLAIN (COSTS false) UPDATE s1.p1 SET c4 = c4 WHERE c1 = 1; ---- ---- No. S-3-9 inheritance table number ---- -- No. S-3-9-1 EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; /*+IndexScan(p1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; -- No. S-3-9-2 EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; /*+IndexScan(p2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; ---- ---- No. S-3-10 inheritance table specified table ---- EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; -- No. S-3-10-1 /*+IndexScan(p2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; -- No. S-3-10-2 /*+IndexScan(p2c1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p2 WHERE c1 = 1; -- No. S-3-10-3 SELECT explain_filter(' EXPLAIN SELECT c4 FROM s1.p1 WHERE c2 * 2 < 100 AND c1 < 10; '); SELECT explain_filter(' /*+IndexScan(p1 p1_parent)*/ EXPLAIN SELECT c4 FROM s1.p1 WHERE c2 * 2 < 100 AND c1 < 10; '); -- No. S-3-10-4 SELECT explain_filter(' /*+IndexScan(p1 p1_i2)*/ EXPLAIN SELECT c2 FROM s1.p1 WHERE c2 = 1; '); -- No. S-3-10-5 SELECT explain_filter(' /*+IndexScan(p2 p2c1_pkey)*/ EXPLAIN (COSTS true) SELECT * FROM s1.p2 WHERE c1 = 1; '); ---- ---- No. S-3-12 specified same table ---- -- No. S-3-12-1 /*+IndexScan(ti1) BitmapScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-12-2 /*+IndexScan(ti1 ti1_pkey) BitmapScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-12-3 /*+BitmapScan(ti1) IndexScan(ti1) BitmapScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-12-4 /*+BitmapScan(ti1 ti1_hash) IndexScan(ti1 ti1_pkey) BitmapScan(ti1 ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; ---- ---- No. S-3-13 message output of hint ---- -- No. S-3-13-1 /*+SeqScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-2 /*+SeqScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-3 /*+SeqScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-4 /*+IndexScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-5 /*+IndexScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-6 /*+IndexScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-7 /*+BitmapScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-8 /*+BitmapScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-9 /*+BitmapScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-10 /*+TidScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-11 /*+TidScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-12 /*+TidScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-13 /*+NoSeqScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-14 /*+NoSeqScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-15 /*+NoSeqScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-16 /*+NoIndexScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-17 /*+NoIndexScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-18 /*+NoIndexScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-19 /*+NoBitmapScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-20 /*+NoBitmapScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-21 /*+NoBitmapScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-22 /*+NoTidScan(ti1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-23 /*+NoTidScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-24 /*+NoTidScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 = 1 AND ctid = '(1,1)'; -- No. S-3-13-25 /*+IndexOnlyScan(ti1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; -- No. S-3-13-26 /*+IndexOnlyScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; -- No. S-3-13-27 /*+IndexOnlyScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 >= 1; -- No. S-3-13-28 /*+NoIndexOnlyScan(ti1)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; -- No. S-3-13-29 /*+NoIndexOnlyScan(ti1 ti1_pkey)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; -- No. S-3-13-30 /*+NoIndexOnlyScan(ti1 ti1_pkey ti1_btree)*/ EXPLAIN (COSTS false) SELECT c1 FROM s1.ti1 WHERE c1 = 1; ---- ---- No. S-3-14 regular expression ---- EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; -- No. S-3-14-1 /*+IndexScanRegexp(ti1 ti1_.*_key)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; -- No. S-3-14-2 /*+IndexScanRegexp(ti1 ti1_i.)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; -- No. S-3-14-3 /*+IndexScanRegexp(ti1 no.*_exist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; -- No. S-3-14-4 /*+IndexScanRegexp(p1 .*pkey)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; -- No. S-3-14-5 /*+IndexScanRegexp(p1 p1.*i)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; -- No. S-3-14-6 /*+IndexScanRegexp(p1 no.*_exist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1; ---- ---- No. S-3-15 message output of index candidate ---- -- No. S-3-15-1 /*+IndexScan(ti1 ti1_i1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; -- No. S-3-15-2 /*+IndexScan(ti1 not_exist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; -- No. S-3-15-3 /*+IndexScan(ti1 ti1_i1 ti1_i2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; -- No. S-3-15-4 /*+IndexScan(ti1 ti1_i1 not_exist)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; -- No. S-3-15-5 /*+IndexScan(ti1 not_exist1 not_exist2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; pg_hint_plan-REL17_1_7_0/sql/ut-T.sql000066400000000000000000000024301466301071500173500ustar00rootroot00000000000000-- ut-T: tests for table hints -- This test is focusing on hint retrieval from table LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET search_path TO public; -- This hint affects queries with an equivalent query ID when executed as -- a subquery. SET pg_hint_plan.enable_hint_table TO on; SELECT get_query_id('SELECT * FROM t1 WHERE id = 1;') AS query_id \gset INSERT INTO hint_plan.hints VALUES (DEFAULT, :'query_id', '', 'SeqScan(t1)'); PREPARE p1 AS SELECT * FROM t1 WHERE id = 100; -- These queries uses IndexScan without hints SET pg_hint_plan.enable_hint_table to off; EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id = 100; EXPLAIN (COSTS false) EXECUTE p1; DEALLOCATE p1; PREPARE p1 AS SELECT * FROM t1 WHERE id = 100; EXPLAIN (COSTS false) CREATE TABLE ct1 AS EXECUTE p1; DEALLOCATE p1; PREPARE p1 AS SELECT * FROM t1 WHERE id = 100; -- Forced to use SeqScan by table hints SET pg_hint_plan.enable_hint_table to on; EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id = 100; EXPLAIN (COSTS false) EXECUTE p1; DEALLOCATE p1; PREPARE p1 AS SELECT * FROM t1 WHERE id = 100; EXPLAIN (COSTS false) CREATE TABLE ct1 AS EXECUTE p1; DEALLOCATE p1; SET pg_hint_plan.enable_hint_table to off; DELETE FROM hint_plan.hints; pg_hint_plan-REL17_1_7_0/sql/ut-W.sql000066400000000000000000000202721466301071500173570ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET pg_hint_plan.enable_hint TO on; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; -- Queries on ordinary tables with default setting EXPLAIN (COSTS false) SELECT * FROM s1.t1; -- Note that parallel is not enforced on a single relation without -- the GUCs related to parallelism reset. /*+Parallel(t1 5 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1; -- Still it works for multiple relations. /*+Parallel(t11 5 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 as t11, s1.t1 as t12; SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET max_parallel_workers_per_gather to DEFAULT; /*+Parallel(t1 8)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1; /*+Parallel(t1 8 soft)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1; /*+Parallel(t1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1; /*+Parallel(t1 4 hard) */ /* to be gather merge*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 ORDER BY s1.t1.c1 LIMIT 4; -- Queries on inheritance tables SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET enable_parallel_append to false; /*+Parallel(p1 8)*/ EXPLAIN (COSTS false) SELECT * FROM p1; SET enable_parallel_append to true; /*+Parallel(p1 8)*/ EXPLAIN (COSTS false) SELECT * FROM p1; SET parallel_setup_cost to DEFAULT; SET parallel_tuple_cost to DEFAULT; SET min_parallel_table_scan_size to DEFAULT; SET min_parallel_index_scan_size to DEFAULT; SET enable_parallel_append to false; /*+Parallel(p1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; SET enable_parallel_append to true; /*+Parallel(p1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; -- hinting on children doesn't work (changed as of pg_hint_plan 10) SET enable_parallel_append to false; /*+Parallel(p1_c1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; SET enable_parallel_append to true; /*+Parallel(p1_c1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; -- Joins EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; /*+Parallel(p1_c1_c1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; /*+Parallel(p1_c1_c1 8 soft) Parallel(p2_c1_c1 0)*/ EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; /*+Parallel(p1_c1_c1 8 hard) Parallel(p2_c1_c1 0)*/ EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; /*+Parallel(p1_c1_c1 8 hard) Parallel(p2_c1_c1 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1_c1_c1 join p2_c1_c1 on p1_c1_c1.id = p2_c1_c1.id; -- Joins on inheritance tables SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET enable_parallel_append to false; /*+Parallel(p1 8)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; SET enable_parallel_append to true; /*+Parallel(p1 8)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; SET enable_parallel_append to false; /*+Parallel(p1 8)Parallel(p2 0)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; SET enable_parallel_append to true; /*+Parallel(p1 8)Parallel(p2 0)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; SET parallel_setup_cost to DEFAULT; SET parallel_tuple_cost to DEFAULT; SET min_parallel_table_scan_size to DEFAULT; SET min_parallel_index_scan_size to DEFAULT; /*+Parallel(p2 8 soft)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; /*+Parallel(p2 8 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; -- Number of workers results to the largest number SET enable_parallel_append to false; /*+Parallel(p2 8 hard) Parallel(p1 5 hard) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; SET enable_parallel_append to true; /*+Parallel(p2 8 hard) Parallel(p1 5 hard) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; -- Mixture with scan hints -- p1 can be parallel SET enable_parallel_append to false; /*+Parallel(p1 8 hard) IndexScan(p2) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; SET enable_parallel_append to true; /*+Parallel(p1 8 hard) IndexScan(p2) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; -- Parallel sequential scan SET enable_parallel_append to false; /*+Parallel(p1 8 hard) SeqScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; SET enable_parallel_append to true; /*+Parallel(p1 8 hard) SeqScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; -- Parallel index scan SET enable_parallel_append to false; /*+Parallel(p1 8 hard) IndexScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; SET enable_parallel_append to true; /*+Parallel(p1 8 hard) IndexScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; -- This hint doesn't turn on parallel, so the Parallel hint is ignored set max_parallel_workers_per_gather TO 0; /*+Parallel(p1 0 hard) IndexScan(p1) */ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id; -- Parallel on UNION EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; -- parallel hinting on any relation enables parallel SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET max_parallel_workers_per_gather to 0; /*+Parallel(p1 8) */ EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; -- set hint has the same effect /*+Set(max_parallel_workers_per_gather 1)*/ EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; -- applies largest number of workers on merged parallel paths SET parallel_setup_cost to DEFAULT; SET parallel_tuple_cost to DEFAULT; SET min_parallel_table_scan_size to DEFAULT; SET min_parallel_index_scan_size to DEFAULT; SET max_parallel_workers_per_gather to 8; /*+Parallel(p1 5 hard)Parallel(p2 6 hard) */ EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; -- On empty tables, parallel hints can only be enforced for index scans -- and not sequential scans. Adding a single row allows a parallel -- hint to be enforced on a sequential scan. It is a bit weird that -- having no rows controls how parallel workers are triggered, but -- at the same time we have nothing to query, and this is an old -- historical (and accidental) behavior. /*+Parallel(t5 4 hard) Parallel(t6 2 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t5 NATURAL JOIN s1.t6; /*+Parallel(t5 4 hard) Parallel(t6 2 hard) NoSeqScan(t5) NoSeqScan(t6) */ EXPLAIN (COSTS false) SELECT * FROM s1.t5 NATURAL JOIN s1.t6; INSERT INTO s1.t5 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 1) i) t; INSERT INTO s1.t6 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 1) i) t; ANALYZE s1.t5; ANALYZE s1.t6; /*+Parallel(t5 4 hard) Parallel(t6 2 hard)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t5 NATURAL JOIN s1.t6; -- Negative hints SET enable_indexscan to DEFAULT; SET parallel_setup_cost to 0; SET parallel_tuple_cost to 0; SET min_parallel_table_scan_size to 0; SET min_parallel_index_scan_size to 0; SET max_parallel_workers_per_gather to 5; EXPLAIN (COSTS false) SELECT * FROM p1; SET enable_parallel_append to false; /*+Parallel(p1 0 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; SET enable_parallel_append to true; /*+Parallel(p1 0 hard)*/ EXPLAIN (COSTS false) SELECT * FROM p1; -- Errors /*+Parallel(p1 100x hard)Parallel(p1 -1000 hard)Parallel(p1 1000000 hard) Parallel(p1 8 hoge)Parallel(p1)Parallel(p1 100 soft x)*/ EXPLAIN (COSTS false) SELECT id FROM p1 UNION ALL SELECT id FROM p2; -- Hints on unhintable relations are just ignored SELECT explain_filter(' /*+Parallel(p1 5 hard) Parallel(s1 3 hard) IndexScan(ft1) SeqScan(cte1) IndexScan(t) IndexScan(*VALUES*) */ EXPLAIN (COSTS false) SELECT id FROM p1_c1_c1 as s1 TABLESAMPLE SYSTEM(10) UNION ALL SELECT id FROM ft1 UNION ALL (WITH cte1 AS (SELECT id FROM p1 WHERE id % 2 = 0) SELECT id FROM cte1) UNION ALL SELECT x FROM (VALUES (1), (2), (3)) t(x); '); pg_hint_plan-REL17_1_7_0/sql/ut-fdw.sql000066400000000000000000000032111466301071500177230ustar00rootroot00000000000000-- directory paths and dlsuffix are passed to us in environment variables \getenv abs_srcdir PG_ABS_SRCDIR \set filename :abs_srcdir '/data/data.csv' LOAD 'pg_hint_plan'; SET search_path TO public; SET pg_hint_plan.debug_print TO on; SET client_min_messages TO LOG; SET pg_hint_plan.enable_hint TO on; CREATE EXTENSION file_fdw; CREATE SERVER file_server FOREIGN DATA WRAPPER file_fdw; CREATE USER MAPPING FOR PUBLIC SERVER file_server; CREATE FOREIGN TABLE ft1 (id int, val int) SERVER file_server OPTIONS (format 'csv', filename :'filename'); -- foreign table test SELECT * FROM ft1; \t SELECT explain_filter(' EXPLAIN (COSTS false) SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); ---- ---- No. S-1-5 object type for the hint ---- -- No. S-1-5-6 SELECT explain_filter(' /*+SeqScan(t1)SeqScan(ft_1)SeqScan(ft_2)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); ---- ---- No. J-1-6 object type for the hint ---- -- No. J-1-6-6 SELECT explain_filter(' /*+MergeJoin(ft_1 ft_2)Leading(ft_1 ft_2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); ---- ---- No. L-1-6 object type for the hint ---- -- No. L-1-6-6 SELECT explain_filter(' /*+Leading(ft_1 ft_2 t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); ---- ---- No. R-1-6 object type for the hint ---- -- No. R-1-6-6 SELECT explain_filter(' /*+Rows(ft_1 ft_2 #1)Leading(ft_1 ft_2 t1)*/ EXPLAIN SELECT * FROM s1.t1, ft1 ft_1, ft1 ft_2 WHERE t1.c1 = ft_1.id AND t1.c1 = ft_2.id; '); pg_hint_plan-REL17_1_7_0/sql/ut-fini.sql000066400000000000000000000001561466301071500200750ustar00rootroot00000000000000DROP ROLE IF EXISTS regress_super_user; DROP ROLE IF EXISTS regress_normal_user; DROP EXTENSION pg_hint_plan; pg_hint_plan-REL17_1_7_0/sql/ut-init.sql000066400000000000000000000223321466301071500201130ustar00rootroot00000000000000SET search_path TO public; CREATE EXTENSION btree_gist; CREATE EXTENSION btree_gin; CREATE ROLE regress_super_user SUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION CONNECTION LIMIT 1; CREATE ROLE regress_normal_user NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION CONNECTION LIMIT 1; CREATE SCHEMA s1; CREATE SCHEMA s2; CREATE TABLE s1.t1 (c1 int, c2 int, c3 int, c4 text, PRIMARY KEY (c1)); CREATE TABLE s1.t2 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.t3 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.t4 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.t5 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.t6 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s2.t1 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.p1 (LIKE s1.t1 INCLUDING ALL); CREATE UNIQUE INDEX p1_parent ON s1.p1 USING btree (c4 COLLATE "C" varchar_ops ASC NULLS LAST, (c1 * 2 < 100)) WHERE c1 < 10; CREATE TABLE s1.p2 (LIKE s1.t1 INCLUDING ALL); CREATE TABLE s1.p1c1 (LIKE s1.p1 INCLUDING ALL, CHECK (c1 <= 100)) INHERITS(s1.p1); CREATE TABLE s1.p1c2 (LIKE s1.p1 INCLUDING ALL, CHECK (c1 > 100 AND c1 <= 200)) INHERITS(s1.p1); CREATE TABLE s1.p1c3 (LIKE s1.p1 INCLUDING ALL, CHECK (c1 > 200)) INHERITS(s1.p1); CREATE TABLE s1.p2c1 (LIKE s1.p2 INCLUDING ALL, CHECK (c1 <= 100)) INHERITS(s1.p2); CREATE TABLE s1.p2c2 (LIKE s1.p2 INCLUDING ALL, CHECK (c1 > 100 AND c1 <= 200)) INHERITS(s1.p2); CREATE TABLE s1.p2c3 (LIKE s1.p2 INCLUDING ALL, CHECK (c1 > 200)) INHERITS(s1.p2); CREATE TABLE s1.p2c1c1 (LIKE s1.p2c1 INCLUDING ALL, CHECK (c1 <= 50)) INHERITS(s1.p2c1); CREATE TABLE s1.p2c1c2 (LIKE s1.p2c1 INCLUDING ALL, CHECK (c1 > 50 AND c1 <= 100)) INHERITS(s1.p2c1); CREATE TABLE s1.p2c2c1 (LIKE s1.p2c2 INCLUDING ALL, CHECK (c1 > 100 AND c1 <= 150)) INHERITS(s1.p2c2); CREATE TABLE s1.p2c2c2 (LIKE s1.p2c2 INCLUDING ALL, CHECK (c1 > 150 AND c1 <= 200)) INHERITS(s1.p2c2); CREATE TABLE s1.p2c3c1 (LIKE s1.p2c3 INCLUDING ALL, CHECK (c1 > 200 AND c1 <= 250)) INHERITS(s1.p2c3); CREATE TABLE s1.p2c3c2 (LIKE s1.p2c3 INCLUDING ALL, CHECK (c1 > 250)) INHERITS(s1.p2c3); CREATE TABLE s1.r1 (LIKE s1.t1); CREATE TABLE s1.r2 (LIKE s1.t1); CREATE TABLE s1.r3 (LIKE s1.t1); CREATE TABLE s1.r4 (LIKE s1.t1); CREATE TABLE s1.r5 (LIKE s1.t1); CREATE TABLE s1.r1_ (LIKE s1.t1); CREATE TABLE s1.r2_ (LIKE s1.t1); CREATE TABLE s1.r3_ (LIKE s1.t1); CREATE TABLE s1.ti1 (c1 int, c2 int, c3 int, c4 text, PRIMARY KEY (c1), UNIQUE (c2)); CREATE TABLE s1.pt1 (c1 int, c2 int, c3 int, c4 int) PARTITION BY RANGE (c1); CREATE TABLE s1.pt1_c1 PARTITION OF s1.pt1 FOR VALUES FROM (MINVALUE) TO (101); CREATE TABLE s1.pt1_c2 PARTITION OF s1.pt1 FOR VALUES FROM (101) TO (201); CREATE TABLE s1.pt1_c3 PARTITION OF s1.pt1 FOR VALUES FROM (201) TO (MAXVALUE); CREATE UNLOGGED TABLE s1.ul1 (LIKE s1.t1 INCLUDING ALL); INSERT INTO s1.t1 SELECT i, i, i % 100, i FROM (SELECT generate_series(1, 1000) i) t; INSERT INTO s1.t2 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 100) i) t; INSERT INTO s2.t1 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 100) i) t; INSERT INTO s1.p1c1 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 100) i) t; INSERT INTO s1.p1c2 SELECT i, i, i % 10, i FROM (SELECT generate_series(101, 200) i) t; INSERT INTO s1.p1c3 SELECT i, i, i % 10, i FROM (SELECT generate_series(201, 300) i) t; INSERT INTO s1.p2c1c1 SELECT i, i, i % 10, i FROM (SELECT generate_series(1, 50) i) t; INSERT INTO s1.p2c1c2 SELECT i, i, i % 10, i FROM (SELECT generate_series(51, 100) i) t; INSERT INTO s1.p2c2c1 SELECT i, i, i % 10, i FROM (SELECT generate_series(101, 150) i) t; INSERT INTO s1.p2c2c2 SELECT i, i, i % 10, i FROM (SELECT generate_series(151, 200) i) t; INSERT INTO s1.p2c3c1 SELECT i, i, i % 10, i FROM (SELECT generate_series(201, 250) i) t; INSERT INTO s1.p2c3c2 SELECT i, i, i % 10, i FROM (SELECT generate_series(251, 300) i) t; INSERT INTO s1.ti1 SELECT i, i, i % 100, i FROM (SELECT generate_series(1, 1000) i) t; INSERT INTO s1.pt1 SELECT i, i, i % 10, i FROM (SELECT generate_series(0, 300) i) t; CREATE INDEX t1_i ON s1.t1 (c3); CREATE INDEX t1_i1 ON s1.t1 (c1); CREATE INDEX t2_i1 ON s1.t2 (c1); CREATE INDEX t3_i1 ON s1.t3 (c1); CREATE INDEX t4_i1 ON s1.t4 (c1); CREATE INDEX p1_i ON s1.p1 (c1); CREATE INDEX p2_i ON s1.p2 (c1); CREATE INDEX p1_i2 ON s1.p1 (c2); CREATE INDEX p1c1_i ON s1.p1c1 (c1); CREATE INDEX p1c2_i ON s1.p1c2 (c1); CREATE INDEX p1c3_i ON s1.p1c3 (c1); CREATE INDEX p2c1_i ON s1.p2c1 (c1); CREATE INDEX p2c2_i ON s1.p2c2 (c1); CREATE INDEX p2c3_i ON s1.p2c3 (c1); CREATE INDEX p2c1c1_i ON s1.p2c1c1 (c1); CREATE INDEX p2c1c2_i ON s1.p2c1c2 (c1); CREATE INDEX p2c2c1_i ON s1.p2c2c1 (c1); CREATE INDEX p2c2c2_i ON s1.p2c2c2 (c1); CREATE INDEX p2c3c1_i ON s1.p2c3c1 (c1); CREATE INDEX p2c3c2_i ON s1.p2c3c2 (c1); CREATE INDEX ti1_i1 ON s1.ti1 (c2); CREATE INDEX ti1_i2 ON s1.ti1 (c2, c4); CREATE INDEX ti1_i3 ON s1.ti1 (c2, c4, c4); CREATE INDEX ti1_i4 ON s1.ti1 (c2, c4, c4, c4); CREATE INDEX ti1_btree ON s1.ti1 USING btree (c1); CREATE INDEX ti1_hash ON s1.ti1 USING hash (c1); CREATE INDEX ti1_gist ON s1.ti1 USING gist (c1); CREATE INDEX ti1_gin ON s1.ti1 USING gin (c1); CREATE INDEX ti1_expr ON s1.ti1 ((c1 < 100)); CREATE INDEX ti1_pred ON s1.ti1 (lower(c4)); CREATE UNIQUE INDEX ti1_uniq ON s1.ti1 (c1); CREATE INDEX ti1_multi ON s1.ti1 (c1, c2, c3, c4); CREATE INDEX ti1_ts ON s1.ti1 USING gin(to_tsvector('english', c4)); CREATE INDEX pt1_c1_c2_i ON s1.pt1_c1(c2); CREATE INDEX pt1_c1_c3_i ON s1.pt1_c1(c3); CREATE INDEX pt1_c2_c2_i ON s1.pt1_c2(c2); CREATE INDEX pt1_c2_c3_i ON s1.pt1_c2(c3); CREATE INDEX pt1_c3_c2_i ON s1.pt1_c3(c2); CREATE INDEX pt1_c3_c3_i ON s1.pt1_c3(c3); CREATE VIEW s1.v1 AS SELECT v1t1.c1, v1t1.c2, v1t1.c3, v1t1.c4 FROM s1.t1 v1t1; CREATE VIEW s1.v1_ AS SELECT v1t1_.c1, v1t1_.c2, v1t1_.c3, v1t1_.c4 FROM s1.t1 v1t1_; CREATE VIEW s1.v2 AS SELECT v2t1.c1, v2t1.c2, v2t1.c3, v2t1.c4 FROM s1.t1 v2t1 JOIN s1.t2 v2t2 ON(v2t1.c1 = v2t2.c1); CREATE VIEW s1.v3 AS SELECT v3t1.c1, v3t1.c2, v3t1.c3, v3t1.c4 FROM s1.t1 v3t1 JOIN s1.t2 v3t2 ON(v3t1.c1 = v3t2.c1) JOIN s1.t3 v3t3 ON(v3t1.c1 = v3t3.c1); ANALYZE s1.t1; ANALYZE s1.t2; ANALYZE s2.t1; ANALYZE s1.p1; ANALYZE s1.p2; ANALYZE s1.p1c1; ANALYZE s1.p1c2; ANALYZE s1.p1c3; ANALYZE s1.p2c1c1; ANALYZE s1.p2c1c2; ANALYZE s1.p2c2c1; ANALYZE s1.p2c2c2; ANALYZE s1.p2c3c1; ANALYZE s1.p2c3c2; ANALYZE s1.ti1; ANALYZE s1.pt1; ANALYZE s1.t5; ANALYZE s1.t6; CREATE FUNCTION s1.f1 () RETURNS s1.t1 AS $$ VALUES(1,1,1,'1'), (2,2,2,'2'), (3,3,3,'3') $$ LANGUAGE sql; CREATE RULE r1 AS ON UPDATE TO s1.r1 DO INSTEAD ( SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; ); CREATE RULE r2 AS ON UPDATE TO s1.r2 DO INSTEAD ( SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; ); CREATE RULE r3 AS ON UPDATE TO s1.r3 DO INSTEAD ( SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; SELECT max(t1.c1) FROM s1.t1, s1.t2, s1.t3, s1.t4 WHERE t1.ctid = '(1,1)' AND t1.c1 = t2.c1 AND t2.ctid = '(1,1)' AND t1.c1 = t3.c1 AND t3.ctid = '(1,1)' AND t1.c1 = t4.c1 AND t4.ctid = '(1,1)'; ); CREATE RULE r1_ AS ON UPDATE TO s1.r1_ DO INSTEAD ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)'; ); CREATE RULE r2_ AS ON UPDATE TO s1.r2_ DO INSTEAD ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)'; SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)'; ); CREATE RULE r3_ AS ON UPDATE TO s1.r3_ DO INSTEAD ( SELECT max(b1t1.c1) FROM s1.t1 b1t1, s1.t2 b1t2, s1.t3 b1t3, s1.t4 b1t4 WHERE b1t1.ctid = '(1,1)' AND b1t1.c1 = b1t2.c1 AND b1t2.ctid = '(1,1)' AND b1t1.c1 = b1t3.c1 AND b1t3.ctid = '(1,1)' AND b1t1.c1 = b1t4.c1 AND b1t4.ctid = '(1,1)'; SELECT max(b2t1.c1) FROM s1.t1 b2t1, s1.t2 b2t2, s1.t3 b2t3, s1.t4 b2t4 WHERE b2t1.ctid = '(1,1)' AND b2t1.c1 = b2t2.c1 AND b2t2.ctid = '(1,1)' AND b2t1.c1 = b2t3.c1 AND b2t3.ctid = '(1,1)' AND b2t1.c1 = b2t4.c1 AND b2t4.ctid = '(1,1)'; SELECT max(b3t1.c1) FROM s1.t1 b3t1, s1.t2 b3t2, s1.t3 b3t3, s1.t4 b3t4 WHERE b3t1.ctid = '(1,1)' AND b3t1.c1 = b3t2.c1 AND b3t2.ctid = '(1,1)' AND b3t1.c1 = b3t3.c1 AND b3t3.ctid = '(1,1)' AND b3t1.c1 = b3t4.c1 AND b3t4.ctid = '(1,1)'; ); pg_hint_plan-REL17_1_7_0/update_copied_funcs.pl000077500000000000000000000216521466301071500215510ustar00rootroot00000000000000#! /usr/bin/perl use strict; my $srcpath; my @sources = ( 'src/backend/optimizer/path/allpaths.c', 'src/backend/optimizer/path/joinrels.c'); my %defs = ('core.c' => {protos => [], funcs => ['set_plain_rel_pathlist', 'standard_join_search', 'create_plain_partial_paths', 'join_search_one_level', 'make_rels_by_clause_joins', 'make_rels_by_clauseless_joins', 'join_is_legal', 'has_join_restriction', 'restriction_is_constant_false', 'build_child_join_sjinfo', 'get_matching_part_pairs', 'compute_partition_bounds', 'try_partitionwise_join', 'free_child_join_sjinfo'], head => core_c_head()}, 'make_join_rel.c' => {protos => [], funcs => ['make_join_rel', 'populate_joinrel_with_paths'], head => make_join_rel_head()}); open (my $in, '-|', "objdump -W `which postgres`") || die "failed to objdump"; while (<$in>) { if (/DW_AT_comp_dir .*: (.*\/)src\/backend\//) { $srcpath = $1; last; } } close($in); die "source path not found" if (! defined $srcpath); #printf("Source path = %s\n", $srcpath); my %protos; my %funcs; my %func_is_static; my %func_source; for my $fname (@sources) { my $f = $srcpath.$fname; my $source; open ($in, '<', $f) || die "failed to open $f: $!"; while (<$in>) { $source .= $_; } ## Collect static prototypes while ($source =~ /\n(static [^\(\)\{\}]*?(\w+)(\([^\{\);]+?\);))/gsm) { # print "Prototype found: $2\n"; $protos{$2} = $1; } ## Collect function bodies while ($source =~ /(\n\/\*\n.+?\*\/\n(static )?(.+?)\n(.+?) *\(.*?\)\n\{.+?\n\}\n)/gsm) { $funcs{$4} = $1; $func_is_static{$4} = (defined $2); $func_source{$4} = $fname; # printf("Function found: %s$4\n", $func_is_static{$4} ? "static " : ""); } close($in); } # Generate files for my $fname (keys %defs) { my %d = %{$defs{$fname}}; my @protonames = @{$d{'protos'}}; my @funcnames = @{$d{'funcs'}}; my $head = $d{'head'}; print "Generate $fname.\n"; open (my $out, '>', $fname) || die "could not open $fname: $!"; print $out $head; for (@protonames) { print " Prototype: $_\n"; print $out "\n"; die "Prototype for $_ not found" if (! defined $protos{$_}); print $out $protos{$_}; } for (@funcnames) { printf(" %s function: $_@%s\n", $func_is_static{$_}?"static":"public", $func_source{$_}); print $out "\n"; die "Function body for $_ not found" if (! defined $funcs{$_}); print $out $funcs{$_}; } close($out); } # modify make_join_rel.c patch_make_join_rel(); sub core_c_head() { return << "EOS"; /*------------------------------------------------------------------------- * * core.c * Routines copied from PostgreSQL core distribution. * * The main purpose of this files is having access to static functions in core. * Another purpose is tweaking functions behavior by replacing part of them by * macro definitions. See at the end of pg_hint_plan.c for details. Anyway, * this file *must* contain required functions without making any change. * * This file contains the following functions from corresponding files. * * src/backend/optimizer/path/allpaths.c * * public functions: * standard_join_search(): This funcion is not static. The reason for * including this function is make_rels_by_clause_joins. In order to * avoid generating apparently unwanted join combination, we decided to * change the behavior of make_join_rel, which is called under this * function. * * static functions: * set_plain_rel_pathlist() * create_plain_partial_paths() * * src/backend/optimizer/path/joinrels.c * * public functions: * join_search_one_level(): We have to modify this to call my definition of * make_rels_by_clause_joins. * * static functions: * make_rels_by_clause_joins() * make_rels_by_clauseless_joins() * join_is_legal() * has_join_restriction() * restriction_is_constant_false() * build_child_join_sjinfo() * get_matching_part_pairs() * compute_partition_bounds() * try_partitionwise_join() * * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- */ #include "access/tsmapi.h" #include "catalog/pg_operator.h" #include "foreign/fdwapi.h" EOS } sub make_join_rel_head { return << "EOS"; /*------------------------------------------------------------------------- * * make_join_rel.c * Routines copied from PostgreSQL core distribution with some * modifications. * * src/backend/optimizer/path/joinrels.c * * This file contains the following functions from corresponding files. * * static functions: * make_join_rel() * populate_joinrel_with_paths() * * Portions Copyright (c) 2013-2024, NIPPON TELEGRAPH AND TELEPHONE CORPORATION * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- */ /* * adjust_rows: tweak estimated row numbers according to the hint. */ static double adjust_rows(double rows, RowsHint *hint) { double result = 0.0; /* keep compiler quiet */ if (hint->value_type == RVT_ABSOLUTE) result = hint->rows; else if (hint->value_type == RVT_ADD) result = rows + hint->rows; else if (hint->value_type == RVT_SUB) result = rows - hint->rows; else if (hint->value_type == RVT_MULTI) result = rows * hint->rows; else Assert(false); /* unrecognized rows value type */ hint->base.state = HINT_STATE_USED; if (result < 1.0) ereport(WARNING, (errmsg("Force estimate to be at least one row, to avoid possible divide-by-zero when interpolating costs : %s", hint->base.hint_str))); result = clamp_row_est(result); elog(DEBUG1, "adjusted rows %d to %d", (int) rows, (int) result); return result; } EOS } sub patch_make_join_rel { open(my $out, '|-', 'patch') || die "failed to open pipe: $!"; print $out <<"EOS"; diff --git b/make_join_rel.c a/make_join_rel.c index 0e7b99f..287e7f1 100644 --- b/make_join_rel.c +++ a/make_join_rel.c @@ -126,6 +126,84 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2) joinrel = build_join_rel(root, joinrelids, rel1, rel2, sjinfo, &restrictlist); + /* !!! START: HERE IS THE PART WHICH IS ADDED FOR PG_HINT_PLAN !!! */ + { + RowsHint *rows_hint = NULL; + int i; + RowsHint *justforme = NULL; + RowsHint *domultiply = NULL; + + /* Search for applicable rows hint for this join node */ + for (i = 0; i < current_hint_state->num_hints[HINT_TYPE_ROWS]; i++) + { + rows_hint = current_hint_state->rows_hints[i]; + + /* + * Skip this rows_hint if it is invalid from the first or it + * doesn't target any join rels. + */ + if (!rows_hint->joinrelids || + rows_hint->base.state == HINT_STATE_ERROR) + continue; + + if (bms_equal(joinrelids, rows_hint->joinrelids)) + { + /* + * This joinrel is just the target of this rows_hint, so tweak + * rows estimation according to the hint. + */ + justforme = rows_hint; + } + else if (!(bms_is_subset(rows_hint->joinrelids, rel1->relids) || + bms_is_subset(rows_hint->joinrelids, rel2->relids)) && + bms_is_subset(rows_hint->joinrelids, joinrelids) && + rows_hint->value_type == RVT_MULTI) + { + /* + * If the rows_hint's target relids is not a subset of both of + * component rels and is a subset of this joinrel, ths hint's + * targets spread over both component rels. This menas that + * this hint has been never applied so far and this joinrel is + * the first (and only) chance to fire in current join tree. + * Only the multiplication hint has the cumulative nature so we + * apply only RVT_MULTI in this way. + */ + domultiply = rows_hint; + } + } + + if (justforme) + { + /* + * If a hint just for me is found, no other adjust method is + * useles, but this cannot be more than twice becuase this joinrel + * is already adjusted by this hint. + */ + if (justforme->base.state == HINT_STATE_NOTUSED) + joinrel->rows = adjust_rows(joinrel->rows, justforme); + } + else + { + if (domultiply) + { + /* + * If we have multiple routes up to this joinrel which are not + * applicable this hint, this multiply hint will applied more + * than twice. But there's no means to know of that, + * re-estimate the row number of this joinrel always just + * before applying the hint. This is a bit different from + * normal planner behavior but it doesn't harm so much. + */ + set_joinrel_size_estimates(root, joinrel, rel1, rel2, sjinfo, + restrictlist); + + joinrel->rows = adjust_rows(joinrel->rows, domultiply); + } + + } + } + /* !!! END: HERE IS THE PART WHICH IS ADDED FOR PG_HINT_PLAN !!! */ + /* * If we've already proven this join is empty, we needn't consider any * more paths for it. EOS }