PostgreSQL Source Code: src/backend/utils/adt/multirangetypes_selfuncs.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

19

20#include <math.h>

21

26#include "utils/fmgrprotos.h"

32

40 Oid operator);

44 int hist_nvalues, bool equal);

53 int length_hist_nvalues, double value,

56 int length_hist_nvalues, double length1,

57 double length2, bool equal);

62 int hist_nvalues,

63 Datum *length_hist_values,

64 int length_hist_nvalues);

69 int hist_nvalues,

70 Datum *length_hist_values,

71 int length_hist_nvalues);

72

73

74

75

76

77static double

79{

80 switch (operator)

81 {

82 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:

83 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:

84 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:

85 return 0.01;

86

87 case OID_RANGE_CONTAINS_MULTIRANGE_OP:

88 case OID_RANGE_MULTIRANGE_CONTAINED_OP:

89 case OID_MULTIRANGE_CONTAINS_RANGE_OP:

90 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:

91 case OID_MULTIRANGE_RANGE_CONTAINED_OP:

92 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:

93 return 0.005;

94

95 case OID_MULTIRANGE_CONTAINS_ELEM_OP:

96 case OID_MULTIRANGE_ELEM_CONTAINED_OP:

97

98

99

100

101

103

104 case OID_MULTIRANGE_LESS_OP:

105 case OID_MULTIRANGE_LESS_EQUAL_OP:

106 case OID_MULTIRANGE_GREATER_OP:

107 case OID_MULTIRANGE_GREATER_EQUAL_OP:

108 case OID_MULTIRANGE_LEFT_RANGE_OP:

109 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:

110 case OID_RANGE_LEFT_MULTIRANGE_OP:

111 case OID_MULTIRANGE_RIGHT_RANGE_OP:

112 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:

113 case OID_RANGE_RIGHT_MULTIRANGE_OP:

114 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:

115 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:

116 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:

117 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:

118 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:

119 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:

120

122

123 default:

124

125

126

127

128

129 return 0.01;

130 }

131}

132

133

134

135

138{

145 bool varonleft;

150

151

152

153

154

156 &vardata, &other, &varonleft))

158

159

160

161

163 {

166 }

167

168

169

170

171

172 if (((Const *) other)->constisnull)

173 {

176 }

177

178

179

180

181

182 if (!varonleft)

183 {

184

186 if (!operator)

187 {

188

191 }

192 }

193

194

195

196

197

198

199

200

201

202

203

204

205 if (operator == OID_MULTIRANGE_CONTAINS_ELEM_OP)

206 {

208

210 {

213

214 lower.inclusive = true;

215 lower.val = ((Const *) other)->constvalue;

216 lower.infinite = false;

217 lower.lower = true;

218 upper.inclusive = true;

219 upper.val = ((Const *) other)->constvalue;

220 upper.infinite = false;

221 upper.lower = false;

223 false, NULL);

225 1, &constrange);

226 }

227 }

228 else if (operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||

229 operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||

230 operator == OID_MULTIRANGE_OVERLAPS_RANGE_OP ||

231 operator == OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP ||

232 operator == OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP ||

233 operator == OID_MULTIRANGE_LEFT_RANGE_OP ||

234 operator == OID_MULTIRANGE_RIGHT_RANGE_OP)

235 {

236

237

238

239

242 {

245 1, &constrange);

246 }

247 }

248 else if (operator == OID_RANGE_OVERLAPS_MULTIRANGE_OP ||

249 operator == OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP ||

250 operator == OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP ||

251 operator == OID_RANGE_LEFT_MULTIRANGE_OP ||

252 operator == OID_RANGE_RIGHT_MULTIRANGE_OP ||

253 operator == OID_RANGE_CONTAINS_MULTIRANGE_OP ||

254 operator == OID_MULTIRANGE_ELEM_CONTAINED_OP ||

255 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP)

256 {

257

258

259

260

261

262

263 }

264 else if (((Const *) other)->consttype == vardata.vartype)

265 {

266

268

270 }

271

272

273

274

275

276

277

278 if (constmultirange)

279 selec = calc_multirangesel(typcache, &vardata, constmultirange, operator);

280 else

282

284

286

288}

289

290static double

293{

294 double hist_selec;

295 double selec;

297 null_frac;

298

299

300

301

302

304 {

307

309 null_frac = stats->stanullfrac;

310

311

313 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,

316 {

318 elog(ERROR, "invalid empty fraction statistic");

319 empty_frac = sslot.numbers[0];

321 }

322 else

323 {

324

325 empty_frac = 0.0;

326 }

327 }

328 else

329 {

330

331

332

333

334

335

336 null_frac = 0.0;

337 empty_frac = 0.0;

338 }

339

341 {

342

343

344

345

346 switch (operator)

347 {

348

349 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:

350 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:

351 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:

352 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:

353 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:

354 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:

355 case OID_MULTIRANGE_LEFT_RANGE_OP:

356 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:

357 case OID_MULTIRANGE_RIGHT_RANGE_OP:

358 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:

359

360 case OID_MULTIRANGE_LESS_OP:

361 selec = 0.0;

362 break;

363

364

365

366

367

368 case OID_RANGE_MULTIRANGE_CONTAINED_OP:

369 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:

370

371 case OID_MULTIRANGE_LESS_EQUAL_OP:

372 selec = empty_frac;

373 break;

374

375

376 case OID_MULTIRANGE_CONTAINS_RANGE_OP:

377 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:

378

379 case OID_MULTIRANGE_GREATER_EQUAL_OP:

380 selec = 1.0;

381 break;

382

383

384 case OID_MULTIRANGE_GREATER_OP:

385 selec = 1.0 - empty_frac;

386 break;

387

388

389 case OID_MULTIRANGE_CONTAINS_ELEM_OP:

390

391

392 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:

393 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:

394 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:

395 case OID_RANGE_LEFT_MULTIRANGE_OP:

396 case OID_RANGE_RIGHT_MULTIRANGE_OP:

397 case OID_RANGE_CONTAINS_MULTIRANGE_OP:

398 case OID_MULTIRANGE_ELEM_CONTAINED_OP:

399 case OID_MULTIRANGE_RANGE_CONTAINED_OP:

400

401 default:

402 elog(ERROR, "unexpected operator %u", operator);

403 selec = 0.0;

404 break;

405 }

406 }

407 else

408 {

409

410

411

412

413

414

415

416

418 operator);

419 if (hist_selec < 0.0)

421

422

423

424

425

426

427 if (operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||

428 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)

429 {

430

431 selec = (1.0 - empty_frac) * hist_selec + empty_frac;

432 }

433 else

434 {

435

436 selec = (1.0 - empty_frac) * hist_selec;

437 }

438 }

439

440

441 selec *= (1.0 - null_frac);

442

443

445

446 return selec;

447}

448

449

450

451

452

453

454

455static double

458{

462 int nhist;

465 int i;

469 double hist_selec;

470

471

474 return -1;

478 return -1;

479

480

483 STATISTIC_KIND_BOUNDS_HISTOGRAM, InvalidOid,

485 return -1.0;

486

487

489 {

491 return -1.0;

492 }

493

494

495

496

497

501 for (i = 0; i < nhist; i++)

502 {

503 bool empty;

504

506 &hist_lower[i], &hist_upper[i], &empty);

507

508 if (empty)

509 elog(ERROR, "bounds histogram contains an empty range");

510 }

511

512

513 if (operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||

514 operator == OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP ||

515 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP ||

516 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)

517 {

520 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,

523 {

525 return -1.0;

526 }

527

528

530 {

533 return -1.0;

534 }

535 }

536 else

537 memset(&lslot, 0, sizeof(lslot));

538

539

542 &const_lower, &tmp);

544 &tmp, &const_upper);

545

546

547

548

549

550 switch (operator)

551 {

552 case OID_MULTIRANGE_LESS_OP:

553

554

555

556

557

558

559

560

561

562 hist_selec =

564 hist_lower, nhist, false);

565 break;

566

567 case OID_MULTIRANGE_LESS_EQUAL_OP:

568 hist_selec =

570 hist_lower, nhist, true);

571 break;

572

573 case OID_MULTIRANGE_GREATER_OP:

574 hist_selec =

576 hist_lower, nhist, false);

577 break;

578

579 case OID_MULTIRANGE_GREATER_EQUAL_OP:

580 hist_selec =

582 hist_lower, nhist, true);

583 break;

584

585 case OID_MULTIRANGE_LEFT_RANGE_OP:

586 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:

587

588 hist_selec =

590 hist_upper, nhist, false);

591 break;

592

593 case OID_MULTIRANGE_RIGHT_RANGE_OP:

594 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:

595

596 hist_selec =

598 hist_lower, nhist, true);

599 break;

600

601 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:

602 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:

603

604 hist_selec =

606 hist_lower, nhist, false);

607 break;

608

609 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:

610 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:

611

612 hist_selec =

614 hist_upper, nhist, true);

615 break;

616

617 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:

618 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:

619 case OID_MULTIRANGE_CONTAINS_ELEM_OP:

620

621

622

623

624

625

626

627

628

629

630

631

632

633 hist_selec =

635 &const_lower, hist_upper,

636 nhist, false);

637 hist_selec +=

639 &const_upper, hist_lower,

640 nhist, true));

641 hist_selec = 1.0 - hist_selec;

642 break;

643

644 case OID_MULTIRANGE_CONTAINS_RANGE_OP:

645 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:

646 hist_selec =

648 &const_upper, hist_lower, nhist,

650 break;

651

652 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:

653 case OID_RANGE_MULTIRANGE_CONTAINED_OP:

655 {

656

657

658

659

660 hist_selec =

662 hist_upper, nhist, true);

663 }

664 else if (const_upper.infinite)

665 {

666 hist_selec =

668 hist_lower, nhist, false);

669 }

670 else

671 {

672 hist_selec =

674 &const_upper, hist_lower, nhist,

676 }

677 break;

678

679

680 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:

681 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:

682 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:

683 case OID_RANGE_LEFT_MULTIRANGE_OP:

684 case OID_RANGE_RIGHT_MULTIRANGE_OP:

685 case OID_RANGE_CONTAINS_MULTIRANGE_OP:

686 case OID_MULTIRANGE_ELEM_CONTAINED_OP:

687 case OID_MULTIRANGE_RANGE_CONTAINED_OP:

688

689 default:

690 elog(ERROR, "unknown multirange operator %u", operator);

691 hist_selec = -1.0;

692 break;

693 }

694

697

698 return hist_selec;

699}

700

701

702

703

704

705

706static double

709{

712

713

714

715

716

719

720

721 if (index >= 0 && index < hist_nvalues - 1)

724

725 return selec;

726}

727

728

729

730

731

732

733

734

735

736

737

738static int

740 int hist_length, bool equal)

741{

743 upper = hist_length - 1,

745 middle;

746

748 {

751

754 else

755 upper = middle - 1;

756 }

758}

759

760

761

762

763

764

765

766

767static int

770{

772 upper = length_hist_nvalues - 1,

773 middle;

774

776 {

777 double middleval;

778

780

781 middleval = DatumGetFloat8(length_hist_values[middle]);

784 else

785 upper = middle - 1;

786 }

788}

789

790

791

792

796{

799

801 {

803

804

805

806

807

808

809

810 if (value->infinite)

811 return 0.5;

812

813

814 if (!has_subdiff)

815 return 0.5;

816

817

820 hist2->val,

821 hist1->val));

822 if (isnan(bin_width) || bin_width <= 0.0)

823 return 0.5;

824

828 hist1->val))

829 / bin_width;

830

831 if (isnan(position))

832 return 0.5;

833

834

835 position = Max(position, 0.0);

836 position = Min(position, 1.0);

837 return position;

838 }

840 {

841

842

843

844

845

846

847 return ((value->infinite && value->lower) ? 0.0 : 1.0);

848 }

850 {

851

852 return ((value->infinite && value->lower) ? 1.0 : 0.0);

853 }

854 else

855 {

856

857

858

859

860

861

862

863

864 return 0.5;

865 }

866}

867

868

869

870

871

872static double

874{

875 if (!isinf(hist1) && !isinf(hist2))

876 {

877

878

879

880

881

882 if (isinf(value))

883 return 0.5;

884

885 return 1.0 - (hist2 - value) / (hist2 - hist1);

886 }

887 else if (isinf(hist1) && !isinf(hist2))

888 {

889

890

891

892

893 return 1.0;

894 }

895 else if (isinf(hist1) && isinf(hist2))

896 {

897

898 return 0.0;

899 }

900 else

901 {

902

903

904

905

906

907

908

909

910 return 0.5;

911 }

912}

913

914

915

916

919{

921

923 {

924

925

926

927

928 if (has_subdiff)

929 {

931

934 bound2->val,

935 bound1->val));

936

937 if (isnan(res) || res < 0.0)

938 return 1.0;

939 else

940 return res;

941 }

942 else

943 return 1.0;

944 }

946 {

947

949 return 0.0;

950 else

952 }

953 else

954 {

955

957 }

958}

959

960

961

962

963

964

965static double

967 double length1, double length2, bool equal)

968{

969 double frac;

970 double A,

971 B,

972 PA,

973 PB;

974 double pos;

975 int i;

976 double area;

977

978 Assert(length2 >= length1);

979

980 if (length2 < 0.0)

981 return 0.0;

982

983

984 if (isinf(length2) && equal)

985 return 1.0;

986

987

988

989

990

991

992

993

994

995

996

997

998

999

1000

1001

1002

1003

1004

1005

1006

1007

1008

1009

1010

1011

1012

1013

1014

1015

1016

1017

1018

1019

1020

1021

1022

1023

1024

1025

1027 if (i >= length_hist_nvalues - 1)

1028 return 1.0;

1029

1030 if (i < 0)

1031 {

1032 i = 0;

1033 pos = 0.0;

1034 }

1035 else

1036 {

1037

1041 }

1042 PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1);

1043 B = length1;

1044

1045

1046

1047

1048

1049

1050 if (length2 == length1)

1051 return PB;

1052

1053

1054

1055

1056

1057

1058 area = 0.0;

1059 for (; i < length_hist_nvalues - 1; i++)

1060 {

1061 double bin_upper = DatumGetFloat8(length_hist_values[i + 1]);

1062

1063

1064 if (!(bin_upper < length2 || (equal && bin_upper <= length2)))

1065 break;

1066

1067

1068 A = B;

1069 PA = PB;

1070

1071 B = bin_upper;

1072 PB = (double) i / (double) (length_hist_nvalues - 1);

1073

1074

1075

1076

1077

1078

1079

1080 if (PA > 0 || PB > 0)

1081 area += 0.5 * (PB + PA) * (B - A);

1082 }

1083

1084

1085 A = B;

1086 PA = PB;

1087

1088 B = length2;

1089 if (i >= length_hist_nvalues - 1)

1090 pos = 0.0;

1091 else

1092 {

1094 pos = 0.0;

1095 else

1099 }

1100 PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1);

1101

1102 if (PA > 0 || PB > 0)

1103 area += 0.5 * (PB + PA) * (B - A);

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113 if (isinf(area) && isinf(length2))

1114 frac = 0.5;

1115 else

1116 frac = area / (length2 - length1);

1117

1118 return frac;

1119}

1120

1121

1122

1123

1124

1125

1126

1127

1128

1129

1130static double

1133 const RangeBound *hist_lower, int hist_nvalues,

1134 Datum *length_hist_values, int length_hist_nvalues)

1135{

1136 int i,

1137 upper_index;

1139 double bin_width;

1140 double upper_bin_width;

1141 double sum_frac;

1142

1143

1144

1145

1146

1147

1148 upper->inclusive = upper->inclusive;

1149 upper->lower = true;

1151 false);

1152

1153

1154

1155

1156

1157 if (upper_index < 0)

1158 return 0.0;

1159

1160

1161

1162

1163

1164

1165

1166

1167

1168 upper_index = Min(upper_index, hist_nvalues - 2);

1169

1170

1171

1172

1173

1174

1176 &hist_lower[upper_index],

1177 &hist_lower[upper_index + 1]);

1178

1179

1180

1181

1182

1183

1184

1185

1186

1187

1188 prev_dist = 0.0;

1189 bin_width = upper_bin_width;

1190

1191 sum_frac = 0.0;

1192 for (i = upper_index; i >= 0; i--)

1193 {

1194 double dist;

1195 double length_hist_frac;

1196 bool final_bin = false;

1197

1198

1199

1200

1201

1202

1203

1205 {

1207

1208

1209

1210

1211

1213 &hist_lower[i + 1]);

1214 if (bin_width < 0.0)

1215 bin_width = 0.0;

1216 final_bin = true;

1217 }

1218 else

1220

1221

1222

1223

1224

1226 length_hist_nvalues,

1227 prev_dist, dist, true);

1228

1229

1230

1231

1232

1233 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);

1234

1235 if (final_bin)

1236 break;

1237

1238 bin_width = 1.0;

1239 prev_dist = dist;

1240 }

1241

1242 return sum_frac;

1243}

1244

1245

1246

1247

1248

1249

1250

1251static double

1254 const RangeBound *hist_lower, int hist_nvalues,

1255 Datum *length_hist_values, int length_hist_nvalues)

1256{

1257 int i,

1258 lower_index;

1259 double bin_width,

1260 lower_bin_width;

1261 double sum_frac;

1263

1264

1266 true);

1267

1268

1269

1270

1271

1272 if (lower_index < 0)

1273 return 0.0;

1274

1275

1276

1277

1278

1279

1280

1281

1282

1283 lower_index = Min(lower_index, hist_nvalues - 2);

1284

1285

1286

1287

1288

1289

1290 lower_bin_width = get_position(typcache, lower, &hist_lower[lower_index],

1291 &hist_lower[lower_index + 1]);

1292

1293

1294

1295

1296

1297

1298

1299

1300

1301

1302

1303

1304

1306 sum_frac = 0.0;

1307 bin_width = lower_bin_width;

1308 for (i = lower_index; i >= 0; i--)

1309 {

1311 double length_hist_frac;

1312

1313

1314

1315

1316

1317

1319

1320

1321

1322

1323

1324 length_hist_frac =

1326 length_hist_nvalues,

1327 prev_dist, dist, false);

1328

1329 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);

1330

1331 bin_width = 1.0;

1332 prev_dist = dist;

1333 }

1334

1335 return sum_frac;

1336}

#define OidIsValid(objectId)

bool equal(const void *a, const void *b)

static float8 get_float8_infinity(void)

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

#define PG_RETURN_FLOAT8(x)

#define PG_GETARG_POINTER(n)

#define PG_GETARG_INT32(n)

Assert(PointerIsAligned(start, uint64))

#define HeapTupleIsValid(tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

void free_attstatsslot(AttStatsSlot *sslot)

bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)

Oid get_commutator(Oid opno)

#define ATTSTATSSLOT_NUMBERS

#define ATTSTATSSLOT_VALUES

MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)

void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)

TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)

#define MultirangeIsEmpty(mr)

static MultirangeType * DatumGetMultirangeTypeP(Datum X)

static double calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues, double length1, double length2, bool equal)

static double calc_hist_selectivity_contained(TypeCacheEntry *typcache, const RangeBound *lower, RangeBound *upper, const RangeBound *hist_lower, int hist_nvalues, Datum *length_hist_values, int length_hist_nvalues)

static float8 get_position(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist1, const RangeBound *hist2)

static double calc_hist_selectivity_scalar(TypeCacheEntry *typcache, const RangeBound *constbound, const RangeBound *hist, int hist_nvalues, bool equal)

static double calc_hist_selectivity_contains(TypeCacheEntry *typcache, const RangeBound *lower, const RangeBound *upper, const RangeBound *hist_lower, int hist_nvalues, Datum *length_hist_values, int length_hist_nvalues)

static double calc_multirangesel(TypeCacheEntry *typcache, VariableStatData *vardata, const MultirangeType *constval, Oid operator)

static int length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues, double value, bool equal)

static int rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist, int hist_length, bool equal)

static double calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata, const MultirangeType *constval, Oid operator)

static double default_multirange_selectivity(Oid operator)

static float8 get_len_position(double value, double hist1, double hist2)

Datum multirangesel(PG_FUNCTION_ARGS)

static float8 get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, const RangeBound *bound2)

#define IsA(nodeptr, _type_)

Datum lower(PG_FUNCTION_ARGS)

Datum upper(PG_FUNCTION_ARGS)

FormData_pg_statistic * Form_pg_statistic

static float8 DatumGetFloat8(Datum X)

int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)

RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)

void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)

static RangeType * DatumGetRangeTypeP(Datum X)

static int cmp(const chr *x, const chr *y, size_t len)

bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)

bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid)

#define ReleaseVariableStats(vardata)

#define CLAMP_PROBABILITY(p)

#define DEFAULT_MULTIRANGE_INEQ_SEL

FmgrInfo rng_cmp_proc_finfo

struct TypeCacheEntry * rngelemtype

struct TypeCacheEntry * rngtype

FmgrInfo rng_subdiff_finfo