/*-------------------------------------------------------------------------
 *
 * heapfuncs.c
 *	  Functions to investigate heap pages
 *
 * We check the input to these functions for corrupt pointers etc. that
 * might cause crashes, but at the same time we try to print out as much
 * information as possible, even if it's nonsense. That's because if a
 * page is corrupt, we don't know why and how exactly it is corrupt, so we
 * let the user judge it.
 *
 * These functions are restricted to superusers for the fear of introducing
 * security holes if the input checking isn't as water-tight as it should be.
 * You'd need to be superuser to obtain a raw page image anyway, so
 * there's hardly any use case for using these without superuser-rights
 * anyway.
 *
 * Copyright (c) 2007-2023, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *	  contrib/pageinspect/heapfuncs.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/htup_details.h"
#include "access/relation.h"
#include "catalog/pg_am_d.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "pageinspect.h"
#include "port/pg_bitutils.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/rel.h"

/*
 * It's not supported to create tuples with oids anymore, but when pg_upgrade
 * was used to upgrade from an older version, tuples might still have an
 * oid. Seems worthwhile to display that.
 */
#define HeapTupleHeaderGetOidOld(tup) \
( \
	((tup)->t_infomask & HEAP_HASOID_OLD) ? \
	   *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \
	: \
		InvalidOid \
)


/*
 * bits_to_text
 *
 * Converts a bits8-array of 'len' bits to a human-readable
 * c-string representation.
 */
static char *
bits_to_text(bits8 *bits, int len)
{
	int			i;
	char	   *str;

	str = palloc(len + 1);

	for (i = 0; i < len; i++)
		str[i] = (bits[(i / 8)] & (1 << (i % 8))) ? '1' : '0';

	str[i] = '\0';

	return str;
}


/*
 * text_to_bits
 *
 * Converts a c-string representation of bits into a bits8-array. This is
 * the reverse operation of previous routine.
 */
static bits8 *
text_to_bits(char *str, int len)
{
	bits8	   *bits;
	int			off = 0;
	char		byte = 0;

	bits = palloc(len + 1);

	while (off < len)
	{
		if (off % 8 == 0)
			byte = 0;

		if ((str[off] == '0') || (str[off] == '1'))
			byte = byte | ((str[off] - '0') << off % 8);
		else
			ereport(ERROR,
					(errcode(ERRCODE_DATA_CORRUPTED),
					 errmsg("invalid character \"%.*s\" in t_bits string",
							pg_mblen(str + off), str + off)));

		if (off % 8 == 7)
			bits[off / 8] = byte;

		off++;
	}

	return bits;
}

/*
 * heap_page_items
 *
 * Allows inspection of line pointers and tuple headers of a heap page.
 */
PG_FUNCTION_INFO_V1(heap_page_items);

typedef struct heap_page_items_state
{
	TupleDesc	tupd;
	Page		page;
	uint16		offset;
} heap_page_items_state;

