------------------------------------------------------------------------
Index: src/backend/executor/nodeSubplan.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v
retrieving revision 1.69
diff -c -r1.69 nodeSubplan.c
*** src/backend/executor/nodeSubplan.c 6 May 2005 17:24:54 -0000 1.69
--- src/backend/executor/nodeSubplan.c 26 May 2005 18:52:16 -0000
***************
*** 215,220 ****
--- 215,221 ----
ListCell *pvar;
ListCell *l;
ArrayBuildState *astate = NULL;
+ Oid element_type =
planstate->ps_ResultTupleSlot->tts_tupleDescriptor->attrs[0]->atttypid;
/*
* We are probably in a short-lived expression-evaluation context.
***************
*** 259,268 ****
*
* For EXPR_SUBLINK we require the subplan to produce no more than one
* tuple, else an error is raised. For ARRAY_SUBLINK we allow the
! * subplan to produce more than one tuple. In either case, if zero
! * tuples are produced, we return NULL. Assuming we get a tuple, we
! * just use its first column (there can be only one non-junk column in
! * this case).
*/
result = BoolGetDatum(subLinkType == ALL_SUBLINK);
*isNull = false;
--- 260,269 ----
*
* For EXPR_SUBLINK we require the subplan to produce no more than one
* tuple, else an error is raised. For ARRAY_SUBLINK we allow the
! * subplan to produce more than one tuple. In the former case, if zero
! * tuples are produced, we return NULL. In the latter, we return an
! * empty array. Assuming we get a tuple, we just use its first column
! * (there can be only one non-junk column in this case).
*/
result = BoolGetDatum(subLinkType == ALL_SUBLINK);
*isNull = false;
***************
*** 432,458 ****
}
}
! if (!found)
{
/*
* deal with empty subplan result. result/isNull were
previously
! * initialized correctly for all sublink types except EXPR,
ARRAY,
* and MULTIEXPR; for those, return NULL.
*/
if (subLinkType == EXPR_SUBLINK ||
- subLinkType == ARRAY_SUBLINK ||
subLinkType == MULTIEXPR_SUBLINK)
{
result = (Datum) 0;
*isNull = true;
}
}
- else if (subLinkType == ARRAY_SUBLINK)
- {
- Assert(astate != NULL);
- /* We return the result in the caller's context */
- result = makeArrayResult(astate, oldcontext);
- }
MemoryContextSwitchTo(oldcontext);
--- 433,459 ----
}
}
! if (subLinkType == ARRAY_SUBLINK)
! {
! if (!astate)
! astate = initArrayResult(element_type, oldcontext);
! /* We return the result in the caller's context */
! result = makeArrayResult(astate, oldcontext);
! }
! else if (!found)
{
/*
* deal with empty subplan result. result/isNull were
previously
! * initialized correctly for all sublink types except EXPR
* and MULTIEXPR; for those, return NULL.
*/
if (subLinkType == EXPR_SUBLINK ||
subLinkType == MULTIEXPR_SUBLINK)
{
result = (Datum) 0;
*isNull = true;
}
}
MemoryContextSwitchTo(oldcontext);
***************
*** 925,930 ****
--- 926,932 ----
ListCell *l;
bool found = false;
ArrayBuildState *astate = NULL;
+ Oid element_type =
planstate->ps_ResultTupleSlot->tts_tupleDescriptor->attrs[0]->atttypid;
/*
* Must switch to child query's per-query memory context.
***************
*** 1010,1016 ****
}
}
! if (!found)
{
if (subLinkType == EXISTS_SUBLINK)
{
--- 1012,1033 ----
}
}
! if (subLinkType == ARRAY_SUBLINK)
! {
! /* There can be only one param... */
! int paramid =
linitial_int(subplan->setParam);
! ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
!
! prm->execPlan = NULL;
!
! if (!astate)
! astate = initArrayResult(element_type, oldcontext);
!
! /* We build the result in query context so it won't disappear */
! prm->value = makeArrayResult(astate,
econtext->ecxt_per_query_memory);
! prm->isnull = false;
! }
! else if (!found)
{
if (subLinkType == EXISTS_SUBLINK)
{
***************
*** 1035,1052 ****
}
}
}
- else if (subLinkType == ARRAY_SUBLINK)
- {
- /* There can be only one param... */
- int paramid =
linitial_int(subplan->setParam);
- ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
-
- Assert(astate != NULL);
- prm->execPlan = NULL;
- /* We build the result in query context so it won't disappear */
- prm->value = makeArrayResult(astate,
econtext->ecxt_per_query_memory);
- prm->isnull = false;
- }
MemoryContextSwitchTo(oldcontext);
}
--- 1052,1057 ----
Index: src/backend/utils/adt/arrayfuncs.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v
retrieving revision 1.120
diff -c -r1.120 arrayfuncs.c
*** src/backend/utils/adt/arrayfuncs.c 1 May 2005 18:56:18 -0000 1.120
--- src/backend/utils/adt/arrayfuncs.c 26 May 2005 18:52:16 -0000
***************
*** 3252,3257 ****
--- 3252,3293 ----
&my_extra->amstate);
}
+
+ /*
+ * initArrayResult - initialize an ArrayBuildState for an array result
+ *
+ * rcontext is where to keep working state
+ */
+ ArrayBuildState *
+ initArrayResult(Oid element_type, MemoryContext rcontext)
+ {
+ ArrayBuildState *astate;
+ MemoryContext arr_context,
+ oldcontext;
+
+ /* Make a temporary context to hold all the junk */
+ arr_context = AllocSetContextCreate(rcontext,
+
"accumArrayResult",
+
ALLOCSET_DEFAULT_MINSIZE,
+
ALLOCSET_DEFAULT_INITSIZE,
+
ALLOCSET_DEFAULT_MAXSIZE);
+ oldcontext = MemoryContextSwitchTo(arr_context);
+ astate = (ArrayBuildState *) palloc(sizeof(ArrayBuildState));
+ astate->mcontext = arr_context;
+ astate->dvalues = (Datum *)
+ palloc(ARRAY_ELEMS_CHUNKSIZE * sizeof(Datum));
+ astate->nelems = 0;
+ astate->element_type = element_type;
+ get_typlenbyvalalign(element_type,
+ &astate->typlen,
+ &astate->typbyval,
+ &astate->typalign);
+
+ MemoryContextSwitchTo(oldcontext);
+
+ return astate;
+ }
+
/*
* accumArrayResult - accumulate one (more) Datum for an array result
*
***************
*** 3264,3293 ****
Oid element_type,
MemoryContext rcontext)
{
! MemoryContext arr_context,
! oldcontext;
if (astate == NULL)
{
/* First time through --- initialize */
!
! /* Make a temporary context to hold all the junk */
! arr_context = AllocSetContextCreate(rcontext,
!
"accumArrayResult",
!
ALLOCSET_DEFAULT_MINSIZE,
!
ALLOCSET_DEFAULT_INITSIZE,
!
ALLOCSET_DEFAULT_MAXSIZE);
! oldcontext = MemoryContextSwitchTo(arr_context);
! astate = (ArrayBuildState *) palloc(sizeof(ArrayBuildState));
! astate->mcontext = arr_context;
! astate->dvalues = (Datum *)
! palloc(ARRAY_ELEMS_CHUNKSIZE * sizeof(Datum));
! astate->nelems = 0;
! astate->element_type = element_type;
! get_typlenbyvalalign(element_type,
! &astate->typlen,
! &astate->typbyval,
! &astate->typalign);
}
else
{
--- 3300,3311 ----
Oid element_type,
MemoryContext rcontext)
{
! MemoryContext oldcontext;
if (astate == NULL)
{
/* First time through --- initialize */
! astate = initArrayResult(element_type, rcontext);
}
else
{
Index: src/include/utils/array.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/utils/array.h,v
retrieving revision 1.54
diff -c -r1.54 array.h
*** src/include/utils/array.h 29 Mar 2005 00:17:18 -0000 1.54
--- src/include/utils/array.h 26 May 2005 18:52:16 -0000
***************
*** 176,181 ****
--- 176,182 ----
Oid elmtype,
int elmlen, bool elmbyval, char elmalign,
Datum **elemsp, int *nelemsp);
+ extern ArrayBuildState *initArrayResult(Oid element_type, MemoryContext
rcontext);
extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate,
Datum dvalue, bool disnull,
Oid element_type,
------------------------------------------------------------------------
---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?
http://archives.postgresql.org