path toward faster partition pruning

Started by Amit Langoteover 8 years ago403 messageshackers
Jump to latest
#1Amit Langote
Langote_Amit_f8@lab.ntt.co.jp

I've been working on implementing a way to perform plan-time
partition-pruning that is hopefully faster than the current method of
using constraint exclusion to prune each of the potentially many
partitions one-by-one. It's not fully cooked yet though.

Meanwhile, I thought I'd share a couple of patches that implement some
restructuring of the planner code related to partitioned table inheritance
planning that I think would be helpful. They are to be applied on top of
the patches being discussed at [1]/messages/by-id/befd7ec9-8f4c-6928-d330-ab05dbf860bf@lab.ntt.co.jp. Note that these patches themselves
don't implement the actual code that replaces constraint exclusion as a
method of performing partition pruning. I will share that patch after
debugging it some more.

The main design goal of the patches I'm sharing here now is to defer the
locking and opening of leaf partitions in a given partition tree to a
point after set_append_rel_size() is called on the root partitioned table.
Currently, AFAICS, we need to lock and open the child tables in
expand_inherited_rtentry() only to set the translated_vars field in
AppendRelInfo that we create for the child. ISTM, we can defer the
creation of a child AppendRelInfo to a point when it (its field
translated_vars in particular) will actually be used and so lock and open
the child tables only at such a time. Although we don't lock and open the
partition child tables in expand_inherited_rtentry(), their RT entries are
still created and added to root->parse->rtable, so that
setup_simple_rel_arrays() knows the maximum number of entries
root->simple_rel_array will need to hold and allocate the memory for that
array accordingly. Slots in simple_rel_array[] corresponding to
partition child tables will be empty until they are created when
set_append_rel_size() is called on the root parent table and it determines
the partitions that will be scanned after all.

Patch augments the existing PartitionedChildRelInfo node, which currently
holds only the partitioned child rel RT indexes, to carry some more
information about the partition tree, which includes the information
returned by RelationGetPartitionDispatchInfo() when it is called from
expand_inherited_rtentry() (per the proposed patch in [1]/messages/by-id/befd7ec9-8f4c-6928-d330-ab05dbf860bf@lab.ntt.co.jp, we call it to
be able to add partitions to the query tree in the bound order).
Actually, since PartitionedChildRelInfo now contains more information
about the partition tree than it used to before, I thought the struct's
name is no longer relevant, so renamed it to PartitionRootInfo and renamed
root->pcinfo_list accordingly to prinfo_list. That seems okay because we
only use that node internally.

Then during the add_base_rels_to_query() step, when build_simple_rel()
builds a RelOptInfo for the root partitioned table, it also initializes
some newly introduced fields in RelOptInfo from the information contained
in PartitionRootInfo of the table. The aforementioned fields are only
initialized in RelOptInfos of root partitioned tables. Note that the
add_base_rels_to_query() step won't add the partition "otherrel"
RelOptInfos yet (unlike the regular inheritance case, where they are,
after looking them up in root->append_rel_list).

When set_append_rel_size() is called on the root partitioned table, it
will call a find_partitions_for_query(), which using the partition tree
information, determines the partitions that will need to be scanned for
the query. This processing happens recursively, that is, we first
determine the root-parent's partitions and then for each partition that's
partitioned, we will determine its partitions and so on. As we determine
partitions in this per-partitioned-table manner, we maintain a pair
(parent_relid, list-of-partition-relids-to-scan) for each partitioned
table and also a single list of all leaf partitions determined so far.
Once all partitions have been determined, we turn to locking the leaf
partitions. The locking happens in the order of OIDs as
find_all_inheritors would have returned in expand_inherited_rtentry(); the
list of OIDs in that original order is also stored in the table's
PartitionRootInfo node. For each OID in that list, check if that OID is
in the set of leaf partition OIDs that was just computed, and if so, lock
it. For all chosen partitions that are partitioned tables (including the
root), we create a PartitionAppendInfo node which stores the
aforementioned pair (parent_relid, list-of-partitions-relids-to-scan), and
append it to a list in the root table's RelOptInfo, with the root table's
PartitionAppendInfo at the head of the list. Note that the list of
partitions in this pair contains only the immediate partitions, so that
the original parent-child relationship is reflected in the list of
PartitionAppendInfos thus collected. The next patch that will implement
actual partition-pruning will add some more code that will run under
find_partitions_for_query().

set_append_rel_size() processing then continues for the root partitioned
table. It is at this point that we will create the RelOptInfos and
AppendRelInfos for partitions. First for those of the root partitioned
table and then for those of each partitioned table when
set_append_rel_size() will be recursively called for the latter.

Note that this is still largely a WIP patch and the implementation details
might change per both the feedback here and the discussion at [1]/messages/by-id/befd7ec9-8f4c-6928-d330-ab05dbf860bf@lab.ntt.co.jp.

Thanks,
Amit

[1]: /messages/by-id/befd7ec9-8f4c-6928-d330-ab05dbf860bf@lab.ntt.co.jp
/messages/by-id/befd7ec9-8f4c-6928-d330-ab05dbf860bf@lab.ntt.co.jp

Attachments:

0001-Teach-pg_inherits.c-a-bit-about-partitioning.patchtext/plain; charset=UTF-8; name=0001-Teach-pg_inherits.c-a-bit-about-partitioning.patchDownload+200-68
0002-Allow-locking-only-partitioned-children-in-partition.patchtext/plain; charset=UTF-8; name=0002-Allow-locking-only-partitioned-children-in-partition.patchDownload+48-33
0003-WIP-Defer-opening-and-locking-partitions-to-set_appe.patchtext/plain; charset=UTF-8; name=0003-WIP-Defer-opening-and-locking-partitions-to-set_appe.patchDownload+938-185
#2Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Amit Langote (#1)
Re: path toward faster partition pruning

On Mon, Aug 21, 2017 at 12:07 PM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

I've been working on implementing a way to perform plan-time
partition-pruning that is hopefully faster than the current method of
using constraint exclusion to prune each of the potentially many
partitions one-by-one. It's not fully cooked yet though.

Meanwhile, I thought I'd share a couple of patches that implement some
restructuring of the planner code related to partitioned table inheritance
planning that I think would be helpful. They are to be applied on top of
the patches being discussed at [1]. Note that these patches themselves
don't implement the actual code that replaces constraint exclusion as a
method of performing partition pruning. I will share that patch after
debugging it some more.

The main design goal of the patches I'm sharing here now is to defer the
locking and opening of leaf partitions in a given partition tree to a
point after set_append_rel_size() is called on the root partitioned table.
Currently, AFAICS, we need to lock and open the child tables in
expand_inherited_rtentry() only to set the translated_vars field in
AppendRelInfo that we create for the child. ISTM, we can defer the
creation of a child AppendRelInfo to a point when it (its field
translated_vars in particular) will actually be used and so lock and open
the child tables only at such a time. Although we don't lock and open the
partition child tables in expand_inherited_rtentry(), their RT entries are
still created and added to root->parse->rtable, so that
setup_simple_rel_arrays() knows the maximum number of entries
root->simple_rel_array will need to hold and allocate the memory for that
array accordingly. Slots in simple_rel_array[] corresponding to
partition child tables will be empty until they are created when
set_append_rel_size() is called on the root parent table and it determines
the partitions that will be scanned after all.

The partition pruning can happen only after the quals have been
distributed to Rels i.e. after deconstruct_jointree(),
reconsider_outer_join_clauses() and generate_base_implied_equalities()
have been called. If the goal is to not heap_open() the partitions
which are pruned, we can't do that in expand_inherited_rtentry(). One
reason why I think we don't want to heap_open() partition relations is
to avoid relcache bloat because of opened partition relations, which
are ultimately pruned. But please note that according to your patches,
we still need to populate catalog caches to get relkind and reltype
etc.

There are many functions that traverse simple_rel_array[] after it's
created. Most of them assume that the empty entries in that array
correspond to non-simple range entries like join RTEs. But now we are
breaking that assumption. Most of these functions also skip "other"
relations, so that may be OK now, but I am not sure if it's really
going to be fine if we keep empty slots in place of partition
relations. There may be three options here 1. add placeholder
RelOptInfos for partition relations (may be mark those specially) and
mark the ones which get pruned as dummy later. 2. Prune the partitions
before any functions scans simple_rel_array[] or postpone creating
simple_rel_array till pruning. 3. Examine all the current scanners
esp. the ones which will be called before pruning to make sure that
skipping "other" relations is going to be kosher.

Patch augments the existing PartitionedChildRelInfo node, which currently
holds only the partitioned child rel RT indexes, to carry some more
information about the partition tree, which includes the information
returned by RelationGetPartitionDispatchInfo() when it is called from
expand_inherited_rtentry() (per the proposed patch in [1], we call it to
be able to add partitions to the query tree in the bound order).
Actually, since PartitionedChildRelInfo now contains more information
about the partition tree than it used to before, I thought the struct's
name is no longer relevant, so renamed it to PartitionRootInfo and renamed
root->pcinfo_list accordingly to prinfo_list. That seems okay because we
only use that node internally.

Then during the add_base_rels_to_query() step, when build_simple_rel()
builds a RelOptInfo for the root partitioned table, it also initializes
some newly introduced fields in RelOptInfo from the information contained
in PartitionRootInfo of the table. The aforementioned fields are only
initialized in RelOptInfos of root partitioned tables. Note that the
add_base_rels_to_query() step won't add the partition "otherrel"
RelOptInfos yet (unlike the regular inheritance case, where they are,
after looking them up in root->append_rel_list).

