Since createplan.c no longer cares whether index operators are lossy, it has
no particular need to do get_op_opfamily_properties() while building an indexscan plan. Postpone that lookup until executor start. This simplifies createplan.c a lot more than it complicates nodeIndexscan.c, and makes things more uniform since we already had to do it that way for RowCompare expressions. Should be a bit faster too, at least for plans that aren't re-used many times, since we avoid palloc'ing and perhaps copying the intermediate list data structure.
This commit is contained in:
parent
24558da14a
commit
226837e57e
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.228 2008/03/25 22:42:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.229 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -4175,14 +4175,12 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
||||||
int strategy;
|
int strategy;
|
||||||
Oid lefttype;
|
Oid lefttype;
|
||||||
Oid righttype;
|
Oid righttype;
|
||||||
bool recheck;
|
|
||||||
Oid proc;
|
Oid proc;
|
||||||
|
|
||||||
get_op_opfamily_properties(opno, opfamily,
|
get_op_opfamily_properties(opno, opfamily,
|
||||||
&strategy,
|
&strategy,
|
||||||
&lefttype,
|
&lefttype,
|
||||||
&righttype,
|
&righttype);
|
||||||
&recheck);
|
|
||||||
proc = get_opfamily_proc(opfamily,
|
proc = get_opfamily_proc(opfamily,
|
||||||
lefttype,
|
lefttype,
|
||||||
righttype,
|
righttype,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.26 2008/04/10 22:25:25 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.27 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -276,8 +276,6 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
|
||||||
ExecIndexBuildScanKeys((PlanState *) indexstate,
|
ExecIndexBuildScanKeys((PlanState *) indexstate,
|
||||||
indexstate->biss_RelationDesc,
|
indexstate->biss_RelationDesc,
|
||||||
node->indexqual,
|
node->indexqual,
|
||||||
node->indexstrategy,
|
|
||||||
node->indexsubtype,
|
|
||||||
&indexstate->biss_ScanKeys,
|
&indexstate->biss_ScanKeys,
|
||||||
&indexstate->biss_NumScanKeys,
|
&indexstate->biss_NumScanKeys,
|
||||||
&indexstate->biss_RuntimeKeys,
|
&indexstate->biss_RuntimeKeys,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.127 2008/04/13 19:18:14 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.128 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -576,8 +576,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
|
||||||
ExecIndexBuildScanKeys((PlanState *) indexstate,
|
ExecIndexBuildScanKeys((PlanState *) indexstate,
|
||||||
indexstate->iss_RelationDesc,
|
indexstate->iss_RelationDesc,
|
||||||
node->indexqual,
|
node->indexqual,
|
||||||
node->indexstrategy,
|
|
||||||
node->indexsubtype,
|
|
||||||
&indexstate->iss_ScanKeys,
|
&indexstate->iss_ScanKeys,
|
||||||
&indexstate->iss_NumScanKeys,
|
&indexstate->iss_NumScanKeys,
|
||||||
&indexstate->iss_RuntimeKeys,
|
&indexstate->iss_RuntimeKeys,
|
||||||
|
@ -655,12 +653,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
|
||||||
* planstate: executor state node we are working for
|
* planstate: executor state node we are working for
|
||||||
* index: the index we are building scan keys for
|
* index: the index we are building scan keys for
|
||||||
* quals: indexquals expressions
|
* quals: indexquals expressions
|
||||||
* strategies: associated operator strategy numbers
|
|
||||||
* subtypes: associated operator subtype OIDs
|
|
||||||
*
|
|
||||||
* (Any elements of the strategies and subtypes lists that correspond to
|
|
||||||
* RowCompareExpr quals are not used here; instead we look up the info
|
|
||||||
* afresh.)
|
|
||||||
*
|
*
|
||||||
* Output params are:
|
* Output params are:
|
||||||
*
|
*
|
||||||
|
@ -675,15 +667,12 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
|
||||||
* ScalarArrayOpExpr quals are not supported.
|
* ScalarArrayOpExpr quals are not supported.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
ExecIndexBuildScanKeys(PlanState *planstate, Relation index, List *quals,
|
||||||
List *quals, List *strategies, List *subtypes,
|
|
||||||
ScanKey *scanKeys, int *numScanKeys,
|
ScanKey *scanKeys, int *numScanKeys,
|
||||||
IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys,
|
IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys,
|
||||||
IndexArrayKeyInfo **arrayKeys, int *numArrayKeys)
|
IndexArrayKeyInfo **arrayKeys, int *numArrayKeys)
|
||||||
{
|
{
|
||||||
ListCell *qual_cell;
|
ListCell *qual_cell;
|
||||||
ListCell *strategy_cell;
|
|
||||||
ListCell *subtype_cell;
|
|
||||||
ScanKey scan_keys;
|
ScanKey scan_keys;
|
||||||
IndexRuntimeKeyInfo *runtime_keys;
|
IndexRuntimeKeyInfo *runtime_keys;
|
||||||
IndexArrayKeyInfo *array_keys;
|
IndexArrayKeyInfo *array_keys;
|
||||||
|
@ -725,40 +714,31 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
extra_scan_keys = n_scan_keys;
|
extra_scan_keys = n_scan_keys;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* for each opclause in the given qual, convert each qual's opclause into
|
* for each opclause in the given qual, convert the opclause into
|
||||||
* a single scan key
|
* a single scan key
|
||||||
*/
|
*/
|
||||||
qual_cell = list_head(quals);
|
j = 0;
|
||||||
strategy_cell = list_head(strategies);
|
foreach(qual_cell, quals)
|
||||||
subtype_cell = list_head(subtypes);
|
|
||||||
|
|
||||||
for (j = 0; j < n_scan_keys; j++)
|
|
||||||
{
|
{
|
||||||
ScanKey this_scan_key = &scan_keys[j];
|
Expr *clause = (Expr *) lfirst(qual_cell);
|
||||||
Expr *clause; /* one clause of index qual */
|
ScanKey this_scan_key = &scan_keys[j++];
|
||||||
|
Oid opno; /* operator's OID */
|
||||||
RegProcedure opfuncid; /* operator proc id used in scan */
|
RegProcedure opfuncid; /* operator proc id used in scan */
|
||||||
StrategyNumber strategy; /* op's strategy number */
|
Oid opfamily; /* opfamily of index column */
|
||||||
Oid subtype; /* op's strategy subtype */
|
int op_strategy; /* operator's strategy number */
|
||||||
|
Oid op_lefttype; /* operator's declared input types */
|
||||||
|
Oid op_righttype;
|
||||||
Expr *leftop; /* expr on lhs of operator */
|
Expr *leftop; /* expr on lhs of operator */
|
||||||
Expr *rightop; /* expr on rhs ... */
|
Expr *rightop; /* expr on rhs ... */
|
||||||
AttrNumber varattno; /* att number used in scan */
|
AttrNumber varattno; /* att number used in scan */
|
||||||
|
|
||||||
/*
|
|
||||||
* extract clause information from the qualification
|
|
||||||
*/
|
|
||||||
clause = (Expr *) lfirst(qual_cell);
|
|
||||||
qual_cell = lnext(qual_cell);
|
|
||||||
strategy = lfirst_int(strategy_cell);
|
|
||||||
strategy_cell = lnext(strategy_cell);
|
|
||||||
subtype = lfirst_oid(subtype_cell);
|
|
||||||
subtype_cell = lnext(subtype_cell);
|
|
||||||
|
|
||||||
if (IsA(clause, OpExpr))
|
if (IsA(clause, OpExpr))
|
||||||
{
|
{
|
||||||
/* indexkey op const or indexkey op expression */
|
/* indexkey op const or indexkey op expression */
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
Datum scanvalue;
|
Datum scanvalue;
|
||||||
|
|
||||||
|
opno = ((OpExpr *) clause)->opno;
|
||||||
opfuncid = ((OpExpr *) clause)->opfuncid;
|
opfuncid = ((OpExpr *) clause)->opfuncid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -776,6 +756,19 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
elog(ERROR, "indexqual doesn't have key on left side");
|
elog(ERROR, "indexqual doesn't have key on left side");
|
||||||
|
|
||||||
varattno = ((Var *) leftop)->varattno;
|
varattno = ((Var *) leftop)->varattno;
|
||||||
|
if (varattno < 1 || varattno > index->rd_index->indnatts)
|
||||||
|
elog(ERROR, "bogus index qualification");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to look up the operator's strategy number. This
|
||||||
|
* provides a cross-check that the operator does match the index.
|
||||||
|
*/
|
||||||
|
opfamily = index->rd_opfamily[varattno - 1];
|
||||||
|
|
||||||
|
get_op_opfamily_properties(opno, opfamily,
|
||||||
|
&op_strategy,
|
||||||
|
&op_lefttype,
|
||||||
|
&op_righttype);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rightop is the constant or variable comparison value
|
* rightop is the constant or variable comparison value
|
||||||
|
@ -810,8 +803,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
ScanKeyEntryInitialize(this_scan_key,
|
ScanKeyEntryInitialize(this_scan_key,
|
||||||
flags,
|
flags,
|
||||||
varattno, /* attribute number to scan */
|
varattno, /* attribute number to scan */
|
||||||
strategy, /* op's strategy */
|
op_strategy, /* op's strategy */
|
||||||
subtype, /* strategy subtype */
|
op_righttype, /* strategy subtype */
|
||||||
opfuncid, /* reg proc to use */
|
opfuncid, /* reg proc to use */
|
||||||
scanvalue); /* constant */
|
scanvalue); /* constant */
|
||||||
}
|
}
|
||||||
|
@ -830,12 +823,6 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
ScanKey this_sub_key = &scan_keys[extra_scan_keys];
|
ScanKey this_sub_key = &scan_keys[extra_scan_keys];
|
||||||
int flags = SK_ROW_MEMBER;
|
int flags = SK_ROW_MEMBER;
|
||||||
Datum scanvalue;
|
Datum scanvalue;
|
||||||
Oid opno;
|
|
||||||
Oid opfamily;
|
|
||||||
int op_strategy;
|
|
||||||
Oid op_lefttype;
|
|
||||||
Oid op_righttype;
|
|
||||||
bool op_recheck;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* leftop should be the index key Var, possibly relabeled
|
* leftop should be the index key Var, possibly relabeled
|
||||||
|
@ -897,8 +884,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
get_op_opfamily_properties(opno, opfamily,
|
get_op_opfamily_properties(opno, opfamily,
|
||||||
&op_strategy,
|
&op_strategy,
|
||||||
&op_lefttype,
|
&op_lefttype,
|
||||||
&op_righttype,
|
&op_righttype);
|
||||||
&op_recheck);
|
|
||||||
|
|
||||||
if (op_strategy != rc->rctype)
|
if (op_strategy != rc->rctype)
|
||||||
elog(ERROR, "RowCompare index qualification contains wrong operator");
|
elog(ERROR, "RowCompare index qualification contains wrong operator");
|
||||||
|
@ -941,6 +927,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
|
ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
|
||||||
|
|
||||||
Assert(saop->useOr);
|
Assert(saop->useOr);
|
||||||
|
opno = saop->opno;
|
||||||
opfuncid = saop->opfuncid;
|
opfuncid = saop->opfuncid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -958,6 +945,19 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
elog(ERROR, "indexqual doesn't have key on left side");
|
elog(ERROR, "indexqual doesn't have key on left side");
|
||||||
|
|
||||||
varattno = ((Var *) leftop)->varattno;
|
varattno = ((Var *) leftop)->varattno;
|
||||||
|
if (varattno < 1 || varattno > index->rd_index->indnatts)
|
||||||
|
elog(ERROR, "bogus index qualification");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to look up the operator's strategy number. This
|
||||||
|
* provides a cross-check that the operator does match the index.
|
||||||
|
*/
|
||||||
|
opfamily = index->rd_opfamily[varattno - 1];
|
||||||
|
|
||||||
|
get_op_opfamily_properties(opno, opfamily,
|
||||||
|
&op_strategy,
|
||||||
|
&op_lefttype,
|
||||||
|
&op_righttype);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rightop is the constant or variable array value
|
* rightop is the constant or variable array value
|
||||||
|
@ -981,8 +981,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
ScanKeyEntryInitialize(this_scan_key,
|
ScanKeyEntryInitialize(this_scan_key,
|
||||||
0, /* flags */
|
0, /* flags */
|
||||||
varattno, /* attribute number to scan */
|
varattno, /* attribute number to scan */
|
||||||
strategy, /* op's strategy */
|
op_strategy, /* op's strategy */
|
||||||
subtype, /* strategy subtype */
|
op_righttype, /* strategy subtype */
|
||||||
opfuncid, /* reg proc to use */
|
opfuncid, /* reg proc to use */
|
||||||
(Datum) 0); /* constant */
|
(Datum) 0); /* constant */
|
||||||
}
|
}
|
||||||
|
@ -1013,8 +1013,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
ScanKeyEntryInitialize(this_scan_key,
|
ScanKeyEntryInitialize(this_scan_key,
|
||||||
SK_ISNULL | SK_SEARCHNULL,
|
SK_ISNULL | SK_SEARCHNULL,
|
||||||
varattno, /* attribute number to scan */
|
varattno, /* attribute number to scan */
|
||||||
strategy, /* op's strategy */
|
InvalidStrategy, /* no strategy */
|
||||||
subtype, /* strategy subtype */
|
InvalidOid, /* no strategy subtype */
|
||||||
InvalidOid, /* no reg proc for this */
|
InvalidOid, /* no reg proc for this */
|
||||||
(Datum) 0); /* constant */
|
(Datum) 0); /* constant */
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.90 2008/01/01 19:45:49 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.91 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -180,7 +180,6 @@ MJExamineQuals(List *mergeclauses,
|
||||||
int op_strategy;
|
int op_strategy;
|
||||||
Oid op_lefttype;
|
Oid op_lefttype;
|
||||||
Oid op_righttype;
|
Oid op_righttype;
|
||||||
bool op_recheck;
|
|
||||||
RegProcedure cmpproc;
|
RegProcedure cmpproc;
|
||||||
AclResult aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
|
@ -197,12 +196,10 @@ MJExamineQuals(List *mergeclauses,
|
||||||
get_op_opfamily_properties(qual->opno, opfamily,
|
get_op_opfamily_properties(qual->opno, opfamily,
|
||||||
&op_strategy,
|
&op_strategy,
|
||||||
&op_lefttype,
|
&op_lefttype,
|
||||||
&op_righttype,
|
&op_righttype);
|
||||||
&op_recheck);
|
|
||||||
if (op_strategy != BTEqualStrategyNumber) /* should not happen */
|
if (op_strategy != BTEqualStrategyNumber) /* should not happen */
|
||||||
elog(ERROR, "cannot merge using non-equality operator %u",
|
elog(ERROR, "cannot merge using non-equality operator %u",
|
||||||
qual->opno);
|
qual->opno);
|
||||||
Assert(!op_recheck); /* never true for btree */
|
|
||||||
|
|
||||||
/* And get the matching support procedure (comparison function) */
|
/* And get the matching support procedure (comparison function) */
|
||||||
cmpproc = get_opfamily_proc(opfamily,
|
cmpproc = get_opfamily_proc(opfamily,
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.390 2008/03/21 22:41:48 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.391 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -279,8 +279,6 @@ _copyIndexScan(IndexScan *from)
|
||||||
COPY_SCALAR_FIELD(indexid);
|
COPY_SCALAR_FIELD(indexid);
|
||||||
COPY_NODE_FIELD(indexqual);
|
COPY_NODE_FIELD(indexqual);
|
||||||
COPY_NODE_FIELD(indexqualorig);
|
COPY_NODE_FIELD(indexqualorig);
|
||||||
COPY_NODE_FIELD(indexstrategy);
|
|
||||||
COPY_NODE_FIELD(indexsubtype);
|
|
||||||
COPY_SCALAR_FIELD(indexorderdir);
|
COPY_SCALAR_FIELD(indexorderdir);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
|
@ -305,8 +303,6 @@ _copyBitmapIndexScan(BitmapIndexScan *from)
|
||||||
COPY_SCALAR_FIELD(indexid);
|
COPY_SCALAR_FIELD(indexid);
|
||||||
COPY_NODE_FIELD(indexqual);
|
COPY_NODE_FIELD(indexqual);
|
||||||
COPY_NODE_FIELD(indexqualorig);
|
COPY_NODE_FIELD(indexqualorig);
|
||||||
COPY_NODE_FIELD(indexstrategy);
|
|
||||||
COPY_NODE_FIELD(indexsubtype);
|
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.324 2008/03/21 22:41:48 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.325 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
|
@ -372,8 +372,6 @@ _outIndexScan(StringInfo str, IndexScan *node)
|
||||||
WRITE_OID_FIELD(indexid);
|
WRITE_OID_FIELD(indexid);
|
||||||
WRITE_NODE_FIELD(indexqual);
|
WRITE_NODE_FIELD(indexqual);
|
||||||
WRITE_NODE_FIELD(indexqualorig);
|
WRITE_NODE_FIELD(indexqualorig);
|
||||||
WRITE_NODE_FIELD(indexstrategy);
|
|
||||||
WRITE_NODE_FIELD(indexsubtype);
|
|
||||||
WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
|
WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,8 +385,6 @@ _outBitmapIndexScan(StringInfo str, BitmapIndexScan *node)
|
||||||
WRITE_OID_FIELD(indexid);
|
WRITE_OID_FIELD(indexid);
|
||||||
WRITE_NODE_FIELD(indexqual);
|
WRITE_NODE_FIELD(indexqual);
|
||||||
WRITE_NODE_FIELD(indexqualorig);
|
WRITE_NODE_FIELD(indexqualorig);
|
||||||
WRITE_NODE_FIELD(indexstrategy);
|
|
||||||
WRITE_NODE_FIELD(indexsubtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.228 2008/03/25 22:42:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.229 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -2465,7 +2465,6 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
|
||||||
int op_strategy;
|
int op_strategy;
|
||||||
Oid op_lefttype;
|
Oid op_lefttype;
|
||||||
Oid op_righttype;
|
Oid op_righttype;
|
||||||
bool op_recheck;
|
|
||||||
int matching_cols;
|
int matching_cols;
|
||||||
Oid expr_op;
|
Oid expr_op;
|
||||||
List *opfamilies;
|
List *opfamilies;
|
||||||
|
@ -2488,8 +2487,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
|
||||||
get_op_opfamily_properties(expr_op, index->opfamily[indexcol],
|
get_op_opfamily_properties(expr_op, index->opfamily[indexcol],
|
||||||
&op_strategy,
|
&op_strategy,
|
||||||
&op_lefttype,
|
&op_lefttype,
|
||||||
&op_righttype,
|
&op_righttype);
|
||||||
&op_recheck);
|
|
||||||
/* Build lists of the opfamilies and operator datatypes in case needed */
|
/* Build lists of the opfamilies and operator datatypes in case needed */
|
||||||
opfamilies = list_make1_oid(index->opfamily[indexcol]);
|
opfamilies = list_make1_oid(index->opfamily[indexcol]);
|
||||||
lefttypes = list_make1_oid(op_lefttype);
|
lefttypes = list_make1_oid(op_lefttype);
|
||||||
|
@ -2557,8 +2555,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
|
||||||
get_op_opfamily_properties(expr_op, index->opfamily[i],
|
get_op_opfamily_properties(expr_op, index->opfamily[i],
|
||||||
&op_strategy,
|
&op_strategy,
|
||||||
&op_lefttype,
|
&op_lefttype,
|
||||||
&op_righttype,
|
&op_righttype);
|
||||||
&op_recheck);
|
|
||||||
opfamilies = lappend_oid(opfamilies, index->opfamily[i]);
|
opfamilies = lappend_oid(opfamilies, index->opfamily[i]);
|
||||||
lefttypes = lappend_oid(lefttypes, op_lefttype);
|
lefttypes = lappend_oid(lefttypes, op_lefttype);
|
||||||
righttypes = lappend_oid(righttypes, op_righttype);
|
righttypes = lappend_oid(righttypes, op_righttype);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.238 2008/04/13 19:18:14 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.239 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -67,12 +67,8 @@ static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path,
|
||||||
Plan *outer_plan, Plan *inner_plan);
|
Plan *outer_plan, Plan *inner_plan);
|
||||||
static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path,
|
static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path,
|
||||||
Plan *outer_plan, Plan *inner_plan);
|
Plan *outer_plan, Plan *inner_plan);
|
||||||
static void fix_indexqual_references(List *indexquals, IndexPath *index_path,
|
static List *fix_indexqual_references(List *indexquals, IndexPath *index_path);
|
||||||
List **fixed_indexquals,
|
static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index);
|
||||||
List **indexstrategy,
|
|
||||||
List **indexsubtype);
|
|
||||||
static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index,
|
|
||||||
Oid *opfamily);
|
|
||||||
static List *get_switched_clauses(List *clauses, Relids outerrelids);
|
static List *get_switched_clauses(List *clauses, Relids outerrelids);
|
||||||
static List *order_qual_clauses(PlannerInfo *root, List *clauses);
|
static List *order_qual_clauses(PlannerInfo *root, List *clauses);
|
||||||
static void copy_path_costsize(Plan *dest, Path *src);
|
static void copy_path_costsize(Plan *dest, Path *src);
|
||||||
|
@ -80,13 +76,10 @@ static void copy_plan_costsize(Plan *dest, Plan *src);
|
||||||
static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
|
static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
|
||||||
static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
|
static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
|
||||||
Oid indexid, List *indexqual, List *indexqualorig,
|
Oid indexid, List *indexqual, List *indexqualorig,
|
||||||
List *indexstrategy, List *indexsubtype,
|
|
||||||
ScanDirection indexscandir);
|
ScanDirection indexscandir);
|
||||||
static BitmapIndexScan *make_bitmap_indexscan(Index scanrelid, Oid indexid,
|
static BitmapIndexScan *make_bitmap_indexscan(Index scanrelid, Oid indexid,
|
||||||
List *indexqual,
|
List *indexqual,
|
||||||
List *indexqualorig,
|
List *indexqualorig);
|
||||||
List *indexstrategy,
|
|
||||||
List *indexsubtype);
|
|
||||||
static BitmapHeapScan *make_bitmap_heapscan(List *qptlist,
|
static BitmapHeapScan *make_bitmap_heapscan(List *qptlist,
|
||||||
List *qpqual,
|
List *qpqual,
|
||||||
Plan *lefttree,
|
Plan *lefttree,
|
||||||
|
@ -850,8 +843,6 @@ create_indexscan_plan(PlannerInfo *root,
|
||||||
List *qpqual;
|
List *qpqual;
|
||||||
List *stripped_indexquals;
|
List *stripped_indexquals;
|
||||||
List *fixed_indexquals;
|
List *fixed_indexquals;
|
||||||
List *indexstrategy;
|
|
||||||
List *indexsubtype;
|
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
IndexScan *scan_plan;
|
IndexScan *scan_plan;
|
||||||
|
|
||||||
|
@ -867,13 +858,9 @@ create_indexscan_plan(PlannerInfo *root,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The executor needs a copy with the indexkey on the left of each clause
|
* The executor needs a copy with the indexkey on the left of each clause
|
||||||
* and with index attr numbers substituted for table ones. This pass also
|
* and with index attr numbers substituted for table ones.
|
||||||
* gets strategy info.
|
|
||||||
*/
|
*/
|
||||||
fix_indexqual_references(indexquals, best_path,
|
fixed_indexquals = fix_indexqual_references(indexquals, best_path);
|
||||||
&fixed_indexquals,
|
|
||||||
&indexstrategy,
|
|
||||||
&indexsubtype);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is an innerjoin scan, the indexclauses will contain join
|
* If this is an innerjoin scan, the indexclauses will contain join
|
||||||
|
@ -951,8 +938,6 @@ create_indexscan_plan(PlannerInfo *root,
|
||||||
indexoid,
|
indexoid,
|
||||||
fixed_indexquals,
|
fixed_indexquals,
|
||||||
stripped_indexquals,
|
stripped_indexquals,
|
||||||
indexstrategy,
|
|
||||||
indexsubtype,
|
|
||||||
best_path->indexscandir);
|
best_path->indexscandir);
|
||||||
|
|
||||||
copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
|
copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
|
||||||
|
@ -1193,9 +1178,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
|
||||||
plan = (Plan *) make_bitmap_indexscan(iscan->scan.scanrelid,
|
plan = (Plan *) make_bitmap_indexscan(iscan->scan.scanrelid,
|
||||||
iscan->indexid,
|
iscan->indexid,
|
||||||
iscan->indexqual,
|
iscan->indexqual,
|
||||||
iscan->indexqualorig,
|
iscan->indexqualorig);
|
||||||
iscan->indexstrategy,
|
|
||||||
iscan->indexsubtype);
|
|
||||||
plan->startup_cost = 0.0;
|
plan->startup_cost = 0.0;
|
||||||
plan->total_cost = ipath->indextotalcost;
|
plan->total_cost = ipath->indextotalcost;
|
||||||
plan->plan_rows =
|
plan->plan_rows =
|
||||||
|
@ -1757,52 +1740,36 @@ create_hashjoin_plan(PlannerInfo *root,
|
||||||
* Adjust indexqual clauses to the form the executor's indexqual
|
* Adjust indexqual clauses to the form the executor's indexqual
|
||||||
* machinery needs.
|
* machinery needs.
|
||||||
*
|
*
|
||||||
* We have four tasks here:
|
* We have three tasks here:
|
||||||
* * Remove RestrictInfo nodes from the input clauses.
|
* * Remove RestrictInfo nodes from the input clauses.
|
||||||
* * Index keys must be represented by Var nodes with varattno set to the
|
* * Index keys must be represented by Var nodes with varattno set to the
|
||||||
* index's attribute number, not the attribute number in the original rel.
|
* index's attribute number, not the attribute number in the original rel.
|
||||||
* * If the index key is on the right, commute the clause to put it on the
|
* * If the index key is on the right, commute the clause to put it on the
|
||||||
* left.
|
* left.
|
||||||
* * We must construct lists of operator strategy numbers and subtypes
|
|
||||||
* for the top-level operators of each index clause.
|
|
||||||
*
|
*
|
||||||
* fixed_indexquals receives a modified copy of the indexquals list --- the
|
* The result is a modified copy of the indexquals list --- the
|
||||||
* original is not changed. Note also that the copy shares no substructure
|
* original is not changed. Note also that the copy shares no substructure
|
||||||
* with the original; this is needed in case there is a subplan in it (we need
|
* with the original; this is needed in case there is a subplan in it (we need
|
||||||
* two separate copies of the subplan tree, or things will go awry).
|
* two separate copies of the subplan tree, or things will go awry).
|
||||||
*
|
|
||||||
* indexstrategy receives an integer list of strategy numbers.
|
|
||||||
* indexsubtype receives an OID list of strategy subtypes.
|
|
||||||
*/
|
*/
|
||||||
static void
|
static List *
|
||||||
fix_indexqual_references(List *indexquals, IndexPath *index_path,
|
fix_indexqual_references(List *indexquals, IndexPath *index_path)
|
||||||
List **fixed_indexquals,
|
|
||||||
List **indexstrategy,
|
|
||||||
List **indexsubtype)
|
|
||||||
{
|
{
|
||||||
IndexOptInfo *index = index_path->indexinfo;
|
IndexOptInfo *index = index_path->indexinfo;
|
||||||
|
List *fixed_indexquals;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
|
||||||
*fixed_indexquals = NIL;
|
fixed_indexquals = NIL;
|
||||||
*indexstrategy = NIL;
|
|
||||||
*indexsubtype = NIL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For each qual clause, commute if needed to put the indexkey operand on
|
* For each qual clause, commute if needed to put the indexkey operand on
|
||||||
* the left, and then fix its varattno. (We do not need to change the
|
* the left, and then fix its varattno. (We do not need to change the
|
||||||
* other side of the clause.) Then determine the operator's strategy
|
* other side of the clause.)
|
||||||
* number and subtype number.
|
|
||||||
*/
|
*/
|
||||||
foreach(l, indexquals)
|
foreach(l, indexquals)
|
||||||
{
|
{
|
||||||
RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
|
RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
|
||||||
Expr *clause;
|
Expr *clause;
|
||||||
Oid clause_op;
|
|
||||||
Oid opfamily;
|
|
||||||
int stratno;
|
|
||||||
Oid stratlefttype;
|
|
||||||
Oid stratrighttype;
|
|
||||||
bool is_null_op = false;
|
|
||||||
|
|
||||||
Assert(IsA(rinfo, RestrictInfo));
|
Assert(IsA(rinfo, RestrictInfo));
|
||||||
|
|
||||||
|
@ -1831,13 +1798,11 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
|
||||||
CommuteOpExpr(op);
|
CommuteOpExpr(op);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now, determine which index attribute this is, change the
|
* Now, determine which index attribute this is and change the
|
||||||
* indexkey operand as needed, and get the index opfamily.
|
* indexkey operand as needed.
|
||||||
*/
|
*/
|
||||||
linitial(op->args) = fix_indexqual_operand(linitial(op->args),
|
linitial(op->args) = fix_indexqual_operand(linitial(op->args),
|
||||||
index,
|
index);
|
||||||
&opfamily);
|
|
||||||
clause_op = op->opno;
|
|
||||||
}
|
}
|
||||||
else if (IsA(clause, RowCompareExpr))
|
else if (IsA(clause, RowCompareExpr))
|
||||||
{
|
{
|
||||||
|
@ -1856,23 +1821,12 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
|
||||||
/*
|
/*
|
||||||
* For each column in the row comparison, determine which index
|
* For each column in the row comparison, determine which index
|
||||||
* attribute this is and change the indexkey operand as needed.
|
* attribute this is and change the indexkey operand as needed.
|
||||||
*
|
|
||||||
* Save the index opfamily for only the first column. We will
|
|
||||||
* return the operator and opfamily info for just the first column
|
|
||||||
* of the row comparison; the executor will have to look up the
|
|
||||||
* rest if it needs them.
|
|
||||||
*/
|
*/
|
||||||
foreach(lc, rc->largs)
|
foreach(lc, rc->largs)
|
||||||
{
|
{
|
||||||
Oid tmp_opfamily;
|
|
||||||
|
|
||||||
lfirst(lc) = fix_indexqual_operand(lfirst(lc),
|
lfirst(lc) = fix_indexqual_operand(lfirst(lc),
|
||||||
index,
|
index);
|
||||||
&tmp_opfamily);
|
|
||||||
if (lc == list_head(rc->largs))
|
|
||||||
opfamily = tmp_opfamily;
|
|
||||||
}
|
}
|
||||||
clause_op = linitial_oid(rc->opnos);
|
|
||||||
}
|
}
|
||||||
else if (IsA(clause, ScalarArrayOpExpr))
|
else if (IsA(clause, ScalarArrayOpExpr))
|
||||||
{
|
{
|
||||||
|
@ -1881,13 +1835,11 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
|
||||||
/* Never need to commute... */
|
/* Never need to commute... */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now, determine which index attribute this is, change the
|
* Determine which index attribute this is and change the
|
||||||
* indexkey operand as needed, and get the index opfamily.
|
* indexkey operand as needed.
|
||||||
*/
|
*/
|
||||||
linitial(saop->args) = fix_indexqual_operand(linitial(saop->args),
|
linitial(saop->args) = fix_indexqual_operand(linitial(saop->args),
|
||||||
index,
|
index);
|
||||||
&opfamily);
|
|
||||||
clause_op = saop->opno;
|
|
||||||
}
|
}
|
||||||
else if (IsA(clause, NullTest))
|
else if (IsA(clause, NullTest))
|
||||||
{
|
{
|
||||||
|
@ -1895,49 +1847,20 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
|
||||||
|
|
||||||
Assert(nt->nulltesttype == IS_NULL);
|
Assert(nt->nulltesttype == IS_NULL);
|
||||||
nt->arg = (Expr *) fix_indexqual_operand((Node *) nt->arg,
|
nt->arg = (Expr *) fix_indexqual_operand((Node *) nt->arg,
|
||||||
index,
|
index);
|
||||||
&opfamily);
|
|
||||||
is_null_op = true;
|
|
||||||
clause_op = InvalidOid; /* keep compiler quiet */
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
elog(ERROR, "unsupported indexqual type: %d",
|
elog(ERROR, "unsupported indexqual type: %d",
|
||||||
(int) nodeTag(clause));
|
(int) nodeTag(clause));
|
||||||
continue; /* keep compiler quiet */
|
|
||||||
|
fixed_indexquals = lappend(fixed_indexquals, clause);
|
||||||
}
|
}
|
||||||
|
|
||||||
*fixed_indexquals = lappend(*fixed_indexquals, clause);
|
return fixed_indexquals;
|
||||||
|
|
||||||
if (is_null_op)
|
|
||||||
{
|
|
||||||
/* IS NULL doesn't have a clause_op */
|
|
||||||
stratno = InvalidStrategy;
|
|
||||||
stratrighttype = InvalidOid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Look up the (possibly commuted) operator in the operator family
|
|
||||||
* to get its strategy number and the recheck indicator. This also
|
|
||||||
* double-checks that we found an operator matching the index.
|
|
||||||
*/
|
|
||||||
bool recheck;
|
|
||||||
|
|
||||||
get_op_opfamily_properties(clause_op, opfamily,
|
|
||||||
&stratno,
|
|
||||||
&stratlefttype,
|
|
||||||
&stratrighttype,
|
|
||||||
&recheck);
|
|
||||||
}
|
|
||||||
|
|
||||||
*indexstrategy = lappend_int(*indexstrategy, stratno);
|
|
||||||
*indexsubtype = lappend_oid(*indexsubtype, stratrighttype);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node *
|
static Node *
|
||||||
fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opfamily)
|
fix_indexqual_operand(Node *node, IndexOptInfo *index)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We represent index keys by Var nodes having the varno of the base table
|
* We represent index keys by Var nodes having the varno of the base table
|
||||||
|
@ -1970,8 +1893,6 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opfamily)
|
||||||
{
|
{
|
||||||
result = (Var *) copyObject(node);
|
result = (Var *) copyObject(node);
|
||||||
result->varattno = pos + 1;
|
result->varattno = pos + 1;
|
||||||
/* return the correct opfamily, too */
|
|
||||||
*opfamily = index->opfamily[pos];
|
|
||||||
return (Node *) result;
|
return (Node *) result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1997,8 +1918,6 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opfamily)
|
||||||
result = makeVar(index->rel->relid, pos + 1,
|
result = makeVar(index->rel->relid, pos + 1,
|
||||||
exprType(lfirst(indexpr_item)), -1,
|
exprType(lfirst(indexpr_item)), -1,
|
||||||
0);
|
0);
|
||||||
/* return the correct opfamily, too */
|
|
||||||
*opfamily = index->opfamily[pos];
|
|
||||||
return (Node *) result;
|
return (Node *) result;
|
||||||
}
|
}
|
||||||
indexpr_item = lnext(indexpr_item);
|
indexpr_item = lnext(indexpr_item);
|
||||||
|
@ -2007,8 +1926,7 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opfamily)
|
||||||
|
|
||||||
/* Ooops... */
|
/* Ooops... */
|
||||||
elog(ERROR, "node is not an index attribute");
|
elog(ERROR, "node is not an index attribute");
|
||||||
*opfamily = InvalidOid; /* keep compiler quiet */
|
return NULL; /* keep compiler quiet */
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2229,8 +2147,6 @@ make_indexscan(List *qptlist,
|
||||||
Oid indexid,
|
Oid indexid,
|
||||||
List *indexqual,
|
List *indexqual,
|
||||||
List *indexqualorig,
|
List *indexqualorig,
|
||||||
List *indexstrategy,
|
|
||||||
List *indexsubtype,
|
|
||||||
ScanDirection indexscandir)
|
ScanDirection indexscandir)
|
||||||
{
|
{
|
||||||
IndexScan *node = makeNode(IndexScan);
|
IndexScan *node = makeNode(IndexScan);
|
||||||
|
@ -2245,8 +2161,6 @@ make_indexscan(List *qptlist,
|
||||||
node->indexid = indexid;
|
node->indexid = indexid;
|
||||||
node->indexqual = indexqual;
|
node->indexqual = indexqual;
|
||||||
node->indexqualorig = indexqualorig;
|
node->indexqualorig = indexqualorig;
|
||||||
node->indexstrategy = indexstrategy;
|
|
||||||
node->indexsubtype = indexsubtype;
|
|
||||||
node->indexorderdir = indexscandir;
|
node->indexorderdir = indexscandir;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
@ -2256,9 +2170,7 @@ static BitmapIndexScan *
|
||||||
make_bitmap_indexscan(Index scanrelid,
|
make_bitmap_indexscan(Index scanrelid,
|
||||||
Oid indexid,
|
Oid indexid,
|
||||||
List *indexqual,
|
List *indexqual,
|
||||||
List *indexqualorig,
|
List *indexqualorig)
|
||||||
List *indexstrategy,
|
|
||||||
List *indexsubtype)
|
|
||||||
{
|
{
|
||||||
BitmapIndexScan *node = makeNode(BitmapIndexScan);
|
BitmapIndexScan *node = makeNode(BitmapIndexScan);
|
||||||
Plan *plan = &node->scan.plan;
|
Plan *plan = &node->scan.plan;
|
||||||
|
@ -2272,8 +2184,6 @@ make_bitmap_indexscan(Index scanrelid,
|
||||||
node->indexid = indexid;
|
node->indexid = indexid;
|
||||||
node->indexqual = indexqual;
|
node->indexqual = indexqual;
|
||||||
node->indexqualorig = indexqualorig;
|
node->indexqualorig = indexqualorig;
|
||||||
node->indexstrategy = indexstrategy;
|
|
||||||
node->indexsubtype = indexsubtype;
|
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.247 2008/03/25 22:42:44 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.248 2008/04/13 20:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -2275,7 +2275,6 @@ mergejoinscansel(PlannerInfo *root, Node *clause,
|
||||||
int op_strategy;
|
int op_strategy;
|
||||||
Oid op_lefttype;
|
Oid op_lefttype;
|
||||||
Oid op_righttype;
|
Oid op_righttype;
|
||||||
bool op_recheck;
|
|
||||||
Oid opno,
|
Oid opno,
|
||||||
lsortop,
|
lsortop,
|
||||||
rsortop,
|
rsortop,
|
||||||
|
@ -2314,10 +2313,8 @@ mergejoinscansel(PlannerInfo *root, Node *clause,
|
||||||
get_op_opfamily_properties(opno, opfamily,
|
get_op_opfamily_properties(opno, opfamily,
|
||||||
&op_strategy,
|
&op_strategy,
|
||||||
&op_lefttype,
|
&op_lefttype,
|
||||||
&op_righttype,
|
&op_righttype);
|
||||||
&op_recheck);
|
|
||||||
Assert(op_strategy == BTEqualStrategyNumber);
|
Assert(op_strategy == BTEqualStrategyNumber);
|
||||||
Assert(!op_recheck);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up the various operators we need. If we don't find them all, it
|
* Look up the various operators we need. If we don't find them all, it
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.156 2008/03/25 22:42:44 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.157 2008/04/13 20:51:21 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
|
@ -80,8 +80,8 @@ get_op_opfamily_strategy(Oid opno, Oid opfamily)
|
||||||
/*
|
/*
|
||||||
* get_op_opfamily_properties
|
* get_op_opfamily_properties
|
||||||
*
|
*
|
||||||
* Get the operator's strategy number, input types, and recheck (lossy)
|
* Get the operator's strategy number and declared input data types
|
||||||
* flag within the specified opfamily.
|
* within the specified opfamily.
|
||||||
*
|
*
|
||||||
* Caller should already have verified that opno is a member of opfamily,
|
* Caller should already have verified that opno is a member of opfamily,
|
||||||
* therefore we raise an error if the tuple is not found.
|
* therefore we raise an error if the tuple is not found.
|
||||||
|
@ -90,8 +90,7 @@ void
|
||||||
get_op_opfamily_properties(Oid opno, Oid opfamily,
|
get_op_opfamily_properties(Oid opno, Oid opfamily,
|
||||||
int *strategy,
|
int *strategy,
|
||||||
Oid *lefttype,
|
Oid *lefttype,
|
||||||
Oid *righttype,
|
Oid *righttype)
|
||||||
bool *recheck)
|
|
||||||
{
|
{
|
||||||
HeapTuple tp;
|
HeapTuple tp;
|
||||||
Form_pg_amop amop_tup;
|
Form_pg_amop amop_tup;
|
||||||
|
@ -107,7 +106,6 @@ get_op_opfamily_properties(Oid opno, Oid opfamily,
|
||||||
*strategy = amop_tup->amopstrategy;
|
*strategy = amop_tup->amopstrategy;
|
||||||
*lefttype = amop_tup->amoplefttype;
|
*lefttype = amop_tup->amoplefttype;
|
||||||
*righttype = amop_tup->amoprighttype;
|
*righttype = amop_tup->amoprighttype;
|
||||||
*recheck = amop_tup->amopreqcheck;
|
|
||||||
ReleaseSysCache(tp);
|
ReleaseSysCache(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/executor/nodeIndexscan.h,v 1.31 2008/01/01 19:45:57 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/executor/nodeIndexscan.h,v 1.32 2008/04/13 20:51:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -26,8 +26,7 @@ extern void ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt);
|
||||||
|
|
||||||
/* routines exported to share code with nodeBitmapIndexscan.c */
|
/* routines exported to share code with nodeBitmapIndexscan.c */
|
||||||
extern void ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
extern void ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
|
||||||
List *quals, List *strategies, List *subtypes,
|
List *quals, ScanKey *scanKeys, int *numScanKeys,
|
||||||
ScanKey *scanKeys, int *numScanKeys,
|
|
||||||
IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys,
|
IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys,
|
||||||
IndexArrayKeyInfo **arrayKeys, int *numArrayKeys);
|
IndexArrayKeyInfo **arrayKeys, int *numArrayKeys);
|
||||||
extern void ExecIndexEvalRuntimeKeys(ExprContext *econtext,
|
extern void ExecIndexEvalRuntimeKeys(ExprContext *econtext,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.99 2008/01/01 19:45:58 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.100 2008/04/13 20:51:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -241,10 +241,6 @@ typedef Scan SeqScan;
|
||||||
* table). This is a bit hokey ... would be cleaner to use a special-purpose
|
* table). This is a bit hokey ... would be cleaner to use a special-purpose
|
||||||
* node type that could not be mistaken for a regular Var. But it will do
|
* node type that could not be mistaken for a regular Var. But it will do
|
||||||
* for now.
|
* for now.
|
||||||
*
|
|
||||||
* indexstrategy and indexsubtype are lists corresponding one-to-one with
|
|
||||||
* indexqual; they give information about the indexable operators that appear
|
|
||||||
* at the top of each indexqual.
|
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
typedef struct IndexScan
|
typedef struct IndexScan
|
||||||
|
@ -253,8 +249,6 @@ typedef struct IndexScan
|
||||||
Oid indexid; /* OID of index to scan */
|
Oid indexid; /* OID of index to scan */
|
||||||
List *indexqual; /* list of index quals (OpExprs) */
|
List *indexqual; /* list of index quals (OpExprs) */
|
||||||
List *indexqualorig; /* the same in original form */
|
List *indexqualorig; /* the same in original form */
|
||||||
List *indexstrategy; /* integer list of strategy numbers */
|
|
||||||
List *indexsubtype; /* OID list of strategy subtypes */
|
|
||||||
ScanDirection indexorderdir; /* forward or backward or don't care */
|
ScanDirection indexorderdir; /* forward or backward or don't care */
|
||||||
} IndexScan;
|
} IndexScan;
|
||||||
|
|
||||||
|
@ -281,8 +275,6 @@ typedef struct BitmapIndexScan
|
||||||
Oid indexid; /* OID of index to scan */
|
Oid indexid; /* OID of index to scan */
|
||||||
List *indexqual; /* list of index quals (OpExprs) */
|
List *indexqual; /* list of index quals (OpExprs) */
|
||||||
List *indexqualorig; /* the same in original form */
|
List *indexqualorig; /* the same in original form */
|
||||||
List *indexstrategy; /* integer list of strategy numbers */
|
|
||||||
List *indexsubtype; /* OID list of strategy subtypes */
|
|
||||||
} BitmapIndexScan;
|
} BitmapIndexScan;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.122 2008/01/01 19:45:59 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.123 2008/04/13 20:51:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -31,8 +31,7 @@ extern int get_op_opfamily_strategy(Oid opno, Oid opfamily);
|
||||||
extern void get_op_opfamily_properties(Oid opno, Oid opfamily,
|
extern void get_op_opfamily_properties(Oid opno, Oid opfamily,
|
||||||
int *strategy,
|
int *strategy,
|
||||||
Oid *lefttype,
|
Oid *lefttype,
|
||||||
Oid *righttype,
|
Oid *righttype);
|
||||||
bool *recheck);
|
|
||||||
extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
|
extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
|
||||||
int16 strategy);
|
int16 strategy);
|
||||||
extern bool get_ordering_op_properties(Oid opno,
|
extern bool get_ordering_op_properties(Oid opno,
|
||||||
|
|
Loading…
Reference in New Issue