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

Commite4e6459

Browse files
committed
Further cleanup of array behavior. Slice assignments to arrays with
varlena elements work now. Allow assignment to previously-nonexistentsubscript position to extend array, but only for 1-D arrays and onlyif adjacent to existing positions (could do more if we had a way torepresent nulls in arrays, but I don't want to tackle that now).Arrange for assignment of NULL to an array element in UPDATE to be ano-op, rather than setting the entire array to NULL as it used to.(Throwing an error would be a reasonable alternative, but it's neverdone that...) Update regress test accordingly.
1 parentef2a6b8 commite4e6459

File tree

4 files changed

+612
-249
lines changed

4 files changed

+612
-249
lines changed

‎src/backend/executor/execQual.c

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.75 2000/07/22 03:34:27 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.76 2000/07/23 01:35:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -64,18 +64,30 @@ static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
6464
staticDatumExecMakeFunctionResult(Node*node,List*arguments,
6565
ExprContext*econtext,bool*isNull,bool*isDone);
6666

67-
/*
67+
/*----------
6868
* ExecEvalArrayRef
6969
*
7070
* This function takes an ArrayRef and returns the extracted Datum
7171
* if it's a simple reference, or the modified array value if it's
72-
* an array assignment (read array element insertion).
72+
* an array assignment (i.e., array element or slice insertion).
73+
*
74+
* NOTE: if we get a NULL result from a subexpression, we return NULL when
75+
* it's an array reference, or the unmodified source array when it's an
76+
* array assignment. This may seem peculiar, but if we return NULL (as was
77+
* done in versions up through 7.0) then an assignment like
78+
*UPDATE table SET arrayfield[4] = NULL
79+
* will result in setting the whole array to NULL, which is certainly not
80+
* very desirable. By returning the source array we make the assignment
81+
* into a no-op, instead. (Eventually we need to redesign arrays so that
82+
* individual elements can be NULL, but for now, let's try to protect users
83+
* from shooting themselves in the foot.)
7384
*
7485
* NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
7586
* even though that might seem natural, because this code needs to support
7687
* both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
7788
* only works for the varlena kind. The routines we call in arrayfuncs.c
7889
* have to know the difference (that's what they need refattrlength for).
90+
*----------
7991
*/
8092
staticDatum
8193
ExecEvalArrayRef(ArrayRef*arrayRef,
@@ -85,6 +97,7 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
8597
{
8698
ArrayType*array_source;
8799
ArrayType*resultArray;
100+
boolisAssignment= (arrayRef->refassgnexpr!=NULL);
88101
List*elt;
89102
inti=0,
90103
j=0;
@@ -102,15 +115,19 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
102115
econtext,
103116
isNull,
104117
isDone));
105-
/* If refexpr yields NULL, result is always NULL, for now anyway */
118+
/*
119+
* If refexpr yields NULL, result is always NULL, for now anyway.
120+
* (This means you cannot assign to an element or slice of an array
121+
* that's NULL; it'll just stay NULL.)
122+
*/
106123
if (*isNull)
107124
return (Datum)NULL;
108125
}
109126
else
110127
{
111128

112129
/*
113-
*Null refexpr indicates we are doing an INSERT into an array
130+
*Empty refexpr indicates we are doing an INSERT into an array
114131
* column. For now, we just take the refassgnexpr (which the
115132
* parser will have ensured is an array value) and return it
116133
* as-is, ignoring any subscripts that may have been supplied in
@@ -130,9 +147,14 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
130147
econtext,
131148
isNull,
132149
&dummy));
133-
/* If any index expr yields NULL, result is NULL */
150+
/* If any index expr yields NULL, result is NULLor source array*/
134151
if (*isNull)
135-
return (Datum)NULL;
152+
{
153+
if (!isAssignment||array_source==NULL)
154+
return (Datum)NULL;
155+
*isNull= false;
156+
returnPointerGetDatum(array_source);
157+
}
136158
}
137159

138160
if (arrayRef->reflowerindexpr!=NIL)
@@ -147,9 +169,14 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
147169
econtext,
148170
isNull,
149171
&dummy));
150-
/* If any index expr yields NULL, result is NULL */
172+
/* If any index expr yields NULL, result is NULLor source array*/
151173
if (*isNull)
152-
return (Datum)NULL;
174+
{
175+
if (!isAssignment||array_source==NULL)
176+
return (Datum)NULL;
177+
*isNull= false;
178+
returnPointerGetDatum(array_source);
179+
}
153180
}
154181
if (i!=j)
155182
elog(ERROR,
@@ -159,18 +186,26 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
159186
else
160187
lIndex=NULL;
161188

162-
if (arrayRef->refassgnexpr!=NULL)
189+
if (isAssignment)
163190
{
164191
DatumsourceData=ExecEvalExpr(arrayRef->refassgnexpr,
165192
econtext,
166193
isNull,
167194
&dummy);
168-
/* For now, can't cope with inserting NULL into an array */
195+
/*
196+
* For now, can't cope with inserting NULL into an array,
197+
* so make it a no-op per discussion above...
198+
*/
169199
if (*isNull)
170-
return (Datum)NULL;
200+
{
201+
if (array_source==NULL)
202+
return (Datum)NULL;
203+
*isNull= false;
204+
returnPointerGetDatum(array_source);
205+
}
171206

172207
if (array_source==NULL)
173-
returnsourceData;/* XXX do something else? */
208+
returnsourceData;/* XXX do something else? */
174209

175210
if (lIndex==NULL)
176211
resultArray=array_set(array_source,i,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp