mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
pgindent run for 9.0
This commit is contained in:
@ -26,7 +26,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.347 2010/02/20 21:24:02 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.348 2010/02/26 02:00:41 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -76,7 +76,7 @@ static void ExecCheckRTPerms(List *rangeTable);
|
||||
static void ExecCheckRTEPerms(RangeTblEntry *rte);
|
||||
static void ExecCheckXactReadOnly(PlannedStmt *plannedstmt);
|
||||
static void EvalPlanQualStart(EPQState *epqstate, EState *parentestate,
|
||||
Plan *planTree);
|
||||
Plan *planTree);
|
||||
static void OpenIntoRel(QueryDesc *queryDesc);
|
||||
static void CloseIntoRel(QueryDesc *queryDesc);
|
||||
static void intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo);
|
||||
@ -582,8 +582,8 @@ ExecCheckXactReadOnly(PlannedStmt *plannedstmt)
|
||||
/*
|
||||
* CREATE TABLE AS or SELECT INTO?
|
||||
*
|
||||
* XXX should we allow this if the destination is temp? Considering
|
||||
* that it would still require catalog changes, probably not.
|
||||
* XXX should we allow this if the destination is temp? Considering that
|
||||
* it would still require catalog changes, probably not.
|
||||
*/
|
||||
if (plannedstmt->intoClause != NULL)
|
||||
PreventCommandIfReadOnly(CreateCommandTag((Node *) plannedstmt));
|
||||
@ -641,8 +641,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
/*
|
||||
* initialize result relation stuff, and open/lock the result rels.
|
||||
*
|
||||
* We must do this before initializing the plan tree, else we might
|
||||
* try to do a lock upgrade if a result rel is also a source rel.
|
||||
* We must do this before initializing the plan tree, else we might try to
|
||||
* do a lock upgrade if a result rel is also a source rel.
|
||||
*/
|
||||
if (plannedstmt->resultRelations)
|
||||
{
|
||||
@ -686,8 +686,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
|
||||
/*
|
||||
* Similarly, we have to lock relations selected FOR UPDATE/FOR SHARE
|
||||
* before we initialize the plan tree, else we'd be risking lock
|
||||
* upgrades. While we are at it, build the ExecRowMark list.
|
||||
* before we initialize the plan tree, else we'd be risking lock upgrades.
|
||||
* While we are at it, build the ExecRowMark list.
|
||||
*/
|
||||
estate->es_rowMarks = NIL;
|
||||
foreach(l, plannedstmt->rowMarks)
|
||||
@ -804,8 +804,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
tupType = ExecGetResultType(planstate);
|
||||
|
||||
/*
|
||||
* Initialize the junk filter if needed. SELECT queries need a
|
||||
* filter if there are any junk attrs in the top-level tlist.
|
||||
* Initialize the junk filter if needed. SELECT queries need a filter if
|
||||
* there are any junk attrs in the top-level tlist.
|
||||
*/
|
||||
if (operation == CMD_SELECT)
|
||||
{
|
||||
@ -1101,9 +1101,9 @@ ExecEndPlan(PlanState *planstate, EState *estate)
|
||||
|
||||
/*
|
||||
* destroy the executor's tuple table. Actually we only care about
|
||||
* releasing buffer pins and tupdesc refcounts; there's no need to
|
||||
* pfree the TupleTableSlots, since the containing memory context
|
||||
* is about to go away anyway.
|
||||
* releasing buffer pins and tupdesc refcounts; there's no need to pfree
|
||||
* the TupleTableSlots, since the containing memory context is about to go
|
||||
* away anyway.
|
||||
*/
|
||||
ExecResetTupleTable(estate->es_tupleTable, false);
|
||||
|
||||
@ -1208,8 +1208,8 @@ ExecutePlan(EState *estate,
|
||||
slot = ExecFilterJunk(estate->es_junkFilter, slot);
|
||||
|
||||
/*
|
||||
* If we are supposed to send the tuple somewhere, do so.
|
||||
* (In practice, this is probably always the case at this point.)
|
||||
* If we are supposed to send the tuple somewhere, do so. (In
|
||||
* practice, this is probably always the case at this point.)
|
||||
*/
|
||||
if (sendTuples)
|
||||
(*dest->receiveSlot) (slot, dest);
|
||||
@ -1390,8 +1390,8 @@ EvalPlanQual(EState *estate, EPQState *epqstate,
|
||||
EvalPlanQualBegin(epqstate, estate);
|
||||
|
||||
/*
|
||||
* Free old test tuple, if any, and store new tuple where relation's
|
||||
* scan node will see it
|
||||
* Free old test tuple, if any, and store new tuple where relation's scan
|
||||
* node will see it
|
||||
*/
|
||||
EvalPlanQualSetTuple(epqstate, rti, copyTuple);
|
||||
|
||||
@ -1406,19 +1406,19 @@ EvalPlanQual(EState *estate, EPQState *epqstate,
|
||||
slot = EvalPlanQualNext(epqstate);
|
||||
|
||||
/*
|
||||
* If we got a tuple, force the slot to materialize the tuple so that
|
||||
* it is not dependent on any local state in the EPQ query (in particular,
|
||||
* If we got a tuple, force the slot to materialize the tuple so that it
|
||||
* is not dependent on any local state in the EPQ query (in particular,
|
||||
* it's highly likely that the slot contains references to any pass-by-ref
|
||||
* datums that may be present in copyTuple). As with the next step,
|
||||
* this is to guard against early re-use of the EPQ query.
|
||||
* datums that may be present in copyTuple). As with the next step, this
|
||||
* is to guard against early re-use of the EPQ query.
|
||||
*/
|
||||
if (!TupIsNull(slot))
|
||||
(void) ExecMaterializeSlot(slot);
|
||||
|
||||
/*
|
||||
* Clear out the test tuple. This is needed in case the EPQ query
|
||||
* is re-used to test a tuple for a different relation. (Not clear
|
||||
* that can really happen, but let's be safe.)
|
||||
* Clear out the test tuple. This is needed in case the EPQ query is
|
||||
* re-used to test a tuple for a different relation. (Not clear that can
|
||||
* really happen, but let's be safe.)
|
||||
*/
|
||||
EvalPlanQualSetTuple(epqstate, rti, NULL);
|
||||
|
||||
@ -1680,8 +1680,8 @@ EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple)
|
||||
Assert(rti > 0);
|
||||
|
||||
/*
|
||||
* free old test tuple, if any, and store new tuple where relation's
|
||||
* scan node will see it
|
||||
* free old test tuple, if any, and store new tuple where relation's scan
|
||||
* node will see it
|
||||
*/
|
||||
if (estate->es_epqTuple[rti - 1] != NULL)
|
||||
heap_freetuple(estate->es_epqTuple[rti - 1]);
|
||||
@ -1704,7 +1704,7 @@ EvalPlanQualGetTuple(EPQState *epqstate, Index rti)
|
||||
|
||||
/*
|
||||
* Fetch the current row values for any non-locked relations that need
|
||||
* to be scanned by an EvalPlanQual operation. origslot must have been set
|
||||
* to be scanned by an EvalPlanQual operation. origslot must have been set
|
||||
* to contain the current result row (top-level row) that we need to recheck.
|
||||
*/
|
||||
void
|
||||
@ -1841,7 +1841,7 @@ EvalPlanQualBegin(EPQState *epqstate, EState *parentestate)
|
||||
/* Recopy current values of parent parameters */
|
||||
if (parentestate->es_plannedstmt->nParamExec > 0)
|
||||
{
|
||||
int i = parentestate->es_plannedstmt->nParamExec;
|
||||
int i = parentestate->es_plannedstmt->nParamExec;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
@ -1913,7 +1913,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
|
||||
estate->es_param_list_info = parentestate->es_param_list_info;
|
||||
if (parentestate->es_plannedstmt->nParamExec > 0)
|
||||
{
|
||||
int i = parentestate->es_plannedstmt->nParamExec;
|
||||
int i = parentestate->es_plannedstmt->nParamExec;
|
||||
|
||||
estate->es_param_exec_vals = (ParamExecData *)
|
||||
palloc0(i * sizeof(ParamExecData));
|
||||
@ -1929,7 +1929,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
|
||||
|
||||
/*
|
||||
* Each EState must have its own es_epqScanDone state, but if we have
|
||||
* nested EPQ checks they should share es_epqTuple arrays. This allows
|
||||
* nested EPQ checks they should share es_epqTuple arrays. This allows
|
||||
* sub-rechecks to inherit the values being examined by an outer recheck.
|
||||
*/
|
||||
estate->es_epqScanDone = (bool *) palloc0(rtsize * sizeof(bool));
|
||||
@ -1954,10 +1954,10 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
|
||||
/*
|
||||
* Initialize private state information for each SubPlan. We must do this
|
||||
* before running ExecInitNode on the main query tree, since
|
||||
* ExecInitSubPlan expects to be able to find these entries.
|
||||
* Some of the SubPlans might not be used in the part of the plan tree
|
||||
* we intend to run, but since it's not easy to tell which, we just
|
||||
* initialize them all.
|
||||
* ExecInitSubPlan expects to be able to find these entries. Some of the
|
||||
* SubPlans might not be used in the part of the plan tree we intend to
|
||||
* run, but since it's not easy to tell which, we just initialize them
|
||||
* all.
|
||||
*/
|
||||
Assert(estate->es_subplanstates == NIL);
|
||||
foreach(l, parentestate->es_plannedstmt->subplans)
|
||||
@ -1972,9 +1972,9 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the private state information for all the nodes in the
|
||||
* part of the plan tree we need to run. This opens files, allocates
|
||||
* storage and leaves us ready to start processing tuples.
|
||||
* Initialize the private state information for all the nodes in the part
|
||||
* of the plan tree we need to run. This opens files, allocates storage
|
||||
* and leaves us ready to start processing tuples.
|
||||
*/
|
||||
epqstate->planstate = ExecInitNode(planTree, estate, 0);
|
||||
|
||||
@ -2078,8 +2078,8 @@ OpenIntoRel(QueryDesc *queryDesc)
|
||||
Assert(into);
|
||||
|
||||
/*
|
||||
* XXX This code needs to be kept in sync with DefineRelation().
|
||||
* Maybe we should try to use that function instead.
|
||||
* XXX This code needs to be kept in sync with DefineRelation(). Maybe we
|
||||
* should try to use that function instead.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -2242,7 +2242,8 @@ CloseIntoRel(QueryDesc *queryDesc)
|
||||
/* If we skipped using WAL, must heap_sync before commit */
|
||||
if (myState->hi_options & HEAP_INSERT_SKIP_WAL)
|
||||
{
|
||||
char reason[NAMEDATALEN + 30];
|
||||
char reason[NAMEDATALEN + 30];
|
||||
|
||||
snprintf(reason, sizeof(reason), "SELECT INTO on \"%s\"",
|
||||
RelationGetRelationName(myState->rel));
|
||||
XLogReportUnloggedStatement(reason);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.262 2010/02/18 18:41:47 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.263 2010/02/26 02:00:41 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -357,7 +357,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
|
||||
* We might have a nested-assignment situation, in which the
|
||||
* refassgnexpr is itself a FieldStore or ArrayRef that needs to
|
||||
* obtain and modify the previous value of the array element or slice
|
||||
* being replaced. If so, we have to extract that value from the
|
||||
* being replaced. If so, we have to extract that value from the
|
||||
* array and pass it down via the econtext's caseValue. It's safe to
|
||||
* reuse the CASE mechanism because there cannot be a CASE between
|
||||
* here and where the value would be needed, and an array assignment
|
||||
@ -386,7 +386,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
|
||||
astate->refelemlength,
|
||||
astate->refelembyval,
|
||||
astate->refelemalign,
|
||||
&econtext->caseValue_isNull);
|
||||
&econtext->caseValue_isNull);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -673,7 +673,7 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
|
||||
* We really only care about number of attributes and data type.
|
||||
* Also, we can ignore type mismatch on columns that are dropped
|
||||
* in the destination type, so long as (1) the physical storage
|
||||
* matches or (2) the actual column value is NULL. Case (1) is
|
||||
* matches or (2) the actual column value is NULL. Case (1) is
|
||||
* helpful in some cases involving out-of-date cached plans, while
|
||||
* case (2) is expected behavior in situations such as an INSERT
|
||||
* into a table with dropped columns (the planner typically
|
||||
@ -682,8 +682,8 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
|
||||
* holds, we have to use ExecEvalWholeRowSlow to check (2) for
|
||||
* each row. Also, we have to allow the case that the slot has
|
||||
* more columns than the Var's type, because we might be looking
|
||||
* at the output of a subplan that includes resjunk columns.
|
||||
* (XXX it would be nice to verify that the extra columns are all
|
||||
* at the output of a subplan that includes resjunk columns. (XXX
|
||||
* it would be nice to verify that the extra columns are all
|
||||
* marked resjunk, but we haven't got access to the subplan
|
||||
* targetlist here...) Resjunk columns should always be at the end
|
||||
* of a targetlist, so it's sufficient to ignore them here; but we
|
||||
@ -702,7 +702,7 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
|
||||
slot_tupdesc->natts,
|
||||
var_tupdesc->natts)));
|
||||
else if (var_tupdesc->natts < slot_tupdesc->natts)
|
||||
needslow = true; /* need to trim trailing atts */
|
||||
needslow = true; /* need to trim trailing atts */
|
||||
|
||||
for (i = 0; i < var_tupdesc->natts; i++)
|
||||
{
|
||||
@ -722,7 +722,7 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
|
||||
|
||||
if (vattr->attlen != sattr->attlen ||
|
||||
vattr->attalign != sattr->attalign)
|
||||
needslow = true; /* need runtime check for null */
|
||||
needslow = true; /* need runtime check for null */
|
||||
}
|
||||
|
||||
ReleaseTupleDesc(var_tupdesc);
|
||||
@ -907,7 +907,7 @@ ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
|
||||
|
||||
if (!vattr->attisdropped)
|
||||
continue; /* already checked non-dropped cols */
|
||||
if (heap_attisnull(tuple, i+1))
|
||||
if (heap_attisnull(tuple, i + 1))
|
||||
continue; /* null is always okay */
|
||||
if (vattr->attlen != sattr->attlen ||
|
||||
vattr->attalign != sattr->attalign)
|
||||
@ -2722,7 +2722,7 @@ ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
|
||||
/* prepare map from old to new attribute numbers */
|
||||
cstate->map = convert_tuples_by_name(cstate->indesc,
|
||||
cstate->outdesc,
|
||||
gettext_noop("could not convert row type"));
|
||||
gettext_noop("could not convert row type"));
|
||||
cstate->initialized = true;
|
||||
|
||||
MemoryContextSwitchTo(old_cxt);
|
||||
@ -3870,11 +3870,11 @@ ExecEvalFieldSelect(FieldSelectState *fstate,
|
||||
&fstate->argdesc, econtext);
|
||||
|
||||
/*
|
||||
* Find field's attr record. Note we don't support system columns here:
|
||||
* a datum tuple doesn't have valid values for most of the interesting
|
||||
* Find field's attr record. Note we don't support system columns here: a
|
||||
* datum tuple doesn't have valid values for most of the interesting
|
||||
* system columns anyway.
|
||||
*/
|
||||
if (fieldnum <= 0) /* should never happen */
|
||||
if (fieldnum <= 0) /* should never happen */
|
||||
elog(ERROR, "unsupported reference to system column %d in FieldSelect",
|
||||
fieldnum);
|
||||
if (fieldnum > tupDesc->natts) /* should never happen */
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execScan.c,v 1.48 2010/01/02 16:57:41 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execScan.c,v 1.49 2010/02/26 02:00:41 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -30,7 +30,7 @@ static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, Tuple
|
||||
* ExecScanFetch -- fetch next potential tuple
|
||||
*
|
||||
* This routine is concerned with substituting a test tuple if we are
|
||||
* inside an EvalPlanQual recheck. If we aren't, just execute
|
||||
* inside an EvalPlanQual recheck. If we aren't, just execute
|
||||
* the access method's next-tuple routine.
|
||||
*/
|
||||
static inline TupleTableSlot *
|
||||
@ -152,7 +152,7 @@ ExecScan(ScanState *node,
|
||||
ResetExprContext(econtext);
|
||||
|
||||
/*
|
||||
* get a tuple from the access method. Loop until we obtain a tuple that
|
||||
* get a tuple from the access method. Loop until we obtain a tuple that
|
||||
* passes the qualification.
|
||||
*/
|
||||
for (;;)
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Routines dealing with TupleTableSlots. These are used for resource
|
||||
* management associated with tuples (eg, releasing buffer pins for
|
||||
* tuples in disk buffers, or freeing the memory occupied by transient
|
||||
* tuples). Slots also provide access abstraction that lets us implement
|
||||
* tuples). Slots also provide access abstraction that lets us implement
|
||||
* "virtual" tuples to reduce data-copying overhead.
|
||||
*
|
||||
* Routines dealing with the type information for tuples. Currently,
|
||||
@ -17,7 +17,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.111 2010/01/02 16:57:41 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.112 2010/02/26 02:00:41 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1178,7 +1178,7 @@ void
|
||||
do_text_output_multiline(TupOutputState *tstate, char *text)
|
||||
{
|
||||
Datum values[1];
|
||||
bool isnull[1] = { false };
|
||||
bool isnull[1] = {false};
|
||||
|
||||
while (*text)
|
||||
{
|
||||
@ -1189,6 +1189,7 @@ do_text_output_multiline(TupOutputState *tstate, char *text)
|
||||
if (eol)
|
||||
{
|
||||
len = eol - text;
|
||||
|
||||
eol++;
|
||||
}
|
||||
else
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.170 2010/02/08 04:33:54 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.171 2010/02/26 02:00:41 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -342,7 +342,7 @@ CreateStandaloneExprContext(void)
|
||||
* any previously computed pass-by-reference expression result will go away!
|
||||
*
|
||||
* If isCommit is false, we are being called in error cleanup, and should
|
||||
* not call callbacks but only release memory. (It might be better to call
|
||||
* not call callbacks but only release memory. (It might be better to call
|
||||
* the callbacks and pass the isCommit flag to them, but that would require
|
||||
* more invasive code changes than currently seems justified.)
|
||||
*
|
||||
@ -1078,9 +1078,9 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
|
||||
checkUnique = UNIQUE_CHECK_PARTIAL;
|
||||
|
||||
satisfiesConstraint =
|
||||
index_insert(indexRelation, /* index relation */
|
||||
values, /* array of index Datums */
|
||||
isnull, /* null flags */
|
||||
index_insert(indexRelation, /* index relation */
|
||||
values, /* array of index Datums */
|
||||
isnull, /* null flags */
|
||||
tupleid, /* tid of heap tuple */
|
||||
heapRelation, /* heap relation */
|
||||
checkUnique); /* type of uniqueness check to do */
|
||||
@ -1088,7 +1088,7 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
|
||||
/*
|
||||
* If the index has an associated exclusion constraint, check that.
|
||||
* This is simpler than the process for uniqueness checks since we
|
||||
* always insert first and then check. If the constraint is deferred,
|
||||
* always insert first and then check. If the constraint is deferred,
|
||||
* we check now anyway, but don't throw error on violation; instead
|
||||
* we'll queue a recheck event.
|
||||
*
|
||||
@ -1098,7 +1098,7 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
|
||||
*/
|
||||
if (indexInfo->ii_ExclusionOps != NULL)
|
||||
{
|
||||
bool errorOK = !indexRelation->rd_index->indimmediate;
|
||||
bool errorOK = !indexRelation->rd_index->indimmediate;
|
||||
|
||||
satisfiesConstraint =
|
||||
check_exclusion_constraint(heapRelation,
|
||||
@ -1152,23 +1152,23 @@ check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo,
|
||||
ItemPointer tupleid, Datum *values, bool *isnull,
|
||||
EState *estate, bool newIndex, bool errorOK)
|
||||
{
|
||||
Oid *constr_procs = indexInfo->ii_ExclusionProcs;
|
||||
uint16 *constr_strats = indexInfo->ii_ExclusionStrats;
|
||||
int index_natts = index->rd_index->indnatts;
|
||||
IndexScanDesc index_scan;
|
||||
HeapTuple tup;
|
||||
ScanKeyData scankeys[INDEX_MAX_KEYS];
|
||||
SnapshotData DirtySnapshot;
|
||||
int i;
|
||||
bool conflict;
|
||||
bool found_self;
|
||||
ExprContext *econtext;
|
||||
Oid *constr_procs = indexInfo->ii_ExclusionProcs;
|
||||
uint16 *constr_strats = indexInfo->ii_ExclusionStrats;
|
||||
int index_natts = index->rd_index->indnatts;
|
||||
IndexScanDesc index_scan;
|
||||
HeapTuple tup;
|
||||
ScanKeyData scankeys[INDEX_MAX_KEYS];
|
||||
SnapshotData DirtySnapshot;
|
||||
int i;
|
||||
bool conflict;
|
||||
bool found_self;
|
||||
ExprContext *econtext;
|
||||
TupleTableSlot *existing_slot;
|
||||
TupleTableSlot *save_scantuple;
|
||||
|
||||
/*
|
||||
* If any of the input values are NULL, the constraint check is assumed
|
||||
* to pass (i.e., we assume the operators are strict).
|
||||
* If any of the input values are NULL, the constraint check is assumed to
|
||||
* pass (i.e., we assume the operators are strict).
|
||||
*/
|
||||
for (i = 0; i < index_natts; i++)
|
||||
{
|
||||
@ -1177,8 +1177,8 @@ check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo,
|
||||
}
|
||||
|
||||
/*
|
||||
* Search the tuples that are in the index for any violations,
|
||||
* including tuples that aren't visible yet.
|
||||
* Search the tuples that are in the index for any violations, including
|
||||
* tuples that aren't visible yet.
|
||||
*/
|
||||
InitDirtySnapshot(DirtySnapshot);
|
||||
|
||||
@ -1205,8 +1205,8 @@ check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo,
|
||||
econtext->ecxt_scantuple = existing_slot;
|
||||
|
||||
/*
|
||||
* May have to restart scan from this point if a potential
|
||||
* conflict is found.
|
||||
* May have to restart scan from this point if a potential conflict is
|
||||
* found.
|
||||
*/
|
||||
retry:
|
||||
conflict = false;
|
||||
@ -1217,11 +1217,11 @@ retry:
|
||||
while ((tup = index_getnext(index_scan,
|
||||
ForwardScanDirection)) != NULL)
|
||||
{
|
||||
TransactionId xwait;
|
||||
TransactionId xwait;
|
||||
Datum existing_values[INDEX_MAX_KEYS];
|
||||
bool existing_isnull[INDEX_MAX_KEYS];
|
||||
char *error_new;
|
||||
char *error_existing;
|
||||
char *error_new;
|
||||
char *error_existing;
|
||||
|
||||
/*
|
||||
* Ignore the entry for the tuple we're trying to check.
|
||||
@ -1239,7 +1239,7 @@ retry:
|
||||
* Extract the index column values and isnull flags from the existing
|
||||
* tuple.
|
||||
*/
|
||||
ExecStoreTuple(tup, existing_slot, InvalidBuffer, false);
|
||||
ExecStoreTuple(tup, existing_slot, InvalidBuffer, false);
|
||||
FormIndexDatum(indexInfo, existing_slot, estate,
|
||||
existing_values, existing_isnull);
|
||||
|
||||
@ -1251,12 +1251,13 @@ retry:
|
||||
existing_values,
|
||||
existing_isnull,
|
||||
values))
|
||||
continue; /* tuple doesn't actually match, so no conflict */
|
||||
continue; /* tuple doesn't actually match, so no
|
||||
* conflict */
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point we have either a conflict or a potential conflict.
|
||||
* If we're not supposed to raise error, just return the fact of the
|
||||
* At this point we have either a conflict or a potential conflict. If
|
||||
* we're not supposed to raise error, just return the fact of the
|
||||
* potential conflict without waiting to see if it's real.
|
||||
*/
|
||||
if (errorOK)
|
||||
@ -1267,7 +1268,7 @@ retry:
|
||||
|
||||
/*
|
||||
* If an in-progress transaction is affecting the visibility of this
|
||||
* tuple, we need to wait for it to complete and then recheck. For
|
||||
* tuple, we need to wait for it to complete and then recheck. For
|
||||
* simplicity we do rechecking by just restarting the whole scan ---
|
||||
* this case probably doesn't happen often enough to be worth trying
|
||||
* harder, and anyway we don't want to hold any index internal locks
|
||||
@ -1308,15 +1309,15 @@ retry:
|
||||
index_endscan(index_scan);
|
||||
|
||||
/*
|
||||
* We should have found our tuple in the index, unless we exited the
|
||||
* loop early because of conflict. Complain if not.
|
||||
* We should have found our tuple in the index, unless we exited the loop
|
||||
* early because of conflict. Complain if not.
|
||||
*/
|
||||
if (!found_self && !conflict)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("failed to re-find tuple within index \"%s\"",
|
||||
RelationGetRelationName(index)),
|
||||
errhint("This may be because of a non-immutable index expression.")));
|
||||
errhint("This may be because of a non-immutable index expression.")));
|
||||
|
||||
econtext->ecxt_scantuple = save_scantuple;
|
||||
|
||||
@ -1327,7 +1328,7 @@ retry:
|
||||
|
||||
/*
|
||||
* Check existing tuple's index values to see if it really matches the
|
||||
* exclusion condition against the new_values. Returns true if conflict.
|
||||
* exclusion condition against the new_values. Returns true if conflict.
|
||||
*/
|
||||
static bool
|
||||
index_recheck_constraint(Relation index, Oid *constr_procs,
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.141 2010/02/14 18:42:14 rhaas Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.142 2010/02/26 02:00:41 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -636,8 +636,8 @@ fmgr_sql(PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* For simplicity, we require callers to support both set eval modes.
|
||||
* There are cases where we must use one or must use the other, and
|
||||
* it's not really worthwhile to postpone the check till we know.
|
||||
* But note we do not require caller to provide an expectedDesc.
|
||||
* it's not really worthwhile to postpone the check till we know. But
|
||||
* note we do not require caller to provide an expectedDesc.
|
||||
*/
|
||||
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
|
||||
(rsi->allowedModes & SFRM_ValuePerCall) == 0 ||
|
||||
@ -1042,7 +1042,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
|
||||
AssertArg(!IsPolymorphicType(rettype));
|
||||
|
||||
if (modifyTargetList)
|
||||
*modifyTargetList = false; /* initialize for no change */
|
||||
*modifyTargetList = false; /* initialize for no change */
|
||||
if (junkFilter)
|
||||
*junkFilter = NULL; /* initialize in case of VOID result */
|
||||
|
||||
@ -1219,7 +1219,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
|
||||
/*
|
||||
* Verify that the targetlist matches the return tuple type. We scan
|
||||
* the non-deleted attributes to ensure that they match the datatypes
|
||||
* of the non-resjunk columns. For deleted attributes, insert NULL
|
||||
* of the non-resjunk columns. For deleted attributes, insert NULL
|
||||
* result columns if the caller asked for that.
|
||||
*/
|
||||
tupnatts = tupdesc->natts;
|
||||
@ -1254,7 +1254,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
|
||||
attr = tupdesc->attrs[colindex - 1];
|
||||
if (attr->attisdropped && modifyTargetList)
|
||||
{
|
||||
Expr *null_expr;
|
||||
Expr *null_expr;
|
||||
|
||||
/* The type of the null we insert isn't important */
|
||||
null_expr = (Expr *) makeConst(INT4OID,
|
||||
@ -1311,17 +1311,17 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
|
||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||
errmsg("return type mismatch in function declared to return %s",
|
||||
format_type_be(rettype)),
|
||||
errdetail("Final statement returns too few columns.")));
|
||||
errdetail("Final statement returns too few columns.")));
|
||||
if (modifyTargetList)
|
||||
{
|
||||
Expr *null_expr;
|
||||
Expr *null_expr;
|
||||
|
||||
/* The type of the null we insert isn't important */
|
||||
null_expr = (Expr *) makeConst(INT4OID,
|
||||
-1,
|
||||
sizeof(int32),
|
||||
(Datum) 0,
|
||||
true, /* isnull */
|
||||
true, /* isnull */
|
||||
true /* byval */ );
|
||||
newtlist = lappend(newtlist,
|
||||
makeTargetEntry(null_expr,
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Copyright (c) 2001-2010, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.24 2010/01/02 16:57:41 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.25 2010/02/26 02:00:41 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -17,10 +17,10 @@
|
||||
|
||||
#include "executor/instrument.h"
|
||||
|
||||
BufferUsage pgBufferUsage;
|
||||
BufferUsage pgBufferUsage;
|
||||
|
||||
static void BufferUsageAccumDiff(BufferUsage *dst,
|
||||
const BufferUsage *add, const BufferUsage *sub);
|
||||
const BufferUsage *add, const BufferUsage *sub);
|
||||
|
||||
/* Allocate new instrumentation structure(s) */
|
||||
Instrumentation *
|
||||
@ -34,7 +34,7 @@ InstrAlloc(int n, int instrument_options)
|
||||
instr = palloc0(n * sizeof(Instrumentation));
|
||||
if (instrument_options & INSTRUMENT_BUFFERS)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
instr[i].needs_bufusage = true;
|
||||
@ -80,7 +80,7 @@ InstrStopNode(Instrumentation *instr, double nTuples)
|
||||
/* Adds delta of buffer usage to node's count. */
|
||||
if (instr->needs_bufusage)
|
||||
BufferUsageAccumDiff(&instr->bufusage,
|
||||
&pgBufferUsage, &instr->bufusage_start);
|
||||
&pgBufferUsage, &instr->bufusage_start);
|
||||
|
||||
/* Is this the first tuple of this cycle? */
|
||||
if (!instr->running)
|
||||
|
@ -55,7 +55,7 @@
|
||||
* it is completely forbidden for functions to modify pass-by-ref inputs,
|
||||
* but in the aggregate case we know the left input is either the initial
|
||||
* transition value or a previous function result, and in either case its
|
||||
* value need not be preserved. See int8inc() for an example. Notice that
|
||||
* value need not be preserved. See int8inc() for an example. Notice that
|
||||
* advance_transition_function() is coded to avoid a data copy step when
|
||||
* the previous transition value pointer is returned. Also, some
|
||||
* transition functions want to store working state in addition to the
|
||||
@ -71,7 +71,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.174 2010/02/14 18:42:14 rhaas Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.175 2010/02/26 02:00:41 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -135,12 +135,12 @@ typedef struct AggStatePerAggData
|
||||
|
||||
/* number of sorting columns to consider in DISTINCT comparisons */
|
||||
/* (this is either zero or the same as numSortCols) */
|
||||
int numDistinctCols;
|
||||
int numDistinctCols;
|
||||
|
||||
/* deconstructed sorting information (arrays of length numSortCols) */
|
||||
AttrNumber *sortColIdx;
|
||||
Oid *sortOperators;
|
||||
bool *sortNullsFirst;
|
||||
Oid *sortOperators;
|
||||
bool *sortNullsFirst;
|
||||
|
||||
/*
|
||||
* fmgr lookup data for input columns' equality operators --- only
|
||||
@ -170,12 +170,12 @@ typedef struct AggStatePerAggData
|
||||
transtypeByVal;
|
||||
|
||||
/*
|
||||
* Stuff for evaluation of inputs. We used to just use ExecEvalExpr, but
|
||||
* Stuff for evaluation of inputs. We used to just use ExecEvalExpr, but
|
||||
* with the addition of ORDER BY we now need at least a slot for passing
|
||||
* data to the sort object, which requires a tupledesc, so we might as
|
||||
* well go whole hog and use ExecProject too.
|
||||
*/
|
||||
TupleDesc evaldesc; /* descriptor of input tuples */
|
||||
TupleDesc evaldesc; /* descriptor of input tuples */
|
||||
ProjectionInfo *evalproj; /* projection machinery */
|
||||
|
||||
/*
|
||||
@ -190,7 +190,7 @@ typedef struct AggStatePerAggData
|
||||
* input tuple group and updated for each input tuple.
|
||||
*
|
||||
* For a simple (non DISTINCT/ORDER BY) aggregate, we just feed the input
|
||||
* values straight to the transition function. If it's DISTINCT or
|
||||
* values straight to the transition function. If it's DISTINCT or
|
||||
* requires ORDER BY, we pass the input values into a Tuplesort object;
|
||||
* then at completion of the input tuple group, we scan the sorted values,
|
||||
* eliminate duplicates if needed, and run the transition function on the
|
||||
@ -257,11 +257,11 @@ static void advance_transition_function(AggState *aggstate,
|
||||
FunctionCallInfoData *fcinfo);
|
||||
static void advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup);
|
||||
static void process_ordered_aggregate_single(AggState *aggstate,
|
||||
AggStatePerAgg peraggstate,
|
||||
AggStatePerGroup pergroupstate);
|
||||
AggStatePerAgg peraggstate,
|
||||
AggStatePerGroup pergroupstate);
|
||||
static void process_ordered_aggregate_multi(AggState *aggstate,
|
||||
AggStatePerAgg peraggstate,
|
||||
AggStatePerGroup pergroupstate);
|
||||
AggStatePerAgg peraggstate,
|
||||
AggStatePerGroup pergroupstate);
|
||||
static void finalize_aggregate(AggState *aggstate,
|
||||
AggStatePerAgg peraggstate,
|
||||
AggStatePerGroup pergroupstate,
|
||||
@ -307,8 +307,8 @@ initialize_aggregates(AggState *aggstate,
|
||||
tuplesort_end(peraggstate->sortstate);
|
||||
|
||||
/*
|
||||
* We use a plain Datum sorter when there's a single input
|
||||
* column; otherwise sort the full tuple. (See comments for
|
||||
* We use a plain Datum sorter when there's a single input column;
|
||||
* otherwise sort the full tuple. (See comments for
|
||||
* process_ordered_aggregate_single.)
|
||||
*/
|
||||
peraggstate->sortstate =
|
||||
@ -488,11 +488,11 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
|
||||
Assert(slot->tts_nvalid == peraggstate->numInputs);
|
||||
|
||||
/*
|
||||
* If the transfn is strict, we want to check for nullity
|
||||
* before storing the row in the sorter, to save space if
|
||||
* there are a lot of nulls. Note that we must only check
|
||||
* numArguments columns, not numInputs, since nullity in
|
||||
* columns used only for sorting is not relevant here.
|
||||
* If the transfn is strict, we want to check for nullity before
|
||||
* storing the row in the sorter, to save space if there are a lot
|
||||
* of nulls. Note that we must only check numArguments columns,
|
||||
* not numInputs, since nullity in columns used only for sorting
|
||||
* is not relevant here.
|
||||
*/
|
||||
if (peraggstate->transfn.fn_strict)
|
||||
{
|
||||
@ -537,7 +537,7 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
|
||||
/*
|
||||
* Run the transition function for a DISTINCT or ORDER BY aggregate
|
||||
* with only one input. This is called after we have completed
|
||||
* entering all the input values into the sort object. We complete the
|
||||
* entering all the input values into the sort object. We complete the
|
||||
* sort, read out the values in sorted order, and run the transition
|
||||
* function on each value (applying DISTINCT if appropriate).
|
||||
*
|
||||
@ -559,11 +559,11 @@ process_ordered_aggregate_single(AggState *aggstate,
|
||||
AggStatePerGroup pergroupstate)
|
||||
{
|
||||
Datum oldVal = (Datum) 0;
|
||||
bool oldIsNull = true;
|
||||
bool oldIsNull = true;
|
||||
bool haveOldVal = false;
|
||||
MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory;
|
||||
MemoryContext oldContext;
|
||||
bool isDistinct = (peraggstate->numDistinctCols > 0);
|
||||
bool isDistinct = (peraggstate->numDistinctCols > 0);
|
||||
Datum *newVal;
|
||||
bool *isNull;
|
||||
FunctionCallInfoData fcinfo;
|
||||
@ -632,7 +632,7 @@ process_ordered_aggregate_single(AggState *aggstate,
|
||||
/*
|
||||
* Run the transition function for a DISTINCT or ORDER BY aggregate
|
||||
* with more than one input. This is called after we have completed
|
||||
* entering all the input values into the sort object. We complete the
|
||||
* entering all the input values into the sort object. We complete the
|
||||
* sort, read out the values in sorted order, and run the transition
|
||||
* function on each value (applying DISTINCT if appropriate).
|
||||
*
|
||||
@ -647,10 +647,10 @@ process_ordered_aggregate_multi(AggState *aggstate,
|
||||
FunctionCallInfoData fcinfo;
|
||||
TupleTableSlot *slot1 = peraggstate->evalslot;
|
||||
TupleTableSlot *slot2 = peraggstate->uniqslot;
|
||||
int numArguments = peraggstate->numArguments;
|
||||
int numDistinctCols = peraggstate->numDistinctCols;
|
||||
bool haveOldValue = false;
|
||||
int i;
|
||||
int numArguments = peraggstate->numArguments;
|
||||
int numDistinctCols = peraggstate->numDistinctCols;
|
||||
bool haveOldValue = false;
|
||||
int i;
|
||||
|
||||
tuplesort_performsort(peraggstate->sortstate);
|
||||
|
||||
@ -983,9 +983,9 @@ ExecAgg(AggState *node)
|
||||
}
|
||||
|
||||
/*
|
||||
* Exit if nothing left to do. (We must do the ps_TupFromTlist check
|
||||
* first, because in some cases agg_done gets set before we emit the
|
||||
* final aggregate tuple, and we have to finish running SRFs for it.)
|
||||
* Exit if nothing left to do. (We must do the ps_TupFromTlist check
|
||||
* first, because in some cases agg_done gets set before we emit the final
|
||||
* aggregate tuple, and we have to finish running SRFs for it.)
|
||||
*/
|
||||
if (node->agg_done)
|
||||
return NULL;
|
||||
@ -1066,9 +1066,9 @@ agg_retrieve_direct(AggState *aggstate)
|
||||
|
||||
/*
|
||||
* Clear the per-output-tuple context for each group, as well as
|
||||
* aggcontext (which contains any pass-by-ref transvalues of the
|
||||
* old group). We also clear any child contexts of the aggcontext;
|
||||
* some aggregate functions store working state in such contexts.
|
||||
* aggcontext (which contains any pass-by-ref transvalues of the old
|
||||
* group). We also clear any child contexts of the aggcontext; some
|
||||
* aggregate functions store working state in such contexts.
|
||||
*/
|
||||
ResetExprContext(econtext);
|
||||
|
||||
@ -1402,8 +1402,8 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
|
||||
* structures and transition values. NOTE: the details of what is stored
|
||||
* in aggcontext and what is stored in the regular per-query memory
|
||||
* context are driven by a simple decision: we want to reset the
|
||||
* aggcontext at group boundaries (if not hashing) and in ExecReScanAgg
|
||||
* to recover no-longer-wanted space.
|
||||
* aggcontext at group boundaries (if not hashing) and in ExecReScanAgg to
|
||||
* recover no-longer-wanted space.
|
||||
*/
|
||||
aggstate->aggcontext =
|
||||
AllocSetContextCreate(CurrentMemoryContext,
|
||||
@ -1539,7 +1539,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
|
||||
int numInputs;
|
||||
int numSortCols;
|
||||
int numDistinctCols;
|
||||
List *sortlist;
|
||||
List *sortlist;
|
||||
HeapTuple aggTuple;
|
||||
Form_pg_aggregate aggform;
|
||||
Oid aggtranstype;
|
||||
@ -1735,9 +1735,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* If we're doing either DISTINCT or ORDER BY, then we have a list
|
||||
* of SortGroupClause nodes; fish out the data in them and
|
||||
* stick them into arrays.
|
||||
* If we're doing either DISTINCT or ORDER BY, then we have a list of
|
||||
* SortGroupClause nodes; fish out the data in them and stick them
|
||||
* into arrays.
|
||||
*
|
||||
* Note that by construction, if there is a DISTINCT clause then the
|
||||
* ORDER BY clause is a prefix of it (see transformDistinctClause).
|
||||
@ -1976,8 +1976,8 @@ ExecReScanAgg(AggState *node, ExprContext *exprCtxt)
|
||||
*
|
||||
* The transition and/or final functions of an aggregate may want to verify
|
||||
* that they are being called as aggregates, rather than as plain SQL
|
||||
* functions. They should use this function to do so. The return value
|
||||
* is nonzero if being called as an aggregate, or zero if not. (Specific
|
||||
* functions. They should use this function to do so. The return value
|
||||
* is nonzero if being called as an aggregate, or zero if not. (Specific
|
||||
* nonzero values are AGG_CONTEXT_AGGREGATE or AGG_CONTEXT_WINDOW, but more
|
||||
* values could conceivably appear in future.)
|
||||
*
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.128 2010/02/14 18:42:14 rhaas Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.129 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -458,7 +458,7 @@ ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
|
||||
/*
|
||||
* Set nbuckets to achieve an average bucket load of NTUP_PER_BUCKET when
|
||||
* memory is filled. Set nbatch to the smallest power of 2 that appears
|
||||
* sufficient. The Min() steps limit the results so that the pointer
|
||||
* sufficient. The Min() steps limit the results so that the pointer
|
||||
* arrays we'll try to allocate do not exceed work_mem.
|
||||
*/
|
||||
max_pointers = (work_mem * 1024L) / sizeof(void *);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.138 2010/01/02 16:57:42 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.139 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -240,9 +240,9 @@ ExecIndexEvalRuntimeKeys(ExprContext *econtext,
|
||||
* 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.
|
||||
* 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 = ExecEvalExpr(key_expr,
|
||||
econtext,
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeLockRows.c,v 1.3 2010/01/02 16:57:42 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeLockRows.c,v 1.4 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -154,8 +154,8 @@ lnext:
|
||||
tuple.t_self = copyTuple->t_self;
|
||||
|
||||
/*
|
||||
* Need to run a recheck subquery. Initialize EPQ state
|
||||
* if we didn't do so already.
|
||||
* Need to run a recheck subquery. Initialize EPQ state if we
|
||||
* didn't do so already.
|
||||
*/
|
||||
if (!epq_started)
|
||||
{
|
||||
@ -185,9 +185,9 @@ lnext:
|
||||
{
|
||||
/*
|
||||
* First, fetch a copy of any rows that were successfully locked
|
||||
* without any update having occurred. (We do this in a separate
|
||||
* pass so as to avoid overhead in the common case where there are
|
||||
* no concurrent updates.)
|
||||
* without any update having occurred. (We do this in a separate pass
|
||||
* so as to avoid overhead in the common case where there are no
|
||||
* concurrent updates.)
|
||||
*/
|
||||
foreach(lc, node->lr_rowMarks)
|
||||
{
|
||||
@ -209,12 +209,14 @@ lnext:
|
||||
heap_copytuple(&tuple));
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now fetch any non-locked source rows --- the EPQ logic knows
|
||||
* how to do that.
|
||||
* Now fetch any non-locked source rows --- the EPQ logic knows how to
|
||||
* do that.
|
||||
*/
|
||||
EvalPlanQualSetSlot(&node->lr_epqstate, slot);
|
||||
EvalPlanQualFetchRowMarks(&node->lr_epqstate);
|
||||
|
||||
/*
|
||||
* And finally we can re-evaluate the tuple.
|
||||
*/
|
||||
@ -272,15 +274,15 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags)
|
||||
outerPlanState(lrstate) = ExecInitNode(outerPlan, estate, eflags);
|
||||
|
||||
/*
|
||||
* LockRows nodes do no projections, so initialize projection info for this
|
||||
* node appropriately
|
||||
* LockRows nodes do no projections, so initialize projection info for
|
||||
* this node appropriately
|
||||
*/
|
||||
ExecAssignResultTypeFromTL(&lrstate->ps);
|
||||
lrstate->ps.ps_ProjInfo = NULL;
|
||||
|
||||
/*
|
||||
* Locate the ExecRowMark(s) that this node is responsible for.
|
||||
* (InitPlan should already have built the global list of ExecRowMarks.)
|
||||
* Locate the ExecRowMark(s) that this node is responsible for. (InitPlan
|
||||
* should already have built the global list of ExecRowMarks.)
|
||||
*/
|
||||
lrstate->lr_rowMarks = NIL;
|
||||
foreach(lc, node->rowMarks)
|
||||
@ -307,10 +309,10 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags)
|
||||
rc->rti);
|
||||
|
||||
/*
|
||||
* Only locking rowmarks go into our own list. Non-locking marks
|
||||
* are passed off to the EvalPlanQual machinery. This is because
|
||||
* we don't want to bother fetching non-locked rows unless we
|
||||
* actually have to do an EPQ recheck.
|
||||
* Only locking rowmarks go into our own list. Non-locking marks are
|
||||
* passed off to the EvalPlanQual machinery. This is because we don't
|
||||
* want to bother fetching non-locked rows unless we actually have to
|
||||
* do an EPQ recheck.
|
||||
*/
|
||||
if (RowMarkRequiresRowShareLock(erm->markType))
|
||||
lrstate->lr_rowMarks = lappend(lrstate->lr_rowMarks, erm);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.100 2010/01/05 23:25:36 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.101 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -507,7 +507,7 @@ check_constant_qual(List *qual, bool *is_const_false)
|
||||
|
||||
foreach(lc, qual)
|
||||
{
|
||||
Const *con = (Const *) lfirst(lc);
|
||||
Const *con = (Const *) lfirst(lc);
|
||||
|
||||
if (!con || !IsA(con, Const))
|
||||
return false;
|
||||
|
@ -8,12 +8,12 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeModifyTable.c,v 1.6 2010/02/08 04:33:54 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeModifyTable.c,v 1.7 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
/* INTERFACE ROUTINES
|
||||
* ExecInitModifyTable - initialize the ModifyTable node
|
||||
* ExecInitModifyTable - initialize the ModifyTable node
|
||||
* ExecModifyTable - retrieve the next tuple from the node
|
||||
* ExecEndModifyTable - shut down the ModifyTable node
|
||||
* ExecReScanModifyTable - rescan the ModifyTable node
|
||||
@ -30,7 +30,7 @@
|
||||
*
|
||||
* If the query specifies RETURNING, then the ModifyTable returns a
|
||||
* RETURNING tuple after completing each row insert, update, or delete.
|
||||
* It must be called again to continue the operation. Without RETURNING,
|
||||
* It must be called again to continue the operation. Without RETURNING,
|
||||
* we just loop within the node until all the work is done, then
|
||||
* return NULL. This avoids useless call/return overhead.
|
||||
*/
|
||||
@ -215,7 +215,7 @@ ExecInsert(TupleTableSlot *slot,
|
||||
* slot should not try to clear it.
|
||||
*/
|
||||
TupleTableSlot *newslot = estate->es_trig_tuple_slot;
|
||||
TupleDesc tupdesc = RelationGetDescr(resultRelationDesc);
|
||||
TupleDesc tupdesc = RelationGetDescr(resultRelationDesc);
|
||||
|
||||
if (newslot->tts_tupleDescriptor != tupdesc)
|
||||
ExecSetSlotDescriptor(newslot, tupdesc);
|
||||
@ -470,7 +470,7 @@ ExecUpdate(ItemPointer tupleid,
|
||||
* slot should not try to clear it.
|
||||
*/
|
||||
TupleTableSlot *newslot = estate->es_trig_tuple_slot;
|
||||
TupleDesc tupdesc = RelationGetDescr(resultRelationDesc);
|
||||
TupleDesc tupdesc = RelationGetDescr(resultRelationDesc);
|
||||
|
||||
if (newslot->tts_tupleDescriptor != tupdesc)
|
||||
ExecSetSlotDescriptor(newslot, tupdesc);
|
||||
@ -646,9 +646,9 @@ fireASTriggers(ModifyTableState *node)
|
||||
TupleTableSlot *
|
||||
ExecModifyTable(ModifyTableState *node)
|
||||
{
|
||||
EState *estate = node->ps.state;
|
||||
CmdType operation = node->operation;
|
||||
PlanState *subplanstate;
|
||||
EState *estate = node->ps.state;
|
||||
CmdType operation = node->operation;
|
||||
PlanState *subplanstate;
|
||||
JunkFilter *junkfilter;
|
||||
TupleTableSlot *slot;
|
||||
TupleTableSlot *planSlot;
|
||||
@ -666,8 +666,8 @@ ExecModifyTable(ModifyTableState *node)
|
||||
|
||||
/*
|
||||
* es_result_relation_info must point to the currently active result
|
||||
* relation. (Note we assume that ModifyTable nodes can't be nested.)
|
||||
* We want it to be NULL whenever we're not within ModifyTable, though.
|
||||
* relation. (Note we assume that ModifyTable nodes can't be nested.) We
|
||||
* want it to be NULL whenever we're not within ModifyTable, though.
|
||||
*/
|
||||
estate->es_result_relation_info =
|
||||
estate->es_result_relations + node->mt_whichplan;
|
||||
@ -791,8 +791,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
|
||||
|
||||
/*
|
||||
* This should NOT get called during EvalPlanQual; we should have passed
|
||||
* a subplan tree to EvalPlanQual, instead. Use a runtime test not just
|
||||
* This should NOT get called during EvalPlanQual; we should have passed a
|
||||
* subplan tree to EvalPlanQual, instead. Use a runtime test not just
|
||||
* Assert because this condition is easy to miss in testing ...
|
||||
*/
|
||||
if (estate->es_epqTuple != NULL)
|
||||
@ -846,8 +846,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
ExprContext *econtext;
|
||||
|
||||
/*
|
||||
* Initialize result tuple slot and assign its rowtype using the
|
||||
* first RETURNING list. We assume the rest will look the same.
|
||||
* Initialize result tuple slot and assign its rowtype using the first
|
||||
* RETURNING list. We assume the rest will look the same.
|
||||
*/
|
||||
tupDesc = ExecTypeFromTL((List *) linitial(node->returningLists),
|
||||
false);
|
||||
@ -881,8 +881,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
else
|
||||
{
|
||||
/*
|
||||
* We still must construct a dummy result tuple type, because
|
||||
* InitPlan expects one (maybe should change that?).
|
||||
* We still must construct a dummy result tuple type, because InitPlan
|
||||
* expects one (maybe should change that?).
|
||||
*/
|
||||
tupDesc = ExecTypeFromTL(NIL, false);
|
||||
ExecInitResultTupleSlot(estate, &mtstate->ps);
|
||||
@ -892,10 +892,10 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have any secondary relations in an UPDATE or DELETE, they need
|
||||
* to be treated like non-locked relations in SELECT FOR UPDATE, ie,
|
||||
* the EvalPlanQual mechanism needs to be told about them. Locate
|
||||
* the relevant ExecRowMarks.
|
||||
* If we have any secondary relations in an UPDATE or DELETE, they need to
|
||||
* be treated like non-locked relations in SELECT FOR UPDATE, ie, the
|
||||
* EvalPlanQual mechanism needs to be told about them. Locate the
|
||||
* relevant ExecRowMarks.
|
||||
*/
|
||||
foreach(l, node->rowMarks)
|
||||
{
|
||||
@ -925,12 +925,12 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
|
||||
/*
|
||||
* Initialize the junk filter(s) if needed. INSERT queries need a filter
|
||||
* if there are any junk attrs in the tlist. UPDATE and DELETE
|
||||
* always need a filter, since there's always a junk 'ctid' attribute
|
||||
* present --- no need to look first.
|
||||
* if there are any junk attrs in the tlist. UPDATE and DELETE always
|
||||
* need a filter, since there's always a junk 'ctid' attribute present ---
|
||||
* no need to look first.
|
||||
*
|
||||
* If there are multiple result relations, each one needs its own junk
|
||||
* filter. Note multiple rels are only possible for UPDATE/DELETE, so we
|
||||
* filter. Note multiple rels are only possible for UPDATE/DELETE, so we
|
||||
* can't be fooled by some needing a filter and some not.
|
||||
*
|
||||
* This section of code is also a convenient place to verify that the
|
||||
@ -999,9 +999,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a tuple table slot for use for trigger output tuples.
|
||||
* In a plan containing multiple ModifyTable nodes, all can share
|
||||
* one such slot, so we keep it in the estate.
|
||||
* Set up a tuple table slot for use for trigger output tuples. In a plan
|
||||
* containing multiple ModifyTable nodes, all can share one such slot, so
|
||||
* we keep it in the estate.
|
||||
*/
|
||||
if (estate->es_trig_tuple_slot == NULL)
|
||||
estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate);
|
||||
@ -1020,7 +1020,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
void
|
||||
ExecEndModifyTable(ModifyTableState *node)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Free the exprcontext
|
||||
@ -1040,7 +1040,7 @@ ExecEndModifyTable(ModifyTableState *node)
|
||||
/*
|
||||
* shut down subplans
|
||||
*/
|
||||
for (i=0; i<node->mt_nplans; i++)
|
||||
for (i = 0; i < node->mt_nplans; i++)
|
||||
ExecEndNode(node->mt_plans[i]);
|
||||
}
|
||||
|
||||
@ -1048,8 +1048,8 @@ void
|
||||
ExecReScanModifyTable(ModifyTableState *node, ExprContext *exprCtxt)
|
||||
{
|
||||
/*
|
||||
* Currently, we don't need to support rescan on ModifyTable nodes.
|
||||
* The semantics of that would be a bit debatable anyway.
|
||||
* Currently, we don't need to support rescan on ModifyTable nodes. The
|
||||
* semantics of that would be a bit debatable anyway.
|
||||
*/
|
||||
elog(ERROR, "ExecReScanModifyTable is not implemented");
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSeqscan.c,v 1.69 2010/01/02 16:57:45 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSeqscan.c,v 1.70 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -92,9 +92,8 @@ static bool
|
||||
SeqRecheck(SeqScanState *node, TupleTableSlot *slot)
|
||||
{
|
||||
/*
|
||||
* Note that unlike IndexScan, SeqScan never use keys in
|
||||
* heap_beginscan (and this is very bad) - so, here we do not check
|
||||
* are keys ok or not.
|
||||
* Note that unlike IndexScan, SeqScan never use keys in heap_beginscan
|
||||
* (and this is very bad) - so, here we do not check are keys ok or not.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.44 2010/01/02 16:57:45 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.45 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,9 +53,9 @@ SubqueryNext(SubqueryScanState *node)
|
||||
slot = ExecProcNode(node->subplan);
|
||||
|
||||
/*
|
||||
* We just return the subplan's result slot, rather than expending
|
||||
* extra cycles for ExecCopySlot(). (Our own ScanTupleSlot is used
|
||||
* only for EvalPlanQual rechecks.)
|
||||
* We just return the subplan's result slot, rather than expending extra
|
||||
* cycles for ExecCopySlot(). (Our own ScanTupleSlot is used only for
|
||||
* EvalPlanQual rechecks.)
|
||||
*/
|
||||
return slot;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeWindowAgg.c,v 1.11 2010/02/14 18:42:14 rhaas Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeWindowAgg.c,v 1.12 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -416,8 +416,8 @@ eval_windowaggregates(WindowAggState *winstate)
|
||||
* need the current aggregate value. This is considerably more efficient
|
||||
* than the naive approach of re-running the entire aggregate calculation
|
||||
* for each current row. It does assume that the final function doesn't
|
||||
* damage the running transition value, but we have the same assumption
|
||||
* in nodeAgg.c too (when it rescans an existing hash table).
|
||||
* damage the running transition value, but we have the same assumption in
|
||||
* nodeAgg.c too (when it rescans an existing hash table).
|
||||
*
|
||||
* For other frame start rules, we discard the aggregate state and re-run
|
||||
* the aggregates whenever the frame head row moves. We can still
|
||||
@ -434,11 +434,11 @@ eval_windowaggregates(WindowAggState *winstate)
|
||||
* accumulated into the aggregate transition values. Whenever we start a
|
||||
* new peer group, we accumulate forward to the end of the peer group.
|
||||
*
|
||||
* TODO: Rerunning aggregates from the frame start can be pretty slow.
|
||||
* For some aggregates like SUM and COUNT we could avoid that by
|
||||
* implementing a "negative transition function" that would be called for
|
||||
* each row as it exits the frame. We'd have to think about avoiding
|
||||
* recalculation of volatile arguments of aggregate functions, too.
|
||||
* TODO: Rerunning aggregates from the frame start can be pretty slow. For
|
||||
* some aggregates like SUM and COUNT we could avoid that by implementing
|
||||
* a "negative transition function" that would be called for each row as
|
||||
* it exits the frame. We'd have to think about avoiding recalculation of
|
||||
* volatile arguments of aggregate functions, too.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -447,8 +447,8 @@ eval_windowaggregates(WindowAggState *winstate)
|
||||
update_frameheadpos(agg_winobj, winstate->temp_slot_1);
|
||||
|
||||
/*
|
||||
* Initialize aggregates on first call for partition, or if the frame
|
||||
* head position moved since last time.
|
||||
* Initialize aggregates on first call for partition, or if the frame head
|
||||
* position moved since last time.
|
||||
*/
|
||||
if (winstate->currentpos == 0 ||
|
||||
winstate->frameheadpos != winstate->aggregatedbase)
|
||||
@ -468,8 +468,8 @@ eval_windowaggregates(WindowAggState *winstate)
|
||||
}
|
||||
|
||||
/*
|
||||
* If we created a mark pointer for aggregates, keep it pushed up
|
||||
* to frame head, so that tuplestore can discard unnecessary rows.
|
||||
* If we created a mark pointer for aggregates, keep it pushed up to
|
||||
* frame head, so that tuplestore can discard unnecessary rows.
|
||||
*/
|
||||
if (agg_winobj->markptr >= 0)
|
||||
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
|
||||
@ -485,9 +485,9 @@ eval_windowaggregates(WindowAggState *winstate)
|
||||
/*
|
||||
* In UNBOUNDED_FOLLOWING mode, we don't have to recalculate aggregates
|
||||
* except when the frame head moves. In END_CURRENT_ROW mode, we only
|
||||
* have to recalculate when the frame head moves or currentpos has advanced
|
||||
* past the place we'd aggregated up to. Check for these cases and if
|
||||
* so, reuse the saved result values.
|
||||
* have to recalculate when the frame head moves or currentpos has
|
||||
* advanced past the place we'd aggregated up to. Check for these cases
|
||||
* and if so, reuse the saved result values.
|
||||
*/
|
||||
if ((winstate->frameOptions & (FRAMEOPTION_END_UNBOUNDED_FOLLOWING |
|
||||
FRAMEOPTION_END_CURRENT_ROW)) &&
|
||||
@ -508,7 +508,7 @@ eval_windowaggregates(WindowAggState *winstate)
|
||||
* Advance until we reach a row not in frame (or end of partition).
|
||||
*
|
||||
* Note the loop invariant: agg_row_slot is either empty or holds the row
|
||||
* at position aggregatedupto. We advance aggregatedupto after processing
|
||||
* at position aggregatedupto. We advance aggregatedupto after processing
|
||||
* a row.
|
||||
*/
|
||||
for (;;)
|
||||
@ -896,7 +896,7 @@ row_is_in_frame(WindowAggState *winstate, int64 pos, TupleTableSlot *slot)
|
||||
{
|
||||
if (frameOptions & FRAMEOPTION_ROWS)
|
||||
{
|
||||
int64 offset = DatumGetInt64(winstate->startOffsetValue);
|
||||
int64 offset = DatumGetInt64(winstate->startOffsetValue);
|
||||
|
||||
/* rows before current row + offset are out of frame */
|
||||
if (frameOptions & FRAMEOPTION_START_VALUE_PRECEDING)
|
||||
@ -937,7 +937,7 @@ row_is_in_frame(WindowAggState *winstate, int64 pos, TupleTableSlot *slot)
|
||||
{
|
||||
if (frameOptions & FRAMEOPTION_ROWS)
|
||||
{
|
||||
int64 offset = DatumGetInt64(winstate->endOffsetValue);
|
||||
int64 offset = DatumGetInt64(winstate->endOffsetValue);
|
||||
|
||||
/* rows after current row + offset are out of frame */
|
||||
if (frameOptions & FRAMEOPTION_END_VALUE_PRECEDING)
|
||||
@ -965,7 +965,7 @@ row_is_in_frame(WindowAggState *winstate, int64 pos, TupleTableSlot *slot)
|
||||
*
|
||||
* Uses the winobj's read pointer for any required fetches; hence, if the
|
||||
* frame mode is one that requires row comparisons, the winobj's mark must
|
||||
* not be past the currently known frame head. Also uses the specified slot
|
||||
* not be past the currently known frame head. Also uses the specified slot
|
||||
* for any required fetches.
|
||||
*/
|
||||
static void
|
||||
@ -1007,9 +1007,9 @@ update_frameheadpos(WindowObject winobj, TupleTableSlot *slot)
|
||||
/*
|
||||
* In RANGE START_CURRENT mode, frame head is the first row that
|
||||
* is a peer of current row. We search backwards from current,
|
||||
* which could be a bit inefficient if peer sets are large.
|
||||
* Might be better to have a separate read pointer that moves
|
||||
* forward tracking the frame head.
|
||||
* which could be a bit inefficient if peer sets are large. Might
|
||||
* be better to have a separate read pointer that moves forward
|
||||
* tracking the frame head.
|
||||
*/
|
||||
fhprev = winstate->currentpos - 1;
|
||||
for (;;)
|
||||
@ -1018,9 +1018,9 @@ update_frameheadpos(WindowObject winobj, TupleTableSlot *slot)
|
||||
if (fhprev < winstate->frameheadpos)
|
||||
break;
|
||||
if (!window_gettupleslot(winobj, fhprev, slot))
|
||||
break; /* start of partition */
|
||||
break; /* start of partition */
|
||||
if (!are_peers(winstate, slot, winstate->ss.ss_ScanTupleSlot))
|
||||
break; /* not peer of current row */
|
||||
break; /* not peer of current row */
|
||||
fhprev--;
|
||||
}
|
||||
winstate->frameheadpos = fhprev + 1;
|
||||
@ -1034,7 +1034,7 @@ update_frameheadpos(WindowObject winobj, TupleTableSlot *slot)
|
||||
if (frameOptions & FRAMEOPTION_ROWS)
|
||||
{
|
||||
/* In ROWS mode, bound is physically n before/after current */
|
||||
int64 offset = DatumGetInt64(winstate->startOffsetValue);
|
||||
int64 offset = DatumGetInt64(winstate->startOffsetValue);
|
||||
|
||||
if (frameOptions & FRAMEOPTION_START_VALUE_PRECEDING)
|
||||
offset = -offset;
|
||||
@ -1070,7 +1070,7 @@ update_frameheadpos(WindowObject winobj, TupleTableSlot *slot)
|
||||
*
|
||||
* Uses the winobj's read pointer for any required fetches; hence, if the
|
||||
* frame mode is one that requires row comparisons, the winobj's mark must
|
||||
* not be past the currently known frame tail. Also uses the specified slot
|
||||
* not be past the currently known frame tail. Also uses the specified slot
|
||||
* for any required fetches.
|
||||
*/
|
||||
static void
|
||||
@ -1122,9 +1122,9 @@ update_frametailpos(WindowObject winobj, TupleTableSlot *slot)
|
||||
for (;;)
|
||||
{
|
||||
if (!window_gettupleslot(winobj, ftnext, slot))
|
||||
break; /* end of partition */
|
||||
break; /* end of partition */
|
||||
if (!are_peers(winstate, slot, winstate->ss.ss_ScanTupleSlot))
|
||||
break; /* not peer of current row */
|
||||
break; /* not peer of current row */
|
||||
ftnext++;
|
||||
}
|
||||
winstate->frametailpos = ftnext - 1;
|
||||
@ -1138,7 +1138,7 @@ update_frametailpos(WindowObject winobj, TupleTableSlot *slot)
|
||||
if (frameOptions & FRAMEOPTION_ROWS)
|
||||
{
|
||||
/* In ROWS mode, bound is physically n before/after current */
|
||||
int64 offset = DatumGetInt64(winstate->endOffsetValue);
|
||||
int64 offset = DatumGetInt64(winstate->endOffsetValue);
|
||||
|
||||
if (frameOptions & FRAMEOPTION_END_VALUE_PRECEDING)
|
||||
offset = -offset;
|
||||
@ -1213,12 +1213,12 @@ ExecWindowAgg(WindowAggState *winstate)
|
||||
*/
|
||||
if (winstate->all_first)
|
||||
{
|
||||
int frameOptions = winstate->frameOptions;
|
||||
ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
|
||||
Datum value;
|
||||
bool isnull;
|
||||
int16 len;
|
||||
bool byval;
|
||||
int frameOptions = winstate->frameOptions;
|
||||
ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
|
||||
Datum value;
|
||||
bool isnull;
|
||||
int16 len;
|
||||
bool byval;
|
||||
|
||||
if (frameOptions & FRAMEOPTION_START_VALUE)
|
||||
{
|
||||
@ -1238,12 +1238,12 @@ ExecWindowAgg(WindowAggState *winstate)
|
||||
if (frameOptions & FRAMEOPTION_ROWS)
|
||||
{
|
||||
/* value is known to be int8 */
|
||||
int64 offset = DatumGetInt64(value);
|
||||
int64 offset = DatumGetInt64(value);
|
||||
|
||||
if (offset < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("frame starting offset must not be negative")));
|
||||
errmsg("frame starting offset must not be negative")));
|
||||
}
|
||||
}
|
||||
if (frameOptions & FRAMEOPTION_END_VALUE)
|
||||
@ -1264,12 +1264,12 @@ ExecWindowAgg(WindowAggState *winstate)
|
||||
if (frameOptions & FRAMEOPTION_ROWS)
|
||||
{
|
||||
/* value is known to be int8 */
|
||||
int64 offset = DatumGetInt64(value);
|
||||
int64 offset = DatumGetInt64(value);
|
||||
|
||||
if (offset < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("frame ending offset must not be negative")));
|
||||
errmsg("frame ending offset must not be negative")));
|
||||
}
|
||||
}
|
||||
winstate->all_first = false;
|
||||
@ -2146,8 +2146,8 @@ WinGetFuncArgInPartition(WindowObject winobj, int argno,
|
||||
*isout = false;
|
||||
if (set_mark)
|
||||
{
|
||||
int frameOptions = winstate->frameOptions;
|
||||
int64 mark_pos = abs_pos;
|
||||
int frameOptions = winstate->frameOptions;
|
||||
int64 mark_pos = abs_pos;
|
||||
|
||||
/*
|
||||
* In RANGE mode with a moving frame head, we must not let the
|
||||
@ -2155,10 +2155,10 @@ WinGetFuncArgInPartition(WindowObject winobj, int argno,
|
||||
* fetchable during future update_frameheadpos calls.
|
||||
*
|
||||
* XXX it is very ugly to pollute window functions' marks with
|
||||
* this consideration; it could for instance mask a logic bug
|
||||
* that lets a window function fetch rows before what it had
|
||||
* claimed was its mark. Perhaps use a separate mark for
|
||||
* frame head probes?
|
||||
* this consideration; it could for instance mask a logic bug that
|
||||
* lets a window function fetch rows before what it had claimed
|
||||
* was its mark. Perhaps use a separate mark for frame head
|
||||
* probes?
|
||||
*/
|
||||
if ((frameOptions & FRAMEOPTION_RANGE) &&
|
||||
!(frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING))
|
||||
@ -2245,8 +2245,8 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
|
||||
*isout = false;
|
||||
if (set_mark)
|
||||
{
|
||||
int frameOptions = winstate->frameOptions;
|
||||
int64 mark_pos = abs_pos;
|
||||
int frameOptions = winstate->frameOptions;
|
||||
int64 mark_pos = abs_pos;
|
||||
|
||||
/*
|
||||
* In RANGE mode with a moving frame head, we must not let the
|
||||
@ -2254,10 +2254,10 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
|
||||
* fetchable during future update_frameheadpos calls.
|
||||
*
|
||||
* XXX it is very ugly to pollute window functions' marks with
|
||||
* this consideration; it could for instance mask a logic bug
|
||||
* that lets a window function fetch rows before what it had
|
||||
* claimed was its mark. Perhaps use a separate mark for
|
||||
* frame head probes?
|
||||
* this consideration; it could for instance mask a logic bug that
|
||||
* lets a window function fetch rows before what it had claimed
|
||||
* was its mark. Perhaps use a separate mark for frame head
|
||||
* probes?
|
||||
*/
|
||||
if ((frameOptions & FRAMEOPTION_RANGE) &&
|
||||
!(frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING))
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.214 2010/02/14 18:42:14 rhaas Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.215 2010/02/26 02:00:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1268,10 +1268,9 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
|
||||
}
|
||||
|
||||
/*
|
||||
* If the plan has parameters, copy them into the portal. Note that
|
||||
* this must be done after revalidating the plan, because in dynamic
|
||||
* parameter cases the set of parameters could have changed during
|
||||
* re-parsing.
|
||||
* If the plan has parameters, copy them into the portal. Note that this
|
||||
* must be done after revalidating the plan, because in dynamic parameter
|
||||
* cases the set of parameters could have changed during re-parsing.
|
||||
*/
|
||||
if (paramLI)
|
||||
{
|
||||
|
Reference in New Issue
Block a user