Refactoring SysCacheGetAttr to know when attr cannot be NULL
Today we have two fairly common patterns around extracting an attr from a
cached tuple:
a = SysCacheGetAttr(OID, tuple, Anum_pg_foo_bar, &isnull);
Assert(!isnull);
a = SysCacheGetAttr(OID, tuple, Anum_pg_foo_bar, &isnull);
if (isnull)
elog(ERROR, "..");
The error message in the elog() cases also vary quite a lot. I've been unable
to find much in terms of guidelines for when to use en elog or an Assert, with
the likelyhood of a NULL value seemingly being the guiding principle (but not
in all cases IIUC).
The attached refactoring introduce SysCacheGetAttrNotNull as a wrapper around
SysCacheGetAttr where a NULL value triggers an elog(). This removes a lot of
boilerplate error handling which IMO leads to increased readability as the
error handling *in these cases* don't add much (there are other cases where
checking isnull does a lot of valuable work of course). Personally I much
prefer the error-out automatically style of APIs like how palloc saves a ton of
checking the returned allocation for null, this aims at providing a similar
abstraction.
This will reduce granularity of error messages, and as the patch sits now it
does so a lot since the message is left to work on - I wanted to see if this
was at all seen as a net positive before spending time on that part. I chose
an elog since I as a user would prefer to hit an elog instead of a silent keep
going with an assert, this is of course debateable.
Thoughts?
--
Daniel Gustafsson
Attachments:
0001-Add-SysCacheGetAttrNotNull-for-guarnteed-not-null-at.patchapplication/octet-stream; name=0001-Add-SysCacheGetAttrNotNull-for-guarnteed-not-null-at.patch; x-unix-mode=0644Download
From 251f542bb157b21d434d36041f77c07c72fd25e4 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <dgustafsson@postgresql.org>
Date: Tue, 28 Feb 2023 21:06:45 +0100
Subject: [PATCH] Add SysCacheGetAttrNotNull for guarnteed not-null attrs
When extracting an attr from a cached tuple in the syscache with
SysCacheGetAttr the isnull parameter must be checked in case the
attr cannot be NULL. For cases when this is known beforehand, a
wrapper is introduced which perform the errorhandling internally
on behalf of the caller, invoking an elog in case of a NULL attr.
---
src/backend/access/brin/brin_inclusion.c | 7 +-
src/backend/access/brin/brin_minmax.c | 7 +-
src/backend/access/brin/brin_minmax_multi.c | 7 +-
src/backend/access/index/indexam.c | 6 +-
src/backend/catalog/aclchk.c | 38 +++---
src/backend/catalog/index.c | 20 ++--
src/backend/catalog/objectaddress.c | 23 ++--
src/backend/catalog/pg_constraint.c | 33 ++----
src/backend/catalog/pg_proc.c | 25 +---
src/backend/catalog/pg_subscription.c | 32 ++----
src/backend/commands/collationcmds.c | 23 ++--
src/backend/commands/dbcommands.c | 11 +-
src/backend/commands/indexcmds.c | 7 +-
src/backend/commands/matview.c | 9 +-
src/backend/commands/subscriptioncmds.c | 10 +-
src/backend/commands/tablecmds.c | 27 ++---
src/backend/commands/typecmds.c | 8 +-
src/backend/executor/execReplication.c | 6 +-
src/backend/executor/functions.c | 9 +-
src/backend/optimizer/util/clauses.c | 25 +---
src/backend/parser/parse_func.c | 7 +-
src/backend/parser/parse_utilcmd.c | 31 ++---
src/backend/partitioning/partbounds.c | 9 +-
src/backend/statistics/extended_stats.c | 5 +-
src/backend/utils/adt/amutils.c | 6 +-
src/backend/utils/adt/pg_locale.c | 19 +--
src/backend/utils/adt/ruleutils.c | 121 ++++++--------------
src/backend/utils/cache/lsyscache.c | 21 +---
src/backend/utils/cache/partcache.c | 10 +-
src/backend/utils/cache/syscache.c | 21 ++++
src/backend/utils/fmgr/fmgr.c | 39 ++-----
src/backend/utils/fmgr/funcapi.c | 25 ++--
src/backend/utils/init/postinit.c | 9 +-
src/include/utils/syscache.h | 3 +
src/pl/plperl/plperl.c | 6 +-
src/pl/plpgsql/src/pl_comp.c | 7 +-
src/pl/plpython/plpy_procedure.c | 6 +-
src/pl/tcl/pltcl.c | 6 +-
38 files changed, 233 insertions(+), 451 deletions(-)
diff --git a/src/backend/access/brin/brin_inclusion.c b/src/backend/access/brin/brin_inclusion.c
index 248116c149..02f4d0ae76 100644
--- a/src/backend/access/brin/brin_inclusion.c
+++ b/src/backend/access/brin/brin_inclusion.c
@@ -630,7 +630,6 @@ inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -643,10 +642,10 @@ inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c
index 2431591be6..8229493c84 100644
--- a/src/backend/access/brin/brin_minmax.c
+++ b/src/backend/access/brin/brin_minmax.c
@@ -290,7 +290,6 @@ minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -303,10 +302,10 @@ minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
index 0ace6035be..84bcdf49a9 100644
--- a/src/backend/access/brin/brin_minmax_multi.c
+++ b/src/backend/access/brin/brin_minmax_multi.c
@@ -2953,7 +2953,6 @@ minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -2965,10 +2964,10 @@ minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index dbf147ed22..b25b03f7ab 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -961,7 +961,6 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
Oid opclass;
Datum indclassDatum;
oidvector *indclass;
- bool isnull;
if (!DatumGetPointer(attoptions))
return NULL; /* ok, no options, no procedure */
@@ -970,9 +969,8 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
* Report an error if the opclass's options-parsing procedure does not
* exist but the opclass options are specified.
*/
- indclassDatum = SysCacheGetAttr(INDEXRELID, indrel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indrel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
opclass = indclass->values[attnum - 1];
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index c4232344aa..03febea7ba 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -2178,11 +2178,9 @@ ExecGrant_common(InternalGrant *istmt, Oid classid, AclMode default_privs,
* Get owner ID and working copy of existing ACL. If there's no ACL,
* substitute the proper default.
*/
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isNull));
- Assert(!isNull);
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
aclDatum = SysCacheGetAttr(cacheid,
tuple,
get_object_attnum_acl(classid),
@@ -2206,10 +2204,8 @@ ExecGrant_common(InternalGrant *istmt, Oid classid, AclMode default_privs,
old_acl, ownerId,
&grantorId, &avail_goptions);
- nameDatum = SysCacheGetAttr(cacheid, tuple,
- get_object_attnum_name(classid),
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(cacheid, tuple,
+ get_object_attnum_name(classid));
/*
* Restrict the privileges to what we can actually grant, and emit the
@@ -2476,10 +2472,8 @@ ExecGrant_Parameter(InternalGrant *istmt)
parameterId);
/* We'll need the GUC's name */
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tuple,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tuple,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
/* Treat all parameters as belonging to the bootstrap superuser. */
@@ -3113,11 +3107,9 @@ object_aclmask(Oid classid, Oid objectid, Oid roleid,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isNull));
- Assert(!isNull);
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
aclDatum = SysCacheGetAttr(cacheid, tuple, get_object_attnum_acl(classid),
&isNull);
@@ -3994,7 +3986,6 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
if (cacheid != -1)
{
HeapTuple tuple;
- bool isnull;
tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
if (!HeapTupleIsValid(tuple))
@@ -4002,12 +3993,9 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isnull));
- Assert(!isnull);
-
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
ReleaseSysCache(tuple);
}
else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 7777e7ec77..864f2e6d86 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1320,14 +1320,12 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(oldIndexId));
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "cache lookup failed for index %u", oldIndexId);
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
- colOptionDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ colOptionDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indoption);
indcoloptions = (int2vector *) DatumGetPointer(colOptionDatum);
/* Fetch options of index if any */
@@ -1347,9 +1345,8 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
Datum exprDatum;
char *exprString;
- exprDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indexprs, &isnull);
- Assert(!isnull);
+ exprDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indexprs);
exprString = TextDatumGetCString(exprDatum);
indexExprs = (List *) stringToNode(exprString);
pfree(exprString);
@@ -1359,9 +1356,8 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
Datum predDatum;
char *predString;
- predDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indpred, &isnull);
- Assert(!isnull);
+ predDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indpred);
predString = TextDatumGetCString(predDatum);
indexPreds = (List *) stringToNode(predString);
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 2f688166e1..65f877c5b7 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -2597,7 +2597,6 @@ get_object_namespace(const ObjectAddress *address)
{
int cache;
HeapTuple tuple;
- bool isnull;
Oid oid;
const ObjectPropertyType *property;
@@ -2615,11 +2614,9 @@ get_object_namespace(const ObjectAddress *address)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for cache %d oid %u",
cache, address->objectId);
- oid = DatumGetObjectId(SysCacheGetAttr(cache,
- tuple,
- property->attnum_namespace,
- &isnull));
- Assert(!isnull);
+ oid = DatumGetObjectId(SysCacheGetAttrNotNull(cache,
+ tuple,
+ property->attnum_namespace));
ReleaseSysCache(tuple);
return oid;
@@ -3890,7 +3887,6 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
{
HeapTuple tup;
Datum nameDatum;
- bool isNull;
char *parname;
tup = SearchSysCache1(PARAMETERACLOID,
@@ -3902,10 +3898,8 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
object->objectId);
break;
}
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tup,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
appendStringInfo(&buffer, _("parameter %s"), parname);
ReleaseSysCache(tup);
@@ -5753,7 +5747,6 @@ getObjectIdentityParts(const ObjectAddress *object,
{
HeapTuple tup;
Datum nameDatum;
- bool isNull;
char *parname;
tup = SearchSysCache1(PARAMETERACLOID,
@@ -5765,10 +5758,8 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
break;
}
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tup,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
appendStringInfoString(&buffer, parname);
if (objname)
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 7392c72e90..ce82ede7f9 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -1190,23 +1190,18 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs,
int *num_fk_del_set_cols, AttrNumber *fk_del_set_cols)
{
- Oid constrId;
Datum adatum;
bool isNull;
ArrayType *arr;
int numkeys;
- constrId = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
-
/*
* We expect the arrays to be 1-D arrays of the right types; verify that.
* We don't need to use deconstruct_array() since the array data is just
* going to look like a C array of values.
*/
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conkey, &isNull);
- if (isNull)
- elog(ERROR, "null conkey for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conkey);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -1219,10 +1214,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if ((Pointer) arr != DatumGetPointer(adatum))
pfree(arr); /* free de-toasted copy, if any */
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_confkey, &isNull);
- if (isNull)
- elog(ERROR, "null confkey for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_confkey);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
@@ -1235,10 +1228,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (pf_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conpfeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conpfeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conpfeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
/* see TryReuseForeignKey if you change the test below */
if (ARR_NDIM(arr) != 1 ||
@@ -1253,10 +1244,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (pp_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conppeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conppeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conppeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
@@ -1270,10 +1259,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (ff_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conffeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conffeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conffeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 14d552fe2d..41fa2a4987 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -520,10 +520,8 @@ ProcedureCreate(const char *procedureName,
dropcmd,
format_procedure(oldproc->oid))));
- proargdefaults = SysCacheGetAttr(PROCNAMEARGSNSP, oldtup,
- Anum_pg_proc_proargdefaults,
- &isnull);
- Assert(!isnull);
+ proargdefaults = SysCacheGetAttrNotNull(PROCNAMEARGSNSP, oldtup,
+ Anum_pg_proc_proargdefaults);
oldDefaults = castNode(List, stringToNode(TextDatumGetCString(proargdefaults)));
Assert(list_length(oldDefaults) == oldproc->pronargdefaults);
@@ -731,7 +729,6 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
{
Oid funcoid = PG_GETARG_OID(0);
HeapTuple tuple;
- bool isnull;
Datum tmp;
char *prosrc;
@@ -747,9 +744,7 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for function %u", funcoid);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
if (fmgr_internal_function(prosrc) == InvalidOid)
@@ -778,7 +773,6 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
Oid funcoid = PG_GETARG_OID(0);
void *libraryhandle;
HeapTuple tuple;
- bool isnull;
Datum tmp;
char *prosrc;
char *probin;
@@ -796,14 +790,10 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for function %u", funcoid);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", funcoid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", funcoid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_probin);
probin = TextDatumGetCString(tmp);
(void) load_external_function(probin, prosrc, true, &libraryhandle);
@@ -876,10 +866,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
/* Postpone body checks if !check_function_bodies */
if (check_function_bodies)
{
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
-
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
/*
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index a56ae311c3..d322b9482c 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -73,11 +73,9 @@ GetSubscription(Oid subid, bool missing_ok)
sub->disableonerr = subform->subdisableonerr;
/* Get conninfo */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subconninfo,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subconninfo);
sub->conninfo = TextDatumGetCString(datum);
/* Get slotname */
@@ -91,27 +89,21 @@ GetSubscription(Oid subid, bool missing_ok)
sub->slotname = NULL;
/* Get synccommit */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subsynccommit,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subsynccommit);
sub->synccommit = TextDatumGetCString(datum);
/* Get publications */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subpublications,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subpublications);
sub->publications = textarray_to_stringlist(DatumGetArrayTypeP(datum));
/* Get origin */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_suborigin,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_suborigin);
sub->origin = TextDatumGetCString(datum);
ReleaseSysCache(tup);
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index eb62d285ea..e60a249963 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -384,9 +384,7 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate, &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_collation");
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
/* cannot change from NULL to non-NULL or vice versa */
@@ -437,7 +435,6 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
char *locale;
char *version;
Datum datum;
- bool isnull;
if (collid == DEFAULT_COLLATION_OID)
{
@@ -451,12 +448,9 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_database) GETSTRUCT(dbtup))->datlocprovider;
- datum = SysCacheGetAttr(DATABASEOID, dbtup,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_database_daticulocale : Anum_pg_database_datcollate,
- &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
+ provider == COLLPROVIDER_ICU ?
+ Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
locale = TextDatumGetCString(datum);
@@ -474,12 +468,9 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_collation) GETSTRUCT(colltp))->collprovider;
Assert(provider != COLLPROVIDER_DEFAULT);
- datum = SysCacheGetAttr(COLLOID, colltp,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate,
- &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_collation");
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp,
+ provider == COLLPROVIDER_ICU ?
+ Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
locale = TextDatumGetCString(datum);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index a0259cc593..12c8e2c739 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -2558,7 +2558,6 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
HeapTuple tp;
char datlocprovider;
Datum datum;
- bool isnull;
char *version;
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
@@ -2569,9 +2568,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttr(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate, &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
ReleaseSysCache(tp);
@@ -2697,14 +2694,12 @@ get_db_info(const char *name, LOCKMODE lockmode,
*dbLocProvider = dbform->datlocprovider;
if (dbCollate)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datcollate);
*dbCollate = TextDatumGetCString(datum);
}
if (dbCtype)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datctype);
*dbCtype = TextDatumGetCString(datum);
}
if (dbIculocale)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 16ec0b114e..c63350a6b7 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -188,7 +188,6 @@ CheckIndexCompatible(Oid oldId,
IndexInfo *indexInfo;
int numberOfAttributes;
int old_natts;
- bool isnull;
bool ret = true;
oidvector *old_indclass;
oidvector *old_indcollation;
@@ -267,12 +266,10 @@ CheckIndexCompatible(Oid oldId,
old_natts = indexForm->indnkeyatts;
Assert(old_natts == numberOfAttributes);
- d = SysCacheGetAttr(INDEXRELID, tuple, Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ d = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indcollation);
old_indcollation = (oidvector *) DatumGetPointer(d);
- d = SysCacheGetAttr(INDEXRELID, tuple, Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ d = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indclass);
old_indclass = (oidvector *) DatumGetPointer(d);
ret = (memcmp(old_indclass->values, classObjectId,
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index fb30d2595c..c00b9df3e3 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -692,15 +692,12 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
int indnkeyatts = indexStruct->indnkeyatts;
oidvector *indclass;
Datum indclassDatum;
- bool isnull;
int i;
/* Must get indclass the hard way. */
- indclassDatum = SysCacheGetAttr(INDEXRELID,
- indexRel->rd_indextuple,
- Anum_pg_index_indclass,
- &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID,
+ indexRel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/* Add quals for all columns from this index. */
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 464db6d247..8a26ddab1c 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -1436,15 +1436,13 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
LockSharedObject(SubscriptionRelationId, subid, 0, AccessExclusiveLock);
/* Get subname */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup,
- Anum_pg_subscription_subname, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, tup,
+ Anum_pg_subscription_subname);
subname = pstrdup(NameStr(*DatumGetName(datum)));
/* Get conninfo */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup,
- Anum_pg_subscription_subconninfo, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, tup,
+ Anum_pg_subscription_subconninfo);
conninfo = TextDatumGetCString(datum);
/* Get slotname */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 62d9917ca3..77fc3280b7 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -11078,7 +11078,6 @@ ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName,
List *children = NIL;
ListCell *child;
NewConstraint *newcon;
- bool isnull;
Datum val;
char *conbin;
@@ -11133,11 +11132,8 @@ ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName,
newcon->refindid = InvalidOid;
newcon->conid = con->oid;
- val = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conbin, &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u", con->oid);
-
+ val = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
newcon->qual = (Node *) stringToNode(conbin);
@@ -11239,7 +11235,6 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
HeapTuple indexTuple = NULL;
Form_pg_index indexStruct = NULL;
Datum indclassDatum;
- bool isnull;
oidvector *indclass;
int i;
@@ -11291,9 +11286,8 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
RelationGetRelationName(pkrel))));
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/*
@@ -11386,13 +11380,11 @@ transformFkeyCheckAttrs(Relation pkrel,
heap_attisnull(indexTuple, Anum_pg_index_indexprs, NULL))
{
Datum indclassDatum;
- bool isnull;
oidvector *indclass;
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/*
@@ -13544,7 +13536,6 @@ TryReuseForeignKey(Oid oldId, Constraint *con)
{
HeapTuple tup;
Datum adatum;
- bool isNull;
ArrayType *arr;
Oid *rawarr;
int numkeys;
@@ -13557,10 +13548,8 @@ TryReuseForeignKey(Oid oldId, Constraint *con)
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "cache lookup failed for constraint %u", oldId);
- adatum = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conpfeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conpfeqop for constraint %u", oldId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conpfeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
numkeys = ARR_DIMS(arr)[0];
/* test follows the one in ri_FetchConstraintInfo() */
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 04bddaef81..3440dbc440 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -3039,7 +3039,6 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
char *conbin;
SysScanDesc scan;
Datum val;
- bool isnull;
HeapTuple tuple;
HeapTuple copyTuple;
ScanKeyData skey[3];
@@ -3094,12 +3093,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
errmsg("constraint \"%s\" of domain \"%s\" is not a check constraint",
constrName, TypeNameToString(typename))));
- val = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conbin,
- &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u",
- con->oid);
+ val = SysCacheGetAttrNotNull(CONSTROID, tuple, Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
validateDomainConstraint(domainoid, conbin);
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index c484f5c301..8ee7ea63c5 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -51,7 +51,6 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel,
TupleTableSlot *searchslot)
{
int attoff;
- bool isnull;
Datum indclassDatum;
oidvector *opclass;
int2vector *indkey = &idxrel->rd_index->indkey;
@@ -60,9 +59,8 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel,
Assert(RelationGetReplicaIndex(rel) == RelationGetRelid(idxrel) ||
RelationGetPrimaryKeyIndex(rel) == RelationGetRelid(idxrel));
- indclassDatum = SysCacheGetAttr(INDEXRELID, idxrel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, idxrel->rd_indextuple,
+ Anum_pg_index_indclass);
opclass = (oidvector *) DatumGetPointer(indclassDatum);
/* Build scankey for every attribute in the index. */
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 50e06ec693..8745c3f436 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -660,12 +660,9 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
/*
* And of course we need the function body text.
*/
- tmp = SysCacheGetAttr(PROCOID,
- procedureTuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", foid);
+ tmp = SysCacheGetAttrNotNull(PROCOID,
+ procedureTuple,
+ Anum_pg_proc_prosrc);
fcache->src = TextDatumGetCString(tmp);
/* If we have prosqlbody, pay attention to that not prosrc. */
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 76e25118f9..9fd6f00874 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -4177,15 +4177,10 @@ fetch_function_defaults(HeapTuple func_tuple)
{
List *defaults;
Datum proargdefaults;
- bool isnull;
char *str;
- /* The error cases here shouldn't happen, but check anyway */
- proargdefaults = SysCacheGetAttr(PROCOID, func_tuple,
- Anum_pg_proc_proargdefaults,
- &isnull);
- if (isnull)
- elog(ERROR, "not enough default arguments");
+ proargdefaults = SysCacheGetAttrNotNull(PROCOID, func_tuple,
+ Anum_pg_proc_proargdefaults);
str = TextDatumGetCString(proargdefaults);
defaults = castNode(List, stringToNode(str));
pfree(str);
@@ -4457,12 +4452,9 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
fexpr->location = -1;
/* Fetch the function body */
- tmp = SysCacheGetAttr(PROCOID,
- func_tuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", funcid);
+ tmp = SysCacheGetAttrNotNull(PROCOID,
+ func_tuple,
+ Anum_pg_proc_prosrc);
src = TextDatumGetCString(tmp);
/*
@@ -5015,12 +5007,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
oldcxt = MemoryContextSwitchTo(mycxt);
/* Fetch the function body */
- tmp = SysCacheGetAttr(PROCOID,
- func_tuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", func_oid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc);
src = TextDatumGetCString(tmp);
/*
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index ca14f06308..b3f0b6a137 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -1632,7 +1632,6 @@ func_get_detail(List *funcname,
if (argdefaults && best_candidate->ndargs > 0)
{
Datum proargdefaults;
- bool isnull;
char *str;
List *defaults;
@@ -1640,10 +1639,8 @@ func_get_detail(List *funcname,
if (best_candidate->ndargs > pform->pronargdefaults)
elog(ERROR, "not enough default arguments");
- proargdefaults = SysCacheGetAttr(PROCOID, ftup,
- Anum_pg_proc_proargdefaults,
- &isnull);
- Assert(!isnull);
+ proargdefaults = SysCacheGetAttrNotNull(PROCOID, ftup,
+ Anum_pg_proc_proargdefaults);
str = TextDatumGetCString(proargdefaults);
defaults = castNode(List, stringToNode(str));
pfree(str);
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index f9218f48aa..e62f2909c2 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1562,15 +1562,13 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
amrec = (Form_pg_am) GETSTRUCT(ht_am);
/* Extract indcollation from the pg_index tuple */
- datum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indcollation);
indcollation = (oidvector *) DatumGetPointer(datum);
/* Extract indclass from the pg_index tuple */
- datum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(datum);
/* Begin building the IndexStmt */
@@ -1641,13 +1639,8 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
Assert(conrec->contype == CONSTRAINT_EXCLUSION);
/* Extract operator OIDs from the pg_constraint tuple */
- datum = SysCacheGetAttr(CONSTROID, ht_constr,
- Anum_pg_constraint_conexclop,
- &isnull);
- if (isnull)
- elog(ERROR, "null conexclop for constraint %u",
- constraintId);
-
+ datum = SysCacheGetAttrNotNull(CONSTROID, ht_constr,
+ Anum_pg_constraint_conexclop);
deconstruct_array_builtin(DatumGetArrayTypeP(datum), OIDOID, &elems, NULL, &nElems);
for (i = 0; i < nElems; i++)
@@ -1898,9 +1891,8 @@ generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid,
statsrec = (Form_pg_statistic_ext) GETSTRUCT(ht_stats);
/* Determine which statistics types exist */
- datum = SysCacheGetAttr(STATEXTOID, ht_stats,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, ht_stats,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -2228,7 +2220,6 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
Form_pg_index index_form;
oidvector *indclass;
Datum indclassDatum;
- bool isnull;
int i;
/* Grammar should not allow this with explicit column list */
@@ -2327,9 +2318,9 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
parser_errposition(cxt->pstate, constraint->location)));
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, index_rel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID,
+ index_rel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
for (i = 0; i < index_form->indnatts; i++)
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index a69c1d1e77..cf1156b842 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -4311,19 +4311,14 @@ get_qual_for_range(Relation parent, PartitionBoundSpec *spec,
Oid inhrelid = inhoids[k];
HeapTuple tuple;
Datum datum;
- bool isnull;
PartitionBoundSpec *bspec;
tuple = SearchSysCache1(RELOID, inhrelid);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", inhrelid);
- datum = SysCacheGetAttr(RELOID, tuple,
- Anum_pg_class_relpartbound,
- &isnull);
- if (isnull)
- elog(ERROR, "null relpartbound for relation %u", inhrelid);
-
+ datum = SysCacheGetAttrNotNull(RELOID, tuple,
+ Anum_pg_class_relpartbound);
bspec = (PartitionBoundSpec *)
stringToNode(TextDatumGetCString(datum));
if (!IsA(bspec, PartitionBoundSpec))
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 572d9b4464..54e3bb4aa2 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -465,9 +465,8 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid)
}
/* decode the stxkind char array into a list of chars */
- datum = SysCacheGetAttr(STATEXTOID, htup,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, htup,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
diff --git a/src/backend/utils/adt/amutils.c b/src/backend/utils/adt/amutils.c
index 2fb5f64d36..b40f79b2c3 100644
--- a/src/backend/utils/adt/amutils.c
+++ b/src/backend/utils/adt/amutils.c
@@ -119,7 +119,6 @@ test_indoption(HeapTuple tuple, int attno, bool guard,
bool *res)
{
Datum datum;
- bool isnull;
int2vector *indoption;
int16 indoption_val;
@@ -129,9 +128,8 @@ test_indoption(HeapTuple tuple, int attno, bool guard,
return true;
}
- datum = SysCacheGetAttr(INDEXRELID, tuple,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, tuple,
+ Anum_pg_index_indoption);
indoption = ((int2vector *) DatumGetPointer(datum));
indoption_val = indoption->values[attno - 1];
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 274b8b9ccd..04f138b8cd 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1280,15 +1280,12 @@ lookup_collation_cache(Oid collation, bool set_flags)
if (collform->collprovider == COLLPROVIDER_LIBC)
{
Datum datum;
- bool isnull;
const char *collcollate;
const char *collctype;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
collcollate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
collctype = TextDatumGetCString(datum);
cache_entry->collate_is_c = ((strcmp(collcollate, "C") == 0) ||
@@ -1550,11 +1547,9 @@ pg_newlocale_from_collation(Oid collid)
const char *collctype pg_attribute_unused();
locale_t loc;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
collcollate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
collctype = TextDatumGetCString(datum);
if (strcmp(collcollate, collctype) == 0)
@@ -1609,8 +1604,7 @@ pg_newlocale_from_collation(Oid collid)
{
const char *iculocstr;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colliculocale, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colliculocale);
iculocstr = TextDatumGetCString(datum);
make_icu_collator(iculocstr, &result);
}
@@ -1624,8 +1618,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
TextDatumGetCString(datum));
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 6dc117dea8..91d172fad7 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -1228,7 +1228,6 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Datum indcollDatum;
Datum indclassDatum;
Datum indoptionDatum;
- bool isnull;
oidvector *indcollation;
oidvector *indclass;
int2vector *indoption;
@@ -1252,19 +1251,16 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Assert(indexrelid == idxrec->indexrelid);
/* Must get indcollation, indclass, and indoption the hard way */
- indcollDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ indcollDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indcollation);
indcollation = (oidvector *) DatumGetPointer(indcollDatum);
- indclassDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
- indoptionDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ indoptionDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indoption);
indoption = (int2vector *) DatumGetPointer(indoptionDatum);
/*
@@ -1297,9 +1293,8 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Datum exprsDatum;
char *exprsString;
- exprsDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indexprs);
exprsString = TextDatumGetCString(exprsDatum);
indexprs = (List *) stringToNode(exprsString);
pfree(exprsString);
@@ -1494,9 +1489,8 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
char *predString;
/* Convert text string to node tree */
- predDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indpred, &isnull);
- Assert(!isnull);
+ predDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indpred);
predString = TextDatumGetCString(predDatum);
node = (Node *) stringToNode(predString);
pfree(predString);
@@ -1637,12 +1631,10 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
if (has_exprs)
{
Datum exprsDatum;
- bool isnull;
char *exprsString;
- exprsDatum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxexprs);
exprsString = TextDatumGetCString(exprsDatum);
exprs = (List *) stringToNode(exprsString);
pfree(exprsString);
@@ -1657,8 +1649,6 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
if (!columns_only)
{
- bool isnull;
-
nsp = get_namespace_name_or_temp(statextrec->stxnamespace);
appendStringInfo(&buf, "CREATE STATISTICS %s",
quote_qualified_identifier(nsp,
@@ -1668,9 +1658,8 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
* Decode the stxkind column so that we know which stats types to
* print.
*/
- datum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -1790,7 +1779,6 @@ pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS)
Form_pg_statistic_ext statextrec;
HeapTuple statexttup;
Datum datum;
- bool isnull;
List *context;
ListCell *lc;
List *exprs = NIL;
@@ -1818,10 +1806,8 @@ pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS)
/*
* Get the statistics expressions, and deparse them into text values.
*/
- datum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxexprs, &isnull);
-
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxexprs);
tmp = TextDatumGetCString(datum);
exprs = (List *) stringToNode(tmp);
pfree(tmp);
@@ -1897,7 +1883,6 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
ListCell *partexpr_item;
List *context;
Datum datum;
- bool isnull;
StringInfoData buf;
int keyno;
char *str;
@@ -1916,14 +1901,12 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
Assert(form->partrelid == relid);
/* Must get partclass and partcollation the hard way */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partclass);
partclass = (oidvector *) DatumGetPointer(datum);
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partcollation);
partcollation = (oidvector *) DatumGetPointer(datum);
@@ -1937,9 +1920,8 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
Datum exprsDatum;
char *exprsString;
- exprsDatum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partexprs);
exprsString = TextDatumGetCString(exprsDatum);
partexprs = (List *) stringToNode(exprsString);
@@ -2229,11 +2211,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoString(&buf, "FOREIGN KEY (");
/* Fetch and build referencing-column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conkey, &isnull);
- if (isnull)
- elog(ERROR, "null conkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conkey);
decompile_column_index_array(val, conForm->conrelid, &buf);
@@ -2243,11 +2222,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
NIL));
/* Fetch and build referenced-column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_confkey, &isnull);
- if (isnull)
- elog(ERROR, "null confkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_confkey);
decompile_column_index_array(val, conForm->confrelid, &buf);
@@ -2345,7 +2321,6 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
case CONSTRAINT_UNIQUE:
{
Datum val;
- bool isnull;
Oid indexId;
int keyatts;
HeapTuple indtup;
@@ -2368,21 +2343,16 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoChar(&buf, '(');
/* Fetch and build target column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conkey, &isnull);
- if (isnull)
- elog(ERROR, "null conkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conkey);
keyatts = decompile_column_index_array(val, conForm->conrelid, &buf);
appendStringInfoChar(&buf, ')');
/* Build including column list (from pg_index.indkeys) */
- val = SysCacheGetAttr(INDEXRELID, indtup,
- Anum_pg_index_indnatts, &isnull);
- if (isnull)
- elog(ERROR, "null indnatts for index %u", indexId);
+ val = SysCacheGetAttrNotNull(INDEXRELID, indtup,
+ Anum_pg_index_indnatts);
if (DatumGetInt32(val) > keyatts)
{
Datum cols;
@@ -2392,10 +2362,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoString(&buf, " INCLUDE (");
- cols = SysCacheGetAttr(INDEXRELID, indtup,
- Anum_pg_index_indkey, &isnull);
- if (isnull)
- elog(ERROR, "null indkey for index %u", indexId);
+ cols = SysCacheGetAttrNotNull(INDEXRELID, indtup,
+ Anum_pg_index_indkey);
deconstruct_array_builtin(DatumGetArrayTypeP(cols), INT2OID,
&keys, NULL, &nKeys);
@@ -2444,18 +2412,14 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
case CONSTRAINT_CHECK:
{
Datum val;
- bool isnull;
char *conbin;
char *consrc;
Node *expr;
List *context;
/* Fetch constraint expression in parsetree form */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conbin, &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
expr = stringToNode(conbin);
@@ -2507,19 +2471,14 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
{
Oid indexOid = conForm->conindid;
Datum val;
- bool isnull;
Datum *elems;
int nElems;
int i;
Oid *operators;
/* Extract operator OIDs from the pg_constraint tuple */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conexclop,
- &isnull);
- if (isnull)
- elog(ERROR, "null conexclop for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conexclop);
deconstruct_array_builtin(DatumGetArrayTypeP(val), OIDOID,
&elems, NULL, &nElems);
@@ -3088,9 +3047,7 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
appendStringInfoString(&buf, ", "); /* assume prosrc isn't null */
}
- tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ tmp = SysCacheGetAttrNotNull(PROCOID, proctup, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
/*
@@ -3512,7 +3469,6 @@ print_function_sqlbody(StringInfo buf, HeapTuple proctup)
char *argmodes;
deparse_namespace dpns = {0};
Datum tmp;
- bool isnull;
Node *n;
dpns.funcname = pstrdup(NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname));
@@ -3521,8 +3477,7 @@ print_function_sqlbody(StringInfo buf, HeapTuple proctup)
dpns.numargs = numargs;
dpns.argnames = argnames;
- tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosqlbody, &isnull);
- Assert(!isnull);
+ tmp = SysCacheGetAttrNotNull(PROCOID, proctup, Anum_pg_proc_prosqlbody);
n = stringToNode(TextDatumGetCString(tmp));
if (IsA(n, List))
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index c07382051d..c7607895cd 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -3195,7 +3195,6 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
int i;
Datum val;
- bool isnull;
ArrayType *statarray;
Oid arrayelemtype;
int narrayelem;
@@ -3219,11 +3218,8 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
if (flags & ATTSTATSSLOT_VALUES)
{
- val = SysCacheGetAttr(STATRELATTINH, statstuple,
- Anum_pg_statistic_stavalues1 + i,
- &isnull);
- if (isnull)
- elog(ERROR, "stavalues is null");
+ val = SysCacheGetAttrNotNull(STATRELATTINH, statstuple,
+ Anum_pg_statistic_stavalues1 + i);
/*
* Detoast the array if needed, and in any case make a copy that's
@@ -3267,11 +3263,8 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
if (flags & ATTSTATSSLOT_NUMBERS)
{
- val = SysCacheGetAttr(STATRELATTINH, statstuple,
- Anum_pg_statistic_stanumbers1 + i,
- &isnull);
- if (isnull)
- elog(ERROR, "stanumbers is null");
+ val = SysCacheGetAttrNotNull(STATRELATTINH, statstuple,
+ Anum_pg_statistic_stanumbers1 + i);
/*
* Detoast the array if needed, and in any case make a copy that's
@@ -3479,7 +3472,6 @@ get_index_column_opclass(Oid index_oid, int attno)
HeapTuple tuple;
Form_pg_index rd_index;
Datum datum;
- bool isnull;
oidvector *indclass;
Oid opclass;
@@ -3501,10 +3493,7 @@ get_index_column_opclass(Oid index_oid, int attno)
return InvalidOid;
}
- datum = SysCacheGetAttr(INDEXRELID, tuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
-
+ datum = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indclass);
indclass = ((oidvector *) DatumGetPointer(datum));
Assert(attno <= indclass->dim1);
diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c
index 4f53d47233..5f3516ad0c 100644
--- a/src/backend/utils/cache/partcache.c
+++ b/src/backend/utils/cache/partcache.c
@@ -130,15 +130,13 @@ RelationBuildPartitionKey(Relation relation)
/* But use the hard way to retrieve further variable-length attributes */
/* Operator class */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partclass);
opclass = (oidvector *) DatumGetPointer(datum);
/* Collation */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partcollation);
collation = (oidvector *) DatumGetPointer(datum);
/* Expressions */
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 94abede512..8fde14c9d1 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -1099,6 +1099,27 @@ SysCacheGetAttr(int cacheId, HeapTuple tup,
isNull);
}
+/*
+ * SysCacheGetAttrNotNull
+ *
+ * As above, a version of SysCacheGetAttr which knows that the attr cannot
+ * be NULL.
+ */
+Datum
+SysCacheGetAttrNotNull(int cacheId, HeapTuple tup,
+ AttrNumber attributeNumber)
+{
+ bool isnull;
+ Datum attr = SysCacheGetAttr(cacheId, tup, attributeNumber, &isnull);
+
+ /*
+ * TODO: a better error message */
+ if (unlikely(isnull))
+ elog(ERROR, "unexpected NULL value in cached tuple");
+
+ return attr;
+}
+
/*
* GetSysCacheHashValue
*
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 3f64161760..f72dd25efa 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -151,7 +151,6 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
HeapTuple procedureTuple;
Form_pg_proc procedureStruct;
Datum prosrcdatum;
- bool isnull;
char *prosrc;
/*
@@ -227,10 +226,8 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
* internal function is stored in prosrc (it doesn't have to be
* the same as the name of the alias!)
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(prosrcdatum);
fbp = fmgr_lookupByName(prosrc);
if (fbp == NULL)
@@ -285,7 +282,6 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
{
HeapTuple procedureTuple;
Form_pg_proc procedureStruct;
- bool isnull;
Datum prosrcattr;
Datum probinattr;
@@ -308,25 +304,19 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
switch (procedureStruct->prolang)
{
case INTERNALlanguageId:
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
*mod = NULL; /* core binary */
*fn = TextDatumGetCString(prosrcattr);
break;
case ClanguageId:
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", functionId);
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
- probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", functionId);
+ probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_probin);
/*
* No need to check symbol presence / API version here, already
@@ -361,7 +351,6 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
CFuncHashTabEntry *hashentry;
PGFunction user_fn;
const Pg_finfo_record *inforec;
- bool isnull;
/*
* See if we have the function address cached already
@@ -385,16 +374,12 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
* While in general these columns might be null, that's not allowed
* for C-language functions.
*/
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", functionId);
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
prosrcstring = TextDatumGetCString(prosrcattr);
- probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", functionId);
+ probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_probin);
probinstring = TextDatumGetCString(probinattr);
/* Look up the function itself */
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 217835d590..24683bb608 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -1602,7 +1602,6 @@ get_func_result_name(Oid functionId)
HeapTuple procTuple;
Datum proargmodes;
Datum proargnames;
- bool isnull;
ArrayType *arr;
int numargs;
char *argmodes;
@@ -1623,14 +1622,10 @@ get_func_result_name(Oid functionId)
else
{
/* Get the data out of the tuple */
- proargmodes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargmodes,
- &isnull);
- Assert(!isnull);
- proargnames = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargnames,
- &isnull);
- Assert(!isnull);
+ proargmodes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargmodes);
+ proargnames = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargnames);
/*
* We expect the arrays to be 1-D arrays of the right types; verify
@@ -1717,14 +1712,10 @@ build_function_result_tupdesc_t(HeapTuple procTuple)
return NULL;
/* Get the data out of the tuple */
- proallargtypes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proallargtypes,
- &isnull);
- Assert(!isnull);
- proargmodes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargmodes,
- &isnull);
- Assert(!isnull);
+ proallargtypes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proallargtypes);
+ proargmodes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargmodes);
proargnames = SysCacheGetAttr(PROCOID, procTuple,
Anum_pg_proc_proargnames,
&isnull);
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 2f07ca7a0e..74026d8019 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -398,11 +398,9 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
/* assign locale variables */
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_datcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datcollate);
collate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_datctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datctype);
ctype = TextDatumGetCString(datum);
if (pg_perm_setlocale(LC_COLLATE, collate) == NULL)
@@ -421,8 +419,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticulocale, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_daticulocale);
iculocale = TextDatumGetCString(datum);
make_icu_collator(iculocale, &default_locale);
}
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index d5d50ceab4..28c72558d5 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -157,6 +157,9 @@ extern HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum);
extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
AttrNumber attributeNumber, bool *isNull);
+extern Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup,
+ AttrNumber attributeNumber);
+
extern uint32 GetSysCacheHashValue(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4);
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 8143ae40a0..d7d9c1bee3 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -2915,10 +2915,8 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger)
* we do not use a named subroutine so that we can call directly
* through the reference.
************************************************************/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
/************************************************************
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 7db912fd18..3deb53e408 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -271,7 +271,6 @@ do_compile(FunctionCallInfo fcinfo,
bool is_dml_trigger = CALLED_AS_TRIGGER(fcinfo);
bool is_event_trigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
Datum prosrcdatum;
- bool isnull;
char *proc_source;
HeapTuple typeTup;
Form_pg_type typeStruct;
@@ -296,10 +295,8 @@ do_compile(FunctionCallInfo fcinfo,
* cannot be invoked recursively, so there's no need to save and restore
* the static variables used here.
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
plpgsql_scanner_init(proc_source);
diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c
index 494f109b32..79b6ef6a44 100644
--- a/src/pl/plpython/plpy_procedure.c
+++ b/src/pl/plpython/plpy_procedure.c
@@ -324,10 +324,8 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
/*
* get the text of the function.
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
procSource = TextDatumGetCString(prosrcdatum);
PLy_procedure_compile(proc, procSource);
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 499a9eaba8..56c3a60fdd 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -1673,10 +1673,8 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid,
/************************************************************
* Add user's function definition to proc body
************************************************************/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
UTF_BEGIN;
Tcl_DStringAppend(&proc_internal_body, UTF_E2U(proc_source), -1);
--
2.32.1 (Apple Git-133)
Daniel Gustafsson <daniel@yesql.se> writes:
The attached refactoring introduce SysCacheGetAttrNotNull as a wrapper around
SysCacheGetAttr where a NULL value triggers an elog().
+1, seems like a good idea. (I didn't review the patch details.)
This will reduce granularity of error messages, and as the patch sits now it
does so a lot since the message is left to work on - I wanted to see if this
was at all seen as a net positive before spending time on that part. I chose
an elog since I as a user would prefer to hit an elog instead of a silent keep
going with an assert, this is of course debateable.
I'd venture that the Assert cases are mostly from laziness, and
that once we centralize this it's plenty worthwhile to generate
a decent elog message. You ought to be able to look up the
table and column name from the info that is at hand.
Also ... at least in assert-enabled builds, maybe we could check that
the column being fetched this way is actually marked attnotnull?
That would help to catch misuse.
regards, tom lane
On 28.02.23 21:14, Daniel Gustafsson wrote:
Today we have two fairly common patterns around extracting an attr from a
cached tuple:a = SysCacheGetAttr(OID, tuple, Anum_pg_foo_bar, &isnull);
Assert(!isnull);a = SysCacheGetAttr(OID, tuple, Anum_pg_foo_bar, &isnull);
if (isnull)
elog(ERROR, "..");
The attached refactoring introduce SysCacheGetAttrNotNull as a wrapper around
SysCacheGetAttr where a NULL value triggers an elog(). This removes a lot of
boilerplate error handling which IMO leads to increased readability as the
error handling *in these cases* don't add much (there are other cases where
checking isnull does a lot of valuable work of course). Personally I much
prefer the error-out automatically style of APIs like how palloc saves a ton of
checking the returned allocation for null, this aims at providing a similar
abstraction.
Yes please!
I have occasionally wondered whether just passing the isnull argument as
NULL would be sufficient, so we don't need a new function.
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
Yes please!
I have occasionally wondered whether just passing the isnull argument as
NULL would be sufficient, so we don't need a new function.
I thought about that too. I think I prefer Daniel's formulation
with the new function, but I'm not especially set on that.
An advantage of using a new function name is it'd be more obvious
what's wrong if you try to back-patch such code into a branch that
lacks the feature. (Or, of course, we could back-patch the feature.)
regards, tom lane
On 1 Mar 2023, at 21:04, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
Yes please!
I have occasionally wondered whether just passing the isnull argument as
NULL would be sufficient, so we don't need a new function.I thought about that too. I think I prefer Daniel's formulation
with the new function, but I'm not especially set on that.
I prefer the new function since the name makes the code self documented rather
than developers not used to the API having to look up what the last NULL
actually means.
--
Daniel Gustafsson
On 28.02.23 21:14, Daniel Gustafsson wrote:
The attached refactoring introduce SysCacheGetAttrNotNull as a wrapper around
SysCacheGetAttr where a NULL value triggers an elog(). This removes a lot of
boilerplate error handling which IMO leads to increased readability as the
error handling *in these cases* don't add much (there are other cases where
checking isnull does a lot of valuable work of course). Personally I much
prefer the error-out automatically style of APIs like how palloc saves a ton of
checking the returned allocation for null, this aims at providing a similar
abstraction.
I looked through the patch. The changes look ok to me. In some cases,
more line breaks could be removed (that is, the whole call could be put
on one line now).
This will reduce granularity of error messages, and as the patch sits now it
does so a lot since the message is left to work on - I wanted to see if this
was at all seen as a net positive before spending time on that part. I chose
an elog since I as a user would prefer to hit an elog instead of a silent keep
going with an assert, this is of course debateable.
I think an error message like
"unexpected null value in system cache %d column %d"
is sufficient. Since these are "can't happen" errors, we don't need to
spend too much extra effort to make it prettier.
I don't think the unlikely() is going to buy much. If you are worried
on that level, SysCacheGetAttrNotNull() ought to be made inline.
Looking through the sites of the changes, I didn't find any callers
where I'd be worried on that level.
On 1 Mar 2023, at 00:20, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Also ... at least in assert-enabled builds, maybe we could check that
the column being fetched this way is actually marked attnotnull?
That would help to catch misuse.
We could, but that would limit the API to attnotnull columns, rather than when
the caller knows that the attr cannot be NULL either due to attnotnull or due
to intrinsic knowledge based on what is being extracted.
An example of the latter is build_function_result_tupdesc_t() which knows that
proallargtypes cannot be NULL when calling SysCacheGetAttr.
I think I prefer to allow those cases rather than the strict mode where
attnotnull has to be true, do you think it's preferrable to align the API with
attnotnull and keep the current coding for cases like the above?
--
Daniel Gustafsson
On 2 Mar 2023, at 10:59, Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
On 28.02.23 21:14, Daniel Gustafsson wrote:
The attached refactoring introduce SysCacheGetAttrNotNull as a wrapper around
SysCacheGetAttr where a NULL value triggers an elog(). This removes a lot of
boilerplate error handling which IMO leads to increased readability as the
error handling *in these cases* don't add much (there are other cases where
checking isnull does a lot of valuable work of course). Personally I much
prefer the error-out automatically style of APIs like how palloc saves a ton of
checking the returned allocation for null, this aims at providing a similar
abstraction.I looked through the patch.
Thanks!
The changes look ok to me. In some cases, more line breaks could be removed (that is, the whole call could be put on one line now).
I've tried to find those that would fit on a single line in the attached v2.
This will reduce granularity of error messages, and as the patch sits now it
does so a lot since the message is left to work on - I wanted to see if this
was at all seen as a net positive before spending time on that part. I chose
an elog since I as a user would prefer to hit an elog instead of a silent keep
going with an assert, this is of course debateable.I think an error message like
"unexpected null value in system cache %d column %d"
is sufficient. Since these are "can't happen" errors, we don't need to spend too much extra effort to make it prettier.
They really should never happen, but since we have all the information we need
it seems reasonable to ease debugging. I've made a slightly extended elog in
the attached patch.
Callsites which had a detailed errormessage have been left passing isnull, like
for example statext_expressions_load().
I don't think the unlikely() is going to buy much. If you are worried on that level, SysCacheGetAttrNotNull() ought to be made inline. Looking through the sites of the changes, I didn't find any callers where I'd be worried on that level.
Fair enough, removed.
--
Daniel Gustafsson
Attachments:
v2-0001-Add-SysCacheGetAttrNotNull-for-guarnteed-not-null.patchapplication/octet-stream; name=v2-0001-Add-SysCacheGetAttrNotNull-for-guarnteed-not-null.patch; x-unix-mode=0644Download
From 4ea9210a96b96d168caa61438e061c55dfa8fef4 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <dgustafsson@postgresql.org>
Date: Thu, 2 Mar 2023 12:27:02 +0100
Subject: [PATCH v2] Add SysCacheGetAttrNotNull for guarnteed not-null attrs
When extracting an attr from a cached tuple in the syscache with
SysCacheGetAttr the isnull parameter must be checked in case the
attr cannot be NULL. For cases when this is known beforehand, a
wrapper is introduced which perform the errorhandling internally
on behalf of the caller, invoking an elog in case of a NULL attr.
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Discussion: https://postgr.es/m/AD76405E-DB45-46B6-941F-17B1EB3A9076@yesql.se
---
src/backend/access/brin/brin_inclusion.c | 7 +-
src/backend/access/brin/brin_minmax.c | 7 +-
src/backend/access/brin/brin_minmax_multi.c | 7 +-
src/backend/access/index/indexam.c | 6 +-
src/backend/catalog/aclchk.c | 38 +++---
src/backend/catalog/index.c | 20 ++--
src/backend/catalog/objectaddress.c | 23 ++--
src/backend/catalog/pg_constraint.c | 33 ++----
src/backend/catalog/pg_proc.c | 25 +---
src/backend/catalog/pg_subscription.c | 32 ++----
src/backend/commands/collationcmds.c | 23 ++--
src/backend/commands/dbcommands.c | 11 +-
src/backend/commands/indexcmds.c | 7 +-
src/backend/commands/matview.c | 9 +-
src/backend/commands/subscriptioncmds.c | 10 +-
src/backend/commands/tablecmds.c | 27 ++---
src/backend/commands/typecmds.c | 8 +-
src/backend/executor/execReplication.c | 6 +-
src/backend/executor/functions.c | 7 +-
src/backend/optimizer/util/clauses.c | 23 +---
src/backend/parser/parse_func.c | 7 +-
src/backend/parser/parse_utilcmd.c | 30 ++---
src/backend/partitioning/partbounds.c | 9 +-
src/backend/statistics/extended_stats.c | 5 +-
src/backend/utils/adt/amutils.c | 5 +-
src/backend/utils/adt/pg_locale.c | 19 +--
src/backend/utils/adt/ruleutils.c | 121 ++++++--------------
src/backend/utils/cache/lsyscache.c | 21 +---
src/backend/utils/cache/partcache.c | 10 +-
src/backend/utils/cache/syscache.c | 27 +++++
src/backend/utils/fmgr/fmgr.c | 39 ++-----
src/backend/utils/fmgr/funcapi.c | 25 ++--
src/backend/utils/init/postinit.c | 9 +-
src/include/utils/syscache.h | 3 +
src/pl/plperl/plperl.c | 6 +-
src/pl/plpgsql/src/pl_comp.c | 6 +-
src/pl/plpython/plpy_procedure.c | 6 +-
src/pl/tcl/pltcl.c | 7 +-
38 files changed, 232 insertions(+), 452 deletions(-)
diff --git a/src/backend/access/brin/brin_inclusion.c b/src/backend/access/brin/brin_inclusion.c
index 248116c149..02f4d0ae76 100644
--- a/src/backend/access/brin/brin_inclusion.c
+++ b/src/backend/access/brin/brin_inclusion.c
@@ -630,7 +630,6 @@ inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -643,10 +642,10 @@ inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c
index 2431591be6..8229493c84 100644
--- a/src/backend/access/brin/brin_minmax.c
+++ b/src/backend/access/brin/brin_minmax.c
@@ -290,7 +290,6 @@ minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -303,10 +302,10 @@ minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
index 0ace6035be..84bcdf49a9 100644
--- a/src/backend/access/brin/brin_minmax_multi.c
+++ b/src/backend/access/brin/brin_minmax_multi.c
@@ -2953,7 +2953,6 @@ minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -2965,10 +2964,10 @@ minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index dbf147ed22..b25b03f7ab 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -961,7 +961,6 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
Oid opclass;
Datum indclassDatum;
oidvector *indclass;
- bool isnull;
if (!DatumGetPointer(attoptions))
return NULL; /* ok, no options, no procedure */
@@ -970,9 +969,8 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
* Report an error if the opclass's options-parsing procedure does not
* exist but the opclass options are specified.
*/
- indclassDatum = SysCacheGetAttr(INDEXRELID, indrel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indrel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
opclass = indclass->values[attnum - 1];
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index c4232344aa..03febea7ba 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -2178,11 +2178,9 @@ ExecGrant_common(InternalGrant *istmt, Oid classid, AclMode default_privs,
* Get owner ID and working copy of existing ACL. If there's no ACL,
* substitute the proper default.
*/
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isNull));
- Assert(!isNull);
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
aclDatum = SysCacheGetAttr(cacheid,
tuple,
get_object_attnum_acl(classid),
@@ -2206,10 +2204,8 @@ ExecGrant_common(InternalGrant *istmt, Oid classid, AclMode default_privs,
old_acl, ownerId,
&grantorId, &avail_goptions);
- nameDatum = SysCacheGetAttr(cacheid, tuple,
- get_object_attnum_name(classid),
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(cacheid, tuple,
+ get_object_attnum_name(classid));
/*
* Restrict the privileges to what we can actually grant, and emit the
@@ -2476,10 +2472,8 @@ ExecGrant_Parameter(InternalGrant *istmt)
parameterId);
/* We'll need the GUC's name */
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tuple,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tuple,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
/* Treat all parameters as belonging to the bootstrap superuser. */
@@ -3113,11 +3107,9 @@ object_aclmask(Oid classid, Oid objectid, Oid roleid,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isNull));
- Assert(!isNull);
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
aclDatum = SysCacheGetAttr(cacheid, tuple, get_object_attnum_acl(classid),
&isNull);
@@ -3994,7 +3986,6 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
if (cacheid != -1)
{
HeapTuple tuple;
- bool isnull;
tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
if (!HeapTupleIsValid(tuple))
@@ -4002,12 +3993,9 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isnull));
- Assert(!isnull);
-
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
ReleaseSysCache(tuple);
}
else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 7777e7ec77..864f2e6d86 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1320,14 +1320,12 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(oldIndexId));
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "cache lookup failed for index %u", oldIndexId);
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
- colOptionDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ colOptionDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indoption);
indcoloptions = (int2vector *) DatumGetPointer(colOptionDatum);
/* Fetch options of index if any */
@@ -1347,9 +1345,8 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
Datum exprDatum;
char *exprString;
- exprDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indexprs, &isnull);
- Assert(!isnull);
+ exprDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indexprs);
exprString = TextDatumGetCString(exprDatum);
indexExprs = (List *) stringToNode(exprString);
pfree(exprString);
@@ -1359,9 +1356,8 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
Datum predDatum;
char *predString;
- predDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indpred, &isnull);
- Assert(!isnull);
+ predDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indpred);
predString = TextDatumGetCString(predDatum);
indexPreds = (List *) stringToNode(predString);
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 2f688166e1..65f877c5b7 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -2597,7 +2597,6 @@ get_object_namespace(const ObjectAddress *address)
{
int cache;
HeapTuple tuple;
- bool isnull;
Oid oid;
const ObjectPropertyType *property;
@@ -2615,11 +2614,9 @@ get_object_namespace(const ObjectAddress *address)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for cache %d oid %u",
cache, address->objectId);
- oid = DatumGetObjectId(SysCacheGetAttr(cache,
- tuple,
- property->attnum_namespace,
- &isnull));
- Assert(!isnull);
+ oid = DatumGetObjectId(SysCacheGetAttrNotNull(cache,
+ tuple,
+ property->attnum_namespace));
ReleaseSysCache(tuple);
return oid;
@@ -3890,7 +3887,6 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
{
HeapTuple tup;
Datum nameDatum;
- bool isNull;
char *parname;
tup = SearchSysCache1(PARAMETERACLOID,
@@ -3902,10 +3898,8 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
object->objectId);
break;
}
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tup,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
appendStringInfo(&buffer, _("parameter %s"), parname);
ReleaseSysCache(tup);
@@ -5753,7 +5747,6 @@ getObjectIdentityParts(const ObjectAddress *object,
{
HeapTuple tup;
Datum nameDatum;
- bool isNull;
char *parname;
tup = SearchSysCache1(PARAMETERACLOID,
@@ -5765,10 +5758,8 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
break;
}
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tup,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
appendStringInfoString(&buffer, parname);
if (objname)
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 7392c72e90..ce82ede7f9 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -1190,23 +1190,18 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs,
int *num_fk_del_set_cols, AttrNumber *fk_del_set_cols)
{
- Oid constrId;
Datum adatum;
bool isNull;
ArrayType *arr;
int numkeys;
- constrId = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
-
/*
* We expect the arrays to be 1-D arrays of the right types; verify that.
* We don't need to use deconstruct_array() since the array data is just
* going to look like a C array of values.
*/
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conkey, &isNull);
- if (isNull)
- elog(ERROR, "null conkey for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conkey);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -1219,10 +1214,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if ((Pointer) arr != DatumGetPointer(adatum))
pfree(arr); /* free de-toasted copy, if any */
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_confkey, &isNull);
- if (isNull)
- elog(ERROR, "null confkey for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_confkey);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
@@ -1235,10 +1228,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (pf_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conpfeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conpfeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conpfeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
/* see TryReuseForeignKey if you change the test below */
if (ARR_NDIM(arr) != 1 ||
@@ -1253,10 +1244,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (pp_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conppeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conppeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conppeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
@@ -1270,10 +1259,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (ff_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conffeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conffeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conffeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 14d552fe2d..41fa2a4987 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -520,10 +520,8 @@ ProcedureCreate(const char *procedureName,
dropcmd,
format_procedure(oldproc->oid))));
- proargdefaults = SysCacheGetAttr(PROCNAMEARGSNSP, oldtup,
- Anum_pg_proc_proargdefaults,
- &isnull);
- Assert(!isnull);
+ proargdefaults = SysCacheGetAttrNotNull(PROCNAMEARGSNSP, oldtup,
+ Anum_pg_proc_proargdefaults);
oldDefaults = castNode(List, stringToNode(TextDatumGetCString(proargdefaults)));
Assert(list_length(oldDefaults) == oldproc->pronargdefaults);
@@ -731,7 +729,6 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
{
Oid funcoid = PG_GETARG_OID(0);
HeapTuple tuple;
- bool isnull;
Datum tmp;
char *prosrc;
@@ -747,9 +744,7 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for function %u", funcoid);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
if (fmgr_internal_function(prosrc) == InvalidOid)
@@ -778,7 +773,6 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
Oid funcoid = PG_GETARG_OID(0);
void *libraryhandle;
HeapTuple tuple;
- bool isnull;
Datum tmp;
char *prosrc;
char *probin;
@@ -796,14 +790,10 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for function %u", funcoid);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", funcoid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", funcoid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_probin);
probin = TextDatumGetCString(tmp);
(void) load_external_function(probin, prosrc, true, &libraryhandle);
@@ -876,10 +866,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
/* Postpone body checks if !check_function_bodies */
if (check_function_bodies)
{
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
-
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
/*
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index a56ae311c3..d322b9482c 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -73,11 +73,9 @@ GetSubscription(Oid subid, bool missing_ok)
sub->disableonerr = subform->subdisableonerr;
/* Get conninfo */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subconninfo,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subconninfo);
sub->conninfo = TextDatumGetCString(datum);
/* Get slotname */
@@ -91,27 +89,21 @@ GetSubscription(Oid subid, bool missing_ok)
sub->slotname = NULL;
/* Get synccommit */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subsynccommit,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subsynccommit);
sub->synccommit = TextDatumGetCString(datum);
/* Get publications */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subpublications,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subpublications);
sub->publications = textarray_to_stringlist(DatumGetArrayTypeP(datum));
/* Get origin */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_suborigin,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_suborigin);
sub->origin = TextDatumGetCString(datum);
ReleaseSysCache(tup);
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index eb62d285ea..e60a249963 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -384,9 +384,7 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate, &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_collation");
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
/* cannot change from NULL to non-NULL or vice versa */
@@ -437,7 +435,6 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
char *locale;
char *version;
Datum datum;
- bool isnull;
if (collid == DEFAULT_COLLATION_OID)
{
@@ -451,12 +448,9 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_database) GETSTRUCT(dbtup))->datlocprovider;
- datum = SysCacheGetAttr(DATABASEOID, dbtup,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_database_daticulocale : Anum_pg_database_datcollate,
- &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
+ provider == COLLPROVIDER_ICU ?
+ Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
locale = TextDatumGetCString(datum);
@@ -474,12 +468,9 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_collation) GETSTRUCT(colltp))->collprovider;
Assert(provider != COLLPROVIDER_DEFAULT);
- datum = SysCacheGetAttr(COLLOID, colltp,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate,
- &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_collation");
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp,
+ provider == COLLPROVIDER_ICU ?
+ Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
locale = TextDatumGetCString(datum);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index a0259cc593..12c8e2c739 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -2558,7 +2558,6 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
HeapTuple tp;
char datlocprovider;
Datum datum;
- bool isnull;
char *version;
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
@@ -2569,9 +2568,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttr(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate, &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
ReleaseSysCache(tp);
@@ -2697,14 +2694,12 @@ get_db_info(const char *name, LOCKMODE lockmode,
*dbLocProvider = dbform->datlocprovider;
if (dbCollate)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datcollate);
*dbCollate = TextDatumGetCString(datum);
}
if (dbCtype)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datctype);
*dbCtype = TextDatumGetCString(datum);
}
if (dbIculocale)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 16ec0b114e..c63350a6b7 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -188,7 +188,6 @@ CheckIndexCompatible(Oid oldId,
IndexInfo *indexInfo;
int numberOfAttributes;
int old_natts;
- bool isnull;
bool ret = true;
oidvector *old_indclass;
oidvector *old_indcollation;
@@ -267,12 +266,10 @@ CheckIndexCompatible(Oid oldId,
old_natts = indexForm->indnkeyatts;
Assert(old_natts == numberOfAttributes);
- d = SysCacheGetAttr(INDEXRELID, tuple, Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ d = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indcollation);
old_indcollation = (oidvector *) DatumGetPointer(d);
- d = SysCacheGetAttr(INDEXRELID, tuple, Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ d = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indclass);
old_indclass = (oidvector *) DatumGetPointer(d);
ret = (memcmp(old_indclass->values, classObjectId,
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index fb30d2595c..c00b9df3e3 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -692,15 +692,12 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
int indnkeyatts = indexStruct->indnkeyatts;
oidvector *indclass;
Datum indclassDatum;
- bool isnull;
int i;
/* Must get indclass the hard way. */
- indclassDatum = SysCacheGetAttr(INDEXRELID,
- indexRel->rd_indextuple,
- Anum_pg_index_indclass,
- &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID,
+ indexRel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/* Add quals for all columns from this index. */
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 464db6d247..8a26ddab1c 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -1436,15 +1436,13 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
LockSharedObject(SubscriptionRelationId, subid, 0, AccessExclusiveLock);
/* Get subname */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup,
- Anum_pg_subscription_subname, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, tup,
+ Anum_pg_subscription_subname);
subname = pstrdup(NameStr(*DatumGetName(datum)));
/* Get conninfo */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup,
- Anum_pg_subscription_subconninfo, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, tup,
+ Anum_pg_subscription_subconninfo);
conninfo = TextDatumGetCString(datum);
/* Get slotname */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 62d9917ca3..77fc3280b7 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -11078,7 +11078,6 @@ ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName,
List *children = NIL;
ListCell *child;
NewConstraint *newcon;
- bool isnull;
Datum val;
char *conbin;
@@ -11133,11 +11132,8 @@ ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName,
newcon->refindid = InvalidOid;
newcon->conid = con->oid;
- val = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conbin, &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u", con->oid);
-
+ val = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
newcon->qual = (Node *) stringToNode(conbin);
@@ -11239,7 +11235,6 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
HeapTuple indexTuple = NULL;
Form_pg_index indexStruct = NULL;
Datum indclassDatum;
- bool isnull;
oidvector *indclass;
int i;
@@ -11291,9 +11286,8 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
RelationGetRelationName(pkrel))));
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/*
@@ -11386,13 +11380,11 @@ transformFkeyCheckAttrs(Relation pkrel,
heap_attisnull(indexTuple, Anum_pg_index_indexprs, NULL))
{
Datum indclassDatum;
- bool isnull;
oidvector *indclass;
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/*
@@ -13544,7 +13536,6 @@ TryReuseForeignKey(Oid oldId, Constraint *con)
{
HeapTuple tup;
Datum adatum;
- bool isNull;
ArrayType *arr;
Oid *rawarr;
int numkeys;
@@ -13557,10 +13548,8 @@ TryReuseForeignKey(Oid oldId, Constraint *con)
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "cache lookup failed for constraint %u", oldId);
- adatum = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conpfeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conpfeqop for constraint %u", oldId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conpfeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
numkeys = ARR_DIMS(arr)[0];
/* test follows the one in ri_FetchConstraintInfo() */
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 04bddaef81..3440dbc440 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -3039,7 +3039,6 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
char *conbin;
SysScanDesc scan;
Datum val;
- bool isnull;
HeapTuple tuple;
HeapTuple copyTuple;
ScanKeyData skey[3];
@@ -3094,12 +3093,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
errmsg("constraint \"%s\" of domain \"%s\" is not a check constraint",
constrName, TypeNameToString(typename))));
- val = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conbin,
- &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u",
- con->oid);
+ val = SysCacheGetAttrNotNull(CONSTROID, tuple, Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
validateDomainConstraint(domainoid, conbin);
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index c484f5c301..8ee7ea63c5 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -51,7 +51,6 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel,
TupleTableSlot *searchslot)
{
int attoff;
- bool isnull;
Datum indclassDatum;
oidvector *opclass;
int2vector *indkey = &idxrel->rd_index->indkey;
@@ -60,9 +59,8 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel,
Assert(RelationGetReplicaIndex(rel) == RelationGetRelid(idxrel) ||
RelationGetPrimaryKeyIndex(rel) == RelationGetRelid(idxrel));
- indclassDatum = SysCacheGetAttr(INDEXRELID, idxrel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, idxrel->rd_indextuple,
+ Anum_pg_index_indclass);
opclass = (oidvector *) DatumGetPointer(indclassDatum);
/* Build scankey for every attribute in the index. */
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 50e06ec693..f55424eb5a 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -660,12 +660,7 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
/*
* And of course we need the function body text.
*/
- tmp = SysCacheGetAttr(PROCOID,
- procedureTuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", foid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, procedureTuple, Anum_pg_proc_prosrc);
fcache->src = TextDatumGetCString(tmp);
/* If we have prosqlbody, pay attention to that not prosrc. */
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 76e25118f9..fc245c60e4 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -4177,15 +4177,10 @@ fetch_function_defaults(HeapTuple func_tuple)
{
List *defaults;
Datum proargdefaults;
- bool isnull;
char *str;
- /* The error cases here shouldn't happen, but check anyway */
- proargdefaults = SysCacheGetAttr(PROCOID, func_tuple,
- Anum_pg_proc_proargdefaults,
- &isnull);
- if (isnull)
- elog(ERROR, "not enough default arguments");
+ proargdefaults = SysCacheGetAttrNotNull(PROCOID, func_tuple,
+ Anum_pg_proc_proargdefaults);
str = TextDatumGetCString(proargdefaults);
defaults = castNode(List, stringToNode(str));
pfree(str);
@@ -4457,12 +4452,7 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
fexpr->location = -1;
/* Fetch the function body */
- tmp = SysCacheGetAttr(PROCOID,
- func_tuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", funcid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc);
src = TextDatumGetCString(tmp);
/*
@@ -5015,12 +5005,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
oldcxt = MemoryContextSwitchTo(mycxt);
/* Fetch the function body */
- tmp = SysCacheGetAttr(PROCOID,
- func_tuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", func_oid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc);
src = TextDatumGetCString(tmp);
/*
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index ca14f06308..b3f0b6a137 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -1632,7 +1632,6 @@ func_get_detail(List *funcname,
if (argdefaults && best_candidate->ndargs > 0)
{
Datum proargdefaults;
- bool isnull;
char *str;
List *defaults;
@@ -1640,10 +1639,8 @@ func_get_detail(List *funcname,
if (best_candidate->ndargs > pform->pronargdefaults)
elog(ERROR, "not enough default arguments");
- proargdefaults = SysCacheGetAttr(PROCOID, ftup,
- Anum_pg_proc_proargdefaults,
- &isnull);
- Assert(!isnull);
+ proargdefaults = SysCacheGetAttrNotNull(PROCOID, ftup,
+ Anum_pg_proc_proargdefaults);
str = TextDatumGetCString(proargdefaults);
defaults = castNode(List, stringToNode(str));
pfree(str);
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index f9218f48aa..15a1dab8c5 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1562,15 +1562,12 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
amrec = (Form_pg_am) GETSTRUCT(ht_am);
/* Extract indcollation from the pg_index tuple */
- datum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indcollation);
indcollation = (oidvector *) DatumGetPointer(datum);
/* Extract indclass from the pg_index tuple */
- datum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx, Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(datum);
/* Begin building the IndexStmt */
@@ -1641,13 +1638,8 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
Assert(conrec->contype == CONSTRAINT_EXCLUSION);
/* Extract operator OIDs from the pg_constraint tuple */
- datum = SysCacheGetAttr(CONSTROID, ht_constr,
- Anum_pg_constraint_conexclop,
- &isnull);
- if (isnull)
- elog(ERROR, "null conexclop for constraint %u",
- constraintId);
-
+ datum = SysCacheGetAttrNotNull(CONSTROID, ht_constr,
+ Anum_pg_constraint_conexclop);
deconstruct_array_builtin(DatumGetArrayTypeP(datum), OIDOID, &elems, NULL, &nElems);
for (i = 0; i < nElems; i++)
@@ -1898,9 +1890,8 @@ generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid,
statsrec = (Form_pg_statistic_ext) GETSTRUCT(ht_stats);
/* Determine which statistics types exist */
- datum = SysCacheGetAttr(STATEXTOID, ht_stats,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, ht_stats,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -2228,7 +2219,6 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
Form_pg_index index_form;
oidvector *indclass;
Datum indclassDatum;
- bool isnull;
int i;
/* Grammar should not allow this with explicit column list */
@@ -2327,9 +2317,9 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
parser_errposition(cxt->pstate, constraint->location)));
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, index_rel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID,
+ index_rel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
for (i = 0; i < index_form->indnatts; i++)
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index a69c1d1e77..cf1156b842 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -4311,19 +4311,14 @@ get_qual_for_range(Relation parent, PartitionBoundSpec *spec,
Oid inhrelid = inhoids[k];
HeapTuple tuple;
Datum datum;
- bool isnull;
PartitionBoundSpec *bspec;
tuple = SearchSysCache1(RELOID, inhrelid);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", inhrelid);
- datum = SysCacheGetAttr(RELOID, tuple,
- Anum_pg_class_relpartbound,
- &isnull);
- if (isnull)
- elog(ERROR, "null relpartbound for relation %u", inhrelid);
-
+ datum = SysCacheGetAttrNotNull(RELOID, tuple,
+ Anum_pg_class_relpartbound);
bspec = (PartitionBoundSpec *)
stringToNode(TextDatumGetCString(datum));
if (!IsA(bspec, PartitionBoundSpec))
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 572d9b4464..54e3bb4aa2 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -465,9 +465,8 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid)
}
/* decode the stxkind char array into a list of chars */
- datum = SysCacheGetAttr(STATEXTOID, htup,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, htup,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
diff --git a/src/backend/utils/adt/amutils.c b/src/backend/utils/adt/amutils.c
index 2fb5f64d36..48852bf79e 100644
--- a/src/backend/utils/adt/amutils.c
+++ b/src/backend/utils/adt/amutils.c
@@ -119,7 +119,6 @@ test_indoption(HeapTuple tuple, int attno, bool guard,
bool *res)
{
Datum datum;
- bool isnull;
int2vector *indoption;
int16 indoption_val;
@@ -129,9 +128,7 @@ test_indoption(HeapTuple tuple, int attno, bool guard,
return true;
}
- datum = SysCacheGetAttr(INDEXRELID, tuple,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indoption);
indoption = ((int2vector *) DatumGetPointer(datum));
indoption_val = indoption->values[attno - 1];
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 4aa5eaa984..161044649e 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1280,15 +1280,12 @@ lookup_collation_cache(Oid collation, bool set_flags)
if (collform->collprovider == COLLPROVIDER_LIBC)
{
Datum datum;
- bool isnull;
const char *collcollate;
const char *collctype;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
collcollate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
collctype = TextDatumGetCString(datum);
cache_entry->collate_is_c = ((strcmp(collcollate, "C") == 0) ||
@@ -1550,11 +1547,9 @@ pg_newlocale_from_collation(Oid collid)
const char *collctype pg_attribute_unused();
locale_t loc;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
collcollate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
collctype = TextDatumGetCString(datum);
if (strcmp(collcollate, collctype) == 0)
@@ -1609,8 +1604,7 @@ pg_newlocale_from_collation(Oid collid)
{
const char *iculocstr;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colliculocale, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colliculocale);
iculocstr = TextDatumGetCString(datum);
make_icu_collator(iculocstr, &result);
}
@@ -1624,8 +1618,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
TextDatumGetCString(datum));
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 6dc117dea8..91d172fad7 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -1228,7 +1228,6 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Datum indcollDatum;
Datum indclassDatum;
Datum indoptionDatum;
- bool isnull;
oidvector *indcollation;
oidvector *indclass;
int2vector *indoption;
@@ -1252,19 +1251,16 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Assert(indexrelid == idxrec->indexrelid);
/* Must get indcollation, indclass, and indoption the hard way */
- indcollDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ indcollDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indcollation);
indcollation = (oidvector *) DatumGetPointer(indcollDatum);
- indclassDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
- indoptionDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ indoptionDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indoption);
indoption = (int2vector *) DatumGetPointer(indoptionDatum);
/*
@@ -1297,9 +1293,8 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Datum exprsDatum;
char *exprsString;
- exprsDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indexprs);
exprsString = TextDatumGetCString(exprsDatum);
indexprs = (List *) stringToNode(exprsString);
pfree(exprsString);
@@ -1494,9 +1489,8 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
char *predString;
/* Convert text string to node tree */
- predDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indpred, &isnull);
- Assert(!isnull);
+ predDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indpred);
predString = TextDatumGetCString(predDatum);
node = (Node *) stringToNode(predString);
pfree(predString);
@@ -1637,12 +1631,10 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
if (has_exprs)
{
Datum exprsDatum;
- bool isnull;
char *exprsString;
- exprsDatum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxexprs);
exprsString = TextDatumGetCString(exprsDatum);
exprs = (List *) stringToNode(exprsString);
pfree(exprsString);
@@ -1657,8 +1649,6 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
if (!columns_only)
{
- bool isnull;
-
nsp = get_namespace_name_or_temp(statextrec->stxnamespace);
appendStringInfo(&buf, "CREATE STATISTICS %s",
quote_qualified_identifier(nsp,
@@ -1668,9 +1658,8 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
* Decode the stxkind column so that we know which stats types to
* print.
*/
- datum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -1790,7 +1779,6 @@ pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS)
Form_pg_statistic_ext statextrec;
HeapTuple statexttup;
Datum datum;
- bool isnull;
List *context;
ListCell *lc;
List *exprs = NIL;
@@ -1818,10 +1806,8 @@ pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS)
/*
* Get the statistics expressions, and deparse them into text values.
*/
- datum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxexprs, &isnull);
-
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxexprs);
tmp = TextDatumGetCString(datum);
exprs = (List *) stringToNode(tmp);
pfree(tmp);
@@ -1897,7 +1883,6 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
ListCell *partexpr_item;
List *context;
Datum datum;
- bool isnull;
StringInfoData buf;
int keyno;
char *str;
@@ -1916,14 +1901,12 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
Assert(form->partrelid == relid);
/* Must get partclass and partcollation the hard way */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partclass);
partclass = (oidvector *) DatumGetPointer(datum);
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partcollation);
partcollation = (oidvector *) DatumGetPointer(datum);
@@ -1937,9 +1920,8 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
Datum exprsDatum;
char *exprsString;
- exprsDatum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partexprs);
exprsString = TextDatumGetCString(exprsDatum);
partexprs = (List *) stringToNode(exprsString);
@@ -2229,11 +2211,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoString(&buf, "FOREIGN KEY (");
/* Fetch and build referencing-column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conkey, &isnull);
- if (isnull)
- elog(ERROR, "null conkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conkey);
decompile_column_index_array(val, conForm->conrelid, &buf);
@@ -2243,11 +2222,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
NIL));
/* Fetch and build referenced-column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_confkey, &isnull);
- if (isnull)
- elog(ERROR, "null confkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_confkey);
decompile_column_index_array(val, conForm->confrelid, &buf);
@@ -2345,7 +2321,6 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
case CONSTRAINT_UNIQUE:
{
Datum val;
- bool isnull;
Oid indexId;
int keyatts;
HeapTuple indtup;
@@ -2368,21 +2343,16 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoChar(&buf, '(');
/* Fetch and build target column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conkey, &isnull);
- if (isnull)
- elog(ERROR, "null conkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conkey);
keyatts = decompile_column_index_array(val, conForm->conrelid, &buf);
appendStringInfoChar(&buf, ')');
/* Build including column list (from pg_index.indkeys) */
- val = SysCacheGetAttr(INDEXRELID, indtup,
- Anum_pg_index_indnatts, &isnull);
- if (isnull)
- elog(ERROR, "null indnatts for index %u", indexId);
+ val = SysCacheGetAttrNotNull(INDEXRELID, indtup,
+ Anum_pg_index_indnatts);
if (DatumGetInt32(val) > keyatts)
{
Datum cols;
@@ -2392,10 +2362,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoString(&buf, " INCLUDE (");
- cols = SysCacheGetAttr(INDEXRELID, indtup,
- Anum_pg_index_indkey, &isnull);
- if (isnull)
- elog(ERROR, "null indkey for index %u", indexId);
+ cols = SysCacheGetAttrNotNull(INDEXRELID, indtup,
+ Anum_pg_index_indkey);
deconstruct_array_builtin(DatumGetArrayTypeP(cols), INT2OID,
&keys, NULL, &nKeys);
@@ -2444,18 +2412,14 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
case CONSTRAINT_CHECK:
{
Datum val;
- bool isnull;
char *conbin;
char *consrc;
Node *expr;
List *context;
/* Fetch constraint expression in parsetree form */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conbin, &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
expr = stringToNode(conbin);
@@ -2507,19 +2471,14 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
{
Oid indexOid = conForm->conindid;
Datum val;
- bool isnull;
Datum *elems;
int nElems;
int i;
Oid *operators;
/* Extract operator OIDs from the pg_constraint tuple */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conexclop,
- &isnull);
- if (isnull)
- elog(ERROR, "null conexclop for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conexclop);
deconstruct_array_builtin(DatumGetArrayTypeP(val), OIDOID,
&elems, NULL, &nElems);
@@ -3088,9 +3047,7 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
appendStringInfoString(&buf, ", "); /* assume prosrc isn't null */
}
- tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ tmp = SysCacheGetAttrNotNull(PROCOID, proctup, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
/*
@@ -3512,7 +3469,6 @@ print_function_sqlbody(StringInfo buf, HeapTuple proctup)
char *argmodes;
deparse_namespace dpns = {0};
Datum tmp;
- bool isnull;
Node *n;
dpns.funcname = pstrdup(NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname));
@@ -3521,8 +3477,7 @@ print_function_sqlbody(StringInfo buf, HeapTuple proctup)
dpns.numargs = numargs;
dpns.argnames = argnames;
- tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosqlbody, &isnull);
- Assert(!isnull);
+ tmp = SysCacheGetAttrNotNull(PROCOID, proctup, Anum_pg_proc_prosqlbody);
n = stringToNode(TextDatumGetCString(tmp));
if (IsA(n, List))
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index c07382051d..c7607895cd 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -3195,7 +3195,6 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
int i;
Datum val;
- bool isnull;
ArrayType *statarray;
Oid arrayelemtype;
int narrayelem;
@@ -3219,11 +3218,8 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
if (flags & ATTSTATSSLOT_VALUES)
{
- val = SysCacheGetAttr(STATRELATTINH, statstuple,
- Anum_pg_statistic_stavalues1 + i,
- &isnull);
- if (isnull)
- elog(ERROR, "stavalues is null");
+ val = SysCacheGetAttrNotNull(STATRELATTINH, statstuple,
+ Anum_pg_statistic_stavalues1 + i);
/*
* Detoast the array if needed, and in any case make a copy that's
@@ -3267,11 +3263,8 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
if (flags & ATTSTATSSLOT_NUMBERS)
{
- val = SysCacheGetAttr(STATRELATTINH, statstuple,
- Anum_pg_statistic_stanumbers1 + i,
- &isnull);
- if (isnull)
- elog(ERROR, "stanumbers is null");
+ val = SysCacheGetAttrNotNull(STATRELATTINH, statstuple,
+ Anum_pg_statistic_stanumbers1 + i);
/*
* Detoast the array if needed, and in any case make a copy that's
@@ -3479,7 +3472,6 @@ get_index_column_opclass(Oid index_oid, int attno)
HeapTuple tuple;
Form_pg_index rd_index;
Datum datum;
- bool isnull;
oidvector *indclass;
Oid opclass;
@@ -3501,10 +3493,7 @@ get_index_column_opclass(Oid index_oid, int attno)
return InvalidOid;
}
- datum = SysCacheGetAttr(INDEXRELID, tuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
-
+ datum = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indclass);
indclass = ((oidvector *) DatumGetPointer(datum));
Assert(attno <= indclass->dim1);
diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c
index 4f53d47233..5f3516ad0c 100644
--- a/src/backend/utils/cache/partcache.c
+++ b/src/backend/utils/cache/partcache.c
@@ -130,15 +130,13 @@ RelationBuildPartitionKey(Relation relation)
/* But use the hard way to retrieve further variable-length attributes */
/* Operator class */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partclass);
opclass = (oidvector *) DatumGetPointer(datum);
/* Collation */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partcollation);
collation = (oidvector *) DatumGetPointer(datum);
/* Expressions */
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 94abede512..0c1ed801e1 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -77,6 +77,7 @@
#include "catalog/pg_user_mapping.h"
#include "lib/qunique.h"
#include "utils/catcache.h"
+#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
@@ -1099,6 +1100,32 @@ SysCacheGetAttr(int cacheId, HeapTuple tup,
isNull);
}
+/*
+ * SysCacheGetAttrNotNull
+ *
+ * As above, a version of SysCacheGetAttr which knows that the attr cannot
+ * be NULL.
+ */
+Datum
+SysCacheGetAttrNotNull(int cacheId, HeapTuple tup,
+ AttrNumber attributeNumber)
+{
+ bool isnull;
+ Datum attr;
+
+ attr = SysCacheGetAttr(cacheId, tup, attributeNumber, &isnull);
+
+ if (isnull)
+ {
+ elog(ERROR,
+ "unexpected NULL value in cached tuple for pg_catalog.%s.%s",
+ get_rel_name(cacheinfo[cacheId].reloid),
+ NameStr(TupleDescAttr(SysCache[cacheId]->cc_tupdesc, attributeNumber - 1)->attname));
+ }
+
+ return attr;
+}
+
/*
* GetSysCacheHashValue
*
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 3f64161760..f72dd25efa 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -151,7 +151,6 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
HeapTuple procedureTuple;
Form_pg_proc procedureStruct;
Datum prosrcdatum;
- bool isnull;
char *prosrc;
/*
@@ -227,10 +226,8 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
* internal function is stored in prosrc (it doesn't have to be
* the same as the name of the alias!)
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(prosrcdatum);
fbp = fmgr_lookupByName(prosrc);
if (fbp == NULL)
@@ -285,7 +282,6 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
{
HeapTuple procedureTuple;
Form_pg_proc procedureStruct;
- bool isnull;
Datum prosrcattr;
Datum probinattr;
@@ -308,25 +304,19 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
switch (procedureStruct->prolang)
{
case INTERNALlanguageId:
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
*mod = NULL; /* core binary */
*fn = TextDatumGetCString(prosrcattr);
break;
case ClanguageId:
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", functionId);
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
- probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", functionId);
+ probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_probin);
/*
* No need to check symbol presence / API version here, already
@@ -361,7 +351,6 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
CFuncHashTabEntry *hashentry;
PGFunction user_fn;
const Pg_finfo_record *inforec;
- bool isnull;
/*
* See if we have the function address cached already
@@ -385,16 +374,12 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
* While in general these columns might be null, that's not allowed
* for C-language functions.
*/
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", functionId);
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
prosrcstring = TextDatumGetCString(prosrcattr);
- probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", functionId);
+ probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_probin);
probinstring = TextDatumGetCString(probinattr);
/* Look up the function itself */
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 217835d590..24683bb608 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -1602,7 +1602,6 @@ get_func_result_name(Oid functionId)
HeapTuple procTuple;
Datum proargmodes;
Datum proargnames;
- bool isnull;
ArrayType *arr;
int numargs;
char *argmodes;
@@ -1623,14 +1622,10 @@ get_func_result_name(Oid functionId)
else
{
/* Get the data out of the tuple */
- proargmodes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargmodes,
- &isnull);
- Assert(!isnull);
- proargnames = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargnames,
- &isnull);
- Assert(!isnull);
+ proargmodes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargmodes);
+ proargnames = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargnames);
/*
* We expect the arrays to be 1-D arrays of the right types; verify
@@ -1717,14 +1712,10 @@ build_function_result_tupdesc_t(HeapTuple procTuple)
return NULL;
/* Get the data out of the tuple */
- proallargtypes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proallargtypes,
- &isnull);
- Assert(!isnull);
- proargmodes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargmodes,
- &isnull);
- Assert(!isnull);
+ proallargtypes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proallargtypes);
+ proargmodes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargmodes);
proargnames = SysCacheGetAttr(PROCOID, procTuple,
Anum_pg_proc_proargnames,
&isnull);
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 2f07ca7a0e..74026d8019 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -398,11 +398,9 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
/* assign locale variables */
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_datcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datcollate);
collate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_datctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datctype);
ctype = TextDatumGetCString(datum);
if (pg_perm_setlocale(LC_COLLATE, collate) == NULL)
@@ -421,8 +419,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticulocale, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_daticulocale);
iculocale = TextDatumGetCString(datum);
make_icu_collator(iculocale, &default_locale);
}
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index d5d50ceab4..28c72558d5 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -157,6 +157,9 @@ extern HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum);
extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
AttrNumber attributeNumber, bool *isNull);
+extern Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup,
+ AttrNumber attributeNumber);
+
extern uint32 GetSysCacheHashValue(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4);
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 8143ae40a0..d7d9c1bee3 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -2915,10 +2915,8 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger)
* we do not use a named subroutine so that we can call directly
* through the reference.
************************************************************/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
/************************************************************
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 7db912fd18..a341cde2c1 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -271,7 +271,6 @@ do_compile(FunctionCallInfo fcinfo,
bool is_dml_trigger = CALLED_AS_TRIGGER(fcinfo);
bool is_event_trigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
Datum prosrcdatum;
- bool isnull;
char *proc_source;
HeapTuple typeTup;
Form_pg_type typeStruct;
@@ -296,10 +295,7 @@ do_compile(FunctionCallInfo fcinfo,
* cannot be invoked recursively, so there's no need to save and restore
* the static variables used here.
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup, Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
plpgsql_scanner_init(proc_source);
diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c
index 494f109b32..79b6ef6a44 100644
--- a/src/pl/plpython/plpy_procedure.c
+++ b/src/pl/plpython/plpy_procedure.c
@@ -324,10 +324,8 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
/*
* get the text of the function.
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
procSource = TextDatumGetCString(prosrcdatum);
PLy_procedure_compile(proc, procSource);
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 499a9eaba8..e8f9d7b289 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -1454,7 +1454,6 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid,
Form_pg_type typeStruct;
char proc_internal_args[33 * FUNC_MAX_ARGS];
Datum prosrcdatum;
- bool isnull;
char *proc_source;
char buf[48];
Tcl_Interp *interp;
@@ -1673,10 +1672,8 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid,
/************************************************************
* Add user's function definition to proc body
************************************************************/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
UTF_BEGIN;
Tcl_DStringAppend(&proc_internal_body, UTF_E2U(proc_source), -1);
--
2.32.1 (Apple Git-133)
Daniel Gustafsson <daniel@yesql.se> writes:
On 1 Mar 2023, at 00:20, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Also ... at least in assert-enabled builds, maybe we could check that
the column being fetched this way is actually marked attnotnull?
We could, but that would limit the API to attnotnull columns, rather than when
the caller knows that the attr cannot be NULL either due to attnotnull or due
to intrinsic knowledge based on what is being extracted.
An example of the latter is build_function_result_tupdesc_t() which knows that
proallargtypes cannot be NULL when calling SysCacheGetAttr.
OK, if there are counterexamples then never mind that. I don't think
we want to discourage call sites from using this function.
regards, tom lane
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
I think an error message like
"unexpected null value in system cache %d column %d"
is sufficient. Since these are "can't happen" errors, we don't need to
spend too much extra effort to make it prettier.
I'd at least like to see it give the catalog's OID. That's easily
convertible to a name, and it doesn't tend to move around across PG
versions, neither of which are true for syscache IDs.
Also, I'm fairly unconvinced that it's a "can't happen" --- this
would be very likely to fire as a result of catalog corruption,
so it would be good if it's at least minimally interpretable
by a non-expert. Given that we'll now have just one copy of the
code, ISTM there's a good case for doing the small extra work
to report catalog and column by name.
regards, tom lane
On 2 Mar 2023, at 15:44, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
I think an error message like
"unexpected null value in system cache %d column %d"
is sufficient. Since these are "can't happen" errors, we don't need to
spend too much extra effort to make it prettier.I'd at least like to see it give the catalog's OID. That's easily
convertible to a name, and it doesn't tend to move around across PG
versions, neither of which are true for syscache IDs.Also, I'm fairly unconvinced that it's a "can't happen" --- this
would be very likely to fire as a result of catalog corruption,
so it would be good if it's at least minimally interpretable
by a non-expert. Given that we'll now have just one copy of the
code, ISTM there's a good case for doing the small extra work
to report catalog and column by name.
Rebased v3 on top of recent conflicting ICU changes causing the patch to not
apply anymore. Also took another look around the tree to see if there were
missed callsites but found none new.
--
Daniel Gustafsson
Attachments:
v3-0001-Add-SysCacheGetAttrNotNull-for-guaranteed-not-nul.patchapplication/octet-stream; name=v3-0001-Add-SysCacheGetAttrNotNull-for-guaranteed-not-nul.patch; x-unix-mode=0644Download
From d97490656c8d35965637c6a59b6a239b1b85866f Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 13 Mar 2023 14:10:18 +0100
Subject: [PATCH v3] Add SysCacheGetAttrNotNull for guaranteed not-null attrs
When extracting an attr from a cached tuple in the syscache with
SysCacheGetAttr the isnull parameter must be checked in case the
attr cannot be NULL. For cases when this is known beforehand, a
wrapper is introduced which perform the errorhandling internally
on behalf of the caller, invoking an elog in case of a NULL attr.
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Discussion: https://postgr.es/m/AD76405E-DB45-46B6-941F-17B1EB3A9076@yesql.se
---
src/backend/access/brin/brin_inclusion.c | 7 +-
src/backend/access/brin/brin_minmax.c | 7 +-
src/backend/access/brin/brin_minmax_multi.c | 7 +-
src/backend/access/index/indexam.c | 6 +-
src/backend/catalog/aclchk.c | 38 +++---
src/backend/catalog/index.c | 20 ++--
src/backend/catalog/objectaddress.c | 23 ++--
src/backend/catalog/pg_constraint.c | 33 ++----
src/backend/catalog/pg_proc.c | 25 +---
src/backend/catalog/pg_subscription.c | 32 ++----
src/backend/commands/collationcmds.c | 23 ++--
src/backend/commands/dbcommands.c | 11 +-
src/backend/commands/indexcmds.c | 7 +-
src/backend/commands/matview.c | 9 +-
src/backend/commands/subscriptioncmds.c | 10 +-
src/backend/commands/tablecmds.c | 27 ++---
src/backend/commands/typecmds.c | 8 +-
src/backend/executor/execReplication.c | 6 +-
src/backend/executor/functions.c | 7 +-
src/backend/optimizer/util/clauses.c | 23 +---
src/backend/parser/parse_func.c | 7 +-
src/backend/parser/parse_utilcmd.c | 30 ++---
src/backend/partitioning/partbounds.c | 9 +-
src/backend/statistics/extended_stats.c | 5 +-
src/backend/utils/adt/amutils.c | 5 +-
src/backend/utils/adt/pg_locale.c | 19 +--
src/backend/utils/adt/ruleutils.c | 121 ++++++--------------
src/backend/utils/cache/lsyscache.c | 21 +---
src/backend/utils/cache/partcache.c | 10 +-
src/backend/utils/cache/syscache.c | 27 +++++
src/backend/utils/fmgr/fmgr.c | 39 ++-----
src/backend/utils/fmgr/funcapi.c | 25 ++--
src/backend/utils/init/postinit.c | 9 +-
src/include/utils/syscache.h | 3 +
src/pl/plperl/plperl.c | 6 +-
src/pl/plpgsql/src/pl_comp.c | 6 +-
src/pl/plpython/plpy_procedure.c | 6 +-
src/pl/tcl/pltcl.c | 7 +-
38 files changed, 232 insertions(+), 452 deletions(-)
diff --git a/src/backend/access/brin/brin_inclusion.c b/src/backend/access/brin/brin_inclusion.c
index 248116c149..02f4d0ae76 100644
--- a/src/backend/access/brin/brin_inclusion.c
+++ b/src/backend/access/brin/brin_inclusion.c
@@ -630,7 +630,6 @@ inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -643,10 +642,10 @@ inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c
index 2431591be6..8229493c84 100644
--- a/src/backend/access/brin/brin_minmax.c
+++ b/src/backend/access/brin/brin_minmax.c
@@ -290,7 +290,6 @@ minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -303,10 +302,10 @@ minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
index 0ace6035be..84bcdf49a9 100644
--- a/src/backend/access/brin/brin_minmax_multi.c
+++ b/src/backend/access/brin/brin_minmax_multi.c
@@ -2953,7 +2953,6 @@ minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
HeapTuple tuple;
Oid opfamily,
oprid;
- bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
@@ -2965,10 +2964,10 @@ minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
- oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
- Anum_pg_amop_amopopr, &isNull));
+ oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
+ Anum_pg_amop_amopopr));
ReleaseSysCache(tuple);
- Assert(!isNull && RegProcedureIsValid(oprid));
+ Assert(RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index dbf147ed22..b25b03f7ab 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -961,7 +961,6 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
Oid opclass;
Datum indclassDatum;
oidvector *indclass;
- bool isnull;
if (!DatumGetPointer(attoptions))
return NULL; /* ok, no options, no procedure */
@@ -970,9 +969,8 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
* Report an error if the opclass's options-parsing procedure does not
* exist but the opclass options are specified.
*/
- indclassDatum = SysCacheGetAttr(INDEXRELID, indrel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indrel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
opclass = indclass->values[attnum - 1];
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index c4232344aa..03febea7ba 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -2178,11 +2178,9 @@ ExecGrant_common(InternalGrant *istmt, Oid classid, AclMode default_privs,
* Get owner ID and working copy of existing ACL. If there's no ACL,
* substitute the proper default.
*/
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isNull));
- Assert(!isNull);
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
aclDatum = SysCacheGetAttr(cacheid,
tuple,
get_object_attnum_acl(classid),
@@ -2206,10 +2204,8 @@ ExecGrant_common(InternalGrant *istmt, Oid classid, AclMode default_privs,
old_acl, ownerId,
&grantorId, &avail_goptions);
- nameDatum = SysCacheGetAttr(cacheid, tuple,
- get_object_attnum_name(classid),
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(cacheid, tuple,
+ get_object_attnum_name(classid));
/*
* Restrict the privileges to what we can actually grant, and emit the
@@ -2476,10 +2472,8 @@ ExecGrant_Parameter(InternalGrant *istmt)
parameterId);
/* We'll need the GUC's name */
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tuple,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tuple,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
/* Treat all parameters as belonging to the bootstrap superuser. */
@@ -3113,11 +3107,9 @@ object_aclmask(Oid classid, Oid objectid, Oid roleid,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isNull));
- Assert(!isNull);
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
aclDatum = SysCacheGetAttr(cacheid, tuple, get_object_attnum_acl(classid),
&isNull);
@@ -3994,7 +3986,6 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
if (cacheid != -1)
{
HeapTuple tuple;
- bool isnull;
tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
if (!HeapTupleIsValid(tuple))
@@ -4002,12 +3993,9 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
- ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
- tuple,
- get_object_attnum_owner(classid),
- &isnull));
- Assert(!isnull);
-
+ ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
+ tuple,
+ get_object_attnum_owner(classid)));
ReleaseSysCache(tuple);
}
else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 7777e7ec77..864f2e6d86 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1320,14 +1320,12 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(oldIndexId));
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "cache lookup failed for index %u", oldIndexId);
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
- colOptionDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ colOptionDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indoption);
indcoloptions = (int2vector *) DatumGetPointer(colOptionDatum);
/* Fetch options of index if any */
@@ -1347,9 +1345,8 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
Datum exprDatum;
char *exprString;
- exprDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indexprs, &isnull);
- Assert(!isnull);
+ exprDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indexprs);
exprString = TextDatumGetCString(exprDatum);
indexExprs = (List *) stringToNode(exprString);
pfree(exprString);
@@ -1359,9 +1356,8 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
Datum predDatum;
char *predString;
- predDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indpred, &isnull);
- Assert(!isnull);
+ predDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indpred);
predString = TextDatumGetCString(predDatum);
indexPreds = (List *) stringToNode(predString);
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 2f688166e1..65f877c5b7 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -2597,7 +2597,6 @@ get_object_namespace(const ObjectAddress *address)
{
int cache;
HeapTuple tuple;
- bool isnull;
Oid oid;
const ObjectPropertyType *property;
@@ -2615,11 +2614,9 @@ get_object_namespace(const ObjectAddress *address)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for cache %d oid %u",
cache, address->objectId);
- oid = DatumGetObjectId(SysCacheGetAttr(cache,
- tuple,
- property->attnum_namespace,
- &isnull));
- Assert(!isnull);
+ oid = DatumGetObjectId(SysCacheGetAttrNotNull(cache,
+ tuple,
+ property->attnum_namespace));
ReleaseSysCache(tuple);
return oid;
@@ -3890,7 +3887,6 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
{
HeapTuple tup;
Datum nameDatum;
- bool isNull;
char *parname;
tup = SearchSysCache1(PARAMETERACLOID,
@@ -3902,10 +3898,8 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
object->objectId);
break;
}
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tup,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
appendStringInfo(&buffer, _("parameter %s"), parname);
ReleaseSysCache(tup);
@@ -5753,7 +5747,6 @@ getObjectIdentityParts(const ObjectAddress *object,
{
HeapTuple tup;
Datum nameDatum;
- bool isNull;
char *parname;
tup = SearchSysCache1(PARAMETERACLOID,
@@ -5765,10 +5758,8 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
break;
}
- nameDatum = SysCacheGetAttr(PARAMETERACLOID, tup,
- Anum_pg_parameter_acl_parname,
- &isNull);
- Assert(!isNull);
+ nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
+ Anum_pg_parameter_acl_parname);
parname = TextDatumGetCString(nameDatum);
appendStringInfoString(&buffer, parname);
if (objname)
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 7392c72e90..ce82ede7f9 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -1190,23 +1190,18 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs,
int *num_fk_del_set_cols, AttrNumber *fk_del_set_cols)
{
- Oid constrId;
Datum adatum;
bool isNull;
ArrayType *arr;
int numkeys;
- constrId = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
-
/*
* We expect the arrays to be 1-D arrays of the right types; verify that.
* We don't need to use deconstruct_array() since the array data is just
* going to look like a C array of values.
*/
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conkey, &isNull);
- if (isNull)
- elog(ERROR, "null conkey for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conkey);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -1219,10 +1214,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if ((Pointer) arr != DatumGetPointer(adatum))
pfree(arr); /* free de-toasted copy, if any */
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_confkey, &isNull);
- if (isNull)
- elog(ERROR, "null confkey for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_confkey);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
@@ -1235,10 +1228,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (pf_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conpfeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conpfeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conpfeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
/* see TryReuseForeignKey if you change the test below */
if (ARR_NDIM(arr) != 1 ||
@@ -1253,10 +1244,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (pp_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conppeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conppeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conppeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
@@ -1270,10 +1259,8 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
if (ff_eq_oprs)
{
- adatum = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conffeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conffeqop for constraint %u", constrId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conffeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numkeys ||
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 14d552fe2d..41fa2a4987 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -520,10 +520,8 @@ ProcedureCreate(const char *procedureName,
dropcmd,
format_procedure(oldproc->oid))));
- proargdefaults = SysCacheGetAttr(PROCNAMEARGSNSP, oldtup,
- Anum_pg_proc_proargdefaults,
- &isnull);
- Assert(!isnull);
+ proargdefaults = SysCacheGetAttrNotNull(PROCNAMEARGSNSP, oldtup,
+ Anum_pg_proc_proargdefaults);
oldDefaults = castNode(List, stringToNode(TextDatumGetCString(proargdefaults)));
Assert(list_length(oldDefaults) == oldproc->pronargdefaults);
@@ -731,7 +729,6 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
{
Oid funcoid = PG_GETARG_OID(0);
HeapTuple tuple;
- bool isnull;
Datum tmp;
char *prosrc;
@@ -747,9 +744,7 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for function %u", funcoid);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
if (fmgr_internal_function(prosrc) == InvalidOid)
@@ -778,7 +773,6 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
Oid funcoid = PG_GETARG_OID(0);
void *libraryhandle;
HeapTuple tuple;
- bool isnull;
Datum tmp;
char *prosrc;
char *probin;
@@ -796,14 +790,10 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for function %u", funcoid);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", funcoid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", funcoid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_probin);
probin = TextDatumGetCString(tmp);
(void) load_external_function(probin, prosrc, true, &libraryhandle);
@@ -876,10 +866,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
/* Postpone body checks if !check_function_bodies */
if (check_function_bodies)
{
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
-
+ tmp = SysCacheGetAttrNotNull(PROCOID, tuple, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
/*
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index a56ae311c3..d322b9482c 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -73,11 +73,9 @@ GetSubscription(Oid subid, bool missing_ok)
sub->disableonerr = subform->subdisableonerr;
/* Get conninfo */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subconninfo,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subconninfo);
sub->conninfo = TextDatumGetCString(datum);
/* Get slotname */
@@ -91,27 +89,21 @@ GetSubscription(Oid subid, bool missing_ok)
sub->slotname = NULL;
/* Get synccommit */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subsynccommit,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subsynccommit);
sub->synccommit = TextDatumGetCString(datum);
/* Get publications */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_subpublications,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_subpublications);
sub->publications = textarray_to_stringlist(DatumGetArrayTypeP(datum));
/* Get origin */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID,
- tup,
- Anum_pg_subscription_suborigin,
- &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID,
+ tup,
+ Anum_pg_subscription_suborigin);
sub->origin = TextDatumGetCString(datum);
ReleaseSysCache(tup);
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 8949684afe..34961a79ca 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -404,9 +404,7 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate, &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_collation");
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
/* cannot change from NULL to non-NULL or vice versa */
@@ -457,7 +455,6 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
char *locale;
char *version;
Datum datum;
- bool isnull;
if (collid == DEFAULT_COLLATION_OID)
{
@@ -471,12 +468,9 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_database) GETSTRUCT(dbtup))->datlocprovider;
- datum = SysCacheGetAttr(DATABASEOID, dbtup,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_database_daticulocale : Anum_pg_database_datcollate,
- &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
+ provider == COLLPROVIDER_ICU ?
+ Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
locale = TextDatumGetCString(datum);
@@ -494,12 +488,9 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_collation) GETSTRUCT(colltp))->collprovider;
Assert(provider != COLLPROVIDER_DEFAULT);
- datum = SysCacheGetAttr(COLLOID, colltp,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate,
- &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_collation");
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp,
+ provider == COLLPROVIDER_ICU ?
+ Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
locale = TextDatumGetCString(datum);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 4d5d5d6866..9408dd6cc7 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -2597,7 +2597,6 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
HeapTuple tp;
char datlocprovider;
Datum datum;
- bool isnull;
char *version;
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
@@ -2608,9 +2607,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttr(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate, &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
ReleaseSysCache(tp);
@@ -2737,14 +2734,12 @@ get_db_info(const char *name, LOCKMODE lockmode,
*dbLocProvider = dbform->datlocprovider;
if (dbCollate)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datcollate);
*dbCollate = TextDatumGetCString(datum);
}
if (dbCtype)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datctype);
*dbCtype = TextDatumGetCString(datum);
}
if (dbIculocale)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 16ec0b114e..c63350a6b7 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -188,7 +188,6 @@ CheckIndexCompatible(Oid oldId,
IndexInfo *indexInfo;
int numberOfAttributes;
int old_natts;
- bool isnull;
bool ret = true;
oidvector *old_indclass;
oidvector *old_indcollation;
@@ -267,12 +266,10 @@ CheckIndexCompatible(Oid oldId,
old_natts = indexForm->indnkeyatts;
Assert(old_natts == numberOfAttributes);
- d = SysCacheGetAttr(INDEXRELID, tuple, Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ d = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indcollation);
old_indcollation = (oidvector *) DatumGetPointer(d);
- d = SysCacheGetAttr(INDEXRELID, tuple, Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ d = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indclass);
old_indclass = (oidvector *) DatumGetPointer(d);
ret = (memcmp(old_indclass->values, classObjectId,
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index fb30d2595c..c00b9df3e3 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -692,15 +692,12 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
int indnkeyatts = indexStruct->indnkeyatts;
oidvector *indclass;
Datum indclassDatum;
- bool isnull;
int i;
/* Must get indclass the hard way. */
- indclassDatum = SysCacheGetAttr(INDEXRELID,
- indexRel->rd_indextuple,
- Anum_pg_index_indclass,
- &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID,
+ indexRel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/* Add quals for all columns from this index. */
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 464db6d247..8a26ddab1c 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -1436,15 +1436,13 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
LockSharedObject(SubscriptionRelationId, subid, 0, AccessExclusiveLock);
/* Get subname */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup,
- Anum_pg_subscription_subname, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, tup,
+ Anum_pg_subscription_subname);
subname = pstrdup(NameStr(*DatumGetName(datum)));
/* Get conninfo */
- datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup,
- Anum_pg_subscription_subconninfo, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, tup,
+ Anum_pg_subscription_subconninfo);
conninfo = TextDatumGetCString(datum);
/* Get slotname */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 3e2c5f797c..4a24cde878 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -11114,7 +11114,6 @@ ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName,
List *children = NIL;
ListCell *child;
NewConstraint *newcon;
- bool isnull;
Datum val;
char *conbin;
@@ -11169,11 +11168,8 @@ ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName,
newcon->refindid = InvalidOid;
newcon->conid = con->oid;
- val = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conbin, &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u", con->oid);
-
+ val = SysCacheGetAttrNotNull(CONSTROID, tuple,
+ Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
newcon->qual = (Node *) stringToNode(conbin);
@@ -11275,7 +11271,6 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
HeapTuple indexTuple = NULL;
Form_pg_index indexStruct = NULL;
Datum indclassDatum;
- bool isnull;
oidvector *indclass;
int i;
@@ -11327,9 +11322,8 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
RelationGetRelationName(pkrel))));
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/*
@@ -11422,13 +11416,11 @@ transformFkeyCheckAttrs(Relation pkrel,
heap_attisnull(indexTuple, Anum_pg_index_indexprs, NULL))
{
Datum indclassDatum;
- bool isnull;
oidvector *indclass;
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/*
@@ -13580,7 +13572,6 @@ TryReuseForeignKey(Oid oldId, Constraint *con)
{
HeapTuple tup;
Datum adatum;
- bool isNull;
ArrayType *arr;
Oid *rawarr;
int numkeys;
@@ -13593,10 +13584,8 @@ TryReuseForeignKey(Oid oldId, Constraint *con)
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "cache lookup failed for constraint %u", oldId);
- adatum = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conpfeqop, &isNull);
- if (isNull)
- elog(ERROR, "null conpfeqop for constraint %u", oldId);
+ adatum = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conpfeqop);
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
numkeys = ARR_DIMS(arr)[0];
/* test follows the one in ri_FetchConstraintInfo() */
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 04bddaef81..3440dbc440 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -3039,7 +3039,6 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
char *conbin;
SysScanDesc scan;
Datum val;
- bool isnull;
HeapTuple tuple;
HeapTuple copyTuple;
ScanKeyData skey[3];
@@ -3094,12 +3093,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
errmsg("constraint \"%s\" of domain \"%s\" is not a check constraint",
constrName, TypeNameToString(typename))));
- val = SysCacheGetAttr(CONSTROID, tuple,
- Anum_pg_constraint_conbin,
- &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u",
- con->oid);
+ val = SysCacheGetAttrNotNull(CONSTROID, tuple, Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
validateDomainConstraint(domainoid, conbin);
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index 4f5083a598..f2fb096622 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -51,7 +51,6 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel,
TupleTableSlot *searchslot)
{
int attoff;
- bool isnull;
Datum indclassDatum;
oidvector *opclass;
int2vector *indkey = &idxrel->rd_index->indkey;
@@ -60,9 +59,8 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel,
Assert(RelationGetReplicaIndex(rel) == RelationGetRelid(idxrel) ||
RelationGetPrimaryKeyIndex(rel) == RelationGetRelid(idxrel));
- indclassDatum = SysCacheGetAttr(INDEXRELID, idxrel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, idxrel->rd_indextuple,
+ Anum_pg_index_indclass);
opclass = (oidvector *) DatumGetPointer(indclassDatum);
/* Build scankey for every attribute in the index. */
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 50e06ec693..f55424eb5a 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -660,12 +660,7 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
/*
* And of course we need the function body text.
*/
- tmp = SysCacheGetAttr(PROCOID,
- procedureTuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", foid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, procedureTuple, Anum_pg_proc_prosrc);
fcache->src = TextDatumGetCString(tmp);
/* If we have prosqlbody, pay attention to that not prosrc. */
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 76e25118f9..fc245c60e4 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -4177,15 +4177,10 @@ fetch_function_defaults(HeapTuple func_tuple)
{
List *defaults;
Datum proargdefaults;
- bool isnull;
char *str;
- /* The error cases here shouldn't happen, but check anyway */
- proargdefaults = SysCacheGetAttr(PROCOID, func_tuple,
- Anum_pg_proc_proargdefaults,
- &isnull);
- if (isnull)
- elog(ERROR, "not enough default arguments");
+ proargdefaults = SysCacheGetAttrNotNull(PROCOID, func_tuple,
+ Anum_pg_proc_proargdefaults);
str = TextDatumGetCString(proargdefaults);
defaults = castNode(List, stringToNode(str));
pfree(str);
@@ -4457,12 +4452,7 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
fexpr->location = -1;
/* Fetch the function body */
- tmp = SysCacheGetAttr(PROCOID,
- func_tuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", funcid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc);
src = TextDatumGetCString(tmp);
/*
@@ -5015,12 +5005,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
oldcxt = MemoryContextSwitchTo(mycxt);
/* Fetch the function body */
- tmp = SysCacheGetAttr(PROCOID,
- func_tuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", func_oid);
+ tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc);
src = TextDatumGetCString(tmp);
/*
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index ca14f06308..b3f0b6a137 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -1632,7 +1632,6 @@ func_get_detail(List *funcname,
if (argdefaults && best_candidate->ndargs > 0)
{
Datum proargdefaults;
- bool isnull;
char *str;
List *defaults;
@@ -1640,10 +1639,8 @@ func_get_detail(List *funcname,
if (best_candidate->ndargs > pform->pronargdefaults)
elog(ERROR, "not enough default arguments");
- proargdefaults = SysCacheGetAttr(PROCOID, ftup,
- Anum_pg_proc_proargdefaults,
- &isnull);
- Assert(!isnull);
+ proargdefaults = SysCacheGetAttrNotNull(PROCOID, ftup,
+ Anum_pg_proc_proargdefaults);
str = TextDatumGetCString(proargdefaults);
defaults = castNode(List, stringToNode(str));
pfree(str);
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index f9218f48aa..15a1dab8c5 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1562,15 +1562,12 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
amrec = (Form_pg_am) GETSTRUCT(ht_am);
/* Extract indcollation from the pg_index tuple */
- datum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indcollation);
indcollation = (oidvector *) DatumGetPointer(datum);
/* Extract indclass from the pg_index tuple */
- datum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx, Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(datum);
/* Begin building the IndexStmt */
@@ -1641,13 +1638,8 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
Assert(conrec->contype == CONSTRAINT_EXCLUSION);
/* Extract operator OIDs from the pg_constraint tuple */
- datum = SysCacheGetAttr(CONSTROID, ht_constr,
- Anum_pg_constraint_conexclop,
- &isnull);
- if (isnull)
- elog(ERROR, "null conexclop for constraint %u",
- constraintId);
-
+ datum = SysCacheGetAttrNotNull(CONSTROID, ht_constr,
+ Anum_pg_constraint_conexclop);
deconstruct_array_builtin(DatumGetArrayTypeP(datum), OIDOID, &elems, NULL, &nElems);
for (i = 0; i < nElems; i++)
@@ -1898,9 +1890,8 @@ generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid,
statsrec = (Form_pg_statistic_ext) GETSTRUCT(ht_stats);
/* Determine which statistics types exist */
- datum = SysCacheGetAttr(STATEXTOID, ht_stats,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, ht_stats,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -2228,7 +2219,6 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
Form_pg_index index_form;
oidvector *indclass;
Datum indclassDatum;
- bool isnull;
int i;
/* Grammar should not allow this with explicit column list */
@@ -2327,9 +2317,9 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
parser_errposition(cxt->pstate, constraint->location)));
/* Must get indclass the hard way */
- indclassDatum = SysCacheGetAttr(INDEXRELID, index_rel->rd_indextuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID,
+ index_rel->rd_indextuple,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
for (i = 0; i < index_form->indnatts; i++)
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index a69c1d1e77..cf1156b842 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -4311,19 +4311,14 @@ get_qual_for_range(Relation parent, PartitionBoundSpec *spec,
Oid inhrelid = inhoids[k];
HeapTuple tuple;
Datum datum;
- bool isnull;
PartitionBoundSpec *bspec;
tuple = SearchSysCache1(RELOID, inhrelid);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", inhrelid);
- datum = SysCacheGetAttr(RELOID, tuple,
- Anum_pg_class_relpartbound,
- &isnull);
- if (isnull)
- elog(ERROR, "null relpartbound for relation %u", inhrelid);
-
+ datum = SysCacheGetAttrNotNull(RELOID, tuple,
+ Anum_pg_class_relpartbound);
bspec = (PartitionBoundSpec *)
stringToNode(TextDatumGetCString(datum));
if (!IsA(bspec, PartitionBoundSpec))
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 572d9b4464..54e3bb4aa2 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -465,9 +465,8 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid)
}
/* decode the stxkind char array into a list of chars */
- datum = SysCacheGetAttr(STATEXTOID, htup,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, htup,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
diff --git a/src/backend/utils/adt/amutils.c b/src/backend/utils/adt/amutils.c
index 2fb5f64d36..48852bf79e 100644
--- a/src/backend/utils/adt/amutils.c
+++ b/src/backend/utils/adt/amutils.c
@@ -119,7 +119,6 @@ test_indoption(HeapTuple tuple, int attno, bool guard,
bool *res)
{
Datum datum;
- bool isnull;
int2vector *indoption;
int16 indoption_val;
@@ -129,9 +128,7 @@ test_indoption(HeapTuple tuple, int attno, bool guard,
return true;
}
- datum = SysCacheGetAttr(INDEXRELID, tuple,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indoption);
indoption = ((int2vector *) DatumGetPointer(datum));
indoption_val = indoption->values[attno - 1];
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 1d3d4d86d3..4f9daf2557 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1281,15 +1281,12 @@ lookup_collation_cache(Oid collation, bool set_flags)
if (collform->collprovider == COLLPROVIDER_LIBC)
{
Datum datum;
- bool isnull;
const char *collcollate;
const char *collctype;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
collcollate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
collctype = TextDatumGetCString(datum);
cache_entry->collate_is_c = ((strcmp(collcollate, "C") == 0) ||
@@ -1581,11 +1578,9 @@ pg_newlocale_from_collation(Oid collid)
const char *collctype pg_attribute_unused();
locale_t loc;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
collcollate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
collctype = TextDatumGetCString(datum);
if (strcmp(collcollate, collctype) == 0)
@@ -1641,8 +1636,7 @@ pg_newlocale_from_collation(Oid collid)
const char *iculocstr;
const char *icurules;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colliculocale, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colliculocale);
iculocstr = TextDatumGetCString(datum);
datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
@@ -1663,8 +1657,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
TextDatumGetCString(datum));
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index bcb493b56c..4a98b82f07 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -1228,7 +1228,6 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Datum indcollDatum;
Datum indclassDatum;
Datum indoptionDatum;
- bool isnull;
oidvector *indcollation;
oidvector *indclass;
int2vector *indoption;
@@ -1252,19 +1251,16 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Assert(indexrelid == idxrec->indexrelid);
/* Must get indcollation, indclass, and indoption the hard way */
- indcollDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indcollation, &isnull);
- Assert(!isnull);
+ indcollDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indcollation);
indcollation = (oidvector *) DatumGetPointer(indcollDatum);
- indclassDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
+ indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indclass);
indclass = (oidvector *) DatumGetPointer(indclassDatum);
- indoptionDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indoption, &isnull);
- Assert(!isnull);
+ indoptionDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indoption);
indoption = (int2vector *) DatumGetPointer(indoptionDatum);
/*
@@ -1297,9 +1293,8 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
Datum exprsDatum;
char *exprsString;
- exprsDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indexprs);
exprsString = TextDatumGetCString(exprsDatum);
indexprs = (List *) stringToNode(exprsString);
pfree(exprsString);
@@ -1494,9 +1489,8 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
char *predString;
/* Convert text string to node tree */
- predDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
- Anum_pg_index_indpred, &isnull);
- Assert(!isnull);
+ predDatum = SysCacheGetAttrNotNull(INDEXRELID, ht_idx,
+ Anum_pg_index_indpred);
predString = TextDatumGetCString(predDatum);
node = (Node *) stringToNode(predString);
pfree(predString);
@@ -1637,12 +1631,10 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
if (has_exprs)
{
Datum exprsDatum;
- bool isnull;
char *exprsString;
- exprsDatum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxexprs);
exprsString = TextDatumGetCString(exprsDatum);
exprs = (List *) stringToNode(exprsString);
pfree(exprsString);
@@ -1657,8 +1649,6 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
if (!columns_only)
{
- bool isnull;
-
nsp = get_namespace_name_or_temp(statextrec->stxnamespace);
appendStringInfo(&buf, "CREATE STATISTICS %s",
quote_qualified_identifier(nsp,
@@ -1668,9 +1658,8 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
* Decode the stxkind column so that we know which stats types to
* print.
*/
- datum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxkind, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxkind);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
@@ -1790,7 +1779,6 @@ pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS)
Form_pg_statistic_ext statextrec;
HeapTuple statexttup;
Datum datum;
- bool isnull;
List *context;
ListCell *lc;
List *exprs = NIL;
@@ -1818,10 +1806,8 @@ pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS)
/*
* Get the statistics expressions, and deparse them into text values.
*/
- datum = SysCacheGetAttr(STATEXTOID, statexttup,
- Anum_pg_statistic_ext_stxexprs, &isnull);
-
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(STATEXTOID, statexttup,
+ Anum_pg_statistic_ext_stxexprs);
tmp = TextDatumGetCString(datum);
exprs = (List *) stringToNode(tmp);
pfree(tmp);
@@ -1897,7 +1883,6 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
ListCell *partexpr_item;
List *context;
Datum datum;
- bool isnull;
StringInfoData buf;
int keyno;
char *str;
@@ -1916,14 +1901,12 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
Assert(form->partrelid == relid);
/* Must get partclass and partcollation the hard way */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partclass);
partclass = (oidvector *) DatumGetPointer(datum);
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partcollation);
partcollation = (oidvector *) DatumGetPointer(datum);
@@ -1937,9 +1920,8 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
Datum exprsDatum;
char *exprsString;
- exprsDatum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partexprs, &isnull);
- Assert(!isnull);
+ exprsDatum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partexprs);
exprsString = TextDatumGetCString(exprsDatum);
partexprs = (List *) stringToNode(exprsString);
@@ -2229,11 +2211,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoString(&buf, "FOREIGN KEY (");
/* Fetch and build referencing-column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conkey, &isnull);
- if (isnull)
- elog(ERROR, "null conkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conkey);
decompile_column_index_array(val, conForm->conrelid, &buf);
@@ -2243,11 +2222,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
NIL));
/* Fetch and build referenced-column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_confkey, &isnull);
- if (isnull)
- elog(ERROR, "null confkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_confkey);
decompile_column_index_array(val, conForm->confrelid, &buf);
@@ -2345,7 +2321,6 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
case CONSTRAINT_UNIQUE:
{
Datum val;
- bool isnull;
Oid indexId;
int keyatts;
HeapTuple indtup;
@@ -2368,21 +2343,16 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoChar(&buf, '(');
/* Fetch and build target column list */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conkey, &isnull);
- if (isnull)
- elog(ERROR, "null conkey for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conkey);
keyatts = decompile_column_index_array(val, conForm->conrelid, &buf);
appendStringInfoChar(&buf, ')');
/* Build including column list (from pg_index.indkeys) */
- val = SysCacheGetAttr(INDEXRELID, indtup,
- Anum_pg_index_indnatts, &isnull);
- if (isnull)
- elog(ERROR, "null indnatts for index %u", indexId);
+ val = SysCacheGetAttrNotNull(INDEXRELID, indtup,
+ Anum_pg_index_indnatts);
if (DatumGetInt32(val) > keyatts)
{
Datum cols;
@@ -2392,10 +2362,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
appendStringInfoString(&buf, " INCLUDE (");
- cols = SysCacheGetAttr(INDEXRELID, indtup,
- Anum_pg_index_indkey, &isnull);
- if (isnull)
- elog(ERROR, "null indkey for index %u", indexId);
+ cols = SysCacheGetAttrNotNull(INDEXRELID, indtup,
+ Anum_pg_index_indkey);
deconstruct_array_builtin(DatumGetArrayTypeP(cols), INT2OID,
&keys, NULL, &nKeys);
@@ -2444,18 +2412,14 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
case CONSTRAINT_CHECK:
{
Datum val;
- bool isnull;
char *conbin;
char *consrc;
Node *expr;
List *context;
/* Fetch constraint expression in parsetree form */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conbin, &isnull);
- if (isnull)
- elog(ERROR, "null conbin for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
expr = stringToNode(conbin);
@@ -2507,19 +2471,14 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
{
Oid indexOid = conForm->conindid;
Datum val;
- bool isnull;
Datum *elems;
int nElems;
int i;
Oid *operators;
/* Extract operator OIDs from the pg_constraint tuple */
- val = SysCacheGetAttr(CONSTROID, tup,
- Anum_pg_constraint_conexclop,
- &isnull);
- if (isnull)
- elog(ERROR, "null conexclop for constraint %u",
- constraintId);
+ val = SysCacheGetAttrNotNull(CONSTROID, tup,
+ Anum_pg_constraint_conexclop);
deconstruct_array_builtin(DatumGetArrayTypeP(val), OIDOID,
&elems, NULL, &nElems);
@@ -3088,9 +3047,7 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
appendStringInfoString(&buf, ", "); /* assume prosrc isn't null */
}
- tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ tmp = SysCacheGetAttrNotNull(PROCOID, proctup, Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(tmp);
/*
@@ -3512,7 +3469,6 @@ print_function_sqlbody(StringInfo buf, HeapTuple proctup)
char *argmodes;
deparse_namespace dpns = {0};
Datum tmp;
- bool isnull;
Node *n;
dpns.funcname = pstrdup(NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname));
@@ -3521,8 +3477,7 @@ print_function_sqlbody(StringInfo buf, HeapTuple proctup)
dpns.numargs = numargs;
dpns.argnames = argnames;
- tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosqlbody, &isnull);
- Assert(!isnull);
+ tmp = SysCacheGetAttrNotNull(PROCOID, proctup, Anum_pg_proc_prosqlbody);
n = stringToNode(TextDatumGetCString(tmp));
if (IsA(n, List))
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index c07382051d..c7607895cd 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -3195,7 +3195,6 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
int i;
Datum val;
- bool isnull;
ArrayType *statarray;
Oid arrayelemtype;
int narrayelem;
@@ -3219,11 +3218,8 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
if (flags & ATTSTATSSLOT_VALUES)
{
- val = SysCacheGetAttr(STATRELATTINH, statstuple,
- Anum_pg_statistic_stavalues1 + i,
- &isnull);
- if (isnull)
- elog(ERROR, "stavalues is null");
+ val = SysCacheGetAttrNotNull(STATRELATTINH, statstuple,
+ Anum_pg_statistic_stavalues1 + i);
/*
* Detoast the array if needed, and in any case make a copy that's
@@ -3267,11 +3263,8 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
if (flags & ATTSTATSSLOT_NUMBERS)
{
- val = SysCacheGetAttr(STATRELATTINH, statstuple,
- Anum_pg_statistic_stanumbers1 + i,
- &isnull);
- if (isnull)
- elog(ERROR, "stanumbers is null");
+ val = SysCacheGetAttrNotNull(STATRELATTINH, statstuple,
+ Anum_pg_statistic_stanumbers1 + i);
/*
* Detoast the array if needed, and in any case make a copy that's
@@ -3479,7 +3472,6 @@ get_index_column_opclass(Oid index_oid, int attno)
HeapTuple tuple;
Form_pg_index rd_index;
Datum datum;
- bool isnull;
oidvector *indclass;
Oid opclass;
@@ -3501,10 +3493,7 @@ get_index_column_opclass(Oid index_oid, int attno)
return InvalidOid;
}
- datum = SysCacheGetAttr(INDEXRELID, tuple,
- Anum_pg_index_indclass, &isnull);
- Assert(!isnull);
-
+ datum = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indclass);
indclass = ((oidvector *) DatumGetPointer(datum));
Assert(attno <= indclass->dim1);
diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c
index 4f53d47233..5f3516ad0c 100644
--- a/src/backend/utils/cache/partcache.c
+++ b/src/backend/utils/cache/partcache.c
@@ -130,15 +130,13 @@ RelationBuildPartitionKey(Relation relation)
/* But use the hard way to retrieve further variable-length attributes */
/* Operator class */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partclass, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partclass);
opclass = (oidvector *) DatumGetPointer(datum);
/* Collation */
- datum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partcollation, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(PARTRELID, tuple,
+ Anum_pg_partitioned_table_partcollation);
collation = (oidvector *) DatumGetPointer(datum);
/* Expressions */
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 94abede512..0c1ed801e1 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -77,6 +77,7 @@
#include "catalog/pg_user_mapping.h"
#include "lib/qunique.h"
#include "utils/catcache.h"
+#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
@@ -1099,6 +1100,32 @@ SysCacheGetAttr(int cacheId, HeapTuple tup,
isNull);
}
+/*
+ * SysCacheGetAttrNotNull
+ *
+ * As above, a version of SysCacheGetAttr which knows that the attr cannot
+ * be NULL.
+ */
+Datum
+SysCacheGetAttrNotNull(int cacheId, HeapTuple tup,
+ AttrNumber attributeNumber)
+{
+ bool isnull;
+ Datum attr;
+
+ attr = SysCacheGetAttr(cacheId, tup, attributeNumber, &isnull);
+
+ if (isnull)
+ {
+ elog(ERROR,
+ "unexpected NULL value in cached tuple for pg_catalog.%s.%s",
+ get_rel_name(cacheinfo[cacheId].reloid),
+ NameStr(TupleDescAttr(SysCache[cacheId]->cc_tupdesc, attributeNumber - 1)->attname));
+ }
+
+ return attr;
+}
+
/*
* GetSysCacheHashValue
*
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 3f64161760..f72dd25efa 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -151,7 +151,6 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
HeapTuple procedureTuple;
Form_pg_proc procedureStruct;
Datum prosrcdatum;
- bool isnull;
char *prosrc;
/*
@@ -227,10 +226,8 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
* internal function is stored in prosrc (it doesn't have to be
* the same as the name of the alias!)
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
prosrc = TextDatumGetCString(prosrcdatum);
fbp = fmgr_lookupByName(prosrc);
if (fbp == NULL)
@@ -285,7 +282,6 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
{
HeapTuple procedureTuple;
Form_pg_proc procedureStruct;
- bool isnull;
Datum prosrcattr;
Datum probinattr;
@@ -308,25 +304,19 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
switch (procedureStruct->prolang)
{
case INTERNALlanguageId:
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
*mod = NULL; /* core binary */
*fn = TextDatumGetCString(prosrcattr);
break;
case ClanguageId:
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", functionId);
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
- probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", functionId);
+ probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_probin);
/*
* No need to check symbol presence / API version here, already
@@ -361,7 +351,6 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
CFuncHashTabEntry *hashentry;
PGFunction user_fn;
const Pg_finfo_record *inforec;
- bool isnull;
/*
* See if we have the function address cached already
@@ -385,16 +374,12 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
* While in general these columns might be null, that's not allowed
* for C-language functions.
*/
- prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc for C function %u", functionId);
+ prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc);
prosrcstring = TextDatumGetCString(prosrcattr);
- probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
- Anum_pg_proc_probin, &isnull);
- if (isnull)
- elog(ERROR, "null probin for C function %u", functionId);
+ probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
+ Anum_pg_proc_probin);
probinstring = TextDatumGetCString(probinattr);
/* Look up the function itself */
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 217835d590..24683bb608 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -1602,7 +1602,6 @@ get_func_result_name(Oid functionId)
HeapTuple procTuple;
Datum proargmodes;
Datum proargnames;
- bool isnull;
ArrayType *arr;
int numargs;
char *argmodes;
@@ -1623,14 +1622,10 @@ get_func_result_name(Oid functionId)
else
{
/* Get the data out of the tuple */
- proargmodes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargmodes,
- &isnull);
- Assert(!isnull);
- proargnames = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargnames,
- &isnull);
- Assert(!isnull);
+ proargmodes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargmodes);
+ proargnames = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargnames);
/*
* We expect the arrays to be 1-D arrays of the right types; verify
@@ -1717,14 +1712,10 @@ build_function_result_tupdesc_t(HeapTuple procTuple)
return NULL;
/* Get the data out of the tuple */
- proallargtypes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proallargtypes,
- &isnull);
- Assert(!isnull);
- proargmodes = SysCacheGetAttr(PROCOID, procTuple,
- Anum_pg_proc_proargmodes,
- &isnull);
- Assert(!isnull);
+ proallargtypes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proallargtypes);
+ proargmodes = SysCacheGetAttrNotNull(PROCOID, procTuple,
+ Anum_pg_proc_proargmodes);
proargnames = SysCacheGetAttr(PROCOID, procTuple,
Anum_pg_proc_proargnames,
&isnull);
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index b0e20cc635..04adaa03f6 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -398,11 +398,9 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
/* assign locale variables */
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_datcollate, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datcollate);
collate = TextDatumGetCString(datum);
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_datctype, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datctype);
ctype = TextDatumGetCString(datum);
if (pg_perm_setlocale(LC_COLLATE, collate) == NULL)
@@ -423,8 +421,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *icurules;
- datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticulocale, &isnull);
- Assert(!isnull);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_daticulocale);
iculocale = TextDatumGetCString(datum);
datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticurules, &isnull);
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index d5d50ceab4..28c72558d5 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -157,6 +157,9 @@ extern HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum);
extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
AttrNumber attributeNumber, bool *isNull);
+extern Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup,
+ AttrNumber attributeNumber);
+
extern uint32 GetSysCacheHashValue(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4);
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 8143ae40a0..d7d9c1bee3 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -2915,10 +2915,8 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger)
* we do not use a named subroutine so that we can call directly
* through the reference.
************************************************************/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
/************************************************************
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 7db912fd18..a341cde2c1 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -271,7 +271,6 @@ do_compile(FunctionCallInfo fcinfo,
bool is_dml_trigger = CALLED_AS_TRIGGER(fcinfo);
bool is_event_trigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
Datum prosrcdatum;
- bool isnull;
char *proc_source;
HeapTuple typeTup;
Form_pg_type typeStruct;
@@ -296,10 +295,7 @@ do_compile(FunctionCallInfo fcinfo,
* cannot be invoked recursively, so there's no need to save and restore
* the static variables used here.
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup, Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
plpgsql_scanner_init(proc_source);
diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c
index 494f109b32..79b6ef6a44 100644
--- a/src/pl/plpython/plpy_procedure.c
+++ b/src/pl/plpython/plpy_procedure.c
@@ -324,10 +324,8 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
/*
* get the text of the function.
*/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
procSource = TextDatumGetCString(prosrcdatum);
PLy_procedure_compile(proc, procSource);
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 499a9eaba8..e8f9d7b289 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -1454,7 +1454,6 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid,
Form_pg_type typeStruct;
char proc_internal_args[33 * FUNC_MAX_ARGS];
Datum prosrcdatum;
- bool isnull;
char *proc_source;
char buf[48];
Tcl_Interp *interp;
@@ -1673,10 +1672,8 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid,
/************************************************************
* Add user's function definition to proc body
************************************************************/
- prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
- Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
+ prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
+ Anum_pg_proc_prosrc);
proc_source = TextDatumGetCString(prosrcdatum);
UTF_BEGIN;
Tcl_DStringAppend(&proc_internal_body, UTF_E2U(proc_source), -1);
--
2.32.1 (Apple Git-133)
On 13.03.23 14:19, Daniel Gustafsson wrote:
On 2 Mar 2023, at 15:44, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
I think an error message like
"unexpected null value in system cache %d column %d"
is sufficient. Since these are "can't happen" errors, we don't need to
spend too much extra effort to make it prettier.I'd at least like to see it give the catalog's OID. That's easily
convertible to a name, and it doesn't tend to move around across PG
versions, neither of which are true for syscache IDs.Also, I'm fairly unconvinced that it's a "can't happen" --- this
would be very likely to fire as a result of catalog corruption,
so it would be good if it's at least minimally interpretable
by a non-expert. Given that we'll now have just one copy of the
code, ISTM there's a good case for doing the small extra work
to report catalog and column by name.Rebased v3 on top of recent conflicting ICU changes causing the patch to not
apply anymore. Also took another look around the tree to see if there were
missed callsites but found none new.
I think the only open question here was the granularity of the error
message, which I think you had addressed in v2.
+ if (isnull)
+ {
+ elog(ERROR,
+ "unexpected NULL value in cached tuple for pg_catalog.%s.%s",
+ get_rel_name(cacheinfo[cacheId].reloid),
+ NameStr(TupleDescAttr(SysCache[cacheId]->cc_tupdesc,
attributeNumber - 1)->attname));
+ }
I prefer to use "null value" for SQL null values, and NULL for the C symbol.
I'm a bit hesitant about hardcoding pg_catalog here. That happens to be
true, of course, but isn't actually enforced, I think. I think that
could be left off. It's not like people will be confused about which
schema "pg_class.relname" is in.
Also, the cached tuple isn't really for the attribute, so maybe split
that up a bit, like
"unexpected null value in cached tuple for catalog %s column %s"
On Tue, 14 Mar 2023 at 02:19, Daniel Gustafsson <daniel@yesql.se> wrote:
Rebased v3 on top of recent conflicting ICU changes causing the patch to not
apply anymore. Also took another look around the tree to see if there were
missed callsites but found none new.
I had a look at this. It generally seems like a good change.
One thing I thought about while looking is it stage 2 might do
something similar for SearchSysCacheN. I then wondered if we're more
likely to want to keep the localised __FILE__, __LINE__ and __func__
in the elog for those or not. It's probably less important that we're
losing those for this change, but worth noting here at least in case
nobody else thought of it.
I only noticed in a couple of places you have a few lines at 80 chars
before the LF. Ideally those would wrap at 79 so that it's 80
including LF. No big deal though.
David
On 23.03.23 09:52, David Rowley wrote:
One thing I thought about while looking is it stage 2 might do
something similar for SearchSysCacheN. I then wondered if we're more
likely to want to keep the localised __FILE__, __LINE__ and __func__
in the elog for those or not. It's probably less important that we're
losing those for this change, but worth noting here at least in case
nobody else thought of it.
I don't follow what you are asking for here.
On Fri, 24 Mar 2023 at 20:31, Peter Eisentraut
<peter.eisentraut@enterprisedb.com> wrote:
On 23.03.23 09:52, David Rowley wrote:
One thing I thought about while looking is it stage 2 might do
something similar for SearchSysCacheN. I then wondered if we're more
likely to want to keep the localised __FILE__, __LINE__ and __func__
in the elog for those or not. It's probably less important that we're
losing those for this change, but worth noting here at least in case
nobody else thought of it.I don't follow what you are asking for here.
I had two points:
1. Doing something similar for SearchSysCache1 and co might be a good
phase two to this change.
2. With the change Daniel is proposing here, \set VERBOSITY verbose is
not going to print as useful information to tracking down where any
unexpected nulls in the catalogue originates.
For #2, I don't think that's necessarily a problem. I can think of two
reasons why SysCacheGetAttrNotNull might throw an ERROR:
a) We used SysCacheGetAttrNotNull() when we should have used SysCacheGetAttr().
b) Catalogue corruption.
A more localised ERROR message might just help more easily tracking
down type a) problems. I imagine it won't be too difficult to just
grep for all the SysCacheGetAttrNotNull calls for the particular
nullable column to find the one causing the issue. For b), the error
message in SysCacheGetAttrNotNull is sufficient without needing to
know where the SysCacheGetAttrNotNull call came from.
David
On 24 Mar 2023, at 21:59, David Rowley <dgrowleyml@gmail.com> wrote:
On Fri, 24 Mar 2023 at 20:31, Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
On 23.03.23 09:52, David Rowley wrote:
One thing I thought about while looking is it stage 2 might do
something similar for SearchSysCacheN. I then wondered if we're more
likely to want to keep the localised __FILE__, __LINE__ and __func__
in the elog for those or not. It's probably less important that we're
losing those for this change, but worth noting here at least in case
nobody else thought of it.I don't follow what you are asking for here.
I had two points:
1. Doing something similar for SearchSysCache1 and co might be a good
phase two to this change.
Quite possibly yes, they do follow a pretty repeatable pattern.
2. With the change Daniel is proposing here, \set VERBOSITY verbose is
not going to print as useful information to tracking down where any
unexpected nulls in the catalogue originates.
Thats a fair point for the elog() removals, for the rather many assertions it
might be a net positive to get a non-local elog when failing in production.
--
Daniel Gustafsson
On 14 Mar 2023, at 08:00, Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
I prefer to use "null value" for SQL null values, and NULL for the C symbol.
Thats a fair point, I agree with that.
I'm a bit hesitant about hardcoding pg_catalog here. That happens to be true, of course, but isn't actually enforced, I think. I think that could be left off. It's not like people will be confused about which schema "pg_class.relname" is in.
Also, the cached tuple isn't really for the attribute, so maybe split that up a bit, like
"unexpected null value in cached tuple for catalog %s column %s"
No objections, so changed to that wording.
With these changes and a pgindent run across it per Davids comment downthread,
I've pushed this now. Thanks for review!
I'm keeping a watchful eye on the buildfarm; francolin has errored in
recoveryCheck which I'm looking into but at first glance I don't think it's
related (other animals have since passed it and it works locally, but I'll keep
digging at it to make sure).
--
Daniel Gustafsson
On Mon, Mar 13, 2023 at 02:19:07PM +0100, Daniel Gustafsson wrote:
On 2 Mar 2023, at 15:44, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
I think an error message like
"unexpected null value in system cache %d column %d"
is sufficient. Since these are "can't happen" errors, we don't need to
spend too much extra effort to make it prettier.I'd at least like to see it give the catalog's OID. That's easily
convertible to a name, and it doesn't tend to move around across PG
versions, neither of which are true for syscache IDs.Also, I'm fairly unconvinced that it's a "can't happen" --- this
would be very likely to fire as a result of catalog corruption,
so it would be good if it's at least minimally interpretable
by a non-expert. Given that we'll now have just one copy of the
code, ISTM there's a good case for doing the small extra work
to report catalog and column by name.Rebased v3 on top of recent conflicting ICU changes causing the patch to not
apply anymore. Also took another look around the tree to see if there were
missed callsites but found none new.
+++ b/src/backend/utils/cache/syscache.c
@@ -77,6 +77,7 @@
#include "catalog/pg_user_mapping.h"
#include "lib/qunique.h"
#include "utils/catcache.h"
+#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
@@ -1099,6 +1100,32 @@ SysCacheGetAttr(int cacheId, HeapTuple tup,
+ elog(ERROR,
+ "unexpected NULL value in cached tuple for pg_catalog.%s.%s",
+ get_rel_name(cacheinfo[cacheId].reloid),
Question: Is it safe to be making catalog access inside an error
handler, when one of the most likely reason for hitting the error is
catalog corruption ?
Maybe the answer is that it's not "safe" but "safe enough" - IOW, if
you're willing to throw an assertion, it's good enough to try to show
the table name, and if the error report crashes the server, that's "not
much worse" than having Asserted().
--
Justin
Justin Pryzby <pryzby@telsasoft.com> writes:
On Mon, Mar 13, 2023 at 02:19:07PM +0100, Daniel Gustafsson wrote:
+ elog(ERROR, + "unexpected NULL value in cached tuple for pg_catalog.%s.%s", + get_rel_name(cacheinfo[cacheId].reloid),
Question: Is it safe to be making catalog access inside an error
handler, when one of the most likely reason for hitting the error is
catalog corruption ?
I don't see a big problem here. If there were catalog corruption
preventing fetching the catalog's pg_class row, it's highly unlikely
that you'd have managed to retrieve a catalog row to complain about.
(That is, corruption in this particular catalog entry probably does
not extend to the metadata about the catalog containing it.)
Maybe the answer is that it's not "safe" but "safe enough"
Right.
If we got concerned about this we could dodge the extra catalog access
by adding the catalog's name to CatCache entries. I doubt it's worth
it though. We can always re-evaluate if we see actual evidence of
problems.
regards, tom lane