Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4d1b76e

Browse files
committed
Fix up gincostestimate for new extractQuery API.
The only reason this wasn't crashing while testing the core anyarray operators was that it was disabled for those cases because of passing the wrong type information to get_opfamily_proc :-(. So fix that too, and make it insist on finding the support proc --- in hindsight, silently doing nothing is not as sane a coping mechanism as all that.
1 parent 833a2b5 commit 4d1b76e

File tree

1 file changed

+43
-22
lines changed

1 file changed

+43
-22
lines changed

src/backend/utils/adt/selfuncs.c

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6281,14 +6281,14 @@ gincostestimate(PG_FUNCTION_ARGS)
62816281
Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(7);
62826282
double *indexCorrelation = (double *) PG_GETARG_POINTER(8);
62836283
ListCell *l;
6284-
int32 nfullscan = 0;
62856284
List *selectivityQuals;
62866285
double numPages = index->pages,
62876286
numTuples = index->tuples;
62886287
double numEntryPages,
62896288
numDataPages,
62906289
numPendingPages,
62916290
numEntries;
6291+
bool haveFullScan = false;
62926292
double partialEntriesInQuals = 0.0;
62936293
double searchEntriesInQuals = 0.0;
62946294
double exactEntriesInQuals = 0.0;
@@ -6394,6 +6394,8 @@ gincostestimate(PG_FUNCTION_ARGS)
63946394
int32 nentries = 0;
63956395
bool *partial_matches = NULL;
63966396
Pointer *extra_data = NULL;
6397+
bool *nullFlags = NULL;
6398+
int32 searchMode = GIN_SEARCH_MODE_DEFAULT;
63976399
int indexcol;
63986400

63996401
Assert(IsA(rinfo, RestrictInfo));
@@ -6414,7 +6416,7 @@ gincostestimate(PG_FUNCTION_ARGS)
64146416
}
64156417
else
64166418
{
6417-
elog(ERROR, "Could not match index to operand");
6419+
elog(ERROR, "could not match index to operand");
64186420
operand = NULL; /* keep compiler quiet */
64196421
}
64206422

@@ -6443,50 +6445,51 @@ gincostestimate(PG_FUNCTION_ARGS)
64436445

64446446
/*
64456447
* Get the operator's strategy number and declared input data types
6446-
* within the index opfamily.
6448+
* within the index opfamily. (We don't need the latter, but we
6449+
* use get_op_opfamily_properties because it will throw error if
6450+
* it fails to find a matching pg_amop entry.)
64476451
*/
64486452
get_op_opfamily_properties(clause_op, index->opfamily[indexcol], false,
64496453
&strategy_op, &lefttype, &righttype);
64506454

64516455
/*
6452-
* GIN (like GiST) always has lefttype == righttype in pg_amproc
6453-
* and they are equal to type Oid on which index was created/designed
6456+
* GIN always uses the "default" support functions, which are those
6457+
* with lefttype == righttype == the opclass' opcintype (see
6458+
* IndexSupportInitialize in relcache.c).
64546459
*/
64556460
extractProcOid = get_opfamily_proc(index->opfamily[indexcol],
6456-
lefttype, lefttype,
6461+
index->opcintype[indexcol],
6462+
index->opcintype[indexcol],
64576463
GIN_EXTRACTQUERY_PROC);
64586464

64596465
if (!OidIsValid(extractProcOid))
64606466
{
6461-
/* probably shouldn't happen, but cope sanely if so */
6462-
searchEntriesInQuals++;
6463-
continue;
6467+
/* should not happen; throw same error as index_getprocinfo */
6468+
elog(ERROR, "missing support function %d for attribute %d of index \"%s\"",
6469+
GIN_EXTRACTQUERY_PROC, indexcol+1,
6470+
get_rel_name(index->indexoid));
64646471
}
64656472

6466-
OidFunctionCall5(extractProcOid,
6467-
((Const*)operand)->constvalue,
6473+
OidFunctionCall7(extractProcOid,
6474+
((Const*) operand)->constvalue,
64686475
PointerGetDatum(&nentries),
64696476
UInt16GetDatum(strategy_op),
64706477
PointerGetDatum(&partial_matches),
6471-
PointerGetDatum(&extra_data));
6478+
PointerGetDatum(&extra_data),
6479+
PointerGetDatum(&nullFlags),
6480+
PointerGetDatum(&searchMode));
64726481

6473-
if (nentries == 0)
6474-
{
6475-
nfullscan++;
6476-
}
6477-
else if (nentries < 0)
6482+
if (nentries <= 0 && searchMode == GIN_SEARCH_MODE_DEFAULT)
64786483
{
6479-
/*
6480-
* GIN_EXTRACTQUERY_PROC guarantees that nothing will be found
6481-
*/
6484+
/* No match is possible */
64826485
*indexStartupCost = 0;
64836486
*indexTotalCost = 0;
64846487
*indexSelectivity = 0;
64856488
PG_RETURN_VOID();
64866489
}
64876490
else
64886491
{
6489-
int i;
6492+
int32 i;
64906493

64916494
for (i=0; i<nentries; i++)
64926495
{
@@ -6503,10 +6506,28 @@ gincostestimate(PG_FUNCTION_ARGS)
65036506
searchEntriesInQuals++;
65046507
}
65056508
}
6509+
6510+
if (searchMode == GIN_SEARCH_MODE_INCLUDE_EMPTY)
6511+
{
6512+
/* Treat "include empty" like an exact-match item */
6513+
exactEntriesInQuals++;
6514+
searchEntriesInQuals++;
6515+
}
6516+
else if (searchMode != GIN_SEARCH_MODE_DEFAULT)
6517+
{
6518+
/* It's GIN_SEARCH_MODE_ALL */
6519+
haveFullScan = true;
6520+
}
65066521
}
65076522

6508-
if (nfullscan == list_length(indexQuals))
6523+
if (haveFullScan || indexQuals == NIL)
6524+
{
6525+
/*
6526+
* Full index scan will be required. We treat this as if every key in
6527+
* the index had been listed in the query; is that reasonable?
6528+
*/
65096529
searchEntriesInQuals = numEntries;
6530+
}
65106531

65116532
/* Will we have more than one iteration of a nestloop scan? */
65126533
if (outer_rel != NULL && outer_rel->rows > 1)

0 commit comments

Comments
 (0)