Datum
heap_page_items(PG_FUNCTION_ARGS)
{
	bytea	   *raw_page = PG_GETARG_BYTEA_P(0);
	heap_page_items_state *inter_call_data = NULL;
	FuncCallContext *fctx;
	int			raw_page_size;

	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("must be superuser to use raw page functions")));

	raw_page_size = VARSIZE(raw_page) - VARHDRSZ;

	if (SRF_IS_FIRSTCALL())
	{
		TupleDesc	tupdesc;
		MemoryContext mctx;

		if (raw_page_size < SizeOfPageHeaderData)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("input page too small (%d bytes)", raw_page_size)));

		fctx = SRF_FIRSTCALL_INIT();
		mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);

		inter_call_data = palloc(sizeof(heap_page_items_state));

		/* Build a tuple descriptor for our result type */
		if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
			elog(ERROR, "return type must be a row type");

		inter_call_data->tupd = tupdesc;

		inter_call_data->offset = FirstOffsetNumber;
		inter_call_data->page = VARDATA(raw_page);

		fctx->max_calls = PageGetMaxOffsetNumber(inter_call_data->page);
		fctx->user_fctx = inter_call_data;

		MemoryContextSwitchTo(mctx);
	}

	fctx = SRF_PERCALL_SETUP();
	inter_call_data = fctx->user_fctx;

	if (fctx->call_cntr < fctx->max_calls)
	{
		Page		page = inter_call_data->page;
		HeapTuple	resultTuple;
		Datum		result;
		ItemId		id;
		Datum		values[14];
		bool		nulls[14];
		uint16		lp_offset;
		uint16		lp_flags;
		uint16		lp_len;

		memset(nulls, 0, sizeof(nulls));

		/* Extract information from the line pointer */

		id = PageGetItemId(page, inter_call_data->offset);

		lp_offset = ItemIdGetOffset(id);
		lp_flags = ItemIdGetFlags(id);
		lp_len = ItemIdGetLength(id);

		values[0] = UInt16GetDatum(inter_call_data->offset);
		values[1] = UInt16GetDatum(lp_offset);
		values[2] = UInt16GetDatum(lp_flags);
		values[3] = UInt16GetDatum(lp_len);

		/*
		 * We do just enough validity checking to make sure we don't reference
		 * data outside the page passed to us. The page could be corrupt in
		 * many other ways, but at least we won't crash.
		 */
		if (ItemIdHasStorage(id) &&
			lp_len >= MinHeapTupleSize &&
			lp_offset == MAXALIGN(lp_offset) &&
			lp_offset + lp_len <= raw_page_size)
		{
			HeapTupleHeader tuphdr;

			/* Extract information from the tuple header */
			tuphdr = (HeapTupleHeader) PageGetItem(page, id);

			values[4] = UInt32GetDatum(HeapTupleHeaderGetRawXmin(tuphdr));
			values[5] = UInt32GetDatum(HeapTupleHeaderGetRawXmax(tuphdr));
			/* shared with xvac */
			values[6] = UInt32GetDatum(HeapTupleHeaderGetRawCommandId(tuphdr));
			values[7] = PointerGetDatum(&tuphdr->t_ctid);
			values[8] = UInt32GetDatum(tuphdr->t_infomask2);
			values[9] = UInt32GetDatum(tuphdr->t_infomask);
			values[10] = UInt8GetDatum(tuphdr->t_hoff);

			/*
			 * We already checked that the item is completely within the raw
			 * page passed to us, with the length given in the line pointer.
			 * But t_hoff could be out of range, so check it before relying on
			 * it to fetch additional info.
			 */
			if (tuphdr->t_hoff >= SizeofHeapTupleHeader &&
				tuphdr->t_hoff <= lp_len &&
				tuphdr->t_hoff == MAXALIGN(tuphdr->t_hoff))
			{
				int			tuple_data_len;
				bytea	   *tuple_data_bytea;

				/* Copy null bitmask and OID, if present */
				if (tuphdr->t_infomask & HEAP_HASNULL)
				{
					int			bitmaplen;

					bitmaplen = BITMAPLEN(HeapTupleHeaderGetNatts(tuphdr));
					/* better range-check the attribute count, too */
					if (bitmaplen <= tuphdr->t_hoff - SizeofHeapTupleHeader)
						values[11] =
							CStringGetTextDatum(bits_to_text(tuphdr->t_bits,
															 bitmaplen * BITS_PER_BYTE));
					else
						nulls[11] = true;
				}
				else
					nulls[11] = true;

				if (tuphdr->t_infomask & HEAP_HASOID_OLD)
					values[12] = HeapTupleHeaderGetOidOld(tuphdr);
				else
					nulls[12] = true;

				/* Copy raw tuple data into bytea attribute */
				tuple_data_len = lp_len - tuphdr->t_hoff;
				tuple_data_bytea = (bytea *) palloc(tuple_data_len + VARHDRSZ);
				SET_VARSIZE(tuple_data_bytea, tuple_data_len + VARHDRSZ);
				if (tuple_data_len > 0)
					memcpy(VARDATA(tuple_data_bytea),
						   (char *) tuphdr + tuphdr->t_hoff,
						   tuple_data_len);
				values[13] = PointerGetDatum(tuple_data_bytea);
			}
			else
			{
				nulls[11] = true;
				nulls[12] = true;
				nulls[13] = true;
			}
		}
		else
		{
			/*
			 * The line pointer is not used, or it's invalid. Set the rest of
			 * the fields to NULL
			 */
			int			i;

			for (i = 4; i <= 13; i++)
				nulls[i] = true;
		}

		/* Build and return the result tuple. */
		resultTuple = heap_form_tuple(inter_call_data->tupd, values, nulls);
		result = HeapTupleGetDatum(resultTuple);

		inter_call_data->offset++;

		SRF_RETURN_NEXT(fctx, result);
	}
	else
		SRF_RETURN_DONE(fctx);
}

