!3157 解决兼容性b库下,对于二级分区表分区键为year函数时,在进行add partition操作后,使用pg_get_tabledef会报未知错误
Merge pull request !3157 from 王修强/partition_bug_partexprstr
This commit is contained in:
@ -145,10 +145,10 @@ static void addNewPartitionTuplesForPartition(Relation pg_partition_rel,
|
||||
Oid relid, Oid reltablespace,
|
||||
Oid bucketOid, PartitionState* partTableState, Oid ownerid,
|
||||
Datum reloptions, const TupleDesc tupledesc, char strategy, StorageType storage_type, LOCKMODE partLockMode,
|
||||
bool partkeyexprIsNull = true, bool partkeyIsFunc = false);
|
||||
PartitionExprKeyInfo *partExprKeyInfo = NULL);
|
||||
static void addNewPartitionTupleForTable(Relation pg_partition_rel, const char* relname, const Oid reloid,
|
||||
const Oid reltablespaceid, const TupleDesc reltupledesc, const PartitionState* partTableState, Oid ownerid,
|
||||
Datum reloptions, bool partkeyexprIsNull = true, bool partkeyIsFunc = false);
|
||||
Datum reloptions, PartitionExprKeyInfo *partExprKeyInfo = NULL);
|
||||
|
||||
static void addNewPartitionTupleForValuePartitionedTable(Relation pg_partition_rel, const char* relname,
|
||||
const Oid reloid, const Oid reltablespaceid, const TupleDesc reltupledesc, const PartitionState* partTableState,
|
||||
@ -2804,12 +2804,11 @@ Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltable
|
||||
|
||||
/* Get uids info from reloptions */
|
||||
relhasuids = StdRdOptionsHasUids(hreloptions, relkind);
|
||||
bool partkeyexprIsNull = true;
|
||||
PartitionExprKeyInfo partExprKeyInfo = PartitionExprKeyInfo();
|
||||
bool subpartkeyexprIsNull = true;
|
||||
bool partkeyIsFunc = false;
|
||||
bool subpartkeyIsFunc = false;
|
||||
if (partTableState) {
|
||||
partkeyexprIsNull = CheckPartitionExprKey(partTableState->partitionKey, partTableState->partitionStrategy, &partkeyIsFunc);
|
||||
partExprKeyInfo.partkeyexprIsNull = CheckPartitionExprKey(partTableState->partitionKey, partTableState->partitionStrategy, &(partExprKeyInfo.partkeyIsFunc));
|
||||
if (partTableState->subPartitionState)
|
||||
subpartkeyexprIsNull = CheckPartitionExprKey(partTableState->subPartitionState->partitionKey,
|
||||
partTableState->subPartitionState->partitionStrategy, &subpartkeyIsFunc);
|
||||
@ -3022,9 +3021,10 @@ Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltable
|
||||
partTableState, /*partition schema of partitioned table*/
|
||||
ownerid, /*partitioned table's owner id*/
|
||||
reloptions,
|
||||
partkeyexprIsNull,
|
||||
partkeyIsFunc);
|
||||
&partExprKeyInfo);
|
||||
|
||||
partExprKeyInfo.partkeyexprIsNull = subpartkeyexprIsNull;
|
||||
partExprKeyInfo.partkeyIsFunc = subpartkeyIsFunc;
|
||||
/* add partition entry to pg_partition */
|
||||
addNewPartitionTuplesForPartition(pg_partition_desc, /*RelationData pointer for pg_partition*/
|
||||
relid, /*partitioned table's oid in pg_class*/
|
||||
@ -3037,8 +3037,7 @@ Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltable
|
||||
partTableState->partitionStrategy,
|
||||
storage_type,
|
||||
partLockMode,
|
||||
subpartkeyexprIsNull,
|
||||
subpartkeyIsFunc);
|
||||
&partExprKeyInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6093,8 +6092,8 @@ void GetNewPartitionOidAndNewPartrelfileOid(List *subPartitionDefState, Oid *new
|
||||
*/
|
||||
Oid heapAddRangePartition(Relation pgPartRel, Oid partTableOid, Oid partTablespace, Oid bucketOid,
|
||||
RangePartitionDefState *newPartDef, Oid ownerid, Datum reloptions, const bool *isTimestamptz,
|
||||
StorageType storage_type, LOCKMODE partLockMode, int2vector* subpartition_key, bool isSubpartition, bool partkeyexprIsNull,
|
||||
bool partkeyIsFunc)
|
||||
StorageType storage_type, LOCKMODE partLockMode, int2vector* subpartition_key, bool isSubpartition,
|
||||
PartitionExprKeyInfo *partExprKeyInfo)
|
||||
{
|
||||
Datum boundaryValue = (Datum)0;
|
||||
Oid newPartitionOid = InvalidOid;
|
||||
@ -6184,8 +6183,11 @@ Oid heapAddRangePartition(Relation pgPartRel, Oid partTableOid, Oid partTablespa
|
||||
partTupleInfo.pkey = subpartition_key;
|
||||
partTupleInfo.boundaries = boundaryValue;
|
||||
partTupleInfo.reloptions = reloptions;
|
||||
partTupleInfo.partkeyexprIsNull = partkeyexprIsNull;
|
||||
partTupleInfo.partkeyIsFunc = partkeyIsFunc;
|
||||
if (partExprKeyInfo) {
|
||||
partTupleInfo.partexprkeyinfo.partkeyexprIsNull = partExprKeyInfo->partkeyexprIsNull;
|
||||
partTupleInfo.partexprkeyinfo.partkeyIsFunc = partExprKeyInfo->partkeyIsFunc;
|
||||
partTupleInfo.partexprkeyinfo.partExprKeyStr = partExprKeyInfo->partExprKeyStr;
|
||||
}
|
||||
|
||||
/* step 3: insert into pg_partition tuple */
|
||||
addNewPartitionTuple(pgPartRel, newPartition, &partTupleInfo);
|
||||
@ -6416,8 +6418,8 @@ Oid HeapAddIntervalPartition(Relation pgPartRel, Relation rel, Oid partTableOid,
|
||||
|
||||
Oid HeapAddListPartition(Relation pgPartRel, Oid partTableOid, Oid partTablespace, Oid bucketOid,
|
||||
ListPartitionDefState* newListPartDef, Oid ownerid, Datum reloptions, const bool* isTimestamptz,
|
||||
StorageType storage_type, int2vector* subpartition_key, bool isSubpartition, bool partkeyexprIsNull,
|
||||
bool partkeyIsFunc)
|
||||
StorageType storage_type, int2vector* subpartition_key, bool isSubpartition,
|
||||
PartitionExprKeyInfo *partExprKeyInfo)
|
||||
{
|
||||
Datum boundaryValue = (Datum)0;
|
||||
Oid newListPartitionOid = InvalidOid;
|
||||
@ -6496,8 +6498,11 @@ Oid HeapAddListPartition(Relation pgPartRel, Oid partTableOid, Oid partTablespac
|
||||
partTupleInfo.pkey = subpartition_key;
|
||||
partTupleInfo.boundaries = boundaryValue;
|
||||
partTupleInfo.reloptions = reloptions;
|
||||
partTupleInfo.partkeyexprIsNull = partkeyexprIsNull;
|
||||
partTupleInfo.partkeyIsFunc = partkeyIsFunc;
|
||||
if (partExprKeyInfo) {
|
||||
partTupleInfo.partexprkeyinfo.partkeyexprIsNull = partExprKeyInfo->partkeyexprIsNull;
|
||||
partTupleInfo.partexprkeyinfo.partkeyIsFunc = partExprKeyInfo->partkeyIsFunc;
|
||||
partTupleInfo.partexprkeyinfo.partExprKeyStr = partExprKeyInfo->partExprKeyStr;
|
||||
}
|
||||
|
||||
/* step 3: insert into pg_partition tuple */
|
||||
addNewPartitionTuple(pgPartRel, newListPartition, &partTupleInfo);
|
||||
@ -6718,8 +6723,8 @@ Oid AddNewIntervalPartition(Relation rel, void* insertTuple, int *partitionno, b
|
||||
|
||||
Oid HeapAddHashPartition(Relation pgPartRel, Oid partTableOid, Oid partTablespace, Oid bucketOid,
|
||||
HashPartitionDefState* newHashPartDef, Oid ownerid, Datum reloptions, const bool* isTimestamptz,
|
||||
StorageType storage_type, int2vector* subpartition_key, bool isSubpartition, bool partkeyexprIsNull,
|
||||
bool partkeyIsFunc)
|
||||
StorageType storage_type, int2vector* subpartition_key, bool isSubpartition,
|
||||
PartitionExprKeyInfo *partExprKeyInfo)
|
||||
{
|
||||
Datum boundaryValue = (Datum)0;
|
||||
Oid newHashPartitionOid = InvalidOid;
|
||||
@ -6809,8 +6814,11 @@ Oid HeapAddHashPartition(Relation pgPartRel, Oid partTableOid, Oid partTablespac
|
||||
partTupleInfo.pkey = subpartition_key;
|
||||
partTupleInfo.boundaries = boundaryValue;
|
||||
partTupleInfo.reloptions = reloptions;
|
||||
partTupleInfo.partkeyexprIsNull = partkeyexprIsNull;
|
||||
partTupleInfo.partkeyIsFunc = partkeyIsFunc;
|
||||
if (partExprKeyInfo) {
|
||||
partTupleInfo.partexprkeyinfo.partkeyexprIsNull = partExprKeyInfo->partkeyexprIsNull;
|
||||
partTupleInfo.partexprkeyinfo.partkeyIsFunc = partExprKeyInfo->partkeyIsFunc;
|
||||
partTupleInfo.partexprkeyinfo.partExprKeyStr = partExprKeyInfo->partExprKeyStr;
|
||||
}
|
||||
|
||||
/* step 3: insert into pg_partition tuple */
|
||||
addNewPartitionTuple(pgPartRel, newHashPartition, &partTupleInfo);
|
||||
@ -6923,7 +6931,7 @@ static void addNewPartitionTupleForValuePartitionedTable(Relation pg_partition_r
|
||||
*/
|
||||
static void addNewPartitionTupleForTable(Relation pg_partition_rel, const char* relname, const Oid reloid,
|
||||
const Oid reltablespaceid, const TupleDesc reltupledesc, const PartitionState* partTableState, Oid ownerid,
|
||||
Datum reloptions, bool partkeyexprIsNull, bool partkeyIsFunc)
|
||||
Datum reloptions, PartitionExprKeyInfo *partExprKeyInfo)
|
||||
{
|
||||
Datum interval = (Datum)0;
|
||||
Datum transition_point = (Datum)0;
|
||||
@ -7000,10 +7008,13 @@ static void addNewPartitionTupleForTable(Relation pg_partition_rel, const char*
|
||||
partTupleInfo.boundaries = (Datum)0;
|
||||
partTupleInfo.transitionPoint = transition_point;
|
||||
partTupleInfo.reloptions = newOptions;
|
||||
partTupleInfo.partkeyexprIsNull = partkeyexprIsNull;
|
||||
partTupleInfo.partkeyIsFunc = partkeyIsFunc;
|
||||
partTupleInfo.partitionno = -list_length(partTableState->partitionList);
|
||||
partTupleInfo.subpartitionno = INVALID_PARTITION_NO;
|
||||
if (partExprKeyInfo) {
|
||||
partTupleInfo.partexprkeyinfo.partkeyexprIsNull = partExprKeyInfo->partkeyexprIsNull;
|
||||
partTupleInfo.partexprkeyinfo.partkeyIsFunc = partExprKeyInfo->partkeyIsFunc;
|
||||
partTupleInfo.partexprkeyinfo.partExprKeyStr = partExprKeyInfo->partExprKeyStr;
|
||||
}
|
||||
|
||||
/*step 2: insert into pg_partition tuple*/
|
||||
addNewPartitionTuple(pg_partition_rel, new_partition, &partTupleInfo);
|
||||
@ -7237,8 +7248,7 @@ Oid GetPartTablespaceOidForSubpartition(Oid reltablespace, const char* partTable
|
||||
*/
|
||||
static void addNewPartitionTuplesForPartition(Relation pg_partition_rel, Oid relid,
|
||||
Oid reltablespace, Oid bucketOid, PartitionState* partTableState, Oid ownerid, Datum reloptions,
|
||||
const TupleDesc tupledesc, char strategy, StorageType storage_type, LOCKMODE partLockMode, bool partkeyexprIsNull,
|
||||
bool partkeyIsFunc)
|
||||
const TupleDesc tupledesc, char strategy, StorageType storage_type, LOCKMODE partLockMode, PartitionExprKeyInfo *partExprKeyInfo)
|
||||
{
|
||||
int partKeyNum = list_length(partTableState->partitionKey);
|
||||
bool isTimestamptzForPartKey[partKeyNum];
|
||||
@ -7285,8 +7295,7 @@ static void addNewPartitionTuplesForPartition(Relation pg_partition_rel, Oid rel
|
||||
storage_type,
|
||||
subpartition_key_attr_no,
|
||||
false,
|
||||
partkeyexprIsNull,
|
||||
partkeyIsFunc);
|
||||
partExprKeyInfo);
|
||||
|
||||
Oid partTablespaceOid =
|
||||
GetPartTablespaceOidForSubpartition(reltablespace, partitionDefState->tablespacename);
|
||||
@ -7315,8 +7324,7 @@ static void addNewPartitionTuplesForPartition(Relation pg_partition_rel, Oid rel
|
||||
storage_type,
|
||||
subpartition_key_attr_no,
|
||||
false,
|
||||
partkeyexprIsNull,
|
||||
partkeyIsFunc);
|
||||
partExprKeyInfo);
|
||||
|
||||
Oid partTablespaceOid =
|
||||
GetPartTablespaceOidForSubpartition(reltablespace, partitionDefState->tablespacename);
|
||||
@ -7346,8 +7354,7 @@ static void addNewPartitionTuplesForPartition(Relation pg_partition_rel, Oid rel
|
||||
partLockMode,
|
||||
subpartition_key_attr_no,
|
||||
false,
|
||||
partkeyexprIsNull,
|
||||
partkeyIsFunc);
|
||||
partExprKeyInfo);
|
||||
|
||||
Oid partTablespaceOid =
|
||||
GetPartTablespaceOidForSubpartition(reltablespace, partitionDefState->tablespacename);
|
||||
|
||||
@ -154,12 +154,18 @@ void insertPartitionEntry(Relation pg_partition_desc, Partition new_part_desc, O
|
||||
values[Anum_pg_partition_relminmxid - 1] = InvalidMultiXactId;
|
||||
#endif
|
||||
}
|
||||
if (partTupleInfo->partkeyexprIsNull) {
|
||||
if (partTupleInfo->partexprkeyinfo.partkeyexprIsNull) {
|
||||
nulls[Anum_pg_partition_partkeyexpr - 1] = true;
|
||||
} else if (partTupleInfo->partkeyIsFunc) {
|
||||
values[Anum_pg_partition_partkeyexpr - 1] = CStringGetTextDatum("partkeyisfunc");
|
||||
} else if (partTupleInfo->partexprkeyinfo.partkeyIsFunc) {
|
||||
if (partTupleInfo->partexprkeyinfo.partExprKeyStr)
|
||||
values[Anum_pg_partition_partkeyexpr - 1] = CStringGetTextDatum(partTupleInfo->partexprkeyinfo.partExprKeyStr);
|
||||
else
|
||||
values[Anum_pg_partition_partkeyexpr - 1] = CStringGetTextDatum("partkeyisfunc");
|
||||
} else {
|
||||
values[Anum_pg_partition_partkeyexpr - 1] = CStringGetTextDatum("");
|
||||
if (partTupleInfo->partexprkeyinfo.partExprKeyStr)
|
||||
values[Anum_pg_partition_partkeyexpr - 1] = CStringGetTextDatum(partTupleInfo->partexprkeyinfo.partExprKeyStr);
|
||||
else
|
||||
values[Anum_pg_partition_partkeyexpr - 1] = CStringGetTextDatum("");
|
||||
}
|
||||
|
||||
if (partTupleInfo->partitionno != INVALID_PARTITION_NO) {
|
||||
|
||||
@ -23379,7 +23379,7 @@ static void CheckPartitionValueConflictForAddPartition(Relation rel, Node *partD
|
||||
decre_partmap_refcount(rel->partMap);
|
||||
}
|
||||
|
||||
bool IsPartKeyFunc(Relation rel, bool isPartRel, bool forSubPartition)
|
||||
bool IsPartKeyFunc(Relation rel, bool isPartRel, bool forSubPartition, PartitionExprKeyInfo* partExprKeyInfo)
|
||||
{
|
||||
HeapTuple partTuple = NULL;
|
||||
if (forSubPartition) {
|
||||
@ -23403,10 +23403,12 @@ bool IsPartKeyFunc(Relation rel, bool isPartRel, bool forSubPartition)
|
||||
if (!partTuple)
|
||||
ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("The partTuple for oid %d can't be found", rel->rd_id)));
|
||||
|
||||
bool isPartExprKeyNull = false;
|
||||
bool isNull = false;
|
||||
Datum datum = 0;
|
||||
datum = SysCacheGetAttr(PARTRELID, partTuple, Anum_pg_partition_partkeyexpr, &isPartExprKeyNull);
|
||||
if (isPartExprKeyNull) {
|
||||
datum = SysCacheGetAttr(PARTRELID, partTuple, Anum_pg_partition_partkeyexpr, &isNull);
|
||||
if (partExprKeyInfo)
|
||||
partExprKeyInfo->partkeyexprIsNull = isNull;
|
||||
if (isNull) {
|
||||
if (forSubPartition)
|
||||
ReleaseSysCache(partTuple);
|
||||
else
|
||||
@ -23414,15 +23416,19 @@ bool IsPartKeyFunc(Relation rel, bool isPartRel, bool forSubPartition)
|
||||
return false;
|
||||
}
|
||||
|
||||
char* partkeystr = TextDatumGetCString(datum);
|
||||
char* partKeyStr = TextDatumGetCString(datum);
|
||||
Node* partkeyexpr = NULL;
|
||||
if (forSubPartition)
|
||||
ReleaseSysCache(partTuple);
|
||||
else
|
||||
heap_freetuple(partTuple);
|
||||
|
||||
partkeyexpr = (Node*)stringToNode_skip_extern_fields(partkeystr);
|
||||
pfree_ext(partkeystr);
|
||||
partkeyexpr = (Node*)stringToNode_skip_extern_fields(partKeyStr);
|
||||
if (!partExprKeyInfo)
|
||||
pfree_ext(partKeyStr);
|
||||
else
|
||||
partExprKeyInfo->partExprKeyStr = partKeyStr;
|
||||
|
||||
if (!partkeyexpr)
|
||||
ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("The partkeyexpr can't be NULL")));
|
||||
|
||||
@ -23687,6 +23693,9 @@ static void ATExecAddPartitionInternal(Relation rel, AddPartitionState *partStat
|
||||
|
||||
bucketOid = RelationGetBucketOid(rel);
|
||||
|
||||
PartitionExprKeyInfo partExprKeyInfo = PartitionExprKeyInfo();
|
||||
partExprKeyInfo.partkeyIsFunc = IsPartKeyFunc(rel, false, true, &partExprKeyInfo);
|
||||
|
||||
List *partitionNameList =
|
||||
list_concat(GetPartitionNameList(partState->partitionList), RelationGetPartitionNameList(rel));
|
||||
foreach (cell, partState->partitionList) {
|
||||
@ -23715,7 +23724,8 @@ static void ATExecAddPartitionInternal(Relation rel, AddPartitionState *partStat
|
||||
isTimestamptz,
|
||||
RelationGetStorageType(rel),
|
||||
subpartitionKey,
|
||||
RelationIsPartitionOfSubPartitionTable(rel));
|
||||
RelationIsPartitionOfSubPartitionTable(rel),
|
||||
&partExprKeyInfo);
|
||||
} else {
|
||||
newPartOid = heapAddRangePartition(pgPartRel,
|
||||
rel->rd_id,
|
||||
@ -23728,7 +23738,8 @@ static void ATExecAddPartitionInternal(Relation rel, AddPartitionState *partStat
|
||||
RelationGetStorageType(rel),
|
||||
AccessExclusiveLock,
|
||||
subpartitionKey,
|
||||
RelationIsPartitionOfSubPartitionTable(rel));
|
||||
RelationIsPartitionOfSubPartitionTable(rel),
|
||||
&partExprKeyInfo);
|
||||
}
|
||||
|
||||
Oid partTablespaceOid =
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "catalog/objectaddress.h"
|
||||
#include "utils/partcache.h"
|
||||
#include "utils/partitionmap.h"
|
||||
#include "catalog/pg_partition_fn.h"
|
||||
|
||||
#define PSORT_RESERVE_COLUMN "tid"
|
||||
#define CHCHK_PSORT_RESERVE_COLUMN(attname) (strcmp(PSORT_RESERVE_COLUMN, (attname)) == 0)
|
||||
@ -150,17 +151,17 @@ extern void heapDropPartitionList(Relation rel, List* partitionList);
|
||||
extern Oid heapAddRangePartition(Relation pgPartRel, Oid partTableOid, Oid partTablespace,
|
||||
Oid bucketOid, RangePartitionDefState *newPartDef, Oid ownerid, Datum reloptions,
|
||||
const bool* isTimestamptz, StorageType storage_type, LOCKMODE partLockMode, int2vector* subpartition_key = NULL, bool isSubPartition = false,
|
||||
bool partkeyexprIsNull = true, bool partkeyIsFunc = false);
|
||||
PartitionExprKeyInfo *partExprKeyInfo = NULL);
|
||||
|
||||
extern Oid HeapAddListPartition(Relation pgPartRel, Oid partTableOid, Oid partTablespace,
|
||||
Oid bucketOid, ListPartitionDefState *newPartDef, Oid ownerid, Datum reloptions,
|
||||
const bool* isTimestamptz, StorageType storage_type, int2vector* subpartition_key = NULL, bool isSubPartition = false,
|
||||
bool partkeyexprIsNull = true, bool partkeyIsFunc = false);
|
||||
PartitionExprKeyInfo *partExprKeyInfo = NULL);
|
||||
|
||||
extern Oid HeapAddHashPartition(Relation pgPartRel, Oid partTableOid, Oid partTablespace,
|
||||
Oid bucketOid, HashPartitionDefState *newPartDef, Oid ownerid, Datum reloptions,
|
||||
const bool* isTimestamptz, StorageType storage_type, int2vector* subpartition_key = NULL, bool isSubPartition = false,
|
||||
bool partkeyexprIsNull = true, bool partkeyIsFunc = false);
|
||||
PartitionExprKeyInfo *partExprKeyInfo = NULL);
|
||||
extern Node *MakeDefaultSubpartition(PartitionState *partitionState, PartitionDefState *partitionDefState);
|
||||
extern List *addNewSubPartitionTuplesForPartition(Relation pgPartRel, Oid partTableOid, Oid partTablespace,
|
||||
Oid bucketOid, Oid ownerid, Datum reloptions, const bool *isTimestamptz, StorageType storage_type,
|
||||
@ -169,8 +170,7 @@ extern List *addNewSubPartitionTuplesForPartition(Relation pgPartRel, Oid partTa
|
||||
extern Oid GetPartTablespaceOidForSubpartition(Oid reltablespace, const char* partTablespacename);
|
||||
|
||||
extern void heapDropPartitionIndex(Relation parentIndex, Oid partIndexId);
|
||||
extern void addNewPartitionTuple(Relation pg_part_desc, Partition new_part_desc, int2vector* pkey, oidvector *intablespace,
|
||||
Datum interval, Datum maxValues, Datum transitionPoint, Datum reloptions, bool partkeyexprIsNull = true, bool partkeyIsFunc = false);
|
||||
extern void addNewPartitionTuple(Relation pg_part_desc, Partition new_part_desc, PartitionTupleInfo *partTupleInfo);
|
||||
|
||||
extern void heap_truncate_one_part(Relation rel , Oid partOid);
|
||||
extern Oid heapTupleGetPartitionId(Relation rel, void *tuple, int *partitionno, bool isDDL = false,
|
||||
|
||||
@ -168,6 +168,20 @@ extern const uint32 PARTITION_ENHANCE_VERSION_NUM;
|
||||
typedef void (*PartitionNameGetPartidCallback) (Oid partitioned_relation, const char *partition_name, Oid partId,
|
||||
Oid oldPartId, char partition_type, void *callback_arg, LOCKMODE callbackobj_lockMode);
|
||||
|
||||
/* some partition expr key info */
|
||||
struct PartitionExprKeyInfo {
|
||||
bool partkeyexprIsNull;
|
||||
bool partkeyIsFunc;
|
||||
char* partExprKeyStr;
|
||||
|
||||
PartitionExprKeyInfo()
|
||||
{
|
||||
partkeyexprIsNull = true;
|
||||
partkeyIsFunc = false;
|
||||
partExprKeyStr = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
/* some pg_partition tuple info */
|
||||
struct PartitionTupleInfo {
|
||||
int2vector* pkey;
|
||||
@ -176,10 +190,9 @@ struct PartitionTupleInfo {
|
||||
Datum boundaries;
|
||||
Datum transitionPoint;
|
||||
Datum reloptions;
|
||||
bool partkeyexprIsNull;
|
||||
bool partkeyIsFunc;
|
||||
int partitionno;
|
||||
int subpartitionno;
|
||||
PartitionExprKeyInfo partexprkeyinfo;
|
||||
|
||||
PartitionTupleInfo()
|
||||
{
|
||||
@ -189,10 +202,9 @@ struct PartitionTupleInfo {
|
||||
boundaries = (Datum)0;
|
||||
transitionPoint = (Datum)0;
|
||||
reloptions = (Datum)0;
|
||||
partkeyexprIsNull = true;
|
||||
partkeyIsFunc = false;
|
||||
partitionno = INVALID_PARTITION_NO;
|
||||
subpartitionno = INVALID_PARTITION_NO;
|
||||
partexprkeyinfo = PartitionExprKeyInfo();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "access/htup.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/objectaddress.h"
|
||||
#include "catalog/pg_partition_fn.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "nodes/plannodes.h"
|
||||
#include "rewrite/rewriteRlsPolicy.h"
|
||||
@ -132,7 +133,7 @@ extern bool checkPartitionLocalIndexesUsable(Oid partitionOid);
|
||||
extern bool checkRelationLocalIndexesUsable(Relation relation);
|
||||
extern List* GetPartitionkeyPos(List* partitionkeys, List* schema, bool* partkeyIsFunc = NULL);
|
||||
|
||||
extern bool IsPartKeyFunc(Relation rel, bool isPartRel, bool forSubPartition);
|
||||
extern bool IsPartKeyFunc(Relation rel, bool isPartRel, bool forSubPartition, PartitionExprKeyInfo* partExprKeyInfo = NULL);
|
||||
extern void ComparePartitionValue(List* pos, FormData_pg_attribute* attrs, List *partitionList, bool isPartition = true, bool partkeyIsFunc = false);
|
||||
extern void CompareListValue(const List* pos, FormData_pg_attribute* attrs, List *partitionList, bool partkeyIsFunc = false);
|
||||
extern void clearAttrInitDefVal(Oid relid);
|
||||
|
||||
@ -216,6 +216,45 @@ select * from b_bug_2 partition(p1);
|
||||
select * from b_bug_2 partition(p2);
|
||||
select * from b_bug_2 partition(p3);
|
||||
|
||||
--test some bug fix
|
||||
create table subpart_range_add (col1 int, col2 int) partition by range( abs(col2) )
|
||||
subpartition by hash( abs(col1) )
|
||||
(
|
||||
partition p1 values less than (2000)
|
||||
(
|
||||
SUBPARTITION p1sub1,
|
||||
SUBPARTITION p1sub2
|
||||
),
|
||||
partition p2 values less than (3000)
|
||||
(
|
||||
SUBPARTITION p2sub1,
|
||||
SUBPARTITION p2sub2
|
||||
)
|
||||
);
|
||||
select pg_get_tabledef('subpart_range_add');
|
||||
alter table subpart_range_add add partition p3 values less than(4000);
|
||||
select pg_get_tabledef('subpart_range_add');
|
||||
select partkeyexpr from pg_partition where (parttype = 'p') and (parentid in (select oid from pg_class where relname = 'subpart_range_add'));
|
||||
|
||||
create table subpart_list_add (col1 int, col2 int) partition by list( abs(col2) )
|
||||
subpartition by hash( abs(col1) )
|
||||
(
|
||||
partition p1 values(2000)
|
||||
(
|
||||
SUBPARTITION p1sub1,
|
||||
SUBPARTITION p1sub2
|
||||
),
|
||||
partition p2 values(3000)
|
||||
(
|
||||
SUBPARTITION p2sub1,
|
||||
SUBPARTITION p2sub2
|
||||
)
|
||||
);
|
||||
select pg_get_tabledef('subpart_list_add');
|
||||
alter table subpart_list_add add partition p3 values(4000);
|
||||
select pg_get_tabledef('subpart_list_add');
|
||||
select partkeyexpr from pg_partition where (parttype = 'p') and (parentid in (select oid from pg_class where relname = 'subpart_list_add'));
|
||||
|
||||
|
||||
--test pg_get_tabledef and pg_dump
|
||||
create table testnormalsubpart(a int, b int) partition by range(a) subpartition by range(b)
|
||||
|
||||
@ -604,6 +604,161 @@ select * from b_bug_2 partition(p3);
|
||||
50 | 30 | 3
|
||||
(1 row)
|
||||
|
||||
--test some bug fix
|
||||
create table subpart_range_add (col1 int, col2 int) partition by range( abs(col2) )
|
||||
subpartition by hash( abs(col1) )
|
||||
(
|
||||
partition p1 values less than (2000)
|
||||
(
|
||||
SUBPARTITION p1sub1,
|
||||
SUBPARTITION p1sub2
|
||||
),
|
||||
partition p2 values less than (3000)
|
||||
(
|
||||
SUBPARTITION p2sub1,
|
||||
SUBPARTITION p2sub2
|
||||
)
|
||||
);
|
||||
select pg_get_tabledef('subpart_range_add');
|
||||
pg_get_tabledef
|
||||
-----------------------------------------------------------------
|
||||
SET search_path = public; +
|
||||
CREATE TABLE subpart_range_add ( +
|
||||
col1 integer, +
|
||||
col2 integer +
|
||||
) +
|
||||
WITH (orientation=row, compression=no) +
|
||||
PARTITION BY RANGE (abs(col2)) SUBPARTITION BY HASH (abs(col1))+
|
||||
( +
|
||||
PARTITION p1 VALUES LESS THAN (2000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p1sub1 TABLESPACE pg_default, +
|
||||
SUBPARTITION p1sub2 TABLESPACE pg_default +
|
||||
), +
|
||||
PARTITION p2 VALUES LESS THAN (3000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p2sub1 TABLESPACE pg_default, +
|
||||
SUBPARTITION p2sub2 TABLESPACE pg_default +
|
||||
) +
|
||||
) +
|
||||
ENABLE ROW MOVEMENT;
|
||||
(1 row)
|
||||
|
||||
alter table subpart_range_add add partition p3 values less than(4000);
|
||||
select pg_get_tabledef('subpart_range_add');
|
||||
pg_get_tabledef
|
||||
-----------------------------------------------------------------
|
||||
SET search_path = public; +
|
||||
CREATE TABLE subpart_range_add ( +
|
||||
col1 integer, +
|
||||
col2 integer +
|
||||
) +
|
||||
WITH (orientation=row, compression=no) +
|
||||
PARTITION BY RANGE (abs(col2)) SUBPARTITION BY HASH (abs(col1))+
|
||||
( +
|
||||
PARTITION p1 VALUES LESS THAN (2000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p1sub1 TABLESPACE pg_default, +
|
||||
SUBPARTITION p1sub2 TABLESPACE pg_default +
|
||||
), +
|
||||
PARTITION p2 VALUES LESS THAN (3000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p2sub1 TABLESPACE pg_default, +
|
||||
SUBPARTITION p2sub2 TABLESPACE pg_default +
|
||||
), +
|
||||
PARTITION p3 VALUES LESS THAN (4000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p3_subpartdefault1 TABLESPACE pg_default +
|
||||
) +
|
||||
) +
|
||||
ENABLE ROW MOVEMENT;
|
||||
(1 row)
|
||||
|
||||
select partkeyexpr from pg_partition where (parttype = 'p') and (parentid in (select oid from pg_class where relname = 'subpart_range_add'));
|
||||
partkeyexpr
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{FUNCEXPR :funcid 1397 :funcresulttype 23 :funcresulttype_orig -1 :funcretset false :funcformat 0 :funccollid 0 :inputcollid 0 :args ({VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location 110}) :location 106 :refSynOid 0}
|
||||
{FUNCEXPR :funcid 1397 :funcresulttype 23 :funcresulttype_orig -1 :funcretset false :funcformat 0 :funccollid 0 :inputcollid 0 :args ({VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location 110}) :location 106 :refSynOid 0}
|
||||
{FUNCEXPR :funcid 1397 :funcresulttype 23 :funcresulttype_orig -1 :funcretset false :funcformat 0 :funccollid 0 :inputcollid 0 :args ({VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location 110}) :location 106 :refSynOid 0}
|
||||
(3 rows)
|
||||
|
||||
create table subpart_list_add (col1 int, col2 int) partition by list( abs(col2) )
|
||||
subpartition by hash( abs(col1) )
|
||||
(
|
||||
partition p1 values(2000)
|
||||
(
|
||||
SUBPARTITION p1sub1,
|
||||
SUBPARTITION p1sub2
|
||||
),
|
||||
partition p2 values(3000)
|
||||
(
|
||||
SUBPARTITION p2sub1,
|
||||
SUBPARTITION p2sub2
|
||||
)
|
||||
);
|
||||
select pg_get_tabledef('subpart_list_add');
|
||||
pg_get_tabledef
|
||||
----------------------------------------------------------------
|
||||
SET search_path = public; +
|
||||
CREATE TABLE subpart_list_add ( +
|
||||
col1 integer, +
|
||||
col2 integer +
|
||||
) +
|
||||
WITH (orientation=row, compression=no) +
|
||||
PARTITION BY LIST (abs(col2)) SUBPARTITION BY HASH (abs(col1))+
|
||||
( +
|
||||
PARTITION p1 VALUES (2000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p1sub1 TABLESPACE pg_default, +
|
||||
SUBPARTITION p1sub2 TABLESPACE pg_default +
|
||||
), +
|
||||
PARTITION p2 VALUES (3000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p2sub1 TABLESPACE pg_default, +
|
||||
SUBPARTITION p2sub2 TABLESPACE pg_default +
|
||||
) +
|
||||
) +
|
||||
ENABLE ROW MOVEMENT;
|
||||
(1 row)
|
||||
|
||||
alter table subpart_list_add add partition p3 values(4000);
|
||||
select pg_get_tabledef('subpart_list_add');
|
||||
pg_get_tabledef
|
||||
----------------------------------------------------------------
|
||||
SET search_path = public; +
|
||||
CREATE TABLE subpart_list_add ( +
|
||||
col1 integer, +
|
||||
col2 integer +
|
||||
) +
|
||||
WITH (orientation=row, compression=no) +
|
||||
PARTITION BY LIST (abs(col2)) SUBPARTITION BY HASH (abs(col1))+
|
||||
( +
|
||||
PARTITION p1 VALUES (2000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p1sub1 TABLESPACE pg_default, +
|
||||
SUBPARTITION p1sub2 TABLESPACE pg_default +
|
||||
), +
|
||||
PARTITION p2 VALUES (3000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p2sub1 TABLESPACE pg_default, +
|
||||
SUBPARTITION p2sub2 TABLESPACE pg_default +
|
||||
), +
|
||||
PARTITION p3 VALUES (4000) TABLESPACE pg_default +
|
||||
( +
|
||||
SUBPARTITION p3_subpartdefault1 TABLESPACE pg_default +
|
||||
) +
|
||||
) +
|
||||
ENABLE ROW MOVEMENT;
|
||||
(1 row)
|
||||
|
||||
select partkeyexpr from pg_partition where (parttype = 'p') and (parentid in (select oid from pg_class where relname = 'subpart_list_add'));
|
||||
partkeyexpr
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{FUNCEXPR :funcid 1397 :funcresulttype 23 :funcresulttype_orig -1 :funcretset false :funcformat 0 :funccollid 0 :inputcollid 0 :args ({VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location 108}) :location 104 :refSynOid 0}
|
||||
{FUNCEXPR :funcid 1397 :funcresulttype 23 :funcresulttype_orig -1 :funcretset false :funcformat 0 :funccollid 0 :inputcollid 0 :args ({VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location 108}) :location 104 :refSynOid 0}
|
||||
{FUNCEXPR :funcid 1397 :funcresulttype 23 :funcresulttype_orig -1 :funcretset false :funcformat 0 :funccollid 0 :inputcollid 0 :args ({VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location 108}) :location 104 :refSynOid 0}
|
||||
(3 rows)
|
||||
|
||||
--test pg_get_tabledef and pg_dump
|
||||
create table testnormalsubpart(a int, b int) partition by range(a) subpartition by range(b)
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user