PostgreSQL Source Code: contrib/pageinspect/heapfuncs.c File Reference (original) (raw)

#include "[postgres.h](postgres%5F8h%5Fsource.html)"
#include "[access/htup_details.h](htup%5F%5Fdetails%5F8h%5Fsource.html)"
#include "[access/relation.h](relation%5F8h%5Fsource.html)"
#include "catalog/pg_am_d.h"
#include "[catalog/pg_type.h](pg%5F%5Ftype%5F8h%5Fsource.html)"
#include "[funcapi.h](funcapi%5F8h%5Fsource.html)"
#include "[mb/pg_wchar.h](pg%5F%5Fwchar%5F8h%5Fsource.html)"
#include "[miscadmin.h](miscadmin%5F8h%5Fsource.html)"
#include "[port/pg_bitutils.h](pg%5F%5Fbitutils%5F8h%5Fsource.html)"
#include "[utils/array.h](array%5F8h%5Fsource.html)"
#include "[utils/builtins.h](builtins%5F8h%5Fsource.html)"
#include "[utils/rel.h](rel%5F8h%5Fsource.html)"

Go to the source code of this file.

Functions
static Oid HeapTupleHeaderGetOidOld (const HeapTupleHeaderData *tup)
static char * bits_to_text (bits8 *bits, int len)
static bits8 * text_to_bits (char *str, int len)
PG_FUNCTION_INFO_V1 (heap_page_items)
Datum heap_page_items (PG_FUNCTION_ARGS)
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)
PG_FUNCTION_INFO_V1 (tuple_data_split)
Datum tuple_data_split (PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1 (heap_tuple_infomask_flags)
Datum heap_tuple_infomask_flags (PG_FUNCTION_ARGS)

HEAP_TUPLE_INFOMASK_COLS

#define HEAP_TUPLE_INFOMASK_COLS 2

heap_page_items_state

bits_to_text()

static char * bits_to_text ( bits8 * bits, int len ) static

heap_page_items()

Definition at line 130 of file heapfuncs.c.

131{

135 int raw_page_size;

136

139 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

140 errmsg("must be superuser to use raw page functions")));

141

143

145 {

148

151 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

152 errmsg("input page too small (%d bytes)", raw_page_size)));

153

156

158

159

161 elog(ERROR, "return type must be a row type");

162

163 inter_call_data->tupd = tupdesc;

164

166 inter_call_data->page = VARDATA(raw_page);

167

169 fctx->user_fctx = inter_call_data;

170

172 }

173

175 inter_call_data = fctx->user_fctx;

176

178 {

179 Page page = inter_call_data->page;

184 bool nulls[14];

188

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

190

191

192

194

198

203

204

205

206

207

208

211 lp_offset == MAXALIGN(lp_offset) &&

212 lp_offset + lp_len <= raw_page_size)

213 {

215

216

218

221

227

228

229

230

231

232

233

235 tuphdr->t_hoff <= lp_len &&

237 {

238 int tuple_data_len;

239 bytea *tuple_data_bytea;

240

241

243 {

244 int bitmaplen;

245

247

252 else

253 nulls[11] = true;

254 }

255 else

256 nulls[11] = true;

257

260 else

261 nulls[12] = true;

262

263

264 tuple_data_len = lp_len - tuphdr->t_hoff;

267 if (tuple_data_len > 0)

268 memcpy(VARDATA(tuple_data_bytea),

269 (char *) tuphdr + tuphdr->t_hoff,

270 tuple_data_len);

272 }

273 else

274 {

275 nulls[11] = true;

276 nulls[12] = true;

277 nulls[13] = true;

278 }

279 }

280 else

281 {

282

283

284

285

286 int i;

287

288 for (i = 4; i <= 13; i++)

289 nulls[i] = true;

290 }

291

292

295

296 inter_call_data->offset++;

297

299 }

300 else

302}

static Datum values[MAXATTR]

static Item PageGetItem(const PageData *page, const ItemIdData *itemId)

#define SizeOfPageHeaderData

static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)

static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)

#define CStringGetTextDatum(s)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

#define PG_GETARG_BYTEA_P(n)

TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)

#define SRF_IS_FIRSTCALL()

#define SRF_PERCALL_SETUP()

#define SRF_RETURN_NEXT(_funcctx, _result)

#define SRF_FIRSTCALL_INIT()

static Datum HeapTupleGetDatum(const HeapTupleData *tuple)

#define SRF_RETURN_DONE(_funcctx)

static char * bits_to_text(bits8 *bits, int len)

static Oid HeapTupleHeaderGetOidOld(const HeapTupleHeaderData *tup)

HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)

HeapTupleHeaderData * HeapTupleHeader

#define HeapTupleHeaderGetNatts(tup)

#define SizeofHeapTupleHeader

static int BITMAPLEN(int NATTS)

static CommandId HeapTupleHeaderGetRawCommandId(const HeapTupleHeaderData *tup)

static TransactionId HeapTupleHeaderGetRawXmax(const HeapTupleHeaderData *tup)

static TransactionId HeapTupleHeaderGetRawXmin(const HeapTupleHeaderData *tup)

#define ItemIdGetLength(itemId)

#define ItemIdGetOffset(itemId)

#define ItemIdGetFlags(itemId)

#define ItemIdHasStorage(itemId)

#define FirstOffsetNumber

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

static Datum PointerGetDatum(const void *X)

static Datum UInt16GetDatum(uint16 X)

static Datum UInt8GetDatum(uint8 X)

static Datum UInt32GetDatum(uint32 X)

MemoryContext multi_call_memory_ctx

#define SET_VARSIZE(PTR, len)

References BITMAPLEN(), BITS_PER_BYTE, bits_to_text(), FuncCallContext::call_cntr, CStringGetTextDatum, elog, ereport, errcode(), errmsg(), ERROR, FirstOffsetNumber, get_call_result_type(), heap_form_tuple(), HEAP_HASNULL, HEAP_HASOID_OLD, HeapTupleGetDatum(), HeapTupleHeaderGetNatts, HeapTupleHeaderGetOidOld(), HeapTupleHeaderGetRawCommandId(), HeapTupleHeaderGetRawXmax(), HeapTupleHeaderGetRawXmin(), i, ItemIdGetFlags, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, FuncCallContext::max_calls, MAXALIGN, MemoryContextSwitchTo(), MinHeapTupleSize, FuncCallContext::multi_call_memory_ctx, heap_page_items_state::offset, heap_page_items_state::page, PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), palloc(), PG_GETARG_BYTEA_P, PointerGetDatum(), SET_VARSIZE, SizeofHeapTupleHeader, SizeOfPageHeaderData, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, superuser(), HeapTupleHeaderData::t_bits, HeapTupleHeaderData::t_ctid, HeapTupleHeaderData::t_hoff, HeapTupleHeaderData::t_infomask, HeapTupleHeaderData::t_infomask2, heap_page_items_state::tupd, TYPEFUNC_COMPOSITE, UInt16GetDatum(), UInt32GetDatum(), UInt8GetDatum(), FuncCallContext::user_fctx, values, VARDATA, VARHDRSZ, and VARSIZE.

heap_tuple_infomask_flags()

Definition at line 520 of file heapfuncs.c.

521{

522#define HEAP_TUPLE_INFOMASK_COLS 2

527 int cnt = 0;

529 int bitcnt;

533

536 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

537 errmsg("must be superuser to use raw page functions")));

538

539

541 elog(ERROR, "return type must be a row type");

542

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

545

546

547 if (bitcnt <= 0)

548 {

553 }

554

555

557

558

591

592

599

600

601 Assert(cnt <= bitcnt);

604

605

606

607

608

