Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit67bf7b9

Browse files
committed
Make ARRAY(SELECT ...) return an empty array, rather than a NULL, when the
sub-select returns zero rows. Per complaint from Jens Schicke. Since thisis more in the nature of a definition change than a bug, not back-patched.
1 parent75d5f6f commit67bf7b9

File tree

3 files changed

+52
-41
lines changed

3 files changed

+52
-41
lines changed

‎src/backend/executor/nodeSubplan.c

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* 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 $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -259,10 +259,14 @@ ExecScanSubPlan(SubPlanState *node,
259259
* ROWCOMPARE_SUBLINK.
260260
*
261261
* 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).
266270
*/
267271
result=BoolGetDatum(subLinkType==ALL_SUBLINK);
268272
*isNull= false;
@@ -317,10 +321,10 @@ ExecScanSubPlan(SubPlanState *node,
317321

318322
found= true;
319323
/* stash away current value */
324+
Assert(subplan->firstColType==tdesc->attrs[0]->atttypid);
320325
dvalue=slot_getattr(slot,1,&disnull);
321326
astate=accumArrayResult(astate,dvalue,disnull,
322-
tdesc->attrs[0]->atttypid,
323-
oldcontext);
327+
subplan->firstColType,oldcontext);
324328
/* keep scanning subplan to collect all values */
325329
continue;
326330
}
@@ -385,29 +389,30 @@ ExecScanSubPlan(SubPlanState *node,
385389
}
386390
}
387391

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+
elseif (!found)
389403
{
390404
/*
391405
* 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
393407
* ROWCOMPARE; for those, return NULL.
394408
*/
395409
if (subLinkType==EXPR_SUBLINK||
396-
subLinkType==ARRAY_SUBLINK||
397410
subLinkType==ROWCOMPARE_SUBLINK)
398411
{
399412
result= (Datum)0;
400413
*isNull= true;
401414
}
402415
}
403-
elseif (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);
411416

412417
returnresult;
413418
}
@@ -938,10 +943,10 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
938943

939944
found= true;
940945
/* stash away current value */
946+
Assert(subplan->firstColType==tdesc->attrs[0]->atttypid);
941947
dvalue=slot_getattr(slot,1,&disnull);
942948
astate=accumArrayResult(astate,dvalue,disnull,
943-
tdesc->attrs[0]->atttypid,
944-
oldcontext);
949+
subplan->firstColType,oldcontext);
945950
/* keep scanning subplan to collect all values */
946951
continue;
947952
}
@@ -980,7 +985,25 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
980985
}
981986
}
982987

983-
if (!found)
988+
if (subLinkType==ARRAY_SUBLINK)
989+
{
990+
/* There can be only one param... */
991+
intparamid=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+
elseif (!found)
9841007
{
9851008
if (subLinkType==EXISTS_SUBLINK)
9861009
{
@@ -1005,18 +1028,6 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
10051028
}
10061029
}
10071030
}
1008-
elseif (subLinkType==ARRAY_SUBLINK)
1009-
{
1010-
/* There can be only one param... */
1011-
intparamid=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-
}
10201031

10211032
MemoryContextSwitchTo(oldcontext);
10221033
}

‎src/backend/optimizer/plan/subselect.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.123 2007/07/18 21:40:57 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.124 2007/08/26 21:44:25 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -208,10 +208,10 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod)
208208
/*
209209
* Get the datatype of the first column of the plan's output.
210210
*
211-
* This isa hack to supportexprType(), which doesn't have any way to get
212-
* at the plan associated with a SubPlan node. We really only need the value
213-
* for EXPR_SUBLINK and ARRAY_SUBLINK subplans, but for consistency we set
214-
* it always.
211+
* This isstored for ARRAY_SUBLINK and forexprType(), which doesn't have any
212+
*way to getat the plan associated with a SubPlan node. We really only need
213+
*the valuefor EXPR_SUBLINK and ARRAY_SUBLINK subplans, but for consistency
214+
*we setit always.
215215
*/
216216
staticOid
217217
get_first_col_type(Plan*plan)

‎src/include/nodes/primnodes.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
13-
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.132 2007/06/11 22:22:42 tgl Exp $
13+
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.133 2007/08/26 21:44:25 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -388,7 +388,7 @@ typedef struct BoolExpr
388388
* results. ALL and ANY combine the per-row results using AND and OR
389389
* semantics respectively.
390390
* ARRAY requires just one target column, and creates an array of the target
391-
* column's type usingone or more rows resulting from the subselect.
391+
* column's type usingany number of rows resulting from the subselect.
392392
*
393393
* SubLink is classed as an Expr node, but it is not actually executable;
394394
* it must be replaced in the expression tree by a SubPlan node during
@@ -468,7 +468,7 @@ typedef struct SubPlan
468468
List*paramIds;/* IDs of Params embedded in the above */
469469
/* Identification of the Plan tree to use: */
470470
intplan_id;/* Index (from 1) in PlannedStmt.subplans */
471-
/* Extra datasaved forthe convenience of exprType(): */
471+
/* Extra datauseful fordetermining subplan's output type: */
472472
OidfirstColType;/* Type of first column of subplan result */
473473
/* Information about execution strategy: */
474474
booluseHashTable;/* TRUE to store subselect output in a hash

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp