From 02f83ec98ae362e006f2f5ae178a445a8c142289 Mon Sep 17 00:00:00 2001 From: Amul Sul Date: Thu, 16 Nov 2017 16:51:34 +0530 Subject: [PATCH 1/3] argument validation v3 --- src/backend/catalog/partition.c | 65 +++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index ce29ba2eda..ea93646509 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -3103,15 +3103,41 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) int16 nkeys; FmgrInfo partsupfunc[PARTITION_MAX_KEYS]; } ColumnsHashData; - Oid parentId = PG_GETARG_OID(0); - int modulus = PG_GETARG_INT32(1); - int remainder = PG_GETARG_INT32(2); + Oid parentId; + int modulus; + int remainder; short nkeys = PG_NARGS() - 3; int i; Datum seed = UInt64GetDatum(HASH_PARTITION_SEED); ColumnsHashData *my_extra; uint64 rowHash = 0; + /*---------- + * Error out if any of the following violated: + * + * 1. Parent id, modulus, and the remainder should not be null. + * 2. Parent id must be valid relation id, + * 3. Modulus must be a positive integer and + * 4. Remainder must be a non-negative integer less than the modulus. + *---------- + */ + if (!(PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2))) + { + parentId = PG_GETARG_OID(0); + modulus = PG_GETARG_INT32(1); + remainder = PG_GETARG_INT32(2); + + if (!OidIsValid(parentId) || modulus <= 0 || remainder < 0 || + modulus <= remainder) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid hash partition bound"))); + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("parent relation id, modulus and the remainder cannot be null"))); + /* * Cache hash function information. */ @@ -3121,7 +3147,33 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) { Relation parent; PartitionKey key; - int j; + int j; + + /* Open parent relation and fetch partition keyinfo */ + parent = heap_open(parentId, AccessShareLock); + key = RelationGetPartitionKey(parent); + + if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE || + key->strategy != PARTITION_STRATEGY_HASH) + { + heap_close(parent, AccessShareLock); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("\"%s\" is not a hash partitioned table", + get_rel_name(parentId)))); + } + + /* complain if too few column values; we ignore extras, however */ + if (key->partnatts > nkeys) + { + heap_close(parent, AccessShareLock); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("value missing for partition column %d", + (nkeys + 1)))); + } + else + nkeys = key->partnatts; fcinfo->flinfo->fn_extra = MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt, @@ -3131,11 +3183,6 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) my_extra->nkeys = nkeys; my_extra->relid = parentId; - /* Open parent relation and fetch partition keyinfo */ - parent = heap_open(parentId, AccessShareLock); - key = RelationGetPartitionKey(parent); - - Assert(key->partnatts == nkeys); for (j = 0; j < nkeys; ++j) fmgr_info_copy(&my_extra->partsupfunc[j], key->partsupfunc, -- 2.14.1