PostgreSQL Source Code: src/include/access/gist_private.h File Reference (original) (raw)

Go to the source code of this file.

Data Structures
struct GISTNodeBufferPage
struct GISTSTATE
struct GISTSearchHeapItem
struct GISTSearchItem
struct GISTScanOpaqueData
struct gistxlogPage
struct SplitPageLayout
struct GISTInsertStack
struct GistSplitVector
struct GISTInsertState
struct GISTNodeBuffer
struct GISTBuildBuffers
struct GiSTOptions
struct GISTPageSplitInfo
Macros
#define GIST_MAX_SPLIT_PAGES 75
#define GIST_SHARE BUFFER_LOCK_SHARE
#define GIST_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE
#define GIST_UNLOCK BUFFER_LOCK_UNLOCK
#define BUFFER_PAGE_DATA_OFFSET MAXALIGN(offsetof(GISTNodeBufferPage, tupledata))
#define PAGE_FREE_SPACE(nbp) (nbp->freespace)
#define PAGE_IS_EMPTY(nbp) (nbp->freespace == BLCKSZ - BUFFER_PAGE_DATA_OFFSET)
#define PAGE_NO_SPACE(nbp, itup)
#define GISTSearchItemIsHeap(item) ((item).blkno == InvalidBlockNumber)
#define SizeOfGISTSearchItem(n_distances)
#define GIST_ROOT_BLKNO 0
#define TUPLE_IS_VALID 0xffff
#define TUPLE_IS_INVALID 0xfffe
#define GistTupleIsInvalid(itup) ( ItemPointerGetOffsetNumber( &((itup)->t_tid) ) == TUPLE_IS_INVALID )
#define GistTupleSetValid(itup) ItemPointerSetOffsetNumber( &((itup)->t_tid), TUPLE_IS_VALID )
#define LEVEL_HAS_BUFFERS(nlevel, gfbb)
#define BUFFER_HALF_FILLED(nodeBuffer, gfbb) ((nodeBuffer)->blocksCount > (gfbb)->pagesPerBuffer / 2)
#define BUFFER_OVERFLOWED(nodeBuffer, gfbb) ((nodeBuffer)->blocksCount > (gfbb)->pagesPerBuffer)
#define GiSTPageSize ( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GISTPageOpaqueData)) )
#define GIST_MIN_FILLFACTOR 10
#define GIST_DEFAULT_FILLFACTOR 90
Typedefs
typedef struct GISTSTATE GISTSTATE
typedef struct GISTSearchHeapItem GISTSearchHeapItem
typedef struct GISTSearchItem GISTSearchItem
typedef struct GISTScanOpaqueData GISTScanOpaqueData
typedef GISTScanOpaqueData * GISTScanOpaque
typedef struct gistxlogPage gistxlogPage
typedef struct SplitPageLayout SplitPageLayout
typedef struct GISTInsertStack GISTInsertStack
typedef struct GistSplitVector GistSplitVector
typedef struct GISTBuildBuffers GISTBuildBuffers
typedef enum GistOptBufferingMode GistOptBufferingMode
typedef struct GiSTOptions GiSTOptions
Functions
void gistbuildempty (Relation index)
bool gistinsert (Relation r, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, struct IndexInfo *indexInfo)
MemoryContext createTempGistContext (void)
GISTSTATE * initGISTstate (Relation index)
void freeGISTstate (GISTSTATE *giststate)
void gistdoinsert (Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate, Relation heapRel, bool is_build)
bool gistplacetopage (Relation rel, Size freespace, GISTSTATE *giststate, Buffer buffer, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber *newblkno, Buffer leftchildbuf, List **splitinfo, bool markfollowright, Relation heapRel, bool is_build)
SplitPageLayout * gistSplit (Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate)
XLogRecPtr gistXLogPageDelete (Buffer buffer, FullTransactionId xid, Buffer parentBuffer, OffsetNumber downlinkOffset)
void gistXLogPageReuse (Relation rel, Relation heaprel, BlockNumber blkno, FullTransactionId deleteXid)
XLogRecPtr gistXLogUpdate (Buffer buffer, OffsetNumber *todelete, int ntodelete, IndexTuple *itup, int ituplen, Buffer leftchildbuf)
XLogRecPtr gistXLogDelete (Buffer buffer, OffsetNumber *todelete, int ntodelete, TransactionId snapshotConflictHorizon, Relation heaprel)
XLogRecPtr gistXLogSplit (bool page_is_leaf, SplitPageLayout *dist, BlockNumber origrlink, GistNSN orignsn, Buffer leftchildbuf, bool markfollowright)
XLogRecPtr gistXLogAssignLSN (void)
bool gistgettuple (IndexScanDesc scan, ScanDirection dir)
int64 gistgetbitmap (IndexScanDesc scan, TIDBitmap *tbm)
bool gistcanreturn (Relation index, int attno)
bool gistvalidate (Oid opclassoid)
void gistadjustmembers (Oid opfamilyoid, Oid opclassoid, List *operators, List *functions)
bytea * gistoptions (Datum reloptions, bool validate)
bool gistproperty (Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
bool gistfitpage (IndexTuple *itvec, int len)
bool gistnospace (Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace)
void gistcheckpage (Relation rel, Buffer buf)
Buffer gistNewBuffer (Relation r, Relation heaprel)
bool gistPageRecyclable (Page page)
void gistfillbuffer (Page page, IndexTuple *itup, int len, OffsetNumber off)
IndexTuple * gistextractpage (Page page, int *len)
IndexTuple * gistjoinvector (IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
IndexTupleData * gistfillitupvec (IndexTuple *vec, int veclen, int *memlen)
IndexTuple gistunion (Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
IndexTuple gistgetadjusted (Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)
IndexTuple gistFormTuple (GISTSTATE *giststate, Relation r, const Datum *attdata, const bool *isnull, bool isleaf)
void gistCompressValues (GISTSTATE *giststate, Relation r, const Datum *attdata, const bool *isnull, bool isleaf, Datum *compatt)
OffsetNumber gistchoose (Relation r, Page p, IndexTuple it, GISTSTATE *giststate)
void GISTInitBuffer (Buffer b, uint32 f)
void gistinitpage (Page page, uint32 f)
void gistdentryinit (GISTSTATE *giststate, int nkey, GISTENTRY *e, Datum k, Relation r, Page pg, OffsetNumber o, bool l, bool isNull)
float gistpenalty (GISTSTATE *giststate, int attno, GISTENTRY *orig, bool isNullOrig, GISTENTRY *add, bool isNullAdd)
void gistMakeUnionItVec (GISTSTATE *giststate, IndexTuple *itvec, int len, Datum *attr, bool *isnull)
bool gistKeyIsEQ (GISTSTATE *giststate, int attno, Datum a, Datum b)
void gistDeCompressAtt (GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p, OffsetNumber o, GISTENTRY *attdata, bool *isnull)
HeapTuple gistFetchTuple (GISTSTATE *giststate, Relation r, IndexTuple tuple)
void gistMakeUnionKey (GISTSTATE *giststate, int attno, GISTENTRY *entry1, bool isnull1, GISTENTRY *entry2, bool isnull2, Datum *dst, bool *dstisnull)
XLogRecPtr gistGetFakeLSN (Relation rel)
IndexBulkDeleteResult * gistbulkdelete (IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
IndexBulkDeleteResult * gistvacuumcleanup (IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
void gistSplitByKey (Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate, GistSplitVector *v, int attno)
IndexBuildResult * gistbuild (Relation heap, Relation index, struct IndexInfo *indexInfo)
GISTBuildBuffers * gistInitBuildBuffers (int pagesPerBuffer, int levelStep, int maxLevel)
GISTNodeBuffer * gistGetNodeBuffer (GISTBuildBuffers *gfbb, GISTSTATE *giststate, BlockNumber nodeBlocknum, int level)
void gistPushItupToNodeBuffer (GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple itup)
bool gistPopItupFromNodeBuffer (GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple *itup)
void gistFreeBuildBuffers (GISTBuildBuffers *gfbb)
void gistRelocateBuildBuffersOnSplit (GISTBuildBuffers *gfbb, GISTSTATE *giststate, Relation r, int level, Buffer buffer, List *splitinfo)
void gistUnloadNodeBuffers (GISTBuildBuffers *gfbb)

BUFFER_HALF_FILLED

| #define BUFFER_HALF_FILLED | ( | | nodeBuffer, | | ---------------------------- | -------------------------------------------------------- | | ----------- | | | gfbb | | | | | ) | ((nodeBuffer)->blocksCount > (gfbb)->pagesPerBuffer / 2) | | |

BUFFER_OVERFLOWED

| #define BUFFER_OVERFLOWED | ( | | nodeBuffer, | | -------------------------- | ---------------------------------------------------- | | ----------- | | | gfbb | | | | | ) | ((nodeBuffer)->blocksCount > (gfbb)->pagesPerBuffer) | | |

BUFFER_PAGE_DATA_OFFSET

GIST_DEFAULT_FILLFACTOR

#define GIST_DEFAULT_FILLFACTOR 90

GIST_EXCLUSIVE

GIST_MAX_SPLIT_PAGES

#define GIST_MAX_SPLIT_PAGES 75

GIST_MIN_FILLFACTOR

#define GIST_MIN_FILLFACTOR 10

GIST_ROOT_BLKNO

#define GIST_ROOT_BLKNO 0

GIST_SHARE

GIST_UNLOCK

GiSTPageSize

GISTSearchItemIsHeap

GistTupleIsInvalid

GistTupleSetValid

LEVEL_HAS_BUFFERS

| #define LEVEL_HAS_BUFFERS | ( | | nlevel, | | --------------------------- | - | | -------------------------------------------------------------------- | | | gfbb | | | | | ) | | | |

PAGE_FREE_SPACE

| #define PAGE_FREE_SPACE | ( | | nbp | ) | (nbp->freespace) | | ------------------------- | - | | --- | - | ---------------- |

PAGE_IS_EMPTY

PAGE_NO_SPACE

| #define PAGE_NO_SPACE | ( | | nbp, | | ----------------------- | - | | ---- | | | itup | | | | | ) | | | |

Value:

#define PAGE_FREE_SPACE(nbp)

static Size IndexTupleSize(const IndexTupleData *itup)

Definition at line 59 of file gist_private.h.

SizeOfGISTSearchItem

| #define SizeOfGISTSearchItem | ( | | n_distances | ) | | ---------------------------- | - | | ------------ | - |

TUPLE_IS_INVALID

#define TUPLE_IS_INVALID 0xfffe

TUPLE_IS_VALID

#define TUPLE_IS_VALID 0xffff

GISTBuildBuffers

GISTInsertStack

GistOptBufferingMode

GiSTOptions

GISTScanOpaque

GISTScanOpaqueData

GISTSearchHeapItem

GISTSearchItem

GistSplitVector

GISTSTATE

gistxlogPage

SplitPageLayout

GistOptBufferingMode

Enumerator
GIST_OPTION_BUFFERING_AUTO
GIST_OPTION_BUFFERING_ON
GIST_OPTION_BUFFERING_OFF

Definition at line 384 of file gist_private.h.

385{

@ GIST_OPTION_BUFFERING_OFF

@ GIST_OPTION_BUFFERING_AUTO

@ GIST_OPTION_BUFFERING_ON

createTempGistContext()

freeGISTstate()

gistadjustmembers()

void gistadjustmembers ( Oid opfamilyoid,
Oid opclassoid,
List * operators,
List * functions
)

Definition at line 288 of file gistvalidate.c.

292{

294

295

296

297

298

299

300

301

302

303 foreach(lc, operators)

304 {

306

310 }

311

312

313

314

315

316

317

318

320 {

322

324 {

330

332 break;

340

344 break;

345 default:

347 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

348 errmsg("support function number %d is invalid for access method %s",

349 op->number, "gist")));

350 break;

351 }

352 }

353}

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

#define GIST_STRATNUM_PROC

#define GIST_DECOMPRESS_PROC

#define GIST_PICKSPLIT_PROC

#define GIST_CONSISTENT_PROC

#define GIST_SORTSUPPORT_PROC

#define GIST_COMPRESS_PROC

#define GIST_PENALTY_PROC

#define GIST_OPTIONS_PROC

#define GIST_DISTANCE_PROC

static const struct fns functions

References ereport, errcode(), errmsg(), ERROR, functions, GIST_COMPRESS_PROC, GIST_CONSISTENT_PROC, GIST_DECOMPRESS_PROC, GIST_DISTANCE_PROC, GIST_EQUAL_PROC, GIST_FETCH_PROC, GIST_OPTIONS_PROC, GIST_PENALTY_PROC, GIST_PICKSPLIT_PROC, GIST_SORTSUPPORT_PROC, GIST_STRATNUM_PROC, GIST_UNION_PROC, lfirst, OpFamilyMember::number, OpFamilyMember::ref_is_family, OpFamilyMember::ref_is_hard, and OpFamilyMember::refobjid.

Referenced by gisthandler().

gistbuild()

Definition at line 179 of file gistbuild.c.

180{

182 double reltuples;

188

189

190

191

192

194 elog(ERROR, "index \"%s\" already contains data",

196

198 buildstate.heaprel = heap;

201

202

203

204

205

206

208

209

210

211

212

213

215 {

220 else

222 }

223 else

224 {

226 }

227

228

229

230

232 {

233 bool hasallsortsupports = true;

235

236 for (int i = 0; i < keyscount; i++)

237 {

241 {

242 hasallsortsupports = false;

243 break;

244 }

245 }

246 if (hasallsortsupports)

248 }

249

250

251

252

255

256

257

258

261

263 {

264

265

266

270 NULL,

272

273

276 &buildstate, NULL);

277

278

279

280

282

284

286 }

287 else

288 {

289

290

291

292

295

296

300

302

304

307

309

311

312

315 &buildstate, NULL);

316

317

318

319

320

322 {

323 elog(DEBUG1, "all tuples processed, emptying buffers");

326 }

327

328

329

330

331

333 {

336 true);

337 }

338 }

339

340

343

345

346

347

348

350

353

354 return result;

355}

BlockNumber BufferGetBlockNumber(Buffer buffer)

void UnlockReleaseBuffer(Buffer buffer)

void MarkBufferDirty(Buffer buffer)

#define RelationGetNumberOfBlocks(reln)

static Page BufferGetPage(Buffer buffer)

static void PageSetLSN(Page page, XLogRecPtr lsn)

#define OidIsValid(objectId)

GISTSTATE * initGISTstate(Relation index)

MemoryContext createTempGistContext(void)

void freeGISTstate(GISTSTATE *giststate)

#define GIST_DEFAULT_FILLFACTOR

@ GIST_BUFFERING_DISABLED

static void gist_indexsortbuild(GISTBuildState *state)

static void gistBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)

static void gistSortedBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)

static void gistEmptyAllBuffers(GISTBuildState *buildstate)

void gistFreeBuildBuffers(GISTBuildBuffers *gfbb)

Buffer gistNewBuffer(Relation r, Relation heaprel)

void GISTInitBuffer(Buffer b, uint32 f)

Assert(PointerIsAligned(start, uint64))

RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)

if(TABLE==NULL||TABLE_index==NULL)

#define START_CRIT_SECTION()

#define END_CRIT_SECTION()

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

#define RelationGetRelationName(relation)

#define RelationNeedsWAL(relation)

#define IndexRelationGetNumberOfKeyAttributes(relation)

Tuplesortstate * sortstate

static double table_index_build_scan(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)

void tuplesort_performsort(Tuplesortstate *state)

void tuplesort_end(Tuplesortstate *state)

Tuplesortstate * tuplesort_begin_index_gist(Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)

void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)

References Assert(), BufferGetBlockNumber(), BufferGetPage(), GISTBuildState::buildMode, createTempGistContext(), CurrentMemoryContext, DEBUG1, elog, END_CRIT_SECTION, ERROR, F_LEAF, fillfactor, freeGISTstate(), GISTBuildState::freespace, GISTBuildState::gfbb, GIST_BUFFERING_ACTIVE, GIST_BUFFERING_AUTO, GIST_BUFFERING_DISABLED, GIST_BUFFERING_STATS, GIST_DEFAULT_FILLFACTOR, gist_indexsortbuild(), GIST_OPTION_BUFFERING_OFF, GIST_OPTION_BUFFERING_ON, GIST_ROOT_BLKNO, GIST_SORTED_BUILD, GIST_SORTSUPPORT_PROC, gistBuildCallback(), GistBuildLSN, gistEmptyAllBuffers(), gistFreeBuildBuffers(), GISTInitBuffer(), gistNewBuffer(), gistSortedBuildCallback(), GISTBuildState::giststate, IndexBuildResult::heap_tuples, GISTBuildState::heaprel, i, if(), index_getprocid(), INDEX_MAX_KEYS, IndexBuildResult::index_tuples, GISTBuildState::indexrel, IndexRelationGetNumberOfKeyAttributes, GISTBuildState::indtuples, GISTBuildState::indtuplesSize, initGISTstate(), log_newpage_range(), MAIN_FORKNUM, maintenance_work_mem, MarkBufferDirty(), MemoryContextDelete(), MemoryContextSwitchTo(), OidIsValid, PageSetLSN(), palloc(), RelationGetNumberOfBlocks, RelationGetRelationName, RelationNeedsWAL, GISTBuildState::sortstate, START_CRIT_SECTION, table_index_build_scan(), GISTSTATE::tempCxt, tuplesort_begin_index_gist(), tuplesort_end(), TUPLESORT_NONE, tuplesort_performsort(), and UnlockReleaseBuffer().

Referenced by gisthandler().

gistbuildempty()

Definition at line 139 of file gist.c.

140{

142

143

146

147

153

154

156}

Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)

XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)

References BMR_REL, EB_LOCK_FIRST, EB_SKIP_EXTENSION_LOCK, END_CRIT_SECTION, ExtendBufferedRel(), F_LEAF, GISTInitBuffer(), INIT_FORKNUM, log_newpage_buffer(), MarkBufferDirty(), START_CRIT_SECTION, and UnlockReleaseBuffer().

Referenced by gisthandler().

gistbulkdelete()

Definition at line 59 of file gistvacuum.c.

61{

62

63 if (stats == NULL)

65

67

68 return stats;

69}

static void gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)

void * palloc0(Size size)

static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)

References callback(), gistvacuumscan(), and palloc0().

Referenced by gisthandler().

gistcanreturn()

bool gistcanreturn ( Relation index,
int attno
)

gistcheckpage()

Definition at line 785 of file gistutil.c.

786{

788

789

790

791

792

793

794

797 (errcode(ERRCODE_INDEX_CORRUPTED),

798 errmsg("index \"%s\" contains unexpected zero page at block %u",

801 errhint("Please REINDEX it.")));

802

803

804

805

808 (errcode(ERRCODE_INDEX_CORRUPTED),

809 errmsg("index \"%s\" contains corrupted page at block %u",

812 errhint("Please REINDEX it.")));

813}

static uint16 PageGetSpecialSize(const PageData *page)

static bool PageIsNew(const PageData *page)

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

References buf, BufferGetBlockNumber(), BufferGetPage(), ereport, errcode(), errhint(), errmsg(), ERROR, MAXALIGN, PageGetSpecialSize(), PageIsNew(), and RelationGetRelationName.

Referenced by gistBufferingFindCorrectParent(), gistdoinsert(), gistFindCorrectParent(), gistFindPath(), gistkillitems(), gistNewBuffer(), gistScanPage(), gistvacuum_delete_empty_pages(), and pgstat_gist_page().

gistchoose()

Definition at line 374 of file gistutil.c.

376{

384 int keep_current_best;

385

387

390 identry, isnull);

391

392

394

395

396

397

398

399

400

401

402

403

404

405 best_penalty[0] = -1;

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430 keep_current_best = -1;

431

432

433

434

437

439 {

441 bool zero_penalty;

442 int j;

443

444 zero_penalty = true;

445

446

448 {

450 float usize;

451 bool IsNull;

452

453

455 &IsNull);

457 false, IsNull);

458 usize = gistpenalty(giststate, j, &entry, IsNull,

459 &identry[j], isnull[j]);

460 if (usize > 0)

461 zero_penalty = false;

462

463 if (best_penalty[j] < 0 || usize < best_penalty[j])

464 {

465

466

467

468

469

470

471

472

473 result = i;

474 best_penalty[j] = usize;

475

477 best_penalty[j + 1] = -1;

478

479

480 keep_current_best = -1;

481 }

482 else if (best_penalty[j] == usize)

483 {

484

485

486

487

488

489 }

490 else

491 {

492

493

494

495

496

497 zero_penalty = false;

498 break;

499 }

500 }

501

502

503

504

505

507 {

508 if (keep_current_best == -1)

509 {

510

512 }

513 if (keep_current_best == 0)

514 {

515

516 result = i;

517

518 keep_current_best = -1;

519 }

520 }

521

522

523

524

525

526

527

528 if (zero_penalty)

529 {

530 if (keep_current_best == -1)

531 {

532

534 }

535 if (keep_current_best == 1)

536 break;

537 }

538 }

539

540 return result;

541}

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

static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)

static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)

#define GistPageIsLeaf(page)

void gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p, OffsetNumber o, GISTENTRY *attdata, bool *isnull)

void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, Datum k, Relation r, Page pg, OffsetNumber o, bool l, bool isNull)

float gistpenalty(GISTSTATE *giststate, int attno, GISTENTRY *orig, bool isNullOrig, GISTENTRY *add, bool isNullAdd)

IndexTupleData * IndexTuple

static Datum index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)

#define OffsetNumberNext(offsetNumber)

#define FirstOffsetNumber

pg_prng_state pg_global_prng_state

bool pg_prng_bool(pg_prng_state *state)

References Assert(), FirstOffsetNumber, gistDeCompressAtt(), gistdentryinit(), GistPageIsLeaf, gistpenalty(), i, index_getattr(), INDEX_MAX_KEYS, IndexRelationGetNumberOfKeyAttributes, j, GISTSTATE::leafTupdesc, OffsetNumberNext, PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), pg_global_prng_state, and pg_prng_bool().

Referenced by gistdoinsert(), and gistProcessItup().

gistCompressValues()

void gistCompressValues ( GISTSTATE * giststate,
Relation r,
const Datum * attdata,
const bool * isnull,
bool isleaf,
Datum * compatt
)

Definition at line 596 of file gistutil.c.

598{

599 int i;

600

601

602

603

605 {

606 if (isnull[i])

607 compatt[i] = (Datum) 0;

608 else

609 {

612

614 isleaf);

615

621 else

622 cep = ¢ry;

623 compatt[i] = cep->key;

624 }

625 }

626

627 if (isleaf)

628 {

629

630

631

633 {

634 if (isnull[i])

635 compatt[i] = (Datum) 0;

636 else

637 compatt[i] = attdata[i];

638 }

639 }

640}

Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)

#define gistentryinit(e, k, r, pg, o, l)

static Datum PointerGetDatum(const void *X)

static Pointer DatumGetPointer(Datum X)

Oid supportCollation[INDEX_MAX_KEYS]

FmgrInfo compressFn[INDEX_MAX_KEYS]

References GISTSTATE::compressFn, DatumGetPointer(), FmgrInfo::fn_oid, FunctionCall1Coll(), gistentryinit, i, IndexRelationGetNumberOfKeyAttributes, GISTENTRY::key, TupleDescData::natts, OidIsValid, PointerGetDatum(), RelationData::rd_att, and GISTSTATE::supportCollation.

Referenced by gistFormTuple(), and gistSortedBuildCallback().

gistDeCompressAtt()

Definition at line 296 of file gistutil.c.

298{

299 int i;

300

302 {

304

307 datum, r, p, o,

308 false, isnull[i]);

309 }

310}

References gistdentryinit(), i, index_getattr(), IndexRelationGetNumberOfKeyAttributes, and GISTSTATE::leafTupdesc.

Referenced by gistchoose(), gistgetadjusted(), gistRelocateBuildBuffersOnSplit(), and placeOne().

gistdentryinit()

Definition at line 547 of file gistutil.c.

550{

551 if (!isNull)

552 {

554

556

557

559 return;

560

565

566 if (dep != e)

569 }

570 else

572}

FmgrInfo decompressFn[INDEX_MAX_KEYS]

References DatumGetPointer(), GISTSTATE::decompressFn, FmgrInfo::fn_oid, FunctionCall1Coll(), gistentryinit, GISTENTRY::key, GISTENTRY::leafkey, GISTENTRY::offset, OidIsValid, GISTENTRY::page, PointerGetDatum(), GISTENTRY::rel, and GISTSTATE::supportCollation.

Referenced by gistchoose(), gistDeCompressAtt(), gistindex_keytest(), gistMakeUnionItVec(), and gistSplitByKey().

gistdoinsert()

Definition at line 639 of file gist.c.

641{

647 bool xlocked = false;

648

650 state.freespace = freespace;

652 state.heapRel = heapRel;

653 state.is_build = is_build;

654

655

657 firststack.lsn = 0;

659 firststack.parent = NULL;

661 state.stack = stack = &firststack;

662

663

664

665

666

667

668

669 for (;;)

670 {

671

672

673

674

675

676

678 {

679 if (xlocked)

681 xlocked = false;

684 }

685

688

689

690

691

692

693 if (!xlocked)

694 {

697 }

698

700 stack->lsn = xlocked ?

703

704

705

706

707

708

710 {

711 if (!xlocked)

712 {

715 xlocked = true;

716

718 continue;

719 }

721

723 xlocked = false;

725 continue;

726 }

727

731 {

732

733

734

735

736

737

739 xlocked = false;

741 continue;

742 }

743

745 {

746

747

748

749

754

759

760

761

762

765 (errmsg("index \"%s\" contains an inner tuple marked as invalid",

767 errdetail("This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1."),

768 errhint("Please REINDEX it.")));

769

770

771

772

773

775 if (newtup)

776 {

777

778

779

780

781 if (!xlocked)

782 {

785 xlocked = true;

787

789 {

790

791 continue;

792 }

793 }

794

795

796

797

798

799

800

801

802

803

804

806 downlinkoffnum))

807 {

808

809

810

811

812

813

815 {

817 xlocked = false;

819 }

820 continue;

821 }

822 }

824 xlocked = false;

825

826

828 item->blkno = childblkno;

829 item->parent = stack;

831 state.stack = stack = item;

832 }

833 else

834 {

835

836

837

838

839

840

841

842

843

844

845 if (!xlocked)

846 {

849 xlocked = true;

852

854 {

855

856

857

858

860 {

861

862

863

864

866 xlocked = false;

867 continue;

868 }

869

870

871

872

873

874 }

878 {

879

880

881

882

884 xlocked = false;

886 continue;

887 }

888 }

889

890

891

895

896

897 for (; stack; stack = stack->parent)

899 break;

900 }

901 }

902}

void ReleaseBuffer(Buffer buffer)

XLogRecPtr BufferGetLSNAtomic(Buffer buffer)

void LockBuffer(Buffer buffer, int mode)

Buffer ReadBuffer(Relation reln, BlockNumber blockNum)

static XLogRecPtr PageGetLSN(const PageData *page)

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

static void gistfixsplit(GISTInsertState *state, GISTSTATE *giststate)

static bool gistinserttuple(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, IndexTuple tuple, OffsetNumber oldoffnum)

#define GistFollowRight(page)

#define GistPageIsDeleted(page)

#define GistPageGetNSN(page)

#define GistTupleIsInvalid(itup)

IndexTuple gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)

OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)

void gistcheckpage(Relation rel, Buffer buf)

static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)

#define InvalidOffsetNumber

OffsetNumber downlinkoffnum

struct GISTInsertStack * parent

#define XLogRecPtrIsInvalid(r)

References Assert(), GISTInsertStack::blkno, GISTInsertStack::buffer, BufferGetLSNAtomic(), BufferGetPage(), GISTInsertStack::downlinkoffnum, ereport, errdetail(), errhint(), errmsg(), ERROR, GIST_EXCLUSIVE, GIST_ROOT_BLKNO, GIST_SHARE, GIST_UNLOCK, gistcheckpage(), gistchoose(), gistfixsplit(), GistFollowRight, gistgetadjusted(), gistinserttuple(), GistPageGetNSN, GistPageIsDeleted, GistPageIsLeaf, GistTupleIsInvalid, InvalidOffsetNumber, ItemPointerGetBlockNumber(), LockBuffer(), GISTInsertStack::lsn, GISTInsertStack::page, PageGetItem(), PageGetItemId(), PageGetLSN(), palloc0(), GISTInsertStack::parent, ReadBuffer(), RelationGetRelationName, RelationNeedsWAL, ReleaseBuffer(), GISTInsertStack::retry_from_parent, IndexTupleData::t_tid, UnlockReleaseBuffer(), and XLogRecPtrIsInvalid.

Referenced by gistBuildCallback(), and gistinsert().

gistextractpage()

gistFetchTuple()

Definition at line 667 of file gistutil.c.

668{

672 int i;

673

675 {

677

679

681 {

682 if (!isnull[i])

684 else

686 }

688 {

689

690

691

692

693 if (!isnull[i])

695 else

697 }

698 else

699 {

700

701

702

703

704

705 isnull[i] = true;

707 }

708 }

709

710

711

712

714 {

716 &isnull[i]);

717 }

719

721}

static Datum gistFetchAtt(GISTSTATE *giststate, int nkey, Datum k, Relation r)

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

FmgrInfo fetchFn[INDEX_MAX_KEYS]

References GISTSTATE::compressFn, fetchatt, GISTSTATE::fetchFn, GISTSTATE::fetchTupdesc, FmgrInfo::fn_oid, gistFetchAtt(), heap_form_tuple(), i, index_getattr(), INDEX_MAX_KEYS, IndexRelationGetNumberOfKeyAttributes, InvalidOid, GISTSTATE::leafTupdesc, MemoryContextSwitchTo(), TupleDescData::natts, RelationData::rd_att, and GISTSTATE::tempCxt.

Referenced by gistScanPage().

gistfillbuffer()

Definition at line 34 of file gistutil.c.

35{

36 int i;

37

41

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

43 {

46

49 elog(ERROR, "failed to add item to GiST index page, item %d out of %d, size %d bytes",

50 i, len, (int) sz);

51 off++;

52 }

53}

static bool PageIsEmpty(const PageData *page)

#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)

References elog, ERROR, FirstOffsetNumber, i, IndexTupleSize(), InvalidOffsetNumber, len, OffsetNumberNext, PageAddItem, PageGetMaxOffsetNumber(), and PageIsEmpty().

Referenced by gist_indexsortbuild_levelstate_add(), gistplacetopage(), and gistRedoPageSplitRecord().

gistfillitupvec()

gistfitpage()

gistFormTuple()

Definition at line 575 of file gistutil.c.

577{

580

582

585 compatt, isnull);

586

587

588

589

590

592 return res;

593}

void gistCompressValues(GISTSTATE *giststate, Relation r, const Datum *attdata, const bool *isnull, bool isleaf, Datum *compatt)

IndexTuple index_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)

static void ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber)

References gistCompressValues(), index_form_tuple(), INDEX_MAX_KEYS, ItemPointerSetOffsetNumber(), GISTSTATE::leafTupdesc, GISTSTATE::nonLeafTupdesc, and IndexTupleData::t_tid.

Referenced by gistBuildCallback(), gistgetadjusted(), gistinsert(), gistSplit(), and gistunion().

gistFreeBuildBuffers()

gistgetadjusted()

Definition at line 316 of file gistutil.c.

317{

318 bool neednew = false;

326 int i;

327

330

333

335 {

337 oldentries + i, oldisnull[i],

338 addentries + i, addisnull[i],

339 attr + i, isnull + i);

340

341 if (neednew)

342

343 continue;

344

345 if (isnull[i])

346

347 continue;

348

349 if (!addisnull[i])

350 {

351 if (oldisnull[i] ||

353 neednew = true;

354 }

355 }

356

357 if (neednew)

358 {

359

360 newtup = gistFormTuple(giststate, r, attr, isnull, false);

362 }

363

364 return newtup;

365}

void gistMakeUnionKey(GISTSTATE *giststate, int attno, GISTENTRY *entry1, bool isnull1, GISTENTRY *entry2, bool isnull2, Datum *dst, bool *dstisnull)

bool gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b)

IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, const Datum *attdata, const bool *isnull, bool isleaf)

References gistDeCompressAtt(), gistFormTuple(), gistKeyIsEQ(), gistMakeUnionKey(), i, INDEX_MAX_KEYS, IndexRelationGetNumberOfKeyAttributes, sort-test::key, and IndexTupleData::t_tid.

Referenced by gistdoinsert(), gistformdownlink(), gistProcessItup(), and gistRelocateBuildBuffersOnSplit().

gistgetbitmap()

Definition at line 745 of file gistget.c.

746{

750

752 return 0;

753

757

758

763

765 memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));

766 gistScanPage(scan, &fakeItem, NULL, tbm, &ntids);

767

768

769

770

771

772 for (;;)

773 {

775

776 if (!item)

777 break;

778

780

782

784 }

785

786 return ntids;

787}

GISTScanOpaqueData * GISTScanOpaque

static GISTSearchItem * getNextGISTSearchItem(GISTScanOpaque so)

static void gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, IndexOrderByDistance *myDistances, TIDBitmap *tbm, int64 *ntids)

void MemoryContextReset(MemoryContext context)

void pfree(void *pointer)

#define CHECK_FOR_INTERRUPTS()

#define pgstat_count_index_scan(rel)

MemoryContext pageDataCxt

IndexOrderByDistance distances[FLEXIBLE_ARRAY_MEMBER]

struct IndexScanInstrumentation * instrument

References CHECK_FOR_INTERRUPTS, GISTScanOpaqueData::curPageData, GISTSearchItem::distances, getNextGISTSearchItem(), GIST_ROOT_BLKNO, gistScanPage(), if(), IndexScanDescData::indexRelation, IndexScanDescData::instrument, MemoryContextReset(), GISTScanOpaqueData::nPageData, IndexScanInstrumentation::nsearches, IndexScanDescData::opaque, GISTScanOpaqueData::pageDataCxt, pfree(), pgstat_count_index_scan, GISTScanOpaqueData::qual_ok, and IndexScanDescData::xs_hitup.

Referenced by gisthandler().

gistGetFakeLSN()

Definition at line 1016 of file gistutil.c.

1017{

1018 if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)

1019 {

1020

1021

1022

1023

1025

1026 return counter++;

1027 }

1029 {

1030

1031

1032

1033

1034

1035

1038

1039

1041

1042

1045

1046 lastlsn = currlsn;

1047 return currlsn;

1048 }

1049 else

1050 {

1051

1052

1053

1054

1055 Assert(rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED);

1057 }

1058}

XLogRecPtr gistXLogAssignLSN(void)

#define RelationIsPermanent(relation)

XLogRecPtr GetXLogInsertRecPtr(void)

XLogRecPtr GetFakeLSNForUnloggedRel(void)

#define FirstNormalUnloggedLSN

#define InvalidXLogRecPtr

References Assert(), FirstNormalUnloggedLSN, GetFakeLSNForUnloggedRel(), GetXLogInsertRecPtr(), gistXLogAssignLSN(), InvalidXLogRecPtr, RelationData::rd_rel, RelationIsPermanent, RelationNeedsWAL, and XLogRecPtrIsInvalid.

Referenced by gistdeletepage(), gistplacetopage(), gistprunepage(), gistvacuumpage(), and gistvacuumscan().

gistGetNodeBuffer()

Definition at line 113 of file gistbuildbuffers.c.

115{

117 bool found;

118

119

121 &nodeBlocknum,

123 &found);

124 if (!found)

125 {

126

127

128

130

131

136 nodeBuffer->isTemp = false;

137 nodeBuffer->level = level;

138

139

140

141

142

144 {

145 int i;

146

149 (level + 1) * sizeof(List *));

150

151

155 }

156

157

158

159

160

161

162

163

164

165

166

167

170

172 }

173

174 return nodeBuffer;

175}

#define InvalidBlockNumber

void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)

List * lcons(void *datum, List *list)

void * repalloc(void *pointer, Size size)

GISTNodeBufferPage * pageBuffer

References GISTNodeBuffer::blocksCount, GISTBuildBuffers::buffersOnLevels, GISTBuildBuffers::buffersOnLevelsLen, GISTBuildBuffers::context, HASH_ENTER, hash_search(), i, InvalidBlockNumber, GISTNodeBuffer::isTemp, lcons(), GISTNodeBuffer::level, MemoryContextSwitchTo(), NIL, GISTBuildBuffers::nodeBuffersTab, GISTNodeBuffer::pageBlocknum, GISTNodeBuffer::pageBuffer, GISTNodeBuffer::queuedForEmptying, and repalloc().

Referenced by gistProcessItup(), and gistRelocateBuildBuffersOnSplit().

gistgettuple()

Definition at line 612 of file gistget.c.

613{

615

617 elog(ERROR, "GiST only supports forward scan direction");

618

620 return false;

621

623 {

624

626

630

636

639 gistScanPage(scan, &fakeItem, NULL, NULL, NULL);

640 }

641

643 {

644

646 }

647 else

648 {

649

650 for (;;)

651 {

653 {

655 {

656

658 {

661

665

667 }

671 }

672

675

676

679

681

682 return true;

683 }

684

685

686

687

688

692 {

693

695 {

698

702

704 }

708 }

709

710 do

711 {

713

716

718

719 if (!item)

720 return false;

721

723

724

726

727

728

729

730

731

732

734

737 }

738 }

739}

static bool getNextNearest(IndexScanDesc scan)

static void gistkillitems(IndexScanDesc scan)

#define MaxIndexTuplesPerPage

OffsetNumber * killedItems

GISTSearchHeapItem pageData[BLCKSZ/sizeof(IndexTupleData)]

union GISTSearchItem::@45 data

ItemPointerData xs_heaptid

References GISTSearchItem::blkno, CHECK_FOR_INTERRUPTS, GISTScanOpaqueData::curBlkno, GISTScanOpaqueData::curPageData, GISTSearchItem::data, GISTSearchItem::distances, elog, ERROR, GISTScanOpaqueData::firstCall, ForwardScanDirection, getNextGISTSearchItem(), getNextNearest(), GIST_ROOT_BLKNO, gistkillitems(), gistScanPage(), GISTScanOpaqueData::giststate, GISTSearchHeapItem::heapPtr, if(), IndexScanDescData::indexRelation, IndexScanDescData::instrument, InvalidBlockNumber, IndexScanDescData::kill_prior_tuple, GISTScanOpaqueData::killedItems, MaxIndexTuplesPerPage, MemoryContextReset(), MemoryContextSwitchTo(), GISTScanOpaqueData::nPageData, IndexScanInstrumentation::nsearches, IndexScanDescData::numberOfOrderBys, GISTScanOpaqueData::numKilled, GISTSearchHeapItem::offnum, IndexScanDescData::opaque, GISTScanOpaqueData::pageData, GISTScanOpaqueData::pageDataCxt, palloc(), GISTSearchItem::parentlsn, pfree(), pgstat_count_index_scan, GISTScanOpaqueData::qual_ok, GISTSearchHeapItem::recheck, GISTSearchHeapItem::recontup, GISTSTATE::scanCxt, IndexScanDescData::xs_heaptid, IndexScanDescData::xs_hitup, IndexScanDescData::xs_recheck, and IndexScanDescData::xs_want_itup.

Referenced by gisthandler().

GISTInitBuffer()

gistInitBuildBuffers()

GISTBuildBuffers * gistInitBuildBuffers ( int pagesPerBuffer,
int levelStep,
int maxLevel
)

Definition at line 44 of file gistbuildbuffers.c.

45{

48

52

53

54

55

56

59

60

64

65

66

67

68

70

71

72

73

74

79 1024,

80 &hashCtl,

82

84

85

86

87

88

93

94

95

96

97

102

104

105 return gfbb;

106}

BufFile * BufFileCreateTemp(bool interXact)

HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)

GISTNodeBuffer ** loadedBuffers

List * bufferEmptyingQueue

References GISTBuildBuffers::bufferEmptyingQueue, GISTBuildBuffers::buffersOnLevels, GISTBuildBuffers::buffersOnLevelsLen, BufFileCreateTemp(), GISTBuildBuffers::context, CurrentMemoryContext, HASHCTL::entrysize, GISTBuildBuffers::freeBlocks, GISTBuildBuffers::freeBlocksLen, HASH_BLOBS, HASH_CONTEXT, hash_create(), HASH_ELEM, HASHCTL::hcxt, HASHCTL::keysize, GISTBuildBuffers::levelStep, GISTBuildBuffers::loadedBuffers, GISTBuildBuffers::loadedBuffersCount, GISTBuildBuffers::loadedBuffersLen, GISTBuildBuffers::nFileBlocks, GISTBuildBuffers::nFreeBlocks, NIL, GISTBuildBuffers::nodeBuffersTab, GISTBuildBuffers::pagesPerBuffer, palloc(), GISTBuildBuffers::pfile, and GISTBuildBuffers::rootlevel.

Referenced by gistInitBuffering().

gistinitpage()

Definition at line 757 of file gistutil.c.

758{

760

762

765 opaque->flags = f;

767}

void PageInit(Page page, Size pageSize, Size specialSize)

#define GistPageGetOpaque(page)

References GISTPageOpaqueData::flags, GISTPageOpaqueData::gist_page_id, GIST_PAGE_ID, GistPageGetOpaque, InvalidBlockNumber, PageInit(), and GISTPageOpaqueData::rightlink.

Referenced by gist_indexsortbuild(), gist_indexsortbuild_levelstate_add(), gist_indexsortbuild_levelstate_flush(), and GISTInitBuffer().

gistinsert()

Definition at line 165 of file gist.c.

170{

174

175

176 if (giststate == NULL)

177 {

183 }

184

186

188 itup->t_tid = *ht_ctid;

189

190 gistdoinsert(r, itup, 0, giststate, heapRel, false);

191

192

195

196 return false;

197}

static Datum values[MAXATTR]

void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate, Relation heapRel, bool is_build)

References createTempGistContext(), gistdoinsert(), gistFormTuple(), if(), IndexInfo::ii_AmCache, IndexInfo::ii_Context, initGISTstate(), MemoryContextReset(), MemoryContextSwitchTo(), GISTSTATE::tempCxt, and values.

Referenced by gisthandler().

gistjoinvector()

gistKeyIsEQ()

Definition at line 281 of file gistutil.c.

282{

283 bool result = false;

284

287 a, b,

289 return result;

290}

Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3)

FmgrInfo equalFn[INDEX_MAX_KEYS]

References a, b, GISTSTATE::equalFn, FunctionCall3Coll(), PointerGetDatum(), and GISTSTATE::supportCollation.

Referenced by gistgetadjusted(), and gistUserPicksplit().

gistMakeUnionItVec()

Definition at line 155 of file gistutil.c.

157{

158 int i;

160 int attrsize;

161

163

165 {

166 int j;

167

168

169 evec->n = 0;

170 for (j = 0; j < len; j++)

171 {

173 bool IsNull;

174

176 &IsNull);

177 if (IsNull)

178 continue;

179

182 datum,

184 false, IsNull);

185 evec->n++;

186 }

187

188

189 if (evec->n == 0)

190 {

192 isnull[i] = true;

193 }

194 else

195 {

196 if (evec->n == 1)

197 {

198

199 evec->n = 2;

201 }

202

203

208

209 isnull[i] = false;

210 }

211 }

212}

Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)

struct GISTENTRY GISTENTRY

FmgrInfo unionFn[INDEX_MAX_KEYS]

GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]

References FunctionCall2Coll(), GEVHDRSZ, gistdentryinit(), i, index_getattr(), j, GISTSTATE::leafTupdesc, len, GistEntryVector::n, TupleDescData::natts, GISTSTATE::nonLeafTupdesc, palloc(), PointerGetDatum(), GISTSTATE::supportCollation, GISTSTATE::unionFn, and GistEntryVector::vector.

Referenced by gistunion(), and gistunionsubkeyvec().

gistMakeUnionKey()

gistNewBuffer()

Definition at line 824 of file gistutil.c.

825{

827

828

829 for (;;)

830 {

832

834 break;

835

837

838

839

840

841

843 {

845

846

847

848

850 return buffer;

851

853

854

855

856

857

859 {

860

861

862

863

864

865

868

869 return buffer;

870 }

871

873 }

874

875

877 }

878

879

882

883 return buffer;

884}

bool ConditionalLockBuffer(Buffer buffer)

static FullTransactionId GistPageGetDeleteXid(Page page)

bool gistPageRecyclable(Page page)

void gistXLogPageReuse(Relation rel, Relation heaprel, BlockNumber blkno, FullTransactionId deleteXid)

BlockNumber GetFreeIndexPage(Relation rel)

#define XLogStandbyInfoActive()

References BMR_REL, BufferGetPage(), ConditionalLockBuffer(), EB_LOCK_FIRST, ExtendBufferedRel(), GetFreeIndexPage(), GIST_UNLOCK, gistcheckpage(), GistPageGetDeleteXid(), gistPageRecyclable(), gistXLogPageReuse(), InvalidBlockNumber, LockBuffer(), MAIN_FORKNUM, PageIsNew(), ReadBuffer(), RelationNeedsWAL, ReleaseBuffer(), and XLogStandbyInfoActive.

Referenced by gistbuild(), and gistplacetopage().

gistnospace()

gistoptions()

bytea * gistoptions ( Datum reloptions,
bool validate
)

Definition at line 912 of file gistutil.c.

913{

917 };

918

923}

static bool validate(Port *port, const char *auth)

void * build_reloptions(Datum reloptions, bool validate, relopt_kind kind, Size relopt_struct_size, const relopt_parse_elt *relopt_elems, int num_relopt_elems)

References build_reloptions(), fillfactor, lengthof, RELOPT_KIND_GIST, RELOPT_TYPE_ENUM, RELOPT_TYPE_INT, and validate().

Referenced by gisthandler().

gistPageRecyclable()

bool gistPageRecyclable ( Page page )

gistpenalty()

gistplacetopage()

bool gistplacetopage ( Relation rel,
Size freespace,
GISTSTATE * giststate,
Buffer buffer,
IndexTuple * itup,
int ntup,
OffsetNumber oldoffnum,
BlockNumber * newblkno,
Buffer leftchildbuf,
List ** splitinfo,
bool markfollowright,
Relation heapRel,
bool is_build
)

Definition at line 230 of file gist.c.

239{

242 bool is_leaf = (GistPageIsLeaf(page)) ? true : false;

244 bool is_split;

245

246

247

248

249

250

251

252

253

254

256 elog(ERROR, "concurrent GiST page split was incomplete");

257

258

260

261 *splitinfo = NIL;

262

263

264

265

266

267

268

269

270

271

272

273 is_split = gistnospace(page, itup, ntup, oldoffnum, freespace);

274

275

276

277

278

280 {

282 is_split = gistnospace(page, itup, ntup, oldoffnum, freespace);

283 }

284

285 if (is_split)

286 {

287

289 int tlen;

291 *ptr;

295 bool is_rootsplit;

296 int npage;

297

299

300

301

302

303

306 {

307

309

310 tlen--;

311 if (pos != tlen)

312 memmove(itvec + pos, itvec + pos + 1, sizeof(IndexTuple) * (tlen - pos));

313 }

315 dist = gistSplit(rel, page, itvec, tlen, giststate);

316

317

318

319

320 npage = 0;

321 for (ptr = dist; ptr; ptr = ptr->next)

322 npage++;

323

324 if (is_rootsplit)

325 npage++;

327 elog(ERROR, "GiST page split into too many halves (%d, maximum %d)",

329

330

331

332

333

334

335

336

337

338

339 ptr = dist;

340 if (!is_rootsplit)

341 {

342

345

346 dist->buffer = buffer;

349

350

352

353 ptr = ptr->next;

354 }

355 for (; ptr; ptr = ptr->next)

356 {

357

365 }

366

367

368

369

370

371 for (ptr = dist; ptr; ptr = ptr->next)

372 {

375 }

376

377

378

379

380

381

382 if (is_rootsplit)

383 {

385 int ndownlinks = 0;

386 int i;

387

388 rootpg.buffer = buffer;

391

392

393 for (ptr = dist; ptr; ptr = ptr->next)

394 ndownlinks++;

396 for (i = 0, ptr = dist; ptr; ptr = ptr->next)

397 downlinks[i++] = ptr->itup;

398

400 rootpg.block.num = ndownlinks;

403 rootpg.itup = NULL;

404

405 rootpg.next = dist;

406 dist = &rootpg;

407 }

408 else

409 {

410

411 for (ptr = dist; ptr; ptr = ptr->next)

412 {

414

415 si->buf = ptr->buffer;

417 *splitinfo = lappend(*splitinfo, si);

418 }

419 }

420

421

422

423

424

425 for (ptr = dist; ptr; ptr = ptr->next)

426 {

427 char *data = (char *) (ptr->list);

428

429 for (int i = 0; i < ptr->block.num; i++)

430 {

432

435

436

437

438

439

441 *newblkno = ptr->block.blkno;

442

444 }

445

446

449 ptr->next->block.blkno;

450 else

452

453

454

455

456

457

458

459

460

461 if (ptr->next && !is_rootsplit && markfollowright)

463 else

465

466

467

468

469

470

472 }

473

474

475

476

477

478

481

483

484

485

486

487

488 for (ptr = dist; ptr; ptr = ptr->next)

492

493

494

495

496

499

500

501

502

503

504

505

506

507

508

509

510 if (is_build)

512 else

513 {

516 dist, oldrlink, oldnsn, leftchildbuf,

517 markfollowright);

518 else

520 }

521

522 for (ptr = dist; ptr; ptr = ptr->next)

524

525

526

527

528

529

530

531

532 if (is_rootsplit)

533 {

534 for (ptr = dist->next; ptr; ptr = ptr->next)

536 }

537 }

538 else

539 {

540

541

542

544

545

546

547

548

550 {

551 if (ntup == 1)

552 {

553

556 elog(ERROR, "failed to add item to index page in \"%s\"",

558 }

559 else

560 {

561

564 }

565 }

566 else

567 {

568

570 }

571

573

576

577 if (is_build)

579 else

580 {

582 {

584 deloffs[1];

585

587 {

588 deloffs[0] = oldoffnum;

589 ndeloffs = 1;

590 }

591

593 deloffs, ndeloffs, itup, ntup,

594 leftchildbuf);

595 }

596 else

598 }

600

601 if (newblkno)

602 *newblkno = blkno;

603 }

604

605

606

607

608

609

610

611

612

613

614

615

616

617

619 {

621

624

626 }

627

629

630 return is_split;

631}

static bool BufferIsValid(Buffer bufnum)

void PageRestoreTempPage(Page tempPage, Page oldPage)

bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, Item newtup, Size newsize)

void PageIndexTupleDelete(Page page, OffsetNumber offnum)

Page PageGetTempPageCopySpecial(const PageData *page)

SplitPageLayout * gistSplit(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate)

static void gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel)

#define GistMarkFollowRight(page)

#define GistClearFollowRight(page)

#define GistPageSetNSN(page, val)

#define GistPageHasGarbage(page)

#define GIST_MAX_SPLIT_PAGES

#define GistTupleSetValid(itup)

bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace)

void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)

IndexTuple * gistextractpage(Page page, int *len)

XLogRecPtr gistGetFakeLSN(Relation rel)

IndexTuple * gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)

IndexTupleData * gistfillitupvec(IndexTuple *vec, int veclen, int *memlen)

XLogRecPtr gistXLogSplit(bool page_is_leaf, SplitPageLayout *dist, BlockNumber origrlink, GistNSN orignsn, Buffer leftchildbuf, bool markfollowright)

XLogRecPtr gistXLogUpdate(Buffer buffer, OffsetNumber *todelete, int ntodelete, IndexTuple *itup, int ituplen, Buffer leftchildbuf)

bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)

static void ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)

List * lappend(List *list, void *datum)

#define OffsetNumberIsValid(offsetNumber)

void PredicateLockPageSplit(Relation relation, BlockNumber oldblkno, BlockNumber newblkno)

struct SplitPageLayout * next

void XLogEnsureRecordSpace(int max_block_id, int ndatas)

References Assert(), gistxlogPage::blkno, SplitPageLayout::block, GISTPageSplitInfo::buf, SplitPageLayout::buffer, BufferGetBlockNumber(), BufferGetPage(), BufferIsValid(), data, GISTPageSplitInfo::downlink, elog, END_CRIT_SECTION, ERROR, F_LEAF, FirstOffsetNumber, GIST_MAX_SPLIT_PAGES, GIST_ROOT_BLKNO, GistBuildLSN, GistClearFollowRight, gistextractpage(), gistfillbuffer(), gistfillitupvec(), GistFollowRight, gistGetFakeLSN(), GISTInitBuffer(), gistjoinvector(), GistMarkFollowRight, gistNewBuffer(), gistnospace(), GistPageGetNSN, GistPageGetOpaque, GistPageHasGarbage, GistPageIsDeleted, GistPageIsLeaf, GistPageSetNSN, gistprunepage(), gistSplit(), GistTupleSetValid, gistXLogSplit(), gistXLogUpdate(), i, IndexTupleSize(), InvalidBlockNumber, InvalidOffsetNumber, ItemPointerEquals(), ItemPointerSetBlockNumber(), SplitPageLayout::itup, lappend(), SplitPageLayout::lenlist, SplitPageLayout::list, MarkBufferDirty(), SplitPageLayout::next, NIL, gistxlogPage::num, OffsetNumberIsValid, SplitPageLayout::page, PageAddItem, PageGetTempPageCopySpecial(), PageIndexTupleDelete(), PageIndexTupleOverwrite(), PageRestoreTempPage(), PageSetLSN(), palloc(), PredicateLockPageSplit(), RelationGetRelationName, RelationNeedsWAL, START_CRIT_SECTION, IndexTupleData::t_tid, UnlockReleaseBuffer(), and XLogEnsureRecordSpace().

Referenced by gistbufferinginserttuples(), and gistinserttuples().

gistPopItupFromNodeBuffer()

Definition at line 406 of file gistbuildbuffers.c.

408{

409

410

411

413 return false;

414

415

418

419

420

421

423

424

425

426

427

429 {

431

432

433

434

436

437

438

439

442 {

443

446

447

448

449

450

452 }

453 else

454 {

455

459 }

460 }

461 return true;

462}

#define PAGE_IS_EMPTY(nbp)

static void gistBuffersReleaseBlock(GISTBuildBuffers *gfbb, long blocknum)

static void gistLoadNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer)

static void ReadTempFileBlock(BufFile *file, long blknum, void *ptr)

static void gistGetItupFromPage(GISTNodeBufferPage *pageBuffer, IndexTuple *itup)

References Assert(), GISTNodeBuffer::blocksCount, gistBuffersReleaseBlock(), gistGetItupFromPage(), gistLoadNodeBuffer(), InvalidBlockNumber, PAGE_IS_EMPTY, GISTNodeBuffer::pageBuffer, GISTBuildBuffers::pfile, pfree(), GISTNodeBufferPage::prev, and ReadTempFileBlock().

Referenced by gistProcessEmptyingQueue(), and gistRelocateBuildBuffersOnSplit().

gistproperty()

bool gistproperty ( Oid index_oid,
int attno,
IndexAMProperty prop,
const char * propname,
bool * res,
bool * isnull
)

Definition at line 933 of file gistutil.c.

936{

937 Oid opclass,

938 opfamily,

939 opcintype;

941

942

943 if (attno == 0)

944 return false;

945

946

947

948

949

950

951

952

953

954

955

956

957 switch (prop)

958 {

961 break;

964 break;

965 default:

966 return false;

967 }

968

969

972 {

973 *isnull = true;

974 return true;

975 }

976

977

979 {

980 *isnull = true;

981 return true;

982 }

983

984

985

991

992

993

994

995

997 {

1003 }

1004

1005 *isnull = false;

1006

1007 return true;

1008}

@ AMPROP_DISTANCE_ORDERABLE

bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)

Oid get_index_column_opclass(Oid index_oid, int attno)

static Datum Int16GetDatum(int16 X)

static Datum ObjectIdGetDatum(Oid X)

#define SearchSysCacheExists4(cacheId, key1, key2, key3, key4)

References AMPROP_DISTANCE_ORDERABLE, AMPROP_RETURNABLE, get_index_column_opclass(), get_opclass_opfamily_and_input_type(), GIST_COMPRESS_PROC, GIST_DISTANCE_PROC, GIST_FETCH_PROC, Int16GetDatum(), ObjectIdGetDatum(), OidIsValid, and SearchSysCacheExists4.

Referenced by gisthandler().

gistPushItupToNodeBuffer()

Definition at line 336 of file gistbuildbuffers.c.

338{

339

340

341

342

344

345

346

347

349 {

353 }

354

355

358

359

360

361

363 {

364

365

366

368

369

372

373

374

375

376

380

381

383 }

384

386

387

388

389

391 {

395 }

396

397

399}

#define BUFFER_HALF_FILLED(nodeBuffer, gfbb)

#define PAGE_NO_SPACE(nbp, itup)

static void WriteTempFileBlock(BufFile *file, long blknum, const void *ptr)

static void gistAddLoadedBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer)

static void gistPlaceItupToPage(GISTNodeBufferPage *pageBuffer, IndexTuple itup)

static GISTNodeBufferPage * gistAllocateNewPageBuffer(GISTBuildBuffers *gfbb)

static long gistBuffersGetFreeBlock(GISTBuildBuffers *gfbb)

References GISTNodeBuffer::blocksCount, BUFFER_HALF_FILLED, GISTBuildBuffers::bufferEmptyingQueue, GISTBuildBuffers::context, gistAddLoadedBuffer(), gistAllocateNewPageBuffer(), gistBuffersGetFreeBlock(), gistLoadNodeBuffer(), gistPlaceItupToPage(), lcons(), MAXALIGN, MemoryContextSwitchTo(), PAGE_FREE_SPACE, PAGE_NO_SPACE, GISTNodeBuffer::pageBuffer, GISTBuildBuffers::pfile, GISTNodeBufferPage::prev, GISTNodeBuffer::queuedForEmptying, and WriteTempFileBlock().

Referenced by gistProcessItup(), and gistRelocateBuildBuffersOnSplit().

gistRelocateBuildBuffersOnSplit()

Definition at line 533 of file gistbuildbuffers.c.

536{

538 bool found;

542 int splitPagesCount = 0;

547

548

550 return;

551

552

553

554

558 if (!found)

559 {

560

561 return;

562 }

563

564

565

566

567

568

569

570

571

574 oldBuf.isTemp = true;

575

576

580

581

582

583

584 splitPagesCount = list_length(splitinfo);

585 relocationBuffersInfos =

587 splitPagesCount);

588

589

590

591

592

593 foreach(lc, splitinfo)

594 {

598

599

602 relocationBuffersInfos[i].entry,

603 relocationBuffersInfos[i].isnull);

604

605

606

607

608

609

610

611

613

614 relocationBuffersInfos[i].nodeBuffer = newNodeBuffer;

615 relocationBuffersInfos[i].splitinfo = si;

616 }

617

618

619

620

621

622

623

624

625

626

628 {

630 int i,

631 which;

634

636 itup, NULL, (OffsetNumber) 0, entry, isnull);

637

638

639 which = 0;

640

641

642

643

644

645

646 best_penalty[0] = -1;

647

648

649

650

651

652 for (i = 0; i < splitPagesCount; i++)

653 {

655 bool zero_penalty;

656 int j;

657

658 zero_penalty = true;

659

660

662 {

663 float usize;

664

665

667 &splitPageInfo->entry[j],

668 splitPageInfo->isnull[j],

669 &entry[j], isnull[j]);

670 if (usize > 0)

671 zero_penalty = false;

672

673 if (best_penalty[j] < 0 || usize < best_penalty[j])

674 {

675

676

677

678

679

680

681

682

683

684 which = i;

685 best_penalty[j] = usize;

686

688 best_penalty[j + 1] = -1;

689 }

690 else if (best_penalty[j] == usize)

691 {

692

693

694

695

696

697 }

698 else

699 {

700

701

702

703

704

705 zero_penalty = false;

706 break;

707 }

708 }

709

710

711

712

713

714

715 if (zero_penalty)

716 break;

717 }

718

719

720 targetBufferInfo = &relocationBuffersInfos[which];

721

722

724

725

727 itup, giststate);

728 if (newtup)

729 {

732 targetBufferInfo->entry,

733 targetBufferInfo->isnull);

734

736 }

737 }

738

739 pfree(relocationBuffersInfos);

740}

#define LEVEL_HAS_BUFFERS(nlevel, gfbb)

void gistPushItupToNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple itup)

bool gistPopItupFromNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple *itup)

GISTNodeBuffer * gistGetNodeBuffer(GISTBuildBuffers *gfbb, GISTSTATE *giststate, BlockNumber nodeBlocknum, int level)

static int list_length(const List *l)

#define foreach_current_index(var_or_cell)

bool isnull[INDEX_MAX_KEYS]

GISTPageSplitInfo * splitinfo

GISTNodeBuffer * nodeBuffer

GISTENTRY entry[INDEX_MAX_KEYS]

References Assert(), GISTNodeBuffer::blocksCount, GISTPageSplitInfo::buf, BufferGetBlockNumber(), GISTPageSplitInfo::downlink, RelocationBufferInfo::entry, foreach_current_index, GIST_ROOT_BLKNO, gistDeCompressAtt(), gistgetadjusted(), gistGetNodeBuffer(), gistpenalty(), gistPopItupFromNodeBuffer(), gistPushItupToNodeBuffer(), HASH_FIND, hash_search(), i, INDEX_MAX_KEYS, IndexRelationGetNumberOfKeyAttributes, InvalidBlockNumber, RelocationBufferInfo::isnull, GISTNodeBuffer::isTemp, j, LEVEL_HAS_BUFFERS, lfirst, list_length(), RelocationBufferInfo::nodeBuffer, GISTBuildBuffers::nodeBuffersTab, GISTNodeBuffer::pageBlocknum, GISTNodeBuffer::pageBuffer, palloc(), pfree(), and RelocationBufferInfo::splitinfo.

Referenced by gistbufferinginserttuples().

gistSplit()

Definition at line 1450 of file gist.c.

1455{

1457 *rvectup;

1459 int i;

1461

1462

1464

1465

1467

1468

1469

1470

1471

1472 if (len == 1)

1474 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

1475 errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",

1478

1484

1485

1488

1491

1494

1495

1497 {

1499 }

1500 else

1501 {

1506 }

1507

1509 {

1511 *subres;

1512

1514

1515

1516 while (resptr->next)

1517 resptr = resptr->next;

1518

1519 resptr->next = res;

1520 res = subres;

1521 }

1522 else

1523 {

1528 }

1529

1530 return res;

1531}

void gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate, GistSplitVector *v, int attno)

bool gistfitpage(IndexTuple *itvec, int len)

void check_stack_depth(void)

GIST_SPLITVEC splitVector

Datum spl_lattr[INDEX_MAX_KEYS]

bool spl_lisnull[INDEX_MAX_KEYS]

Datum spl_rattr[INDEX_MAX_KEYS]

bool spl_risnull[INDEX_MAX_KEYS]

References Assert(), SplitPageLayout::block, check_stack_depth(), ereport, errcode(), errmsg(), ERROR, for(), gistfillitupvec(), gistfitpage(), gistFormTuple(), GiSTPageSize, gistSplit(), gistSplitByKey(), i, if(), IndexTupleSize(), SplitPageLayout::itup, len, SplitPageLayout::lenlist, SplitPageLayout::list, TupleDescData::natts, SplitPageLayout::next, GISTSTATE::nonLeafTupdesc, gistxlogPage::num, palloc(), RelationGetRelationName, ROTATEDIST, GistSplitVector::spl_lattr, GIST_SPLITVEC::spl_left, GistSplitVector::spl_lisnull, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GistSplitVector::spl_rattr, GIST_SPLITVEC::spl_right, GistSplitVector::spl_risnull, and GistSplitVector::splitVector.

Referenced by gist_indexsortbuild_levelstate_flush(), gistplacetopage(), and gistSplit().

gistSplitByKey()

Definition at line 623 of file gistsplit.c.

625{

628 int nOffNullTuples = 0;

629 int i;

630

631

632

634 entryvec->n = len + 1;

636

637 for (i = 1; i <= len; i++)

638 {

640 bool IsNull;

641

643 &IsNull);

645 datum, r, page, i,

646 false, IsNull);

647 if (IsNull)

648 offNullTuples[nOffNullTuples++] = i;

649 }

650

651 if (nOffNullTuples == len)

652 {

653

654

655

656

657

659

662 else

664 }

665 else if (nOffNullTuples > 0)

666 {

667 int j = 0;

668

669

670

671

672

676

679 for (i = 1; i <= len; i++)

680 if (j < v->splitVector.spl_nright && offNullTuples[j] == i)

681 j++;

682 else

684

685

687 {

690 }

691 }

692 else

693 {

694

695

696

698 {

699

700

701

702

704

706 {

707

708

709

710

712 }

713 else

714 {

715

716

717

718

721 int newlen = 0;

723

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

725 {

727 {

728 newitup[newlen] = itup[i];

729 map[newlen] = i + 1;

730 newlen++;

731 }

732 }

733

735

736

737

738

739

745

746

747 gistSplitByKey(r, page, newitup, newlen, giststate, v, attno + 1);

748

749

754

756 }

757 }

758 }

759

760

761

762

763

764

765

766

767

768

769

770

771

772

773

775 {

778 }

779}

static void gistunionsubkey(GISTSTATE *giststate, IndexTuple *itvec, GistSplitVector *spl)

static bool gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GistSplitVector *v, IndexTuple *itup, int len, GISTSTATE *giststate)

static void gistSplitHalf(GIST_SPLITVEC *v, int len)

References Assert(), for(), GEVHDRSZ, gistdentryinit(), gistSplitByKey(), gistSplitHalf(), gistunionsubkey(), gistUserPicksplit(), i, index_getattr(), j, GISTSTATE::leafTupdesc, len, GistEntryVector::n, TupleDescData::natts, GISTSTATE::nonLeafTupdesc, palloc(), GistSplitVector::spl_dontcare, GIST_SPLITVEC::spl_left, GistSplitVector::spl_lisnull, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_right, GistSplitVector::spl_risnull, GistSplitVector::splitVector, and GistEntryVector::vector.

Referenced by gistSplit(), and gistSplitByKey().

gistunion()

Definition at line 219 of file gistutil.c.

220{

223

225

226 return gistFormTuple(giststate, r, attr, isnull, false);

227}

void gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len, Datum *attr, bool *isnull)

References gistFormTuple(), gistMakeUnionItVec(), INDEX_MAX_KEYS, and len.

Referenced by gist_indexsortbuild_levelstate_flush().

gistUnloadNodeBuffers()

gistvacuumcleanup()

gistvalidate()

bool gistvalidate ( Oid opclassoid )

Definition at line 32 of file gistvalidate.c.

33{

34 bool result = true;

37 Oid opfamilyoid;

38 Oid opcintype;

39 Oid opckeytype;

40 char *opclassname;

41 char *opfamilyname;

43 *oprlist;

44 List *grouplist;

46 int i;

48

49

52 elog(ERROR, "cache lookup failed for operator class %u", opclassoid);

54

55 opfamilyoid = classform->opcfamily;

56 opcintype = classform->opcintype;

57 opckeytype = classform->opckeytype;

59 opckeytype = opcintype;

60 opclassname = NameStr(classform->opcname);

61

62

64

65

68

69

71 {

74 bool ok;

75

76

77

78

79

80 if (procform->amproclefttype != procform->amprocrighttype)

81 {

83 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

84 errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types",

85 opfamilyname, "gist",

87 result = false;

88 }

89

90

91

92

93

94 if (procform->amproclefttype != opcintype)

95 continue;

96

97

98 switch (procform->amprocnum)

99 {

102 5, 5, INTERNALOID, opcintype,

103 INT2OID, OIDOID, INTERNALOID);

104 break;

107 2, 2, INTERNALOID, INTERNALOID);

108 break;

113 1, 1, INTERNALOID);

114 break;

117 3, 3, INTERNALOID,

118 INTERNALOID, INTERNALOID);

119 break;

122 2, 2, INTERNALOID, INTERNALOID);

123 break;

126 3, 3, opckeytype, opckeytype,

127 INTERNALOID);

128 break;

131 5, 5, INTERNALOID, opcintype,

132 INT2OID, OIDOID, INTERNALOID);

133 break;

136 break;

139 1, 1, INTERNALOID);

140 break;

143 1, 1, INT4OID) &&

