aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-07-19 00:26:20 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-07-19 00:26:20 +0000
commit7f76eab140e703b7847b107245a669e2010886c0 (patch)
tree8c9d01c654aa8de0e14c0d446817ba60c33d0199 /src/backend/executor
parentc9814427722798751fa5bf254f597d722d76b5e3 (diff)
downloadpostgresql-7f76eab140e703b7847b107245a669e2010886c0.tar.gz
postgresql-7f76eab140e703b7847b107245a669e2010886c0.zip
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.
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execQual.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 649c189ea97..a3eb943ab96 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.57 1999/07/17 20:16:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.58 1999/07/19 00:26:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -86,31 +86,44 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
bool *isNull,
bool *isDone)
{
- bool dummy;
- int i = 0,
- j = 0;
ArrayType *array_scanner;
- List *upperIndexpr,
- *lowerIndexpr;
- Node *assgnexpr;
List *elt;
+ int i = 0,
+ j = 0;
IntArray upper,
lower;
int *lIndex;
- char *dataPtr;
+ bool dummy;
*isNull = false;
- array_scanner = (ArrayType *) ExecEvalExpr(arrayRef->refexpr,
- econtext,
- isNull,
- isDone);
- if (*isNull)
- return (Datum) NULL;
- upperIndexpr = arrayRef->refupperindexpr;
+ if (arrayRef->refexpr != NULL)
+ {
+ array_scanner = (ArrayType *) ExecEvalExpr(arrayRef->refexpr,
+ econtext,
+ isNull,
+ isDone);
+ if (*isNull)
+ return (Datum) NULL;
+ }
+ else
+ {
+ /* Null refexpr indicates we are doing an INSERT into an array column.
+ * For now, we just take the refassgnexpr (which the parser will have
+ * ensured is an array value) and return it as-is, ignoring any
+ * subscripts that may have been supplied in the INSERT column list.
+ * This is a kluge, but it's not real clear what the semantics ought
+ * to be...
+ */
+ array_scanner = NULL;
+ }
- foreach(elt, upperIndexpr)
+ foreach(elt, arrayRef->refupperindexpr)
{
+ if (i >= MAXDIM)
+ elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
+ MAXDIM);
+
upper.indx[i++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
econtext,
isNull,
@@ -119,12 +132,14 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
return (Datum) NULL;
}
- lowerIndexpr = arrayRef->reflowerindexpr;
- lIndex = NULL;
- if (lowerIndexpr != NIL)
+ if (arrayRef->reflowerindexpr != NIL)
{
- foreach(elt, lowerIndexpr)
+ foreach(elt, arrayRef->reflowerindexpr)
{
+ if (j >= MAXDIM)
+ elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
+ MAXDIM);
+
lower.indx[j++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
econtext,
isNull,
@@ -137,30 +152,42 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
"ExecEvalArrayRef: upper and lower indices mismatch");
lIndex = lower.indx;
}
+ else
+ {
+ lIndex = NULL;
+ }
- assgnexpr = arrayRef->refassgnexpr;
- if (assgnexpr != NULL)
+ if (arrayRef->refassgnexpr != NULL)
{
- dataPtr = (char *) ExecEvalExpr((Node *)
- assgnexpr, econtext,
- isNull, &dummy);
+ Datum sourceData = ExecEvalExpr(arrayRef->refassgnexpr,
+ econtext,
+ isNull,
+ &dummy);
if (*isNull)
return (Datum) NULL;
+
execConstByVal = arrayRef->refelembyval;
execConstLen = arrayRef->refelemlength;
+
+ if (array_scanner == NULL)
+ return sourceData; /* XXX do something else? */
+
if (lIndex == NULL)
- return (Datum) array_set(array_scanner, i, upper.indx, dataPtr,
+ return (Datum) array_set(array_scanner, i, upper.indx,
+ (char *) sourceData,
arrayRef->refelembyval,
arrayRef->refelemlength,
arrayRef->refattrlength, isNull);
return (Datum) array_assgn(array_scanner, i, upper.indx,
lower.indx,
- (ArrayType *) dataPtr,
+ (ArrayType *) sourceData,
arrayRef->refelembyval,
arrayRef->refelemlength, isNull);
}
+
execConstByVal = arrayRef->refelembyval;
execConstLen = arrayRef->refelemlength;
+
if (lIndex == NULL)
return (Datum) array_ref(array_scanner, i, upper.indx,
arrayRef->refelembyval,