/*
 * tuple_data_split_internal
 *
 * Split raw tuple data taken directly from a page into an array of bytea
 * elements. This routine does a lookup on NULL values and creates array
 * elements accordingly. This is a reimplementation of nocachegetattr()
 * in heaptuple.c simplified for educational purposes.
 */
static Datum
tuple_data_split_internal(Oid relid, char *tupdata,
						  uint16 tupdata_len, uint16 t_infomask,
						  uint16 t_infomask2, bits8 *t_bits,
						  bool do_detoast)
{
	ArrayBuildState *raw_attrs;
	int			nattrs;
	int			i;
	int			off = 0;
	Relation	rel;
	TupleDesc	tupdesc;

	/* Get tuple descriptor from relation OID */
	rel = relation_open(relid, AccessShareLock);
	tupdesc = RelationGetDescr(rel);

	raw_attrs = initArrayResult(BYTEAOID, CurrentMemoryContext, false);
	nattrs = tupdesc->natts;

	/*
	 * Sequences always use heap AM, but they don't show that in the catalogs.
	 */
	if (rel->rd_rel->relkind != RELKIND_SEQUENCE &&
		rel->rd_rel->relam != HEAP_TABLE_AM_OID)
		ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						errmsg("only heap AM is supported")));

	if (nattrs < (t_infomask2 & HEAP_NATTS_MASK))
		ereport(ERROR,
				(errcode(ERRCODE_DATA_CORRUPTED),
				 errmsg("number of attributes in tuple header is greater than number of attributes in tuple descriptor")));

	for (i = 0; i < nattrs; i++)
	{
		Form_pg_attribute attr;
		bool		is_null;
		bytea	   *attr_data = NULL;

		attr = TupleDescAttr(tupdesc, i);

		/*
		 * Tuple header can specify fewer attributes than tuple descriptor as
		 * ALTER TABLE ADD COLUMN without DEFAULT keyword does not actually
		 * change tuples in pages, so attributes with numbers greater than
		 * (t_infomask2 & HEAP_NATTS_MASK) should be treated as NULL.
		 */
		if (i >= (t_infomask2 & HEAP_NATTS_MASK))
			is_null = true;
		else
			is_null = (t_infomask & HEAP_HASNULL) && att_isnull(i, t_bits);

		if (!is_null)
		{
			int			len;

			if (attr->attlen == -1)
			{
				off = att_align_pointer(off, attr->attalign, -1,
										tupdata + off);

				/*
				 * As VARSIZE_ANY throws an exception if it can't properly
				 * detect the type of external storage in macros VARTAG_SIZE,
				 * this check is repeated to have a nicer error handling.
				 */
				if (VARATT_IS_EXTERNAL(tupdata + off) &&
					!VARATT_IS_EXTERNAL_ONDISK(tupdata + off) &&
					!VARATT_IS_EXTERNAL_INDIRECT(tupdata + off))
					ereport(ERROR,
							(errcode(ERRCODE_DATA_CORRUPTED),
							 errmsg("first byte of varlena attribute is incorrect for attribute %d", i)));

				len = VARSIZE_ANY(tupdata + off);
			}
			else
			{
				off = att_align_nominal(off, attr->attalign);
				len = attr->attlen;
			}

			if (tupdata_len < off + len)
				ereport(ERROR,
						(errcode(ERRCODE_DATA_CORRUPTED),
						 errmsg("unexpected end of tuple data")));

			if (attr->attlen == -1 && do_detoast)
				attr_data = pg_detoast_datum_copy((struct varlena *) (tupdata + off));
			else
			{
				attr_data = (bytea *) palloc(len + VARHDRSZ);
				SET_VARSIZE(attr_data, len + VARHDRSZ);
				memcpy(VARDATA(attr_data), tupdata + off, len);
			}

			off = att_addlength_pointer(off, attr->attlen,
										tupdata + off);
		}

		raw_attrs = accumArrayResult(raw_attrs, PointerGetDatum(attr_data),
									 is_null, BYTEAOID, CurrentMemoryContext);
		if (attr_data)
			pfree(attr_data);
	}

	if (tupdata_len != off)
		ereport(ERROR,
				(errcode(ERRCODE_DATA_CORRUPTED),
				 errmsg("end of tuple reached without looking at all its data")));

	relation_close(rel, AccessShareLock);

	return makeArrayResult(raw_attrs, CurrentMemoryContext);
}

/*
 * tuple_data_split
 *
 * Split raw tuple data taken directly from page into distinct elements
 * taking into account null values.
 */
PG_FUNCTION_INFO_V1(tuple_data_split);

Datum
tuple_data_split(PG_FUNCTION_ARGS)
{
	Oid			relid;
	bytea	   *raw_data;
	uint16		t_infomask;
	uint16		t_infomask2;
	char	   *t_bits_str;
	bool		do_detoast = false;
	bits8	   *t_bits = NULL;
	Datum		res;

	relid = PG_GETARG_OID(0);
	raw_data = PG_ARGISNULL(1) ? NULL : PG_GETARG_BYTEA_P(1);
	t_infomask = PG_GETARG_INT16(2);
	t_infomask2 = PG_GETARG_INT16(3);
	t_bits_str = PG_ARGISNULL(4) ? NULL :
		text_to_cstring(PG_GETARG_TEXT_PP(4));

	if (PG_NARGS() >= 6)
		do_detoast = PG_GETARG_BOOL(5);

	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("must be superuser to use raw page functions")));

	if (!raw_data)
		PG_RETURN_NULL();

	/*
	 * Convert t_bits string back to the bits8 array as represented in the
	 * tuple header.
	 */
	if (t_infomask & HEAP_HASNULL)
	{
		size_t		bits_str_len;
		size_t		bits_len;

		bits_len = BITMAPLEN(t_infomask2 & HEAP_NATTS_MASK) * BITS_PER_BYTE;
		if (!t_bits_str)
			ereport(ERROR,
					(errcode(ERRCODE_DATA_CORRUPTED),
					 errmsg("t_bits string must not be NULL")));

		bits_str_len = strlen(t_bits_str);
		if (bits_len != bits_str_len)
			ereport(ERROR,
					(errcode(ERRCODE_DATA_CORRUPTED),
					 errmsg("unexpected length of t_bits string: %zu, expected %zu",
							bits_str_len, bits_len)));

		/* do the conversion */
		t_bits = text_to_bits(t_bits_str, bits_str_len);
	}
	else
	{
		if (t_bits_str)
			ereport(ERROR,
					(errcode(ERRCODE_DATA_CORRUPTED),
					 errmsg("t_bits string is expected to be NULL, but instead it is %zu bytes long",
							strlen(t_bits_str))));
	}

	/* Split tuple data */
	res = tuple_data_split_internal(relid, (char *) raw_data + VARHDRSZ,
									VARSIZE(raw_data) - VARHDRSZ,
									t_infomask, t_infomask2, t_bits,
									do_detoast);

	if (t_bits)
		pfree(t_bits);

	PG_RETURN_DATUM(res);
}

/*
 * heap_tuple_infomask_flags
 *
 * Decode into a human-readable format t_infomask and t_infomask2 associated
 * to a tuple.  All the flags are described in access/htup_details.h.
 */
PG_FUNCTION_INFO_V1(heap_tuple_infomask_flags);