144 procform->amproclefttype == ANYOID &&

145 procform->amprocrighttype == ANYOID;

146 break;

147 default:

149 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

150 errmsg("operator family \"%s\" of access method %s contains function %s with invalid support number %d",

151 opfamilyname, "gist",

153 procform->amprocnum)));

154 result = false;

155 continue;

156 }

157

158 if (!ok)

159 {

161 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

162 errmsg("operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d",

163 opfamilyname, "gist",

165 procform->amprocnum)));

166 result = false;

167 }

168 }

169

170

172 {

175 Oid op_rettype;

176

177

178 if (oprform->amopstrategy < 1)

179 {

181 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

182 errmsg("operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d",

183 opfamilyname, "gist",

185 oprform->amopstrategy)));

186 result = false;

187 }

188

189

190 if (oprform->amoppurpose != AMOP_SEARCH)

191 {

192

194 oprform->amoplefttype,

195 oprform->amoplefttype,

197 {

199 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

200 errmsg("operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s",

201 opfamilyname, "gist",

203 result = false;

204 }

205

208 {

210 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

211 errmsg("operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s",

212 opfamilyname, "gist",

214 result = false;

215 }

216 }

217 else

218 {

219

220 op_rettype = BOOLOID;

221 }

222

223

225 oprform->amoplefttype,

226 oprform->amoprighttype))

227 {

229 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

230 errmsg("operator family \"%s\" of access method %s contains operator %s with wrong signature",

231 opfamilyname, "gist",

233 result = false;

234 }

235 }

236

237

239 opclassgroup = NULL;

240 foreach(lc, grouplist)

241 {

243

244

245 if (thisgroup->lefttype == opcintype &&

246 thisgroup->righttype == opcintype)

247 opclassgroup = thisgroup;

248

249

250

251

252

253

254

255

256

257 }

258

259

261 {

262 if (opclassgroup &&

264 continue;

269 continue;

271 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

272 errmsg("operator class \"%s\" of access method %s is missing support function %d",

273 opclassname, "gist", i)));

274 result = false;

275 }

276

280

281 return result;

282}

bool check_amproc_signature(Oid funcid, Oid restype, bool exact, int minargs, int maxargs,...)

bool check_amop_signature(Oid opno, Oid restype, Oid lefttype, Oid righttype)

List * identify_opfamily_groups(CatCList *oprlist, CatCList *proclist)

bool opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid)

bool check_amoptsproc_signature(Oid funcid)

void ReleaseCatCacheList(CatCList *list)

#define HeapTupleIsValid(tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)

Oid get_op_rettype(Oid opno)

char * get_opfamily_name(Oid opfid, bool missing_ok)

FormData_pg_amop * Form_pg_amop

FormData_pg_amproc * Form_pg_amproc

FormData_pg_opclass * Form_pg_opclass

char * format_procedure(Oid procedure_oid)

char * format_operator(Oid operator_oid)

CatCTup * members[FLEXIBLE_ARRAY_MEMBER]

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

#define SearchSysCacheList1(cacheId, key1)

References check_amop_signature(), check_amoptsproc_signature(), check_amproc_signature(), elog, ereport, errcode(), errmsg(), ERROR, format_operator(), format_procedure(), OpFamilyOpFuncGroup::functionset, get_op_rettype(), get_opfamily_name(), get_opfamily_proc(), GETSTRUCT(), GIST_COMPRESS_PROC, GIST_CONSISTENT_PROC, GIST_DECOMPRESS_PROC, GIST_DISTANCE_PROC, GIST_EQUAL_PROC, GIST_FETCH_PROC, GIST_OPTIONS_PROC, GIST_PENALTY_PROC, GIST_PICKSPLIT_PROC, GIST_SORTSUPPORT_PROC, GIST_STRATNUM_PROC, GIST_UNION_PROC, GISTNProcs, HeapTupleIsValid, i, identify_opfamily_groups(), INFO, OpFamilyOpFuncGroup::lefttype, lfirst, catclist::members, catclist::n_members, NameStr, ObjectIdGetDatum(), OidIsValid, opfamily_can_sort_type(), ReleaseCatCacheList(), ReleaseSysCache(), OpFamilyOpFuncGroup::righttype, SearchSysCache1(), SearchSysCacheList1, and catctup::tuple.

Referenced by gisthandler().

gistXLogAssignLSN()

gistXLogDelete()

Definition at line 670 of file gistxlog.c.

672{

675

679

682

683

684

685

686

687

689

691

693

694 return recptr;

695}

#define SizeOfGistxlogDelete

#define RelationIsAccessibleInLogicalDecoding(relation)

TransactionId snapshotConflictHorizon

void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)

References gistxlogDelete::isCatalogRel, gistxlogDelete::ntodelete, REGBUF_STANDARD, RelationIsAccessibleInLogicalDecoding, SizeOfGistxlogDelete, gistxlogDelete::snapshotConflictHorizon, XLOG_GIST_DELETE, XLogBeginInsert(), XLogInsert(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by gistprunepage().

gistXLogPageDelete()

gistXLogPageReuse()

Definition at line 594 of file gistxlog.c.

596{

598

599

600

601

602

603

604

605

608 xlrec_reuse.block = blkno;

610

613

615}

#define XLOG_GIST_PAGE_REUSE

#define SizeOfGistxlogPageReuse

RelFileLocator rd_locator

References gistxlogPageReuse::block, gistxlogPageReuse::isCatalogRel, gistxlogPageReuse::locator, RelationData::rd_locator, RelationIsAccessibleInLogicalDecoding, SizeOfGistxlogPageReuse, gistxlogPageReuse::snapshotConflictHorizon, XLOG_GIST_PAGE_REUSE, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by gistNewBuffer().

gistXLogSplit()

Definition at line 495 of file gistxlog.c.

499{

502 int npage = 0;

504 int i;

505

506 for (ptr = dist; ptr; ptr = ptr->next)

507 npage++;

508

511 xlrec.origleaf = page_is_leaf;

514

516

517

518

519

520

523

524

525

526

527

528

529

530

532

533 i = 1;

534 for (ptr = dist; ptr; ptr = ptr->next)

535 {

539 i++;

540 }

541

543

544 return recptr;

545}

#define XLOG_GIST_PAGE_SPLIT

void XLogRegisterBufData(uint8 block_id, const void *data, uint32 len)

References SplitPageLayout::block, SplitPageLayout::buffer, BufferIsValid(), i, SplitPageLayout::lenlist, SplitPageLayout::list, gistxlogPageSplit::markfollowright, SplitPageLayout::next, gistxlogPageSplit::npage, gistxlogPage::num, gistxlogPageSplit::origleaf, gistxlogPageSplit::orignsn, gistxlogPageSplit::origrlink, REGBUF_STANDARD, REGBUF_WILL_INIT, XLOG_GIST_PAGE_SPLIT, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by gistplacetopage().

gistXLogUpdate()

Definition at line 629 of file gistxlog.c.

633{

635 int i;

637

640

643

646

647

648 for (i = 0; i < ituplen; i++)

650

651

652

653

654

657

659

660 return recptr;

661}

#define XLOG_GIST_PAGE_UPDATE

References BufferIsValid(), i, IndexTupleSize(), gistxlogPageUpdate::ntodelete, gistxlogPageUpdate::ntoinsert, REGBUF_STANDARD, XLOG_GIST_PAGE_UPDATE, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by gistplacetopage(), and gistvacuumpage().

initGISTstate()

Definition at line 1537 of file gist.c.

1538{

1542 int i;

1543

1544

1546 elog(ERROR, "numberOfAttributes %d > %d",

1548

1549

1551 "GiST scan context",

1554

1555

1557

1558 giststate->scanCxt = scanCxt;

1559 giststate->tempCxt = scanCxt;

1561

1562

1563

1564

1565

1566

1567

1568

1569

1570

1571

1574

1576 {

1579 scanCxt);

1582 scanCxt);

1583

1584

1588 scanCxt);

1589 else

1591

1592

1596 scanCxt);

1597 else

1599

1602 scanCxt);

1605 scanCxt);

1608 scanCxt);

1609

1610

1614 scanCxt);

1615 else

1617

1618

1622 scanCxt);

1623 else

1625

1626

1627

1628

1629

1630

1631

1632

1633

1634

1635

1636

1639 else

1641 }

1642

1643

1644 for (; i < index->rd_att->natts; i++)

1645 {

1656 }

1657

1659

1660 return giststate;

1661}

void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)

FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)

FmgrInfo distanceFn[INDEX_MAX_KEYS]

FmgrInfo consistentFn[INDEX_MAX_KEYS]

FmgrInfo picksplitFn[INDEX_MAX_KEYS]

TupleDesc CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts)

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, GISTSTATE::compressFn, GISTSTATE::consistentFn, CreateTupleDescTruncatedCopy(), CurrentMemoryContext, GISTSTATE::decompressFn, GISTSTATE::distanceFn, elog, GISTSTATE::equalFn, ERROR, GISTSTATE::fetchFn, fmgr_info_copy(), FmgrInfo::fn_oid, GIST_COMPRESS_PROC, GIST_CONSISTENT_PROC, GIST_DECOMPRESS_PROC, GIST_DISTANCE_PROC, GIST_EQUAL_PROC, GIST_FETCH_PROC, GIST_PENALTY_PROC, GIST_PICKSPLIT_PROC, GIST_UNION_PROC, i, index_getprocid(), index_getprocinfo(), INDEX_MAX_KEYS, IndexRelationGetNumberOfKeyAttributes, InvalidOid, GISTSTATE::leafTupdesc, MemoryContextSwitchTo(), GISTSTATE::nonLeafTupdesc, OidIsValid, palloc(), GISTSTATE::penaltyFn, GISTSTATE::picksplitFn, GISTSTATE::scanCxt, GISTSTATE::supportCollation, GISTSTATE::tempCxt, and GISTSTATE::unionFn.

Referenced by gistbeginscan(), gistbuild(), and gistinsert().