dolphin: add null first policy api
This commit is contained in:
@ -870,6 +870,12 @@ job_queue_processes = 10 # Number of concurrent jobs, optional: [0..1000]
|
||||
#ss_fi_process_fault_entries = ''
|
||||
#ss_fi_custom_fault_entries = ''
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# DOLPHIN OPTIONS
|
||||
#------------------------------------------------------------------------------
|
||||
dolphin.nulls_minimal_policy = on # the inverse of the default configuration value ! do not change !
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# UWAL OPTIONS
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -385,9 +385,9 @@ void partitionKeyCompareForRouting(Const **partkey_value, Const **partkey_bound,
|
||||
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE),
|
||||
errmsg("null value can not be compared with null value.")));
|
||||
} else if (kv->constisnull) {
|
||||
compare = DB_IS_CMPT(B_FORMAT) ? -1 : 1;
|
||||
compare = CheckPluginNullsPolicy() ? -1 : 1;
|
||||
} else {
|
||||
compare = DB_IS_CMPT(B_FORMAT) ? 1 : -1;
|
||||
compare = CheckPluginNullsPolicy() ? 1 : -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3973,9 +3973,17 @@ static void make_partiterator_pathkey(
|
||||
* we do partitionkey comparison just as ''order by ASC NULL LAST'', and pathkey
|
||||
* must follow the same rules. If sortcluase is ether ''ASC NULL FIRST'' or "DESC
|
||||
* NULL LAST", just abandon pathkeys
|
||||
* in B database, nulls was the min value
|
||||
*/
|
||||
if (!(pk_strategy == BTLessStrategyNumber && pk_nulls_first == false) &&
|
||||
!(pk_strategy == BTGreaterStrategyNumber && pk_nulls_first == true)) {
|
||||
bool invalid_path_key= false;
|
||||
if (CheckPluginNullsPolicy()) {
|
||||
invalid_path_key = !(pk_strategy == BTLessStrategyNumber && pk_nulls_first == true) &&
|
||||
!(pk_strategy == BTGreaterStrategyNumber && pk_nulls_first == false);
|
||||
} else {
|
||||
invalid_path_key = !(pk_strategy == BTLessStrategyNumber && pk_nulls_first == false) &&
|
||||
!(pk_strategy == BTGreaterStrategyNumber && pk_nulls_first == true);
|
||||
}
|
||||
if (invalid_path_key) {
|
||||
OPT_LOG(DEBUG2,
|
||||
"partiterator fails to inherit pathkeys since sort strategy is"
|
||||
" nether ASC NULL LAST nor DESC DESC NULL FIRST");
|
||||
|
||||
@ -567,12 +567,12 @@ List* build_index_pathkeys(PlannerInfo* root, IndexOptInfo* index, ScanDirection
|
||||
}
|
||||
|
||||
/*
|
||||
* in B format, null value in insert into the minimal partition
|
||||
* if index is default nulls last, set to nulls first
|
||||
* if index is nulls first, dothing
|
||||
* */
|
||||
if (index->ispartitionedindex && !index->isGlobal && DB_IS_CMPT(B_FORMAT)) {
|
||||
if (!index->nulls_first[i]) {
|
||||
* in B format, null value in insert into the minimal partition
|
||||
* desc default: nulls first -> nulls last
|
||||
* asc default: nulls last -> nulls
|
||||
*/
|
||||
if (index->ispartitionedindex && !index->isGlobal && CheckPluginNullsPolicy()) {
|
||||
if ((!reverse_sort && !nulls_first) || (reverse_sort && nulls_first)) {
|
||||
nulls_first = !nulls_first;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2929,6 +2929,7 @@ typedef struct knl_u_hook_context {
|
||||
void *pluginPlannerHook;
|
||||
void *groupingplannerHook;
|
||||
void *replaceNullOrNotHook;
|
||||
void *nullsMinimalPolicyHook;
|
||||
} knl_u_hook_context;
|
||||
|
||||
typedef struct knl_u_libsw_context {
|
||||
|
||||
@ -473,6 +473,15 @@ extern void DestroyPartitionMap(PartitionMap* partMap);
|
||||
extern bool trySearchFakeReationForPartitionOid(HTAB** fakeRels, MemoryContext cxt, Relation rel, Oid partOid,
|
||||
int partitionno, Relation* fakeRelation, Partition* partition, LOCKMODE lmode, bool checkSubPart = true);
|
||||
|
||||
#ifndef FRONTEND
|
||||
typedef bool (*nullsMinimalPolicy)();
|
||||
extern inline bool CheckPluginNullsPolicy()
|
||||
{
|
||||
return DB_IS_CMPT(B_FORMAT) && (u_sess->hook_cxt.nullsMinimalPolicyHook != NULL ?
|
||||
((nullsMinimalPolicy)(u_sess->hook_cxt.nullsMinimalPolicyHook))() : false);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* partitoin map copy functions */
|
||||
extern ListPartitionMap *CopyListPartitionMap(ListPartitionMap *src_lpm);
|
||||
/* more! other hash/range and its underlaying element data structores will add here later */
|
||||
|
||||
@ -156,13 +156,13 @@ insert into base_partition_tbl values(null, 'test');
|
||||
select * from base_partition_tbl partition (num1);
|
||||
num | data1
|
||||
-----+-------
|
||||
| test
|
||||
(1 row)
|
||||
(0 rows)
|
||||
|
||||
select * from base_partition_tbl partition (num4);
|
||||
num | data1
|
||||
-----+-------
|
||||
(0 rows)
|
||||
| test
|
||||
(1 row)
|
||||
|
||||
create table base_partition_tbl_sub_partition
|
||||
(
|
||||
@ -193,41 +193,39 @@ insert into base_partition_tbl_sub_partition values(null, 'test');
|
||||
select * from base_partition_tbl_sub_partition subpartition (num1_1);
|
||||
num | data1
|
||||
-----+-------
|
||||
| test
|
||||
(1 row)
|
||||
(0 rows)
|
||||
|
||||
select * from base_partition_tbl_sub_partition subpartition (num5_2);
|
||||
num | data1
|
||||
-----+-------
|
||||
(0 rows)
|
||||
| test
|
||||
(1 row)
|
||||
|
||||
create table t_range (c1 int, c2 int) partition by range(c1) (partition p1 values less than (10), partition p2 values less than(maxvalue));
|
||||
insert into t_range values(null),(5),(100);
|
||||
create index t_range_c1_idx on t_range (c1 nulls last) local;
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------------------
|
||||
Sort
|
||||
Sort Key: c1 NULLS FIRST
|
||||
-> Partition Iterator
|
||||
Iterations: 2
|
||||
-> Partitioned Index Scan using t_range_c1_idx on t_range
|
||||
Selected Partitions: 1..2
|
||||
(6 rows)
|
||||
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- NO INDEX
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- NO INDEX
|
||||
WARNING: unused hint: IndexScan(t_range)
|
||||
QUERY PLAN
|
||||
---------------------------------------------
|
||||
Sort
|
||||
Sort Key: c1
|
||||
Sort Key: c1 NULLS FIRST
|
||||
-> Partition Iterator
|
||||
Iterations: 2
|
||||
-> Partitioned Seq Scan on t_range
|
||||
Selected Partitions: 1..2
|
||||
(6 rows)
|
||||
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- INDEX
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------------
|
||||
Partition Iterator
|
||||
Iterations: 2
|
||||
-> Partitioned Index Scan using t_range_c1_idx on t_range
|
||||
Selected Partitions: 1..2
|
||||
(4 rows)
|
||||
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- NO INDEX
|
||||
c1 | c2
|
||||
-----+----
|
||||
|
|
||||
@ -235,7 +233,7 @@ select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
100 |
|
||||
(3 rows)
|
||||
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- NO INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- INDEX
|
||||
c1 | c2
|
||||
-----+----
|
||||
5 |
|
||||
@ -245,7 +243,7 @@ select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- NO IND
|
||||
|
||||
drop index t_range_c1_idx;
|
||||
create index on t_range (c1 nulls first) local;
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- NO INDEX
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------------------
|
||||
Sort
|
||||
@ -268,7 +266,7 @@ WARNING: unused hint: IndexScan(t_range)
|
||||
Selected Partitions: 1..2
|
||||
(6 rows)
|
||||
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- NO INDEX
|
||||
c1 | c2
|
||||
-----+----
|
||||
|
|
||||
|
||||
@ -1685,16 +1685,14 @@ select * from t_multi_parts_order partition (pd) order by col limit 10;
|
||||
|
||||
rollback;
|
||||
explain (costs off) delete from t_multi_parts_order partition(pd, p1) order by col limit 10;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------------------------
|
||||
Delete on t_multi_parts_order
|
||||
-> Sort
|
||||
Sort Key: col
|
||||
-> Partition Iterator
|
||||
Iterations: 2
|
||||
-> Partitioned Seq Scan on t_multi_parts_order
|
||||
Selected Partitions: 1..2
|
||||
(7 rows)
|
||||
-> Partition Iterator
|
||||
Iterations: 2
|
||||
-> Partitioned Index Scan using tbl_idx_t_multi_parts_order on t_multi_parts_order
|
||||
Selected Partitions: 1..2
|
||||
(5 rows)
|
||||
|
||||
begin;
|
||||
delete from t_multi_parts_order partition(p1, pd) order by col desc limit 10;
|
||||
@ -1761,16 +1759,14 @@ select * from t_multi_parts_order partition (pd) order by col desc limit 10;
|
||||
|
||||
rollback;
|
||||
explain (costs off) delete from t_multi_parts_order partition(pd, p1) order by col desc limit 10;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------------------------------
|
||||
Delete on t_multi_parts_order
|
||||
-> Sort
|
||||
Sort Key: col DESC
|
||||
-> Partition Iterator
|
||||
Iterations: 2
|
||||
-> Partitioned Seq Scan on t_multi_parts_order
|
||||
Selected Partitions: 1..2
|
||||
(7 rows)
|
||||
-> Partition Iterator Scan Backward
|
||||
Iterations: 2
|
||||
-> Partitioned Index Scan Backward using tbl_idx_t_multi_parts_order on t_multi_parts_order
|
||||
Selected Partitions: 1..2
|
||||
(5 rows)
|
||||
|
||||
drop table if exists t_multi_parts_order;
|
||||
-- range partitions with global index, single column
|
||||
|
||||
@ -105,15 +105,15 @@ select * from base_partition_tbl_sub_partition subpartition (num5_2);
|
||||
create table t_range (c1 int, c2 int) partition by range(c1) (partition p1 values less than (10), partition p2 values less than(maxvalue));
|
||||
insert into t_range values(null),(5),(100);
|
||||
create index t_range_c1_idx on t_range (c1 nulls last) local;
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- NO INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- NO INDEX
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- NO INDEX
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- NO INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- INDEX
|
||||
drop index t_range_c1_idx;
|
||||
create index on t_range (c1 nulls first) local;
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- NO INDEX
|
||||
explain (costs off) select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- NO INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls first; -- NO INDEX
|
||||
select /*+ indexscan(t_range) */* from t_range order by c1 nulls last; -- NO INDEX
|
||||
|
||||
\c regression
|
||||
|
||||
Reference in New Issue
Block a user