Datum
heap_tuple_infomask_flags(PG_FUNCTION_ARGS)
{
#define HEAP_TUPLE_INFOMASK_COLS 2
	Datum		values[HEAP_TUPLE_INFOMASK_COLS] = {0};
	bool		nulls[HEAP_TUPLE_INFOMASK_COLS] = {0};
	uint16		t_infomask = PG_GETARG_INT16(0);
	uint16		t_infomask2 = PG_GETARG_INT16(1);
	int			cnt = 0;
	ArrayType  *a;
	int			bitcnt;
	Datum	   *flags;
	TupleDesc	tupdesc;
	HeapTuple	tuple;

	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("must be superuser to use raw page functions")));

	/* Build a tuple descriptor for our result type */
	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
		elog(ERROR, "return type must be a row type");

	bitcnt = pg_popcount((const char *) &t_infomask, sizeof(uint16)) +
		pg_popcount((const char *) &t_infomask2, sizeof(uint16));

	/* If no flags, return a set of empty arrays */
	if (bitcnt <= 0)
	{
		values[0] = PointerGetDatum(construct_empty_array(TEXTOID));
		values[1] = PointerGetDatum(construct_empty_array(TEXTOID));
		tuple = heap_form_tuple(tupdesc, values, nulls);
		PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
	}

	/* build set of raw flags */
	flags = (Datum *) palloc0(sizeof(Datum) * bitcnt);

	/* decode t_infomask */
	if ((t_infomask & HEAP_HASNULL) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_HASNULL");
	if ((t_infomask & HEAP_HASVARWIDTH) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_HASVARWIDTH");
	if ((t_infomask & HEAP_HASEXTERNAL) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_HASEXTERNAL");
	if ((t_infomask & HEAP_HASOID_OLD) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_HASOID_OLD");
	if ((t_infomask & HEAP_XMAX_KEYSHR_LOCK) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_KEYSHR_LOCK");
	if ((t_infomask & HEAP_COMBOCID) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_COMBOCID");
	if ((t_infomask & HEAP_XMAX_EXCL_LOCK) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_EXCL_LOCK");
	if ((t_infomask & HEAP_XMAX_LOCK_ONLY) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_LOCK_ONLY");
	if ((t_infomask & HEAP_XMIN_COMMITTED) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMIN_COMMITTED");
	if ((t_infomask & HEAP_XMIN_INVALID) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMIN_INVALID");
	if ((t_infomask & HEAP_XMAX_COMMITTED) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_COMMITTED");
	if ((t_infomask & HEAP_XMAX_INVALID) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_INVALID");
	if ((t_infomask & HEAP_XMAX_IS_MULTI) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_IS_MULTI");
	if ((t_infomask & HEAP_UPDATED) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_UPDATED");
	if ((t_infomask & HEAP_MOVED_OFF) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_MOVED_OFF");
	if ((t_infomask & HEAP_MOVED_IN) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_MOVED_IN");

	/* decode t_infomask2 */
	if ((t_infomask2 & HEAP_KEYS_UPDATED) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_KEYS_UPDATED");
	if ((t_infomask2 & HEAP_HOT_UPDATED) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_HOT_UPDATED");
	if ((t_infomask2 & HEAP_ONLY_TUPLE) != 0)
		flags[cnt++] = CStringGetTextDatum("HEAP_ONLY_TUPLE");

	/* build value */
	Assert(cnt <= bitcnt);
	a = construct_array_builtin(flags, cnt, TEXTOID);
	values[0] = PointerGetDatum(a);

	/*
	 * Build set of combined flags.  Use the same array as previously, this
	 * keeps the code simple.
	 */
	cnt = 0;
	MemSet(flags, 0, sizeof(Datum) * bitcnt);

	/* decode combined masks of t_infomask */
	if ((t_infomask & HEAP_XMAX_SHR_LOCK) == HEAP_XMAX_SHR_LOCK)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_SHR_LOCK");
	if ((t_infomask & HEAP_XMIN_FROZEN) == HEAP_XMIN_FROZEN)
		flags[cnt++] = CStringGetTextDatum("HEAP_XMIN_FROZEN");
	if ((t_infomask & HEAP_MOVED) == HEAP_MOVED)
		flags[cnt++] = CStringGetTextDatum("HEAP_MOVED");

	/* Build an empty array if there are no combined flags */
	if (cnt == 0)
		a = construct_empty_array(TEXTOID);
	else
		a = construct_array_builtin(flags, cnt, TEXTOID);
	pfree(flags);
	values[1] = PointerGetDatum(a);

	/* Returns the record as Datum */
	tuple = heap_form_tuple(tupdesc, values, nulls);
	PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
}
