pax_global_header00006660000000000000000000000064144777676600014542gustar00rootroot0000000000000052 comment=fa0a461af929c06f7c96956369458456c26e7ad9 pg_hint_plan-REL16_1_6_0/000077500000000000000000000000001447776766000152235ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/.gitattributes000066400000000000000000000001101447776766000201060ustar00rootroot00000000000000# Test output files that contain extra whitespace *.out -whitespace pg_hint_plan-REL16_1_6_0/.github/000077500000000000000000000000001447776766000165635ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/.github/workflows/000077500000000000000000000000001447776766000206205ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/.github/workflows/test.yml000066400000000000000000000056771447776766000223410ustar00rootroot00000000000000name: regression test on: push: branches: - PG16 - PG15 - PG14 - PG13 - PG12 - PG11 pull_request: branches: - PG16 - PG15 - PG14 - PG13 - PG12 - PG11 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 }}" == '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 elif [ "${{ github.ref_name }}" == 'PG11' ]; then echo "PG_VERSION=11" >> $GITHUB_ENV elif [ "${{ github.ref_name }}" == 'PG10' ]; then echo "PG_VERSION=10" >> $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/pg_stat_statements make -C contrib/file_fdw make -C contrib/btree_gist make -C contrib/btree_gin sudo make install sudo make -C contrib/pg_stat_statements 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,pg_stat_statements,file_fdw'" >> 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-REL16_1_6_0/.gitignore000066400000000000000000000003321447776766000172110ustar00rootroot00000000000000# Global excludes across all subdirectories *.o *.so *.bc tags regression.* *.tar.gz *~ # Generated subdirectories /.deps/ /log/ /results/ /tmp_check/ /RPMS/ # Documentation artifacts docs/_build docs/locale/**/*.mo pg_hint_plan-REL16_1_6_0/COPYRIGHT000066400000000000000000000030711447776766000165170ustar00rootroot00000000000000Copyright (c) 2012-2023, 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-REL16_1_6_0/COPYRIGHT.postgresql000066400000000000000000000024541447776766000207250ustar00rootroot00000000000000core.c and make_join_rel.c and pg_stat_statements.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-2023, 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-REL16_1_6_0/Makefile000066400000000000000000000043221447776766000166640ustar00rootroot00000000000000# # pg_hint_plan: Makefile # # Copyright (c) 2012-2023, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # MODULES = pg_hint_plan HINTPLANVER = 1.6.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 hints_anywhere plpgsql 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.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.5.sql \ pg_hint_plan--1.5--1.5.1.sql \ pg_hint_plan--1.5.1--1.6.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 STARBALL16 = pg_hint_plan16-$(HINTPLANVER).tar.gz STARBALLS = $(STARBALL16) TARSOURCES = Makefile *.c *.h COPYRIGHT* \ pg_hint_plan--*.sql \ pg_hint_plan.control \ docs/* expected/*.out sql/*.sql sql/maskout*.sh \ data/data.csv SPECS/*.spec rpms: rpm16 # pg_hint_plan.c includes core.c and make_join_rel.c pg_hint_plan.o: core.c make_join_rel.c # pg_stat_statements.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,,$@) rpm16: $(STARBALL16) MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_hint_plan16.spec pg_hint_plan-REL16_1_6_0/README.md000066400000000000000000000021661447776766000165070ustar00rootroot00000000000000# pg\_hint\_plan 1.6 `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, which utilizes data statistics, not static rules. The planner (optimizer) esitimates costs of each possible execution plans for a SQL statement then the execution plan with the lowest cost finally be executed. The planner does its best to select the best best execution plan, but is not always perfect, since it doesn't count some properties of the data, for example, 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. [Unistallation](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-2023, NIPPON TELEGRAPH AND TELEPHONE CORPORATION pg_hint_plan-REL16_1_6_0/SPECS/000077500000000000000000000000001447776766000161005ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/SPECS/pg_hint_plan16.spec000066400000000000000000000060101447776766000215620ustar00rootroot00000000000000# SPEC file for pg_store_plans # Copyright(c) 2022-2023, NIPPON TELEGRAPH AND TELEPHONE CORPORATION %define _pgdir /usr/pgsql-16 %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_store_plans. Summary: Optimizer hint on PostgreSQL 16 Name: pg_hint_plan16 Version: 1.6.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: postgresql16-devel Requires: postgresql16-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 16. %package llvmjit Requires: postgresql16-server, postgresql16-llvmjit Requires: pg_hint_plan16 = 1.6.0 Summary: Just-in-time compilation support for pg_hint_plan16 %description llvmjit Just-in-time compilation support for pg_hint_plan16 ## pre work for build pg_hint_plan %prep PATH=/usr/pgsql-16/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-16/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.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.5.sql %{_datadir}/extension/pg_hint_plan--1.5--1.5.1.sql %{_datadir}/extension/pg_hint_plan--1.5.1--1.6.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 * Thu Jan 17 2023 Michael Paquier - Support PostgreSQL 16. pg_hint_plan-REL16_1_6_0/core.c000066400000000000000000001320411447776766000163200ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * 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-2023, 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). */ 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 debug_print_rel(root, 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)) { /* * 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. */ List *other_rels_list; ListCell *other_rels; if (level == 2) /* consider remaining initial rels */ { other_rels_list = joinrels[level - 1]; other_rels = lnext(other_rels_list, r); } else /* consider all initial rels */ { other_rels_list = joinrels[1]; other_rels = list_head(other_rels_list); } make_rels_by_clause_joins(root, old_rel, other_rels_list, other_rels); } 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); List *other_rels_list; ListCell *other_rels; 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 */ other_rels_list = joinrels[k]; other_rels = lnext(other_rels_list, r); } else { other_rels_list = joinrels[other_level]; other_rels = list_head(other_rels_list); } for_each_cell(r2, other_rels_list, other_rels) { 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_list': a list containing the other * rels to be considered for joining * 'other_rels': the first cell to be considered * * 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_list, ListCell *other_rels) { ListCell *l; for_each_cell(l, other_rels_list, other_rels) { 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. */ 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; 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; Relids child_joinrelids; 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); /* Build correct join relids for child join */ child_joinrelids = bms_union(child_rel1->relids, child_rel2->relids); child_joinrelids = add_outer_joins_to_relids(root, child_joinrelids, child_sjinfo, NULL); /* Find the AppendRelInfo structures */ appinfos = find_appinfos_by_relids(root, child_joinrelids, &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); pfree(appinfos); 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(bms_equal(child_joinrel->relids, child_joinrelids)); populate_joinrel_with_paths(root, child_rel1, child_rel2, child_joinrel, child_sjinfo, child_restrictlist); } } pg_hint_plan-REL16_1_6_0/data/000077500000000000000000000000001447776766000161345ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/data/data.csv000066400000000000000000000000521447776766000175570ustar00rootroot000000000000001,1 2,2 3,3 4,4 5,5 6,6 7,7 8,8 9,9 10,10 pg_hint_plan-REL16_1_6_0/docs/000077500000000000000000000000001447776766000161535ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/docs/Makefile000066400000000000000000000011721447776766000176140ustar00rootroot00000000000000# 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-REL16_1_6_0/docs/README000066400000000000000000000054241447776766000170400ustar00rootroot00000000000000pg_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-REL16_1_6_0/docs/conf.py000066400000000000000000000025251447776766000174560ustar00rootroot00000000000000# 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-2023, 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-REL16_1_6_0/docs/description.md000066400000000000000000000023461447776766000210250ustar00rootroot00000000000000# 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-REL16_1_6_0/docs/errors.md000066400000000000000000000015741447776766000200200ustar00rootroot00000000000000# 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-REL16_1_6_0/docs/functional_limitations.md000066400000000000000000000017041447776766000232550ustar00rootroot00000000000000(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. ## `pg_stat_statements` `pg_stat_statements` 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-REL16_1_6_0/docs/hint_details.md000066400000000000000000000170731447776766000211540ustar00rootroot00000000000000# 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 returns one row (`SELECT`, `INSERT`, `UPDATE` and `DELETE`) - Queries that returns 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 includes 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 hint saffect 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 distinguised 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 its own behavior so some parameters will not work as one could expect: - Hints to change `enable_hint`, `enable_hint_tables` 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-REL16_1_6_0/docs/hint_list.md000066400000000000000000000066161447776766000205030ustar00rootroot00000000000000(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-REL16_1_6_0/docs/hint_table.md000066400000000000000000000160351447776766000206130ustar00rootroot00000000000000# 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. | | `norm_query_string` | A pattern matching with the query to be hinted.
Constants in the query are replaced by '?' as in the following example. | | `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 =# INSERT INTO hint_plan.hints(norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;', '', '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. ## 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 additionaly. 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 vaiues 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-REL16_1_6_0/docs/index.md000066400000000000000000000003601447776766000176030ustar00rootroot00000000000000# pg_hint_plan 1.6 ```{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-REL16_1_6_0/docs/installation.md000066400000000000000000000016011447776766000211740ustar00rootroot00000000000000# 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 ## 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_tables TO on` if you are planning to use the hint table. pg_hint_plan-REL16_1_6_0/docs/locale/000077500000000000000000000000001447776766000174125ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/docs/locale/ja/000077500000000000000000000000001447776766000200045ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/000077500000000000000000000000001447776766000215715ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/description.po000066400000000000000000000043421447776766000244570ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan description. # Copyright (C) 2012-2023, 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. # 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-07-15 12:23+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" #: ../../description.md:1 36ecf3f5b33149abba3c29147babecec msgid "Description" msgstr "機能説明" #: ../../description.md:3 876c61bdb07540eaac5fa67254a8b6d0 msgid "Basic Usage" msgstr "基本的な使用方法" #: ../../description.md:5 da1244d0fca640da9c0728a3d004e462 msgid "" "`pg_hint_plan` reads hinting phrases in a comment of special form given " "with the target SQL statement. The special form is beginning by the " "character sequence `\"/\\*+\"` and ends with `\"\\*/\"`. Hint phrases " "are consists of hint name and following parameters enclosed by " "parentheses and delimited by spaces. Each hinting phrases can be " "delimited by new lines for readability." msgstr "" "`pg_hint_plan`は対象のSQL文と一緒に与えられた特殊形式のコメント内のヒン" "ト句を読みます。\n" "特殊形式は `\"/*+\"` で始まり、`\"*/\"` で終わります。\n" "ヒント句はヒント名とそれに続くパラメータを括弧で囲み、スペースで区切った" "ものです。\n" "各ヒント句は読みやすくするために改行することができます。" #: ../../description.md:11 f580a4b229054382a573c06093f5a37e msgid "" "In the example below, hash join is selected as the joining method and " "scanning `pgbench_accounts` by sequential scan method." msgstr "" "以下の例では、結合方法にハッシュ結合を選択しシーケンシャルスキャンの方法" "で`pgbench_accounts`をスキャンしています。" pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/errors.po000066400000000000000000000100531447776766000234440ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan errors. # Copyright (C) 2012-2023, 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. # 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-07-14 14:55+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" #: ../../errors.md:1 7a1ddc938c2e4eff8e46c6d3a9d7b320 msgid "Errors" msgstr "エラー" #: ../../errors.md:3 2ad9c694dc1f464a9658fdad13822941 msgid "" "`pg_hint_plan` stops parsing on any error and uses hints already parsed " "on the most cases. Following are the typical errors." msgstr "" "`pg_hint_plan`はエラーが発生すると構文解析を停止します。多くの場合は既に" "構文解析されたヒントを使用します。以下は典型的なエラーです。" #: ../../errors.md:6 32c4a156d0224a2cb1360639c163f808 msgid "Syntax errors" msgstr "シンタックスエラー" #: ../../errors.md:8 3fa7aacd17aa43f1b1b07c5ae6df1de7 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:12 41877d1989c6485cbea38eb7994fdf43 msgid "Object misspecifications" msgstr "オブジェクトの指定誤り" #: ../../errors.md:14 74af48e14c8a47eaaaf84bb0773c28e3 msgid "" "Object misspecifications result in silent ignorance of the hints. This " "kind of error is reported as \"not used hints\" in the server log by the " "same condition as syntax errors." msgstr "" "オブジェクトの指定を誤るとヒントは無言で無視されます。この種類のエラーは" "シンタックスエラーと同様の条件で\"not used hints\"としてサーバログに出力" "されます。" #: ../../errors.md:18 36e56d95d7714a399d93f072d0df67bf msgid "Redundant or conflicting hints" msgstr "重複または競合するヒント" #: ../../errors.md:20 dd9d92795ba843f998946bedb601ad2b msgid "" "The last hint will be active when redundant hints or hints conflicting " "with each other. This kind of error is reported as \"duplication hints\" " "in the server log by the same condition to syntax errors." msgstr "" "ヒントが重複、または互いに競合している場合は、最後のヒントが有効になりま" "す。この種類のエラーは シンタックスエラーと同様の条件で\"duplication " "hints\"としてサーバログに出力されます。" #: ../../errors.md:24 55fe2ef2e9f2495a9d52f7beff0ac626 msgid "Nested comments" msgstr "ネストされたコメント" #: ../../errors.md:26 2c875a3235cd45f79ab11d50bec13031 msgid "" "Hint comment cannot include another block comment within. If " "`pg_hint_plan` finds it, differently from other erros, it stops parsing " "and abandans all hints already parsed. This kind of error is reported in " "the same manner as other errors." msgstr "" "コメントヒント内に別のブロックコメントを含めることはできません。" "`pg_hint_plan` はそれを見つけた場合、他のエラーとは異なり構文解析を中止" "し、既に構文解析された全てのヒントを破棄します。この種類のエラーは他のエ" "ラーと同様の方法で出力されます。" pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/functional_limitations.po000066400000000000000000000101221447776766000267030ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan functional limitations. # Copyright (C) 2012-2023, 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. # 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-06-05 16:21+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:1 cc8b677c2cb549fa929dcd81006fa487 msgid "Functional limitations" msgstr "機能的な制限事項" #: ../../functional_limitations.md:3 53469c44e28446319def9d32da932fc3 msgid "Influences of some of planner GUC parameters" msgstr "プランナGUCの一部パラメータの影響" #: ../../functional_limitations.md:5 17f0b27352c74f64bd6dd3387e841833 msgid "" "The planner does not try to consider joining order for FROM clause " "entries more than `from_collapse_limit`. `pg_hint_plan` cannot affect " "joining order as expected for the case." msgstr "" "プランナは、`from_collapse_limit`を超えるFROM句の項目に対する結合順を考慮" "しようとしません。`pg_hint_plan`は、このケースに対して期待される結合順に" "影響を与えることはできません。" #: ../../functional_limitations.md:9 465e0f7dc3204efb9f269b42a2a20a03 msgid "Hints trying to enforce unexecutable plans" msgstr "実行不可能な計画を強制しようとするヒント" #: ../../functional_limitations.md:11 08c0cb232704464e8bf0fd2fb8ba0499 msgid "" "Planner chooses any executable plans when the enforced plan cannot be " "executed." msgstr "" "プランナは、強制されたプランが実行できない場合、任意の実行可能なプランを" "選択します。" #: ../../functional_limitations.md:13 ed572c8c6d0b4c70936aee5225ca826f msgid "`FULL OUTER JOIN` to use nested loop" msgstr "FULL OUTER JOINをnested loopで使用" #: ../../functional_limitations.md:14 cdcca136c9a648ec8081891c39b29ea5 msgid "To use indexes that does not have columns used in quals" msgstr "条件式で使用されるカラムを持たないインデックスを使用" #: ../../functional_limitations.md:15 edf44a241d39485fb81d66b4c1b7fbc2 msgid "To do TID scans for queries without ctid conditions" msgstr "ctid条件が無いクエリに対するTIDスキャンの実行" #: ../../functional_limitations.md:17 1e02a948684f4eb69172f27fd8b5e361 msgid "Queries in ECPG" msgstr "ECPG内のクエリ" #: ../../functional_limitations.md:19 5c0c4a6a4f8449e5ba4d7029785bb68b msgid "" "ECPG removes comments in queries written as embedded SQLs so hints " "cannot be passed form those queries. The only exception is that " "`EXECUTE` command passes given string unmodifed. Please consider using " "the hint table in the case." msgstr "" "ECPGは埋め込みSQLとして書かれたクエリのコメントを削除するので、それらのク" "エリからヒントを渡すことはできません。ただし、例外としてEXECUTEコマンドで" "は与えられた文字列をそのまま渡すことができます。このようなケースにおいて" "はヒントテーブルの利用をご検討ください。" #: ../../functional_limitations.md:23 e78a48e7582f4ecb9e4a33b9b95cf595 msgid "Work with `pg_stat_statements`" msgstr "pg_stat_statementsとの連携" #: ../../functional_limitations.md:25 028c3c93e75944edb2df54987c87fef6 msgid "" "`pg_stat_statements` generates a query id ignoring comments. As the " "result, the identical queries with different hints are summarized as the " "same query." msgstr "" "`pg_stat_statements`はコメントを無視したクエリIDを生成します。その結果、" "異なるヒントを持つ同一のクエリは同じものとして集約されます。" pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/hint_details.po000066400000000000000000000323721447776766000246070ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan hint details. # Copyright (C) 2012-2023, 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. # 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-06-05 16:21+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 693f0f4d9eb74147bbd70fd662533301 msgid "Details in hinting" msgstr "ヒントの詳細" #: ../../hint_details.md:3 b701aac340744d01b1b5581d1eff3fcf msgid "Syntax and placement" msgstr "構文と配置" #: ../../hint_details.md:5 ab77d6f8ecef4caca7b8b1ec9b23e28c msgid "" "`pg_hint_plan` reads hints from only the first block comment and any " "characters except alphabets, digits, spaces, underscores, commas and " "parentheses stops parsing immediately. 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:34 b460c8a84bec418a9c1068caa073b596 msgid "Using with PL/pgSQL" msgstr "PL/pgSQLでの使用" #: ../../hint_details.md:36 8a94b49c7ceb45aaac4e47b04574644a msgid "" "`pg_hint_plan` works for queries in PL/pgSQL scripts with some restrictions." msgstr "" "`pg_hint_plan`はPL/pgSQLスクリプト内のクエリに対してはいくつかの制限付きで動作" "します。" #: ../../hint_details.md:38 6ba14dce61574358b29630cff33f55e0 msgid "Hints affect only on the following kind of queries." msgstr "ヒントは以下のような種類のクエリにのみ影響します。" #: ../../hint_details.md:39 b96677e33bba41cf8974d20ae22aaf44 msgid "Queries that returns one row. (`SELECT`, `INSERT`, `UPDATE` and `DELETE`)" msgstr "1行を返すクエリ (`SELECT`、`INSERT`、`UPDATE`、`DELETE`)" #: ../../hint_details.md:40 12545ff4869e499baa5b622e340efa0b msgid "Queries that returns multiple rows. (`RETURN QUERY`)" msgstr "複数行を返すクエリ (`RETURNクエリ`)" #: ../../hint_details.md:41 90ec2340d8794f05a0033e1727409b18 msgid "Dynamic SQL statements. (`EXECUTE`)" msgstr "動的なSQL文 (`EXECUTE`)" #: ../../hint_details.md:42 b55ec7478c944ad7bec52372d06b3e0f msgid "Cursor open. (`OPEN`)" msgstr "カーソルを開く (`OPEN`)" #: ../../hint_details.md:43 8e27730ad5eb40eba41c2bbbe98833a6 msgid "Loop over result of a query (`FOR`)" msgstr "クエリ結果をループ (`FOR`)" #: ../../hint_details.md:44 49f605e431504d82bb104064d474843e msgid "" "A hint comment have to be placed after the first word in a query as the " "following since preceding comments are not sent as a part of the query." msgstr "" "ヒントコメントは次のようにクエリの最初の単語の後に配置する必要があります。クエ" "リよりも先行するコメントはクエリの一部として送信されません。" #: ../../hint_details.md:62 05c2b66829c0435a881028d578b5ca9b msgid "Letter case in the object names" msgstr "オブジェクト名の大文字と小文字の区別" #: ../../hint_details.md:64 dcf2c7b08e3b4008a4e9203a35be208d msgid "" "Unlike the way PostgreSQL handles object names, `pg_hint_plan` compares bare " "object names in hints against the database internal object names in case " "sensitive way. Therefore an object name TBL in a hint matches only \"TBL\" in " "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:69 5980dd00180049d9bf6982b608deeb93 msgid "Escaping special chacaters in object names" msgstr "オブジェクト名の特殊文字のエスケープ" #: ../../hint_details.md:71 df3b243db1c445b8bdee23d54b7c5a96 msgid "" "The objects as the hint parameter should be enclosed by double quotes if they " "includes parentheses, double quotes and white spaces. The escaping rule is the " "same as PostgreSQL." msgstr "" "ヒントのパラメータであるオブジェクト名は、括弧、二重引用符、空白を含む場合、二" "重引用符で囲む必要があります。エスケープのルールはPostgreSQLと同じです。" #: ../../hint_details.md:75 7fd718fc94a540379515d0f3f01596c9 msgid "Distinction between multiple occurances of a table" msgstr "複数出現するテーブルの区別" #: ../../hint_details.md:77 8739f95e0eba44608680e0cedfa281dc msgid "" "`pg_hint_plan` identifies the target object by using aliases if exists. This " "behavior is usable to point a specific occurance among multiple occurances of " "one table." msgstr "" "`pg_hint_plan`は別名が存在する場合、それを使用して対象オブジェクトを特定しま" "す。この動作は、1つのテーブルが複数出現する中から特定のものを指し示すために使用" "されます。" #: ../../hint_details.md:100 3cc460e3c63b49d29daa5ddbbd5e432c msgid "Underlying tables of views or rules" msgstr "ビューまたはルールの根底にあるテーブル" #: ../../hint_details.md:102 c5e203be5e7e415a814e743161eb24ae msgid "" "Hints are not applicable on views itself, but they can affect the queries " "within if the object names match the object 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:120 600ca488a1884ebaa0b33cb1b31f30a4 msgid "Inheritance tables" msgstr "継承テーブル" #: ../../hint_details.md:122 d9c234efc84646c0bd0e1c8fbd35d8fe msgid "" "Hints can point only the parent of an inheritance tables and the hint affect " "all the inheritance. Hints simultaneously point directly to children are not " "in effect." msgstr "" "ヒントは継承テーブルの親だけを指すことができ、そのヒントはすべての継承に影響し" "ます。同時に子テーブルを直接指定するヒントは無効です。" #: ../../hint_details.md:126 297ea1b1411d4acaa5efbe31a802fdc0 msgid "Hinting on multistatements" msgstr "マルチステートメントでのヒント" #: ../../hint_details.md:128 61e9d455a2964ccbb9505b42ab7c56e8 msgid "" "One multistatement can have exactly one hint comment and the hints affects all " "of the individual statement in the multistatement. Notice that the seemingly " "multistatement on the interactive interface of psql is internally a sequence " "of single statements so hints affects only on the statement just following." msgstr "" "1つのマルチステートメントには1つのヒントコメントを含めることができ、ヒントはマ" "ルチステートメント内のすべてのステートメントに影響します。psqlの対話型インタ" "フェース上では一見マルチステートメントに見えますが、内部的には単一のステートメ" "ントのシーケンスであるため、ヒントは直後のステートメントにのみ影響することに注" "意してください。" #: ../../hint_details.md:133 76e8e046afdf4e859ffca69ad346b63a msgid "VALUES expressions" msgstr "VALUES式" #: ../../hint_details.md:135 18ddb5a3de55446d966bb6ad7b0b0da3 msgid "" "`VALUES` expressions in `FROM` clause are named as `*VALUES*` internally so it " "is hintable if it is the only `VALUES` in a query. Two or more `VALUES` " "expressions in a query seem distinguishable looking at its explain result. But " "in reality, it is merely a cosmetic and they are not distinguishable." msgstr "" "`FROM`句の`VALUES`式は、内部的には`*VALUES*`と名付けられ、クエリ内の唯一の" "`VALUES`であればヒントを使用できる可能性があります。クエリ内の2つ以上の`VALUES`" "式は、`EXPLAIN`の結果を見ると区別がつくように見えます。しかし、実際にはそれは単" "なる表面上のものであり、区別はできません。" #: ../../hint_details.md:155 011ff73775074882bcdd3f3abbb62f5a msgid "Subqueries" msgstr "副問い合わせ" #: ../../hint_details.md:157 dd3132ada14d45e287217b9f73c31da1 msgid "" "Subqueries in the following context occasionally can be hinted using the name " "`ANY_subquery`." msgstr "" "以下のコンテキストにある副問い合わせは、`ANY_subquery`という名前を使ってヒント" "を与えることができます。" #: ../../hint_details.md:164 2c10050069874e09927931d16fea12f3 msgid "" "For these syntaxes, 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 as the following." msgstr "" "これらの構文では、プランナは副問い合わせを含むテーブルの結合を計画する際に、副" "問い合わせに内部的に名前を割り当てます。そのため、そのような結合では以下のよう" "に暗黙の名前を使用して結合方法ヒントが適用できます。" #: ../../hint_details.md:184 f618ca075f8a4cbb8446fbfb23d3f109 msgid "Using `IndexOnlyScan` hint" msgstr "IndexOnlyScanヒントの使用" #: ../../hint_details.md:186 5cd9de39be384363b4bce3ebed069068 msgid "" "Index scan may unexpectedly performed on another index when the index specifed " "in IndexOnlyScan hint cannot perform index only scan." msgstr "" "IndexOnlyScanヒントで指定されたインデックスでインデックスオンリースキャンを実行" "できない場合、インデックススキャンは予期せず別のインデックスで実行されることが" "あります。" #: ../../hint_details.md:189 f85708792b94499da8f268b87e8fc338 msgid "Behavior of `NoIndexScan`" msgstr "NoIndexScanの動作" #: ../../hint_details.md:191 aea68918ae7046f08eefe37079640035 msgid "`NoIndexScan` hint involes `NoIndexOnlyScan`." msgstr "NoIndexScanヒントはNoIndexOnlyScanを含んでいます。" #: ../../hint_details.md:193 14213ece855f45e3bbd563a0dd918e38 msgid "Parallel hint and `UNION`" msgstr "Parallelヒントと`UNION`" #: ../../hint_details.md:195 b078859750714d80a7f231449fb8f233 msgid "" "A `UNION` can run in parallel only when all underlying subqueries are parallel-" "safe. Conversely enforcing parallel on any of the subqueries let a parallel-" "executable `UNION` run in parallel. Meanwhile, a parallel hint with zero " "workers hinhibits a scan from executed in parallel." msgstr "" "UNIONが並列に実行できるのは、その下にあるすべてのサブクエリの並列実行が安全であ" "る場合のみです。サブクエリのいずれかに並列実行を強制することで、並列実行可能な" "UNIONが並列で実行されます。一方、ワーカーがゼロのPARALLELヒントは、スキャンの並" "列実行を禁止します。" #: ../../hint_details.md:200 f051a03d8d5b4b7baf74adf5465650f5 msgid "Setting `pg_hint_plan` parameters by Set hints" msgstr "Set ヒントによる`pg_hint_plan`のパラメータ設定" #: ../../hint_details.md:202 768486a50e1c4208a800f25260b02304 msgid "" "`pg_hint_plan` parameters change the behavior of itself so some parameters " "doesn't work as expected." msgstr "" "`pg_hint_plan`のパラメータはそれ自体の動作を変更するため、一部のパラメータは期" "待通りに動作しません。" #: ../../hint_details.md:205 6aa6255ae67a4589ba094fd354280c4b msgid "" "Hints to change `enable_hint`, `enable_hint_tables` are ignored even though " "they are reported as \"used hints\" in debug logs." msgstr "" "`enable_hint`, `enable_hint_tables`を変更するヒントは、デバッグログに\"used " "hints\"として報告されても無視されます。" #: ../../hint_details.md:207 01117a88f48e4d0989993d4d65a1c535 msgid "" "Setting `debug_print` and `message_level` works from midst of the processing " "of the target query." msgstr "" "`debug_print`と`message_level`の設定は、対象クエリの処理の途中から動作します。" pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/hint_list.po000066400000000000000000000335271447776766000241400ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan hint list. # Copyright (C) 2012-2023, 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. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-20 16:24+0900\n" "PO-Revision-Date: 2023-07-14 14:57+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 1413cb85416e498c8aaaff6b62daa9d2 msgid "Hints list" msgstr "ヒント一覧" #: ../../hint_list.md:4 46d1b07bb54546d58c5786d83870adf2 msgid "The available hints are listed below." msgstr "使用可能なヒントは以下の通りです。" #: ../../hint_list.md db9659cd2526419a89676ff6ca5d6e1f msgid "Group" msgstr "グループ" #: ../../hint_list.md eba61297968c4b788a46bde69cda4760 msgid "Format" msgstr "書式" #: ../../hint_list.md 2e4e6a7a7b6542b58c870d963db8cea2 msgid "Description" msgstr "説明" #: ../../hint_list.md 1168c0824df04b2296aa82164de23ada msgid "Scan method" msgstr "スキャン方法" #: ../../hint_list.md 69d089f1ca1e426a9f770b9813c9f373 msgid "`SeqScan(table)`" msgstr "`SeqScan(テーブル)`" #: ../../hint_list.md 7f920c34598e41c4abbfeebfa0ec8871 msgid "Forces sequential scan on the table" msgstr "指定されたテーブルにシーケンシャルスキャンを強制します。" #: ../../hint_list.md 3d91d6fbac2140b894d5bca6291216ad msgid "`TidScan(table)`" msgstr "`TidScan(テーブル)`" #: ../../hint_list.md 7370bfd7f6134bc089ca1829f1dd161b msgid "Forces TID scan on the table." msgstr "" "指定されたテーブルにTid スキャンを強制します。検索条件にctidを指定した場合にのみ" "有効です。" #: ../../hint_list.md 0997f45a936d496baa32ca3b4792b082 msgid "`IndexScan(table[ index...])`" msgstr "`IndexScan(テーブル[ インデックス...])`" #: ../../hint_list.md 924f8a0bc9c44adba0472db377107fa5 msgid "Forces index scan on the table. Restricts to specified indexes if any." msgstr "" "指定されたテーブルにインデックススキャンを強制します。指定されたインデックスがあ" "る場合は、そのインデックスに限定されます。" #: ../../hint_list.md 630c0aaa32e240a9aebbf6f0d6927b2b msgid "`IndexOnlyScan(table[ index...])`" msgstr "`IndexOnlyScan(テーブル[ インデックス...])`" #: ../../hint_list.md d8dbbcdae0d64097bd27d5a44512a2a8 msgid "" "Forces index only scan on the table. Rstricts to specfied indexes if any. Index " "scan may be used if index only scan is not available. Available for PostgreSQL " "9.2 and later." msgstr "" "指定されたテーブルにインデックスオンリースキャンを強制します。指定されたインデッ" "クスがある場合は、そのインデックスに限定されます。インデックスオンリースキャンが" "利用できない場合、インデックススキャンが使用されることがあります。PostgreSQL 9.2" "以降で利用可能です。" #: ../../hint_list.md faf1f1c88f6a42a1b94e9ba8bbdfc6ed msgid "`BitmapScan(table[ index...])`" msgstr "`BitmapScan(テーブル[ インデックス...])`" #: ../../hint_list.md d6ab022dbdc046c78505847c00d1b4ed msgid "Forces bitmap scan on the table. Restoricts to specfied indexes if any." msgstr "" "指定されたテーブルにビットマップスキャンを強制します。指定されたインデックスがあ" "る場合は、そのインデックスに限定されます。" #: ../../hint_list.md 065a48f89a414a49a3d80e7781e8b756 msgid "" "`IndexScanRegexp(table[ POSIX Regexp...])` `IndexOnlyScanRegexp(table[ POSIX " "Regexp...])` `BitmapScanRegexp(table[ POSIX Regexp...])`" msgstr "" "`IndexScanRegexp(テーブル[ POSIX正規表現...])` `IndexOnlyScanRegexp(テーブル" "[ POSIX正規表現...])` B`itmapScanRegexp(テーブル[ POSIX正規表現...])`" #: ../../hint_list.md 746cae5da6bb405bbb29cdf022f06a02 msgid "" "Forces index scan or 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 58887d5a7c3f4c6b8eaa45c2cb4ea7a2 msgid "`NoSeqScan(table)`" msgstr "`NoSeqScan(テーブル)`" #: ../../hint_list.md 2c091bbb207d4f7fac9f128bee79238a msgid "Forces not to do sequential scan on the table." msgstr "指定されたテーブルにシーケンシャルスキャンを行わないように強制します。" #: ../../hint_list.md 26a8333a1b2c49c891ecacc60f1d8948 msgid "`NoTidScan(table)`" msgstr "`NoTidScan(テーブル)`" #: ../../hint_list.md 157cf450e29f4601b3f4b6f2b07dd554 msgid "Forces not to do TID scan on the table." msgstr "指定されたテーブルにTIDスキャンを行わないように強制します。" #: ../../hint_list.md 475fd42ff95e426598c786cf451e13ee msgid "`NoIndexScan(table)`" msgstr "`NoIndexScan(テーブル)`" #: ../../hint_list.md 733e3b00409f4ff0aa081d76f805bce4 msgid "" "Forces not to do index scan and index only scan (For PostgreSQL 9.2 and later) " "on the table." msgstr "" "指定されたテーブルに対してインデックススキャン、インデックスオンリースキャン" "(PostgreSQL 9.2以降)を行わないように強制します。" #: ../../hint_list.md c25cd00bac584bb3b5d5533b3b0abbcf msgid "`NoIndexOnlyScan(table)`" msgstr "`NoIndexOnlyScan(テーブル)`" #: ../../hint_list.md db740f34a70443b995ad0c1d4c03f02a msgid "" "Forces not to do index only scan on the table. Available for PostgreSQL 9.2 and " "later." msgstr "" "指定されたテーブルにインデックスオンリースキャンを行わないように強制します。" "PostgreSQL 9.2以降で利用可能です。" #: ../../hint_list.md 38fe8e8cf87b404cab12a8094bb4af8a msgid "`NoBitmapScan(table)`" msgstr "`NoBitmapScan(テーブル)`" #: ../../hint_list.md 91c0bdc352d34cea9cf5e55c029f8be8 msgid "Forces not to do bitmap scan on the table." msgstr "指定されたテーブルにビットマップスキャンを行わないように強制します。" #: ../../hint_list.md 72dfbf1afe674a58b3edec26c593413e msgid "Join method" msgstr "結合方法" #: ../../hint_list.md 0a05e92b87ab4945a326b57170e96309 msgid "`NestLoop(table table[ table...])`" msgstr "`NestLoop(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md a2dabc91f3cc4d79b1bb4248359806ce msgid "Forces nested loop for the joins consist of the specifiled tables." msgstr "指定されたテーブルで構成された結合にネステッドループ結合を強制します。" #: ../../hint_list.md 5d30da1c221540a8b87dd81e6c7eeec6 msgid "`HashJoin(table table[ table...])`" msgstr "`HashJoin(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md effcc9a4c6a04b70b7747d7220501685 msgid "Forces hash join for the joins consist of the specifiled tables." msgstr "指定されたテーブルで構成された結合にハッシュ結合を強制します。" #: ../../hint_list.md 16c4fbcddc294a318cae6ca8c5f937a5 msgid "`MergeJoin(table table[ table...])`" msgstr "`MergeJoin(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md bf5200a3a8064ad2846aa15e41347678 msgid "Forces merge join for the joins consist of the specifiled tables." msgstr "指定されたテーブルで構成された結合にマージ結合を強制します。" #: ../../hint_list.md 86a179c45c5746d69f616ffbd596732e msgid "`NoNestLoop(table table[ table...])`" msgstr "`NoNestLoop(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md de1c5f2f54fb40dfb216d79602ab8ba3 msgid "" "Forces not to do nested loop for the joins consist of the specifiled tables." msgstr "" "指定されたテーブルで構成する結合にネステッドループ結合が行われないように強制しま" "す。" #: ../../hint_list.md 83ca91534dc047b9802427739c982d39 msgid "`NoHashJoin(table table[ table...])`" msgstr "`NoHashJoin(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md c5190909839b405f976eb9a4577a62f5 msgid "Forces not to do hash join for the joins consist of the specifiled tables." msgstr "" "指定されたテーブルで構成する結合にハッシュ結合が行われないように強制します。" #: ../../hint_list.md 7391503375834468a238e9cbbf2f4d8d msgid "`NoMergeJoin(table table[ table...])`" msgstr "`NoMergeJoin(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 75d038d3264647ef9ed3cccb4c0500c1 msgid "" "Forces not to do merge join for the joins consist of the specifiled tables." msgstr "" "指定されたテーブルで構成する結合にマージ結合が行われないように強制します。" #: ../../hint_list.md f1b4eeed9580475f806023bc8637f4da msgid "Join order" msgstr "結合順序" #: ../../hint_list.md 217b3910fa25410c98bfcc3e5bf84667 msgid "`Leading(table table[ table...])`" msgstr "`Leading(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 211e2292dd7044558afdefd4ebe073cc msgid "Forces join order as specified." msgstr "指定された結合順序に強制します。" #: ../../hint_list.md a601d2fcdabf45328c36c963d1a6c19b msgid "`Leading()`" msgstr "`Leading(<結合のペア>)`" #: ../../hint_list.md 1936d1297a294f5681842f6c41ed2c3b 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 95863faa28434880931d9d8b59ed2e28 msgid "Behavior control on Join" msgstr "結合時の挙動制御" #: ../../hint_list.md 531dc40687f8428aa27c3c37fd879b23 msgid "`Memoize(table table[ table...])`" msgstr "`Memoize(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 87f89ceb23f14d93ab188f7a3320dc36 msgid "" "Allow the topmost join of a join among the specified tables to memoize the " "inner result. (Note that this doesn't enforce.)" msgstr "" "指定されたテーブル間の結合の最上位の結合が、内部表の結果をメモすることを許可す" "る (これは強制ではないことに注意)。" #: ../../hint_list.md e795ca8346da48889cf64803b3c33c57 msgid "`NoMemoize(table table[ table...])`" msgstr "`NoMemoize(テーブル テーブル[ テーブル...])`" #: ../../hint_list.md 6be8443991d1487887915652a8de0225 msgid "" "Inhibit the topmost join of a join among the specified tables from memoizing " "the inner result." msgstr "" "指定されたテーブル間の結合の最上位の結合が、内部表の結果をメモすることを禁止しま" "す。" #: ../../hint_list.md 584e43a7d7a7486794f2883ce3917846 msgid "Row number correction" msgstr "見積り行数の補正" #: ../../hint_list.md d0f5ca6f324e46f593e7bc3ad4444ccc msgid "`Rows(table table[ table...] correction)`" msgstr "`Rows(テーブル テーブル[ テーブル...] 行数補正)`" #: ../../hint_list.md 6fe388b4092c4029acd7d4afb79df8cb msgid "" "Corrects row number of a result of the joins consist of the specfied tables. " "The available correction methods are absolute (#), addition (+), subtract " "(-) and multiplication (*). should be a string that strtod() can read." msgstr "" "指定されたテーブルの結合結果の見積り行数を補正します。補正方法は、絶対値(#)、" "加算(+)、減算(-)、乗算(*)です。はstrtod()が読み込める文字列でなけれ" "ばなりません。" #: ../../hint_list.md aad2c1c5fa9a4c8dbd622799eb4fe2ea msgid "Parallel query configuration" msgstr "パラレルクエリの設定" #: ../../hint_list.md 22110dff7c3e47bd9d93187994aee370 msgid "`Parallel(table <# of workers> [soft|hard])`" msgstr "`Parallel(table <ワーカー数> [soft|hard])`" #: ../../hint_list.md a4bab43927c64dab88a8178cd90be51b msgid "" "Enforce or inhibit parallel execution of specfied 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 leave everything else to planner. Hard " "means enforcing the specified number of workers." msgstr "" "指定されたテーブルの並列実行を強制または禁止します。<ワーカー数>は希望する並列" "ワーカー数で、0は並列実行を禁止することを意味します。第3パラメータがsoft(デフォ" "ルト)の場合、max_parallel_workers_per_gatherを変更するだけで、その他すべては" "plannerに任せます。hardは指定された数のワーカーを強制することを意味します。" #: ../../hint_list.md 4cdb0ede7ade4a5a83f290cbacb2e911 msgid "GUC" msgstr "GUCパラメータ" #: ../../hint_list.md 4b61016be4784214b9878bf8c76664f5 msgid "`Set(GUC-param value)`" msgstr "`Set(GUCパラメータ 値)`" #: ../../hint_list.md b2bf66afa23c4cd89339b17bde923280 msgid "Set the GUC parameter to the value while planner is running." msgstr "プランナが実行中の間、GUCパラメータの値を設定します。" #~ msgid "copyright (c) 2012-2023, nippon telegraph and telephone corporation" #~ msgstr "copyright (c) 2012-2023, nippon telegraph and telephone corporation" pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/hint_table.po000066400000000000000000000373611447776766000242540ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan hint table. # Copyright (C) 2012-2023, 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. # 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-07-15 14:45+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 8baa4d74a07a484ab10bf71a4db7f6e3 msgid "The hint table" msgstr "ヒントテーブル" #: ../../hint_table.md:3 050b9f70a77d416d94a4c25241ecc840 msgid "" "Hints are described in a comment in a special form in the above section. " "This is 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 f75cb6784010442795ad26847270265b msgid "column" msgstr "列名" #: ../../hint_table.md 344c7576e2224366ab8a919bacf2ee5a msgid "description" msgstr "説明" #: ../../hint_table.md 3a93f17247e34f7ea2cd6faa72aa177c #: bdeed22153a54a69a775e18160173488 msgid "`id`" msgstr "`id`" #: ../../hint_table.md 5c11835e2ca34905bffeedf8cc358494 #: e3e2b2fedd904937ab8d433bbca83393 msgid "" "Unique number to identify a row for a hint.
This column is filled " "automatically by sequence." msgstr "" "ユーザがヒントの行を識別するためのユニークな番号です。連番型ですので新し" "いヒントを登録するときには、この列を指定しないでください。" #: ../../hint_table.md 81a2155af39f40899af1a695d9daa02e msgid "`norm_query_string`" msgstr "`norm_query_string`" #: ../../hint_table.md c9820d515ac3416caa722829f4c90c6c msgid "" "A pattern matches to the query to be hinted.
Constants in the query " "have to be replace with '?' as in the following example.
White space " "is significant in the pattern." msgstr "" "実行計画を制御したいクエリを指定します。対象のクエリに定数があるときは、" "下記の例のように「?」に置き換えます。キーワード間の空白の数が、登録するク" "エリと実行するクエリで異なると別のSQL文として扱われます。" #: ../../hint_table.md 7186678f2325492ba37824e9a7b4efff msgid "`application_name`" msgstr "`application_name`" #: ../../hint_table.md 0aec29349ae44c73a8ffa379a0987b83 msgid "" "The value of `application_name` of sessions to apply the hint.
The " "hint in the example below applies to sessions connected from psql.
An " "empty string means sessions of any `application_name`." msgstr "" "ヒントの適用対象のアプリケーション名を指定します。下記の例ではpsqlから実" "行されたクエリのみがヒントの適用対象となります。全てのアプリケーションに" "ヒントを適用したいときは、空文字列を登録します。アプリケーション名は、" "セッションの`application_name`GUCパラメータと等しいか判断します。" #: ../../hint_table.md ad9353d2dba44ceda768e4e1aa3f4991 msgid "`hints`" msgstr "`hints`" #: ../../hint_table.md 25c56485c9db4e2ea0022516a571ad28 msgid "" "Hint phrase.
This must be a series of hints excluding surrounding " "comment marks." msgstr "ヒント句を指定します。コメントの記号を除いた内容のみを登録します。" #: ../../hint_table.md:16 2670591da3fb47b3a9535f39325bb76b msgid "The following example shows how to operate with the hint table." msgstr "以下の例はヒント テーブルの操作方法を示しています。" #: ../../hint_table.md:36 c0a6b26df5944f9f9912315119eb358e msgid "" "The hint table is owned by the creator user and having the default " "privileges at the time of creation. during `CREATE EXTENSION`. Table " "hints are prioritized over comment hits." msgstr "" "ヒントテーブルは作成者が所有し、作成時のデフォルトの権限を持ちます。テー" "ブルによるヒント(テーブルヒント)はコメントによるヒント(コメントヒン" "ト)よりも優先されます。" #: ../../hint_table.md:40 5ec181551e2d45dcb0a21814f351dba2 msgid "The types of hints" msgstr "ヒントの種類" #: ../../hint_table.md:42 75f0544a2f974923a941cb4d70827047 msgid "" "Hinting phrases are classified into six types based on what kind of " "object and how they can affect planning. Scanning methods, join methods, " "joining order, row number correction, parallel query, and GUC setting. " "You will see the lists of hint phrases of each type in [Hint list]" "(#hint-list)." msgstr "" "ヒント句はどの対象にどのような影響をプランニングに与えるかに基づいて6種" "類に分類されます。種類はスキャン方法・結合方法・結合順序・見積り行数補" "正・並列実行の設定・GUCパラメータです。具体的なヒント句は、[ヒント一覧]" "(#hint_list)を参照してください。" #: ../../hint_table.md:47 d92729e6d6304658812badf989c7b547 msgid "Hints for scan methods" msgstr "スキャン方法" #: ../../hint_table.md:49 731e558d501d44fdb71efde32f578f16 msgid "" "Scan method hints enforce specific scanning method on the target table. " "`pg_hint_plan` recognizes the target table by alias names if any. They " "are `SeqScan`, `IndexScan` and so on in this kind of hint." msgstr "" "スキャン方法のヒントは、対象のテーブルに対して特定のスキャン方法を強制す" "るものです。`pg_hint_plan`は対象のテーブルに別名が存在する場合、別名で認" "識します。この種類のヒントには`SeqScan`や`IndexScan`などを含みます。" #: ../../hint_table.md:53 e7d6f019f9b2478bbc935af86d631587 msgid "" "Scan hints are effective on ordinary tables, inheritance tables, " "UNLOGGED tables, temporary tables and system catalogs. External " "(foreign) tables, table functions, VALUES clause, CTEs, views and " "subquiries are not affected." msgstr "" "スキャン方法のヒントは、通常のテーブル・継承テーブル・UNLOGGEDテーブル・" "一時テーブル・システムカタログに効果があります。外部テーブル・テーブル関" "数・VALUES句・CTE・ビュー・副問い合わせには影響を与えません。" #: ../../hint_table.md:65 9b9f081a314e43c7b89d4b3e91b75228 msgid "Hints for join methods" msgstr "結合方法" #: ../../hint_table.md:67 2d689b208c3147159c3f49a7967fb039 msgid "" "Join method hints enforce the join methods of the joins involving " "specified tables." msgstr "" "結合方法のヒントは、指定したテーブルを含む結合の結合方法を強制するもので" "す。" #: ../../hint_table.md:70 cd01bba4af2247218d855e74f1f0c1ba msgid "" "This can affect on 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. But joins on views and sub query are not " "affected." msgstr "" "これは、通常のテーブル・継承テーブル・UNLOGGEDテーブル・一時テーブル・外" "部テーブル・システムカタログ・テーブル関数・VALUESコマンド結果、およびパ" "ラメータリストに含めることが許可されているCTEの結合にのみ影響を与えます。" "しかし、ビュー・副問い合わせの結合には影響を与えません。" #: ../../hint_table.md:75 d077481a5a1f4d69b87fbe3fa7b99f54 msgid "Hint for joining order" msgstr "結合順序" #: ../../hint_table.md:77 58aa277e5d28418f91c1738bb750d1e1 msgid "" "This hint \"Leading\" enforces the order of join on two or more tables. " "There are two ways of enforcing. One is enforcing specific order of " "joining but not restricting direction at each join level. Another " "enfoces join direction additionaly. Details are seen in the [hint list]" "(#hint-list) table." msgstr "" "`Leading`ヒントは、2つ以上のテーブルの結合順序を強制するものです。強制に" "は2つの方法があります。1つは特定の結合順序を強制し各結合レベルでは方向を" "制限しない方法です。もう1つは結合の方向を追加で指定するものです。詳細は" "[ヒント一覧](#hint-list)で確認できます。" #: ../../hint_table.md:93 e3425878f3a44e12aa1610cc46993a70 msgid "Hint for row number correction" msgstr "行数補正" #: ../../hint_table.md:95 4241c94b75cb45849ff3a8f6c777e124 msgid "" "This hint \"Rows\" corrects row number misestimation of joins that comes " "from restrictions of the planner." msgstr "" "`Rows`ヒントは、プランナの制限に起因する結合の見積り行数誤りを修正しま" "す。" #: ../../hint_table.md:105 467974e2649d40fba83869172b0a7c1d msgid "Hint for parallel plan" msgstr "並列実行" #: ../../hint_table.md:107 11afb39b898642dbb074e8ddfb94f0bf msgid "" "This hint `Parallel` enforces parallel execution configuration on scans. " "The third parameter specifies the strength of enfocement. `soft` means " "that `pg_hint_plan` only changes `max_parallel_worker_per_gather` and " "leave all others to planner. `hard` changes other planner parameters so " "as to forcibly apply the number. This can affect on ordinary tables, " "inheritnce parents, unlogged tables and system catalogues. External " "tables, table functions, values clause, CTEs, views and subqueries are " "not affected. Internal tables of a view can be specified by its real " "name/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:142 c5ce54b7989f47e5ad814c5eccdbb675 msgid "GUC parameters temporarily setting" msgstr "GUCパラメータ" #: ../../hint_table.md:144 f76759e685144105be569d773df841db msgid "" "`Set` hint changes 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 any other hint conflicts with the planner method configuration " "parameters. The last one among hints on the same GUC parameter makes " "effect. [GUC parameters for `pg_hint_plan`](#guc-parameters-for-" "pg_hint_plan) are also settable by this hint but it won't work as your " "expectation. See [Restrictions](#restrictions) 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:160 8b72bd9fc2b84ba8a24097c213f772d7 msgid "GUC parameters for `pg_hint_plan`" msgstr "pg_hint_planのGUCパラメータ" #: ../../hint_table.md:162 6237ee882e3a41e2920e9957cc9cdba6 msgid "GUC parameters below affect the behavior of `pg_hint_plan`." msgstr "pg_hint_planの動作を制御するGUCパラメータを以下に記述します。" #: ../../hint_table.md 08f8096aa841448ebf0ea70074d909e6 msgid "Parameter name" msgstr "パラメータ名" #: ../../hint_table.md 82105f6e9ad84cf9a57efd18de5c588a msgid "Description" msgstr "説明" #: ../../hint_table.md 1505ffc204664aea82ee49df94e5db36 msgid "Default" msgstr "デフォルト値" #: ../../hint_table.md 7e428113623648d1a71cf79670ea1d0d msgid "`pg_hint_plan.enable_hint`" msgstr "`pg_hint_plan.enable_hint`" #: ../../hint_table.md 7f630626e2834f1ea0b49ead7e6db068 msgid "True enbles `pg_hint_plan`." msgstr "Trueは`pg_hint_plan`を有効にします。" #: ../../hint_table.md 6d5412bd09d24a68984200288a8de79f msgid "`on`" msgstr "`on`" #: ../../hint_table.md 475fc500f1c14f90b3ea82ce4529bc29 msgid "`pg_hint_plan.enable_hint_table`" msgstr "`pg_hint_plan.enable_hint_table`" #: ../../hint_table.md 8f91885232f2466d8a72a8dd1864f7c5 msgid "True enbles hinting by table. `true` or `false`." msgstr "Trueはテーブルによってヒントを指定する機能を有効にします。" #: ../../hint_table.md 4eccf61a96e4462b8bf46bed0e11b1c0 #: ddedbba0bc994ba08509d27fbe4d56da msgid "`off`" msgstr "`off`" #: ../../hint_table.md 4fd8865bbe9c4e33a5e1be648a8eb40c msgid "`pg_hint_plan.parse_messages`" msgstr "`pg_hint_plan.parse_messages`" #: ../../hint_table.md 0b02ed9494c5492b85057c2afd33b533 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 05feb42d3c53483da6c24cff302e4312 #: 0f9f4b696da243619601a5ce1dc92eb4 msgid "`INFO`" msgstr "`INFO`" #: ../../hint_table.md 0515a23482d744e5b0ad0518d105a4a6 msgid "`pg_hint_plan.debug_print`" msgstr "`pg_hint_plan.debug_print`" #: ../../hint_table.md c3461a25627b4efa83b851d1f2d937d0 msgid "" "Controls debug print and verbosity. Valid vaiues are `off`, `on`, " "`detailed` and `verbose`." msgstr "" "動作状況を示すログメッセージの出力を制御します。指定可能な値は `off`、" "`on`、`detailed`、`verbose`です。" #: ../../hint_table.md 06e41cc64402445492d6058a38320954 msgid "`pg_hint_plan.message_level`" msgstr "`pg_hint_plan.message_level`" #: ../../hint_table.md f88396e89d2a4340b8adb1c97ebcf6c1 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-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/index.po000066400000000000000000000016221447776766000232410ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan index page. # Copyright (C) 2012-2023, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # This file is distributed under the same license as the pg_hint_plan # package. # Julien Rouhaud , 2023. # #, 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.6" msgstr "pg_hint_plan 1.6" #: ../../index.md:2 b5608f9be7e34270a28850acab4a3fae msgid "Table of Contents" msgstr "目次" pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/installation.po000066400000000000000000000060401447776766000246320ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan installation. # Copyright (C) 2012-2023, 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. # 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-06-05 15:03+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 88a8f8501d174d67bb9ac7eacd67677a msgid "Installation" msgstr "インストール" #: ../../installation.md:3 1a3061c87eb5480cb0426dff856d06b7 msgid "This section describes the installation steps." msgstr "このセクションはpg_hint_planのインストール方法について説明します。" #: ../../installation.md:5 2b41d2a2c4974b1b944e9faa5ac7e799 msgid "building binary module" msgstr "ビルド" #: ../../installation.md:7 eb9484bcbd6c4d05bd6d9e5458b35ea9 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 for the target PostgreSQL for this process." msgstr "" "ソースツリーの先頭で `make` を実行し、適切なユーザで `make install` を実" "行してください。環境変数 `PATH` は、この処理で対象となる PostgreSQL に対" "して適切に設定されている必要があります。" #: ../../installation.md:17 6c3685561f2441f3918283f9a802ca6e msgid "Loading `pg_hint_plan`" msgstr "`pg_hint_plan`のロード" #: ../../installation.md:19 aa76045ee0b74dbb823ffa9767cb4259 msgid "" "Basically `pg_hint_plan` does not require `CREATE EXTENSION`. Simply " "loading it by `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 for specific sessions." msgstr "" "`pg_hint_plan` は基本的に`CREATE EXTENSION`を必要としません。単純に`LOAD`" "コマンドで有効化できます。もちろん、`postgresql.conf`の" "`shared_preload_libraries` を設定することで全体にロード することができま" "す。また、特定のユーザに対し自動的にロードするための`ALTER USER SET`/" "`ALTER DATABASE SET`に興味があるかもしれません。" #: ../../installation.md:31 28ccb49c1b2f498b8ed85e5e231f40d9 msgid "" "Do `CREATE EXTENSION` and `SET pg_hint_plan.enable_hint_tables TO on` if " "you are planning to use the hint table." msgstr "" "ヒントテーブルを使用する場合は、`CREATE EXTENSION` を実行し`SET " "pg_hint_plan.enable_hint_tables TO on`を実行してください。" pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/requirements.po000066400000000000000000000052771447776766000246670ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan requirements. # Copyright (C) 2012-2023, 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. # 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-06-05 16:07+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" #: ../../requirements.md:1 68a32e7085974f1e910660f736a6dfec msgid "Requirements" msgstr "動作環境" #: ../../requirements.md:3 3e0ef43c79334e4b8818ab973f0b8e8b msgid "pg_hint_plan 1.6 requires PostgreSQL 16." msgstr "pg_hint_plan 1.6 は PostgreSQL 16 のみをサポートします。" #: ../../requirements.md:6 d30d4c9f346147fa85c1103448fcf5a6 msgid "PostgreSQL versions tested" msgstr "テスト済みのPostgreSQLバージョン" #: ../../requirements.md:8 454cb93d64d74a68adbb68d0627fbe57 msgid "Version 16" msgstr "バージョン 16" #: ../../requirements.md:10 9c91df10a07a47309edd0401d0d87c2a msgid "OS versions tested" msgstr "テスト済みのOSバージョン" #: ../../requirements.md:12 fc18a166243b42e2a3066aaf4059bb64 msgid "CentOS 8.5" msgstr "CentOS 8.5" #: ../../requirements.md:14 d9dc1776bac04d808fe625969d4ae98a msgid "See also" msgstr "関連項目" #: ../../requirements.md:17 3415b19f8d7a4e4ab5a28944d6c57ea8 msgid "PostgreSQL documents" msgstr "PostgreSQLドキュメント" #: ../../requirements.md:19 edb6d92b6a774ef29d69a1547025766e 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:20 cf2ad6532eb149d28aad3e2a8f23f30b 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:21 709e880d2b554e8a9dc6df98b7897b2e 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:22 56a36dfb4f7c4680ae9479a0ed07f17d 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-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/synopsis.po000066400000000000000000000044751447776766000240320ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan synopsis. # Copyright (C) 2012-2023, 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. # msgid "" msgstr "" "Project-Id-Version: pg_hint_plan\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-20 16:24+0900\n" "PO-Revision-Date: 2023-07-14 14:58+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" #: ../../synopsis.md:1 b690240736284cd1bd13ae1530583873 msgid "Synopsis" msgstr "概要" #: ../../synopsis.md:3 140dfc13208f44eeb44f8592d430de13 msgid "" "`pg_hint_plan` makes it possible to tweak PostgreSQL execution plans using so-called " "\"hints\" in SQL comments, like `/*+ SeqScan(a) */`." msgstr "" "`pg_hint_plan`はヒント (SQLコメント内の`/*+ SeqScan(a) */`など) を用いることで実行計画を制御す" "ることができます。" #: ../../synopsis.md:6 27d61755e5554247b68e06b62a6dfe2c msgid "" "PostgreSQL uses a cost-based optimizer, which utilizes data statistics, not static rules. The " "planner (optimizer) esitimates costs of each possible execution plans for a SQL statement " "then the execution plan with the lowest cost finally be executed. The planner does its best " "to select the best execution plan, but is not always perfect, since it doesn't count some " "properties of the data, for example, correlation between columns." msgstr "" "PostgreSQLのプランナは静的なルールではなくデータの統計情報を用いたコストベースのオプティマイザ" "を利用しています。プランナ(オプティマイザ)はSQL文に対して可能な限りの実行計画のコストを推定" "し、最もコストが低い実行計画を最終的に選択します。プランナは最適な実行計画を選択するために最善" "を尽くしますが、データのいくつかの特性(例えば、カラム間の相関関係)を考慮していないため、常に" "完璧とは言えません。" pg_hint_plan-REL16_1_6_0/docs/locale/ja/LC_MESSAGES/uninstallation.po000066400000000000000000000026351447776766000252030ustar00rootroot00000000000000# LANGUAGE message translation file for pg_hint_plan uninstallation. # Copyright (C) 2012-2023, 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. # 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-06-05 15:06+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" #: ../../uninstallation.md:1 2d6a150c5d724b10b00eb53a67fb7b3e msgid "Uninstallation" msgstr "アンインストール" #: ../../uninstallation.md:3 3e750dafa7a14af6ac4e715f614d0a2d 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." msgstr "" "ソース ツリーからインストールし、それが利用可能なままになっている場合は" "ソース ツリーの最上位ディレクトリ内で `make uninstall` を実行すると、イ" "ンストールされたファイルがアンインストールされます。" pg_hint_plan-REL16_1_6_0/docs/make.bat000066400000000000000000000014401447776766000175570ustar00rootroot00000000000000@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-REL16_1_6_0/docs/requirements.in000066400000000000000000000004351447776766000212300ustar00rootroot00000000000000# 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-REL16_1_6_0/docs/requirements.md000066400000000000000000000007431447776766000212240ustar00rootroot00000000000000# Requirements pg_hint_plan 1.6 requires PostgreSQL 16. PostgreSQL versions tested - Version 16 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-REL16_1_6_0/docs/requirements.txt000066400000000000000000000031761447776766000214460ustar00rootroot00000000000000# # 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>=2023.7.22 # 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.4 # via requests imagesize==1.4.1 # via sphinx jinja2==3.1.2 # 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.15.0 # via sphinx pyyaml==6.0 # via myst-parser requests==2.31.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.14 # via requests # The following packages are considered to be unsafe in a requirements file: # setuptools pg_hint_plan-REL16_1_6_0/docs/synopsis.md000066400000000000000000000010671447776766000203700ustar00rootroot00000000000000# 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-REL16_1_6_0/docs/uninstallation.md000066400000000000000000000004401447776766000215370ustar00rootroot00000000000000# 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-REL16_1_6_0/expected/000077500000000000000000000000001447776766000170245ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/expected/R_sample.out000066400000000000000000000006531447776766000213230ustar00rootroot00000000000000 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-REL16_1_6_0/expected/base_plan.out000066400000000000000000000044161447776766000215060ustar00rootroot00000000000000SET 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-REL16_1_6_0/expected/hints_anywhere.out000066400000000000000000000040311447776766000226020ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET client_min_messages TO log; \set SHOW_CONTEXT always SET pg_hint_plan.debug_print TO on; explain (costs false) select * from t1 join t2 on t1.id = t2.id where '/*+HashJoin(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) set pg_hint_plan.hints_anywhere = on; explain (costs false) select * from t1 join t2 on t1.id = t2.id where '/*+HashJoin(t1 t2)*/' <> ''; 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) set pg_hint_plan.hints_anywhere = off; explain (costs false) select * from t1 join t2 on t1.id = t2.id where '/*+HashJoin(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) set pg_hint_plan.hints_anywhere = on; /*+ MergeJoin(t1 t2) */ explain (costs false) select * from t1 join t2 on t1.val = t2.val where '/*+HashJoin(t1 t2)*/' <> ''; LOG: pg_hint_plan: used hint: MergeJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN ------------------------------------------- Merge Join Merge Cond: (t2.val = t1.val) -> Index Scan using t2_val on t2 -> Materialize -> Index Scan using t1_val on t1 (5 rows) /*+ HashJoin(t1 t2) */ explain (costs false) select * from t1 join t2 on t1.val = t2.val where '/*+MergeJoin(t1 t2)*/' <> ''; LOG: pg_hint_plan: used hint: HashJoin(t1 t2) not used hint: duplication hint: error hint: QUERY PLAN -------------------------------- Hash Join Hash Cond: (t2.val = t1.val) -> Seq Scan on t2 -> Hash -> Seq Scan on t1 (5 rows) pg_hint_plan-REL16_1_6_0/expected/init.out000066400000000000000000000307671447776766000205350ustar00rootroot00000000000000SET 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; /* * The following GUC parameters need the setting of the default value to * succeed in regression test. */ /* Fix auto-tunable parameters */ ALTER SYSTEM SET effective_cache_size TO 16384; SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row) 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_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 (50 rows) ANALYZE; pg_hint_plan-REL16_1_6_0/expected/oldextversions.out000066400000000000000000000073711447776766000226550ustar00rootroot00000000000000-- -- 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 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 (2 rows) DROP EXTENSION pg_hint_plan; pg_hint_plan-REL16_1_6_0/expected/pg_hint_plan.out000066400000000000000000011361161447776766000222300ustar00rootroot00000000000000SET 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 warining 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 warining 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 warining ?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 "/* nest comment */ */ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id;" DETAIL: Nested block comments are not supported. 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; 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 = $3) InitPlan 2 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_1 Index Cond: ((id IS NOT NULL) AND (id < 10)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_2 Index Cond: ((id IS NOT NULL) AND (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 = $3) InitPlan 1 (returns $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 (returns $3) -> Result InitPlan 2 (returns $2) -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_2 Index Cond: ((id IS NOT NULL) AND (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 = $3) InitPlan 2 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_1 Index Cond: ((id IS NOT NULL) AND (id < 10)) InitPlan 3 (returns $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 = $3) InitPlan 2 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_1 Index Cond: ((id IS NOT NULL) AND (id < 10)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_2 Index Cond: ((id IS NOT NULL) AND (id < 10)) -> Bitmap Index Scan on t1_pkey Index Cond: (id = $3) (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 = $3) InitPlan 1 (returns $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 (returns $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(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 = $3) InitPlan 1 (returns $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 (returns $3) -> Result InitPlan 2 (returns $2) -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_2 Index Cond: ((id IS NOT NULL) AND (id < 10)) -> Bitmap Index Scan on t1_pkey Index Cond: (id = $3) (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 = $3) InitPlan 2 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Only Scan Backward using t1_pkey on t1 v_1 Index Cond: ((id IS NOT NULL) AND (id < 10)) InitPlan 3 (returns $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 = $3) (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 = $3) InitPlan 1 (returns $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 (returns $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 = $3) (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 (returns $0) -> 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 (returns $1) -> 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 = $1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $1) -> Seq Scan on t3 t3_1 Filter: (id = $1) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $1) -> Seq Scan on t3 t3_3 Filter: (id = $1) -> Aggregate Filter: (max(t1_5.id) = $1) -> 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 (returns $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 (returns $3) -> 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 = $3) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $3) -> Seq Scan on t3 t3_1 Filter: (id = $3) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $3) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $3) -> Seq Scan on t3 t3_3 Filter: (id = $3) -> Aggregate Filter: (max(t1_5.id) = $3) -> 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 (returns $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 (returns $3) -> 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 = $3) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $3) -> Seq Scan on t3 t3_1 Filter: (id = $3) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $3) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $3) -> Seq Scan on t3 t3_3 Filter: (id = $3) -> Aggregate Filter: (max(t1_5.id) = $3) -> 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 (returns $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 (returns $3) -> 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 = $3) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $3) -> Seq Scan on t3 t3_1 Filter: (id = $3) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $3) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $3) -> Seq Scan on t3 t3_3 Filter: (id = $3) -> Aggregate Filter: (max(t1_5.id) = $3) -> 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 (returns $0) -> 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 (returns $1) -> 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 = $1) -> Aggregate Filter: (max(t1_5.id) = $1) -> 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 = $1) -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $1) -> Seq Scan on t3 t3_1 Filter: (id = $1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $1) -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = $1) (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 (returns $0) -> 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 (returns $1) -> 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 = $1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $1) -> Seq Scan on t3 t3_1 Filter: (id = $1) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $1) -> Seq Scan on t3 t3_3 Filter: (id = $1) -> Aggregate Filter: (max(t1_5.id) = $1) -> 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 (returns $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 (returns $3) -> 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 = $3) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $3) -> Seq Scan on t3 t3_1 Filter: (id = $3) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $3) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $3) -> Seq Scan on t3 t3_3 Filter: (id = $3) -> Aggregate Filter: (max(t1_5.id) = $3) -> 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 (returns $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 (returns $3) -> 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 = $3) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $3) -> Seq Scan on t3 t3_1 Filter: (id = $3) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $3) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $3) -> Seq Scan on t3 t3_3 Filter: (id = $3) -> Aggregate Filter: (max(t1_5.id) = $3) -> 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 (returns $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 (returns $3) -> 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 = $3) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $3) -> Seq Scan on t3 t3_1 Filter: (id = $3) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_pkey on t1 t1_3 Index Cond: (id = $3) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $3) -> Seq Scan on t3 t3_3 Filter: (id = $3) -> Aggregate Filter: (max(t1_5.id) = $3) -> 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 (returns $0) -> 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 (returns $1) -> 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 = $1) -> Index Only Scan using t2_pkey on t2 t2_3 Index Cond: (id = $1) -> Seq Scan on t3 t3_3 Filter: (id = $1) -> Aggregate Filter: (max(t1_5.id) = $1) -> 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 = $1) -> Index Only Scan using t2_pkey on t2 t2_1 Index Cond: (id = $1) -> Index Only Scan using t1_pkey on t1 t1_1 Index Cond: (id = $1) (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 (returns $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 < $1) -> 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 (returns $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 < $1) -> 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 (returns $0) -> 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 < $0) -> 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 (returns $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 < $1) -> 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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ('EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;', '', 'SeqScan(t1)'); INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ('EXPLAIN (COSTS false) SELECT id FROM t1 WHERE t1.id = ?;', '', 'IndexScan(t1)'); INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ('EXPLAIN SELECT * FROM t1 WHERE t1.id = ?;', '', 'BitmapScan(t1)'); SELECT * FROM hint_plan.hints ORDER BY id; id | norm_query_string | application_name | hints ----+----------------------------------------------------------+------------------+---------------- 1 | EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?; | | SeqScan(t1) 2 | EXPLAIN (COSTS false) SELECT id FROM t1 WHERE t1.id = ?; | | IndexScan(t1) 3 | EXPLAIN SELECT * FROM t1 WHERE t1.id = ?; | | BitmapScan(t1) (3 rows) 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 \o results/pg_hint_plan.tmpout EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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: \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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: \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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: \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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: \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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: \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 t2 #aa) \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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. LOG: pg_hint_plan: used hint: not used hint: duplication hint: error hint: Rows(t1 t2 /99) \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) -- round up to 1 \o results/pg_hint_plan.tmpout /*+ 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) LOG: pg_hint_plan: used hint: Rows(t1 t2 -99999) not used hint: duplication hint: error hint: \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) -- complex join tree \o results/pg_hint_plan.tmpout EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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: \o \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \o results/pg_hint_plan.tmpout /*+ 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: \o set max_parallel_workers_per_gather to DEFAULT; \! sql/maskout.sh results/pg_hint_plan.tmpout QUERY PLAN ---------------- 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) \! rm results/pg_hint_plan.tmpout -- 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-REL16_1_6_0/expected/plpgsql.out000066400000000000000000001113631447776766000212440ustar00rootroot00000000000000-- -- 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; 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) -- 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-REL16_1_6_0/expected/ut-A.out000066400000000000000000003540601447776766000203730ustar00rootroot00000000000000LOAD '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; QUERY PLAN ----------------------------------- Index Only Scan using t1_i1 on t1 Index Cond: (c1 = 1) (2 rows) -- No. A-5-2-4 EXPLAIN (COSTS false) SELECT * /*+SeqScan(t1)*/ 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-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 | nextval('hint_plan.hints_id_seq'::regclass) norm_query_string | text | | not null | application_name | text | | not null | hints | text | | not null | Indexes: "hints_pkey" PRIMARY KEY, btree (id) "hints_norm_and_app" UNIQUE, btree (norm_query_string, 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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', '', '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 (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', 'psql', 'BitmapScan(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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', 'dummy_application_name', '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-2-4 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1;', '', '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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT c1 FROM s1.t1;', '', '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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', '', '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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ? OR t1.c1 = ?;', '', '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 "/**/)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "/**/" WHERE "/**/".c1 = 1;" DETAIL: Nested block comments are not supported. 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 "/**//**//**/)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "/**//**//**/" WHERE "/**//**//**/".c1 = 1;" DETAIL: Nested block comments are not supported. 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 "/**/あ")*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 "tT()"" Set/**/あ" WHERE "tT()"" Set/**/あ".c1 = 1;" DETAIL: Nested block comments are not supported. 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 "/* value */off)Set(enable_bitmapscan off)SeqScan(t1)*/ EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1;" DETAIL: Nested block comments are not supported. QUERY PLAN ------------------------------ Index Scan using t1_i1 on t1 Index Cond: (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 ---- INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', '', '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 pg_stat_statements_reset(); pg_stat_statements_reset -------------------------- (1 row) 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) SELECT s.query, s.calls FROM public.pg_stat_statements s JOIN pg_catalog.pg_database d ON (s.dbid = d.oid) ORDER BY 1; query | calls --------------------------------------+------- SELECT * FROM s1.t1 WHERE t1.c1 = $1 | 3 SELECT pg_stat_statements_reset() | 1 (2 rows) ---- ---- 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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_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 (50 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-REL16_1_6_0/expected/ut-G.out000066400000000000000000000742601447776766000204020ustar00rootroot00000000000000LOAD '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) RESET client_min_messages; ---- ---- 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" 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. 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 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 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 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 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; 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" 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; 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-REL16_1_6_0/expected/ut-J.out000066400000000000000000005367671447776766000204240ustar00rootroot00000000000000LOAD '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 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 (returns $0) -> 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 (returns $0) -> 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 (returns $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 (returns $0) -> 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 = $0) -> Seq Scan on t2 Filter: (c1 = $0) (13 rows) \o results/ut-J.tmpout /*+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: \o \! sql/maskout.sh results/ut-J.tmpout QUERY PLAN ---------------- Nested Loop (cost={inf}..{inf} rows=1 width=xxx) InitPlan 1 (returns $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 = $1) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (c1 = $1) -- -- 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 (returns $0) -> 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 (returns $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) -> 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 (returns $0) -> 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 (returns $1) -> 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 (returns $0) -> 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 (returns $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 3 (returns $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 = 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 (returns $0) -> 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 (returns $1) -> 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 (returns $2) -> 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 (returns $0) -> 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 (returns $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) -> 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 <> $0) AND (c1 <> $1)) -> 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 (returns $0) -> 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 (returns $1) -> 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 <> $0) AND (c1 <> $1)) -> 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 (returns $0) -> 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 (returns $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 3 (returns $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 = 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 <> $0) AND (c1 <> $1) AND (c1 <> $2)) -> 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 (returns $0) -> 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 (returns $1) -> 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 (returns $2) -> 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 <> $0) AND (c1 <> $1) AND (c1 <> $2)) -> 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> $3) AND (c1 = 1)) -> Result One-Time Filter: ($4 = 1) InitPlan 5 (returns $4) -> Limit -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> $3) AND (c1 = 1)) -> Result One-Time Filter: ($4 = 1) InitPlan 5 (returns $4) -> Limit -> Tid Scan on t1 b1t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (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 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> 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 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> 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 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> 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 (returns $0) -> 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 (returns $1) -> 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 <> $1) (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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 3 (returns $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 <> $3) -> 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 3 (returns $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 <> $3) (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) \o results/ut-J.tmpout /*+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: \o \! sql/maskout.sh results/ut-J.tmpout QUERY PLAN ---------------- 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) \! rm results/ut-J.tmpout -- 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-REL16_1_6_0/expected/ut-L.out000066400000000000000000005133441447776766000204100ustar00rootroot00000000000000LOAD '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 (returns $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 (returns $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 ---------------------------------------------------- Merge Join Merge Cond: (ct1.c1 = ct3.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 -> Merge Join Merge Cond: (ct1.c1 = ct2.c1) -> Sort Sort Key: ct1.c1 -> CTE Scan on c1 ct1 -> Sort Sort Key: ct2.c1 -> CTE Scan on c1 ct2 -> Materialize -> Merge Join Merge Cond: (ct3.c1 = ct4.c1) -> Sort Sort Key: ct3.c1 -> CTE Scan on c1 ct3 -> Sort Sort Key: ct4.c1 -> CTE Scan on c1 ct4 (33 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 --------------------------------------------------------- Merge Join Merge Cond: (ct1.c1 = ct2.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 -> Sort Sort Key: ct1.c1 -> CTE Scan on c1 ct1 -> Materialize -> Merge Join Merge Cond: (ct2.c1 = ct3.c1) -> Sort Sort Key: ct2.c1 -> CTE Scan on c1 ct2 -> Materialize -> Merge Join Merge Cond: (ct3.c1 = ct4.c1) -> Sort Sort Key: ct3.c1 -> CTE Scan on c1 ct3 -> Sort Sort Key: ct4.c1 -> CTE Scan on c1 ct4 (34 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 (returns $0) -> 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 (returns $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) -> 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 (returns $0) -> 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 (returns $1) -> 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 (returns $0) -> 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 (returns $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 3 (returns $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 = 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 (returns $0) -> 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 (returns $1) -> 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 (returns $2) -> 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 (returns $0) -> 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 (returns $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) -> 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 <> $0) AND (c1 <> $1)) -> 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 (returns $0) -> 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 (returns $1) -> 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 <> $0) AND (c1 <> $1)) -> 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 (returns $0) -> 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 (returns $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 3 (returns $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 = 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 <> $0) AND (c1 <> $1) AND (c1 <> $2)) -> 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 (returns $0) -> 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 (returns $1) -> 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 (returns $2) -> 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 <> $0) AND (c1 <> $1) AND (c1 <> $2)) -> 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> $3) 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> $3) 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 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> 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 (returns $0) -> 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 (returns $1) -> 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 <> $1) (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 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> 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 (returns $0) -> 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 (returns $1) -> 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 <> $1) (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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 3 (returns $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 <> $3) -> 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 3 (returns $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 <> $3) (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-REL16_1_6_0/expected/ut-R.out000066400000000000000000006251321447776766000204150ustar00rootroot00000000000000LOAD '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; \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-1-1 specified pattern of the object name ---- -- No. R-1-1-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-1-2 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-1-3 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-1-2 specified schema name in the hint option ---- -- No. R-1-2-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-2-2 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-1-3 table doesn't exist in the hint option ---- -- No. R-1-3-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-3-2 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-1-4 conflict table name ---- -- No. R-1-4-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-4-2 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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) \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-4-3 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) InitPlan 1 (returns $0) -> 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Merge Join (cost=xxx..xxx rows=100 width=xxx) Merge Cond: (t1.c1 = t2.c1) InitPlan 1 (returns $0) -> 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Merge Join (cost=xxx..xxx rows=1 width=xxx) Merge Cond: (t1.c1 = t2.c1) InitPlan 1 (returns $0) -> 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) ---- ---- No. R-1-5 conflict table name ---- -- No. R-1-5-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-5-2 \o results/ut-R.tmpout /*+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) \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-5-3 \o results/ut-R.tmpout /*+(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 "". \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+(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 "". \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-1-6 object type for the hint ---- -- No. R-1-6-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-6-2 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-6-3 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-6-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); \o results/ut-R.tmpout EXPLAIN SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-6-5 CREATE TEMP TABLE t_pg_class AS SELECT * from pg_class LIMIT 100; \o results/ut-R.tmpout EXPLAIN SELECT * FROM t_pg_class t1, t_pg_class t2 WHERE t1.oid = t2.oid; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-6-6 -- refer ut-fdw.sql -- No. R-1-6-7 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-6-8 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-6-9 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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))) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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))) -- No. R-1-6-10 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-6-11 \o results/ut-R.tmpout 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); \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $0) -> 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 = $0) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (c1 = $0) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $0) -> 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 = $0) -> Seq Scan on t2 (cost=xxx..xxx rows=1 width=xxx) Filter: (c1 = $0) -- -- There are cases where difference in the measured value and predicted value -- depending upon the version of PostgreSQL -- \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-1-7 specified number of conditions ---- -- No. R-1-7-1 \o results/ut-R.tmpout /*+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) \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-7-2 \o results/ut-R.tmpout /*+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) \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-1-7-3 \o results/ut-R.tmpout /*+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) \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-2-1 some complexity query blocks ---- -- No. R-2-1-1 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $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 (returns $3) -> 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $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 (returns $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: (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) -- No. R-2-1-2 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $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 (returns $3) -> 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 (returns $5) -> 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $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 (returns $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: (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 (returns $5) -> 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) -- No. R-2-1-3 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-1-4 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-1-5 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $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 (returns $3) -> 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 <> $1) AND (c1 <> $3)) -> 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $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 (returns $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: (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 <> $1) AND (c1 <> $3)) -> 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) -- No. R-2-1-6 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $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 (returns $3) -> 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 (returns $5) -> 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 <> $1) AND (c1 <> $3) AND (c1 <> $5)) -> 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Aggregate (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $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 (returns $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: (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 (returns $5) -> 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 <> $1) AND (c1 <> $3) AND (c1 <> $5)) -> 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) -- No. R-2-1-7 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-1-8 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-2-2 the number of the tables per quiry block ---- -- No. R-2-2-1 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $0) -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) InitPlan 2 (returns $1) -> 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 <> $1) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=1 width=xxx) InitPlan 1 (returns $0) -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) InitPlan 2 (returns $1) -> 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 <> $1) -> Index Only Scan using t1_i1 on t1 b1t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) -- No. R-2-2-2 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) InitPlan 1 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t1.c1) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt2.c1) InitPlan 1 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> Index Only Scan using t2_i1 on t2 bmt2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = b1t1.c1) -- No. R-2-2-3 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt4.c1) InitPlan 1 (returns $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 (returns $3) -> 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 <> $3) -> 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt4.c1) InitPlan 1 (returns $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 (returns $3) -> 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 <> $3) -> 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) -- No. R-2-2-4 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt4.c1) InitPlan 1 (returns $0) -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) InitPlan 2 (returns $1) -> 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 <> $1) -> 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- Nested Loop (cost=xxx..xxx rows=10 width=xxx) Join Filter: (bmt1.c1 = bmt4.c1) InitPlan 1 (returns $0) -> Index Only Scan using t1_i1 on t1 b2t1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) InitPlan 2 (returns $1) -> 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 <> $1) -> 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) ---- ---- No. R-2-3 RULE or VIEW ---- -- No. R-2-3-1 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-3-2 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-3-3 \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-3-4 \o results/ut-R.tmpout /*+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) \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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) \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-3-5 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-2-4 VALUES clause ---- -- No. R-2-4-1 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-4-2 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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) \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-2-5 ---- -- No. R-2-5-1 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-5-2 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-2-5-3 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+ 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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-3-1 abusolute value ---- -- No. R-3-1-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-1-2 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-3-2 increase or decrease value ---- -- No. R-3-2-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-2-2 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-2-3 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-3-3 multiple ---- -- No. R-3-3-1 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-3-2 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-3-3 \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-3-4 join inherit tables ---- -- No. R-3-4-1 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-4-2 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-3-5 conflict join method hint ---- -- No. R-3-5-1 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-5-2 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-5-3 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) -- No. R-3-5-4 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) ---- ---- No. R-3-6 hint state output ---- -- No. R-3-6-1 SET client_min_messages TO DEBUG1; \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \o results/ut-R.tmpout /*+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: \o \! sql/maskout.sh results/ut-R.tmpout QUERY PLAN ---------------- 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) \! rm results/ut-R.tmpout pg_hint_plan-REL16_1_6_0/expected/ut-S.out000066400000000000000000006215071447776766000204200ustar00rootroot00000000000000LOAD 'pg_hint_plan'; -- We cannot do ALTER USER current_user SET ... DELETE FROM pg_db_role_setting WHERE setrole = (SELECT oid FROM pg_roles WHERE rolname = current_user); INSERT INTO pg_db_role_setting (SELECT 0, (SELECT oid FROM pg_roles WHERE rolname = current_user), '{client_min_messages=log,pg_hint_plan.debug_print=on}'); ALTER SYSTEM SET session_preload_libraries TO 'pg_hint_plan'; SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row) 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 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Only Scan using t1_i1 on t1 t1_1 Index Cond: ((c1 IS NOT NULL) AND (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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Bitmap Heap Scan on t1 t1_1 Recheck Cond: ((c1 IS NOT NULL) AND (c1 = 1)) -> Bitmap Index Scan on t1_i1 Index Cond: ((c1 IS NOT NULL) AND (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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Bitmap Heap Scan on t1 t11 Recheck Cond: ((c1 IS NOT NULL) AND (c1 = 1)) -> Bitmap Index Scan on t1_i1 Index Cond: ((c1 IS NOT NULL) AND (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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Only Scan using t1_i1 on t1 t11 Index Cond: ((c1 IS NOT NULL) AND (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: ($0 = 1) InitPlan 1 (returns $0) -> Limit -> Index Only Scan using t1_i1 on t1 t1_1 Index Cond: ((c1 IS NOT NULL) AND (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: ($0 = 1) InitPlan 1 (returns $0) -> Limit -> Index Only Scan using t1_i1 on t1 t1_1 Index Cond: ((c1 IS NOT NULL) AND (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 (returns $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 (returns $2) -> 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 (returns $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 (returns $3) -> 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 (returns $2) -> 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 (returns $4) -> 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 (returns $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 <> $1) -> 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 (returns $2) -> 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 <> $2) -> 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 (returns $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 (returns $3) -> 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 <> $1) AND (c1 <> $3)) -> 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 (returns $2) -> 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 (returns $4) -> 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 <> $2) AND (c1 <> $4)) -> 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Tid Scan on t1 b3t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) -> Nested Loop -> Tid Scan on t1 bmt1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 <> $3) 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: ((c1 IS NOT NULL) AND (c1 = 1)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Index Scan using t1_pkey on t1 b3t1 Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) Filter: (ctid = '(1,1)'::tid) -> Nested Loop -> Seq Scan on t1 bmt1 Filter: ((c1 <> $3) 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 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> 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 (returns $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 (returns $3) -> 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 <> $3) 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 (returns $0) -> 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 (returns $1) -> 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 <> $1) -> 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 (returns $2) -> 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 (returns $5) -> 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 <> $5) 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Tid Scan on t1 b2t1 TID Cond: (ctid = '(1,1)'::tid) Filter: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 3 (returns $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 <> $3) -> 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Bitmap Heap Scan on t1 b2t1 Recheck Cond: ((c1 IS NOT NULL) AND (c1 = 1)) Filter: (ctid = '(1,1)'::tid) -> Bitmap Index Scan on t1_pkey Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Index Scan Backward using t1_pkey on t1 b3t1 Index Cond: (c1 IS NOT NULL) 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 <> $3) 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) (56 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 \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 100) -- No. S-3-5-2 \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 100) -- No. S-3-5-3 \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 100) -- No. S-3-5-4 \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 100) -- No. S-3-5-5 \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 100) -- No. S-3-5-6 \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 100) -- 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) \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- Seq Scan on t1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (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)'; 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Only Scan using t1_i1 on t1 b2t1 Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Index Only Scan using t1_i1 on t1 b4t1 Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) -> Index Only Scan using t1_i1 on t1 b3t1 Index Cond: (c1 = $3) (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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Scan using t1_pkey on t1 b2t1 Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Seq Scan on t1 b4t1 Filter: ((c1 IS NOT NULL) AND (c1 = 1)) -> Bitmap Heap Scan on t1 b3t1 Recheck Cond: (c1 = $3) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = $3) (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 (returns $0) -> 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 (returns $1) -> 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 = $1) -> Seq Scan on t2 b3t2 Filter: (c1 = $1) -> Aggregate Filter: (max(b1t1.c1) = $1) -> 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 (returns $0) -> 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 (returns $1) -> 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 = $1) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = $1) -> Index Scan using t2_pkey on t2 b3t2 Index Cond: (c1 = $1) -> Aggregate Filter: (max(b1t1.c1) = $1) -> 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Only Scan using t1_i1 on t1 b2t1 Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Index Only Scan using t1_i1 on t1 b4t1 Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) -> Nested Loop -> Nested Loop -> Index Only Scan using t1_i1 on t1 b3t1 Index Cond: (c1 = $3) -> Seq Scan on t2 b3t2 Filter: (c1 = $3) -> Aggregate Filter: (max(b1t1.c1) = $3) -> 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 (returns $1) -> Result InitPlan 1 (returns $0) -> Limit -> Index Scan using t1_pkey on t1 b2t1 Index Cond: ((c1 IS NOT NULL) AND (c1 = 1)) InitPlan 4 (returns $3) -> Result InitPlan 3 (returns $2) -> Limit -> Seq Scan on t1 b4t1 Filter: ((c1 IS NOT NULL) AND (c1 = 1)) -> Nested Loop -> Nested Loop -> Bitmap Heap Scan on t1 b3t1 Recheck Cond: (c1 = $3) -> Bitmap Index Scan on t1_pkey Index Cond: (c1 = $3) -> Index Scan using t2_pkey on t2 b3t2 Index Cond: (c1 = $3) -> Aggregate Filter: (max(b1t1.c1) = $3) -> 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 \o results/ut-S.tmpout EXPLAIN SELECT c4 FROM s1.p1 WHERE c2 * 2 < 100 AND c1 < 10; \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- 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)) \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- 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) -- No. S-3-10-4 \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- 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) -- No. S-3-10-5 \o results/ut-S.tmpout /*+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: \o \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- 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) ---- ---- 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) DELETE FROM pg_db_role_setting WHERE setrole = (SELECT oid FROM pg_roles WHERE rolname = current_user); ALTER SYSTEM SET session_preload_libraries TO DEFAULT; SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row) \! rm results/ut-S.tmpout pg_hint_plan-REL16_1_6_0/expected/ut-T.out000066400000000000000000000070011447776766000204040ustar00rootroot00000000000000-- 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; -- test for get_query_string INSERT INTO hint_plan.hints VALUES(DEFAULT,'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id = ?;', '', 'SeqScan(t1)'); INSERT INTO hint_plan.hints VALUES(DEFAULT,'PREPARE p1 AS SELECT * FROM t1 WHERE id = ?;', '', 'SeqScan(t1)'); INSERT INTO hint_plan.hints VALUES(DEFAULT,'EXPLAIN (COSTS false) DECLARE c1 CURSOR FOR SELECT * FROM t1 WHERE id = ?;', '', 'SeqScan(t1)'); INSERT INTO hint_plan.hints VALUES(DEFAULT,'EXPLAIN (COSTS false) CREATE TABLE ct1 AS SELECT * FROM t1 WHERE 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) DECLARE c1 CURSOR FOR SELECT * FROM t1 WHERE id = 100; QUERY PLAN -------------------------------- Index Scan using t1_pkey on t1 Index Cond: (id = 100) (2 rows) EXPLAIN (COSTS false) CREATE TABLE ct1 AS 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) DECLARE c1 CURSOR FOR 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) CREATE TABLE ct1 AS 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; -- Check proper calling to generate_normalized_query \;\;SELECT 1,2; ?column? | ?column? ----------+---------- 1 | 2 (1 row) SET pg_hint_plan.enable_hint_table to off; DELETE FROM hint_plan.hints; pg_hint_plan-REL16_1_6_0/expected/ut-W.out000066400000000000000000001264361447776766000204250ustar00rootroot00000000000000LOAD 'pg_hint_plan'; ALTER SYSTEM SET session_preload_libraries TO '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) -- 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 /*+Parallel(p1 5 hard) Parallel(s1 3 hard) IndexScan(ft1) SeqScan(cte1) TidScan(fs1) IndexScan(t) IndexScan(*VALUES*) */ \o results/ut-W.tmpout 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 userid FROM pg_stat_statements fs1 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) TidScan(fs1) IndexScan(ft1) IndexScan(t) Parallel(s1 3 hard) duplication hint: error hint: \o \! sql/maskout2.sh results/ut-W.tmpout --(snip..) --(snip..) Append -> Result -> Append -> Sample Scan on p1_c1_c1 s1 Sampling: system ('10'::real) -> Foreign Scan on ft1 Foreign File: (snip..) -> Gather Workers Planned: 5 -> 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) -> Function Scan on pg_stat_statements -> Subquery Scan on "*SELECT* 5" -> Values Scan on "*VALUES*" (31 rows) ALTER SYSTEM SET session_preload_libraries TO DEFAULT; SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row) pg_hint_plan-REL16_1_6_0/expected/ut-fdw.out000066400000000000000000000106451447776766000207710ustar00rootroot00000000000000-- 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 \o results/ut-fdw.tmpout 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; \o \! sql/maskout2.sh results/ut-fdw.tmpout 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 \o results/ut-fdw.tmpout /*+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: \o \! sql/maskout2.sh results/ut-fdw.tmpout; 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 \o results/ut-fdw.tmpout /*+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: \o \! sql/maskout2.sh results/ut-fdw.tmpout; 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 \o results/ut-fdw.tmpout /*+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: \o \! sql/maskout2.sh results/ut-fdw.tmpout; 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 \o results/ut-fdw.tmpout /*+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: \o \! sql/maskout.sh results/ut-fdw.tmpout | sql/maskout2.sh 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) \! rm results/ut-fdw.tmpout pg_hint_plan-REL16_1_6_0/expected/ut-fini.out000066400000000000000000000001561447776766000211320ustar00rootroot00000000000000DROP ROLE IF EXISTS regress_super_user; DROP ROLE IF EXISTS regress_normal_user; DROP EXTENSION pg_hint_plan; pg_hint_plan-REL16_1_6_0/expected/ut-init.out000066400000000000000000000301541447776766000211510ustar00rootroot00000000000000SET search_path TO public; CREATE EXTENSION pg_stat_statements; 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 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; 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-REL16_1_6_0/make_join_rel.c000066400000000000000000000311071447776766000201670ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * 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-2023, NIPPON TELEGRAPH AND TELEPHONE CORPORATION * Portions Copyright (c) 1996-2023, 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; sjinfo->type = T_SpecialJoinInfo; sjinfo->min_lefthand = rel1->relids; sjinfo->min_righthand = rel2->relids; sjinfo->syn_lefthand = rel1->relids; sjinfo->syn_righthand = rel2->relids; sjinfo->jointype = JOIN_INNER; sjinfo->ojrelid = 0; sjinfo->commute_above_l = NULL; sjinfo->commute_above_r = NULL; sjinfo->commute_below_l = NULL; sjinfo->commute_below_r = NULL; /* we don't bother trying to make the remaining fields valid */ sjinfo->lhs_strict = false; sjinfo->semi_can_btree = false; sjinfo->semi_can_hash = false; sjinfo->semi_operators = NIL; sjinfo->semi_rhs_exprs = NIL; } /* * 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-REL16_1_6_0/normalize_query.h000066400000000000000000000010111447776766000206120ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * normalize_query.h * Normalize query string. * * This header file is created from pg_stat_statements.c to implement * normalization of query string. * * Portions Copyright (c) 2008-2023, PostgreSQL Global Development Group */ #ifndef NORMALIZE_QUERY_H #define NORMALIZE_QUERY_H static char * generate_normalized_query(JumbleState *jstate, const char *query, int query_loc, int *query_len_p); #endif /* NORMALIZE_QUERY_H */ pg_hint_plan-REL16_1_6_0/pg_hint_plan--1.3.0--1.3.1.sql000066400000000000000000000006651447776766000216420ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.0.sql000066400000000000000000000012541447776766000211220ustar00rootroot00000000000000/* 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-REL16_1_6_0/pg_hint_plan--1.3.1--1.3.2.sql000066400000000000000000000006651447776766000216440ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.2--1.3.3.sql000066400000000000000000000006651447776766000216460ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.3--1.3.4.sql000066400000000000000000000006651447776766000216500ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.4--1.3.5.sql000066400000000000000000000006651447776766000216520ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.5--1.3.6.sql000066400000000000000000000006651447776766000216540ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.6--1.3.7.sql000066400000000000000000000006651447776766000216560ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.7--1.3.8.sql000066400000000000000000000006651447776766000216600ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.8--1.3.9.sql000066400000000000000000000006651447776766000216620ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.3.9--1.4.sql000066400000000000000000000006611447776766000215110ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.3.9--1.4.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.4--1.4.1.sql000066400000000000000000000006631447776766000215040ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.4.1--1.4.2.sql000066400000000000000000000006651447776766000216460ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.4.2--1.5.sql000066400000000000000000000006621447776766000215050ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.4.2--1.5.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION pg_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.5--1.5.1.sql000066400000000000000000000006641447776766000215070ustar00rootroot00000000000000/* 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_dbms_stats 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-REL16_1_6_0/pg_hint_plan--1.5.1--1.6.0.sql000066400000000000000000000006661447776766000216500ustar00rootroot00000000000000/* pg_hint_plan/pg_hint_plan--1.5.1--1.6.0.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION pg_dbms_stats 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-REL16_1_6_0/pg_hint_plan.c000066400000000000000000003726511447776766000200470ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * pg_hint_plan.c * hinting on how to execute a query for PostgreSQL * * Copyright (c) 2012-2023, NIPPON TELEGRAPH AND TELEPHONE CORPORATION * *------------------------------------------------------------------------- */ #include #include "postgres.h" #include "access/genam.h" #include "access/heapam.h" #include "access/relation.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" /* partially copied from pg_stat_statements */ #include "normalize_query.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); void _PG_fini(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_list, ListCell *other_rels); 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); 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 bool pg_hint_plan_hints_anywhere = 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); DefineCustomBoolVariable("pg_hint_plan.hints_anywhere", "Read hints from anywhere in a query.", "This option lets pg_hint_plan ignore syntax so be cautious for false reads.", &pg_hint_plan_hints_anywhere, false, PGC_USERSET, 0, NULL, NULL, 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; } /* * Module unload callback * XXX never called */ void _PG_fini(void) { PLpgSQL_plugin **var_ptr; /* Uninstall hooks. */ planner_hook = prev_planner; join_search_hook = prev_join_search; set_rel_pathlist_hook = prev_set_rel_pathlist; needs_fmgr_hook = prev_needs_fmgr_hook; fmgr_hook = prev_fmgr_hook; ExecutorEnd_hook = prev_ExecutorEnd; /* uninstall PL/pgSQL plugin hook */ var_ptr = (PLpgSQL_plugin **) find_rendezvous_variable("PLpgSQL_plugin"); *var_ptr = NULL; } 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 = palloc(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 = palloc(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 = palloc(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 = palloc(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 = palloc(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 = palloc(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 = palloc(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 = palloc(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 **) palloc(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 string and application name. */ static const char * get_hints_from_table(const char *client_query, const char *client_application) { const char *search_query = "SELECT hints " " FROM hint_plan.hints " " WHERE norm_query_string = $1 " " AND ( application_name = $2 " " OR application_name = '' ) " " ORDER BY application_name DESC"; static SPIPlanPtr plan = NULL; char *hints = NULL; Oid argtypes[2] = { TEXTOID, TEXTOID }; Datum values[2]; char nulls[2] = {' ', ' '}; text *qry; text *app; 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); } qry = cstring_to_text(client_query); app = cstring_to_text(client_application); values[0] = PointerGetDatum(qry); 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. */ static const char * get_hints_from_comment(const char *p) { const char *hint_head; char *head; char *tail; int len; if (p == NULL) return NULL; /* extract query head comment. */ hint_head = strstr(p, HINT_START); if (hint_head == NULL) return NULL; if (!pg_hint_plan_hints_anywhere) { for (;p < hint_head; p++) { /* * Allow these characters precedes hint comment: * - digits * - alphabets which are in ASCII range * - space, tabs and new-lines * - underscores, for identifier * - commas, for SELECT clause, EXPLAIN and PREPARE * - parentheses, for EXPLAIN and PREPARE * - squared brackets, for arrays (like arguments of PREPARE * statements). * * Note that we don't use isalpha() nor isalnum() in ctype.h here to * avoid behavior which depends on locale setting. */ if (!(*p >= '0' && *p <= '9') && !(*p >= 'A' && *p <= 'Z') && !(*p >= 'a' && *p <= 'z') && !isspace(*p) && *p != '_' && *p != ',' && *p != '(' && *p != ')' && *p != '[' && *p != ']') return NULL; } } head = (char *)hint_head; p = head + strlen(HINT_START); skip_space(p); /* find hint end keyword. */ if ((tail = strstr(p, HINT_END)) == NULL) { hint_ereport(head, ("Unterminated block comment.")); return NULL; } /* We don't support nested block comments. */ if ((head = strstr(p, BLOCK_COMMENT_START)) != NULL && head < tail) { hint_ereport(head, ("Nested block comments are not supported.")); return NULL; } /* Make a copy of hint. */ len = tail - p; head = palloc(len + 1); memcpy(head, p, len); head[len] = '\0'; p = head; return p; } /* * 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 = palloc(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 = palloc(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() { 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() { 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) { int query_len; char *normalized_query; 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; } if (!jstate) jstate = JumbleQuery(query); if (!jstate) return; /* * Normalize the query string by replacing constants with '?' */ /* * Search hint string which is stored keyed by query string * and application name. The query string is normalized to allow * fuzzy matching. * * Adding 1 byte to query_len ensures that the returned string has * a terminating NULL. */ query_len = strlen(query_str) + 1; normalized_query = generate_normalized_query(jstate, query_str, 0, &query_len); /* * find a hint for the normalized query. the result should be in * TopMemoryContext */ oldcontext = MemoryContextSwitchTo(TopMemoryContext); current_hint_str = get_hints_from_table(normalized_query, 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\": " "normalized_query=\"%s\", " "application name =\"%s\"", qno, current_hint_str, normalized_query, 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\", " "normalized_query=\"%s\"", qno, application_name, normalized_query), 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 */ oldcontext = MemoryContextSwitchTo(TopMemoryContext); current_hint_str = get_hints_from_comment(query_str); MemoryContextSwitchTo(oldcontext); 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 = palloc(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 *) palloc(sizeof(Oid) * index->indnatts); p_info->opclass = (Oid *) palloc(sizeof(Oid) * index->indnatts); p_info->indoption = (int16 *) palloc(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() { 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; AppendPath *apath = (AppendPath *) lfirst(lc); int parallel_workers = 0; if (!IsA(apath, AppendPath)) continue; 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" #include "pg_stat_statements.c" pg_hint_plan-REL16_1_6_0/pg_hint_plan.control000066400000000000000000000001501447776766000212630ustar00rootroot00000000000000# pg_hint_plan extension comment = '' default_version = '1.6.0' relocatable = false schema = hint_plan pg_hint_plan-REL16_1_6_0/pg_stat_statements.c000066400000000000000000000202251447776766000213000ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * pg_stat_statements.c * * Part of pg_stat_statements.c in PostgreSQL 10. * * Copyright (c) 2008-2023, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ #include "postgres.h" #include "parser/scanner.h" static char *generate_normalized_query(JumbleState *jstate, const char *query, int query_loc, int *query_len_p); static void fill_in_constant_lengths(JumbleState *jstate, const char *query, int query_loc); static int comp_location(const void *a, const void *b); /* * Generate a normalized version of the query string that will be used to * represent all similar queries. * * Note that the normalized representation may well vary depending on * just which "equivalent" query is used to create the hashtable entry. * We assume this is OK. * * If query_loc > 0, then "query" has been advanced by that much compared to * the original string start, so we need to translate the provided locations * to compensate. (This lets us avoid re-scanning statements before the one * of interest, so it's worth doing.) * * *query_len_p contains the input string length, and is updated with * the result string length on exit. The resulting string might be longer * or shorter depending on what happens with replacement of constants. * * Returns a palloc'd string. */ static char * generate_normalized_query(JumbleState *jstate, const char *query, int query_loc, int *query_len_p) { char *norm_query; int query_len = *query_len_p; int i, norm_query_buflen, /* Space allowed for norm_query */ len_to_wrt, /* Length (in bytes) to write */ quer_loc = 0, /* Source query byte location */ n_quer_loc = 0, /* Normalized query byte location */ last_off = 0, /* Offset from start for previous tok */ last_tok_len = 0; /* Length (in bytes) of that tok */ /* * Get constants' lengths (core system only gives us locations). Note * this also ensures the items are sorted by location. */ fill_in_constant_lengths(jstate, query, query_loc); /* * Allow for $n symbols to be longer than the constants they replace. * Constants must take at least one byte in text form, while a $n symbol * certainly isn't more than 11 bytes, even if n reaches INT_MAX. We * could refine that limit based on the max value of n for the current * query, but it hardly seems worth any extra effort to do so. */ norm_query_buflen = query_len + jstate->clocations_count * 10; /* Allocate result buffer */ norm_query = palloc(norm_query_buflen + 1); for (i = 0; i < jstate->clocations_count; i++) { int off, /* Offset from start for cur tok */ tok_len; /* Length (in bytes) of that tok */ off = jstate->clocations[i].location; /* Adjust recorded location if we're dealing with partial string */ off -= query_loc; tok_len = jstate->clocations[i].length; if (tok_len < 0) continue; /* ignore any duplicates */ /* Copy next chunk (what precedes the next constant) */ len_to_wrt = off - last_off; len_to_wrt -= last_tok_len; Assert(len_to_wrt >= 0); memcpy(norm_query + n_quer_loc, query + quer_loc, len_to_wrt); n_quer_loc += len_to_wrt; /* And insert a param symbol in place of the constant token */ /* !!! START: HERE IS THE PART WHICH IS MODIFIED FOR PG_HINT_PLAN !!! */ n_quer_loc += sprintf(norm_query + n_quer_loc, "?"); /* !!! END: HERE IS THE PART WHICH IS MODIFIED FOR PG_HINT_PLAN !!! */ quer_loc = off + tok_len; last_off = off; last_tok_len = tok_len; } /* * We've copied up until the last ignorable constant. Copy over the * remaining bytes of the original query string. */ len_to_wrt = query_len - quer_loc; Assert(len_to_wrt >= 0); memcpy(norm_query + n_quer_loc, query + quer_loc, len_to_wrt); n_quer_loc += len_to_wrt; Assert(n_quer_loc <= norm_query_buflen); norm_query[n_quer_loc] = '\0'; *query_len_p = n_quer_loc; return norm_query; } /* * Given a valid SQL string and an array of constant-location records, * fill in the textual lengths of those constants. * * The constants may use any allowed constant syntax, such as float literals, * bit-strings, single-quoted strings and dollar-quoted strings. This is * accomplished by using the public API for the core scanner. * * It is the caller's job to ensure that the string is a valid SQL statement * with constants at the indicated locations. Since in practice the string * has already been parsed, and the locations that the caller provides will * have originated from within the authoritative parser, this should not be * a problem. * * Duplicate constant pointers are possible, and will have their lengths * marked as '-1', so that they are later ignored. (Actually, we assume the * lengths were initialized as -1 to start with, and don't change them here.) * * If query_loc > 0, then "query" has been advanced by that much compared to * the original string start, so we need to translate the provided locations * to compensate. (This lets us avoid re-scanning statements before the one * of interest, so it's worth doing.) * * N.B. There is an assumption that a '-' character at a Const location begins * a negative numeric constant. This precludes there ever being another * reason for a constant to start with a '-'. */ static void fill_in_constant_lengths(JumbleState *jstate, const char *query, int query_loc) { LocationLen *locs; core_yyscan_t yyscanner; core_yy_extra_type yyextra; core_YYSTYPE yylval; YYLTYPE yylloc; int last_loc = -1; int i; /* * Sort the records by location so that we can process them in order while * scanning the query text. */ if (jstate->clocations_count > 1) qsort(jstate->clocations, jstate->clocations_count, sizeof(LocationLen), comp_location); locs = jstate->clocations; /* initialize the flex scanner --- should match raw_parser() */ yyscanner = scanner_init(query, &yyextra, &ScanKeywords, ScanKeywordTokens); /* we don't want to re-emit any escape string warnings */ yyextra.escape_string_warning = false; /* Search for each constant, in sequence */ for (i = 0; i < jstate->clocations_count; i++) { int loc = locs[i].location; int tok; /* Adjust recorded location if we're dealing with partial string */ loc -= query_loc; Assert(loc >= 0); if (loc <= last_loc) continue; /* Duplicate constant, ignore */ /* Lex tokens until we find the desired constant */ for (;;) { tok = core_yylex(&yylval, &yylloc, yyscanner); /* We should not hit end-of-string, but if we do, behave sanely */ if (tok == 0) break; /* out of inner for-loop */ /* * We should find the token position exactly, but if we somehow * run past it, work with that. */ if (yylloc >= loc) { if (query[loc] == '-') { /* * It's a negative value - this is the one and only case * where we replace more than a single token. * * Do not compensate for the core system's special-case * adjustment of location to that of the leading '-' * operator in the event of a negative constant. It is * also useful for our purposes to start from the minus * symbol. In this way, queries like "select * from foo * where bar = 1" and "select * from foo where bar = -2" * will have identical normalized query strings. */ tok = core_yylex(&yylval, &yylloc, yyscanner); if (tok == 0) break; /* out of inner for-loop */ } /* * We now rely on the assumption that flex has placed a zero * byte after the text of the current token in scanbuf. */ locs[i].length = strlen(yyextra.scanbuf + loc); break; /* out of inner for-loop */ } } /* If we hit end-of-string, give up, leaving remaining lengths -1 */ if (tok == 0) break; last_loc = loc; } scanner_finish(yyscanner); } /* * comp_location: comparator for qsorting LocationLen structs by location */ static int comp_location(const void *a, const void *b) { int l = ((const LocationLen *) a)->location; int r = ((const LocationLen *) b)->location; if (l < r) return -1; else if (l > r) return +1; else return 0; } pg_hint_plan-REL16_1_6_0/sql/000077500000000000000000000000001447776766000160225ustar00rootroot00000000000000pg_hint_plan-REL16_1_6_0/sql/base_plan.sql000066400000000000000000000011241447776766000204650ustar00rootroot00000000000000SET 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-REL16_1_6_0/sql/hints_anywhere.sql000066400000000000000000000014221447776766000215710ustar00rootroot00000000000000LOAD 'pg_hint_plan'; SET client_min_messages TO log; \set SHOW_CONTEXT always SET pg_hint_plan.debug_print TO on; explain (costs false) select * from t1 join t2 on t1.id = t2.id where '/*+HashJoin(t1 t2)*/' <> ''; set pg_hint_plan.hints_anywhere = on; explain (costs false) select * from t1 join t2 on t1.id = t2.id where '/*+HashJoin(t1 t2)*/' <> ''; set pg_hint_plan.hints_anywhere = off; explain (costs false) select * from t1 join t2 on t1.id = t2.id where '/*+HashJoin(t1 t2)*/' <> ''; set pg_hint_plan.hints_anywhere = on; /*+ MergeJoin(t1 t2) */ explain (costs false) select * from t1 join t2 on t1.val = t2.val where '/*+HashJoin(t1 t2)*/' <> ''; /*+ HashJoin(t1 t2) */ explain (costs false) select * from t1 join t2 on t1.val = t2.val where '/*+MergeJoin(t1 t2)*/' <> ''; pg_hint_plan-REL16_1_6_0/sql/init.sql000066400000000000000000000144531447776766000175150ustar00rootroot00000000000000SET 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; /* * The following GUC parameters need the setting of the default value to * succeed in regression test. */ /* Fix auto-tunable parameters */ ALTER SYSTEM SET effective_cache_size TO 16384; SELECT pg_reload_conf(); 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; ANALYZE; pg_hint_plan-REL16_1_6_0/sql/maskout.sh000077500000000000000000000004501447776766000200430ustar00rootroot00000000000000#! /bin/sh cat $1 | \ sed 's/cost=10\{7\}[\.0-9]\+ /cost={inf}..{inf} /;s/cost=[\.0-9]\+ /cost=xxx..xxx /;s/width=[0-9]\+\([^0-9]\)/width=xxx\1/' |\ egrep -v "^ *((Planning time|JIT|Functions|Options):|\([0-9]* rows\))" |\ sed -e 's/^ *QUERY PLAN *$/ QUERY PLAN/' -e 's/^--*$/----------------/' pg_hint_plan-REL16_1_6_0/sql/maskout2.sh000077500000000000000000000001701447776766000201240ustar00rootroot00000000000000#! /bin/sh cat $1 | \ sed 's/^ *QUERY PLAN *$/--(snip..)/;s/^-\+$/--(snip..)/;s/^\( \+Foreign File: \).*$/\1 (snip..)/' pg_hint_plan-REL16_1_6_0/sql/oldextversions.sql000066400000000000000000000021321447776766000216310ustar00rootroot00000000000000-- -- 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.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.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.6.0"; \dx+ pg_hint_plan DROP EXTENSION pg_hint_plan; pg_hint_plan-REL16_1_6_0/sql/pg_hint_plan.sql000066400000000000000000001652171447776766000212210ustar00rootroot00000000000000SET 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 warining SELECT 1; -- not SET compute_query_id to on; SELECT 1; -- reactivated SET compute_query_id to off; SELECT 1; -- gets warining 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 warining 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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ('EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;', '', 'SeqScan(t1)'); INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ('EXPLAIN (COSTS false) SELECT id FROM t1 WHERE t1.id = ?;', '', 'IndexScan(t1)'); INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ('EXPLAIN SELECT * FROM t1 WHERE t1.id = ?;', '', 'BitmapScan(t1)'); SELECT * FROM hint_plan.hints ORDER BY id; 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 \o results/pg_hint_plan.tmpout EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 #99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 +99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 -99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 *99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 *0.01) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 #aa) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); -- ERROR \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 /99) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); -- ERROR \o \! sql/maskout.sh results/pg_hint_plan.tmpout -- round up to 1 \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 -99999) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout -- complex join tree \o results/pg_hint_plan.tmpout EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t2 #22) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); \o \! sql/maskout.sh results/pg_hint_plan.tmpout \o results/pg_hint_plan.tmpout /*+ Rows(t1 t3 *10) */ EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id) JOIN t3 ON (t3.id = t2.id); \o set max_parallel_workers_per_gather to DEFAULT; \! sql/maskout.sh results/pg_hint_plan.tmpout \! rm results/pg_hint_plan.tmpout -- 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-REL16_1_6_0/sql/plpgsql.sql000066400000000000000000000107561447776766000202360ustar00rootroot00000000000000-- -- 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; SELECT setting <> 'off' FROM pg_settings WHERE name = 'compute_query_id'; 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-REL16_1_6_0/sql/ut-A.sql000066400000000000000000001054521447776766000173600ustar00rootroot00000000000000LOAD '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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', '', 'SeqScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; -- No. A-6-2-2 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', 'psql', 'BitmapScan(t1)'); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; TRUNCATE hint_plan.hints; -- No. A-6-2-3 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', 'dummy_application_name', 'SeqScan(t1)' ); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; TRUNCATE hint_plan.hints; -- No. A-6-2-4 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1;', '', '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 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT c1 FROM s1.t1;', '', 'SeqScan(t1)' ); EXPLAIN (COSTS false) SELECT c1 FROM s1.t1; TRUNCATE hint_plan.hints; -- No. A-6-3-2 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', '', 'SeqScan(t1)' ); EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; TRUNCATE hint_plan.hints; -- No. A-6-3-3 INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ? OR t1.c1 = ?;', '', '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 ---- INSERT INTO hint_plan.hints (norm_query_string, application_name, hints) VALUES ( 'EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = ?;', '', '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 pg_stat_statements_reset(); 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; SELECT s.query, s.calls FROM public.pg_stat_statements s JOIN pg_catalog.pg_database d ON (s.dbid = d.oid) ORDER BY 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-REL16_1_6_0/sql/ut-G.sql000066400000000000000000000067331447776766000173700ustar00rootroot00000000000000LOAD '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)'; RESET client_min_messages; ---- ---- 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-REL16_1_6_0/sql/ut-J.sql000066400000000000000000001114331447776766000173650ustar00rootroot00000000000000LOAD '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 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); \o results/ut-J.tmpout /*+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); \o \! sql/maskout.sh results/ut-J.tmpout -- -- 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); \o results/ut-J.tmpout /*+NestLoop(t1 t2)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1 FULL OUTER JOIN s1.t2 ON (t1.c1 = t2.c1); \o \! sql/maskout.sh results/ut-J.tmpout \! rm results/ut-J.tmpout -- 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-REL16_1_6_0/sql/ut-L.sql000066400000000000000000001057701447776766000173760ustar00rootroot00000000000000LOAD '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-REL16_1_6_0/sql/ut-R.sql000066400000000000000000001224551447776766000174030ustar00rootroot00000000000000LOAD '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; \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-1-1 specified pattern of the object name ---- -- No. R-1-1-1 \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-1-2 \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-1-3 \o results/ut-R.tmpout /*+Rows(t_1 t_2 #1)*/ EXPLAIN SELECT * FROM s1.t1 t_1, s1.t2 t_2 WHERE t_1.c1 = t_2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-1-2 specified schema name in the hint option ---- -- No. R-1-2-1 \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-2-2 \o results/ut-R.tmpout /*+Rows(s1.t1 s1.t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-1-3 table doesn't exist in the hint option ---- -- No. R-1-3-1 \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-3-2 \o results/ut-R.tmpout /*+Rows(t3 t4 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-1-4 conflict table name ---- -- No. R-1-4-1 \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-4-2 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(s1.t1 s2.t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 WHERE s1.t1.c1 = s2.t1.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 s2t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s2.t1 s2t1 WHERE s1.t1.c1 = s2t1.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-4-3 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+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; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-1-5 conflict table name ---- -- No. R-1-5-1 \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-5-2 \o results/ut-R.tmpout /*+Rows(t1 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-5-3 \o results/ut-R.tmpout /*+(t1 t1)(t2 t2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2, s1.t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+(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; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-1-6 object type for the hint ---- -- No. R-1-6-1 \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-2 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.p1 t1, s1.p1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-3 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.ul1 t1, s1.ul1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-4 CREATE TEMP TABLE tm1 (LIKE s1.t1 INCLUDING ALL); \o results/ut-R.tmpout EXPLAIN SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM tm1 t1, tm1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-5 CREATE TEMP TABLE t_pg_class AS SELECT * from pg_class LIMIT 100; \o results/ut-R.tmpout EXPLAIN SELECT * FROM t_pg_class t1, t_pg_class t2 WHERE t1.oid = t2.oid; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM t_pg_class t1, t_pg_class t2 WHERE t1.oid = t2.oid; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-6 -- refer ut-fdw.sql -- No. R-1-6-7 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.f1() t1, s1.f1() t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-8 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-9 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-10 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.v1 t1, s1.v1 t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(v1t1 v1t1_ #1)*/ EXPLAIN SELECT * FROM s1.v1 t1, s1.v1_ t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-6-11 \o results/ut-R.tmpout 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); \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+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); \o \! sql/maskout.sh results/ut-R.tmpout -- -- There are cases where difference in the measured value and predicted value -- depending upon the version of PostgreSQL -- \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 st2 #1)*/ EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, (SELECT t2.c1 FROM s1.t2) st2 WHERE t1.c1 = st2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-1-7 specified number of conditions ---- -- No. R-1-7-1 \o results/ut-R.tmpout /*+Rows(t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-7-2 \o results/ut-R.tmpout /*+Rows(t1 t2 1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-1-7-3 \o results/ut-R.tmpout /*+Rows(t1 t2 #notrows)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-2-1 some complexity query blocks ---- -- No. R-2-1-1 \o results/ut-R.tmpout /*+ 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 ; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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 ; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-1-2 \o results/ut-R.tmpout /*+ 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 ; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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 ; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-1-3 \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-1-4 \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-1-5 \o results/ut-R.tmpout /*+ 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 ); \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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 ) ; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-1-6 \o results/ut-R.tmpout /*+ 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 ) ; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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 ) ; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-1-7 \o results/ut-R.tmpout /*+ 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 ; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-1-8 \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-2-2 the number of the tables per quiry block ---- -- No. R-2-2-1 \o results/ut-R.tmpout /*+ 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 ); \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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 ); \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-2-2 \o results/ut-R.tmpout /*+ 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 ); \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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 ) ; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-2-3 \o results/ut-R.tmpout /*+ 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 ); \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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 ); \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-2-4 \o results/ut-R.tmpout /*+ 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 ); \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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 ); \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-2-3 RULE or VIEW ---- -- No. R-2-3-1 \o results/ut-R.tmpout /*+ Leading(r1 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r1 SET c1 = c1 WHERE c1 = 1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ Leading(r1_ b1t1 b1t2 b1t3 b1t4) */ EXPLAIN UPDATE s1.r1_ SET c1 = c1 WHERE c1 = 1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-3-2 \o results/ut-R.tmpout /*+ Leading(r2 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r2 SET c1 = c1 WHERE c1 = 1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ Leading(r2_ b1t1 b1t2 b1t3 b1t4) Leading(r2_ b2t1 b2t2 b2t3 b2t4) */ EXPLAIN UPDATE s1.r2_ SET c1 = c1 WHERE c1 = 1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-3-3 \o results/ut-R.tmpout /*+ Leading(r3 t1 t2 t3 t4) */ EXPLAIN UPDATE s1.r3 SET c1 = c1 WHERE c1 = 1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-3-4 \o results/ut-R.tmpout /*+HashJoin(v1t1 v1t1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+HashJoin(v1t1 v1t1)Rows(v1t1 v1t1 #1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1 v2 WHERE v1.c1 = v2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-3-5 \o results/ut-R.tmpout /*+NestLoop(v1t1 v1t1_)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+NestLoop(v1t1 v1t1_)Rows(v1t1 v1t1_ #1)*/ EXPLAIN SELECT * FROM s1.v1 v1, s1.v1_ v2 WHERE v1.c1 = v2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-2-4 VALUES clause ---- -- No. R-2-4-1 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-4-2 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-2-5 ---- -- No. R-2-5-1 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-5-2 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-2-5-3 \o results/ut-R.tmpout 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; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+ 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; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-3-1 abusolute value ---- -- No. R-3-1-1 \o results/ut-R.tmpout /*+Rows(t1 t2 #0)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-1-2 \o results/ut-R.tmpout /*+Rows(t1 t2 #5)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-3-2 increase or decrease value ---- -- No. R-3-2-1 \o results/ut-R.tmpout /*+Rows(t1 t2 +1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-2-2 \o results/ut-R.tmpout /*+Rows(t1 t2 -1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-2-3 \o results/ut-R.tmpout /*+Rows(t1 t2 -1000)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-3-3 multiple ---- -- No. R-3-3-1 \o results/ut-R.tmpout /*+Rows(t1 t2 *0)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-3-2 \o results/ut-R.tmpout /*+Rows(t1 t2 *2)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-3-3 \o results/ut-R.tmpout /*+Rows(t1 t2 *0.1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-3-4 join inherit tables ---- -- No. R-3-4-1 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(p1 p2 #1)*/ EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-4-2 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(p1c1 p2c1 #1)*/ EXPLAIN SELECT * FROM s1.p1, s1.p2 WHERE p1.c1 = p2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-3-5 conflict join method hint ---- -- No. R-3-5-1 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-5-2 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)Rows(t1 t2 #1)Rows(t1 t2 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-5-3 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 #1)Rows(t2 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout -- No. R-3-5-4 \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t2 t1 #1)Rows(t1 t2 #1)Rows(t2 t1 #1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout ---- ---- No. R-3-6 hint state output ---- -- No. R-3-6-1 SET client_min_messages TO DEBUG1; \o results/ut-R.tmpout EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \o results/ut-R.tmpout /*+Rows(t1 t2 +1)*/ EXPLAIN SELECT * FROM s1.t1, s1.t2 WHERE t1.c1 = t2.c1; \o \! sql/maskout.sh results/ut-R.tmpout \! rm results/ut-R.tmpout pg_hint_plan-REL16_1_6_0/sql/ut-S.sql000066400000000000000000001317261447776766000174050ustar00rootroot00000000000000LOAD 'pg_hint_plan'; -- We cannot do ALTER USER current_user SET ... DELETE FROM pg_db_role_setting WHERE setrole = (SELECT oid FROM pg_roles WHERE rolname = current_user); INSERT INTO pg_db_role_setting (SELECT 0, (SELECT oid FROM pg_roles WHERE rolname = current_user), '{client_min_messages=log,pg_hint_plan.debug_print=on}'); ALTER SYSTEM SET session_preload_libraries TO 'pg_hint_plan'; SELECT pg_reload_conf(); 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 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 \o results/ut-S.tmpout /*+IndexScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; \o \! sql/maskout.sh results/ut-S.tmpout -- No. S-3-5-2 \o results/ut-S.tmpout /*+BitmapScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; \o \! sql/maskout.sh results/ut-S.tmpout -- No. S-3-5-3 \o results/ut-S.tmpout /*+IndexOnlyScan(ti1 ti1_pred)*/ EXPLAIN (COSTS true) SELECT c1 FROM s1.ti1 WHERE c1 = 100; \o \! sql/maskout.sh results/ut-S.tmpout -- No. S-3-5-4 \o results/ut-S.tmpout /*+IndexScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; \o \! sql/maskout.sh results/ut-S.tmpout -- No. S-3-5-5 \o results/ut-S.tmpout /*+BitmapScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT * FROM s1.ti1 WHERE c1 = 100; \o \! sql/maskout.sh results/ut-S.tmpout -- No. S-3-5-6 \o results/ut-S.tmpout /*+IndexOnlyScan(ti1 not_exist)*/ EXPLAIN (COSTS true) SELECT c1 FROM s1.ti1 WHERE c1 = 100; \o \! sql/maskout.sh results/ut-S.tmpout -- No. S-3-5-7 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; \o results/ut-S.tmpout /*+TidScan(t1)*/ EXPLAIN (COSTS true) SELECT * FROM s1.t1 WHERE t1.c1 = 1; \o \! sql/maskout.sh results/ut-S.tmpout ---- ---- 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 \o results/ut-S.tmpout EXPLAIN SELECT c4 FROM s1.p1 WHERE c2 * 2 < 100 AND c1 < 10; \o \! sql/maskout.sh results/ut-S.tmpout \o results/ut-S.tmpout /*+IndexScan(p1 p1_parent)*/ EXPLAIN SELECT c4 FROM s1.p1 WHERE c2 * 2 < 100 AND c1 < 10; \o \! sql/maskout.sh results/ut-S.tmpout -- No. S-3-10-4 \o results/ut-S.tmpout /*+IndexScan(p1 p1_i2)*/ EXPLAIN SELECT c2 FROM s1.p1 WHERE c2 = 1; \o \! sql/maskout.sh results/ut-S.tmpout -- No. S-3-10-5 \o results/ut-S.tmpout /*+IndexScan(p2 p2c1_pkey)*/ EXPLAIN (COSTS true) SELECT * FROM s1.p2 WHERE c1 = 1; \o \! sql/maskout.sh results/ut-S.tmpout ---- ---- 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; DELETE FROM pg_db_role_setting WHERE setrole = (SELECT oid FROM pg_roles WHERE rolname = current_user); ALTER SYSTEM SET session_preload_libraries TO DEFAULT; SELECT pg_reload_conf(); \! rm results/ut-S.tmpout pg_hint_plan-REL16_1_6_0/sql/ut-T.sql000066400000000000000000000036201447776766000173750ustar00rootroot00000000000000-- 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; -- test for get_query_string INSERT INTO hint_plan.hints VALUES(DEFAULT,'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id = ?;', '', 'SeqScan(t1)'); INSERT INTO hint_plan.hints VALUES(DEFAULT,'PREPARE p1 AS SELECT * FROM t1 WHERE id = ?;', '', 'SeqScan(t1)'); INSERT INTO hint_plan.hints VALUES(DEFAULT,'EXPLAIN (COSTS false) DECLARE c1 CURSOR FOR SELECT * FROM t1 WHERE id = ?;', '', 'SeqScan(t1)'); INSERT INTO hint_plan.hints VALUES(DEFAULT,'EXPLAIN (COSTS false) CREATE TABLE ct1 AS SELECT * FROM t1 WHERE 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) DECLARE c1 CURSOR FOR SELECT * FROM t1 WHERE id = 100; EXPLAIN (COSTS false) CREATE TABLE ct1 AS 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) DECLARE c1 CURSOR FOR SELECT * FROM t1 WHERE id = 100; EXPLAIN (COSTS false) CREATE TABLE ct1 AS 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; -- Check proper calling to generate_normalized_query \;\;SELECT 1,2; SET pg_hint_plan.enable_hint_table to off; DELETE FROM hint_plan.hints; pg_hint_plan-REL16_1_6_0/sql/ut-W.sql000066400000000000000000000170221447776766000174010ustar00rootroot00000000000000LOAD 'pg_hint_plan'; ALTER SYSTEM SET session_preload_libraries TO '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; -- 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 /*+Parallel(p1 5 hard) Parallel(s1 3 hard) IndexScan(ft1) SeqScan(cte1) TidScan(fs1) IndexScan(t) IndexScan(*VALUES*) */ \o results/ut-W.tmpout 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 userid FROM pg_stat_statements fs1 UNION ALL SELECT x FROM (VALUES (1), (2), (3)) t(x); \o \! sql/maskout2.sh results/ut-W.tmpout ALTER SYSTEM SET session_preload_libraries TO DEFAULT; SELECT pg_reload_conf(); pg_hint_plan-REL16_1_6_0/sql/ut-fdw.sql000066400000000000000000000036061447776766000177560ustar00rootroot00000000000000-- 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 \o results/ut-fdw.tmpout 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; \o \! sql/maskout2.sh results/ut-fdw.tmpout ---- ---- No. S-1-5 object type for the hint ---- -- No. S-1-5-6 \o results/ut-fdw.tmpout /*+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; \o \! sql/maskout2.sh results/ut-fdw.tmpout; ---- ---- No. J-1-6 object type for the hint ---- -- No. J-1-6-6 \o results/ut-fdw.tmpout /*+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; \o \! sql/maskout2.sh results/ut-fdw.tmpout; ---- ---- No. L-1-6 object type for the hint ---- -- No. L-1-6-6 \o results/ut-fdw.tmpout /*+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; \o \! sql/maskout2.sh results/ut-fdw.tmpout; ---- ---- No. R-1-6 object type for the hint ---- -- No. R-1-6-6 \o results/ut-fdw.tmpout /*+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; \o \! sql/maskout.sh results/ut-fdw.tmpout | sql/maskout2.sh \! rm results/ut-fdw.tmpout pg_hint_plan-REL16_1_6_0/sql/ut-fini.sql000066400000000000000000000001561447776766000201200ustar00rootroot00000000000000DROP ROLE IF EXISTS regress_super_user; DROP ROLE IF EXISTS regress_normal_user; DROP EXTENSION pg_hint_plan; pg_hint_plan-REL16_1_6_0/sql/ut-init.sql000066400000000000000000000222031447776766000201330ustar00rootroot00000000000000SET search_path TO public; CREATE EXTENSION pg_stat_statements; 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 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; 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-REL16_1_6_0/update_copied_funcs.pl000077500000000000000000000216131447776766000215710ustar00rootroot00000000000000#! /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'], 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-2023, 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-2023, NIPPON TELEGRAPH AND TELEPHONE CORPORATION * Portions Copyright (c) 1996-2023, 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 }