609 cnt = 0;

610 MemSet(flags, 0, sizeof(Datum) * bitcnt);

611

612

619

620

621 if (cnt == 0)

623 else

627

628

631}

ArrayType * construct_empty_array(Oid elmtype)

ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)

#define MemSet(start, val, len)

#define PG_RETURN_DATUM(x)

#define PG_GETARG_INT16(n)

Assert(PointerIsAligned(start, uint64))

#define HEAP_TUPLE_INFOMASK_COLS

#define HEAP_XMAX_SHR_LOCK

#define HEAP_XMIN_COMMITTED

#define HEAP_KEYS_UPDATED

#define HEAP_XMAX_LOCK_ONLY

#define HEAP_XMAX_IS_MULTI

#define HEAP_XMAX_COMMITTED

#define HEAP_XMIN_INVALID

#define HEAP_XMAX_EXCL_LOCK

#define HEAP_XMAX_INVALID

#define HEAP_XMAX_KEYSHR_LOCK

void pfree(void *pointer)

void * palloc0(Size size)

static uint64 pg_popcount(const char *buf, int bytes)

References a, Assert(), construct_array_builtin(), construct_empty_array(), CStringGetTextDatum, elog, ereport, errcode(), errmsg(), ERROR, get_call_result_type(), HEAP_COMBOCID, heap_form_tuple(), HEAP_HASEXTERNAL, HEAP_HASNULL, HEAP_HASOID_OLD, HEAP_HASVARWIDTH, HEAP_HOT_UPDATED, HEAP_KEYS_UPDATED, HEAP_MOVED, HEAP_MOVED_IN, HEAP_MOVED_OFF, HEAP_ONLY_TUPLE, HEAP_TUPLE_INFOMASK_COLS, HEAP_UPDATED, HEAP_XMAX_COMMITTED, HEAP_XMAX_EXCL_LOCK, HEAP_XMAX_INVALID, HEAP_XMAX_IS_MULTI, HEAP_XMAX_KEYSHR_LOCK, HEAP_XMAX_LOCK_ONLY, HEAP_XMAX_SHR_LOCK, HEAP_XMIN_COMMITTED, HEAP_XMIN_FROZEN, HEAP_XMIN_INVALID, HeapTupleGetDatum(), MemSet, palloc0(), pfree(), PG_GETARG_INT16, pg_popcount(), PG_RETURN_DATUM, PointerGetDatum(), superuser(), TYPEFUNC_COMPOSITE, and values.

HeapTupleHeaderGetOidOld()

PG_FUNCTION_INFO_V1() [1/3]

PG_FUNCTION_INFO_V1() [2/3]

PG_FUNCTION_INFO_V1() [3/3]

text_to_bits()

static bits8 * text_to_bits ( char * str, int len ) static

tuple_data_split()

Definition at line 436 of file heapfuncs.c.

437{

438 Oid relid;

442 char *t_bits_str;

443 bool do_detoast = false;

444 bits8 *t_bits = NULL;

446

453

456

459 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

460 errmsg("must be superuser to use raw page functions")));

461

462 if (!raw_data)

464

465

466

467

468

470 {

471 size_t bits_str_len;

472 size_t bits_len;

473

475 if (!t_bits_str)

478 errmsg("t_bits string must not be NULL")));

479

480 bits_str_len = strlen(t_bits_str);

481 if (bits_len != bits_str_len)

484 errmsg("unexpected length of t_bits string: %zu, expected %zu",

485 bits_str_len, bits_len)));

486

487

488 t_bits = text_to_bits(t_bits_str, bits_str_len);

489 }

490 else

491 {

492 if (t_bits_str)

495 errmsg("t_bits string is expected to be NULL, but instead it is %zu bytes long",

496 strlen(t_bits_str))));

497 }

498

499

502 t_infomask, t_infomask2, t_bits,

503 do_detoast);

504

505 if (t_bits)

507

509}

#define PG_GETARG_TEXT_PP(n)

#define PG_GETARG_BOOL(n)

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)

static bits8 * text_to_bits(char *str, int len)

char * text_to_cstring(const text *t)

References BITMAPLEN(), BITS_PER_BYTE, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, HEAP_HASNULL, HEAP_NATTS_MASK, pfree(), PG_ARGISNULL, PG_GETARG_BOOL, PG_GETARG_BYTEA_P, PG_GETARG_INT16, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_NARGS, PG_RETURN_DATUM, PG_RETURN_NULL, superuser(), text_to_bits(), text_to_cstring(), tuple_data_split_internal(), VARHDRSZ, and VARSIZE.

tuple_data_split_internal()

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 ) static

Definition at line 313 of file heapfuncs.c.

317{

319 int nattrs;

320 int i;

321 int off = 0;

324

325

328

330 nattrs = tupdesc->natts;

331

332

333

334

335 if (rel->rd_rel->relkind != RELKIND_SEQUENCE &&

336 rel->rd_rel->relam != HEAP_TABLE_AM_OID)

338 errmsg("only heap AM is supported")));

339

343 errmsg("number of attributes in tuple header is greater than number of attributes in tuple descriptor")));

344

345 for (i = 0; i < nattrs; i++)

346 {

348 bool is_null;

349 bytea *attr_data = NULL;

350

352

353

354

355

356

357

358

360 is_null = true;

361 else

363

364 if (!is_null)

365 {

367

368 if (attr->attlen == -1)

369 {

371 tupdata + off);

372

373

374

375

376

377

383 errmsg("first byte of varlena attribute is incorrect for attribute %d", i)));

384

386 }

387 else

388 {

391 }

392

393 if (tupdata_len < off + len)

396 errmsg("unexpected end of tuple data")));

397

398 if (attr->attlen == -1 && do_detoast)

400 else

401 {

404 memcpy(VARDATA(attr_data), tupdata + off, len);

405 }

406

408 tupdata + off);

409 }

410

413 if (attr_data)

414 pfree(attr_data);

415 }

416

417 if (tupdata_len != off)

420 errmsg("end of tuple reached without looking at all its data")));

421

423

425}

ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)

ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)

Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)

struct varlena * pg_detoast_datum_copy(struct varlena *datum)

MemoryContext CurrentMemoryContext

#define RelationGetDescr(relation)

void relation_close(Relation relation, LOCKMODE lockmode)

Relation relation_open(Oid relationId, LOCKMODE lockmode)

static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)

#define att_nominal_alignby(cur_offset, attalignby)

static bool att_isnull(int ATT, const bits8 *BITS)

#define att_addlength_pointer(cur_offset, attlen, attptr)

#define att_pointer_alignby(cur_offset, attalignby, attlen, attptr)

#define VARATT_IS_EXTERNAL_ONDISK(PTR)

#define VARATT_IS_EXTERNAL_INDIRECT(PTR)

#define VARATT_IS_EXTERNAL(PTR)

References AccessShareLock, accumArrayResult(), att_addlength_pointer, att_isnull(), att_nominal_alignby, att_pointer_alignby, CompactAttribute::attalignby, CompactAttribute::attlen, CurrentMemoryContext, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, HEAP_HASNULL, HEAP_NATTS_MASK, i, initArrayResult(), len, makeArrayResult(), TupleDescData::natts, palloc(), pfree(), pg_detoast_datum_copy(), PointerGetDatum(), RelationData::rd_rel, relation_close(), relation_open(), RelationGetDescr, SET_VARSIZE, TupleDescCompactAttr(), VARATT_IS_EXTERNAL, VARATT_IS_EXTERNAL_INDIRECT, VARATT_IS_EXTERNAL_ONDISK, VARDATA, VARHDRSZ, and VARSIZE_ANY.

Referenced by tuple_data_split().