Hi, I searched the mailing list but found nothing. Any reason why TupleDescAttr is a macro and not a static inline?
Rather than adding an Assert attached POC replace TupleDescAttr macro by a static inline function with AssertArg. It: - Factorize Assert. - Trigger an Assert in JIT_deform if natts is wrong. - Currently In HEAD src/backend/access/common/tupdesc.c:TupleDescCopyEntry() compiler can optimize out AssertArg(PointerIsValid(...)), no idea if compiling with both cassert and -O2 make sense though). - Remove two UB in memcpy when natts is zero. Note: Comment line 1480 in ../contrib/tablefunc/tablefunc.c is wrong it's the fourth column. Regards Didier On Thu, Jun 13, 2019 at 8:35 PM Andres Freund <and...@anarazel.de> wrote: > > Hi, > > On June 13, 2019 11:08:15 AM PDT, didier <did...@gmail.com> wrote: > >Extensions can do it, timescaledb in this case with: > >INSERT INTO ... RETURNING *; > > > >Or replacing the test in llvm_compile_expr with an Assert in > >slot_compile_deform ? > > In that case we ought to never generate a deform expression step - core code > doesn't afair. That's only done I'd there's actually something to deform. I'm > fine with adding an assert tough > > Andres > -- > Sent from my Android device with K-9 Mail. Please excuse my brevity.
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index a48a6cd757..23ef9a6a75 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -86,9 +86,6 @@ getmissingattr(TupleDesc tupleDesc, { Form_pg_attribute att; - Assert(attnum <= tupleDesc->natts); - Assert(attnum > 0); - att = TupleDescAttr(tupleDesc, attnum - 1); if (att->atthasmissing) diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index 6bc4e4c036..850771acf5 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -115,7 +115,8 @@ CreateTupleDescCopy(TupleDesc tupdesc) desc = CreateTemplateTupleDesc(tupdesc->natts); /* Flat-copy the attribute array */ - memcpy(TupleDescAttr(desc, 0), + if (desc->natts) + memcpy(TupleDescAttr(desc, 0), TupleDescAttr(tupdesc, 0), desc->natts * sizeof(FormData_pg_attribute)); @@ -156,7 +157,8 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) desc = CreateTemplateTupleDesc(tupdesc->natts); /* Flat-copy the attribute array */ - memcpy(TupleDescAttr(desc, 0), + if (desc->natts) + memcpy(TupleDescAttr(desc, 0), TupleDescAttr(tupdesc, 0), desc->natts * sizeof(FormData_pg_attribute)); @@ -274,16 +276,6 @@ TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno, Form_pg_attribute dstAtt = TupleDescAttr(dst, dstAttno - 1); Form_pg_attribute srcAtt = TupleDescAttr(src, srcAttno - 1); - /* - * sanity checks - */ - AssertArg(PointerIsValid(src)); - AssertArg(PointerIsValid(dst)); - AssertArg(srcAttno >= 1); - AssertArg(srcAttno <= src->natts); - AssertArg(dstAttno >= 1); - AssertArg(dstAttno <= dst->natts); - memcpy(dstAtt, srcAtt, ATTRIBUTE_FIXED_PART_SIZE); /* @@ -611,13 +603,6 @@ TupleDescInitEntry(TupleDesc desc, Form_pg_type typeForm; Form_pg_attribute att; - /* - * sanity checks - */ - AssertArg(PointerIsValid(desc)); - AssertArg(attributeNumber >= 1); - AssertArg(attributeNumber <= desc->natts); - /* * initialize the attribute fields */ @@ -682,11 +667,6 @@ TupleDescInitBuiltinEntry(TupleDesc desc, { Form_pg_attribute att; - /* sanity checks */ - AssertArg(PointerIsValid(desc)); - AssertArg(attributeNumber >= 1); - AssertArg(attributeNumber <= desc->natts); - /* initialize the attribute fields */ att = TupleDescAttr(desc, attributeNumber - 1); att->attrelid = 0; /* dummy value */ @@ -770,13 +750,6 @@ TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid) { - /* - * sanity checks - */ - AssertArg(PointerIsValid(desc)); - AssertArg(attributeNumber >= 1); - AssertArg(attributeNumber <= desc->natts); - TupleDescAttr(desc, attributeNumber - 1)->attcollation = collationid; } diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d768b9b061..2fbd2ef207 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -3842,7 +3842,6 @@ heap_tuple_attr_equals(TupleDesc tupdesc, int attrnum, } else { - Assert(attrnum <= tupdesc->natts); att = TupleDescAttr(tupdesc, attrnum - 1); return datumIsEqual(value1, value2, att->attbyval, att->attlen); } diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 77a48b039d..f34334b2a2 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -2600,7 +2600,6 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset, } } - Assert(count <= tupdesc->natts); for (varattno = 0; varattno < count; varattno++) { Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno); @@ -2837,8 +2836,6 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum, /* Composite data type, e.g. a table's row type */ Form_pg_attribute att_tup; - Assert(tupdesc); - Assert(attnum <= tupdesc->natts); att_tup = TupleDescAttr(tupdesc, attnum - 1); /* @@ -3050,8 +3047,6 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum) /* Composite data type, e.g. a table's row type */ Form_pg_attribute att_tup; - Assert(tupdesc); - Assert(attnum - atts_done <= tupdesc->natts); att_tup = TupleDescAttr(tupdesc, attnum - atts_done - 1); return att_tup->attisdropped; diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 00def27881..8554e42803 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -1918,8 +1918,6 @@ CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys) Form_pg_attribute att; /* system attribute are not supported in caches */ - Assert(attnum > 0); - att = TupleDescAttr(tupdesc, attnum - 1); if (!att->attbyval) diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h index a06800555c..4b09c26915 100644 --- a/src/include/access/tupdesc.h +++ b/src/include/access/tupdesc.h @@ -89,7 +89,17 @@ typedef struct TupleDescData typedef struct TupleDescData *TupleDesc; /* Accessor for the i'th attribute of tupdesc. */ +#if 1 +static inline FormData_pg_attribute *TupleDescAttr(TupleDesc tupdesc, int i) +{ + AssertArg(PointerIsValid(tupdesc)); + AssertArg(i >= 0); + AssertArg(i < tupdesc->natts); + return &tupdesc->attrs[i]; +} +#else #define TupleDescAttr(tupdesc, i) (&(tupdesc)->attrs[(i)]) +#endif extern TupleDesc CreateTemplateTupleDesc(int natts);