Skip to content

Commit 7f76eab

Browse files
committed
Rewrite parser's handling of INSERT ... SELECT so that processing
of the SELECT part of the statement is just like a plain SELECT. All INSERT-specific processing happens after the SELECT parsing is done. This eliminates many problems, e.g. INSERT ... SELECT ... GROUP BY using the wrong column labels. Ensure that DEFAULT clauses are coerced to the target column type, whether or not stored clause produces the right type. Substantial cleanup of parser's array support.
1 parent c981442 commit 7f76eab

File tree

12 files changed

+857
-1319
lines changed

12 files changed

+857
-1319
lines changed

src/backend/executor/execQual.c

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.57 1999/07/17 20:16:57 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.58 1999/07/19 00:26:15 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -86,31 +86,44 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
8686
bool *isNull,
8787
bool *isDone)
8888
{
89-
bool dummy;
90-
int i = 0,
91-
j = 0;
9289
ArrayType *array_scanner;
93-
List *upperIndexpr,
94-
*lowerIndexpr;
95-
Node *assgnexpr;
9690
List *elt;
91+
int i = 0,
92+
j = 0;
9793
IntArray upper,
9894
lower;
9995
int *lIndex;
100-
char *dataPtr;
96+
bool dummy;
10197

10298
*isNull = false;
103-
array_scanner = (ArrayType *) ExecEvalExpr(arrayRef->refexpr,
104-
econtext,
105-
isNull,
106-
isDone);
107-
if (*isNull)
108-
return (Datum) NULL;
10999

110-
upperIndexpr = arrayRef->refupperindexpr;
100+
if (arrayRef->refexpr != NULL)
101+
{
102+
array_scanner = (ArrayType *) ExecEvalExpr(arrayRef->refexpr,
103+
econtext,
104+
isNull,
105+
isDone);
106+
if (*isNull)
107+
return (Datum) NULL;
108+
}
109+
else
110+
{
111+
/* Null refexpr indicates we are doing an INSERT into an array column.
112+
* For now, we just take the refassgnexpr (which the parser will have
113+
* ensured is an array value) and return it as-is, ignoring any
114+
* subscripts that may have been supplied in the INSERT column list.
115+
* This is a kluge, but it's not real clear what the semantics ought
116+
* to be...
117+
*/
118+
array_scanner = NULL;
119+
}
111120

112-
foreach(elt, upperIndexpr)
121+
foreach(elt, arrayRef->refupperindexpr)
113122
{
123+
if (i >= MAXDIM)
124+
elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
125+
MAXDIM);
126+
114127
upper.indx[i++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
115128
econtext,
116129
isNull,
@@ -119,12 +132,14 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
119132
return (Datum) NULL;
120133
}
121134

122-
lowerIndexpr = arrayRef->reflowerindexpr;
123-
lIndex = NULL;
124-
if (lowerIndexpr != NIL)
135+
if (arrayRef->reflowerindexpr != NIL)
125136
{
126-
foreach(elt, lowerIndexpr)
137+
foreach(elt, arrayRef->reflowerindexpr)
127138
{
139+
if (j >= MAXDIM)
140+
elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
141+
MAXDIM);
142+
128143
lower.indx[j++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
129144
econtext,
130145
isNull,
@@ -137,30 +152,42 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
137152
"ExecEvalArrayRef: upper and lower indices mismatch");
138153
lIndex = lower.indx;
139154
}
155+
else
156+
{
157+
lIndex = NULL;
158+
}
140159

141-
assgnexpr = arrayRef->refassgnexpr;
142-
if (assgnexpr != NULL)
160+
if (arrayRef->refassgnexpr != NULL)
143161
{
144-
dataPtr = (char *) ExecEvalExpr((Node *)
145-
assgnexpr, econtext,
146-
isNull, &dummy);
162+
Datum sourceData = ExecEvalExpr(arrayRef->refassgnexpr,
163+
econtext,
164+
isNull,
165+
&dummy);
147166
if (*isNull)
148167
return (Datum) NULL;
168+
149169
execConstByVal = arrayRef->refelembyval;
150170
execConstLen = arrayRef->refelemlength;
171+
172+
if (array_scanner == NULL)
173+
return sourceData; /* XXX do something else? */
174+
151175
if (lIndex == NULL)
152-
return (Datum) array_set(array_scanner, i, upper.indx, dataPtr,
176+
return (Datum) array_set(array_scanner, i, upper.indx,
177+
(char *) sourceData,
153178
arrayRef->refelembyval,
154179
arrayRef->refelemlength,
155180
arrayRef->refattrlength, isNull);
156181
return (Datum) array_assgn(array_scanner, i, upper.indx,
157182
lower.indx,
158-
(ArrayType *) dataPtr,
183+
(ArrayType *) sourceData,
159184
arrayRef->refelembyval,
160185
arrayRef->refelemlength, isNull);
161186
}
187+
162188
execConstByVal = arrayRef->refelembyval;
163189
execConstLen = arrayRef->refelemlength;
190+
164191
if (lIndex == NULL)
165192
return (Datum) array_ref(array_scanner, i, upper.indx,
166193
arrayRef->refelembyval,

0 commit comments

Comments
 (0)