[
https://issues.apache.org/jira/browse/HIVE-16832?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Eugene Koifman updated HIVE-16832:
----------------------------------
Description:
{noformat}
create table AcidTablePart(a int, b int) partitioned by (p string) clustered
by (a) into 2 buckets stored as orc TBLPROPERTIES ('transactional'='true');
create temporary table if not exists data1 (x int);
insert into data1 values (1),(2),(1);
from data1
insert into AcidTablePart partition(p) select 0, 0, 'p' || x
insert into AcidTablePart partition(p='p1') select 0, 1
{noformat}
Each branch of this multi-insert create a row in partition p1/bucket0 with
ROW__ID=(1,0,0).
The same can happen when running SQL Merge (HIVE-10924) statement that has both
Insert and Update clauses when target table has
_'transactional'='true','transactional_properties'='default'_ (see
HIVE-14035). This is so because Merge is internally run as a multi-insert
statement.
The solution relies on statement ID introduced in HIVE-11030. Each Insert
clause of a multi-insert is gets a unique ID.
The ROW__ID.bucketId now becomes a bit packed triplet (format version,
bucketId, statementId).
(Since ORC stores field names in the data file we can't rename
ROW__ID.bucketId).
This ensures that there are no collisions and retains desired sort properties
of ROW__ID.
In particular _SortedDynPartitionOptimizer_ works w/o any changes even in cases
where there fewer reducers than buckets.
> duplicate ROW__ID possible in multi insert into transactional table
> -------------------------------------------------------------------
>
> Key: HIVE-16832
> URL: https://issues.apache.org/jira/browse/HIVE-16832
> Project: Hive
> Issue Type: Bug
> Components: Transactions
> Affects Versions: 2.2.0
> Reporter: Eugene Koifman
> Assignee: Eugene Koifman
> Priority: Critical
> Attachments: HIVE-16832.01.patch, HIVE-16832.03.patch,
> HIVE-16832.04.patch, HIVE-16832.05.patch, HIVE-16832.06.patch,
> HIVE-16832.08.patch, HIVE-16832.09.patch, HIVE-16832.10.patch,
> HIVE-16832.11.patch, HIVE-16832.14.patch, HIVE-16832.15.patch,
> HIVE-16832.16.patch, HIVE-16832.17.patch, HIVE-16832.18.patch,
> HIVE-16832.19.patch, HIVE-16832.20.patch, HIVE-16832.20.patch
>
>
> {noformat}
> create table AcidTablePart(a int, b int) partitioned by (p string) clustered
> by (a) into 2 buckets stored as orc TBLPROPERTIES ('transactional'='true');
> create temporary table if not exists data1 (x int);
> insert into data1 values (1),(2),(1);
> from data1
> insert into AcidTablePart partition(p) select 0, 0, 'p' || x
> insert into AcidTablePart partition(p='p1') select 0, 1
> {noformat}
> Each branch of this multi-insert create a row in partition p1/bucket0 with
> ROW__ID=(1,0,0).
> The same can happen when running SQL Merge (HIVE-10924) statement that has
> both Insert and Update clauses when target table has
> _'transactional'='true','transactional_properties'='default'_ (see
> HIVE-14035). This is so because Merge is internally run as a multi-insert
> statement.
> The solution relies on statement ID introduced in HIVE-11030. Each Insert
> clause of a multi-insert is gets a unique ID.
> The ROW__ID.bucketId now becomes a bit packed triplet (format version,
> bucketId, statementId).
> (Since ORC stores field names in the data file we can't rename
> ROW__ID.bucketId).
> This ensures that there are no collisions and retains desired sort properties
> of ROW__ID.
> In particular _SortedDynPartitionOptimizer_ works w/o any changes even in
> cases where there fewer reducers than buckets.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)