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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

27

30#include "catalog/pg_am_d.h"

39

40

41

42

43

44

45static inline Oid

47{

49 return *((Oid *) ((char *) (tup) + (tup)->t_hoff - sizeof(Oid)));

50 else

52}

53

54

55

56

57

58

59

60

61static char *

63{

64 int i;

65 char *str;

66

68

69 for (i = 0; i < len; i++)

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

71

72 str[i] = '\0';

73

74 return str;

75}

76

77

78

79

80

81

82

83

86{

88 int off = 0;

89 char byte = 0;

90

92

93 while (off < len)

94 {

95 if (off % 8 == 0)

96 byte = 0;

97

98 if ((str[off] == '0') || (str[off] == '1'))

99 byte = byte | ((str[off] - '0') << off % 8);

100 else

103 errmsg("invalid character \"%.*s\" in t_bits string",

105

106 if (off % 8 == 7)

107 bits[off / 8] = byte;

108

109 off++;

110 }

111

112 return bits;

113}

114

115

116

117

118

119

121

123{

128

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}

303

304

305

306

307

308

309

310

311

316 bool do_detoast)

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}

426

427

428

429

430

431

432

434

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}

510

511

512

513

514

515

516

518

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}

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

ArrayType * construct_empty_array(Oid elmtype)

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

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

Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)

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)

#define MemSet(start, val, len)

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

struct varlena * pg_detoast_datum_copy(struct varlena *datum)

#define PG_GETARG_TEXT_PP(n)

#define PG_GETARG_BOOL(n)

#define PG_RETURN_DATUM(x)

#define PG_GETARG_BYTEA_P(n)

#define PG_GETARG_INT16(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)

Assert(PointerIsAligned(start, uint64))

#define HEAP_TUPLE_INFOMASK_COLS

PG_FUNCTION_INFO_V1(heap_page_items)

Datum heap_page_items(PG_FUNCTION_ARGS)

struct heap_page_items_state heap_page_items_state

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)

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

Datum heap_tuple_infomask_flags(PG_FUNCTION_ARGS)

static Oid HeapTupleHeaderGetOidOld(const HeapTupleHeaderData *tup)

Datum tuple_data_split(PG_FUNCTION_ARGS)

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

HeapTupleHeaderData * HeapTupleHeader

#define HEAP_XMAX_SHR_LOCK

#define HEAP_XMIN_COMMITTED

#define HeapTupleHeaderGetNatts(tup)

#define SizeofHeapTupleHeader

#define HEAP_KEYS_UPDATED

static int BITMAPLEN(int NATTS)

#define HEAP_XMAX_LOCK_ONLY

static CommandId HeapTupleHeaderGetRawCommandId(const HeapTupleHeaderData *tup)

static TransactionId HeapTupleHeaderGetRawXmax(const HeapTupleHeaderData *tup)

#define HEAP_XMAX_IS_MULTI

#define HEAP_XMAX_COMMITTED

#define HEAP_XMIN_INVALID

#define HEAP_XMAX_EXCL_LOCK

#define HEAP_XMAX_INVALID

static TransactionId HeapTupleHeaderGetRawXmin(const HeapTupleHeaderData *tup)

#define HEAP_XMAX_KEYSHR_LOCK

#define ItemIdGetLength(itemId)

#define ItemIdGetOffset(itemId)

#define ItemIdGetFlags(itemId)

#define ItemIdHasStorage(itemId)

int pg_mblen(const char *mbstr)

void pfree(void *pointer)

void * palloc0(Size size)

MemoryContext CurrentMemoryContext

#define FirstOffsetNumber

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

#define ERRCODE_DATA_CORRUPTED

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

static Datum PointerGetDatum(const void *X)

static Datum UInt16GetDatum(uint16 X)

static Datum UInt8GetDatum(uint8 X)

static Datum UInt32GetDatum(uint32 X)

#define RelationGetDescr(relation)

void relation_close(Relation relation, LOCKMODE lockmode)

Relation relation_open(Oid relationId, LOCKMODE lockmode)

MemoryContext multi_call_memory_ctx

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 SET_VARSIZE(PTR, len)

#define VARATT_IS_EXTERNAL(PTR)

char * text_to_cstring(const text *t)