@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / executor / nodeIndexscan . c , v 1.132 .2 .1 2009 / 07 / 18 19 : 15 : 50 tgl Exp $
* $ PostgreSQL : pgsql / src / backend / executor / nodeIndexscan . c , v 1.132 .2 .2 2009 / 08 / 23 18 : 26 : 15 tgl Exp $
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
@ -238,6 +238,10 @@ ExecIndexEvalRuntimeKeys(ExprContext *econtext,
IndexRuntimeKeyInfo * runtimeKeys , int numRuntimeKeys )
IndexRuntimeKeyInfo * runtimeKeys , int numRuntimeKeys )
{
{
int j ;
int j ;
MemoryContext oldContext ;
/* We want to keep the key values in per-tuple memory */
oldContext = MemoryContextSwitchTo ( econtext - > ecxt_per_tuple_memory ) ;
for ( j = 0 ; j < numRuntimeKeys ; j + + )
for ( j = 0 ; j < numRuntimeKeys ; j + + )
{
{
@ -256,18 +260,32 @@ ExecIndexEvalRuntimeKeys(ExprContext *econtext,
* econtext - > ecxt_per_tuple_memory . We assume that the outer tuple
* econtext - > ecxt_per_tuple_memory . We assume that the outer tuple
* will stay put throughout our scan . If this is wrong , we could copy
* will stay put throughout our scan . If this is wrong , we could copy
* the result into our context explicitly , but I think that ' s not
* the result into our context explicitly , but I think that ' s not
* necessary . . .
* necessary .
*
* It ' s also entirely possible that the result of the eval is a
* toasted value . In this case we should forcibly detoast it ,
* to avoid repeat detoastings each time the value is examined
* by an index support function .
*/
*/
scanvalue = ExecEvalExprSwitchContext ( key_expr ,
scanvalue = ExecEvalExpr ( key_expr ,
econtext ,
econtext ,
& isNull ,
& isNull ,
NULL ) ;
NULL ) ;
scan_key - > sk_argument = scanvalue ;
if ( isNull )
if ( isNull )
{
scan_key - > sk_argument = scanvalue ;
scan_key - > sk_flags | = SK_ISNULL ;
scan_key - > sk_flags | = SK_ISNULL ;
}
else
else
{
if ( runtimeKeys [ j ] . key_toastable )
scanvalue = PointerGetDatum ( PG_DETOAST_DATUM ( scanvalue ) ) ;
scan_key - > sk_argument = scanvalue ;
scan_key - > sk_flags & = ~ SK_ISNULL ;
scan_key - > sk_flags & = ~ SK_ISNULL ;
}
}
}
MemoryContextSwitchTo ( oldContext ) ;
}
}
/*
/*
@ -795,6 +813,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Index scanrelid,
runtime_keys [ n_runtime_keys ] . scan_key = this_scan_key ;
runtime_keys [ n_runtime_keys ] . scan_key = this_scan_key ;
runtime_keys [ n_runtime_keys ] . key_expr =
runtime_keys [ n_runtime_keys ] . key_expr =
ExecInitExpr ( rightop , planstate ) ;
ExecInitExpr ( rightop , planstate ) ;
runtime_keys [ n_runtime_keys ] . key_toastable =
TypeIsToastable ( op_righttype ) ;
n_runtime_keys + + ;
n_runtime_keys + + ;
scanvalue = ( Datum ) 0 ;
scanvalue = ( Datum ) 0 ;
}
}
@ -843,6 +863,31 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Index scanrelid,
varattno = ( ( Var * ) leftop ) - > varattno ;
varattno = ( ( Var * ) leftop ) - > varattno ;
/*
* We have to look up the operator ' s associated btree support
* function
*/
opno = lfirst_oid ( opnos_cell ) ;
opnos_cell = lnext ( opnos_cell ) ;
if ( index - > rd_rel - > relam ! = BTREE_AM_OID | |
varattno < 1 | | varattno > index - > rd_index - > indnatts )
elog ( ERROR , " bogus RowCompare index qualification " ) ;
opfamily = index - > rd_opfamily [ varattno - 1 ] ;
get_op_opfamily_properties ( opno , opfamily ,
& op_strategy ,
& op_lefttype ,
& op_righttype ) ;
if ( op_strategy ! = rc - > rctype )
elog ( ERROR , " RowCompare index qualification contains wrong operator " ) ;
opfuncid = get_opfamily_proc ( opfamily ,
op_lefttype ,
op_righttype ,
BTORDER_PROC ) ;
/*
/*
* rightop is the constant or variable comparison value
* rightop is the constant or variable comparison value
*/
*/
@ -867,35 +912,12 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Index scanrelid,
runtime_keys [ n_runtime_keys ] . scan_key = this_sub_key ;
runtime_keys [ n_runtime_keys ] . scan_key = this_sub_key ;
runtime_keys [ n_runtime_keys ] . key_expr =
runtime_keys [ n_runtime_keys ] . key_expr =
ExecInitExpr ( rightop , planstate ) ;
ExecInitExpr ( rightop , planstate ) ;
runtime_keys [ n_runtime_keys ] . key_toastable =
TypeIsToastable ( op_righttype ) ;
n_runtime_keys + + ;
n_runtime_keys + + ;
scanvalue = ( Datum ) 0 ;
scanvalue = ( Datum ) 0 ;
}
}
/*
* We have to look up the operator ' s associated btree support
* function
*/
opno = lfirst_oid ( opnos_cell ) ;
opnos_cell = lnext ( opnos_cell ) ;
if ( index - > rd_rel - > relam ! = BTREE_AM_OID | |
varattno < 1 | | varattno > index - > rd_index - > indnatts )
elog ( ERROR , " bogus RowCompare index qualification " ) ;
opfamily = index - > rd_opfamily [ varattno - 1 ] ;
get_op_opfamily_properties ( opno , opfamily ,
& op_strategy ,
& op_lefttype ,
& op_righttype ) ;
if ( op_strategy ! = rc - > rctype )
elog ( ERROR , " RowCompare index qualification contains wrong operator " ) ;
opfuncid = get_opfamily_proc ( opfamily ,
op_lefttype ,
op_righttype ,
BTORDER_PROC ) ;
/*
/*
* initialize the subsidiary scan key ' s fields appropriately
* initialize the subsidiary scan key ' s fields appropriately
*/
*/