Re: BUG #15832: COPY into a partitioned table breaks its indexes

From: Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com>
To: harukat(at)sraoss(dot)co(dot)jp, pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: Andres Freund <andres(at)anarazel(dot)de>, David Rowley <david(dot)rowley(at)2ndquadrant(dot)com>
Subject: Re: BUG #15832: COPY into a partitioned table breaks its indexes
Date: 2019-06-04 09:19:48
Message-ID: CAE9k0P=BLBrvRcjnY7B=ET68euL9M38ULSszY8f_O8U4A0FvXQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,

Thanks for finding the bug.

The issue here is that in case of partitioned table, "
*estate->es_result_relation_info*" is not pointing to the correct
resultRelInfo. It is actually pointing to the last partition rather than
the partition whose buffer is being flushed. For e.g. consider the
following case.

*create table part_tab (a int primary key, b text) partition by range
(a);create table part_tab_1 partition of part_tab for values from (1) to
(2);create table part_tab_2 partition of part_tab for values from (2) to
(3);create table part_tab_3 partition of part_tab for values from (3) to
(4);insert into part_tab values (1, 'str1'), (2, 'str2'), (3, 'str3');*

*copy (select * from part_tab) to '/tmp/multi_insert_part_tab.csv'
csv;truncate table part_tab;copy part_tab from
'/tmp/multi_insert_part_tab.csv' csv;*

When above COPY FROM command is executed into the partitioned table
(part_tab), for the first record i.e. (1, 'str1')
'estate->es_result_relation_info' gets updated with the resultRelInfo of
partition-1 as the first record fits into partition 1. Similarly, for the
second record, 'estate->es_result_relation_info' gets updated with the
resultRelInfo of partition-2 and finally for the last record (i.e. (3,
'str3')), 'estate->es_result_relation_info' gets updated with the
resultRelInfo of partition-3. Eventually, when all the records are read and
the buffers are flushed one by one, we also do the index insertion (as
there exists an index on the partitons) but during index insertion, we
refer to the resultRelInfo in estate which is actually pointing to the *last
partition* i.e. *partition-3* in our case.

During heap insertion we actually refer to *buffer->resultRelInfo* which is
always updated and that's the reason heap insertion works fine but not the
index insertion.

Attached patch fixes the issue. It basically updates
*estate->es_result_relation_info* with the correct resultRelInfo in
CopyMultiInsertBufferFlush(). I've also added the test-case for it.

Andres, David, do you all agree with above analysis and the proposed fix ?

--
With Regards,
Ashutosh Sharma
EnterpriseDB:http://www.enterprisedb.com

Attachment Content-Type Size
fix_copyfrom_partitioned_table_index.patch text/x-patch 2.9 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message David Rowley 2019-06-05 06:41:00 Re: BUG #15832: COPY into a partitioned table breaks its indexes
Previous Message Kumar Harsh 2019-06-04 08:37:06 The default timezone is being shown as UCT instead of UTC