7
7
* Portions Copyright (c) 1994, Regents of the University of California
8
8
*
9
9
* IDENTIFICATION
10
- * $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.89 2007/05/17 19:35:08 tgl Exp $
10
+ * $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.90 2007/08/26 21:44:25 tgl Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -259,10 +259,14 @@ ExecScanSubPlan(SubPlanState *node,
259
259
* ROWCOMPARE_SUBLINK.
260
260
*
261
261
* For EXPR_SUBLINK we require the subplan to produce no more than one
262
- * tuple, else an error is raised. For ARRAY_SUBLINK we allow the subplan
263
- * to produce more than one tuple. In either case, if zero tuples are
264
- * produced, we return NULL. Assuming we get a tuple, we just use its
265
- * first column (there can be only one non-junk column in this case).
262
+ * tuple, else an error is raised. If zero tuples are produced, we return
263
+ * NULL. Assuming we get a tuple, we just use its first column (there can
264
+ * be only one non-junk column in this case).
265
+ *
266
+ * For ARRAY_SUBLINK we allow the subplan to produce any number of tuples,
267
+ * and form an array of the first column's values. Note in particular
268
+ * that we produce a zero-element array if no tuples are produced (this
269
+ * is a change from pre-8.3 behavior of returning NULL).
266
270
*/
267
271
result = BoolGetDatum (subLinkType == ALL_SUBLINK );
268
272
* isNull = false;
@@ -317,10 +321,10 @@ ExecScanSubPlan(SubPlanState *node,
317
321
318
322
found = true;
319
323
/* stash away current value */
324
+ Assert (subplan -> firstColType == tdesc -> attrs [0 ]-> atttypid );
320
325
dvalue = slot_getattr (slot , 1 , & disnull );
321
326
astate = accumArrayResult (astate , dvalue , disnull ,
322
- tdesc -> attrs [0 ]-> atttypid ,
323
- oldcontext );
327
+ subplan -> firstColType , oldcontext );
324
328
/* keep scanning subplan to collect all values */
325
329
continue ;
326
330
}
@@ -385,29 +389,30 @@ ExecScanSubPlan(SubPlanState *node,
385
389
}
386
390
}
387
391
388
- if (!found )
392
+ MemoryContextSwitchTo (oldcontext );
393
+
394
+ if (subLinkType == ARRAY_SUBLINK )
395
+ {
396
+ /* We return the result in the caller's context */
397
+ if (astate != NULL )
398
+ result = makeArrayResult (astate , oldcontext );
399
+ else
400
+ result = PointerGetDatum (construct_empty_array (subplan -> firstColType ));
401
+ }
402
+ else if (!found )
389
403
{
390
404
/*
391
405
* deal with empty subplan result. result/isNull were previously
392
- * initialized correctly for all sublink types except EXPR, ARRAY, and
406
+ * initialized correctly for all sublink types except EXPR and
393
407
* ROWCOMPARE; for those, return NULL.
394
408
*/
395
409
if (subLinkType == EXPR_SUBLINK ||
396
- subLinkType == ARRAY_SUBLINK ||
397
410
subLinkType == ROWCOMPARE_SUBLINK )
398
411
{
399
412
result = (Datum ) 0 ;
400
413
* isNull = true;
401
414
}
402
415
}
403
- else if (subLinkType == ARRAY_SUBLINK )
404
- {
405
- Assert (astate != NULL );
406
- /* We return the result in the caller's context */
407
- result = makeArrayResult (astate , oldcontext );
408
- }
409
-
410
- MemoryContextSwitchTo (oldcontext );
411
416
412
417
return result ;
413
418
}
@@ -938,10 +943,10 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
938
943
939
944
found = true;
940
945
/* stash away current value */
946
+ Assert (subplan -> firstColType == tdesc -> attrs [0 ]-> atttypid );
941
947
dvalue = slot_getattr (slot , 1 , & disnull );
942
948
astate = accumArrayResult (astate , dvalue , disnull ,
943
- tdesc -> attrs [0 ]-> atttypid ,
944
- oldcontext );
949
+ subplan -> firstColType , oldcontext );
945
950
/* keep scanning subplan to collect all values */
946
951
continue ;
947
952
}
@@ -980,7 +985,25 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
980
985
}
981
986
}
982
987
983
- if (!found )
988
+ if (subLinkType == ARRAY_SUBLINK )
989
+ {
990
+ /* There can be only one param... */
991
+ int paramid = linitial_int (subplan -> setParam );
992
+ ParamExecData * prm = & (econtext -> ecxt_param_exec_vals [paramid ]);
993
+
994
+ prm -> execPlan = NULL ;
995
+ /* We build the result in query context so it won't disappear */
996
+ if (astate != NULL )
997
+ prm -> value = makeArrayResult (astate ,
998
+ econtext -> ecxt_per_query_memory );
999
+ else
1000
+ {
1001
+ MemoryContextSwitchTo (econtext -> ecxt_per_query_memory );
1002
+ prm -> value = PointerGetDatum (construct_empty_array (subplan -> firstColType ));
1003
+ }
1004
+ prm -> isnull = false;
1005
+ }
1006
+ else if (!found )
984
1007
{
985
1008
if (subLinkType == EXISTS_SUBLINK )
986
1009
{
@@ -1005,18 +1028,6 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
1005
1028
}
1006
1029
}
1007
1030
}
1008
- else if (subLinkType == ARRAY_SUBLINK )
1009
- {
1010
- /* There can be only one param... */
1011
- int paramid = linitial_int (subplan -> setParam );
1012
- ParamExecData * prm = & (econtext -> ecxt_param_exec_vals [paramid ]);
1013
-
1014
- Assert (astate != NULL );
1015
- prm -> execPlan = NULL ;
1016
- /* We build the result in query context so it won't disappear */
1017
- prm -> value = makeArrayResult (astate , econtext -> ecxt_per_query_memory );
1018
- prm -> isnull = false;
1019
- }
1020
1031
1021
1032
MemoryContextSwitchTo (oldcontext );
1022
1033
}
0 commit comments