There are two known problems in the test case.
1. When nextval() is pushed down to the remote nodes, the coordinator session
won't have seen a nextval() invokation and hence a subsequent currval() will
throw an ERROR or return a stale value.
2. When nextval() is pushed down to the remote nodes and a set of rows are
fetched (either ordered or otherwise), the results may be somewhat inconsistent
because each node will run nextval() concurrently and hence the ordering will
change depending on who runs when.
For now, change the queries to force nextval() evaluation on the coordinator.
Also move the original test cases to xl_known_bugs test case and we also have
an internal issue open to track this problem.
-- with ORDER BY and LIMIT.
--
create temp sequence testseq;
+-- XL: The query has been slightly modified to suit XL's execution mechanism
+-- when nextval is pushed down to the remote node. Using a subquery gives
+-- consistent results and also ensures currval() returns correct value (since
+-- nextval gets executed on the coordinator). The original two tests are
+-- copied to xl_known_bugs test case
explain (verbose, costs off)
-select unique1, unique2, nextval('testseq')
- from tenk1 order by unique2 limit 10;
- QUERY PLAN
-----------------------------------------------------------------------------
- Limit
- Output: unique1, unique2, (nextval('testseq'::regclass))
- -> Remote Subquery Scan on all (datanode_1,datanode_2)
- Output: unique1, unique2, nextval('testseq'::regclass)
- Sort Key: tenk1.unique2
- -> Limit
- Output: unique1, unique2, (nextval('testseq'::regclass))
- -> Index Scan using tenk1_unique2 on public.tenk1
- Output: unique1, unique2, nextval('testseq'::regclass)
-(9 rows)
+select *, nextval('testseq') from
+ (select unique1, unique2 from tenk1 order by unique2 limit 10) x;
+ QUERY PLAN
+------------------------------------------------------------------------
+ Subquery Scan on x
+ Output: x.unique1, x.unique2, nextval('testseq'::regclass)
+ -> Limit
+ Output: tenk1.unique1, tenk1.unique2
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ Output: tenk1.unique1, tenk1.unique2
+ Sort Key: tenk1.unique2
+ -> Limit
+ Output: tenk1.unique1, tenk1.unique2
+ -> Index Scan using tenk1_unique2 on public.tenk1
+ Output: tenk1.unique1, tenk1.unique2
+(11 rows)
-select unique1, unique2, nextval('testseq')
- from tenk1 order by unique2 limit 10;
+select *, nextval('testseq') from
+ (select unique1, unique2 from tenk1 order by unique2 limit 10) x;
unique1 | unique2 | nextval
---------+---------+---------
8800 | 0 | 1
(1 row)
explain (verbose, costs off)
-select unique1, unique2, nextval('testseq')
- from tenk1 order by tenthous limit 10;
+select *, nextval('testseq') from
+ (select unique1, unique2 from tenk1 order by tenthous limit 10) x;
QUERY PLAN
--------------------------------------------------------------------------------------
- Limit
- Output: unique1, unique2, (nextval('testseq'::regclass)), tenthous
- -> Remote Subquery Scan on all (datanode_1,datanode_2)
- Output: unique1, unique2, nextval('testseq'::regclass), tenthous
- Sort Key: tenk1.tenthous
- -> Limit
- Output: unique1, unique2, (nextval('testseq'::regclass)), tenthous
- -> Result
- Output: unique1, unique2, nextval('testseq'::regclass), tenthous
+ Subquery Scan on x
+ Output: x.unique1, x.unique2, nextval('testseq'::regclass)
+ -> Limit
+ Output: tenk1.unique1, tenk1.unique2, tenk1.tenthous
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ Output: tenk1.unique1, tenk1.unique2, tenk1.tenthous
+ Sort Key: tenk1.tenthous
+ -> Limit
+ Output: tenk1.unique1, tenk1.unique2, tenk1.tenthous
-> Sort
- Output: unique1, unique2, tenthous
+ Output: tenk1.unique1, tenk1.unique2, tenk1.tenthous
Sort Key: tenk1.tenthous
-> Seq Scan on public.tenk1
- Output: unique1, unique2, tenthous
+ Output: tenk1.unique1, tenk1.unique2, tenk1.tenthous
(14 rows)
-select unique1, unique2, nextval('testseq')
- from tenk1 order by tenthous limit 10;
+select *, nextval('testseq') from
+ (select unique1, unique2 from tenk1 order by tenthous limit 10) x;
unique1 | unique2 | nextval
---------+---------+---------
0 | 9998 | 11
drop table xl_tmp;
drop table xl_onek;
------------------------------------------
+-- When nextval is pushed down the datanode, currval may not be set on the
+-- coordinator (or can be stale). This case is picked up from 'limit' test case,
+-- which is modified to suit XL's current behaviour
+create temp sequence testseq;
+explain (verbose, costs off)
+select unique1, unique2, nextval('testseq')
+ from tenk1 order by unique2 limit 10;
+ QUERY PLAN
+----------------------------------------------------------------------------
+ Limit
+ Output: unique1, unique2, (nextval('testseq'::regclass))
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ Output: unique1, unique2, nextval('testseq'::regclass)
+ Sort Key: tenk1.unique2
+ -> Limit
+ Output: unique1, unique2, (nextval('testseq'::regclass))
+ -> Index Scan using tenk1_unique2 on public.tenk1
+ Output: unique1, unique2, nextval('testseq'::regclass)
+(9 rows)
+
+select unique1, unique2, nextval('testseq')
+ from tenk1 order by unique2 limit 10;
+ unique1 | unique2 | nextval
+---------+---------+---------
+ 8800 | 0 | 1
+ 1891 | 1 | 2
+ 3420 | 2 | 3
+ 9850 | 3 | 4
+ 7164 | 4 | 5
+ 8009 | 5 | 6
+ 5057 | 6 | 7
+ 6701 | 7 | 8
+ 4321 | 8 | 9
+ 3043 | 9 | 10
+(10 rows)
+
+select currval('testseq');
+ currval
+---------
+ 10
+(1 row)
+
+explain (verbose, costs off)
+select unique1, unique2, nextval('testseq')
+ from tenk1 order by tenthous limit 10;
+ QUERY PLAN
+--------------------------------------------------------------------------------------
+ Limit
+ Output: unique1, unique2, (nextval('testseq'::regclass)), tenthous
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ Output: unique1, unique2, nextval('testseq'::regclass), tenthous
+ Sort Key: tenk1.tenthous
+ -> Limit
+ Output: unique1, unique2, (nextval('testseq'::regclass)), tenthous
+ -> Result
+ Output: unique1, unique2, nextval('testseq'::regclass), tenthous
+ -> Sort
+ Output: unique1, unique2, tenthous
+ Sort Key: tenk1.tenthous
+ -> Seq Scan on public.tenk1
+ Output: unique1, unique2, tenthous
+(14 rows)
+
+select unique1, unique2, nextval('testseq')
+ from tenk1 order by tenthous limit 10;
+ unique1 | unique2 | nextval
+---------+---------+---------
+ 0 | 9998 | 11
+ 1 | 2838 | 12
+ 2 | 2716 | 13
+ 3 | 5679 | 14
+ 4 | 1621 | 15
+ 5 | 5557 | 16
+ 6 | 2855 | 17
+ 7 | 8518 | 18
+ 8 | 5435 | 19
+ 9 | 4463 | 20
+(10 rows)
+
+select currval('testseq');
+ currval
+---------
+ 20
+(1 row)
--
create temp sequence testseq;
-
+-- XL: The query has been slightly modified to suit XL's execution mechanism
+-- when nextval is pushed down to the remote node. Using a subquery gives
+-- consistent results and also ensures currval() returns correct value (since
+-- nextval gets executed on the coordinator). The original two tests are
+-- copied to xl_known_bugs test case
explain (verbose, costs off)
-select unique1, unique2, nextval('testseq')
- from tenk1 order by unique2 limit 10;
+select *, nextval('testseq') from
+ (select unique1, unique2 from tenk1 order by unique2 limit 10) x;
-select unique1, unique2, nextval('testseq')
- from tenk1 order by unique2 limit 10;
+select *, nextval('testseq') from
+ (select unique1, unique2 from tenk1 order by unique2 limit 10) x;
select currval('testseq');
explain (verbose, costs off)
-select unique1, unique2, nextval('testseq')
- from tenk1 order by tenthous limit 10;
+select *, nextval('testseq') from
+ (select unique1, unique2 from tenk1 order by tenthous limit 10) x;
-select unique1, unique2, nextval('testseq')
- from tenk1 order by tenthous limit 10;
+select *, nextval('testseq') from
+ (select unique1, unique2 from tenk1 order by tenthous limit 10) x;
select currval('testseq');
drop table xl_onek;
------------------------------------------
+
+-- When nextval is pushed down the datanode, currval may not be set on the
+-- coordinator (or can be stale). This case is picked up from 'limit' test case,
+-- which is modified to suit XL's current behaviour
+create temp sequence testseq;
+
+explain (verbose, costs off)
+select unique1, unique2, nextval('testseq')
+ from tenk1 order by unique2 limit 10;
+
+select unique1, unique2, nextval('testseq')
+ from tenk1 order by unique2 limit 10;
+
+select currval('testseq');
+
+explain (verbose, costs off)
+select unique1, unique2, nextval('testseq')
+ from tenk1 order by tenthous limit 10;
+
+select unique1, unique2, nextval('testseq')
+ from tenk1 order by tenthous limit 10;