On Wed, Jan 6, 2010 at 1:16 PM, Tom Lane <[email protected]> wrote:
> Robert Haas <[email protected]> writes:
>> Spoke with Bruce on IM and we think the best option is to just remove
>> the NULL tests. Since it's been this way for 11 years, presumably
>> nobody is trying to use it with a NULL fourth argument.
>
>> Proposed patch attached.
>
> There are a number of is-null checks in related code that ought to go
> away too --- look at heap_getattr, nocachegetattr, etc. Our principle
> here ought to be that none of the field-fetching routines allow a null
> pointer.
Revised patch attached. Blow-by-blow:
- fastgetattr() is both a macro and a function. I previously fixed
the macro; now I've made the function correspond.
- heap_getattr() is always a macro. The previous version ripped out
the single NULL test therein and this one does the same thing.
- nocachegetattr() already documents that it can't be called when the
attribute being fetched is null, but for some reason it still has an
isNull argument and a bunch of residual cruft, which I have ripped
out, for a substantial improvement in readability, IMHO.
- heap_getsysattr() has an if (isnull) test, which I have removed.
- index_getattr() already follows the proposed coding standard, so no change.
- nocache_index_getattr() is a lobotomized clone of nocachegetattr()
right down to the duplicated comment (gotta love that), and I've given
it the same treatment.
- slot_getattr() already follows the proposed coding standard, so no change.
The naming consistency of these functions and macros leaves a great
deal to be desired. The arrangement whereby we have a macro called
fetchatt() which calls a macro called fetch_att() is particularly
jaw-dropping.
...Robert
*** a/src/backend/access/common/heaptuple.c
--- b/src/backend/access/common/heaptuple.c
***************
*** 323,330 **** heap_attisnull(HeapTuple tup, int attnum)
Datum
nocachegetattr(HeapTuple tuple,
int attnum,
! TupleDesc tupleDesc,
! bool *isnull)
{
HeapTupleHeader tup = tuple->t_data;
Form_pg_attribute *att = tupleDesc->attrs;
--- 323,329 ----
Datum
nocachegetattr(HeapTuple tuple,
int attnum,
! TupleDesc tupleDesc)
{
HeapTupleHeader tup = tuple->t_data;
Form_pg_attribute *att = tupleDesc->attrs;
***************
*** 333,340 **** nocachegetattr(HeapTuple tuple,
bool slow = false; /* do we have to walk attrs? */
int off; /* current offset within data */
- (void) isnull; /* not used */
-
/* ----------------
* Three cases:
*
--- 332,337 ----
***************
*** 344,411 **** nocachegetattr(HeapTuple tuple,
* ----------------
*/
- #ifdef IN_MACRO
- /* This is handled in the macro */
- Assert(attnum > 0);
-
- if (isnull)
- *isnull = false;
- #endif
-
attnum--;
! if (HeapTupleNoNulls(tuple))
! {
! #ifdef IN_MACRO
! /* This is handled in the macro */
! if (att[attnum]->attcacheoff >= 0)
! {
! return fetchatt(att[attnum],
! (char *) tup + tup->t_hoff +
! att[attnum]->attcacheoff);
! }
! #endif
! }
! else
{
/*
* there's a null somewhere in the tuple
*
! * check to see if desired att is null
*/
! #ifdef IN_MACRO
! /* This is handled in the macro */
! if (att_isnull(attnum, bp))
! {
! if (isnull)
! *isnull = true;
! return (Datum) NULL;
! }
! #endif
!
! /*
! * Now check to see if any preceding bits are null...
! */
{
! int byte = attnum >> 3;
! int finalbit = attnum & 0x07;
! /* check for nulls "before" final bit of last byte */
! if ((~bp[byte]) & ((1 << finalbit) - 1))
! slow = true;
! else
{
! /* check for nulls in any "earlier" bytes */
! int i;
!
! for (i = 0; i < byte; i++)
{
! if (bp[i] != 0xFF)
! {
! slow = true;
! break;
! }
}
}
}
--- 341,372 ----
* ----------------
*/
attnum--;
! if (!HeapTupleNoNulls(tuple))
{
/*
* there's a null somewhere in the tuple
*
! * check to see if any preceding bits are null...
*/
+ int byte = attnum >> 3;
+ int finalbit = attnum & 0x07;
! /* check for nulls "before" final bit of last byte */
! if ((~bp[byte]) & ((1 << finalbit) - 1))
! slow = true;
! else
{
! /* check for nulls in any "earlier" bytes */
! int i;
! for (i = 0; i < byte; i++)
{
! if (bp[i] != 0xFF)
{
! slow = true;
! break;
}
}
}
***************
*** 567,574 **** heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Assert(tup);
/* Currently, no sys attribute ever reads as NULL. */
! if (isnull)
! *isnull = false;
switch (attnum)
{
--- 528,534 ----
Assert(tup);
/* Currently, no sys attribute ever reads as NULL. */
! *isnull = false;
switch (attnum)
{
*** a/src/backend/access/common/indextuple.c
--- b/src/backend/access/common/indextuple.c
***************
*** 200,207 **** index_form_tuple(TupleDesc tupleDescriptor,
Datum
nocache_index_getattr(IndexTuple tup,
int attnum,
! TupleDesc tupleDesc,
! bool *isnull)
{
Form_pg_attribute *att = tupleDesc->attrs;
char *tp; /* ptr to data part of tuple */
--- 200,206 ----
Datum
nocache_index_getattr(IndexTuple tup,
int attnum,
! TupleDesc tupleDesc)
{
Form_pg_attribute *att = tupleDesc->attrs;
char *tp; /* ptr to data part of tuple */
***************
*** 210,217 **** nocache_index_getattr(IndexTuple tup,
int data_off; /* tuple data offset */
int off; /* current offset within data */
- (void) isnull; /* not used */
-
/* ----------------
* Three cases:
*
--- 209,214 ----
***************
*** 221,251 **** nocache_index_getattr(IndexTuple tup,
* ----------------
*/
- #ifdef IN_MACRO
- /* This is handled in the macro */
- Assert(PointerIsValid(isnull));
- Assert(attnum > 0);
-
- *isnull = false;
- #endif
-
data_off = IndexInfoFindDataOffset(tup->t_info);
attnum--;
! if (!IndexTupleHasNulls(tup))
! {
! #ifdef IN_MACRO
! /* This is handled in the macro */
! if (att[attnum]->attcacheoff >= 0)
! {
! return fetchatt(att[attnum],
! (char *) tup + data_off +
! att[attnum]->attcacheoff);
! }
! #endif
! }
! else
{
/*
* there's a null somewhere in the tuple
--- 218,228 ----
* ----------------
*/
data_off = IndexInfoFindDataOffset(tup->t_info);
attnum--;
! if (IndexTupleHasNulls(tup))
{
/*
* there's a null somewhere in the tuple
***************
*** 256,271 **** nocache_index_getattr(IndexTuple tup,
/* XXX "knows" t_bits are just after fixed tuple header! */
bp = (bits8 *) ((char *) tup + sizeof(IndexTupleData));
- #ifdef IN_MACRO
- /* This is handled in the macro */
-
- if (att_isnull(attnum, bp))
- {
- *isnull = true;
- return (Datum) NULL;
- }
- #endif
-
/*
* Now check to see if any preceding bits are null...
*/
--- 233,238 ----
*** a/src/backend/access/heap/heapam.c
--- b/src/backend/access/heap/heapam.c
***************
*** 834,840 **** fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
return (
(attnum) > 0 ?
(
! ((isnull) ? (*(isnull) = false) : (dummyret) NULL),
HeapTupleNoNulls(tup) ?
(
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff >= 0 ?
--- 834,840 ----
return (
(attnum) > 0 ?
(
! (*(isnull) = false),
HeapTupleNoNulls(tup) ?
(
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff >= 0 ?
***************
*** 844,861 **** fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff)
)
:
! nocachegetattr((tup), (attnum), (tupleDesc), (isnull))
)
:
(
att_isnull((attnum) - 1, (tup)->t_data->t_bits) ?
(
! ((isnull) ? (*(isnull) = true) : (dummyret) NULL),
(Datum) NULL
)
:
(
! nocachegetattr((tup), (attnum), (tupleDesc), (isnull))
)
)
)
--- 844,861 ----
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff)
)
:
! nocachegetattr((tup), (attnum), (tupleDesc))
)
:
(
att_isnull((attnum) - 1, (tup)->t_data->t_bits) ?
(
! (*(isnull) = true),
(Datum) NULL
)
:
(
! nocachegetattr((tup), (attnum), (tupleDesc))
)
)
)
*** a/src/include/access/htup.h
--- b/src/include/access/htup.h
***************
*** 763,769 **** extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup,
#define fastgetattr(tup, attnum, tupleDesc, isnull) \
( \
AssertMacro((attnum) > 0), \
! (((isnull) != NULL) ? (*(isnull) = false) : (dummyret)NULL), \
HeapTupleNoNulls(tup) ? \
( \
(tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \
--- 763,769 ----
#define fastgetattr(tup, attnum, tupleDesc, isnull) \
( \
AssertMacro((attnum) > 0), \
! (*(isnull) = false), \
HeapTupleNoNulls(tup) ? \
( \
(tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \
***************
*** 773,790 **** extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup,
(tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
) \
: \
! nocachegetattr((tup), (attnum), (tupleDesc), (isnull)) \
) \
: \
( \
att_isnull((attnum)-1, (tup)->t_data->t_bits) ? \
( \
! (((isnull) != NULL) ? (*(isnull) = true) : (dummyret)NULL), \
(Datum)NULL \
) \
: \
( \
! nocachegetattr((tup), (attnum), (tupleDesc), (isnull)) \
) \
) \
)
--- 773,790 ----
(tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
) \
: \
! nocachegetattr((tup), (attnum), (tupleDesc)) \
) \
: \
( \
att_isnull((attnum)-1, (tup)->t_data->t_bits) ? \
( \
! (*(isnull) = true), \
(Datum)NULL \
) \
: \
( \
! nocachegetattr((tup), (attnum), (tupleDesc)) \
) \
) \
)
***************
*** 818,824 **** extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
( \
((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \
( \
! (((isnull) != NULL) ? (*(isnull) = true) : (dummyret)NULL), \
(Datum)NULL \
) \
: \
--- 818,824 ----
( \
((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \
( \
! (*(isnull) = true), \
(Datum)NULL \
) \
: \
***************
*** 838,844 **** extern void heap_fill_tuple(TupleDesc tupleDesc,
uint16 *infomask, bits8 *bit);
extern bool heap_attisnull(HeapTuple tup, int attnum);
extern Datum nocachegetattr(HeapTuple tup, int attnum,
! TupleDesc att, bool *isnull);
extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
bool *isnull);
extern HeapTuple heap_copytuple(HeapTuple tuple);
--- 838,844 ----
uint16 *infomask, bits8 *bit);
extern bool heap_attisnull(HeapTuple tup, int attnum);
extern Datum nocachegetattr(HeapTuple tup, int attnum,
! TupleDesc att);
extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
bool *isnull);
extern HeapTuple heap_copytuple(HeapTuple tuple);
*** a/src/include/access/itup.h
--- b/src/include/access/itup.h
***************
*** 110,116 **** typedef IndexAttributeBitMapData *IndexAttributeBitMap;
+ (tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
) \
: \
! nocache_index_getattr((tup), (attnum), (tupleDesc), (isnull)) \
) \
: \
( \
--- 110,116 ----
+ (tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
) \
: \
! nocache_index_getattr((tup), (attnum), (tupleDesc)) \
) \
: \
( \
***************
*** 121,127 **** typedef IndexAttributeBitMapData *IndexAttributeBitMap;
) \
: \
( \
! nocache_index_getattr((tup), (attnum), (tupleDesc), (isnull)) \
) \
) \
)
--- 121,127 ----
) \
: \
( \
! nocache_index_getattr((tup), (attnum), (tupleDesc)) \
) \
) \
)
***************
*** 142,148 **** typedef IndexAttributeBitMapData *IndexAttributeBitMap;
extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
Datum *values, bool *isnull);
extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
! TupleDesc tupleDesc, bool *isnull);
extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
Datum *values, bool *isnull);
extern IndexTuple CopyIndexTuple(IndexTuple source);
--- 142,148 ----
extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
Datum *values, bool *isnull);
extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
! TupleDesc tupleDesc);
extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
Datum *values, bool *isnull);
extern IndexTuple CopyIndexTuple(IndexTuple source);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers