PostgreSQL Source Code: src/backend/access/gist/gistutil.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

15

16#include <math.h>

17

24#include "utils/fmgrprotos.h"

29

30

31

32

33void

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}

54

55

56

57

58bool

60{

61 unsigned int size = freespace,

62 deleted = 0;

63 int i;

64

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

67

69 {

71

73 }

74

76}

77

78bool

80{

81 int i;

82 Size size = 0;

83

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

86

87

89}

90

91

92

93

96{

98 maxoff;

100

102 *len = maxoff;

106

107 return itvec;

108}

109

110

111

112

115{

117 memmove(&itvec[*len], additvec, sizeof(IndexTuple) * addlen);

118 *len += addlen;

119 return itvec;

120}

121

122

123

124

125

128{

129 char *ptr,

130 *ret;

131 int i;

132

133 *memlen = 0;

134

135 for (i = 0; i < veclen; i++)

137

138 ptr = ret = palloc(*memlen);

139

140 for (i = 0; i < veclen; i++)

141 {

144 }

145

147}

148

149

150

151

152

153

154void

156 Datum *attr, bool *isnull)

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}

213

214

215

216

217

220{

223

225

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

227}

228

229

230

231

232void

236 Datum *dst, bool *dstisnull)

237{

238

239 union

240 {

245 int dstsize;

246

247 evec->n = 2;

248

249 if (isnull1 && isnull2)

250 {

251 *dstisnull = true;

252 *dst = (Datum) 0;

253 }

254 else

255 {

256 if (isnull1 == false && isnull2 == false)

257 {

258 evec->vector[0] = *entry1;

259 evec->vector[1] = *entry2;

260 }

261 else if (isnull1 == false)

262 {

263 evec->vector[0] = *entry1;

264 evec->vector[1] = *entry1;

265 }

266 else

267 {

268 evec->vector[0] = *entry2;

269 evec->vector[1] = *entry2;

270 }

271

272 *dstisnull = false;

277 }

278}

279

280bool

282{

283 bool result = false;

284

287 a, b,

289 return result;

290}

291

292

293

294

295void

298{

299 int i;

300

302 {

304

307 datum, r, p, o,

308 false, isnull[i]);

309 }

310}

311

312

313

314

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}

366

367

368

369

370

371

372

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}

542

543

544

545

546void

549 bool l, bool isNull)

550{

551 if (!isNull)

552 {

554

556

557

559 return;

560

565

566 if (dep != e)

569 }

570 else

572}

573

576 const Datum *attdata, const bool *isnull, bool isleaf)

577{

580

582

585 compatt, isnull);

586

587

588

589

590

592 return res;

593}

594

595void

597 const Datum *attdata, const bool *isnull, bool isleaf, Datum *compatt)

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}

641

642

643

644

647{

650

652

657

658

659 return fep->key;

660}

661

662

663

664

665

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}

722

723float

725 GISTENTRY *orig, bool isNullOrig,

727{

728 float penalty = 0.0;

729

731 (isNullOrig == false && isNullAdd == false))

732 {

738

739 if (isnan(penalty) || penalty < 0.0)

740 penalty = 0.0;

741 }

742 else if (isNullOrig && isNullAdd)

743 penalty = 0.0;

744 else

745 {

746

748 }

749

750 return penalty;

751}

752

753

754

755

756void

758{

760

762

765 opaque->flags = f;

767}

768

769

770

771

772void

774{

776

779}

780

781

782

783

784void

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}

814

815

816

817

818

819

820

821

822

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}

885

886

887bool

889{

891 return true;

893 {

894

895

896

897

898

899

900

901

902

903

905

907 }

908 return false;

909}

910

913{

917 };

918

923}

924

925

926

927

928

929

930

931

932bool

935 bool *res, bool *isnull)

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}

1009

1010

1011

1012

1013

1014

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}

1059

1060

1061

1062

1063

1066{

1068

1069 switch (cmptype)

1070 {

1085 default:

1087 }

1088}

1089

1090

1091

1092

1093

1094

1095

1096

1099{

1100 Oid funcid;

1102

1103

1107

1108

1111}

@ AMPROP_DISTANCE_ORDERABLE

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

#define InvalidBlockNumber

BlockNumber BufferGetBlockNumber(Buffer buffer)

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

bool ConditionalLockBuffer(Buffer buffer)

void ReleaseBuffer(Buffer buffer)

void LockBuffer(Buffer buffer, int mode)

Buffer ReadBuffer(Relation reln, BlockNumber blockNum)

static Page BufferGetPage(Buffer buffer)

Size PageGetFreeSpace(const PageData *page)

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

static bool PageIsEmpty(const PageData *page)

static uint16 PageGetSpecialSize(const PageData *page)

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

static bool PageIsNew(const PageData *page)

static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)

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

static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)

#define OidIsValid(objectId)

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

static float4 get_float4_infinity(void)

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

Datum OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)

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

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

#define PG_GETARG_INT32(n)

#define PG_RETURN_UINT16(x)

#define GIST_STRATNUM_PROC

struct GISTENTRY GISTENTRY

#define GIST_COMPRESS_PROC

#define GistPageIsLeaf(page)

#define GIST_DISTANCE_PROC

static FullTransactionId GistPageGetDeleteXid(Page page)

#define GistPageIsDeleted(page)

#define GistPageGetOpaque(page)

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

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

bytea * gistoptions(Datum reloptions, bool validate)

Buffer gistNewBuffer(Relation r, Relation heaprel)

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

bool gistPageRecyclable(Page page)

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

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

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

HeapTuple gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple)

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

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

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

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

IndexTuple * gistextractpage(Page page, int *len)

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

bool gistfitpage(IndexTuple *itvec, int len)

Datum gist_stratnum_common(PG_FUNCTION_ARGS)

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

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

XLogRecPtr gistGetFakeLSN(Relation rel)

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

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

void gistinitpage(Page page, uint32 f)

IndexTuple gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)

void GISTInitBuffer(Buffer b, uint32 f)

StrategyNumber gisttranslatecmptype(CompareType cmptype, Oid opfamily)

void gistcheckpage(Relation rel, Buffer buf)

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

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

XLogRecPtr gistXLogAssignLSN(void)

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

Assert(PointerIsAligned(start, uint64))

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

BlockNumber GetFreeIndexPage(Relation rel)

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

struct ItemIdData ItemIdData

static void ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber)

IndexTupleData * IndexTuple

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

static Size IndexTupleSize(const IndexTupleData *itup)

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

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

Oid get_index_column_opclass(Oid index_oid, int attno)

void * repalloc(void *pointer, Size size)

#define InvalidOffsetNumber

#define OffsetNumberNext(offsetNumber)

#define FirstOffsetNumber

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

pg_prng_state pg_global_prng_state

bool pg_prng_bool(pg_prng_state *state)

static Datum PointerGetDatum(const void *X)

static Datum Int16GetDatum(int16 X)

static Datum ObjectIdGetDatum(Oid X)

static uint16 DatumGetUInt16(Datum X)

static Pointer DatumGetPointer(Datum X)

static Datum Int32GetDatum(int32 X)

bool GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid)

#define RelationGetRelationName(relation)

#define RelationNeedsWAL(relation)

#define IndexRelationGetNumberOfKeyAttributes(relation)

#define RelationIsPermanent(relation)

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

#define RTOverlapStrategyNumber

#define RTEqualStrategyNumber

#define RTLessEqualStrategyNumber

#define RTGreaterEqualStrategyNumber

#define RTGreaterStrategyNumber

#define RTContainedByStrategyNumber

#define RTLessStrategyNumber

FmgrInfo fetchFn[INDEX_MAX_KEYS]

FmgrInfo penaltyFn[INDEX_MAX_KEYS]

Oid supportCollation[INDEX_MAX_KEYS]

FmgrInfo decompressFn[INDEX_MAX_KEYS]

FmgrInfo compressFn[INDEX_MAX_KEYS]

FmgrInfo equalFn[INDEX_MAX_KEYS]

FmgrInfo unionFn[INDEX_MAX_KEYS]

GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]

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

XLogRecPtr GetXLogInsertRecPtr(void)

XLogRecPtr GetFakeLSNForUnloggedRel(void)

#define XLogStandbyInfoActive()

#define FirstNormalUnloggedLSN

#define XLogRecPtrIsInvalid(r)

#define InvalidXLogRecPtr