Partition-wise join requires the partition hierarchy to be expanded
level-by-level keeping in-tact the parent-child relationship between
partitioned table and its partitions. Your patch doesn't do that and
adds all the partitioning information in the root partitioned table's
RelOptInfo. OTOH, partition-wise join patch adds partition bounds, key
expressions, OID and RelOptInfos of the immediate partitions
(including partitioned partitions) to RelOptInfo of a partitioned
table (see patch 0002 in the latest set of patches at [1]/messages/by-id/CAFjFpRd9Vqh_=-Ldv-XqWY006d07TJ+VXuhXCbdj=P1jukYBrw@mail.gmail.com). I don't
see much point in having conflicting changes in both of our patches.
May be you should review that patch from my set and we can find a set
of members which help both partition pruning and partition-wise join.

When set_append_rel_size() is called on the root partitioned table, it
will call a find_partitions_for_query(), which using the partition tree
information, determines the partitions that will need to be scanned for
the query. This processing happens recursively, that is, we first
determine the root-parent's partitions and then for each partition that's
partitioned, we will determine its partitions and so on. As we determine
partitions in this per-partitioned-table manner, we maintain a pair
(parent_relid, list-of-partition-relids-to-scan) for each partitioned
table and also a single list of all leaf partitions determined so far.
Once all partitions have been determined, we turn to locking the leaf
partitions. The locking happens in the order of OIDs as
find_all_inheritors would have returned in expand_inherited_rtentry(); the
list of OIDs in that original order is also stored in the table's
PartitionRootInfo node. For each OID in that list, check if that OID is
in the set of leaf partition OIDs that was just computed, and if so, lock
it. For all chosen partitions that are partitioned tables (including the
root), we create a PartitionAppendInfo node which stores the
aforementioned pair (parent_relid, list-of-partitions-relids-to-scan), and
append it to a list in the root table's RelOptInfo, with the root table's
PartitionAppendInfo at the head of the list. Note that the list of
partitions in this pair contains only the immediate partitions, so that
the original parent-child relationship is reflected in the list of
PartitionAppendInfos thus collected. The next patch that will implement
actual partition-pruning will add some more code that will run under
find_partitions_for_query().

set_append_rel_size() processing then continues for the root partitioned
table. It is at this point that we will create the RelOptInfos and
AppendRelInfos for partitions. First for those of the root partitioned
table and then for those of each partitioned table when
set_append_rel_size() will be recursively called for the latter.

set_append_rel_size(), set_append_rel_pathlist() are already
recursive, so if we process expansion and pruning for one level in
those functions, the recursion will automatically take care of doing
so for every level.

Note that this is still largely a WIP patch and the implementation details
might change per both the feedback here and the discussion at [1].

The changes to code which handle expansion in this patch set should
really be part of expansion in bound order thread so that it's easy to
review all changes together. And this thread can then only concentrate
on partition pruning.

[1]: /messages/by-id/CAFjFpRd9Vqh_=-Ldv-XqWY006d07TJ+VXuhXCbdj=P1jukYBrw@mail.gmail.com

