tmp
authorAndres Freund <[email protected]>
Fri, 22 Sep 2017 04:06:50 +0000 (21:06 -0700)
committerAndres Freund <[email protected]>
Sun, 8 Oct 2017 16:41:56 +0000 (09:41 -0700)
Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:

src/backend/access/common/tupdesc.c
src/backend/executor/execExpr.c

index 9e37ca73a86fa0ba96e5517b810fbcd01a2b1fd8..1f12cfba25c9632c0ce642347d78e11fab0d2547 100644 (file)
@@ -535,7 +535,10 @@ TupleDescInitEntry(TupleDesc desc,
    if (attributeName == NULL)
        MemSet(NameStr(att->attname), 0, NAMEDATALEN);
    else if (attributeName != NameStr(att->attname))
-       namestrcpy(&(att->attname), attributeName);
+   {
+       Assert(strlen(attributeName) < NAMEDATALEN);
+       strcpy(NameStr(att->attname), attributeName);
+   }
 
    att->attstattarget = -1;
    att->attcacheoff = -1;
index e0839616e196638e657f2fed70c8338ecf164720..904bf4a348ed79656c244baf66e86a862ef81fa7 100644 (file)
@@ -57,6 +57,7 @@ typedef struct LastAttnumInfo
 static void ExecReadyExpr(ExprState *state);
 static void ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state,
                Datum *resv, bool *resnull);
+static void ExprEvalPushStepPrealloc(ExprState *es, size_t n);
 static void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s);
 static void ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args,
             Oid funcid, Oid inputcollid, PlanState *parent,
@@ -316,6 +317,8 @@ ExecBuildProjectionInfo(List *targetList,
    state->expr = (Expr *) targetList;
    state->resultslot = slot;
 
+   ExprEvalPushStepPrealloc(state, list_length(targetList) + 4);
+
    /* Insert EEOP_*_FETCHSOME steps as needed */
    ExecInitExprSlots(state, (Node *) targetList);
 
@@ -386,7 +389,6 @@ ExecBuildProjectionInfo(List *targetList,
 
            scratch.d.assign_var.attnum = attnum - 1;
            scratch.d.assign_var.resultnum = tle->resno - 1;
-           ExprEvalPushStep(state, &scratch);
        }
        else
        {
@@ -410,8 +412,8 @@ ExecBuildProjectionInfo(List *targetList,
            else
                scratch.opcode = EEOP_ASSIGN_TMP;
            scratch.d.assign_tmp.resultnum = tle->resno - 1;
-           ExprEvalPushStep(state, &scratch);
        }
+       ExprEvalPushStep(state, &scratch);
    }
 
    scratch.opcode = EEOP_DONE;
@@ -2064,6 +2066,27 @@ ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
    memcpy(&es->steps[es->steps_len++], s, sizeof(ExprEvalStep));
 }
 
+/*
+ * Preallocate memory for ExprState->steps.
+ *
+ * Preallocating an appropriate amount can reduce memory reallocations during
+ * ExprEvalPushStep, iff a decent estimate about the number of required steps
+ * is possible.
+ */
+static void
+ExprEvalPushStepPrealloc(ExprState *es, size_t n)
+{
+   Assert(es->steps_alloc == 0);
+   Assert(n > 0);
+
+   if (n < 16)
+       n = 16;
+
+   /* should we increase to the next power of two? */
+   es->steps_alloc = n;
+   es->steps = palloc(sizeof(ExprEvalStep) * es->steps_alloc);
+}
+
 /*
  * Perform setup necessary for the evaluation of a function-like expression,
  * appending argument evaluation steps to the steps list in *state, and