Skip to content

Instantly share code, notes, and snippets.

@macdice
Created August 23, 2017 21:56
Show Gist options
  • Select an option

  • Save macdice/fc10503862fb2187572e744e925ce067 to your computer and use it in GitHub Desktop.

Select an option

Save macdice/fc10503862fb2187572e744e925ce067 to your computer and use it in GitHub Desktop.

Revisions

  1. macdice created this gist Aug 23, 2017.
    73 changes: 73 additions & 0 deletions with-memory-context.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
    index 96a64ce6b2c..ba0dcd3f15e 100644
    --- a/src/backend/catalog/partition.c
    +++ b/src/backend/catalog/partition.c
    @@ -1559,7 +1559,6 @@ get_qual_for_range(PartitionKey key, PartitionBoundSpec *spec)
    forboth(cell1, spec->lowerdatums, cell2, spec->upperdatums)
    {
    EState *estate;
    - MemoryContext oldcxt;
    Expr *test_expr;
    ExprState *test_exprstate;
    Datum test_result;
    @@ -1591,16 +1590,18 @@ get_qual_for_range(PartitionKey key, PartitionBoundSpec *spec)

    /* Create the test expression */
    estate = CreateExecutorState();
    - oldcxt = MemoryContextSwitchTo(estate->es_query_cxt);
    - test_expr = make_partition_op_expr(key, i, BTEqualStrategyNumber,
    - (Expr *) lower_val,
    - (Expr *) upper_val);
    - fix_opfuncids((Node *) test_expr);
    - test_exprstate = ExecInitExpr(test_expr, NULL);
    - test_result = ExecEvalExprSwitchContext(test_exprstate,
    - GetPerTupleExprContext(estate),
    - &isNull);
    - MemoryContextSwitchTo(oldcxt);
    + WITH_MEMORY_CONTEXT(estate->es_query_cxt)
    + {
    + test_expr = make_partition_op_expr(key, i, BTEqualStrategyNumber,
    + (Expr *) lower_val,
    + (Expr *) upper_val);
    + fix_opfuncids((Node *) test_expr);
    + test_exprstate = ExecInitExpr(test_expr, NULL);
    + test_result = ExecEvalExprSwitchContext(test_exprstate,
    + GetPerTupleExprContext(estate),
    + &isNull);
    + }
    + END_WITH_MEMORY_CONTEXT;
    FreeExecutorState(estate);

    /* If not equal, go generate the OR expressions */
    diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
    index c5533490668..02ec34e9f89 100644
    --- a/src/include/utils/memutils.h
    +++ b/src/include/utils/memutils.h
    @@ -194,4 +194,27 @@ extern MemoryContext SlabContextCreate(MemoryContext parent,
    #define SLAB_DEFAULT_BLOCK_SIZE (8 * 1024)
    #define SLAB_LARGE_BLOCK_SIZE (8 * 1024 * 1024)

    +/*
    + * Switch to a different memory context and for a limited scope. The calling
    + * code should look like this:
    + *
    + * WITH_MEMORY_CONTEXT(x)
    + * {
    + * ...;
    + * }
    + * END_WITH_MEMORY_CONTEXT;
    + *
    + * If the code in the enclosed scope needs to return early it should use
    + * RESTORE_MEMORY_CONTEXT_AND_RETURN(x) rather than return x.
    + */
    +#define WITH_MEMORY_CONTEXT(context) { \
    + MemoryContext old_context = MemoryContextSwitchTo(context);
    +#define END_WITH_MEMORY_CONTEXT MemoryContextSwitchTo(old_context); }
    +#define RESTORE_MEMORY_CONTEXT_AND_RETURN(value) \
    + do \
    + { \
    + MemoryContextSwitchTo(old_context); \
    + return (value); \
    + };
    +
    #endif /* MEMUTILS_H */