--
Best Wishes,
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Ashutosh Bapat (#2)
Re: path toward faster partition pruning

Hi Ashutosh,

Thanks for the comments and sorry that it took me a while to reply here.

On 2017/08/23 20:16, Ashutosh Bapat wrote:

On Mon, Aug 21, 2017 at 12:07 PM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

I've been working on implementing a way to perform plan-time
partition-pruning that is hopefully faster than the current method of
using constraint exclusion to prune each of the potentially many
partitions one-by-one. It's not fully cooked yet though.

Meanwhile, I thought I'd share a couple of patches that implement some
restructuring of the planner code related to partitioned table inheritance
planning that I think would be helpful. They are to be applied on top of
the patches being discussed at [1]. Note that these patches themselves
don't implement the actual code that replaces constraint exclusion as a
method of performing partition pruning. I will share that patch after
debugging it some more.

The main design goal of the patches I'm sharing here now is to defer the
locking and opening of leaf partitions in a given partition tree to a
point after set_append_rel_size() is called on the root partitioned table.
Currently, AFAICS, we need to lock and open the child tables in
expand_inherited_rtentry() only to set the translated_vars field in
AppendRelInfo that we create for the child. ISTM, we can defer the
creation of a child AppendRelInfo to a point when it (its field
translated_vars in particular) will actually be used and so lock and open
the child tables only at such a time. Although we don't lock and open the
partition child tables in expand_inherited_rtentry(), their RT entries are
still created and added to root->parse->rtable, so that
setup_simple_rel_arrays() knows the maximum number of entries
root->simple_rel_array will need to hold and allocate the memory for that
array accordingly. Slots in simple_rel_array[] corresponding to
partition child tables will be empty until they are created when
set_append_rel_size() is called on the root parent table and it determines
the partitions that will be scanned after all.

The partition pruning can happen only after the quals have been
distributed to Rels i.e. after deconstruct_jointree(),
reconsider_outer_join_clauses() and generate_base_implied_equalities()
have been called. If the goal is to not heap_open() the partitions
which are pruned, we can't do that in expand_inherited_rtentry(). One
reason why I think we don't want to heap_open() partition relations is
to avoid relcache bloat because of opened partition relations, which
are ultimately pruned. But please note that according to your patches,
we still need to populate catalog caches to get relkind and reltype
etc.

Yes, we still hit syscache for *all* partitions. I haven't yet thought
very hard about avoiding that altogether.

There are many functions that traverse simple_rel_array[] after it's
created. Most of them assume that the empty entries in that array
correspond to non-simple range entries like join RTEs. But now we are
breaking that assumption. Most of these functions also skip "other"
relations, so that may be OK now, but I am not sure if it's really
going to be fine if we keep empty slots in place of partition
relations. There may be three options here 1. add placeholder
RelOptInfos for partition relations (may be mark those specially) and
mark the ones which get pruned as dummy later. 2. Prune the partitions
before any functions scans simple_rel_array[] or postpone creating
simple_rel_array till pruning. 3. Examine all the current scanners
esp. the ones which will be called before pruning to make sure that
skipping "other" relations is going to be kosher.

Between the point when slots in simple_rel_array are allocated
(setup_simple_rel_arrays) and partition RelOptInfos are actually created
after the partition-pruning step has occurred (set_append_rel_size), it
seems that most places that iterate over simple_rel_array know also to
skip slots containing NULL values. We might need to document that NULL
means partitions in addition to its current meaning - non-baserels.

Patch augments the existing PartitionedChildRelInfo node, which currently
holds only the partitioned child rel RT indexes, to carry some more
information about the partition tree, which includes the information
returned by RelationGetPartitionDispatchInfo() when it is called from
expand_inherited_rtentry() (per the proposed patch in [1], we call it to
be able to add partitions to the query tree in the bound order).
Actually, since PartitionedChildRelInfo now contains more information
about the partition tree than it used to before, I thought the struct's
name is no longer relevant, so renamed it to PartitionRootInfo and renamed
root->pcinfo_list accordingly to prinfo_list. That seems okay because we
only use that node internally.

Then during the add_base_rels_to_query() step, when build_simple_rel()
builds a RelOptInfo for the root partitioned table, it also initializes
some newly introduced fields in RelOptInfo from the information contained
in PartitionRootInfo of the table. The aforementioned fields are only
initialized in RelOptInfos of root partitioned tables. Note that the
add_base_rels_to_query() step won't add the partition "otherrel"
RelOptInfos yet (unlike the regular inheritance case, where they are,
after looking them up in root->append_rel_list).

Partition-wise join requires the partition hierarchy to be expanded
level-by-level keeping in-tact the parent-child relationship between
partitioned table and its partitions. Your patch doesn't do that and
adds all the partitioning information in the root partitioned table's
RelOptInfo. OTOH, partition-wise join patch adds partition bounds, key
expressions, OID and RelOptInfos of the immediate partitions
(including partitioned partitions) to RelOptInfo of a partitioned
table (see patch 0002 in the latest set of patches at [1]). I don't
see much point in having conflicting changes in both of our patches.
May be you should review that patch from my set and we can find a set
of members which help both partition pruning and partition-wise join.

Yes, I think it would be a good idea for the partition-pruning patch to
initialize those fields in the individual parents' RelOptInfos. I will
review relevant patches in the partitionwise-join thread to see what can
be incorporated here.

When set_append_rel_size() is called on the root partitioned table, it
will call a find_partitions_for_query(), which using the partition tree
information, determines the partitions that will need to be scanned for
the query. This processing happens recursively, that is, we first
determine the root-parent's partitions and then for each partition that's
partitioned, we will determine its partitions and so on. As we determine
partitions in this per-partitioned-table manner, we maintain a pair
(parent_relid, list-of-partition-relids-to-scan) for each partitioned
table and also a single list of all leaf partitions determined so far.
Once all partitions have been determined, we turn to locking the leaf
partitions. The locking happens in the order of OIDs as
find_all_inheritors would have returned in expand_inherited_rtentry(); the
list of OIDs in that original order is also stored in the table's
PartitionRootInfo node. For each OID in that list, check if that OID is
in the set of leaf partition OIDs that was just computed, and if so, lock
it. For all chosen partitions that are partitioned tables (including the
root), we create a PartitionAppendInfo node which stores the
aforementioned pair (parent_relid, list-of-partitions-relids-to-scan), and
append it to a list in the root table's RelOptInfo, with the root table's
PartitionAppendInfo at the head of the list. Note that the list of
partitions in this pair contains only the immediate partitions, so that
the original parent-child relationship is reflected in the list of
PartitionAppendInfos thus collected. The next patch that will implement
actual partition-pruning will add some more code that will run under
find_partitions_for_query().

set_append_rel_size() processing then continues for the root partitioned
table. It is at this point that we will create the RelOptInfos and
AppendRelInfos for partitions. First for those of the root partitioned
table and then for those of each partitioned table when
set_append_rel_size() will be recursively called for the latter.

set_append_rel_size(), set_append_rel_pathlist() are already
recursive, so if we process expansion and pruning for one level in
those functions, the recursion will automatically take care of doing
so for every level.

My only worry about that is locking order of leaf partitions will be
different from concurrent backends if we lock them in an order dictated by
traversing the partition tree level at a time. Because such traversal
will presumably proceed in the partition bound order.

The patch computes *all* leaf partitions that will need to be scanned by
the query (after pruning needless ones) and lock the chosen partitions in
the original order (it keeps the original order OID list generated by
find_all_inheritors around for this purpose). While computing the leaf
partitions, it remembers immediate parent-child relationships in the
process. The way it does it is by processing the partition tree in a
recursive depth-first manner, and in each recursive step, creating a
PartitionAppendInfo that maps a parent table to its immediate children
(only those that will satisfy the query). Once the PartitionAppendInfo's
for all the parents in the partition tree have been computed, we resume
the set_append_rel_size() processing, which takes the root parent's
PartitionAppendInfo and builds RelOptInfos and AppendRelInfos for its
immediate children. Its children that are partitioned tables themselves
will recursively call set_append_rel_size() and look up its own
PartitionAppendInfo and create RelOptInfos and AppendRelInfos for its
children and so on.

Note that this is still largely a WIP patch and the implementation details
might change per both the feedback here and the discussion at [1].

The changes to code which handle expansion in this patch set should
really be part of expansion in bound order thread so that it's easy to
review all changes together. And this thread can then only concentrate
on partition pruning.

I think I agree. I'm posting today the patches that actually implement
partition-pruning. The previous patches do seem to belong on the EIBO
thread, but will post them together here today for convenience of being
able to apply them to HEAD and try out. Now that Robert has posted a
patch to implement depth-first EIBO, I will have to find a way to rebase
the actual partition-pruning patches on this thread so that its core logic
works at all by finding the information it needs.

Thanks,
Amit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#1)
Re: path toward faster partition pruning

On 2017/08/21 15:37, Amit Langote wrote:

Meanwhile, I thought I'd share a couple of patches that implement some
restructuring of the planner code related to partitioned table inheritance
planning that I think would be helpful. They are to be applied on top of
the patches being discussed at [1]. Note that these patches themselves
don't implement the actual code that replaces constraint exclusion as a
method of performing partition pruning. I will share that patch after
debugging it some more.

The next patch that will implement
actual partition-pruning will add some more code that will run under
find_partitions_for_query().

Attached is now also the set of patches that implement the actual
partition-pruning logic, viz. the last 3 patches (0004, 0005, and 0006) of
the attached.

Because the patch helps avoid performing constraint exclusion on *all*
partitions for a given query, one might expect this to improve performance
for queries on partitioned tables and scale to a fairly large number of
partitions. Here are some numbers for the partitioned table and the query
shown below:

\d+ ptab
Columns: (a date, b int, c text)
Partition key: RANGE (a, b)
Partitions:
ptab_00001 FOR VALUES FROM ('2017-08-31', 1) TO ('2017-08-31', 1000),
ptab_00002 FOR VALUES FROM ('2017-08-31', 1000) TO ('2017-08-31', 2000),
ptab_00003 FOR VALUES FROM ('2017-08-31', 2000) TO ('2017-08-31', 3000),
ptab_00004 FOR VALUES FROM ('2017-08-31', 3000) TO ('2017-08-31', 4000),
ptab_00005 FOR VALUES FROM ('2017-08-31', 4000) TO ('2017-08-31', 5000),

ptab_00006 FOR VALUES FROM ('2017-09-01', 1) TO ('2017-09-01', 1000),
ptab_00007 FOR VALUES FROM ('2017-09-01', 1000) TO ('2017-09-01', 2000),

...
ptab_NNNNN FOR VALUES FROM (..., 4000) TO (..., 5000),

A query that prunes all partitions (empty result!):

explain select * from ptab where a < '2017-08-31';

Comparison of the average response times (in milliseconds) after running
the same query 100 times using pgbench against the database:

#: Number of partitions of ptab
c_e: Constraint exclusion
f_p: Fast pruning

# c_e f_p
===== ===== ====
10 0.7 0.4
50 1.8 0.6
100 3.2 0.8
500 16.8 2.7
1000 36.2 5.0
2000 79.7 10.2
5000 214.7 27.0
10000 443.6 64.8

For each partitioned table in a given partition tree (provided it is not
pruned to begin with), the query's clauses are matched to its partition
key and from the matched clauses, a pair of bounding keys (Datum tuples
with <= key->partnatts values for possibly a prefix of a multi-column key)
is generated. They are passed to partition.c: get_partitions_for_keys()
as Datum *minkeys and Datum *maxkeys. A list of partitions covering that
key range is returned. When generating that list, whether a particular
scan key is inclusive or not is considered along with the partitioning
strategy. It should be possible to support hash partitioning with
(hopefully) minimal changes to get_partitions_for_keys().

There are still certain limitations on the planner side of things:

1. OR clauses are not counted as contributing toward bounding scan keys;
currently only OpExprs and NullTests are recognized, so an OR clause
would get skipped from consideration when generating the bounding keys
to pass to partition.c

2. Redundant clauses are not appropriately pre-processed; so if a query
contains a = 10 and a > 1, the latter clause will be matched and
partitions holding values with a > 1 and a < 10 will not be pruned,
even if none of their rows will pass the query's condition

Fixing these limitations, adding more regression tests and implementing
some of the things suggested by Ashutosh Bapat [1]/messages/by-id/CAFjFpRdb_fkmJHFjvAbB+Ln0t45fWjekLd5pY=sv+eAhBAKXPQ@mail.gmail.com to prevent conflicting
changes with some preparatory patches in the partitionwise-join patch
series [2]/messages/by-id/CAFjFpRd9Vqh_=-Ldv-XqWY006d07TJ+VXuhXCbdj=P1jukYBrw@mail.gmail.com are TODOs.

Adding this to CF-201709 as "faster partition pruning in planner".

To try out the attached patches: apply the patches posted at [3]/messages/by-id/2124e99f-9528-0f71-4e10-ac7974dd7077@lab.ntt.co.jp on HEAD
and then apply these

Thanks,
Amit

[1]: /messages/by-id/CAFjFpRdb_fkmJHFjvAbB+Ln0t45fWjekLd5pY=sv+eAhBAKXPQ@mail.gmail.com
/messages/by-id/CAFjFpRdb_fkmJHFjvAbB+Ln0t45fWjekLd5pY=sv+eAhBAKXPQ@mail.gmail.com

[2]: /messages/by-id/CAFjFpRd9Vqh_=-Ldv-XqWY006d07TJ+VXuhXCbdj=P1jukYBrw@mail.gmail.com
/messages/by-id/CAFjFpRd9Vqh_=-Ldv-XqWY006d07TJ+VXuhXCbdj=P1jukYBrw@mail.gmail.com

[3]: /messages/by-id/2124e99f-9528-0f71-4e10-ac7974dd7077@lab.ntt.co.jp
/messages/by-id/2124e99f-9528-0f71-4e10-ac7974dd7077@lab.ntt.co.jp

Attachments:

0001-Teach-pg_inherits.c-a-bit-about-partitioning.patchtext/plain; charset=UTF-8; name=0001-Teach-pg_inherits.c-a-bit-about-partitioning.patchDownload+200-68
0002-Allow-locking-only-partitioned-children-in-partition.patchtext/plain; charset=UTF-8; name=0002-Allow-locking-only-partitioned-children-in-partition.patchDownload+48-33
0003-WIP-Defer-opening-and-locking-partitions-to-set_appe.patchtext/plain; charset=UTF-8; name=0003-WIP-Defer-opening-and-locking-partitions-to-set_appe.patchDownload+1029-202
0004-WIP-Interface-changes-for-partition_bound_-cmp-bsear.patchtext/plain; charset=UTF-8; name=0004-WIP-Interface-changes-for-partition_bound_-cmp-bsear.patchDownload+90-34
0005-WIP-partition.c-interface-additions-for-partition-pr.patchtext/plain; charset=UTF-8; name=0005-WIP-partition.c-interface-additions-for-partition-pr.patchDownload+208-11
0006-WIP-planner-side-changes-for-partition-pruning.patchtext/plain; charset=UTF-8; name=0006-WIP-planner-side-changes-for-partition-pruning.patchDownload+668-9
#5Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#4)
Re: path toward faster partition pruning

On Thu, Aug 31, 2017 at 2:02 AM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

Attached is now also the set of patches that implement the actual
partition-pruning logic, viz. the last 3 patches (0004, 0005, and 0006) of
the attached.

It strikes me that this patch set is doing two things but maybe in the
opposite order that I would have chosen to attack them. First,
there's getting partition pruning to use something other than
constraint exclusion. Second, there's deferring work that is
currently done at an early stage of the process until later, so that
we waste less effort on partitions that are ultimately going to be
pruned.

The second one is certainly a worthwhile goal, but there are fairly
firm interdependencies between the first one and some other things
that are in progress. For example, the first one probably ought to be
done before hash partitioning gets committed, because
constraint-exclusion based partitioning pruning won't work with
partitioning pruning, but some mechanism based on asking the
partitioning code which partitions might match will. Such a mechanism
is more efficient for list and range partitions, but it's the only
thing that will work for hash partitions. Also, Beena Emerson is
working on run-time partition pruning, and the more I think about it,
the more I think that overlaps with this first part. Both patches
need a mechanism to identify, given a btree-indexable comparison
operator (< > <= >= =) and a set of values, which partitions might
contain matching values. Run-time partition pruning will call that at
execution time, and this patch will call it at plan time, but it's the
same logic; it's just a question of the point at which the values are
known. And of course we don't want to end up with two copies of the
logic.

Therefore, IMHO, it would be best to focus first on how we're going to
identify the partitions that survive pruning, and then afterwards work
on transposing that logic to happen before partitions are opened and
locked. That way, we get some incremental benefit sooner, and also
unblock some other development work.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#5)
Re: path toward faster partition pruning

Thanks for the comments.

On 2017/09/02 2:52, Robert Haas wrote:

On Thu, Aug 31, 2017 at 2:02 AM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

Attached is now also the set of patches that implement the actual
partition-pruning logic, viz. the last 3 patches (0004, 0005, and 0006) of
the attached.

It strikes me that this patch set is doing two things but maybe in the
opposite order that I would have chosen to attack them. First,
there's getting partition pruning to use something other than
constraint exclusion. Second, there's deferring work that is
currently done at an early stage of the process until later, so that
we waste less effort on partitions that are ultimately going to be
pruned.

OK.

The second one is certainly a worthwhile goal, but there are fairly
firm interdependencies between the first one and some other things
that are in progress. For example, the first one probably ought to be
done before hash partitioning gets committed, because
constraint-exclusion based partitioning pruning won't work with
partitioning pruning, but some mechanism based on asking the
partitioning code which partitions might match will.

Yeah.

Such a mechanism
is more efficient for list and range partitions, but it's the only
thing that will work for hash partitions. Also, Beena Emerson is
working on run-time partition pruning, and the more I think about it,
the more I think that overlaps with this first part. Both patches
need a mechanism to identify, given a btree-indexable comparison
operator (< > <= >= =) and a set of values, which partitions might
contain matching values. Run-time partition pruning will call that at
execution time, and this patch will call it at plan time, but it's the
same logic; it's just a question of the point at which the values are
known. And of course we don't want to end up with two copies of the
logic.

Agreed here too.

I agree that spending effort on the first part (deferment of locking, etc.
within the planner) does not benefit either the hash partitioning and
run-time pruning patches much.

Therefore, IMHO, it would be best to focus first on how we're going to
identify the partitions that survive pruning, and then afterwards work
on transposing that logic to happen before partitions are opened and
locked. That way, we get some incremental benefit sooner, and also
unblock some other development work.

Alright, I will try to do it that way.

Thanks,
Amit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#6)
Re: path toward faster partition pruning

On 2017/09/04 10:10, Amit Langote wrote:

On 2017/09/02 2:52, Robert Haas wrote:

It strikes me that this patch set is doing two things but maybe in the
opposite order that I would have chosen to attack them. First,
there's getting partition pruning to use something other than
constraint exclusion. Second, there's deferring work that is
currently done at an early stage of the process until later, so that
we waste less effort on partitions that are ultimately going to be
pruned.

OK.

Therefore, IMHO, it would be best to focus first on how we're going to
identify the partitions that survive pruning, and then afterwards work
on transposing that logic to happen before partitions are opened and
locked. That way, we get some incremental benefit sooner, and also
unblock some other development work.

Alright, I will try to do it that way.

Attached set of patches that does things that way. Individual patches
described below:

[PATCH 1/5] Expand partitioned inheritance in a non-flattened manner

This will allow us to perform scan and join planning in a per partition
sub-tree manner, with each sub-tree's root getting its own RelOptInfo.
Previously, only the root of the whole partition tree would get a
RelOptInfo, along with the leaf partitions, with each leaf partition's
AppendRelInfo pointing to the former as its parent.

This is essential, because we will be doing partition-pruning for every
partitioned table in the tree by matching query's scan keys with its
partition key. We won't be able to do that if the intermediate
partitioned tables didn't have a RelOptInfo.

[PATCH 2/5] WIP: planner-side changes for partition-pruning

This patch adds a stub get_partitions_for_keys in partition.c with a
suitable interface for the caller to pass bounding keys extracted from the
query and other related information.

Importantly, it implements the logic within the planner to match query's
scan keys to a parent table's partition key and form the bounding keys
that will be passed to partition.c to compute the list of partitions that
satisfy those bounds.

Also, it adds certain fields to RelOptInfos of the partitioned tables that
reflect its partitioning properties.

[PATCH 3/5] WIP: Interface changes for partition_bound_{cmp/bsearch}

This guy modifies the partition bound comparison function so that the
caller can pass incomplete partition key tuple that is potentially a
prefix of a multi-column partition key. Currently, the input tuple must
contain all of key->partnatts values, but that may not be true for
queries, which may not have restrictions on all the partition key columns.

[PATCH 4/5] WIP: Implement get_partitions_for_keys()

This one fills the get_partitions_for_keys stub with the actual logic that
searches the partdesc->boundinfo for partition bounds that match the
bounding keys specified by the caller.

[PATCH 5/5] Add more tests for the new partitioning-related planning

More tests.

Some TODO items still remain to be done:

* Process OR clauses to use for partition-pruning
* Process redundant clauses (such as a = 10 and a > 1) more smartly
* Other tricks that are missing
* Fix bugs
* More tests

Thanks,
Amit

Attachments:

0001-Expand-partitioned-inheritance-in-a-non-flattened-ma.patchtext/plain; charset=UTF-8; name=0001-Expand-partitioned-inheritance-in-a-non-flattened-ma.patchDownload+146-65
0002-WIP-planner-side-changes-for-partition-pruning.patchtext/plain; charset=UTF-8; name=0002-WIP-planner-side-changes-for-partition-pruning.patchDownload+595-42
0003-WIP-Interface-changes-for-partition_bound_-cmp-bsear.patchtext/plain; charset=UTF-8; name=0003-WIP-Interface-changes-for-partition_bound_-cmp-bsear.patchDownload+90-34
0004-WIP-Implement-get_partitions_for_keys.patchtext/plain; charset=UTF-8; name=0004-WIP-Implement-get_partitions_for_keys.patchDownload+192-6
0005-Add-more-tests-for-the-new-partitioning-related-plan.patchtext/plain; charset=UTF-8; name=0005-Add-more-tests-for-the-new-partitioning-related-plan.patchDownload+531-2
#8Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#7)
Re: path toward faster partition pruning

Forgot to mention a couple of important points about the relation of some
of the patches here to the patches and discussion at the
partitionwise-join thread [1]/messages/by-id/CAFjFpRfRDhWp=oguNjyzN=NMoOD+RCC3wS+b+xbGKwKUk0dRKg@mail.gmail.com.

On 2017/09/06 19:38, Amit Langote wrote:

[PATCH 1/5] Expand partitioned inheritance in a non-flattened manner

This will allow us to perform scan and join planning in a per partition
sub-tree manner, with each sub-tree's root getting its own RelOptInfo.
Previously, only the root of the whole partition tree would get a
RelOptInfo, along with the leaf partitions, with each leaf partition's
AppendRelInfo pointing to the former as its parent.

This is essential, because we will be doing partition-pruning for every
partitioned table in the tree by matching query's scan keys with its
partition key. We won't be able to do that if the intermediate
partitioned tables didn't have a RelOptInfo.

There is a patch in the Ashutosh's posted series of patches, which does
more or less the same thing that this patch does. He included it in his
series of patches, because, IIUC, the main partitionwise-join planning
logic that one of the later patch implements depends on being able to
consider applying that new planning technique individually for every
partition sub-tree, instead of just at the whole tree root.

One notable difference from his patch is that while his patch will expand
in non-flattened manner even in the case where the parent is the result
relation of a query, my patch doesn't in that case, because the new
partition-pruning technique cannot be applied to inheritance parent that
is a result relation, for example,

update partitioned_table set ...

And AFAICS, partitionwise-join cannot be applied to such a parent either.

Note however that if there are other instances of the same partitioned
table (in the FROM list of an update statement) or other partitioned
tables in the query, they will be expanded in a non-flattened manner,
because they are themselves not the result relations of the query. So,
the new partition-pruning and (supposedly) partitionwise-join can be
applied for those other partitioned tables.

[PATCH 2/5] WIP: planner-side changes for partition-pruni[...]

Also, it adds certain fields to RelOptInfos of the partitioned tables that
reflect its partitioning properties.

There is something called PartitionScheme, which is a notion one of the
Ashutosh's patches invented that this patch incorporates as one of the new
fields in RelOptInfo that I mentioned above (also a list of
PartitionScheme's in the planner-global PlannerInfo). Although,
PartitionScheme is not significant for the task of partition-pruning
itself, it's still useful. On Ashutosh's suggestion, I adopted the same
in my patch series, so that the partition-wise join patch doesn't end up
conflicting with the partition-pruning patch while trying to implement the
same and can get straight to the task of implementing partition-wise joins.

The same patch in the partition-wise join patch series that introduces
PartitionScheme, also introduces a field in the RelOptInfo called
partexprs, which records the partition key expressions. Since,
partition-pruning has use for the same, I incorporated the same here;
also, in a format that Ashutosh's partition-wise patch can use directly,
instead of the latter having to hack it again to make it suitable to store
partition key expressions of joinrels. Again, that's to minimize
conflicts and let his patch just find the field to use as is, instead of
implementing it first.

Lastly, this patch introduces a PartitionAppendInfo in a partitioned
table's RelOptInfo that stores AppendRelInfos of the partitions (child
relations) that survive partition-pruning, which serves to identify those
partitions' RelOptInfos. Along with the identities of surviving
partitions, it also stores the partitioning configuration of the
partitioned table after partitions are pruned. That includes
partdesc->boundinfo (which is simply a pointer into the table's relcache)
and a few other fields that are set by partition-pruning code, such
min_datum_index, max_datum_index, null_partition_chosen, that describe the
result after pruning. So, for two partitioned tables being joined, if the
boundinfos match per partition_bounds_equal() and these other fields
match, they can be safely partition-wise joined.

[1]: /messages/by-id/CAFjFpRfRDhWp=oguNjyzN=NMoOD+RCC3wS+b+xbGKwKUk0dRKg@mail.gmail.com
/messages/by-id/CAFjFpRfRDhWp=oguNjyzN=NMoOD+RCC3wS+b+xbGKwKUk0dRKg@mail.gmail.com

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#8)
Re: path toward faster partition pruning

On Thu, Sep 7, 2017 at 7:16 AM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

There is a patch in the Ashutosh's posted series of patches, which does
more or less the same thing that this patch does. He included it in his
series of patches, because, IIUC, the main partitionwise-join planning
logic that one of the later patch implements depends on being able to
consider applying that new planning technique individually for every
partition sub-tree, instead of just at the whole tree root.

One notable difference from his patch is that while his patch will expand
in non-flattened manner even in the case where the parent is the result
relation of a query, my patch doesn't in that case, because the new
partition-pruning technique cannot be applied to inheritance parent that
is a result relation, for example,

update partitioned_table set ...

And AFAICS, partitionwise-join cannot be applied to such a parent either.

Note however that if there are other instances of the same partitioned
table (in the FROM list of an update statement) or other partitioned
tables in the query, they will be expanded in a non-flattened manner,
because they are themselves not the result relations of the query. So,
the new partition-pruning and (supposedly) partitionwise-join can be
applied for those other partitioned tables.

It seems to me that it would be better not to write new patches for
things that already have patches without a really clear explanation
with what's wrong with the already-existing patch; I don't see any
such explanation here. Instead of writing your own patch for this to
duel with his his, why not review his and help him correct any
deficiencies which you can spot? Then we have one patch with more
review instead of two patches with less review both of which I have to
read and try to decide which is better.

In this case, I think Ashutosh has the right idea. I think that
handling the result-relation and non-result-relation differently
creates an unpleasant asymmetry. With your patch, we have to deal
with three cases: (a) partitioned tables that were expanded
level-by-level because they are not result relations, (b) partitioned
tables that were expanded "flattened" because they are result
relations, and (c) non-partitioned tables that were expanded
"flattened". With Ashutosh's approach, we only have two cases to
worry about in the future rather than three, and I like that better.

Your patch also appears to change things so that the table actually
referenced in the query ends up with an AppendRelInfo for the parent,
which seems pointless. And it has no tests.

There are a couple of hunks from your patch that we might want or need
to incorporate into Ashutosh's patch. The change to
relation_excluded_by_constraints() looks like it might be useful,
although it needs a better comment and some tests. Also, Ashutosh's
patch has no equivalent of your change to add_paths_to_append_rel().
I'm not clear what the code you've introduced there is supposed to be
doing, and I'm suspicious that it is confusing "partition root" with
"table named in the query", which will often be the same but not
always; the user could have named an intermediate partition. Can you
expand on what this is doing?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#9)
Re: path toward faster partition pruning

On 2017/09/08 4:41, Robert Haas wrote:

On Thu, Sep 7, 2017 at 7:16 AM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

There is a patch in the Ashutosh's posted series of patches, which does
more or less the same thing that this patch does. He included it in his
series of patches, because, IIUC, the main partitionwise-join planning
logic that one of the later patch implements depends on being able to
consider applying that new planning technique individually for every
partition sub-tree, instead of just at the whole tree root.

One notable difference from his patch is that while his patch will expand
in non-flattened manner even in the case where the parent is the result
relation of a query, my patch doesn't in that case, because the new
partition-pruning technique cannot be applied to inheritance parent that
is a result relation, for example,

update partitioned_table set ...

And AFAICS, partitionwise-join cannot be applied to such a parent either.

Note however that if there are other instances of the same partitioned
table (in the FROM list of an update statement) or other partitioned
tables in the query, they will be expanded in a non-flattened manner,
because they are themselves not the result relations of the query. So,
the new partition-pruning and (supposedly) partitionwise-join can be
applied for those other partitioned tables.

It seems to me that it would be better not to write new patches for
things that already have patches without a really clear explanation
with what's wrong with the already-existing patch; I don't see any
such explanation here. Instead of writing your own patch for this to
duel with his his, why not review his and help him correct any
deficiencies which you can spot? Then we have one patch with more
review instead of two patches with less review both of which I have to
read and try to decide which is better.

Sorry, I think I should have just used the Ashutosh's patch.

In this case, I think Ashutosh has the right idea. I think that
handling the result-relation and non-result-relation differently
creates an unpleasant asymmetry. With your patch, we have to deal
with three cases: (a) partitioned tables that were expanded
level-by-level because they are not result relations, (b) partitioned
tables that were expanded "flattened" because they are result
relations, and (c) non-partitioned tables that were expanded
"flattened". With Ashutosh's approach, we only have two cases to
worry about in the future rather than three, and I like that better.

I tend to agree with this now.

Your patch also appears to change things so that the table actually
referenced in the query ends up with an AppendRelInfo for the parent,
which seems pointless.

Actually, it wouldn't, because my patch also got rid of the notion of
adding the duplicate RTE for original parent, because I thought the
duplicate RTE was pointless in the partitioning case.

There are a couple of hunks from your patch that we might want or need
to incorporate into Ashutosh's patch. The change to
relation_excluded_by_constraints() looks like it might be useful,
although it needs a better comment and some tests.

I think we could just drop that part from this patch. It also looks like
Ashutosh has a patch elsewhere concerning this.

https://commitfest.postgresql.org/14/1108/

Maybe, we could discuss what do about this on that thread. Now that not
only the root partitioned table, but also other partitioned tables in the
tree get an RTE with inh = true, I think it would be interesting to
consider his patch.

Also, Ashutosh's
patch has no equivalent of your change to add_paths_to_append_rel().
I'm not clear what the code you've introduced there is supposed to be
doing, and I'm suspicious that it is confusing "partition root" with
"table named in the query", which will often be the same but not
always; the user could have named an intermediate partition. Can you
expand on what this is doing?

I've replied on the partition-wise thread explaining why changes in the
add_paths_to_append_rel() are necessary.

Anyway, I'm dropping my patch in favor of the patch on the other thread.
Sorry for the duplicated effort involved in having to look at both the
patches.

Thanks,
Amit

[1]: /messages/by-id/CA+TgmoZEUonD9dUZH1FBEyq=PEv_KvE3wC=A=0zm-_tRz_917A@mail.gmail.com
/messages/by-id/CA+TgmoZEUonD9dUZH1FBEyq=PEv_KvE3wC=A=0zm-_tRz_917A@mail.gmail.com

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#1)
Re: path toward faster partition pruning

On 21 August 2017 at 18:37, Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> wrote:

I've been working on implementing a way to perform plan-time
partition-pruning that is hopefully faster than the current method of
using constraint exclusion to prune each of the potentially many
partitions one-by-one. It's not fully cooked yet though.

I'm interested in seeing improvements in this area, so I've put my
name down to review this.

--
David Rowley http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#11)
Re: path toward faster partition pruning

On 2017/09/15 10:55, David Rowley wrote:

On 21 August 2017 at 18:37, Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> wrote:

I've been working on implementing a way to perform plan-time
partition-pruning that is hopefully faster than the current method of
using constraint exclusion to prune each of the potentially many
partitions one-by-one. It's not fully cooked yet though.

I'm interested in seeing improvements in this area, so I've put my
name down to review this.

Great, thanks!

I will post rebased patches later today, although I think the overall
design of the patch on the planner side of things is not quite there yet.
Of course, your and others' feedback is greatly welcome.

Also, I must inform to all of those who're looking at this thread that I
won't be able to respond to emails from tomorrow (9/16, Sat) until 9/23,
Sat, due to some personal business.

Thanks,
Amit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Dilip Kumar
dilipbalaut@gmail.com
In reply to: Amit Langote (#7)
Re: path toward faster partition pruning

On Wed, Sep 6, 2017 at 4:08 PM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

On 2017/09/04 10:10, Amit Langote wrote:

On 2017/09/02 2:52, Robert Haas wrote:

[PATCH 2/5] WIP: planner-side changes for partition-pruning

This patch adds a stub get_partitions_for_keys in partition.c with a
suitable interface for the caller to pass bounding keys extracted from the
query and other related information.

Importantly, it implements the logic within the planner to match query's
scan keys to a parent table's partition key and form the bounding keys
that will be passed to partition.c to compute the list of partitions that
satisfy those bounds.

+ Node   *leftop = get_leftop(clause);
+
+ if (IsA(leftop, RelabelType))
+ leftop = (Node *) ((RelabelType *) leftop)->arg;
+
+ if (equal(leftop, partkey))

It appears that this patch always assume that clause will be of form
"var op const", but it can also be "const op var"

That's the reason in below example where in both the queries condition
is same it can only prune in the first case but not in the second.

postgres=# explain select * from t where t.a < 2;
QUERY PLAN
--------------------------------------------------------
Append (cost=0.00..2.24 rows=1 width=8)
-> Seq Scan on t1 (cost=0.00..2.24 rows=1 width=8)
Filter: (a < 2)
(3 rows)

postgres=# explain select * from t where 2>t.a;
QUERY PLAN
--------------------------------------------------------
Append (cost=0.00..4.49 rows=2 width=8)
-> Seq Scan on t1 (cost=0.00..2.24 rows=1 width=8)
Filter: (2 > a)
-> Seq Scan on t2 (cost=0.00..2.25 rows=1 width=8)
Filter: (2 > a)
(5 rows)

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#14Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Dilip Kumar (#13)
Re: path toward faster partition pruning

Hi Dilip,

Thanks for looking at the patch.

On 2017/09/15 13:43, Dilip Kumar wrote:

On Wed, Sep 6, 2017 at 4:08 PM, Amit Langote

[PATCH 2/5] WIP: planner-side changes for partition-pruning

This patch adds a stub get_partitions_for_keys in partition.c with a
suitable interface for the caller to pass bounding keys extracted from the
query and other related information.

Importantly, it implements the logic within the planner to match query's
scan keys to a parent table's partition key and form the bounding keys
that will be passed to partition.c to compute the list of partitions that
satisfy those bounds.

+ Node   *leftop = get_leftop(clause);
+
+ if (IsA(leftop, RelabelType))
+ leftop = (Node *) ((RelabelType *) leftop)->arg;
+
+ if (equal(leftop, partkey))

It appears that this patch always assume that clause will be of form
"var op const", but it can also be "const op var"

That's the reason in below example where in both the queries condition
is same it can only prune in the first case but not in the second.

postgres=# explain select * from t where t.a < 2;
QUERY PLAN
--------------------------------------------------------
Append (cost=0.00..2.24 rows=1 width=8)
-> Seq Scan on t1 (cost=0.00..2.24 rows=1 width=8)
Filter: (a < 2)
(3 rows)

postgres=# explain select * from t where 2>t.a;
QUERY PLAN
--------------------------------------------------------
Append (cost=0.00..4.49 rows=2 width=8)
-> Seq Scan on t1 (cost=0.00..2.24 rows=1 width=8)
Filter: (2 > a)
-> Seq Scan on t2 (cost=0.00..2.25 rows=1 width=8)
Filter: (2 > a)
(5 rows)

Yeah, there are a bunch of smarts still missing in that patch as it is.

Thanks,
Amit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#15Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#12)
Re: path toward faster partition pruning

On 2017/09/15 11:16, Amit Langote wrote:

I will post rebased patches later today, although I think the overall
design of the patch on the planner side of things is not quite there yet.
Of course, your and others' feedback is greatly welcome.

Rebased patches attached. Because Dilip complained earlier today about
clauses of the form (const op var) not causing partition-pruning, I've
added code to commute the clause where it is required. Some other
previously mentioned limitations remain -- no handling of OR clauses, no
elimination of redundant clauses for given partitioning column, etc.

A note about 0001: this patch overlaps with
0003-Canonical-partition-scheme.patch from the partitionwise-join patch
series that Ashutosh Bapat posted yesterday [1]/messages/by-id/CAFiTN-skmaqeCVaoAHCBqe2DyfO3f6sgdtEjHWrUgi0kV1yPLQ@mail.gmail.com. Because I implemented
the planner-portion of this patch based on what 0001 builds, I'm posting
it here. It might actually turn out that we will review and commit
0003-Canonical-partition-scheme.patch on that thread, but meanwhile apply
0001 if you want to play with the later patches. I would certainly like
to review 0003-Canonical-partition-scheme.patch myself, but won't be able
to immediately (see below).

Also, I must inform to all of those who're looking at this thread that I
won't be able to respond to emails from tomorrow (9/16, Sat) until 9/23,
Sat, due to some personal business.

To remind.

Thanks,
Amit

[1]: /messages/by-id/CAFiTN-skmaqeCVaoAHCBqe2DyfO3f6sgdtEjHWrUgi0kV1yPLQ@mail.gmail.com
/messages/by-id/CAFiTN-skmaqeCVaoAHCBqe2DyfO3f6sgdtEjHWrUgi0kV1yPLQ@mail.gmail.com

Attachments:

0001-Some-optimizer-data-structures-for-partitioned-rels.patchtext/plain; charset=UTF-8; name=0001-Some-optimizer-data-structures-for-partitioned-rels.patchDownload+278-1
0002-WIP-planner-side-changes-for-partition-pruning.patchtext/plain; charset=UTF-8; name=0002-WIP-planner-side-changes-for-partition-pruning.patchDownload+371-40
0003-WIP-Interface-changes-for-partition_bound_-cmp-bsear.patchtext/plain; charset=UTF-8; name=0003-WIP-Interface-changes-for-partition_bound_-cmp-bsear.patchDownload+96-40
0004-WIP-Implement-get_partitions_for_keys.patchtext/plain; charset=UTF-8; name=0004-WIP-Implement-get_partitions_for_keys.patchDownload+209-6
0005-Add-more-tests-for-the-new-partitioning-related-plan.patchtext/plain; charset=UTF-8; name=0005-Add-more-tests-for-the-new-partitioning-related-plan.patchDownload+549-2
#16Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#15)
Re: path toward faster partition pruning

On Fri, Sep 15, 2017 at 4:50 AM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

Rebased patches attached. Because Dilip complained earlier today about
clauses of the form (const op var) not causing partition-pruning, I've
added code to commute the clause where it is required. Some other
previously mentioned limitations remain -- no handling of OR clauses, no
elimination of redundant clauses for given partitioning column, etc.

A note about 0001: this patch overlaps with
0003-Canonical-partition-scheme.patch from the partitionwise-join patch
series that Ashutosh Bapat posted yesterday [1].

It doesn't merely overlap; it's obviously a derivative work, and the
commit message in your version should credit all the authors.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#17Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#16)
Re: path toward faster partition pruning

On Sat, Sep 16, 2017 at 4:04 AM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Sep 15, 2017 at 4:50 AM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

Rebased patches attached. Because Dilip complained earlier today about
clauses of the form (const op var) not causing partition-pruning, I've
added code to commute the clause where it is required. Some other
previously mentioned limitations remain -- no handling of OR clauses, no
elimination of redundant clauses for given partitioning column, etc.

A note about 0001: this patch overlaps with
0003-Canonical-partition-scheme.patch from the partitionwise-join patch
series that Ashutosh Bapat posted yesterday [1].

It doesn't merely overlap; it's obviously a derivative work,

Yes it is. I noted that upthread [1]/messages/by-id/0e829199-a43c-2a66-b966-89a0020a6cd4@lab.ntt.co.jp that most of these are derived
from Ashutosh's patch on his suggestion. I guess I should have
repeated that in this message too, sorry.

and the
commit message in your version should credit all the authors.

That was a mistake on my part, too. Will be careful hereon.

Thanks,
Amit

[1]: /messages/by-id/0e829199-a43c-2a66-b966-89a0020a6cd4@lab.ntt.co.jp

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Dilip Kumar
dilipbalaut@gmail.com
In reply to: Amit Langote (#15)
Re: path toward faster partition pruning

On Fri, Sep 15, 2017 at 2:20 PM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

On 2017/09/15 11:16, Amit Langote wrote:

Thanks for the updated patch. I was going through the logic of
get_rel_partitions in 0002 as almost similar functionality will be
required by runtime partition pruning on which Beena is working. The
only difference is that here we are processing the
"rel->baserestrictinfo" and in case of runtime pruning, we also need
to process join clauses which are pushed down to appendrel.

So can we make some generic logic which can be used for both the patches.

So basically, we need to do two changes

1. In get_rel_partitions instead of processing the
"rel->baserestrictinfo" we can take clause list as input that way we
can pass any clause list to this function.

2. Don't call "get_partitions_for_keys" routine from the
"get_rel_partitions", instead, get_rel_partitions can just prepare
minkey, maxkey and the caller of the get_rel_partitions can call
get_partitions_for_keys, because for runtime pruning we need to call
get_partitions_for_keys at runtime.

After these changes also there will be one problem that the
get_partitions_for_keys is directly fetching the "rightop->constvalue"
whereas, for runtime pruning, we need to store rightop itself and
calculate the value at runtime by param evaluation, I haven't yet
thought how can we make this last part generic.

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Dilip Kumar
dilipbalaut@gmail.com
In reply to: Dilip Kumar (#18)
Re: path toward faster partition pruning

I have done some refactoring of the code where I have moved the code
of getting the matching clause into the separate function so that it
can fetch the matching clause from any set of given restriction list.

It can be applied on top of 0002-WIP:
planner-side-changes-for-partition-pruning.patch

On Sat, Sep 16, 2017 at 3:13 PM, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Fri, Sep 15, 2017 at 2:20 PM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

On 2017/09/15 11:16, Amit Langote wrote:

Thanks for the updated patch. I was going through the logic of
get_rel_partitions in 0002 as almost similar functionality will be
required by runtime partition pruning on which Beena is working. The
only difference is that here we are processing the
"rel->baserestrictinfo" and in case of runtime pruning, we also need
to process join clauses which are pushed down to appendrel.

So can we make some generic logic which can be used for both the patches.

So basically, we need to do two changes

1. In get_rel_partitions instead of processing the
"rel->baserestrictinfo" we can take clause list as input that way we
can pass any clause list to this function.

2. Don't call "get_partitions_for_keys" routine from the
"get_rel_partitions", instead, get_rel_partitions can just prepare
minkey, maxkey and the caller of the get_rel_partitions can call
get_partitions_for_keys, because for runtime pruning we need to call
get_partitions_for_keys at runtime.

After these changes also there will be one problem that the
get_partitions_for_keys is directly fetching the "rightop->constvalue"
whereas, for runtime pruning, we need to store rightop itself and
calculate the value at runtime by param evaluation, I haven't yet
thought how can we make this last part generic.

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

Attachments:

0002-refactor_get_rel_partition.patchapplication/octet-stream; name=0002-refactor_get_rel_partition.patchDownload+40-31
#20Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Dilip Kumar (#18)
Re: path toward faster partition pruning

Hi Dilip.

Thanks for looking at the patches and the comments.

On 2017/09/16 18:43, Dilip Kumar wrote:

On Fri, Sep 15, 2017 at 2:20 PM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:

On 2017/09/15 11:16, Amit Langote wrote:

Thanks for the updated patch. I was going through the logic of
get_rel_partitions in 0002 as almost similar functionality will be
required by runtime partition pruning on which Beena is working. The
only difference is that here we are processing the
"rel->baserestrictinfo" and in case of runtime pruning, we also need
to process join clauses which are pushed down to appendrel.

Yeah, I agree with the point you seem to be making that
get_rel_partitions() covers a lot of functionality, which it would be nice
to break down into reusable function(s) with suitable signature(s) that
the executor will also be able to use.

Your proposed refactoring patch down-thread seems to be a good step in
that direction. Thanks for working on it.

So can we make some generic logic which can be used for both the patches.

So basically, we need to do two changes

1. In get_rel_partitions instead of processing the
"rel->baserestrictinfo" we can take clause list as input that way we
can pass any clause list to this function.

2. Don't call "get_partitions_for_keys" routine from the
"get_rel_partitions", instead, get_rel_partitions can just prepare
minkey, maxkey and the caller of the get_rel_partitions can call
get_partitions_for_keys, because for runtime pruning we need to call
get_partitions_for_keys at runtime.

It's not clear to me whether get_rel_partitions() itself, as it is, is
callable from outside the planner, because its signature contains
RelOptInfo. We have the RelOptInfo in the signature, because we want to
mark certain fields in it so that latter planning steps can use them. So,
get_rel_partitions()'s job is not just to match clauses and find
partitions, but also to perform certain planner-specific tasks of
generating information that the later planning steps will want to use.
That may turn out to be unnecessary, but until we know that, let's not try
to export get_rel_partitions() itself out of the planner.

OTOH, the function that your refactoring patch separates out to match
clauses to partition keys and extract bounding values seems reusable
outside the planner and we should export it in such a way that it can be
used in the executor. Then, the hypothetical executor function that does
the pruning will first call the planner's clause-matching function,
followed by calling get_partitions_for_keys() in partition.c to get the
selected partitions.

We should be careful when designing the interface of the exported function
to make sure it's not bound to the planner. Your patch still maintains
the RelOptInfo in the signature of the clause-matching function, which the
executor pruning function won't have access to.

After these changes also there will be one problem that the
get_partitions_for_keys is directly fetching the "rightop->constvalue"
whereas, for runtime pruning, we need to store rightop itself and
calculate the value at runtime by param evaluation, I haven't yet
thought how can we make this last part generic.

I don't think any code introduced by the patch in partition.c itself looks
inside OpExpr (or any type of clause for that matter). That is, I don't
see where get_partitions_for_keys() is looking at rightop->constvalue.
All it receives to work with are arrays of Datums and some other relevant
information like inclusivity, nullness, etc.

By the way, I'm now rebasing these patches on top of [1]https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=9140cf826 and will try to
merge your refactoring patch in some appropriate way. Will post more
tomorrow.

Thanks,
Amit

[1]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=9140cf826

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#21Dilip Kumar
dilipbalaut@gmail.com
In reply to: Amit Langote (#20)
#22Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Dilip Kumar (#21)
#23Dilip Kumar
dilipbalaut@gmail.com
In reply to: Amit Langote (#22)
#24Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#15)
#25Robert Haas
robertmhaas@gmail.com
In reply to: Jesper Pedersen (#24)
#26Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Robert Haas (#25)
#27Robert Haas
robertmhaas@gmail.com
In reply to: Jesper Pedersen (#26)
#28David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#20)
#29Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#27)
#30Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#28)
#31Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Jesper Pedersen (#24)
#32Amul Sul
sulamul@gmail.com
In reply to: Amit Langote (#29)
#33Dilip Kumar
dilipbalaut@gmail.com
In reply to: Amit Langote (#30)
#34Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Dilip Kumar (#33)
#35Dilip Kumar
dilipbalaut@gmail.com
In reply to: Amit Langote (#34)
#36David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#30)
#37Robert Haas
robertmhaas@gmail.com
In reply to: David Rowley (#36)
#38Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#37)
#39Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#38)
#40Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#36)
#41Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#30)
#42Rajkumar Raghuwanshi
rajkumar.raghuwanshi@enterprisedb.com
In reply to: Amit Langote (#41)
#43Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Rajkumar Raghuwanshi (#42)
#44Rajkumar Raghuwanshi
rajkumar.raghuwanshi@enterprisedb.com
In reply to: Amit Langote (#43)
#45Beena Emerson
memissemerson@gmail.com
In reply to: Rajkumar Raghuwanshi (#44)
#46Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Beena Emerson (#45)
#47Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#46)
#48Beena Emerson
memissemerson@gmail.com
In reply to: Amit Langote (#47)
#49Beena Emerson
memissemerson@gmail.com
In reply to: Amit Langote (#47)
#50Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Beena Emerson (#48)
#51Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#50)
#52Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#51)
#53Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#52)
#54Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#53)
#55Rajkumar Raghuwanshi
rajkumar.raghuwanshi@enterprisedb.com
In reply to: Amit Langote (#50)
#56Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Rajkumar Raghuwanshi (#55)
#57Rajkumar Raghuwanshi
rajkumar.raghuwanshi@enterprisedb.com
In reply to: Amit Langote (#56)
#58Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Rajkumar Raghuwanshi (#57)
#59Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#58)
#60Rajkumar Raghuwanshi
rajkumar.raghuwanshi@enterprisedb.com
In reply to: Amit Langote (#59)
#61Dilip Kumar
dilipbalaut@gmail.com
In reply to: Amit Langote (#59)
#62Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Rajkumar Raghuwanshi (#60)
#63Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Dilip Kumar (#61)
#64David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#63)
#65David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#63)
#66David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#65)
#67David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#63)
#68Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#65)
#69Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#66)
#70David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#68)
#71Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#67)
#72Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#70)
#73David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#72)
#74David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#73)
#75Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#73)
#76David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#73)
#77Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#74)
#78Rajkumar Raghuwanshi
rajkumar.raghuwanshi@enterprisedb.com
In reply to: Amit Langote (#72)
#79Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Rajkumar Raghuwanshi (#78)
#80Amul Sul
sulamul@gmail.com
In reply to: Amit Langote (#72)
#81Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amul Sul (#80)
#82Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Amit Langote (#81)
#83Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Kyotaro Horiguchi (#82)
#84Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Kyotaro Horiguchi (#83)
#85Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Kyotaro Horiguchi (#84)
#86David Rowley
dgrowleyml@gmail.com
In reply to: Kyotaro Horiguchi (#82)
#87Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Kyotaro Horiguchi (#82)
#88David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#87)
#89Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#88)
#90Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: David Rowley (#88)
#91David Rowley
dgrowleyml@gmail.com
In reply to: Kyotaro Horiguchi (#90)
#92Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#76)
#93David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#92)
#94Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#93)
#95Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Amit Langote (#87)
#96Rajkumar Raghuwanshi
rajkumar.raghuwanshi@enterprisedb.com
In reply to: Amit Langote (#92)
#97Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Rajkumar Raghuwanshi (#96)
#98Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#97)
#99Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Jesper Pedersen (#98)
#100Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#99)
#101Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Amit Langote (#97)
#102Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Jesper Pedersen (#100)
#103Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#97)
#104Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#103)
#105Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#103)
#106Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#104)
#107Michael Paquier
michael@paquier.xyz
In reply to: Amit Langote (#106)
#108Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Michael Paquier (#107)
#109David Rowley
dgrowleyml@gmail.com
In reply to: Robert Haas (#104)
#110Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#109)
#111Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Kyotaro Horiguchi (#101)
#112David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#111)
#113Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#112)
#114David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#111)
#115David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#114)
#116David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#111)
#117David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#114)
#118Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#114)
#119Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#118)
#120David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#119)
#121David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#119)
#122Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#119)
#123Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#121)
#124David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#123)
#125Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#122)
#126Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#124)
#127David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#126)
#128David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#127)
#129Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#126)
#130Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Alvaro Herrera (#129)
#131Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#126)
#132Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#126)
#133David Rowley
dgrowleyml@gmail.com
In reply to: Jesper Pedersen (#132)
#134David Rowley
dgrowleyml@gmail.com
In reply to: Jesper Pedersen (#132)
#135Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: David Rowley (#134)
#136Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#131)
#137David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#136)
#138David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#136)
#139David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#136)
#140Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#127)
#141Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Ashutosh Bapat (#130)
#142David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#140)
#143David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#142)
#144Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#142)
#145David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#144)
#146Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#145)
#147David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#139)
#148Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#147)
#149David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#148)
#150Robert Haas
robertmhaas@gmail.com
In reply to: David Rowley (#145)
#151Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#145)
#152David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#151)
#153David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#151)
#154Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#152)
#155David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#153)
#156Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#155)
#157David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#156)
#158David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#157)
#159Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#158)
#160David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#159)
#161Andres Freund
andres@anarazel.de
In reply to: Amit Langote (#159)
#162Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Andres Freund (#161)
#163Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Kyotaro Horiguchi (#162)
#164David Rowley
dgrowleyml@gmail.com
In reply to: Kyotaro Horiguchi (#162)
#165David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#160)
#166Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#165)
#167David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#166)
#168Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#165)
#169Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#168)
#170Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Jesper Pedersen (#169)
#171Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Amit Langote (#170)
#172Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#170)
#173Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Kyotaro Horiguchi (#171)
#174David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#173)
#175Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#173)
#176Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#175)
#177Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#174)
#178Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#176)
#179Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#178)
#180Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#179)
#181Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#180)
#182Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Amit Langote (#180)
#183Robert Haas
robertmhaas@gmail.com
In reply to: Ashutosh Bapat (#182)
#184Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Robert Haas (#183)
#185Robert Haas
robertmhaas@gmail.com
In reply to: Ashutosh Bapat (#184)
#186Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#181)
#187Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Robert Haas (#183)
#188Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Robert Haas (#185)
#189Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Ashutosh Bapat (#188)
#190Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#180)
#191Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#187)
#192Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#190)
#193Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#191)
#194Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Amit Langote (#191)
#195Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: David Rowley (#164)
#196Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#193)
#197Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#192)
#198David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#177)
#199David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#197)
#200David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#198)
#201David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#199)
#202Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#198)
#203Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#199)
#204David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#203)
#205Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#204)
#206Rajkumar Raghuwanshi
rajkumar.raghuwanshi@enterprisedb.com
In reply to: Amit Langote (#205)
#207Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Rajkumar Raghuwanshi (#206)
#208David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#207)
#209Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#208)
#210David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#209)
#211Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#210)
#212David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#211)
#213Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#212)
#214David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#213)
#215Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#214)
#216Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#211)
#217Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#216)
#218Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#217)
#219Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#218)
#220Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#219)
#221Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#219)
#222Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#221)
#223Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Amit Langote (#222)
#224Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Amit Langote (#220)
#225David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#220)
#226Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#222)
#227Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Ashutosh Bapat (#223)
#228Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#226)
#229Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Ashutosh Bapat (#224)
#230Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Amit Langote (#227)
#231Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#220)
#232Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#229)
#233David Rowley
dgrowleyml@gmail.com
In reply to: Robert Haas (#232)
#234Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#231)
#235Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#232)
#236Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#233)
#237Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#234)
#238Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#235)
#239David Rowley
dgrowleyml@gmail.com
In reply to: Robert Haas (#232)
#240David Rowley
dgrowleyml@gmail.com
In reply to: Robert Haas (#238)
#241Robert Haas
robertmhaas@gmail.com
In reply to: David Rowley (#239)
#242David Rowley
dgrowleyml@gmail.com
In reply to: Robert Haas (#238)
#243Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#237)
#244Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#238)
#245Robert Haas
robertmhaas@gmail.com
In reply to: David Rowley (#242)
#246David Rowley
dgrowleyml@gmail.com
In reply to: Robert Haas (#245)
#247Robert Haas
robertmhaas@gmail.com
In reply to: David Rowley (#246)
#248Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#244)
#249Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#248)
#250Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#249)
#251Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#249)
#252Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#251)
#253David Rowley
dgrowleyml@gmail.com
In reply to: Jesper Pedersen (#250)
#254Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#252)
#255David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#249)
#256Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#255)
#257Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#255)
#258David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#257)
#259Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#258)
#260David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#259)
#261Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#257)
#262David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#261)
#263Robert Haas
robertmhaas@gmail.com
In reply to: Amit Langote (#261)
#264Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#262)
#265David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#261)
#266Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#265)
#267Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#263)
#268David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#266)
#269David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#268)
#270David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#269)
#271Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#270)
#272Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#267)
#273David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#271)
#274Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#272)
#275Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#272)
#276Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#275)
#277Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Jesper Pedersen (#274)
#278David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#272)
#279Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#278)
#280Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#279)
#281David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#279)
#282Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Amit Langote (#280)
#283Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Jesper Pedersen (#282)
#284David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#283)
#285Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Amit Langote (#283)
#286Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Tomas Vondra (#285)
#287Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#284)
#288David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#287)
#289David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#288)
#290Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: David Rowley (#288)
#291David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#289)
#292David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#287)
#293Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#291)
#294Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#292)
#295David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#294)
#296Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#295)
#297David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#296)
#298David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#297)
#299David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#298)
#300David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#299)
#301Tom Lane
tgl@sss.pgh.pa.us
In reply to: David Rowley (#300)
#302David Rowley
dgrowleyml@gmail.com
In reply to: Tom Lane (#301)
#303Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#299)
#304Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#303)
#305David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#303)
#306David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#304)
#307David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#304)
#308Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: David Rowley (#307)
#309Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Jesper Pedersen (#308)
#310Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Amit Langote (#309)
#311Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#309)
#312Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#311)
#313Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#310)
#314David Rowley
dgrowleyml@gmail.com
In reply to: Alvaro Herrera (#312)
#315David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#314)
#316Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#312)
#317Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#313)
#318Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#316)
#319Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: David Rowley (#314)
#320Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#312)
#321Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#319)
#322Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#321)
#323Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#319)
#324Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#316)
#325Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#324)
#326Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#325)
#327Jesper Pedersen
jesper.pedersen@redhat.com
In reply to: Alvaro Herrera (#325)
#328Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#325)
#329Andres Freund
andres@anarazel.de
In reply to: Alvaro Herrera (#328)
#330Robert Haas
robertmhaas@gmail.com
In reply to: Alvaro Herrera (#318)
#331Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Robert Haas (#330)
#332Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#328)
#333David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#332)
#334David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#333)
#335Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#334)
#336David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#335)
#337David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#334)
#338Andres Freund
andres@anarazel.de
In reply to: David Rowley (#337)
#339Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: David Rowley (#336)
#340David Rowley
dgrowleyml@gmail.com
In reply to: Andres Freund (#338)
#341David Rowley
dgrowleyml@gmail.com
In reply to: Ashutosh Bapat (#339)
#342Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: David Rowley (#341)
#343Andres Freund
andres@anarazel.de
In reply to: David Rowley (#340)
#344David Rowley
dgrowleyml@gmail.com
In reply to: Andres Freund (#343)
#345David Rowley
dgrowleyml@gmail.com
In reply to: Ashutosh Bapat (#342)
#346Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: David Rowley (#345)
#347Tom Lane
tgl@sss.pgh.pa.us
In reply to: David Rowley (#345)
#348David Rowley
dgrowleyml@gmail.com
In reply to: Tom Lane (#347)
#349Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#347)
#350David Rowley
dgrowleyml@gmail.com
In reply to: Tom Lane (#347)
#351Andres Freund
andres@anarazel.de
In reply to: David Rowley (#350)
#352David Rowley
dgrowleyml@gmail.com
In reply to: Andres Freund (#329)
#353David Rowley
dgrowleyml@gmail.com
In reply to: Andres Freund (#351)
#354David Rowley
dgrowleyml@gmail.com
In reply to: Andres Freund (#343)
#355Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Andres Freund (#351)
#356Tom Lane
tgl@sss.pgh.pa.us
In reply to: Amit Langote (#355)
#357Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Tom Lane (#356)
#358Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Andres Freund (#351)
#359Andres Freund
andres@anarazel.de
In reply to: Alvaro Herrera (#358)
#360Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Andres Freund (#359)
#361David Rowley
dgrowleyml@gmail.com
In reply to: Alvaro Herrera (#328)
#362Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#361)
#363Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#347)
#364Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Robert Haas (#363)
#365Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Ashutosh Bapat (#364)
#366David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#365)
#367Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: David Rowley (#366)
#368Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Ashutosh Bapat (#367)
#369Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#366)
#370David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#369)
#371Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#370)
#372Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Amit Langote (#371)
#373David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#371)
#374Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#371)
#375Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#374)
#376Robert Haas
robertmhaas@gmail.com
In reply to: Alvaro Herrera (#374)
#377Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Robert Haas (#376)
#378David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#377)
#379Ashutosh Bapat
ashutosh.bapat@enterprisedb.com
In reply to: Amit Langote (#377)
#380Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Robert Haas (#376)
#381Robert Haas
robertmhaas@gmail.com
In reply to: Alvaro Herrera (#380)
#382Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#375)
#383Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#382)
#384Marina Polyakova
m.polyakova@postgrespro.ru
In reply to: Amit Langote (#383)
#385Michael Paquier
michael@paquier.xyz
In reply to: Marina Polyakova (#384)
#386Marina Polyakova
m.polyakova@postgrespro.ru
In reply to: Michael Paquier (#385)
#387Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#385)
#388Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Michael Paquier (#387)
#389Michael Paquier
michael@paquier.xyz
In reply to: Amit Langote (#388)
#390Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Michael Paquier (#387)
#391Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#390)
#392Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#391)
#393Michael Paquier
michael@paquier.xyz
In reply to: Alvaro Herrera (#391)
#394Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Michael Paquier (#393)
#395David Rowley
dgrowleyml@gmail.com
In reply to: Amit Langote (#394)
#396Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: David Rowley (#395)
#397Michael Paquier
michael@paquier.xyz
In reply to: Amit Langote (#396)
#398Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Michael Paquier (#397)
#399Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Langote (#396)
#400Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Marina Polyakova (#384)
#401Michael Paquier
michael@paquier.xyz
In reply to: Alvaro Herrera (#398)
#402Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Alvaro Herrera (#399)
#403Marina Polyakova
m.polyakova@postgrespro.ru
In reply to: Alvaro Herrera (#400)