* contains the user-level large object application interface routines.
*
*
+ * Note: we access pg_largeobject.data using its C struct declaration.
+ * This is safe because it immediately follows pageno which is an int4 field,
+ * and therefore the data field will always be 4-byte aligned, even if it
+ * is in the short 1-byte-header format. We have to detoast it since it's
+ * quite likely to be in compressed or short format. We also need to check
+ * for NULLs, since initdb will mark loid and pageno but not data as NOT NULL.
+ *
* Note: many of these routines leak memory in CurrentMemoryContext, as indeed
* does most of the backend code. We expect that CurrentMemoryContext will
* be a short-lived context. Data that must persist across function calls
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.124 2007/04/06 04:21:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.125 2007/06/12 19:46:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
bool pfreeit;
found = true;
+ if (HeapTupleHasNulls(tuple)) /* paranoia */
+ elog(ERROR, "null field found in pg_largeobject");
data = (Form_pg_largeobject) GETSTRUCT(tuple);
- datafield = &(data->data);
+ datafield = &(data->data); /* see note at top of file */
pfreeit = false;
if (VARATT_IS_EXTENDED(datafield))
{
bytea *datafield;
bool pfreeit;
+ if (HeapTupleHasNulls(tuple)) /* paranoia */
+ elog(ERROR, "null field found in pg_largeobject");
data = (Form_pg_largeobject) GETSTRUCT(tuple);
/*
off = (int) (obj_desc->offset - pageoff);
Assert(off >= 0 && off < LOBLKSIZE);
- datafield = &(data->data);
+ datafield = &(data->data); /* see note at top of file */
pfreeit = false;
if (VARATT_IS_EXTENDED(datafield))
{
{
if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
{
+ if (HeapTupleHasNulls(oldtuple)) /* paranoia */
+ elog(ERROR, "null field found in pg_largeobject");
olddata = (Form_pg_largeobject) GETSTRUCT(oldtuple);
Assert(olddata->pageno >= pageno);
}
*
* First, load old data into workbuf
*/
- datafield = &(olddata->data);
+ datafield = &(olddata->data); /* see note at top of file */
pfreeit = false;
if (VARATT_IS_EXTENDED(datafield))
{
olddata = NULL;
if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
{
+ if (HeapTupleHasNulls(oldtuple)) /* paranoia */
+ elog(ERROR, "null field found in pg_largeobject");
olddata = (Form_pg_largeobject) GETSTRUCT(oldtuple);
Assert(olddata->pageno >= pageno);
}
if (olddata != NULL && olddata->pageno == pageno)
{
/* First, load old data into workbuf */
- bytea *datafield = &(olddata->data);
+ bytea *datafield = &(olddata->data); /* see note at top of file */
bool pfreeit = false;
int pagelen;