diff options
Diffstat (limited to 'src/backend/executor/nodeIndexscan.c')
-rw-r--r-- | src/backend/executor/nodeIndexscan.c | 361 |
1 files changed, 161 insertions, 200 deletions
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index a6e6e45e9dc..1adc49d6ff0 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.58 2001/03/22 03:59:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.59 2001/03/22 06:16:13 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -84,9 +84,8 @@ IndexNext(IndexScan *node) bool bBackward; int indexNumber; - /* ---------------- - * extract necessary information from index scan node - * ---------------- + /* + * extract necessary information from index scan node */ estate = node->scan.plan.state; direction = estate->es_direction; @@ -145,11 +144,10 @@ IndexNext(IndexScan *node) tuple = &(indexstate->iss_htup); - /* ---------------- - * ok, now that we have what we need, fetch an index tuple. - * if scanning this index succeeded then return the - * appropriate heap tuple.. else return NULL. - * ---------------- + /* + * ok, now that we have what we need, fetch an index tuple. if + * scanning this index succeeded then return the appropriate heap + * tuple.. else return NULL. */ bBackward = ScanDirectionIsBackward(direction); if (bBackward) @@ -238,10 +236,10 @@ IndexNext(IndexScan *node) indexstate->iss_IndexPtr++; } } - /* ---------------- - * if we get here it means the index scan failed so we - * are at the end of the scan.. - * ---------------- + + /* + * if we get here it means the index scan failed so we are at the end + * of the scan.. */ return ExecClearTuple(slot); } @@ -272,17 +270,15 @@ ExecIndexScan(IndexScan *node) { IndexScanState *indexstate = node->indxstate; - /* ---------------- - * If we have runtime keys and they've not already been set up, - * do it now. - * ---------------- + /* + * If we have runtime keys and they've not already been set up, do it + * now. */ if (indexstate->iss_RuntimeKeyInfo && !indexstate->iss_RuntimeKeysReady) ExecReScan((Plan *) node, NULL, NULL); - /* ---------------- - * use IndexNext as access method - * ---------------- + /* + * use IndexNext as access method */ return ExecScan(&node->scan, (ExecScanAccessMtd) IndexNext); } @@ -448,37 +444,32 @@ ExecEndIndexScan(IndexScan *node) indxqual = node->indxqual; runtimeKeyInfo = indexstate->iss_RuntimeKeyInfo; - /* ---------------- - * extract information from the node - * ---------------- + /* + * extract information from the node */ numIndices = indexstate->iss_NumIndices; scanKeys = indexstate->iss_ScanKeys; numScanKeys = indexstate->iss_NumScanKeys; - /* ---------------- - * Free the projection info and the scan attribute info + /* + * Free the projection info and the scan attribute info * - * Note: we don't ExecFreeResultType(scanstate) - * because the rule manager depends on the tupType - * returned by ExecMain(). So for now, this - * is freed at end-transaction time. -cim 6/2/91 - * ---------------- + * Note: we don't ExecFreeResultType(scanstate) because the rule manager + * depends on the tupType returned by ExecMain(). So for now, this is + * freed at end-transaction time. -cim 6/2/91 */ ExecFreeProjectionInfo(&scanstate->cstate); ExecFreeExprContext(&scanstate->cstate); if (indexstate->iss_RuntimeContext) FreeExprContext(indexstate->iss_RuntimeContext); - /* ---------------- - * close the heap and index relations - * ---------------- + /* + * close the heap and index relations */ ExecCloseR((Plan *) node); - /* ---------------- - * free the scan keys used in scanning the indices - * ---------------- + /* + * free the scan keys used in scanning the indices */ for (i = 0; i < numIndices; i++) { @@ -498,9 +489,8 @@ ExecEndIndexScan(IndexScan *node) pfree(runtimeKeyInfo); } - /* ---------------- - * clear out tuple table slots - * ---------------- + /* + * clear out tuple table slots */ ExecClearTuple(scanstate->cstate.cs_ResultTupleSlot); ExecClearTuple(scanstate->css_ScanTupleSlot); @@ -605,50 +595,45 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) HeapScanDesc currentScanDesc; ScanDirection direction; - /* ---------------- - * assign execution state to node - * ---------------- + /* + * assign execution state to node */ node->scan.plan.state = estate; - /* -------------------------------- - * Part 1) initialize scan state + /* + * Part 1) initialize scan state * - * create new CommonScanState for node - * -------------------------------- + * create new CommonScanState for node */ scanstate = makeNode(CommonScanState); node->scan.scanstate = scanstate; - /* ---------------- - * Miscellaneous initialization + /* + * Miscellaneous initialization * - * + create expression context for node - * ---------------- + * create expression context for node */ ExecAssignExprContext(estate, &scanstate->cstate); #define INDEXSCAN_NSLOTS 3 - /* ---------------- - * tuple table initialization - * ---------------- + + /* + * tuple table initialization */ ExecInitResultTupleSlot(estate, &scanstate->cstate); ExecInitScanTupleSlot(estate, scanstate); - /* ---------------- - * initialize projection info. result type comes from scan desc - * below.. - * ---------------- + /* + * initialize projection info. result type comes from scan desc + * below.. */ ExecAssignProjectionInfo((Plan *) node, &scanstate->cstate); - /* -------------------------------- - * Part 2) initialize index scan state - * - * create new IndexScanState for node - * -------------------------------- - */ + /* + * Part 2) initialize index scan state + * + * create new IndexScanState for node + */ indexstate = makeNode(IndexScanState); indexstate->iss_NumIndices = 0; indexstate->iss_IndexPtr = -1; @@ -662,9 +647,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) node->indxstate = indexstate; - /* ---------------- - * get the index node information - * ---------------- + /* + * get the index node information */ indxid = node->indxid; numIndices = length(indxid); @@ -672,27 +656,24 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext); - /* ---------------- - * scanKeys is used to keep track of the ScanKey's. This is needed - * because a single scan may use several indices and each index has - * its own ScanKey. - * ---------------- + /* + * scanKeys is used to keep track of the ScanKey's. This is needed + * because a single scan may use several indices and each index has + * its own ScanKey. */ numScanKeys = (int *) palloc(numIndices * sizeof(int)); scanKeys = (ScanKey *) palloc(numIndices * sizeof(ScanKey)); relationDescs = (RelationPtr) palloc(numIndices * sizeof(Relation)); scanDescs = (IndexScanDescPtr) palloc(numIndices * sizeof(IndexScanDesc)); - /* ---------------- - * initialize space for runtime key info (may not be needed) - * ---------------- + /* + * initialize space for runtime key info (may not be needed) */ have_runtime_keys = false; runtimeKeyInfo = (int **) palloc(numIndices * sizeof(int *)); - /* ---------------- - * build the index scan keys from the index qualification - * ---------------- + /* + * build the index scan keys from the index qualification */ indxqual = node->indxqual; for (i = 0; i < numIndices; i++) @@ -713,10 +694,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext); - /* ---------------- - * for each opclause in the given qual, - * convert each qual's opclause into a single scan key - * ---------------- + /* + * for each opclause in the given qual, convert each qual's + * opclause into a single scan key */ for (j = 0; j < n_keys; j++) { @@ -731,9 +711,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) Oid opid; /* operator id used in scan */ Datum scanvalue = 0; /* value used in scan (if const) */ - /* ---------------- - * extract clause information from the qualification - * ---------------- + /* + * extract clause information from the qualification */ clause = nth(j, qual); @@ -743,48 +722,46 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) opid = op->opid; - /* ---------------- - * Here we figure out the contents of the index qual. - * The usual case is (var op const) or (const op var) - * which means we form a scan key for the attribute - * listed in the var node and use the value of the const. + /* + * Here we figure out the contents of the index qual. The + * usual case is (var op const) or (const op var) which means + * we form a scan key for the attribute listed in the var node + * and use the value of the const. * - * If we don't have a const node, then it means that - * one of the var nodes refers to the "scan" tuple and - * is used to determine which attribute to scan, and the - * other expression is used to calculate the value used in - * scanning the index. + * If we don't have a const node, then it means that one of the + * var nodes refers to the "scan" tuple and is used to + * determine which attribute to scan, and the other expression + * is used to calculate the value used in scanning the index. * - * This means our index scan's scan key is a function of - * information obtained during the execution of the plan - * in which case we need to recalculate the index scan key - * at run time. + * This means our index scan's scan key is a function of + * information obtained during the execution of the plan in + * which case we need to recalculate the index scan key at run + * time. * - * Hence, we set have_runtime_keys to true and then set - * the appropriate flag in run_keys to LEFT_OP or RIGHT_OP. - * The corresponding scan keys are recomputed at run time. + * Hence, we set have_runtime_keys to true and then set the + * appropriate flag in run_keys to LEFT_OP or RIGHT_OP. The + * corresponding scan keys are recomputed at run time. * - * XXX Although this code *thinks* it can handle an indexqual - * with the indexkey on either side, in fact it cannot. - * Indexscans only work with quals that have the indexkey on - * the left (the planner/optimizer makes sure it never passes - * anything else). The reason: the scankey machinery has no - * provision for distinguishing which side of the operator is - * the indexed attribute and which is the compared-to constant. - * It just assumes that the attribute is on the left :-( + * XXX Although this code *thinks* it can handle an indexqual + * with the indexkey on either side, in fact it cannot. + * Indexscans only work with quals that have the indexkey on + * the left (the planner/optimizer makes sure it never passes + * anything else). The reason: the scankey machinery has no + * provision for distinguishing which side of the operator is + * the indexed attribute and which is the compared-to + * constant. It just assumes that the attribute is on the left + * :-( * - * I am leaving this code able to support both ways, even though - * half of it is dead code, on the off chance that someone will - * fix the scankey machinery someday --- tgl 8/11/99. - * ---------------- + * I am leaving this code able to support both ways, even though + * half of it is dead code, on the off chance that someone + * will fix the scankey machinery someday --- tgl 8/11/99. */ scanvar = NO_OP; run_keys[j] = NO_OP; - /* ---------------- - * determine information in leftop - * ---------------- + /* + * determine information in leftop */ leftop = (Node *) get_leftop(clause); @@ -795,21 +772,21 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) if (IsA(leftop, Var) &&var_is_rel((Var *) leftop)) { - /* ---------------- - * if the leftop is a "rel-var", then it means - * that it is a var node which tells us which - * attribute to use for our scan key. - * ---------------- + + /* + * if the leftop is a "rel-var", then it means that it is + * a var node which tells us which attribute to use for + * our scan key. */ varattno = ((Var *) leftop)->varattno; scanvar = LEFT_OP; } else if (IsA(leftop, Const)) { - /* ---------------- - * if the leftop is a const node then it means - * it identifies the value to place in our scan key. - * ---------------- + + /* + * if the leftop is a const node then it means it + * identifies the value to place in our scan key. */ scanvalue = ((Const *) leftop)->constvalue; if (((Const *) leftop)->constisnull) @@ -819,10 +796,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) { bool isnull; - /* ---------------- - * if the leftop is a Param node then it means - * it identifies the value to place in our scan key. - * ---------------- + /* + * if the leftop is a Param node then it means it + * identifies the value to place in our scan key. */ /* Life was so easy before ... subselects */ @@ -844,19 +820,18 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) } else { - /* ---------------- - * otherwise, the leftop contains an expression evaluable - * at runtime to figure out the value to place in our - * scan key. - * ---------------- + + /* + * otherwise, the leftop contains an expression evaluable + * at runtime to figure out the value to place in our scan + * key. */ have_runtime_keys = true; run_keys[j] = LEFT_OP; } - /* ---------------- - * now determine information in rightop - * ---------------- + /* + * now determine information in rightop */ rightop = (Node *) get_rightop(clause); @@ -867,30 +842,29 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) if (IsA(rightop, Var) &&var_is_rel((Var *) rightop)) { - /* ---------------- - * here we make sure only one op identifies the - * scan-attribute... - * ---------------- + + /* + * here we make sure only one op identifies the + * scan-attribute... */ if (scanvar == LEFT_OP) elog(ERROR, "ExecInitIndexScan: %s", "both left and right op's are rel-vars"); - /* ---------------- - * if the rightop is a "rel-var", then it means - * that it is a var node which tells us which - * attribute to use for our scan key. - * ---------------- + /* + * if the rightop is a "rel-var", then it means that it is + * a var node which tells us which attribute to use for + * our scan key. */ varattno = ((Var *) rightop)->varattno; scanvar = RIGHT_OP; } else if (IsA(rightop, Const)) { - /* ---------------- - * if the rightop is a const node then it means - * it identifies the value to place in our scan key. - * ---------------- + + /* + * if the rightop is a const node then it means it + * identifies the value to place in our scan key. */ scanvalue = ((Const *) rightop)->constvalue; if (((Const *) rightop)->constisnull) @@ -900,10 +874,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) { bool isnull; - /* ---------------- - * if the rightop is a Param node then it means - * it identifies the value to place in our scan key. - * ---------------- + /* + * if the rightop is a Param node then it means it + * identifies the value to place in our scan key. */ /* Life was so easy before ... subselects */ @@ -925,28 +898,26 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) } else { - /* ---------------- - * otherwise, the rightop contains an expression evaluable - * at runtime to figure out the value to place in our - * scan key. - * ---------------- + + /* + * otherwise, the rightop contains an expression evaluable + * at runtime to figure out the value to place in our scan + * key. */ have_runtime_keys = true; run_keys[j] = RIGHT_OP; } - /* ---------------- - * now check that at least one op tells us the scan - * attribute... - * ---------------- + /* + * now check that at least one op tells us the scan + * attribute... */ if (scanvar == NO_OP) elog(ERROR, "ExecInitIndexScan: %s", "neither leftop nor rightop refer to scan relation"); - /* ---------------- - * initialize the scan key's fields appropriately - * ---------------- + /* + * initialize the scan key's fields appropriately */ ScanKeyEntryInitialize(&scan_keys[j], flags, @@ -956,9 +927,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) scanvalue); /* constant */ } - /* ---------------- - * store the key information into our arrays. - * ---------------- + /* + * store the key information into our arrays. */ numScanKeys[i] = n_keys; scanKeys[i] = scan_keys; @@ -972,20 +942,17 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) indexstate->iss_ScanKeys = scanKeys; indexstate->iss_NumScanKeys = numScanKeys; - /* ---------------- - * If all of our keys have the form (op var const) , then we have no - * runtime keys so we store NULL in the runtime key info. - * Otherwise runtime key info contains an array of pointers - * (one for each index) to arrays of flags (one for each key) - * which indicate that the qual needs to be evaluated at runtime. - * -cim 10/24/89 + /* + * If all of our keys have the form (op var const) , then we have no + * runtime keys so we store NULL in the runtime key info. Otherwise + * runtime key info contains an array of pointers (one for each index) + * to arrays of flags (one for each key) which indicate that the qual + * needs to be evaluated at runtime. -cim 10/24/89 * - * If we do have runtime keys, we need an ExprContext to evaluate them; - * the node's standard context won't do because we want to reset that - * context for every tuple. So, build another context just like the - * other one... - * -tgl 7/11/00 - * ---------------- + * If we do have runtime keys, we need an ExprContext to evaluate them; + * the node's standard context won't do because we want to reset that + * context for every tuple. So, build another context just like the + * other one... -tgl 7/11/00 */ if (have_runtime_keys) { @@ -1009,18 +976,15 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) pfree(runtimeKeyInfo); } - /* ---------------- - * get the range table and direction information - * from the execution state (these are needed to - * open the relations). - * ---------------- + /* + * get the range table and direction information from the execution + * state (these are needed to open the relations). */ rangeTable = estate->es_range_table; direction = estate->es_direction; - /* ---------------- - * open the base relation - * ---------------- + /* + * open the base relation */ relid = node->scan.scanrelid; rtentry = rt_fetch(relid, rangeTable); @@ -1040,17 +1004,15 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) scanstate->css_currentRelation = currentRelation; scanstate->css_currentScanDesc = currentScanDesc; - /* ---------------- - * get the scan type from the relation descriptor. - * ---------------- + /* + * get the scan type from the relation descriptor. */ ExecAssignScanType(scanstate, RelationGetDescr(currentRelation), false); ExecAssignResultTypeFromTL((Plan *) node, &scanstate->cstate); - /* ---------------- - * open the index relations and initialize - * relation and scan descriptors. - * ---------------- + /* + * open the index relations and initialize relation and scan + * descriptors. */ for (i = 0; i < numIndices; i++) { @@ -1073,9 +1035,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) indexstate->iss_RelationDescs = relationDescs; indexstate->iss_ScanDescs = scanDescs; - /* ---------------- - * all done. - * ---------------- + /* + * all done. */ return TRUE; } |