You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by st...@apache.org on 2021/03/13 02:24:24 UTC

[impala] branch master updated (2039746 -> 6c6b0ee)

This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git.


    from 2039746  IMPALA-10576: Add refresh authorization to make a test case less flaky
     new a29d06d  IMPALA-9218: Add support for locally compiled Hive
     new 1a01bfe  IMPALA-10377: Improve the accuracy of resource estimation
     new 0d22e89  IMPALA-10520: Implement ds_theta_intersect() function
     new 311938b  IMPALA-10535: Add interface to ImpalaServer for execution of externally compiled statements
     new b3d95d8  IMPALA-10522: Support external use of frontend libraries
     new 2e53c11  IMPALA-10546: Add ImpalaServer interface to retrieve BackendConfig from impalad
     new d5f67fc  IMPALA-10523: Fix impala-shell crash in printing error messages that contain UTF-8 characters
     new 6c6b0ee  IMPALA-10222: CREATE TABLE AS SELECT for Iceberg tables

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 README-build.md                                    |  11 +
 be/generated-sources/gen-cpp/CMakeLists.txt        |   2 +
 be/src/benchmarks/expr-benchmark.cc                |   2 +-
 be/src/catalog/catalog.cc                          |   2 +-
 be/src/common/init.cc                              |  33 +-
 be/src/common/init.h                               |   4 +-
 be/src/exec/hash-table.h                           |   5 +
 be/src/exprs/aggregate-functions-ir.cc             |  87 +++
 be/src/exprs/aggregate-functions.h                 |   9 +
 be/src/rpc/hs2-http-test.cc                        |   4 +
 be/src/runtime/data-stream-test.cc                 |   2 +-
 be/src/runtime/debug-options.h                     |   1 +
 be/src/runtime/exec-env.cc                         |  34 +-
 be/src/runtime/exec-env.h                          |  15 +-
 be/src/runtime/lib-cache.cc                        |  11 +-
 be/src/runtime/lib-cache.h                         |   4 +-
 be/src/runtime/query-driver.cc                     |  25 +
 be/src/runtime/query-driver.h                      |   3 +
 be/src/service/client-request-state.cc             |   4 +
 be/src/service/client-request-state.h              |   4 +
 be/src/service/fe-support.cc                       |  17 +-
 be/src/service/frontend.cc                         |   2 +-
 be/src/service/impala-beeswax-server.cc            |   4 +-
 be/src/service/impala-hs2-server.cc                |  54 +-
 be/src/service/impala-server.cc                    |  74 ++-
 be/src/service/impala-server.h                     |  26 +-
 be/src/util/backend-gflag-util.cc                  |   9 +-
 be/src/util/backend-gflag-util.h                   |   5 +-
 be/src/util/jni-util.cc                            |   2 -
 be/src/util/logging-support.cc                     |   2 +-
 bin/bootstrap_toolchain.py                         |   9 +-
 bin/impala-config.sh                               |  11 +-
 common/thrift/CMakeLists.txt                       |  12 +-
 common/thrift/Frontend.thrift                      | 129 +----
 common/thrift/ImpalaInternalService.thrift         | 619 +--------------------
 common/thrift/ImpalaService.thrift                 |  34 ++
 .../{ImpalaInternalService.thrift => Query.thrift} | 311 ++++-------
 fe/pom.xml                                         |   5 +
 fe/src/main/cup/sql-parser.cup                     |  10 +
 .../java/org/apache/impala/analysis/Analyzer.java  |   9 +-
 .../impala/analysis/CreateTableAsSelectStmt.java   |  18 +-
 .../org/apache/impala/analysis/InsertStmt.java     |  36 +-
 .../org/apache/impala/analysis/PrivilegeSpec.java  |   2 +-
 .../apache/impala/analysis/ResetMetadataStmt.java  |   3 +-
 .../java/org/apache/impala/catalog/BuiltinsDb.java |  14 +
 .../org/apache/impala/catalog/CtasTargetTable.java | 176 ++++++
 .../org/apache/impala/catalog/FeIcebergTable.java  |  23 +-
 .../java/org/apache/impala/catalog/HdfsTable.java  |   2 +-
 .../impala/catalog/iceberg/IcebergCtasTarget.java  | 279 ++++++++++
 .../org/apache/impala/catalog/local/LocalDb.java   |   2 +-
 .../apache/impala/catalog/local/LocalFsTable.java  |   2 +-
 .../org/apache/impala/planner/AggregationNode.java |  48 +-
 .../org/apache/impala/planner/HashJoinNode.java    |  30 +-
 .../java/org/apache/impala/planner/JoinNode.java   |   2 +-
 .../org/apache/impala/planner/KuduScanNode.java    |   3 +-
 .../org/apache/impala/planner/PlanFragment.java    |   6 +-
 .../java/org/apache/impala/planner/PlanNode.java   |  11 +
 .../org/apache/impala/planner/PlannerContext.java  |   5 +
 .../java/org/apache/impala/planner/SortNode.java   |  12 +-
 .../java/org/apache/impala/service/FeSupport.java  |  18 +-
 .../impala/service/IcebergCatalogOpExecutor.java   |   3 +-
 .../apache/impala/util/IcebergSchemaConverter.java |   2 +-
 .../java/org/apache/impala/util/IcebergUtil.java   |  13 +-
 .../org/apache/impala/analysis/AnalyzeDDLTest.java |   4 +-
 .../org/apache/impala/planner/CardinalityTest.java | 196 +++++++
 .../org/apache/impala/planner/PlannerTestBase.java |   3 +-
 java/pom.xml                                       |   2 +-
 shell/impala_shell.py                              |   8 +-
 testdata/bin/run-hive-server.sh                    |   3 +
 .../PlannerTest/bloom-filter-assignment.test       |  30 +-
 .../queries/PlannerTest/constant-folding.test      |  12 +-
 .../queries/PlannerTest/constant-propagation.test  |  54 +-
 .../queries/PlannerTest/disable-codegen.test       |  18 +-
 ...k-join-detection-hdfs-num-rows-est-enabled.test |   8 +-
 .../queries/PlannerTest/fk-pk-join-detection.test  |  16 +-
 .../queries/PlannerTest/max-row-size.test          |  48 +-
 ...-runtime-filters-hdfs-num-rows-est-enabled.test |   4 +-
 .../PlannerTest/min-max-runtime-filters.test       |  18 +-
 .../queries/PlannerTest/mt-dop-validation.test     |  38 +-
 .../PlannerTest/parquet-filtering-disabled.test    |  16 +-
 .../queries/PlannerTest/parquet-filtering.test     |  32 +-
 .../queries/PlannerTest/partition-pruning.test     |  10 +-
 .../queries/PlannerTest/preagg-bytes-limit.test    |  12 +-
 .../queries/PlannerTest/resource-requirements.test | 372 ++++++-------
 .../queries/PlannerTest/result-spooling.test       |  12 +-
 .../PlannerTest/runtime-filter-query-options.test  | 116 ++--
 .../PlannerTest/sort-expr-materialization.test     |  18 +-
 .../PlannerTest/spillable-buffer-sizing.test       | 116 ++--
 .../queries/PlannerTest/tpcds/tpcds-q01.test       |  44 +-
 .../queries/PlannerTest/tpcds/tpcds-q02.test       |  38 +-
 .../queries/PlannerTest/tpcds/tpcds-q04.test       | 172 +++---
 .../queries/PlannerTest/tpcds/tpcds-q05.test       |  30 +-
 .../queries/PlannerTest/tpcds/tpcds-q06.test       |  56 +-
 .../queries/PlannerTest/tpcds/tpcds-q07.test       |  36 +-
 .../queries/PlannerTest/tpcds/tpcds-q08.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q09.test       | 278 ++++-----
 .../queries/PlannerTest/tpcds/tpcds-q10a.test      |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q11.test       | 128 ++---
 .../queries/PlannerTest/tpcds/tpcds-q12.test       |  38 +-
 .../queries/PlannerTest/tpcds/tpcds-q13.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q14a.test      | 274 ++++-----
 .../queries/PlannerTest/tpcds/tpcds-q14b.test      | 190 +++----
 .../queries/PlannerTest/tpcds/tpcds-q15.test       |  38 +-
 .../queries/PlannerTest/tpcds/tpcds-q16.test       |  44 +-
 .../queries/PlannerTest/tpcds/tpcds-q17.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q18.test       |  74 +--
 .../queries/PlannerTest/tpcds/tpcds-q19.test       |  12 +-
 .../queries/PlannerTest/tpcds/tpcds-q20.test       |  48 +-
 .../queries/PlannerTest/tpcds/tpcds-q21.test       |  12 +-
 .../queries/PlannerTest/tpcds/tpcds-q22.test       |  46 +-
 .../queries/PlannerTest/tpcds/tpcds-q23a.test      | 182 +++---
 .../queries/PlannerTest/tpcds/tpcds-q23b.test      | 172 +++---
 .../queries/PlannerTest/tpcds/tpcds-q24a.test      |  86 +--
 .../queries/PlannerTest/tpcds/tpcds-q24b.test      |  86 +--
 .../queries/PlannerTest/tpcds/tpcds-q25.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q26.test       |  36 +-
 .../queries/PlannerTest/tpcds/tpcds-q27.test       |  36 +-
 .../queries/PlannerTest/tpcds/tpcds-q28.test       | 112 ++--
 .../queries/PlannerTest/tpcds/tpcds-q29.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q31.test       | 200 +++----
 .../queries/PlannerTest/tpcds/tpcds-q32.test       |  22 +-
 .../queries/PlannerTest/tpcds/tpcds-q34.test       |   6 +-
 .../queries/PlannerTest/tpcds/tpcds-q35a.test      |  70 +--
 .../queries/PlannerTest/tpcds/tpcds-q36.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q37.test       |  24 +-
 .../queries/PlannerTest/tpcds/tpcds-q38.test       | 118 ++--
 .../queries/PlannerTest/tpcds/tpcds-q39a.test      |  68 +--
 .../queries/PlannerTest/tpcds/tpcds-q39b.test      |  68 +--
 .../queries/PlannerTest/tpcds/tpcds-q40.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q43.test       |   0
 .../queries/PlannerTest/tpcds/tpcds-q44.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q45.test       |  56 +-
 .../queries/PlannerTest/tpcds/tpcds-q46.test       |  50 +-
 .../queries/PlannerTest/tpcds/tpcds-q47.test       | 126 ++---
 .../queries/PlannerTest/tpcds/tpcds-q48.test       |  40 +-
 .../queries/PlannerTest/tpcds/tpcds-q49.test       |  20 +-
 .../queries/PlannerTest/tpcds/tpcds-q50.test       |  50 +-
 .../queries/PlannerTest/tpcds/tpcds-q51.test       |  74 +--
 .../queries/PlannerTest/tpcds/tpcds-q54.test       |  60 +-
 .../queries/PlannerTest/tpcds/tpcds-q56.test       |   8 +-
 .../queries/PlannerTest/tpcds/tpcds-q57.test       |  74 +--
 .../queries/PlannerTest/tpcds/tpcds-q58.test       |  80 +--
 .../queries/PlannerTest/tpcds/tpcds-q59.test       |  72 +--
 .../queries/PlannerTest/tpcds/tpcds-q60.test       |   8 +-
 .../queries/PlannerTest/tpcds/tpcds-q61.test       |  56 +-
 .../queries/PlannerTest/tpcds/tpcds-q64.test       | 178 +++---
 .../queries/PlannerTest/tpcds/tpcds-q65.test       |  42 +-
 .../queries/PlannerTest/tpcds/tpcds-q66.test       |  56 +-
 .../queries/PlannerTest/tpcds/tpcds-q67.test       |  46 +-
 .../queries/PlannerTest/tpcds/tpcds-q68.test       |  50 +-
 .../queries/PlannerTest/tpcds/tpcds-q69.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q71.test       |  42 +-
 .../queries/PlannerTest/tpcds/tpcds-q72.test       |  76 +--
 .../queries/PlannerTest/tpcds/tpcds-q73.test       |  28 +-
 .../queries/PlannerTest/tpcds/tpcds-q74.test       | 122 ++--
 .../queries/PlannerTest/tpcds/tpcds-q75.test       |  88 +--
 .../queries/PlannerTest/tpcds/tpcds-q76.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q77.test       |  22 +-
 .../queries/PlannerTest/tpcds/tpcds-q78.test       |  68 +--
 .../queries/PlannerTest/tpcds/tpcds-q79.test       |  24 +-
 .../queries/PlannerTest/tpcds/tpcds-q80.test       |  68 +--
 .../queries/PlannerTest/tpcds/tpcds-q81.test       |  56 +-
 .../queries/PlannerTest/tpcds/tpcds-q82.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q83.test       |  80 +--
 .../queries/PlannerTest/tpcds/tpcds-q85.test       |  28 +-
 .../queries/PlannerTest/tpcds/tpcds-q86.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q87.test       | 118 ++--
 .../queries/PlannerTest/tpcds/tpcds-q88.test       | 148 ++---
 .../queries/PlannerTest/tpcds/tpcds-q90.test       |  40 +-
 .../queries/PlannerTest/tpcds/tpcds-q91.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q92.test       |  22 +-
 .../queries/PlannerTest/tpcds/tpcds-q93.test       |  28 +-
 .../queries/PlannerTest/tpcds/tpcds-q94.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q95.test       |  68 +--
 .../queries/PlannerTest/tpcds/tpcds-q96.test       |  22 +-
 .../queries/PlannerTest/tpcds/tpcds-q97.test       |  42 +-
 .../queries/PlannerTest/tpcds/tpcds-q98.test       |  46 +-
 .../queries/PlannerTest/tpch-all.test              | 192 +++----
 .../queries/PlannerTest/tpch-kudu.test             |  80 +--
 .../queries/PlannerTest/tpch-nested.test           | 210 +++----
 .../QueryTest/admission-max-min-mem-limits.test    |   4 +-
 .../QueryTest/admission-reject-mem-estimate.test   |   2 +-
 .../admission-reject-min-reservation.test          |   8 +-
 .../queries/QueryTest/datasketches-theta.test      |  72 +++
 .../QueryTest/dedicated-coord-mem-estimates.test   |   6 +-
 .../queries/QueryTest/explain-level2.test          |   4 +-
 .../queries/QueryTest/iceberg-ctas.test            | 105 ++++
 .../queries/QueryTest/iceberg-negative.test        |  10 +-
 .../queries/QueryTest/show-create-table.test       |  39 ++
 tests/hs2/test_hs2.py                              |   8 +
 tests/metadata/test_show_create_table.py           |   5 +-
 tests/query_test/test_iceberg.py                   |   3 +
 tests/query_test/test_mem_usage_scaling.py         |   2 +-
 tests/shell/test_shell_interactive.py              |   9 +
 194 files changed, 5257 insertions(+), 4648 deletions(-)
 copy common/thrift/{ImpalaInternalService.thrift => Query.thrift} (79%)
 create mode 100644 fe/src/main/java/org/apache/impala/catalog/CtasTargetTable.java
 create mode 100644 fe/src/main/java/org/apache/impala/catalog/iceberg/IcebergCtasTarget.java
 mode change 100644 => 100755 testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q43.test
 mode change 100644 => 100755 testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q44.test
 mode change 100644 => 100755 testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q56.test
 mode change 100644 => 100755 testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q60.test
 create mode 100644 testdata/workloads/functional-query/queries/QueryTest/iceberg-ctas.test


[impala] 05/08: IMPALA-10522: Support external use of frontend libraries

Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit b3d95d8f32c33c60657d6f518fe87a624509a618
Author: Kurt Deschler <kd...@cloudera.com>
AuthorDate: Thu Mar 26 10:35:36 2020 -0500

    IMPALA-10522: Support external use of frontend libraries
    
    This patch enables the Impala frontend jar and dependent library
    libfesupport.so to be used by an external Java frontend.
    
    Calling FeSupport.setExternalFE() will cause external frontend
    initialization mode to be used during FeSupport.loadLibrary(). This
    mode builds upon logic that is used to initialize the frontend jar for
    unit tests.
    
    Initialization in external frontend mode differs as follows:
    
    - Skip instantiating Frontend object and it's dependents
    - Skip loading libhdfs
    - Skip starting JVM Pause monitor
    - Disable Minidumper
    - Initialize TimezoneDatabase for external frontends
    - Disable redirect of stderr/stdout to libfesupport.so glog
    - Log messages from libfesupport.so to stderr
    - Use libfesupport.so for JNI symbol look up
    
    Null check were added in places where objects were assumed to be
    instantiated but are now skipped during initialization.
    
    Additional change:
    1) Add libfesupport.lib path to JAVA_LIBRARY_PATH in test driver
    
    Testing: - Initialized frontend jar from external frontend
     - Verified that frontend Java objects can be used externally without
       issues
     - Verified that exceptions thrown from Impala Java or libfesupport
       can be caught or propagated correctly by the external frontend
     - Manual verification of minicluster logs
     - Ran queries with external frontend
    
    Co-authored-by: John Sherman <jf...@cloudera.com>
    Co-authored-by: Aman Sinha <am...@cloudera.com>
    
    Change-Id: I4e3a84721ba196ec00773ce2923b19610b90edd9
    Reviewed-on: http://gerrit.cloudera.org:8080/17115
    Reviewed-by: Thomas Tauber-Marshall <tm...@cloudera.com>
    Tested-by: Thomas Tauber-Marshall <tm...@cloudera.com>
---
 be/src/benchmarks/expr-benchmark.cc                |  2 +-
 be/src/common/init.cc                              | 33 ++++++++++++++++++---
 be/src/common/init.h                               |  4 ++-
 be/src/runtime/data-stream-test.cc                 |  2 +-
 be/src/runtime/exec-env.cc                         | 34 ++++++++++++----------
 be/src/runtime/exec-env.h                          | 15 +++++++---
 be/src/runtime/lib-cache.cc                        | 11 ++++---
 be/src/runtime/lib-cache.h                         |  4 +--
 be/src/service/fe-support.cc                       | 17 ++++++-----
 be/src/util/jni-util.cc                            |  2 --
 .../java/org/apache/impala/service/FeSupport.java  | 18 +++++++++---
 testdata/bin/run-hive-server.sh                    |  3 ++
 12 files changed, 99 insertions(+), 46 deletions(-)

diff --git a/be/src/benchmarks/expr-benchmark.cc b/be/src/benchmarks/expr-benchmark.cc
index 689295f..f915096 100644
--- a/be/src/benchmarks/expr-benchmark.cc
+++ b/be/src/benchmarks/expr-benchmark.cc
@@ -67,7 +67,7 @@ class Planner {
  public:
   Planner() {
     frontend_.SetCatalogIsReady();
-    ABORT_IF_ERROR(exec_env_.InitForFeTests());
+    ABORT_IF_ERROR(exec_env_.InitForFeSupport());
   }
 
   ~Planner() {
diff --git a/be/src/common/init.cc b/be/src/common/init.cc
index 452a0af..3b67247 100644
--- a/be/src/common/init.cc
+++ b/be/src/common/init.cc
@@ -27,6 +27,7 @@
 #include "common/status.h"
 #include "exec/kudu-util.h"
 #include "exprs/scalar-expr-evaluator.h"
+#include "exprs/timezone_db.h"
 #include "gutil/atomicops.h"
 #include "gutil/strings/substitute.h"
 #include "rpc/authentication.h"
@@ -72,6 +73,7 @@ DECLARE_int32(logbufsecs);
 DECLARE_int32(max_log_files);
 DECLARE_int32(max_minidumps);
 DECLARE_string(redaction_rules_file);
+DECLARE_bool(redirect_stdout_stderr);
 DECLARE_string(reserved_words_version);
 DECLARE_bool(symbolize_stacktrace);
 
@@ -252,7 +254,7 @@ void BlockImpalaShutdownSignal() {
 }
 
 void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
-    TestInfo::Mode test_mode) {
+    TestInfo::Mode test_mode, bool external_fe) {
   srand(time(NULL));
   BlockImpalaShutdownSignal();
 
@@ -275,6 +277,16 @@ void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
 # else
   FLAGS_symbolize_stacktrace = true;
 #endif
+
+  if (external_fe) {
+    // Change defaults for flags when loaded as part of external frontend.
+    // Write logs to stderr by default (otherwise logs get written to
+    // FeSupport.INFO/ERROR).
+    FLAGS_logtostderr = true;
+    // Do not redirct stdout/stderr by default.
+    FLAGS_redirect_stdout_stderr = false;
+  }
+
   google::SetVersionString(impala::GetBuildVersion());
   google::ParseCommandLineFlags(&argc, &argv, true);
   if (!FLAGS_redaction_rules_file.empty()) {
@@ -298,7 +310,9 @@ void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
   }
   impala::InitGoogleLoggingSafe(argv[0]);
   // Breakpad needs flags and logging to initialize.
-  ABORT_IF_ERROR(RegisterMinidump(argv[0]));
+  if (!external_fe) {
+    ABORT_IF_ERROR(RegisterMinidump(argv[0]));
+  }
 #ifndef THREAD_SANITIZER
 #ifndef __aarch64__
   AtomicOps_x86CPUFeaturesInit();
@@ -360,14 +374,19 @@ void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
   }
 
   // Required for the FE's Catalog
-  ABORT_IF_ERROR(impala::LibCache::Init());
+  ABORT_IF_ERROR(impala::LibCache::Init(external_fe));
   Status fs_cache_init_status = impala::HdfsFsCache::Init();
   if (!fs_cache_init_status.ok()) CLEAN_EXIT_WITH_ERROR(fs_cache_init_status.GetDetail());
 
   if (init_jvm) {
+    if (!external_fe) {
+      JniUtil::InitLibhdfs();
+    }
     ABORT_IF_ERROR(JniUtil::Init());
     InitJvmLoggingSupport();
-    ABORT_IF_ERROR(JniUtil::InitJvmPauseMonitor());
+    if (!external_fe) {
+      ABORT_IF_ERROR(JniUtil::InitJvmPauseMonitor());
+    }
     ZipUtil::InitJvm();
   }
 
@@ -398,6 +417,12 @@ void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
     error_msg << "Failed to register action for SIGTERM: " << GetStrErrMsg();
     CLEAN_EXIT_WITH_ERROR(error_msg.str());
   }
+
+  if (external_fe) {
+    // Explicitly load the timezone database for external FEs. Impala daemons load it
+    // through ImpaladMain
+    ABORT_IF_ERROR(TimezoneDatabase::Initialize());
+  }
 }
 
 Status impala::StartMemoryMaintenanceThread() {
diff --git a/be/src/common/init.h b/be/src/common/init.h
index ff0194e..e55c32b 100644
--- a/be/src/common/init.h
+++ b/be/src/common/init.h
@@ -32,8 +32,10 @@ namespace impala {
 /// logging directory, and enable special test-specific behavior.
 /// Callers that want to override default gflags variables should do so before calling
 /// this method. No logging should be performed until after this method returns.
+/// Passing external_fe=true causes specific initialization steps to be skipped
+/// that an external frontend will have already performed.
 void InitCommonRuntime(int argc, char** argv, bool init_jvm,
-    TestInfo::Mode m = TestInfo::NON_TEST);
+    TestInfo::Mode m = TestInfo::NON_TEST, bool external_fe = false);
 
 /// Starts background memory maintenance thread. Must be called after
 /// RegisterMemoryMetrics(). This thread is needed for daemons to free memory and
diff --git a/be/src/runtime/data-stream-test.cc b/be/src/runtime/data-stream-test.cc
index 21c273f..a8dd51a 100644
--- a/be/src/runtime/data-stream-test.cc
+++ b/be/src/runtime/data-stream-test.cc
@@ -151,7 +151,7 @@ class DataStreamTest : public testing::Test {
 
   virtual void SetUp() {
     exec_env_.reset(new ExecEnv());
-    ABORT_IF_ERROR(exec_env_->InitForFeTests());
+    ABORT_IF_ERROR(exec_env_->InitForFeSupport());
     exec_env_->InitBufferPool(32 * 1024, 1024 * 1024 * 1024, 32 * 1024);
     runtime_state_.reset(new RuntimeState(TQueryCtx(), exec_env_.get()));
     TPlanFragment* fragment = runtime_state_->obj_pool()->Add(new TPlanFragment());
diff --git a/be/src/runtime/exec-env.cc b/be/src/runtime/exec-env.cc
index fe06948..c3c8f06 100644
--- a/be/src/runtime/exec-env.cc
+++ b/be/src/runtime/exec-env.cc
@@ -229,12 +229,12 @@ struct ExecEnv::KuduClientPtr {
 
 ExecEnv* ExecEnv::exec_env_ = nullptr;
 
-ExecEnv::ExecEnv()
+ExecEnv::ExecEnv(bool external_fe)
   : ExecEnv(FLAGS_krpc_port, FLAGS_state_store_subscriber_port, FLAGS_webserver_port,
-        FLAGS_state_store_host, FLAGS_state_store_port) {}
+        FLAGS_state_store_host, FLAGS_state_store_port, external_fe) {}
 
 ExecEnv::ExecEnv(int krpc_port, int subscriber_port, int webserver_port,
-    const string& statestore_host, int statestore_port)
+    const string& statestore_host, int statestore_port, bool external_fe)
   : obj_pool_(new ObjectPool),
     metrics_(new MetricGroup("impala-metrics")),
     // Create the CatalogServiceClientCache with num_retries = 1 and wait_ms = 0.
@@ -250,11 +250,12 @@ ExecEnv::ExecEnv(int krpc_port, int subscriber_port, int webserver_port,
     pool_mem_trackers_(new PoolMemTrackerRegistry),
     thread_mgr_(new ThreadResourceMgr),
     tmp_file_mgr_(new TmpFileMgr),
-    frontend_(new Frontend()),
+    frontend_(external_fe ? nullptr : new Frontend()),
     async_rpc_pool_(new CallableThreadPool("rpc-pool", "async-rpc-sender", 8, 10000)),
     query_exec_mgr_(new QueryExecMgr()),
     rpc_metrics_(metrics_->GetOrCreateChildGroup("rpc")),
     enable_webserver_(FLAGS_enable_webserver && webserver_port > 0),
+    external_fe_(external_fe),
     configured_backend_address_(MakeNetworkAddress(FLAGS_hostname, krpc_port)) {
   UUIDToUniqueIdPB(boost::uuids::random_generator()(), &backend_id_);
 
@@ -321,7 +322,7 @@ ExecEnv::~ExecEnv() {
   disk_io_mgr_.reset(); // Need to tear down before mem_tracker_.
 }
 
-Status ExecEnv::InitForFeTests() {
+Status ExecEnv::InitForFeSupport() {
   mem_tracker_.reset(new MemTracker(-1, "Process"));
   is_fe_tests_ = true;
   return Status::OK();
@@ -469,7 +470,7 @@ Status ExecEnv::Init() {
   }
 
   RETURN_IF_ERROR(cluster_membership_mgr_->Init());
-  if (FLAGS_is_coordinator) {
+  if (FLAGS_is_coordinator && frontend_ != nullptr) {
     cluster_membership_mgr_->RegisterUpdateCallbackFn(
         [this](ClusterMembershipMgr::SnapshotPtr snapshot) {
           SendClusterMembershipToFrontend(snapshot, this->frontend());
@@ -482,15 +483,18 @@ Status ExecEnv::Init() {
 }
 
 Status ExecEnv::InitHadoopConfig() {
-  // Get the fs.defaultFS value set in core-site.xml and assign it to configured_defaultFs
-  TGetHadoopConfigRequest config_request;
-  config_request.__set_name(DEFAULT_FS);
-  TGetHadoopConfigResponse config_response;
-  RETURN_IF_ERROR(frontend_->GetHadoopConfig(config_request, &config_response));
-  if (config_response.__isset.value) {
-    default_fs_ = config_response.value;
-  } else {
-    default_fs_ = "hdfs://";
+  if (frontend_ != nullptr) {
+    // Get the fs.defaultFS value set in core-site.xml and assign it to
+    // configured_defaultFs
+    TGetHadoopConfigRequest config_request;
+    config_request.__set_name(DEFAULT_FS);
+    TGetHadoopConfigResponse config_response;
+    RETURN_IF_ERROR(frontend_->GetHadoopConfig(config_request, &config_response));
+    if (config_response.__isset.value) {
+      default_fs_ = config_response.value;
+    } else {
+      default_fs_ = "hdfs://";
+    }
   }
   return Status::OK();
 }
diff --git a/be/src/runtime/exec-env.h b/be/src/runtime/exec-env.h
index e378d5b..192b7a4 100644
--- a/be/src/runtime/exec-env.h
+++ b/be/src/runtime/exec-env.h
@@ -81,10 +81,13 @@ namespace io {
 /// ExecEnv::GetInstance().
 class ExecEnv {
  public:
-  ExecEnv();
+  /// If external_fe = true, some members (i.e. frontend_) are not used and will
+  /// be initialized to null.
+  /// TODO: Split out common logic into base class and eliminate null pointers.
+  ExecEnv(bool external_fe = false);
 
   ExecEnv(int krpc_port, int subscriber_port, int webserver_port,
-      const std::string& statestore_host, int statestore_port);
+      const std::string& statestore_host, int statestore_port, bool external_fe = false);
 
   /// Returns the most recently created exec env instance. In a normal impalad, this is
   /// the only instance. In test setups with multiple ExecEnv's per process,
@@ -128,7 +131,10 @@ class ExecEnv {
   HdfsOpThreadPool* hdfs_op_thread_pool() { return hdfs_op_thread_pool_.get(); }
   TmpFileMgr* tmp_file_mgr() { return tmp_file_mgr_.get(); }
   ImpalaServer* impala_server() { return impala_server_; }
-  Frontend* frontend() { return frontend_.get(); }
+  Frontend* frontend() {
+    DCHECK(frontend_.get() != nullptr);
+    return frontend_.get();
+  }
   RequestPoolService* request_pool_service() { return request_pool_service_.get(); }
   CallableThreadPool* rpc_pool() { return async_rpc_pool_.get(); }
   QueryExecMgr* query_exec_mgr() { return query_exec_mgr_.get(); }
@@ -154,7 +160,7 @@ class ExecEnv {
   const TNetworkAddress& krpc_address() const { return krpc_address_; }
 
   /// Initializes the exec env for running FE tests.
-  Status InitForFeTests() WARN_UNUSED_RESULT;
+  Status InitForFeSupport() WARN_UNUSED_RESULT;
 
   /// Returns true if this environment was created from the FE tests. This makes the
   /// environment special since the JVM is started first and libraries are loaded
@@ -229,6 +235,7 @@ class ExecEnv {
   MetricGroup* rpc_metrics_ = nullptr;
 
   bool enable_webserver_;
+  bool external_fe_;
 
  private:
   friend class TestEnv;
diff --git a/be/src/runtime/lib-cache.cc b/be/src/runtime/lib-cache.cc
index c8084eb..838cef7 100644
--- a/be/src/runtime/lib-cache.cc
+++ b/be/src/runtime/lib-cache.cc
@@ -102,14 +102,17 @@ LibCache::~LibCache() {
   if (current_process_handle_ != nullptr) DynamicClose(current_process_handle_);
 }
 
-Status LibCache::Init() {
+Status LibCache::Init(bool external_fe) {
   DCHECK(LibCache::instance_.get() == nullptr);
   LibCache::instance_.reset(new LibCache());
-  return LibCache::instance_->InitInternal();
+  return LibCache::instance_->InitInternal(external_fe);
 }
 
-Status LibCache::InitInternal() {
-  if (TestInfo::is_fe_test()) {
+Status LibCache::InitInternal(bool external_fe) {
+  if (external_fe) {
+    LOG(INFO) << "Library cache is using shared object for process handle";
+    RETURN_IF_ERROR(DynamicOpen("libfesupport.so", &current_process_handle_));
+  } else if (TestInfo::is_fe_test()) {
     // In the FE tests, nullptr gives the handle to the java process.
     // Explicitly load the fe-support shared object.
     string fe_support_path;
diff --git a/be/src/runtime/lib-cache.h b/be/src/runtime/lib-cache.h
index 69a6c77..5f09a9e 100644
--- a/be/src/runtime/lib-cache.h
+++ b/be/src/runtime/lib-cache.h
@@ -72,7 +72,7 @@ class LibCache {
   ~LibCache();
 
   /// Initializes the libcache. Must be called before any other APIs.
-  static Status Init();
+  static Status Init(bool external_fe);
 
   /// Gets the local 'path' used to cache the file stored at the global 'hdfs_lib_file'. If
   /// this file is not already on the local fs, or if the cached entry's last modified
@@ -156,7 +156,7 @@ class LibCache {
   LibCache(LibCache const& l); // disable copy ctor
   LibCache& operator=(LibCache const& l); // disable assignment
 
-  Status InitInternal();
+  Status InitInternal(bool external_fe);
 
   /// Returns the cache entry for 'hdfs_lib_file'. If this library has not been
   /// copied locally, it will copy it and add a new LibCacheEntry to 'lib_cache_'.
diff --git a/be/src/service/fe-support.cc b/be/src/service/fe-support.cc
index 0a25997..c0eb3f0 100644
--- a/be/src/service/fe-support.cc
+++ b/be/src/service/fe-support.cc
@@ -63,23 +63,24 @@ using namespace apache::thrift::server;
 
 static bool fe_support_disable_codegen = true;
 
-// Called from the FE when it explicitly loads libfesupport.so for tests.
+// Called from tests or external FE after it explicitly loads libfesupport.so.
 // This creates the minimal state necessary to service the other JNI calls.
 // This is not called when we first start up the BE.
 extern "C"
 JNIEXPORT void JNICALL
-Java_org_apache_impala_service_FeSupport_NativeFeTestInit(
-    JNIEnv* env, jclass fe_support_class) {
+Java_org_apache_impala_service_FeSupport_NativeFeInit(
+    JNIEnv* env, jclass fe_support_class, bool external_fe) {
   DCHECK(ExecEnv::GetInstance() == NULL) << "This should only be called once from the FE";
   char* env_logs_dir_str = std::getenv("IMPALA_FE_TEST_LOGS_DIR");
   if (env_logs_dir_str != nullptr) FLAGS_log_dir = env_logs_dir_str;
   char* name = const_cast<char*>("FeSupport");
   // Init the JVM to load the classes in JniUtil that are needed for returning
   // exceptions to the FE.
-  InitCommonRuntime(1, &name, true, TestInfo::FE_TEST);
+  InitCommonRuntime(1, &name, true,
+      external_fe ? TestInfo::NON_TEST : TestInfo::FE_TEST, external_fe);
   THROW_IF_ERROR(LlvmCodeGen::InitializeLlvm(true), env, JniUtil::internal_exc_class());
-  ExecEnv* exec_env = new ExecEnv(); // This also caches it from the process.
-  THROW_IF_ERROR(exec_env->InitForFeTests(), env, JniUtil::internal_exc_class());
+  ExecEnv* exec_env = new ExecEnv(external_fe); // This also caches it from the process.
+  THROW_IF_ERROR(exec_env->InitForFeSupport(), env, JniUtil::internal_exc_class());
 }
 
 // Serializes expression value 'value' to thrift structure TColumnValue 'col_val'.
@@ -692,8 +693,8 @@ namespace impala {
 
 static JNINativeMethod native_methods[] = {
   {
-      const_cast<char*>("NativeFeTestInit"), const_cast<char*>("()V"),
-      (void*)::Java_org_apache_impala_service_FeSupport_NativeFeTestInit
+      const_cast<char*>("NativeFeInit"), const_cast<char*>("(Z)V"),
+      (void*)::Java_org_apache_impala_service_FeSupport_NativeFeInit
   },
   {
       const_cast<char*>("NativeEvalExprsWithoutRow"), const_cast<char*>("([B[BJ)[B"),
diff --git a/be/src/util/jni-util.cc b/be/src/util/jni-util.cc
index 62df916..8792f78 100644
--- a/be/src/util/jni-util.cc
+++ b/be/src/util/jni-util.cc
@@ -129,8 +129,6 @@ Status JniUtil::LocalToGlobalRef(JNIEnv* env, jobject local_ref, jobject* global
 }
 
 Status JniUtil::Init() {
-  InitLibhdfs();
-
   // Get the JNIEnv* corresponding to current thread.
   JNIEnv* env = JniUtil::GetJNIEnv();
   if (env == NULL) return Status("Failed to get/create JVM");
diff --git a/fe/src/main/java/org/apache/impala/service/FeSupport.java b/fe/src/main/java/org/apache/impala/service/FeSupport.java
index bbca6bd..0fabc12 100644
--- a/fe/src/main/java/org/apache/impala/service/FeSupport.java
+++ b/fe/src/main/java/org/apache/impala/service/FeSupport.java
@@ -69,10 +69,11 @@ import com.google.common.base.Preconditions;
 public class FeSupport {
   private final static Logger LOG = LoggerFactory.getLogger(FeSupport.class);
   private static boolean loaded_ = false;
+  private static boolean externalFE_ = false;
 
-  // Only called if this library is explicitly loaded. This only happens
-  // when running FE tests.
-  public native static void NativeFeTestInit();
+  // Only called if this library is explicitly loaded. This happens
+  // when running FE tests or external FE
+  public native static void NativeFeInit(boolean externalFE);
 
   // Returns a serialized TResultRow
   public native static byte[] NativeEvalExprsWithoutRow(
@@ -471,6 +472,15 @@ public class FeSupport {
   }
 
   /**
+   * Calling this function before loadLibrary() causes external frontend
+   * initialization to be used during NativeFeInit()
+   */
+  public static synchronized void setExternalFE() {
+    Preconditions.checkState(!loaded_);
+    externalFE_ = true;
+  }
+
+  /**
    * This function should be called explicitly by the FeSupport to ensure that
    * native functions are loaded. Tests that depend on JniCatalog or JniFrontend
    * being instantiated should also call this function.
@@ -481,6 +491,6 @@ public class FeSupport {
     NativeLibUtil.loadLibrary("libfesupport.so");
     LOG.info("Loaded libfesupport.so");
     loaded_ = true;
-    NativeFeTestInit();
+    NativeFeInit(externalFE_);
   }
 }
diff --git a/testdata/bin/run-hive-server.sh b/testdata/bin/run-hive-server.sh
index fda2ce1..25986c5 100755
--- a/testdata/bin/run-hive-server.sh
+++ b/testdata/bin/run-hive-server.sh
@@ -120,6 +120,9 @@ HADOOP_CLIENT_OPTS="-Xmx2024m -Dhive.log.file=hive-metastore.log" hive \
 # Wait for the Metastore to come up because HiveServer2 relies on it being live.
 ${CLUSTER_BIN}/wait-for-metastore.py --transport=${METASTORE_TRANSPORT}
 
+# Include the latest libfesupport.so in the JAVA_LIBRARY_PATH
+export JAVA_LIBRARY_PATH="${JAVA_LIBRARY_PATH-}:${IMPALA_HOME}/be/build/latest/service/"
+
 if [ ${ONLY_METASTORE} -eq 0 ]; then
   # Starts a HiveServer2 instance on the port specified by the HIVE_SERVER2_THRIFT_PORT
   # environment variable. HADOOP_HEAPSIZE should be set to at least 2048 to avoid OOM


[impala] 03/08: IMPALA-10520: Implement ds_theta_intersect() function

Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit 0d22e89df452d3e21912b60c72a087a3e8c38057
Author: Fucun Chu <ch...@hotmail.com>
AuthorDate: Thu Feb 4 15:24:25 2021 +0800

    IMPALA-10520: Implement ds_theta_intersect() function
    
    This function receives a set of serialized Apache DataSketches Theta
    sketches produced by ds_theta_sketch() and intersects them into a
    single sketch.
    
    An example usage is to create a sketch for each partition of a table,
    write these sketches to a separate table and intersect them to get
    estimates based on the partitions the user is interested in related
    sketches. E.g.:
      SELECT
          ds_theta_estimate(ds_theta_intersect(sketch_col))
      FROM sketch_tbl
      WHERE partition_col=1 OR partition_col=5;
    
    Testing:
      - Apart from the automated tests I added to this patch I also
        tested ds_theta_intersect() on a bigger dataset to check that
        serialization, deserialization and merging steps work well. I
        took TPCH25.linelitem, created a number of sketches with grouping
        by l_shipdate and called ds_theta_intersect() on those sketches
    
    Change-Id: I80e68c2151c4604f0386d3dfb004c82b10293f97
    Reviewed-on: http://gerrit.cloudera.org:8080/17088
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 be/src/exprs/aggregate-functions-ir.cc             | 87 ++++++++++++++++++++++
 be/src/exprs/aggregate-functions.h                 |  9 +++
 .../java/org/apache/impala/catalog/BuiltinsDb.java | 14 ++++
 .../queries/QueryTest/datasketches-theta.test      | 72 ++++++++++++++++++
 4 files changed, 182 insertions(+)

diff --git a/be/src/exprs/aggregate-functions-ir.cc b/be/src/exprs/aggregate-functions-ir.cc
index 23ed6d3..f2a078a 100644
--- a/be/src/exprs/aggregate-functions-ir.cc
+++ b/be/src/exprs/aggregate-functions-ir.cc
@@ -42,6 +42,7 @@
 #include "thirdparty/datasketches/hll.hpp"
 #include "thirdparty/datasketches/theta_sketch.hpp"
 #include "thirdparty/datasketches/theta_union.hpp"
+#include "thirdparty/datasketches/theta_intersection.hpp"
 #include "thirdparty/datasketches/kll_sketch.hpp"
 #include "util/arithmetic-util.h"
 #include "util/mpfit-util.h"
@@ -1660,6 +1661,22 @@ StringVal SerializeDsThetaUnion(
   return SerializeDsThetaSketch(ctx, sketch);
 }
 
+/// Auxiliary function that receives a theta_intersection, gets the underlying Theta
+/// sketch from the intersection object and returns the serialized, compacted Theta sketch
+/// wrapped into StringVal (may be null).
+/// Introducing this function in the .cc to avoid including the whole DataSketches Theta
+/// functionality into the header.
+StringVal SerializeDsThetaIntersection(
+    FunctionContext* ctx, const datasketches::theta_intersection& ds_intersection) {
+  std::stringstream serialized_input;
+  // Calling get_result() before calling update() is undefined, so you need to check.
+  if (ds_intersection.has_result()) {
+    datasketches::compact_theta_sketch sketch = ds_intersection.get_result();
+    return SerializeDsThetaSketch(ctx, sketch);
+  }
+  return StringVal::null();
+}
+
 /// Auxiliary function that receives a kll_sketch<float> and returns the serialized
 /// version of it wrapped into a StringVal.
 /// Introducing this function in the .cc to avoid including the whole DataSketches HLL
@@ -2030,6 +2047,76 @@ StringVal AggregateFunctions::DsThetaUnionFinalize(
   return result;
 }
 
+void AggregateFunctions::DsThetaIntersectInit(FunctionContext* ctx, StringVal* slot) {
+  AllocBuffer(ctx, slot, sizeof(datasketches::theta_intersection));
+  if (UNLIKELY(slot->is_null)) {
+    DCHECK(!ctx->impl()->state()->GetQueryStatus().ok());
+    return;
+  }
+  datasketches::theta_intersection* intersection_ptr =
+      reinterpret_cast<datasketches::theta_intersection*>(slot->ptr);
+  *intersection_ptr = datasketches::theta_intersection();
+}
+
+void AggregateFunctions::DsThetaIntersectUpdate(
+    FunctionContext* ctx, const StringVal& src, StringVal* dst) {
+  if (src.is_null) return;
+  DCHECK(!dst->is_null);
+  DCHECK_EQ(dst->len, sizeof(datasketches::theta_intersection));
+  try {
+    auto src_sketch = datasketches::theta_sketch::deserialize((void*)src.ptr, src.len);
+    if (src_sketch->is_empty()) return;
+    datasketches::theta_intersection* intersection_ptr =
+        reinterpret_cast<datasketches::theta_intersection*>(dst->ptr);
+    intersection_ptr->update(*src_sketch);
+  } catch (const std::exception&) {
+    LogSketchDeserializationError(ctx);
+  }
+}
+
+StringVal AggregateFunctions::DsThetaIntersectSerialize(
+    FunctionContext* ctx, const StringVal& src) {
+  DCHECK(!src.is_null);
+  DCHECK_EQ(src.len, sizeof(datasketches::theta_intersection));
+  datasketches::theta_intersection* intersection_ptr =
+      reinterpret_cast<datasketches::theta_intersection*>(src.ptr);
+  StringVal dst = SerializeDsThetaIntersection(ctx, *intersection_ptr);
+  ctx->Free(src.ptr);
+  return dst;
+}
+
+void AggregateFunctions::DsThetaIntersectMerge(
+    FunctionContext* ctx, const StringVal& src, StringVal* dst) {
+  if (src.is_null) return;
+  DCHECK(!dst->is_null);
+  DCHECK_EQ(dst->len, sizeof(datasketches::theta_intersection));
+
+  // Note, 'src' is a serialized compact_theta_sketch and not a serialized
+  // theta_intersection.
+  auto src_sketch = datasketches::theta_sketch::deserialize((void*)src.ptr, src.len);
+
+  datasketches::theta_intersection* dst_intersection_ptr =
+      reinterpret_cast<datasketches::theta_intersection*>(dst->ptr);
+
+  dst_intersection_ptr->update(*src_sketch);
+}
+
+StringVal AggregateFunctions::DsThetaIntersectFinalize(
+    FunctionContext* ctx, const StringVal& src) {
+  DCHECK(!src.is_null);
+  DCHECK_EQ(src.len, sizeof(datasketches::theta_intersection));
+  datasketches::theta_intersection* intersection_ptr =
+      reinterpret_cast<datasketches::theta_intersection*>(src.ptr);
+  if (!intersection_ptr->has_result()) {
+    ctx->Free(src.ptr);
+    return StringVal::null();
+  }
+  auto sketch = intersection_ptr->get_result();
+  StringVal result = SerializeDsThetaSketch(ctx, sketch);
+  ctx->Free(src.ptr);
+  return result;
+}
+
 void AggregateFunctions::DsKllInitHelper(FunctionContext* ctx, StringVal* slot) {
   AllocBuffer(ctx, slot, sizeof(datasketches::kll_sketch<float>));
   if (UNLIKELY(slot->is_null)) {
diff --git a/be/src/exprs/aggregate-functions.h b/be/src/exprs/aggregate-functions.h
index 474e23d..104eda8 100644
--- a/be/src/exprs/aggregate-functions.h
+++ b/be/src/exprs/aggregate-functions.h
@@ -266,6 +266,15 @@ class AggregateFunctions {
   static void DsThetaUnionMerge(FunctionContext*, const StringVal& src, StringVal* dst);
   static StringVal DsThetaUnionFinalize(FunctionContext*, const StringVal& src);
 
+  /// These functions implement ds_theta_intersect().
+  static void DsThetaIntersectInit(FunctionContext*, StringVal* slot);
+  static void DsThetaIntersectUpdate(
+      FunctionContext*, const StringVal& src, StringVal* dst);
+  static StringVal DsThetaIntersectSerialize(FunctionContext*, const StringVal& src);
+  static void DsThetaIntersectMerge(
+      FunctionContext*, const StringVal& src, StringVal* dst);
+  static StringVal DsThetaIntersectFinalize(FunctionContext*, const StringVal& src);
+
   /// These functions implement Apache DataSketches KLL support for sketching.
   static void DsKllInit(FunctionContext*, StringVal* slot);
   static void DsKllUpdate(FunctionContext*, const FloatVal& src, StringVal* dst);
diff --git a/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java b/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java
index 6a1a609..fa76cf1 100644
--- a/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java
+++ b/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java
@@ -1434,6 +1434,20 @@ public class BuiltinsDb extends Db {
             "20DsThetaUnionFinalizeEPN10impala_udf15FunctionContextERKNS1_9StringValE",
         true, false, true));
 
+    // DataSketches Theta intersect
+    db.addBuiltin(AggregateFunction.createBuiltin(db, "ds_theta_intersect",
+        Lists.<Type>newArrayList(Type.STRING), Type.STRING, Type.STRING,
+        prefix + "20DsThetaIntersectInitEPN10impala_udf15FunctionContextEPNS1_9StringValE",
+        prefix +
+            "22DsThetaIntersectUpdateEPN10impala_udf15FunctionContextERKNS1_9StringValEPS4_",
+        prefix +
+            "21DsThetaIntersectMergeEPN10impala_udf15FunctionContextERKNS1_9StringValEPS4_",
+        prefix +
+            "25DsThetaIntersectSerializeEPN10impala_udf15FunctionContextERKNS1_9StringValE",
+        prefix +
+            "24DsThetaIntersectFinalizeEPN10impala_udf15FunctionContextERKNS1_9StringValE",
+        true, false, true));
+
     for (Type t: Type.getSupportedTypes()) {
       if (t.isNull()) continue; // NULL is handled through type promotion.
       if (t.isScalarType(PrimitiveType.CHAR)) continue; // promoted to STRING
diff --git a/testdata/workloads/functional-query/queries/QueryTest/datasketches-theta.test b/testdata/workloads/functional-query/queries/QueryTest/datasketches-theta.test
index 84ae7f9..fe7da72 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/datasketches-theta.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/datasketches-theta.test
@@ -233,3 +233,75 @@ BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT
 ---- RESULTS
 5,7,6,6,7,4,4,3,0
 ====
+---- QUERY
+# Intersect the sketches in sketch_store and check.
+select
+    ds_theta_estimate(ds_theta_intersect(date_sketch)),
+    ds_theta_estimate(ds_theta_intersect(float_sketch))
+from sketch_store;
+---- TYPES
+BIGINT,BIGINT
+---- RESULTS
+0,10
+====
+---- QUERY
+# Checks that ds_theta_intersect() produces NULL for an empty dataset.
+select ds_theta_intersect(field) from functional_parquet.emptytable;
+---- TYPES
+STRING
+---- RESULTS
+'NULL'
+====
+---- QUERY
+# Checks that ds_theta_intersect() produces NULL for NULL inputs.
+select ds_theta_intersect(null_str) from functional_parquet.nullrows;
+---- TYPES
+STRING
+---- RESULTS
+'NULL'
+====
+---- QUERY
+# ds_theta_intersect() returns an error if it receives an invalid serialized sketch.
+select ds_theta_intersect(date_string_col) from functional_parquet.alltypestiny
+where id=1;
+---- CATCH
+UDF ERROR: Unable to deserialize sketch.
+====
+---- QUERY
+# Check that sketches made by Hive for intersection and estimation, which is consistent
+# with direct estimation of these sketches.
+select
+    ds_theta_estimate(ds_theta_intersect(ti)) as ti,
+    ds_theta_estimate(ds_theta_intersect(i)) as i,
+    ds_theta_estimate(ds_theta_intersect(bi)) as bi,
+    ds_theta_estimate(ds_theta_intersect(f)) as f,
+    ds_theta_estimate(ds_theta_intersect(d)) as d,
+    ds_theta_estimate(ds_theta_intersect(s)) as s,
+    ds_theta_estimate(ds_theta_intersect(c)) as c,
+    ds_theta_estimate(ds_theta_intersect(v)) as v,
+    ds_theta_estimate(ds_theta_intersect(nc)) as nc
+from theta_sketches_from_hive;
+---- TYPES
+BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT
+---- RESULTS
+5,7,6,6,7,4,4,3,0
+====
+---- QUERY
+# Intersect the sketches from theta_sketches_impala_hive and checks if the intersection
+# produces the same result as if these sketches were used separately to get the estimates.
+select
+    ds_theta_estimate(ds_theta_intersect(ti)) as ti,
+    ds_theta_estimate(ds_theta_intersect(i)) as i,
+    ds_theta_estimate(ds_theta_intersect(bi)) as bi,
+    ds_theta_estimate(ds_theta_intersect(f)) as f,
+    ds_theta_estimate(ds_theta_intersect(d)) as d,
+    ds_theta_estimate(ds_theta_intersect(s)) as s,
+    ds_theta_estimate(ds_theta_intersect(c)) as c,
+    ds_theta_estimate(ds_theta_intersect(v)) as v,
+    ds_theta_estimate(ds_theta_intersect(nc)) as nc
+from theta_sketches_impala_hive;
+---- TYPES
+BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT,BIGINT
+---- RESULTS
+5,7,6,6,7,4,4,3,0
+====
\ No newline at end of file


[impala] 08/08: IMPALA-10222: CREATE TABLE AS SELECT for Iceberg tables

Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit 6c6b0ee869a766ba816e82c2fc821e499b2041c2
Author: Zoltan Borok-Nagy <bo...@cloudera.com>
AuthorDate: Fri Feb 19 15:30:17 2021 +0100

    IMPALA-10222: CREATE TABLE AS SELECT for Iceberg tables
    
    This patch adds support for CREATE TABLE AS SELECT statements
    for Iceberg tables.
    
    CTAS statements work like the following in Impala:
    
    1. Analysis of the whole CTAS statement
    2. Divide CTAS to CREATE stmt and INSERT stmt
    3. Create temporary in-memory target table from the CREATE stmt
    4. Analyse the INSERT statement by using the temporary target table
    5. If everything is OK so far, create the target table
    6. Execute the INSERT query
    
    For Iceberg tables the non-trivial thing was to create the temporary
    target table without actually creating it via Iceberg API. I've created
    a new class 'IcebergCtasTarget' that mimics an FeIceberg table. It can be
    used with catalog V1 and V2 as well.
    
    Testing
     * e2e CTAS tests in iceberg-ctas.test
     * SHOW CREATE TABLE stmts in show-create-table.test
    
    Change-Id: I81d2084e401b9fa74d5ad161b51fd3e2aa3fcc67
    Reviewed-on: http://gerrit.cloudera.org:8080/17130
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 fe/src/main/cup/sql-parser.cup                     |  10 +
 .../impala/analysis/CreateTableAsSelectStmt.java   |  18 +-
 .../org/apache/impala/analysis/InsertStmt.java     |  36 ++-
 .../org/apache/impala/catalog/CtasTargetTable.java | 176 +++++++++++++
 .../org/apache/impala/catalog/FeIcebergTable.java  |  23 +-
 .../java/org/apache/impala/catalog/HdfsTable.java  |   2 +-
 .../impala/catalog/iceberg/IcebergCtasTarget.java  | 279 +++++++++++++++++++++
 .../org/apache/impala/catalog/local/LocalDb.java   |   2 +-
 .../apache/impala/catalog/local/LocalFsTable.java  |   2 +-
 .../impala/service/IcebergCatalogOpExecutor.java   |   3 +-
 .../apache/impala/util/IcebergSchemaConverter.java |   2 +-
 .../java/org/apache/impala/util/IcebergUtil.java   |  13 +-
 .../org/apache/impala/analysis/AnalyzeDDLTest.java |   4 +-
 .../queries/QueryTest/iceberg-ctas.test            | 105 ++++++++
 .../queries/QueryTest/iceberg-negative.test        |  10 +-
 .../queries/QueryTest/show-create-table.test       |  39 +++
 tests/metadata/test_show_create_table.py           |   5 +-
 tests/query_test/test_iceberg.py                   |   3 +
 18 files changed, 686 insertions(+), 46 deletions(-)

diff --git a/fe/src/main/cup/sql-parser.cup b/fe/src/main/cup/sql-parser.cup
index 6fabdd7..bbb802a 100644
--- a/fe/src/main/cup/sql-parser.cup
+++ b/fe/src/main/cup/sql-parser.cup
@@ -1349,6 +1349,16 @@ create_tbl_as_select_params ::=
         select_stmt, null);
   :}
   | tbl_def_without_col_defs:tbl_def
+    iceberg_partition_spec_list:iceberg_specs
+    tbl_options:options
+    KW_AS query_stmt:select_stmt
+  {:
+    tbl_def.getIcebergPartitionSpecs().addAll(iceberg_specs);
+    tbl_def.setOptions(options);
+    RESULT = new CreateTableAsSelectStmt.CtasParams(new CreateTableStmt(tbl_def),
+        select_stmt, null);
+  :}
+  | tbl_def_without_col_defs:tbl_def
     KW_PARTITIONED KW_BY LPAREN ident_list:partition_cols RPAREN
     tbl_options:options
     KW_AS query_stmt:select_stmt
diff --git a/fe/src/main/java/org/apache/impala/analysis/CreateTableAsSelectStmt.java b/fe/src/main/java/org/apache/impala/analysis/CreateTableAsSelectStmt.java
index 7dc4639..cf952b6 100644
--- a/fe/src/main/java/org/apache/impala/analysis/CreateTableAsSelectStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/CreateTableAsSelectStmt.java
@@ -28,8 +28,10 @@ import org.apache.impala.catalog.FeFsTable;
 import org.apache.impala.catalog.FeKuduTable;
 import org.apache.impala.catalog.FeTable;
 import org.apache.impala.catalog.HdfsFileFormat;
+import org.apache.impala.catalog.IcebergTable;
 import org.apache.impala.catalog.KuduTable;
 import org.apache.impala.catalog.Type;
+import org.apache.impala.catalog.iceberg.IcebergCtasTarget;
 import org.apache.impala.common.AnalysisException;
 import org.apache.impala.compat.MetastoreShim;
 import org.apache.impala.rewrite.ExprRewriter;
@@ -65,7 +67,8 @@ public class CreateTableAsSelectStmt extends StatementBase {
   /////////////////////////////////////////
 
   private final static EnumSet<THdfsFileFormat> SUPPORTED_INSERT_FORMATS =
-      EnumSet.of(THdfsFileFormat.PARQUET, THdfsFileFormat.TEXT, THdfsFileFormat.KUDU);
+      EnumSet.of(THdfsFileFormat.ICEBERG, THdfsFileFormat.PARQUET, THdfsFileFormat.TEXT,
+          THdfsFileFormat.KUDU);
 
   /**
    * Helper class for parsing.
@@ -127,7 +130,7 @@ public class CreateTableAsSelectStmt extends StatementBase {
       throw new AnalysisException(String.format("CREATE TABLE AS SELECT " +
           "does not support the (%s) file format. Supported formats are: (%s)",
           createStmt_.getFileFormat().toString().replace("_", ""),
-          "PARQUET, TEXTFILE, KUDU"));
+          "PARQUET, TEXTFILE, KUDU, ICEBERG"));
     }
     if (createStmt_.getFileFormat() == THdfsFileFormat.KUDU && createStmt_.isExternal()) {
       // TODO: Add support for CTAS on external Kudu tables (see IMPALA-4318)
@@ -223,6 +226,17 @@ public class CreateTableAsSelectStmt extends StatementBase {
         tmpTable = db.createKuduCtasTarget(msTbl, createStmt_.getColumnDefs(),
             createStmt_.getPrimaryKeyColumnDefs(),
             createStmt_.getKuduPartitionParams());
+      } else if (IcebergTable.isIcebergTable(msTbl)) {
+        IcebergPartitionSpec partSpec = null;
+        if (createStmt_.getIcebergPartitionSpecs() != null &&
+           !createStmt_.getIcebergPartitionSpecs().isEmpty()) {
+          // Since this is a CREATE TABLE statement, the Iceberg table can only have
+          // a single partition spec.
+          Preconditions.checkState(createStmt_.getIcebergPartitionSpecs().size() == 1);
+          partSpec = createStmt_.getIcebergPartitionSpecs().get(0);
+        }
+        tmpTable = new IcebergCtasTarget(db, msTbl, createStmt_.getColumnDefs(),
+            partSpec);
       } else if (HdfsFileFormat.isHdfsInputFormatClass(msTbl.getSd().getInputFormat())) {
         tmpTable = db.createFsCtasTarget(msTbl);
       }
diff --git a/fe/src/main/java/org/apache/impala/analysis/InsertStmt.java b/fe/src/main/java/org/apache/impala/analysis/InsertStmt.java
index c880697..21cc3d2 100644
--- a/fe/src/main/java/org/apache/impala/analysis/InsertStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/InsertStmt.java
@@ -360,7 +360,7 @@ public class InsertStmt extends StatementBase {
     }
 
     int numStaticPartitionExprs = 0;
-    if (partitionKeyValues_ != null) {
+    if (partitionKeyValues_ != null && !isIcebergTarget()) {
       for (PartitionKeyValue pkv: partitionKeyValues_) {
         Column column = table_.getColumn(pkv.getColName());
         if (column == null) {
@@ -498,13 +498,24 @@ public class InsertStmt extends StatementBase {
         throw new AnalysisException("PARTITION clause is not valid for INSERT into " +
             "HBase tables. '" + targetTableName_ + "' is an HBase table");
       } else {
-        if (table_ instanceof FeIcebergTable) {
-          throw new AnalysisException("PARTITION clause cannot be used for Iceberg " +
-              "tables.");
+        if (isIcebergTarget()) {
+          IcebergPartitionSpec partSpec =
+              ((FeIcebergTable)table_).getDefaultPartitionSpec();
+          if (partSpec == null || !partSpec.hasPartitionFields()) {
+            throw new AnalysisException("PARTITION clause is only valid for INSERT " +
+                "into partitioned table. '" + targetTableName_ + "' is not partitioned");
+          }
+          for (PartitionKeyValue pkv: partitionKeyValues_) {
+            if (pkv.isStatic()) {
+              throw new AnalysisException("Static partitioning is not supported for " +
+                  "Iceberg tables.");
+            }
+          }
+        } else {
+          // Unpartitioned table, but INSERT has PARTITION clause
+          throw new AnalysisException("PARTITION clause is only valid for INSERT into " +
+              "partitioned table. '" + targetTableName_ + "' is not partitioned");
         }
-        // Unpartitioned table, but INSERT has PARTITION clause
-        throw new AnalysisException("PARTITION clause is only valid for INSERT into " +
-            "partitioned table. '" + targetTableName_ + "' is not partitioned");
       }
     }
 
@@ -604,6 +615,10 @@ public class InsertStmt extends StatementBase {
     return true;
   }
 
+  private boolean isIcebergTarget() {
+    return table_ instanceof FeIcebergTable;
+  }
+
   /**
    * Checks that the column permutation + select list + static partition exprs + dynamic
    * partition exprs collectively cover exactly all required columns in the target table,
@@ -748,9 +763,8 @@ public class InsertStmt extends StatementBase {
     if (isKuduTable) {
       kuduPartitionColumnNames = getKuduPartitionColumnNames((FeKuduTable) table_);
     }
-    boolean isIcebergTable = table_ instanceof FeIcebergTable;
     IcebergPartitionSpec icebergPartSpec = null;
-    if (isIcebergTable) {
+    if (isIcebergTarget()) {
       icebergPartSpec = ((FeIcebergTable)table_).getDefaultPartitionSpec();
     }
 
@@ -799,7 +813,7 @@ public class InsertStmt extends StatementBase {
       }
     }
 
-    if (isIcebergTable) {
+    if (isIcebergTarget()) {
       // Add partition key expressions in the order of the Iceberg partition fields.
       addIcebergPartExprs(analyzer, widestTypeExprList, selectExprTargetColumns,
           selectListExprs, icebergPartSpec);
@@ -820,7 +834,7 @@ public class InsertStmt extends StatementBase {
       }
     }
 
-    if (isIcebergTable) {
+    if (isIcebergTarget()) {
       Preconditions.checkState(
           partitionKeyExprs_.size() == icebergPartSpec.getIcebergPartitionFieldsSize());
     }
diff --git a/fe/src/main/java/org/apache/impala/catalog/CtasTargetTable.java b/fe/src/main/java/org/apache/impala/catalog/CtasTargetTable.java
new file mode 100644
index 0000000..7682833
--- /dev/null
+++ b/fe/src/main/java/org/apache/impala/catalog/CtasTargetTable.java
@@ -0,0 +1,176 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.impala.catalog;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+import org.apache.hadoop.hive.common.ValidWriteIdList;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.impala.analysis.TableName;
+import org.apache.impala.thrift.TCatalogObjectType;
+import org.apache.impala.thrift.TTableDescriptor;
+import org.apache.impala.thrift.TTableStats;
+import org.apache.impala.util.AcidUtils;
+
+/**
+ * Helper class for creating CTAS target tables that can be used with Db and LocalDb
+ * as well.
+ */
+public abstract class CtasTargetTable implements FeTable {
+  protected final Table msTable_;
+  protected final FeDb db_;
+  protected final String name_;
+  protected final String owner_;
+
+  // colsByPos[i] refers to the ith column in the table. The first numClusteringCols are
+  // the clustering columns.
+  protected final List<Column> colsByPos_ = new ArrayList<>();
+
+  // map from lowercase column name to Column object.
+  protected final Map<String, Column> colsByName_ = new HashMap<>();
+
+  // Number of clustering columns.
+  protected int numClusteringCols_ = 0;
+
+  // Type of this table (array of struct) that mirrors the columns. Useful for analysis.
+  protected final ArrayType type_ = new ArrayType(new StructType());
+
+  public CtasTargetTable(org.apache.hadoop.hive.metastore.api.Table msTable, FeDb db,
+  String name, String owner) {
+    msTable_ = msTable;
+    db_ = db;
+    name_ = name;
+    owner_ = owner;
+  }
+
+  @Override
+  public boolean isLoaded() {
+    return false;
+  }
+
+  @Override
+  public Table getMetaStoreTable() {
+    return msTable_;
+  }
+
+  @Override
+  public String getStorageHandlerClassName() {
+    return null;
+  }
+
+  @Override
+  public TCatalogObjectType getCatalogObjectType() {
+    return TCatalogObjectType.TABLE;
+  }
+
+  @Override
+  public FeDb getDb() { return db_; }
+
+  @Override
+  public String getName() { return name_; }
+
+  @Override
+  public String getFullName() { return (db_ != null ? db_.getName() + "." : "") + name_; }
+
+  @Override
+  public TableName getTableName() {
+    return new TableName(db_ != null ? db_.getName() : null, name_);
+  }
+
+  @Override
+  public List<Column> getColumns() { return colsByPos_; }
+
+  @Override
+  public List<Column> getColumnsInHiveOrder() {
+    List<Column> columns = Lists.newArrayList(getNonClusteringColumns());
+    if (getMetaStoreTable() != null &&
+        AcidUtils.isFullAcidTable(getMetaStoreTable().getParameters())) {
+      // Remove synthetic "row__id" column.
+      Preconditions.checkState(columns.get(0).getName().equals("row__id"));
+      columns.remove(0);
+    }
+    columns.addAll(getClusteringColumns());
+    return Collections.unmodifiableList(columns);
+  }
+
+  @Override
+  public List<Column> getClusteringColumns() {
+    return Collections.unmodifiableList(colsByPos_.subList(0, numClusteringCols_));
+  }
+
+  @Override
+  public List<Column> getNonClusteringColumns() {
+    return Collections.unmodifiableList(colsByPos_.subList(numClusteringCols_,
+        colsByPos_.size()));
+  }
+
+  @Override
+  public List<String> getColumnNames() { return Column.toColumnNames(colsByPos_); }
+
+  @Override
+  public SqlConstraints getSqlConstraints() {
+    return null;
+  }
+
+  @Override
+  public int getNumClusteringCols() {
+    return numClusteringCols_;
+  }
+
+  @Override
+  public boolean isClusteringColumn(Column c) {
+      return c.getPosition() < numClusteringCols_;
+  }
+
+  @Override // FeTable
+  public Column getColumn(String name) { return colsByName_.get(name.toLowerCase()); }
+
+  @Override
+  public ArrayType getType() {
+    return type_;
+  }
+
+  @Override
+  public long getNumRows() { return 0; }
+
+  @Override
+  public TTableStats getTTableStats() { return null; }
+
+  @Override
+  public abstract TTableDescriptor toThriftDescriptor(int tableId,
+      Set<Long> referencedPartitions);
+
+  @Override
+  public long getWriteId() { return 0; }
+
+  @Override
+  public ValidWriteIdList getValidWriteIds() { return null; }
+
+  @Override
+  public String getOwnerUser() {
+    return owner_;
+  }
+}
diff --git a/fe/src/main/java/org/apache/impala/catalog/FeIcebergTable.java b/fe/src/main/java/org/apache/impala/catalog/FeIcebergTable.java
index 359d62b..8ad21f0 100644
--- a/fe/src/main/java/org/apache/impala/catalog/FeIcebergTable.java
+++ b/fe/src/main/java/org/apache/impala/catalog/FeIcebergTable.java
@@ -382,19 +382,24 @@ public interface FeIcebergTable extends FeFsTable {
         TableMetadata metadata) throws TableLoadingException {
       List<IcebergPartitionSpec> ret = new ArrayList<>();
       for (PartitionSpec spec : metadata.specs()) {
-        List<IcebergPartitionField> fields = new ArrayList<>();;
-        HashMap<String, Integer> transformParams =
-            IcebergUtil.getPartitionTransformParams(spec);
-        for (PartitionField field : spec.fields()) {
-          fields.add(new IcebergPartitionField(field.sourceId(), field.fieldId(),
-              spec.schema().findColumnName(field.sourceId()), field.name(),
-              IcebergUtil.getPartitionTransform(field, transformParams)));
-        }
-        ret.add(new IcebergPartitionSpec(spec.specId(), fields));
+        ret.add(convertPartitionSpec(spec));
       }
       return ret;
     }
 
+    public static IcebergPartitionSpec convertPartitionSpec(PartitionSpec spec)
+        throws TableLoadingException {
+      List<IcebergPartitionField> fields = new ArrayList<>();;
+      HashMap<String, Integer> transformParams =
+          IcebergUtil.getPartitionTransformParams(spec);
+      for (PartitionField field : spec.fields()) {
+        fields.add(new IcebergPartitionField(field.sourceId(), field.fieldId(),
+            spec.schema().findColumnName(field.sourceId()), field.name(),
+            IcebergUtil.getPartitionTransform(field, transformParams)));
+      }
+      return new IcebergPartitionSpec(spec.specId(), fields);
+    }
+
     public static IcebergPartitionSpec getDefaultPartitionSpec(
         FeIcebergTable feIcebergTable) {
       List<IcebergPartitionSpec> specs = feIcebergTable.getPartitionSpecs();
diff --git a/fe/src/main/java/org/apache/impala/catalog/HdfsTable.java b/fe/src/main/java/org/apache/impala/catalog/HdfsTable.java
index a647423..77eee52 100644
--- a/fe/src/main/java/org/apache/impala/catalog/HdfsTable.java
+++ b/fe/src/main/java/org/apache/impala/catalog/HdfsTable.java
@@ -2174,7 +2174,7 @@ public class HdfsTable extends Table implements FeFsTable {
    *  (e.g. number of blocks, files, etc) in order to compute an estimate of the metadata
    *  size of this table.
    */
-  protected THdfsTable getTHdfsTable(ThriftObjectType type, Set<Long> refPartitions) {
+  public THdfsTable getTHdfsTable(ThriftObjectType type, Set<Long> refPartitions) {
     if (type == ThriftObjectType.FULL) {
       // "full" implies all partitions should be included.
       Preconditions.checkArgument(refPartitions == null);
diff --git a/fe/src/main/java/org/apache/impala/catalog/iceberg/IcebergCtasTarget.java b/fe/src/main/java/org/apache/impala/catalog/iceberg/IcebergCtasTarget.java
new file mode 100644
index 0000000..cd9c8ec
--- /dev/null
+++ b/fe/src/main/java/org/apache/impala/catalog/iceberg/IcebergCtasTarget.java
@@ -0,0 +1,279 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.impala.catalog.iceberg;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.base.Preconditions;
+
+import org.apache.hadoop.hive.metastore.IMetaStoreClient;
+import org.apache.iceberg.PartitionSpec;
+import org.apache.iceberg.Schema;
+import org.apache.iceberg.catalog.Namespace;
+import org.apache.iceberg.catalog.TableIdentifier;
+import org.apache.iceberg.types.TypeUtil;
+import org.apache.impala.analysis.ColumnDef;
+import org.apache.impala.analysis.IcebergPartitionSpec;
+import org.apache.impala.catalog.CatalogException;
+import org.apache.impala.catalog.CatalogObject;
+import org.apache.impala.catalog.Column;
+import org.apache.impala.catalog.CtasTargetTable;
+import org.apache.impala.catalog.Db;
+import org.apache.impala.catalog.FeCatalogUtils;
+import org.apache.impala.catalog.FeDb;
+import org.apache.impala.catalog.FeFsPartition;
+import org.apache.impala.catalog.FeFsTable;
+import org.apache.impala.catalog.FeIcebergTable;
+import org.apache.impala.catalog.HdfsStorageDescriptor;
+import org.apache.impala.catalog.HdfsTable;
+import org.apache.impala.catalog.IcebergColumn;
+import org.apache.impala.catalog.IcebergStructField;
+import org.apache.impala.catalog.HdfsPartition.FileDescriptor;
+import org.apache.impala.catalog.local.LocalDb;
+import org.apache.impala.catalog.local.LocalFsTable;
+import org.apache.impala.common.ImpalaRuntimeException;
+import org.apache.impala.catalog.StructType;
+import org.apache.impala.catalog.Table;
+import org.apache.impala.catalog.TableLoadingException;
+import org.apache.impala.thrift.CatalogObjectsConstants;
+import org.apache.impala.thrift.TCatalogObjectType;
+import org.apache.impala.thrift.TColumn;
+import org.apache.impala.thrift.THdfsPartition;
+import org.apache.impala.thrift.THdfsTable;
+import org.apache.impala.thrift.TIcebergCatalog;
+import org.apache.impala.thrift.TIcebergFileFormat;
+import org.apache.impala.thrift.TTableDescriptor;
+import org.apache.impala.thrift.TTableType;
+import org.apache.impala.util.IcebergSchemaConverter;
+import org.apache.impala.util.IcebergUtil;
+
+/**
+ * Utility class that can be used as a temporary target table for CTAS statements.
+ * It mimics an FeIcebergTable without actually creating it via Iceberg.
+ */
+public class IcebergCtasTarget extends CtasTargetTable implements FeIcebergTable {
+  private FeFsTable fsTable_;
+  private Schema iceSchema_;
+  private List<IcebergPartitionSpec> partitionSpecs_ = new ArrayList<>();
+  private TIcebergFileFormat icebergFileFormat_;
+  private TIcebergCatalog icebergCatalog_;
+  private String icebergTableLocation_;
+  private String icebergCatalogLocation_;
+  private HdfsStorageDescriptor hdfsSd_;
+
+  public IcebergCtasTarget(FeDb db, org.apache.hadoop.hive.metastore.api.Table msTbl,
+      List<ColumnDef> columnDefs, IcebergPartitionSpec partSpec)
+      throws CatalogException {
+    super(msTbl, db, msTbl.getTableName(), msTbl.getOwner());
+    createFsTable(db, msTbl);
+    createIcebergSchema(columnDefs);
+    createPartitionSpec(partSpec);
+    icebergCatalog_ = IcebergUtil.getTIcebergCatalog(msTbl);
+    setLocations();
+    icebergFileFormat_ = Utils.getIcebergFileFormat(msTbl);
+    hdfsSd_ = HdfsStorageDescriptor.fromStorageDescriptor(name_, msTable_.getSd());
+  }
+
+  private void createIcebergSchema(List<ColumnDef> columnDefs) throws CatalogException {
+    List<TColumn> tcols = new ArrayList<>();
+    for (ColumnDef col : columnDefs) {
+      tcols.add(col.toThrift());
+    }
+    try {
+      iceSchema_ = IcebergSchemaConverter.genIcebergSchema(tcols);
+      // In genIcebergSchema() we did our best to assign correct field ids to columns,
+      // but to be sure, let's use Iceberg's API function to assign field ids.
+      iceSchema_ = TypeUtil.assignIncreasingFreshIds(iceSchema_);
+    } catch (ImpalaRuntimeException ex) {
+      throw new CatalogException(
+        "Exception caught during generating Iceberg schema:", ex);
+    }
+    for (Column col : IcebergSchemaConverter.convertToImpalaSchema(iceSchema_)) {
+      addColumn((IcebergColumn)col);
+    }
+  }
+
+  private void createPartitionSpec(IcebergPartitionSpec partSpec)
+      throws CatalogException {
+    Preconditions.checkState(iceSchema_ != null);
+    PartitionSpec iceSpec = null;
+    try {
+      // Let's create an Iceberg PartitionSpec with the help of Icebeg from 'partSpec',
+      // then convert it back to an IcebergPartitionSpec.
+      if (partSpec == null) {
+        iceSpec = PartitionSpec.unpartitioned();
+      } else {
+        iceSpec = IcebergUtil.createIcebergPartition(iceSchema_, partSpec.toThrift());
+      }
+    } catch (ImpalaRuntimeException ex) {
+      throw new CatalogException(
+        "Exception caught during generating Iceberg schema:", ex);
+    }
+    IcebergPartitionSpec resolvedIcebergSpec =
+        FeIcebergTable.Utils.convertPartitionSpec(iceSpec);
+    partitionSpecs_.add(resolvedIcebergSpec);
+  }
+
+  private void setLocations() {
+    Preconditions.checkState(msTable_ != null);
+    Preconditions.checkState(icebergCatalog_ != null);
+    if (icebergCatalog_ == TIcebergCatalog.HADOOP_CATALOG) {
+      icebergCatalogLocation_ = IcebergUtil.getIcebergCatalogLocation(msTable_);
+      TableIdentifier tId = IcebergUtil.getIcebergTableIdentifier(msTable_);
+      Namespace ns = tId.namespace();
+      List<String> components = new ArrayList<>();
+      Collections.addAll(components, ns.levels());
+      components.add(tId.name());
+      icebergTableLocation_ =
+          icebergCatalogLocation_ + "/" + String.join("/", components);
+      return;
+    }
+    Preconditions.checkState(icebergCatalog_ == TIcebergCatalog.HADOOP_TABLES ||
+                             icebergCatalog_ == TIcebergCatalog.HIVE_CATALOG);
+    icebergTableLocation_ = msTable_.getSd().getLocation();
+    icebergCatalogLocation_ = icebergTableLocation_;
+  }
+
+  private void createFsTable(FeDb db, org.apache.hadoop.hive.metastore.api.Table msTbl)
+      throws CatalogException {
+    if (db instanceof Db) {
+      fsTable_ = HdfsTable.createCtasTarget((Db)db, msTbl);
+    } else {
+      fsTable_ = LocalFsTable.createCtasTarget((LocalDb)db, msTbl);
+    }
+  }
+
+  @Override
+  public Map<String, FileDescriptor> getPathHashToFileDescMap() {
+    return Collections.<String, FileDescriptor>emptyMap();
+  }
+
+  @Override
+  public FeFsTable getFeFsTable() {
+    return fsTable_;
+  }
+
+  @Override
+  public TIcebergCatalog getIcebergCatalog() {
+    return icebergCatalog_;
+  }
+
+  @Override
+  public String getIcebergCatalogLocation() {
+    return icebergCatalogLocation_;
+  }
+
+  @Override
+  public TIcebergFileFormat getIcebergFileFormat() {
+    return icebergFileFormat_;
+  }
+
+  @Override
+  public String getIcebergTableLocation() {
+    return icebergTableLocation_;
+  }
+
+  @Override
+  public List<IcebergPartitionSpec> getPartitionSpecs() {
+    return partitionSpecs_;
+  }
+
+  @Override
+  public IcebergPartitionSpec getDefaultPartitionSpec() {
+    return partitionSpecs_.get(0);
+  }
+
+  @Override
+  public int getDefaultPartitionSpecId() {
+    return 0;
+  }
+
+  @Override
+  public Schema getIcebergSchema() {
+    return iceSchema_;
+  }
+
+  @Override
+  public long snapshotId() {
+    return -1;
+  }
+
+  public void addColumn(IcebergColumn col) {
+    colsByPos_.add(col);
+    colsByName_.put(col.getName().toLowerCase(), col);
+    ((StructType) type_.getItemType()).addField(
+        new IcebergStructField(col.getName(), col.getType(), col.getComment(),
+            col.getFieldId()));
+  }
+
+  @Override
+  public TTableDescriptor toThriftDescriptor(int tableId,
+      Set<Long> referencedPartitions) {
+    TTableDescriptor desc = new TTableDescriptor(tableId, TTableType.ICEBERG_TABLE,
+        FeCatalogUtils.getTColumnDescriptors(this),
+        getNumClusteringCols(),
+        getName(), db_.getName());
+
+    desc.setIcebergTable(Utils.getTIcebergTable(this));
+    desc.setHdfsTable(transformToTHdfsTable());
+    return desc;
+  }
+
+  private THdfsTable transformToTHdfsTable() {
+    if (fsTable_ instanceof HdfsTable) {
+      return transformOldToTHdfsTable();
+    } else {
+      return transformLocalToTHdfsTable();
+    }
+  }
+
+  private THdfsTable transformOldToTHdfsTable() {
+    THdfsTable hdfsTable = ((HdfsTable)fsTable_).getTHdfsTable(
+        CatalogObject.ThriftObjectType.FULL, null);
+    hdfsTable.setPrototype_partition(createPrototypePartition());
+    return hdfsTable;
+  }
+
+  private THdfsTable transformLocalToTHdfsTable() {
+    LocalFsTable localFsTable = (LocalFsTable)fsTable_;
+    Map<Long, THdfsPartition> idToPartition = new HashMap<>();
+    THdfsPartition tPrototypePartition = createPrototypePartition();
+    return new THdfsTable(localFsTable.getHdfsBaseDir(),
+        getColumnNames(), localFsTable.getNullPartitionKeyValue(),
+        FeFsTable.DEFAULT_NULL_COLUMN_VALUE, idToPartition, tPrototypePartition);
+  }
+
+  private THdfsPartition createPrototypePartition() {
+    THdfsPartition prototypePart = new THdfsPartition();
+    prototypePart.setFileFormat(IcebergUtil.toTHdfsFileFormat(icebergFileFormat_));
+    prototypePart.setBlockSize(hdfsSd_.getBlockSize());
+    prototypePart.setId(CatalogObjectsConstants.PROTOTYPE_PARTITION_ID);
+    return prototypePart;
+  }
+
+  @Override
+  public TCatalogObjectType getCatalogObjectType() {
+    return TCatalogObjectType.TABLE;
+  }
+}
diff --git a/fe/src/main/java/org/apache/impala/catalog/local/LocalDb.java b/fe/src/main/java/org/apache/impala/catalog/local/LocalDb.java
index b972ca8..39b513e 100644
--- a/fe/src/main/java/org/apache/impala/catalog/local/LocalDb.java
+++ b/fe/src/main/java/org/apache/impala/catalog/local/LocalDb.java
@@ -54,7 +54,7 @@ import com.google.common.collect.Maps;
  * This class is not thread-safe. A new instance is created for
  * each catalog instance.
  */
-class LocalDb implements FeDb {
+public class LocalDb implements FeDb {
   private final LocalCatalog catalog_;
   /** The lower-case name of the database. */
   private final String name_;
diff --git a/fe/src/main/java/org/apache/impala/catalog/local/LocalFsTable.java b/fe/src/main/java/org/apache/impala/catalog/local/LocalFsTable.java
index 12da212..956b964 100644
--- a/fe/src/main/java/org/apache/impala/catalog/local/LocalFsTable.java
+++ b/fe/src/main/java/org/apache/impala/catalog/local/LocalFsTable.java
@@ -369,7 +369,7 @@ public class LocalFsTable extends LocalTable implements FeFsTable {
     return false;
   }
 
-  protected LocalFsPartition createPrototypePartition() {
+  public LocalFsPartition createPrototypePartition() {
     Partition protoMsPartition = new Partition();
 
     // The prototype partition should not have a location set in its storage
diff --git a/fe/src/main/java/org/apache/impala/service/IcebergCatalogOpExecutor.java b/fe/src/main/java/org/apache/impala/service/IcebergCatalogOpExecutor.java
index c4d0259..370f84e 100644
--- a/fe/src/main/java/org/apache/impala/service/IcebergCatalogOpExecutor.java
+++ b/fe/src/main/java/org/apache/impala/service/IcebergCatalogOpExecutor.java
@@ -69,7 +69,8 @@ public class IcebergCatalogOpExecutor {
       String location, TCreateTableParams params) throws ImpalaRuntimeException {
     // Each table id increase from zero
     Schema schema = createIcebergSchema(params);
-    PartitionSpec spec = IcebergUtil.createIcebergPartition(schema, params);
+    PartitionSpec spec = IcebergUtil.createIcebergPartition(schema,
+        params.getPartition_spec());
     IcebergCatalog icebergCatalog = IcebergUtil.getIcebergCatalog(catalog, location);
     Table iceTable = icebergCatalog.createTable(identifier, schema, spec, location,
         params.getTable_properties());
diff --git a/fe/src/main/java/org/apache/impala/util/IcebergSchemaConverter.java b/fe/src/main/java/org/apache/impala/util/IcebergSchemaConverter.java
index 3fdfd2e..131a7f0 100644
--- a/fe/src/main/java/org/apache/impala/util/IcebergSchemaConverter.java
+++ b/fe/src/main/java/org/apache/impala/util/IcebergSchemaConverter.java
@@ -149,7 +149,7 @@ public class IcebergSchemaConverter {
    */
   public static Schema genIcebergSchema(List<TColumn> columns)
       throws ImpalaRuntimeException {
-    iThreadLocal.set(0);
+    iThreadLocal.set(1);
     List<Types.NestedField> fields = new ArrayList<Types.NestedField>();
     for (TColumn column : columns) {
       fields.add(createIcebergField(column));
diff --git a/fe/src/main/java/org/apache/impala/util/IcebergUtil.java b/fe/src/main/java/org/apache/impala/util/IcebergUtil.java
index f1fdb87..5be0a9f 100644
--- a/fe/src/main/java/org/apache/impala/util/IcebergUtil.java
+++ b/fe/src/main/java/org/apache/impala/util/IcebergUtil.java
@@ -72,6 +72,7 @@ import org.apache.impala.thrift.THdfsFileFormat;
 import org.apache.impala.thrift.TIcebergCatalog;
 import org.apache.impala.thrift.TIcebergFileFormat;
 import org.apache.impala.thrift.TIcebergPartitionField;
+import org.apache.impala.thrift.TIcebergPartitionSpec;
 import org.apache.impala.thrift.TIcebergPartitionTransform;
 import org.apache.impala.thrift.TIcebergPartitionTransformType;
 
@@ -178,17 +179,15 @@ public class IcebergUtil {
   }
 
   /**
-   * Build iceberg PartitionSpec by parameters.
+   * Build iceberg PartitionSpec from TIcebergPartitionSpec.
    * partition columns are all from source columns, this is different from hdfs table.
    */
   public static PartitionSpec createIcebergPartition(Schema schema,
-      TCreateTableParams params) throws ImpalaRuntimeException {
-    if (params.getPartition_spec() == null) {
-      return PartitionSpec.unpartitioned();
-    }
+      TIcebergPartitionSpec partSpec) throws ImpalaRuntimeException {
+    if (partSpec == null) return PartitionSpec.unpartitioned();
+
+    List<TIcebergPartitionField> partitionFields = partSpec.getPartition_fields();
     PartitionSpec.Builder builder = PartitionSpec.builderFor(schema);
-    List<TIcebergPartitionField> partitionFields =
-        params.getPartition_spec().getPartition_fields();
     for (TIcebergPartitionField partitionField : partitionFields) {
       TIcebergPartitionTransformType transformType =
           partitionField.getTransform().getTransform_type();
diff --git a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
index 1bb2fc8..fd6570d 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
@@ -2119,10 +2119,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     // Unsupported file formats
     AnalysisError("create table foo stored as sequencefile as select 1",
         "CREATE TABLE AS SELECT does not support the (SEQUENCEFILE) file format. " +
-         "Supported formats are: (PARQUET, TEXTFILE, KUDU)");
+         "Supported formats are: (PARQUET, TEXTFILE, KUDU, ICEBERG)");
     AnalysisError("create table foo stored as RCFILE as select 1",
         "CREATE TABLE AS SELECT does not support the (RCFILE) file format. " +
-         "Supported formats are: (PARQUET, TEXTFILE, KUDU)");
+         "Supported formats are: (PARQUET, TEXTFILE, KUDU, ICEBERG)");
 
     // CTAS with a WITH clause and inline view (IMPALA-1100)
     AnalyzesOk("create table test_with as with with_1 as (select 1 as int_col from " +
diff --git a/testdata/workloads/functional-query/queries/QueryTest/iceberg-ctas.test b/testdata/workloads/functional-query/queries/QueryTest/iceberg-ctas.test
new file mode 100644
index 0000000..eddac95
--- /dev/null
+++ b/testdata/workloads/functional-query/queries/QueryTest/iceberg-ctas.test
@@ -0,0 +1,105 @@
+====
+---- QUERY
+CREATE TABLE value_tbl (t TINYINT, i INT, b BIGINT, s STRING, ts TIMESTAMP, d date);
+insert into value_tbl values (0, 1, 2, 'impala', '2021-02-26 16:16:59', '2021-02-26');
+====
+---- QUERY
+# Test non-partitioned table in Iceberg HiveCatalog.
+CREATE TABLE ice_ctas STORED AS ICEBERG AS SELECT i, b FROM value_tbl;
+SELECT * FROM ice_ctas;
+---- RESULTS
+1,2
+---- TYPES
+INT,BIGINT
+====
+---- QUERY
+show files in ice_ctas;
+---- RESULTS: VERIFY_IS_SUBSET
+row_regex:'$NAMENODE/test-warehouse/$DATABASE.db/ice_ctas/data/.*.0.parq','.*',''
+---- TYPES
+STRING, STRING, STRING
+====
+---- QUERY
+# Test partitioned table in Iceberg HiveCatalog.
+# Use old PARTITIONED BY syntax.
+CREATE TABLE ice_ctas_part PARTITIONED BY(d) STORED AS ICEBERG AS SELECT s, ts, d FROM value_tbl;
+SELECT * FROM ice_ctas_part where d='2021-02-26';
+---- RESULTS
+'impala',2021-02-26 16:16:59,2021-02-26
+---- TYPES
+STRING,TIMESTAMP,DATE
+====
+---- QUERY
+show files in ice_ctas_part;
+---- RESULTS: VERIFY_IS_SUBSET
+row_regex:'$NAMENODE/test-warehouse/$DATABASE.db/ice_ctas_part/data/d=2021-02-26/.*.0.parq','.*',''
+---- TYPES
+STRING, STRING, STRING
+====
+---- QUERY
+# INSERT an additional row to a different partition.
+INSERT INTO ice_ctas_part VALUES ('fox','2021-02-27 16:16:59','2021-02-27');
+SELECT * FROM ice_ctas_part;
+---- RESULTS
+'impala',2021-02-26 16:16:59,2021-02-26
+'fox',2021-02-27 16:16:59,2021-02-27
+---- TYPES
+STRING,TIMESTAMP,DATE
+====
+---- QUERY
+show files in ice_ctas_part;
+---- RESULTS: VERIFY_IS_SUBSET
+row_regex:'$NAMENODE/test-warehouse/$DATABASE.db/ice_ctas_part/data/d=2021-02-26/.*.0.parq','.*',''
+row_regex:'$NAMENODE/test-warehouse/$DATABASE.db/ice_ctas_part/data/d=2021-02-27/.*.0.parq','.*',''
+---- TYPES
+STRING, STRING, STRING
+====
+---- QUERY
+# Test CTAS in Iceberg HadoopTables catalog.
+# Set table location to custom location.
+# Use PARTITION BY SPEC
+CREATE TABLE ice_ctas_hadoop_tables_part PARTITION BY SPEC (d month)
+STORED AS ICEBERG
+LOCATION '/test-warehouse/$DATABASE.db/loc_test'
+TBLPROPERTIES ('iceberg.catalog'='hadoop.tables') AS SELECT s, ts, d FROM value_tbl;
+SELECT * FROM ice_ctas_hadoop_tables_part where d='2021-02-26';
+---- RESULTS
+'impala',2021-02-26 16:16:59,2021-02-26
+---- TYPES
+STRING,TIMESTAMP,DATE
+====
+---- QUERY
+show files in ice_ctas_hadoop_tables_part;
+---- RESULTS: VERIFY_IS_SUBSET
+row_regex:'$NAMENODE/test-warehouse/$DATABASE.db/loc_test/data/d_month=2021-02/.*.0.parq','.*',''
+---- TYPES
+STRING, STRING, STRING
+====
+---- QUERY
+# Test CTAS in Iceberg HadoopCatalog catalog.
+# Set 'iceberg.catalog_location' and 'iceberg.table_identifier'
+# Partition by TRUNCATE
+# Cast TINYINT to INT.
+# INSERT additional row.
+CREATE TABLE ice_ctas_hadoop_catalog_part PARTITION BY SPEC (s truncate 3)
+STORED AS ICEBERG
+TBLPROPERTIES ('iceberg.catalog'='hadoop.catalog',
+               'iceberg.catalog_location'='/test-warehouse/$DATABASE.db/cat_loc',
+               'iceberg.table_identifier'='ns1.ns2.ctas')
+AS SELECT cast(t as INT), s, d FROM value_tbl;
+INSERT INTO ice_ctas_hadoop_catalog_part VALUES (1, 'lion', '2021-02-27');
+SELECT * FROM ice_ctas_hadoop_catalog_part;
+---- RESULTS
+0,'impala',2021-02-26
+1,'lion',2021-02-27
+---- TYPES
+INT,STRING,DATE
+====
+---- QUERY
+show files in ice_ctas_hadoop_catalog_part;
+---- RESULTS: VERIFY_IS_SUBSET
+row_regex:'$NAMENODE/test-warehouse/$DATABASE.db/cat_loc/ns1/ns2/ctas/data/s_trunc=imp/.*.0.parq','.*',''
+row_regex:'$NAMENODE/test-warehouse/$DATABASE.db/cat_loc/ns1/ns2/ctas/data/s_trunc=lio/.*.0.parq','.*',''
+---- TYPES
+STRING, STRING, STRING
+====
diff --git a/testdata/workloads/functional-query/queries/QueryTest/iceberg-negative.test b/testdata/workloads/functional-query/queries/QueryTest/iceberg-negative.test
index bd9d033..38a61a6 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/iceberg-negative.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/iceberg-negative.test
@@ -93,14 +93,6 @@ SHOW CREATE TABLE fake_iceberg_table_hadoop_catalog;
 row_regex:.*CAUSED BY: TableLoadingException: Table does not exist: fake_db.fake_table*
 ====
 ---- QUERY
-CREATE TABLE iceberg_ctas
-STORED AS ICEBERG
-TBLPROPERTIES('iceberg.catalog'='hadoop.tables')
-AS SELECT id FROM functional.alltypes;
----- CATCH
-AnalysisException: CREATE TABLE AS SELECT does not support the (ICEBERG) file format.
-====
----- QUERY
 CREATE TABLE iceberg_overwrite_bucket (i int)
 PARTITION BY SPEC (i bucket 3)
 STORED AS ICEBERG
@@ -159,7 +151,7 @@ TBLPROPERTIES('iceberg.catalog'='hadoop.tables');
 ---- QUERY
 INSERT INTO iceberg_partitioned_insert PARTITION(level='level') VALUES(now());
 ---- CATCH
-AnalysisException: PARTITION clause cannot be used for Iceberg tables.
+Static partitioning is not supported for Iceberg tables.
 ====
 ---- QUERY
 CREATE TABLE all_colss_needed_for_insert (i int, j int, k int)
diff --git a/testdata/workloads/functional-query/queries/QueryTest/show-create-table.test b/testdata/workloads/functional-query/queries/QueryTest/show-create-table.test
index 710ebb3..6b2591a 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/show-create-table.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/show-create-table.test
@@ -808,3 +808,42 @@ LOCATION '$$location_uri$$'
 TBLPROPERTIES ('external.table.purge'='TRUE', 'iceberg.file_format'='parquet',
 'iceberg.catalog'='hive.catalog', 'table_type'='ICEBERG')
 ====
+---- CREATE_TABLE
+CREATE TABLE iceberg_ctas
+PARTITION BY SPEC(id bucket 5)
+STORED AS ICEBERG
+AS SELECT id, bool_col, bigint_col FROM functional.alltypes;
+---- RESULTS-HIVE-3
+CREATE EXTERNAL TABLE show_create_table_test_db.iceberg_ctas (
+  id INT NULL,
+  bool_col BOOLEAN NULL,
+  bigint_col BIGINT NULL
+)
+PARTITION BY SPEC (
+  id BUCKET 5
+)
+STORED AS ICEBERG
+LOCATION '$$location_uri$$'
+TBLPROPERTIES ('external.table.purge'='TRUE', 'iceberg.file_format'='parquet',
+'iceberg.catalog'='hive.catalog', 'table_type'='ICEBERG')
+====
+---- CREATE_TABLE
+CREATE TABLE iceberg_ctas_ht
+PARTITION BY SPEC(id bucket 5)
+STORED AS ICEBERG
+TBLPROPERTIES ('iceberg.catalog'='hadoop.tables')
+AS SELECT id, bool_col, bigint_col FROM functional.alltypes;
+---- RESULTS-HIVE-3
+CREATE EXTERNAL TABLE show_create_table_test_db.iceberg_ctas_ht (
+  id INT NULL,
+  bool_col BOOLEAN NULL,
+  bigint_col BIGINT NULL
+)
+PARTITION BY SPEC (
+  id BUCKET 5
+)
+STORED AS ICEBERG
+LOCATION '$$location_uri$$'
+TBLPROPERTIES ('external.table.purge'='TRUE', 'iceberg.file_format'='parquet',
+'iceberg.catalog'='hadoop.tables')
+====
diff --git a/tests/metadata/test_show_create_table.py b/tests/metadata/test_show_create_table.py
index 44f7fbf..8e82974 100644
--- a/tests/metadata/test_show_create_table.py
+++ b/tests/metadata/test_show_create_table.py
@@ -39,7 +39,7 @@ class TestShowCreateTable(ImpalaTestSuite):
                            "STATS_GENERATED_VIA_STATS_TASK", "last_modified_by",
                            "last_modified_time", "numFilesErasureCoded",
                            "bucketing_version", "OBJCAPABILITIES",
-                           "TRANSLATED_TO_EXTERNAL"]
+                           "TRANSLATED_TO_EXTERNAL", "previous_metadata_location"]
 
   @classmethod
   def get_workload(self):
@@ -169,6 +169,9 @@ class TestShowCreateTable(ImpalaTestSuite):
     # is not valid
     s = re.sub("TBLPROPERTIES\s*\(\s*\)", "", s)
     s = re.sub("SERDEPROPERTIES\s*\(\s*\)", "", s)
+    # By removing properties in the middle we might ended up having extra whitespaces,
+    # let's remove them.
+    s = ' '.join(s.split())
     return s
 
   def __properties_map_regex(self, name):
diff --git a/tests/query_test/test_iceberg.py b/tests/query_test/test_iceberg.py
index 19177af..20c62c8 100644
--- a/tests/query_test/test_iceberg.py
+++ b/tests/query_test/test_iceberg.py
@@ -76,6 +76,9 @@ class TestIcebergTable(ImpalaTestSuite):
   def test_insert_overwrite(self, vector, unique_database):
     self.run_test_case('QueryTest/iceberg-overwrite', vector, use_db=unique_database)
 
+  def test_ctas(self, vector, unique_database):
+    self.run_test_case('QueryTest/iceberg-ctas', vector, use_db=unique_database)
+
   def test_partition_transform_insert(self, vector, unique_database):
     self.run_test_case('QueryTest/iceberg-partition-transform-insert', vector,
         use_db=unique_database)


[impala] 07/08: IMPALA-10523: Fix impala-shell crash in printing error messages that contain UTF-8 characters

Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit d5f67fce41a919b9904c70e53740d8bfd5831e71
Author: stiga-huang <hu...@gmail.com>
AuthorDate: Sun Feb 21 16:40:31 2021 +0800

    IMPALA-10523: Fix impala-shell crash in printing error messages that contain UTF-8 characters
    
    In Python2, print() converts all non-keyword arguments to strings like
    str() does and writes them to the stream. str() on QueryStateException
    returns its value(i.e. error message) which could be in unicode type.
    Python2 will implicitly encode it to str type using the default
    encoding, 'ascii'. This could result in UnicodeEncodeError when there
    are non-ascii characters in the error message.
    
    This patch explicitly encodes the error message using 'utf-8' encoding
    if it's in unicode type and the shell is run in Python2.
    
    Tests:
     - Add test in test_shell_interactive.py
    
    Change-Id: Ie10f5b03ecc5877053c2fbada1afaf256b423a71
    Reviewed-on: http://gerrit.cloudera.org:8080/17099
    Reviewed-by: Tamas Mate <tm...@cloudera.com>
    Reviewed-by: Laszlo Gaal <la...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 shell/impala_shell.py                 | 8 +++++++-
 tests/shell/test_shell_interactive.py | 9 +++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/shell/impala_shell.py b/shell/impala_shell.py
index 17edc2f..3c99e77 100755
--- a/shell/impala_shell.py
+++ b/shell/impala_shell.py
@@ -1317,7 +1317,13 @@ class ImpalaShell(cmd.Cmd, object):
       # an exception occurred while executing the query
       if self.last_query_handle is not None:
         self.imp_client.close_query(self.last_query_handle)
-      print(e, file=sys.stderr)
+      msg = e.value
+      # Python2 will implicitly convert unicode to str when printing to stderr. It's done
+      # using the default 'ascii' encoding, which will fail for UTF-8 error messages.
+      # Here we use 'utf-8' to explicitly convert 'msg' to str if it's in unicode type.
+      if sys.version_info.major == 2 and isinstance(msg, unicode):
+        msg = msg.encode('utf-8')
+      print(msg, file=sys.stderr)
     except DisconnectedException as e:
       # the client has lost the connection
       print(e, file=sys.stderr)
diff --git a/tests/shell/test_shell_interactive.py b/tests/shell/test_shell_interactive.py
index 06259da..49288e1 100755
--- a/tests/shell/test_shell_interactive.py
+++ b/tests/shell/test_shell_interactive.py
@@ -1041,6 +1041,15 @@ class TestImpalaShellInteractive(ImpalaTestSuite):
     assert "ERROR: ParseException: Unmatched string literal" in result.stderr,\
            result.stderr
 
+  def test_utf8_error_message(self, vector):
+    """Test UTF-8 error messages are shown correctly"""
+    shell = ImpalaShell(vector)
+    query = "select cast(now() as string format 'yyyy年MM月dd日')"
+    shell.send_cmd(query)
+    result = shell.get_result()
+    assert "ERROR: Bad date/time conversion format: yyyy年MM月dd日" in result.stderr,\
+           result.stderr
+
   def test_timezone_validation(self, vector):
     """Test that query option TIMEZONE is validated when executing a query.
 


[impala] 06/08: IMPALA-10546: Add ImpalaServer interface to retrieve BackendConfig from impalad

Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit 2e53c11484dd1f9044020b0035d9eab96d496a9c
Author: Kurt Deschler <kd...@cloudera.com>
AuthorDate: Mon Feb 24 23:46:34 2020 -0500

    IMPALA-10546: Add ImpalaServer interface to retrieve BackendConfig from impalad
    
    This patch add a new interface ImpalaServer::GetBackendConfig() that
    returns the current TBackendGflags from impalad.
    
    Testing:
    Called new interface from external frontend. Verified that
    TBackendGflags were populated correctly.
    
    Reviewed-by: John Sherman <jf...@cloudera.com>
    Change-Id: I14a3cee29f1fc91f4431b7ea89053bb3fbfa5e69
    Reviewed-on: http://gerrit.cloudera.org:8080/17116
    Reviewed-by: Thomas Tauber-Marshall <tm...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 be/src/catalog/catalog.cc           |  2 +-
 be/src/rpc/hs2-http-test.cc         |  2 ++
 be/src/service/frontend.cc          |  2 +-
 be/src/service/impala-hs2-server.cc | 22 ++++++++++++++++++++++
 be/src/service/impala-server.h      |  5 +++++
 be/src/util/backend-gflag-util.cc   |  9 +++++++--
 be/src/util/backend-gflag-util.h    |  5 ++++-
 be/src/util/logging-support.cc      |  2 +-
 common/thrift/ImpalaService.thrift  | 13 +++++++++++++
 tests/hs2/test_hs2.py               |  8 ++++++++
 10 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/be/src/catalog/catalog.cc b/be/src/catalog/catalog.cc
index d75484f..e918d4e 100644
--- a/be/src/catalog/catalog.cc
+++ b/be/src/catalog/catalog.cc
@@ -81,7 +81,7 @@ Catalog::Catalog() {
   }
 
   jbyteArray cfg_bytes;
-  ABORT_IF_ERROR(GetThriftBackendGflags(jni_env, &cfg_bytes));
+  ABORT_IF_ERROR(GetThriftBackendGFlagsForJNI(jni_env, &cfg_bytes));
 
   jobject catalog = jni_env->NewObject(catalog_class_, catalog_ctor_, cfg_bytes);
   CLEAN_EXIT_IF_EXC(jni_env);
diff --git a/be/src/rpc/hs2-http-test.cc b/be/src/rpc/hs2-http-test.cc
index 2c95550..0c61df9 100644
--- a/be/src/rpc/hs2-http-test.cc
+++ b/be/src/rpc/hs2-http-test.cc
@@ -50,6 +50,8 @@ class TestHS2Service : public ImpalaHiveServer2ServiceIf {
       TExecuteStatementResp& _return, const TExecuteStatementReq& req) {}
   virtual void ExecutePlannedStatement(
       TExecuteStatementResp& _return, const TExecutePlannedStatementReq& req) {}
+  virtual void GetBackendConfig(TGetBackendConfigResp& _return,
+      const TGetBackendConfigReq& req) {}
   virtual void GetTypeInfo(TGetTypeInfoResp& _return, const TGetTypeInfoReq& req) {}
   virtual void GetCatalogs(TGetCatalogsResp& _return, const TGetCatalogsReq& req) {}
   virtual void GetSchemas(TGetSchemasResp& _return, const TGetSchemasReq& req) {}
diff --git a/be/src/service/frontend.cc b/be/src/service/frontend.cc
index af1339c..b5a3d1a 100644
--- a/be/src/service/frontend.cc
+++ b/be/src/service/frontend.cc
@@ -131,7 +131,7 @@ Frontend::Frontend() {
   };
 
   jbyteArray cfg_bytes;
-  ABORT_IF_ERROR(GetThriftBackendGflags(jni_env, &cfg_bytes));
+  ABORT_IF_ERROR(GetThriftBackendGFlagsForJNI(jni_env, &cfg_bytes));
 
   // Pass in whether this is a backend test, so that the Frontend can avoid certain
   // unnecessary initialization that introduces dependencies on a running minicluster.
diff --git a/be/src/service/impala-hs2-server.cc b/be/src/service/impala-hs2-server.cc
index debd755..76a1c35 100644
--- a/be/src/service/impala-hs2-server.cc
+++ b/be/src/service/impala-hs2-server.cc
@@ -47,6 +47,7 @@
 #include "service/query-options.h"
 #include "service/query-result-set.h"
 #include "util/auth-util.h"
+#include "util/backend-gflag-util.h"
 #include "util/debug-util.h"
 #include "util/impalad-metrics.h"
 #include "util/metrics.h"
@@ -1175,6 +1176,27 @@ void ImpalaServer::GetDelegationToken(TGetDelegationTokenResp& return_val,
   return_val.status.__set_errorMessage("Not implemented");
 }
 
+void ImpalaServer::GetBackendConfig(TGetBackendConfigResp& return_val,
+    const TGetBackendConfigReq& req) {
+  VLOG_QUERY << "GetBackendConfig(): req=" << ThriftDebugString(req);
+  const ThriftServer::ConnectionContext* connection_context =
+      ThriftServer::GetThreadConnectionContext();
+  if (connection_context->server_name != EXTERNAL_FRONTEND_SERVER_NAME) {
+    HS2_RETURN_ERROR(return_val, "Unsupported operation",
+        SQLSTATE_OPTIONAL_FEATURE_NOT_IMPLEMENTED);
+  }
+  TUniqueId session_id;
+  TUniqueId secret;
+  HS2_RETURN_IF_ERROR(return_val, THandleIdentifierToTUniqueId(
+      req.sessionHandle.sessionId, &session_id, &secret), SQLSTATE_GENERAL_ERROR);
+  HS2_RETURN_IF_ERROR(return_val,
+      PopulateThriftBackendGflags(return_val.backend_config),
+      SQLSTATE_GENERAL_ERROR);
+
+  return_val.status.__set_statusCode(thrift::TStatusCode::SUCCESS_STATUS);
+  VLOG_RPC << "GetBackendConfig(): return_val=" << ThriftDebugString(return_val);
+}
+
 void ImpalaServer::CancelDelegationToken(TCancelDelegationTokenResp& return_val,
     const TCancelDelegationTokenReq& req) {
   return_val.status.__set_statusCode(thrift::TStatusCode::ERROR_STATUS);
diff --git a/be/src/service/impala-server.h b/be/src/service/impala-server.h
index 9a3250e..cf63fa8 100644
--- a/be/src/service/impala-server.h
+++ b/be/src/service/impala-server.h
@@ -29,6 +29,7 @@
 #include <boost/uuid/uuid_io.hpp>
 
 #include "common/status.h"
+#include "gen-cpp/BackendGflags_types.h"
 #include "gen-cpp/Frontend_types.h"
 #include "gen-cpp/ImpalaHiveServer2Service.h"
 #include "gen-cpp/ImpalaService.h"
@@ -352,6 +353,10 @@ class ImpalaServer : public ImpalaServiceIf,
       apache::hive::service::cli::thrift::TExecuteStatementResp& return_val,
       const TExecutePlannedStatementReq& req);
 
+  // Retrieves the current BackendConfig
+  virtual void GetBackendConfig(TGetBackendConfigResp& return_val,
+      const TGetBackendConfigReq& request);
+
   /// Closes an Impala operation and returns additional information about the closed
   /// operation.
   virtual void CloseImpalaOperation(
diff --git a/be/src/util/backend-gflag-util.cc b/be/src/util/backend-gflag-util.cc
index 2ef0311..d20c94e 100644
--- a/be/src/util/backend-gflag-util.cc
+++ b/be/src/util/backend-gflag-util.cc
@@ -163,8 +163,7 @@ Status GetConfigFromCommand(const string& flag_cmd, string& result) {
   return Status::OK();
 }
 
-Status GetThriftBackendGflags(JNIEnv* jni_env, jbyteArray* cfg_bytes) {
-  TBackendGflags cfg;
+Status PopulateThriftBackendGflags(TBackendGflags& cfg) {
   cfg.__set_load_catalog_in_background(FLAGS_load_catalog_in_background);
   cfg.__set_enable_orc_scanner(FLAGS_enable_orc_scanner);
   cfg.__set_use_local_catalog(FLAGS_use_local_catalog);
@@ -269,6 +268,12 @@ Status GetThriftBackendGflags(JNIEnv* jni_env, jbyteArray* cfg_bytes) {
   cfg.__set_saml2_group_attribute_name(FLAGS_saml2_group_attribute_name);
   cfg.__set_saml2_group_filter(FLAGS_saml2_group_filter);
   cfg.__set_saml2_ee_test_mode(FLAGS_saml2_ee_test_mode);
+  return Status::OK();
+}
+
+Status GetThriftBackendGFlagsForJNI(JNIEnv* jni_env, jbyteArray* cfg_bytes) {
+  TBackendGflags cfg;
+  RETURN_IF_ERROR(PopulateThriftBackendGflags(cfg));
   RETURN_IF_ERROR(SerializeThriftMsg(jni_env, &cfg, cfg_bytes));
   return Status::OK();
 }
diff --git a/be/src/util/backend-gflag-util.h b/be/src/util/backend-gflag-util.h
index d68ed2f..da17fd6 100644
--- a/be/src/util/backend-gflag-util.h
+++ b/be/src/util/backend-gflag-util.h
@@ -24,9 +24,12 @@
 
 namespace impala {
 
+class TBackendGflags;
+
+Status PopulateThriftBackendGflags(TBackendGflags& cfg);
 /// Builds the TBackendGflags object to pass to JNI. This is used to pass the gflag
 /// configs to the Frontend and the Catalog.
-Status GetThriftBackendGflags(JNIEnv* jni_env, jbyteArray* cfg_bytes);
+Status GetThriftBackendGFlagsForJNI(JNIEnv* jni_env, jbyteArray* cfg_bytes);
 }
 
 #endif
diff --git a/be/src/util/logging-support.cc b/be/src/util/logging-support.cc
index 2b6f9dd..459f913 100644
--- a/be/src/util/logging-support.cc
+++ b/be/src/util/logging-support.cc
@@ -81,7 +81,7 @@ Java_org_apache_impala_util_NativeLogger_Log(
 namespace {
 // Defaults to startup flag --v. FLAGS_v can be overriden at runtime for
 // debugging, so we save the original value here in case we need to restore
-// the defaults. Set in GetThriftBackendGflags().
+// the defaults. Set in GetThriftBackendGFlagsForJNI().
 int FLAGS_v_original_value;
 
 static jclass log4j_logger_class_;
diff --git a/common/thrift/ImpalaService.thrift b/common/thrift/ImpalaService.thrift
index c403055..44cc8a2 100644
--- a/common/thrift/ImpalaService.thrift
+++ b/common/thrift/ImpalaService.thrift
@@ -25,6 +25,7 @@ include "beeswax.thrift"
 include "TCLIService.thrift"
 include "RuntimeProfile.thrift"
 include "Frontend.thrift"
+include "BackendGflags.thrift"
 
 // ImpalaService accepts query execution options through beeswax.Query.configuration in
 // key:value form. For example, the list of strings could be:
@@ -823,6 +824,15 @@ struct TExecutePlannedStatementReq {
   2: required Frontend.TExecRequest plan
 }
 
+struct TGetBackendConfigReq {
+  1: required TCLIService.TSessionHandle sessionHandle
+}
+
+struct TGetBackendConfigResp {
+  1: required TCLIService.TStatus status
+
+  2: required BackendGflags.TBackendGflags backend_config
+}
 
 service ImpalaHiveServer2Service extends TCLIService.TCLIService {
   // Returns the exec summary for the given query. The exec summary is only valid for
@@ -843,4 +853,7 @@ service ImpalaHiveServer2Service extends TCLIService.TCLIService {
   // Execute statement with supplied ExecRequest
   TCLIService.TExecuteStatementResp ExecutePlannedStatement(
       1:TExecutePlannedStatementReq req);
+
+  // Returns the current TBackendGflags. Only supported for the "external fe" service.
+  TGetBackendConfigResp GetBackendConfig(1:TGetBackendConfigReq req);
 }
diff --git a/tests/hs2/test_hs2.py b/tests/hs2/test_hs2.py
index 38c100e..b72e221 100644
--- a/tests/hs2/test_hs2.py
+++ b/tests/hs2/test_hs2.py
@@ -732,6 +732,14 @@ class TestHS2(HS2TestSuite):
     assert len(exec_summary_resp.summary.nodes) > 0
 
   @needs_session()
+  def test_get_backend_config(self):
+    get_backend_config_req = ImpalaHiveServer2Service.TGetBackendConfigReq()
+    get_backend_config_req.sessionHandle = self.session_handle
+    get_backend_config_resp = self.hs2_client.GetBackendConfig(get_backend_config_req)
+    TestHS2.check_response(get_backend_config_resp,
+        TCLIService.TStatusCode.ERROR_STATUS, "Unsupported operation")
+
+  @needs_session()
   def test_get_profile(self):
     statement = "SELECT COUNT(2) FROM functional.alltypes"
     execute_statement_resp = self.execute_statement(statement)


[impala] 04/08: IMPALA-10535: Add interface to ImpalaServer for execution of externally compiled statements

Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit 311938b4f500aeb26f5a42cd955231588821e18b
Author: Kurt Deschler <kd...@cloudera.com>
AuthorDate: Fri Nov 8 15:45:45 2019 -0500

    IMPALA-10535: Add interface to ImpalaServer for execution of externally compiled statements
    
    The ExecutePlannedStatement interface allows an externally supplied
    TExecRequest to be executed by impalad. The TExecRequest must be fully
    populated and will be sent directly to the backend for execution.
    
    The following fields in the TExecRequest are updated by the coordinator:
    - Hostname
    - KRPC address
    - Local Timezone
    
    In order to add the interface to ImpalaInternalService.thrift, several of
    the thrift classes were moved to Query.thrift to avoid a circular
    dependency with Frontend.thrift.
    
    Added functionality to format and dump TExecRequest structures to path
    specified in debug flag dump_exec_request_path.
    
    A start timestamp field has been added to TExecRequest to represent the
    interval in the query profile between when the request was sent by the
    external frontend and handled by the backend.
    
    A local timestamp field has been added to the Ping result struct to
    return the current backend timestamp. This is used by the external to
    frontend to populate the start timestamp.
    
    Also included is a change to avoid generating silent AnalysisExceptions
    during table resolution.
    
    Tested with TExecRequest structures populated by external frontend.
    Local timezone change tested withe INT64 TIMESTAMP datatype
    
    Reviewed-by: John Sherman <jf...@cloudera.com>
    Change-Id: Iace716dd67290f08441857dc02d2428b0e335eaa
    Reviewed-on: http://gerrit.cloudera.org:8080/17104
    Reviewed-by: Thomas Tauber-Marshall <tm...@cloudera.com>
    Tested-by: Thomas Tauber-Marshall <tm...@cloudera.com>
---
 be/generated-sources/gen-cpp/CMakeLists.txt        |   2 +
 be/src/rpc/hs2-http-test.cc                        |   2 +
 be/src/runtime/debug-options.h                     |   1 +
 be/src/runtime/query-driver.cc                     |  25 +
 be/src/runtime/query-driver.h                      |   3 +
 be/src/service/client-request-state.cc             |   4 +
 be/src/service/client-request-state.h              |   4 +
 be/src/service/impala-beeswax-server.cc            |   4 +-
 be/src/service/impala-hs2-server.cc                |  32 +-
 be/src/service/impala-server.cc                    |  74 ++-
 be/src/service/impala-server.h                     |  21 +-
 common/thrift/CMakeLists.txt                       |  12 +-
 common/thrift/Frontend.thrift                      | 129 +----
 common/thrift/ImpalaInternalService.thrift         | 619 +--------------------
 common/thrift/ImpalaService.thrift                 |  21 +
 .../{ImpalaInternalService.thrift => Query.thrift} | 311 ++++-------
 fe/pom.xml                                         |   5 +
 .../java/org/apache/impala/analysis/Analyzer.java  |   9 +-
 .../org/apache/impala/analysis/PrivilegeSpec.java  |   2 +-
 .../apache/impala/analysis/ResetMetadataStmt.java  |   3 +-
 .../org/apache/impala/planner/PlannerTestBase.java |   3 +-
 21 files changed, 330 insertions(+), 956 deletions(-)

diff --git a/be/generated-sources/gen-cpp/CMakeLists.txt b/be/generated-sources/gen-cpp/CMakeLists.txt
index 271dcb7..074dfae 100644
--- a/be/generated-sources/gen-cpp/CMakeLists.txt
+++ b/be/generated-sources/gen-cpp/CMakeLists.txt
@@ -84,6 +84,8 @@ set(SRC_FILES
   Planner_types.cpp
   parquet_constants.cpp
   parquet_types.cpp
+  Query_constants.cpp
+  Query_types.cpp
   ResourceProfile_constants.cpp
   ResourceProfile_types.cpp
   RuntimeProfile_constants.cpp
diff --git a/be/src/rpc/hs2-http-test.cc b/be/src/rpc/hs2-http-test.cc
index d81c9d9..2c95550 100644
--- a/be/src/rpc/hs2-http-test.cc
+++ b/be/src/rpc/hs2-http-test.cc
@@ -48,6 +48,8 @@ class TestHS2Service : public ImpalaHiveServer2ServiceIf {
   virtual void GetInfo(TGetInfoResp& _return, const TGetInfoReq& req) {}
   virtual void ExecuteStatement(
       TExecuteStatementResp& _return, const TExecuteStatementReq& req) {}
+  virtual void ExecutePlannedStatement(
+      TExecuteStatementResp& _return, const TExecutePlannedStatementReq& req) {}
   virtual void GetTypeInfo(TGetTypeInfoResp& _return, const TGetTypeInfoReq& req) {}
   virtual void GetCatalogs(TGetCatalogsResp& _return, const TGetCatalogsReq& req) {}
   virtual void GetSchemas(TGetSchemasResp& _return, const TGetSchemasReq& req) {}
diff --git a/be/src/runtime/debug-options.h b/be/src/runtime/debug-options.h
index 2b76f5c..4b723b3 100644
--- a/be/src/runtime/debug-options.h
+++ b/be/src/runtime/debug-options.h
@@ -23,6 +23,7 @@
 
 #include "gen-cpp/Frontend_types.h"
 #include "gen-cpp/Types_types.h"
+#include "gen-cpp/ImpalaInternalService_types.h"
 
 namespace impala {
 
diff --git a/be/src/runtime/query-driver.cc b/be/src/runtime/query-driver.cc
index 604054c..983d599 100644
--- a/be/src/runtime/query-driver.cc
+++ b/be/src/runtime/query-driver.cc
@@ -23,6 +23,7 @@
 #include "service/frontend.h"
 #include "service/impala-server.h"
 #include "util/debug-util.h"
+#include "util/network-util.h"
 #include "util/runtime-profile-counters.h"
 
 #include "common/names.h"
@@ -63,6 +64,30 @@ Status QueryDriver::RunFrontendPlanner(const TQueryCtx& query_ctx) {
   return Status::OK();
 }
 
+Status QueryDriver::SetExternalPlan(
+    const TQueryCtx& query_ctx, const TExecRequest& external_exec_request) {
+  // Takes the TQueryCtx and calls into the frontend to initialize the TExecRequest for
+  // this query.
+  DCHECK(client_request_state_ != nullptr);
+  DCHECK(exec_request_ != nullptr);
+  RETURN_IF_ERROR(
+      DebugAction(query_ctx.client_request.query_options, "FRONTEND_PLANNER"));
+  *exec_request_.get() = external_exec_request;
+  // Update query_id in the external request
+  exec_request_->query_exec_request.query_ctx.__set_query_id(
+      client_request_state_->query_id());
+  // Update coordinator related internal addresses in the external request
+  exec_request_->query_exec_request.query_ctx.__set_coord_hostname(
+      ExecEnv::GetInstance()->configured_backend_address().hostname);
+  const TNetworkAddress& address = ExecEnv::GetInstance()->krpc_address();
+  DCHECK(IsResolvedAddress(address));
+  exec_request_->query_exec_request.query_ctx.__set_coord_ip_address(address);
+  // Update local_time_zone in the external request
+  exec_request_->query_exec_request.query_ctx.__set_local_time_zone(
+      query_ctx.local_time_zone);
+  return Status::OK();
+}
+
 ClientRequestState* QueryDriver::GetActiveClientRequestState() {
   lock_guard<SpinLock> l(client_request_state_lock_);
   if (retried_client_request_state_ != nullptr) {
diff --git a/be/src/runtime/query-driver.h b/be/src/runtime/query-driver.h
index bc6264a..188b4da 100644
--- a/be/src/runtime/query-driver.h
+++ b/be/src/runtime/query-driver.h
@@ -149,6 +149,9 @@ class QueryDriver {
   /// query string (TQueryCtx::TClientRequest::stmt).
   Status RunFrontendPlanner(const TQueryCtx& query_ctx) WARN_UNUSED_RESULT;
 
+  /// Similar to RunFrontendPlanner but takes TExecRequest from and external planner
+  Status SetExternalPlan(const TQueryCtx& query_ctx, const TExecRequest& exec_request);
+
   /// Returns the ClientRequestState corresponding to the given query id.
   ClientRequestState* GetClientRequestState(const TUniqueId& query_id);
 
diff --git a/be/src/service/client-request-state.cc b/be/src/service/client-request-state.cc
index 7f455a3..23b446f 100644
--- a/be/src/service/client-request-state.cc
+++ b/be/src/service/client-request-state.cc
@@ -186,6 +186,10 @@ Status ClientRequestState::SetResultCache(QueryResultSet* cache,
   return Status::OK();
 }
 
+void ClientRequestState::SetRemoteSubmitTime(int64_t remote_submit_time) {
+  query_events_->Start(remote_submit_time);
+}
+
 void ClientRequestState::SetFrontendProfile(TRuntimeProfileNode profile) {
   // Should we defer creating and adding the child until here? probably.
   TRuntimeProfileTree prof_tree;
diff --git a/be/src/service/client-request-state.h b/be/src/service/client-request-state.h
index 0c7bb6a..c2dd271 100644
--- a/be/src/service/client-request-state.h
+++ b/be/src/service/client-request-state.h
@@ -90,6 +90,10 @@ class ClientRequestState {
   /// which then sets the frontend profile.
   void SetFrontendProfile(TRuntimeProfileNode profile);
 
+  /// Sets the coordinator time that the plan request was submitted at so that
+  /// the backend timeline starts where the frontend timeline ends
+  void SetRemoteSubmitTime(int64_t remote_submit_time);
+
   /// Based on query type, this either initiates execution of this ClientRequestState's
   /// TExecRequest or submits the query to the Admission controller for asynchronous
   /// admission control. When this returns the operation state is either RUNNING_STATE or
diff --git a/be/src/service/impala-beeswax-server.cc b/be/src/service/impala-beeswax-server.cc
index 7eb0094..79a500f 100644
--- a/be/src/service/impala-beeswax-server.cc
+++ b/be/src/service/impala-beeswax-server.cc
@@ -70,7 +70,7 @@ void ImpalaServer::query(beeswax::QueryHandle& beeswax_handle, const Query& quer
   // raise Syntax error or access violation; it's likely to be syntax/analysis error
   // TODO: that may not be true; fix this
   QueryHandle query_handle;
-  RAISE_IF_ERROR(Execute(&query_ctx, session, &query_handle),
+  RAISE_IF_ERROR(Execute(&query_ctx, session, &query_handle, nullptr),
       SQLSTATE_SYNTAX_ERROR_OR_ACCESS_VIOLATION);
 
   // start thread to wait for results to become available, which will allow
@@ -118,7 +118,7 @@ void ImpalaServer::executeAndWait(beeswax::QueryHandle& beeswax_handle,
   // raise Syntax error or access violation; it's likely to be syntax/analysis error
   // TODO: that may not be true; fix this
   QueryHandle query_handle;
-  RAISE_IF_ERROR(Execute(&query_ctx, session, &query_handle),
+  RAISE_IF_ERROR(Execute(&query_ctx, session, &query_handle, nullptr),
       SQLSTATE_SYNTAX_ERROR_OR_ACCESS_VIOLATION);
 
   // Once the query is running do a final check for session closure and add it to the
diff --git a/be/src/service/impala-hs2-server.cc b/be/src/service/impala-hs2-server.cc
index b38a254..debd755 100644
--- a/be/src/service/impala-hs2-server.cc
+++ b/be/src/service/impala-hs2-server.cc
@@ -52,6 +52,7 @@
 #include "util/metrics.h"
 #include "util/pretty-printer.h"
 #include "util/runtime-profile-counters.h"
+#include "util/stopwatch.h"
 #include "util/string-parser.h"
 #include "util/uid-util.h"
 
@@ -453,9 +454,8 @@ void ImpalaServer::GetInfo(TGetInfoResp& return_val,
   return_val.status.__set_statusCode(thrift::TStatusCode::SUCCESS_STATUS);
 }
 
-void ImpalaServer::ExecuteStatement(TExecuteStatementResp& return_val,
-    const TExecuteStatementReq& request) {
-  VLOG_QUERY << "ExecuteStatement(): request=" << ThriftDebugString(request);
+void ImpalaServer::ExecuteStatementCommon(TExecuteStatementResp& return_val,
+    const TExecuteStatementReq& request, const TExecRequest* external_exec_request) {
   HS2_RETURN_IF_ERROR(return_val, CheckNotShuttingDown(), SQLSTATE_GENERAL_ERROR);
   // We ignore the runAsync flag here: Impala's queries will always run asynchronously,
   // and will block on fetch. To the client, this looks like Hive's synchronous mode; the
@@ -497,7 +497,7 @@ void ImpalaServer::ExecuteStatement(TExecuteStatementResp& return_val,
   }
 
   QueryHandle query_handle;
-  status = Execute(&query_ctx, session, &query_handle);
+  status = Execute(&query_ctx, session, &query_handle, external_exec_request);
   HS2_RETURN_IF_ERROR(return_val, status, SQLSTATE_GENERAL_ERROR);
 
   // Start thread to wait for results to become available.
@@ -541,6 +541,29 @@ Status ImpalaServer::SetupResultsCacheing(const QueryHandle& query_handle,
   return Status::OK();
 }
 
+void ImpalaServer::ExecuteStatement(TExecuteStatementResp& return_val,
+    const TExecuteStatementReq& request) {
+  VLOG_QUERY << "ExecuteStatement(): request=" << ThriftDebugString(request);
+  ExecuteStatementCommon(return_val, request);
+}
+
+void ImpalaServer::ExecutePlannedStatement(
+      TExecuteStatementResp& return_val,
+      const TExecutePlannedStatementReq& request) {
+  VLOG_QUERY << "ExecutePlannedStatement(): request=" << ThriftDebugString(request);
+  const ThriftServer::ConnectionContext* connection_context =
+      ThriftServer::GetThreadConnectionContext();
+  // This RPC is only supported on the external frontend service and should only be
+  // exposed to trusted clients since it executes provided query plans directly with
+  // no authorization checks (they are assumed to have been done by the trusted client)
+  if (connection_context->server_name != EXTERNAL_FRONTEND_SERVER_NAME) {
+    HS2_RETURN_ERROR(return_val, "Unsupported operation",
+        SQLSTATE_OPTIONAL_FEATURE_NOT_IMPLEMENTED);
+  }
+  ExecuteStatementCommon(return_val, request.statementReq, &request.plan);
+}
+
+
 void ImpalaServer::GetTypeInfo(TGetTypeInfoResp& return_val,
     const TGetTypeInfoReq& request) {
   VLOG_QUERY << "GetTypeInfo(): request=" << ThriftDebugString(request);
@@ -1206,6 +1229,7 @@ void ImpalaServer::PingImpalaHS2Service(TPingImpalaHS2ServiceResp& return_val,
   } else {
     return_val.__set_webserver_address("");
   }
+  return_val.__set_timestamp(MonotonicStopWatch::Now());
   VLOG_RPC << "PingImpalaHS2Service(): return_val=" << ThriftDebugString(return_val);
 }
 }
diff --git a/be/src/service/impala-server.cc b/be/src/service/impala-server.cc
index 0e8bfe2..c11e2e8 100644
--- a/be/src/service/impala-server.cc
+++ b/be/src/service/impala-server.cc
@@ -21,6 +21,9 @@
 #include <unistd.h>
 #include <algorithm>
 #include <exception>
+#include <fstream>
+#include <sstream>
+
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/join.hpp>
 #include <boost/algorithm/string/replace.hpp>
@@ -313,6 +316,11 @@ DEFINE_int32(query_event_hook_nthreads, 1, "Number of threads to use for "
     "QueryEventHook execution. If this number is >1 then hooks will execute "
     "concurrently.");
 
+// Dumps used for debugging and diffing ExecRequests in text form.
+DEFINE_string(dump_exec_request_path, "",
+    "If set, dump TExecRequest structures to {dump_exec_request_path}/"
+    "TExecRequest-{internal|external}.{query_id.hi}-{query_id.lo}");
+
 DECLARE_bool(compact_catalog_topic);
 
 DEFINE_bool(use_local_tz_for_unix_timestamp_conversions, false,
@@ -1084,7 +1092,8 @@ void ImpalaServer::EnforceMaxMtDop(TQueryCtx* query_ctx, int64_t max_mt_dop) {
 }
 
 Status ImpalaServer::Execute(TQueryCtx* query_ctx, shared_ptr<SessionState> session_state,
-    QueryHandle* query_handle) {
+    QueryHandle* query_handle,
+    const TExecRequest* external_exec_request) {
   PrepareQueryContext(query_ctx);
   ScopedThreadContext debug_ctx(GetThreadDebugInfo(), query_ctx->query_id);
   ImpaladMetrics::IMPALA_SERVER_NUM_QUERIES->Increment(1L);
@@ -1095,26 +1104,57 @@ Status ImpalaServer::Execute(TQueryCtx* query_ctx, shared_ptr<SessionState> sess
   query_ctx->client_request.__set_redacted_stmt((const string) stmt);
 
   bool registered_query = false;
-  Status status = ExecuteInternal(*query_ctx, session_state, &registered_query,
-      query_handle);
+  Status status = ExecuteInternal(*query_ctx, external_exec_request, session_state,
+      &registered_query, query_handle);
   if (!status.ok() && registered_query) {
     UnregisterQueryDiscardResult((*query_handle)->query_id(), false, &status);
   }
   return status;
 }
 
+void DumpTExecReq(const TExecRequest& exec_request, const char* dump_type,
+    const TUniqueId& query_id) {
+  if (FLAGS_dump_exec_request_path.empty()) return;
+  int depth = 0;
+  std::stringstream tmpstr;
+  string fn(Substitute("$1/TExecRequest-$2.$3", FLAGS_dump_exec_request_path,
+      dump_type, PrintId(query_id, "-")));
+  std::ofstream ofs(fn);
+  tmpstr << exec_request;
+  const int len = tmpstr.str().length();
+  const char *p = tmpstr.str().c_str();
+  for (int i = 0; i < len; ++i) {
+    const char ch = p[i];
+    ofs << ch;
+    if (ch == '(') {
+      depth++;
+    } else if (ch == ')' && depth > 0) {
+      depth--;
+    } else if (ch == ',') {
+    } else {
+      continue;
+    }
+    ofs << '\n' << std::setw(depth) << " ";
+  }
+}
+
 Status ImpalaServer::ExecuteInternal(const TQueryCtx& query_ctx,
-    shared_ptr<SessionState> session_state, bool* registered_query,
-    QueryHandle* query_handle) {
+    const TExecRequest* external_exec_request, shared_ptr<SessionState> session_state,
+    bool* registered_query, QueryHandle* query_handle) {
   DCHECK(session_state != nullptr);
   DCHECK(query_handle != nullptr);
   DCHECK(registered_query != nullptr);
   *registered_query = false;
-
   // Create the QueryDriver for this query. CreateNewDriver creates the associated
   // ClientRequestState as well.
   QueryDriver::CreateNewDriver(this, query_handle, query_ctx, session_state);
 
+  bool is_external_req = external_exec_request != nullptr;
+
+  if (is_external_req && external_exec_request->remote_submit_time) {
+    (*query_handle)->SetRemoteSubmitTime(external_exec_request->remote_submit_time);
+  }
+
   (*query_handle)->query_events()->MarkEvent("Query submitted");
 
   {
@@ -1144,9 +1184,25 @@ Status ImpalaServer::ExecuteInternal(const TQueryCtx& query_ctx,
           statement_length, max_statement_length));
     }
 
-    // Takes the TQueryCtx and calls into the frontend to initialize the TExecRequest for
-    // this query.
-    RETURN_IF_ERROR(query_handle->query_driver()->RunFrontendPlanner(query_ctx));
+    Status exec_status = Status::OK();
+    TUniqueId query_id = (*query_handle)->query_id();
+    // Generate TExecRequest here if one was not passed in or we want one
+    // from the Impala planner to compare with
+    if (external_exec_request == nullptr || !FLAGS_dump_exec_request_path.empty()) {
+      // Takes the TQueryCtx and calls into the frontend to initialize the
+      // TExecRequest for this query.
+      RETURN_IF_ERROR(query_handle->query_driver()->RunFrontendPlanner(query_ctx));
+      DumpTExecReq((*query_handle)->exec_request(), "internal", query_id);
+    }
+
+    if (external_exec_request != nullptr) {
+      // Use passed in exec_request
+      RETURN_IF_ERROR(query_handle->query_driver()->SetExternalPlan(
+          query_ctx, *external_exec_request));
+
+      exec_status = Status::OK();
+      DumpTExecReq((*query_handle)->exec_request(), "external", query_id);
+    }
 
     const TExecRequest& result = (*query_handle)->exec_request();
     (*query_handle)->query_events()->MarkEvent("Planning finished");
diff --git a/be/src/service/impala-server.h b/be/src/service/impala-server.h
index f280374..9a3250e 100644
--- a/be/src/service/impala-server.h
+++ b/be/src/service/impala-server.h
@@ -63,6 +63,7 @@ class CancellationWork;
 class ImpalaHttpHandler;
 class RowDescriptor;
 class TDmlResult;
+class TExecutePlannedStatementReq;
 class TNetworkAddress;
 class TClientRequest;
 class TExecRequest;
@@ -76,6 +77,7 @@ struct QueryHandle;
 class SimpleLogger;
 class UpdateFilterParamsPB;
 class UpdateFilterResultPB;
+class TQueryExecRequest;
 
 /// An ImpalaServer contains both frontend and backend functionality;
 /// it implements ImpalaService (Beeswax), ImpalaHiveServer2Service (HiveServer2)
@@ -345,6 +347,11 @@ class ImpalaServer : public ImpalaServiceIf,
   virtual void PingImpalaHS2Service(TPingImpalaHS2ServiceResp& return_val,
       const TPingImpalaHS2ServiceReq& req);
 
+  // Execute the provided Thrift statement/plan
+  virtual void ExecutePlannedStatement(
+      apache::hive::service::cli::thrift::TExecuteStatementResp& return_val,
+      const TExecutePlannedStatementReq& req);
+
   /// Closes an Impala operation and returns additional information about the closed
   /// operation.
   virtual void CloseImpalaOperation(
@@ -669,14 +676,26 @@ class ImpalaServer : public ImpalaServiceIf,
   /// query_driver->request_state will be NULL and nothing will have been registered in
   /// query_driver_map_. session_state is a ptr to the session running this query and must
   /// have been checked out.
+  /// external_exec_request is a statement that was prepared by an external frontend using
+  /// Impala PlanNodes or null if the external frontend isn't being used.
   Status Execute(TQueryCtx* query_ctx, std::shared_ptr<SessionState> session_state,
-      QueryHandle* query_handle) WARN_UNUSED_RESULT;
+      QueryHandle* query_handle,
+      const TExecRequest* external_exec_request) WARN_UNUSED_RESULT;
 
   /// Implements Execute() logic, but doesn't unregister query on error.
   Status ExecuteInternal(const TQueryCtx& query_ctx,
+      const TExecRequest* external_exec_request,
       std::shared_ptr<SessionState> session_state, bool* registered_query,
       QueryHandle* query_handle);
 
+  /// Common execution logic factored out from Execute to be shared with
+  /// ExecutePlannedStatement. Optional TExecRequest is the provided Thrift
+  /// request to execute instead of parsing and executing the SQL statement.
+  void ExecuteStatementCommon(
+      apache::hive::service::cli::thrift::TExecuteStatementResp& return_val,
+      const apache::hive::service::cli::thrift::TExecuteStatementReq& request,
+      const TExecRequest* external_exec_request = nullptr);
+
   /// Registers the query with query_driver_map_ using the globally unique query_id. The
   /// caller must have checked out the session state.
   Status RegisterQuery(const TUniqueId& query_id,
diff --git a/common/thrift/CMakeLists.txt b/common/thrift/CMakeLists.txt
index 9b14ab5..a4fd209 100644
--- a/common/thrift/CMakeLists.txt
+++ b/common/thrift/CMakeLists.txt
@@ -64,12 +64,9 @@ function(THRIFT_GEN VAR)
       set(CPP_ARGS -r ${CPP_ARGS})
     ENDIF(THRIFT_FILE STREQUAL "beeswax.thrift")
 
-    IF (THRIFT_FILE STREQUAL ${TCLI_SERVICE_THRIFT} OR THRIFT_FILE STREQUAL "parquet.thrift" OR
-        THRIFT_FILE STREQUAL "ImpalaService.thrift")
+    IF (THRIFT_FILE STREQUAL ${TCLI_SERVICE_THRIFT} OR THRIFT_FILE STREQUAL "parquet.thrift")
       # Do not generate Java HiveServer2 and Parquet files because we should use the jar
       # from Hive or Parquet.
-      # Also do not generate ImpalaService.thrift because the generated code doesn't
-      # compile with hive if the thrift version in hive is 0.9.0
       add_custom_command(
         OUTPUT ${OUTPUT_BE_FILE}
         COMMAND ${THRIFT_COMPILER} ${CPP_ARGS} ${THRIFT_FILE}
@@ -78,8 +75,7 @@ function(THRIFT_GEN VAR)
         COMMENT "Running thrift compiler on ${THRIFT_FILE}"
         VERBATIM
       )
-    ELSE (THRIFT_FILE STREQUAL ${TCLI_SERVICE_THRIFT} OR THRIFT_FILE STREQUAL "parquet.thrift" OR
-        THRIFT_FILE STREQUAL "ImpalaService.thrift")
+    ELSE (THRIFT_FILE STREQUAL ${TCLI_SERVICE_THRIFT} OR THRIFT_FILE STREQUAL "parquet.thrift")
       add_custom_command(
         OUTPUT ${OUTPUT_BE_FILE}
         COMMAND ${THRIFT_COMPILER} ${CPP_ARGS} ${THRIFT_FILE}
@@ -89,8 +85,7 @@ function(THRIFT_GEN VAR)
         COMMENT "Running thrift compiler on ${THRIFT_FILE}"
         VERBATIM
     )
-    ENDIF (THRIFT_FILE STREQUAL ${TCLI_SERVICE_THRIFT} OR THRIFT_FILE STREQUAL "parquet.thrift" OR
-        THRIFT_FILE STREQUAL "ImpalaService.thrift")
+    ENDIF (THRIFT_FILE STREQUAL ${TCLI_SERVICE_THRIFT} OR THRIFT_FILE STREQUAL "parquet.thrift")
   endforeach(THRIFT_FILE)
 
   set(${VAR} ${${VAR}} PARENT_SCOPE)
@@ -229,6 +224,7 @@ set (SRC_FILES
   Partitions.thrift
   parquet.thrift
   ResourceProfile.thrift
+  Query.thrift
   Results.thrift
   RuntimeProfile.thrift
   SqlConstraints.thrift
diff --git a/common/thrift/Frontend.thrift b/common/thrift/Frontend.thrift
index 5126958..62899bf 100644
--- a/common/thrift/Frontend.thrift
+++ b/common/thrift/Frontend.thrift
@@ -19,19 +19,16 @@ namespace cpp impala
 namespace java org.apache.impala.thrift
 
 include "Types.thrift"
-include "ImpalaInternalService.thrift"
-include "PlanNodes.thrift"
-include "Planner.thrift"
 include "RuntimeProfile.thrift"
 include "Descriptors.thrift"
 include "Data.thrift"
 include "Results.thrift"
-include "Exprs.thrift"
 include "TCLIService.thrift"
 include "Status.thrift"
 include "CatalogObjects.thrift"
 include "CatalogService.thrift"
 include "LineageGraph.thrift"
+include "Query.thrift"
 
 // These are supporting structs for JniFrontend.java, which serves as the glue
 // between our C++ execution environment and the Java frontend.
@@ -79,7 +76,7 @@ struct TGetTablesParams {
   // Session state for the user who initiated this request. If authorization is
   // enabled, only the tables this user has access to will be returned. If not
   // set, access checks will be skipped (used for internal Impala requests)
-  3: optional ImpalaInternalService.TSessionState session
+  3: optional Query.TSessionState session
 }
 
 // getTableNames returns a list of unqualified table names
@@ -126,7 +123,7 @@ struct TGetDbsParams {
   // Session state for the user who initiated this request. If authorization is
   // enabled, only the databases this user has access to will be returned. If not
   // set, access checks will be skipped (used for internal Impala requests)
-  2: optional ImpalaInternalService.TSessionState session
+  2: optional Query.TSessionState session
 }
 
 // getDbs returns a list of databases
@@ -188,7 +185,7 @@ struct TDescribeTableParams {
   3: optional Types.TColumnType result_struct
 
   // Session state for the user who initiated this request.
-  4: optional ImpalaInternalService.TSessionState session
+  4: optional Query.TSessionState session
 }
 
 // Results of a call to describeDb() and describeTable()
@@ -284,11 +281,6 @@ struct TShowRolesResult {
   1: required list<string> role_names
 }
 
-// Result of the DESCRIBE HISTORY command.
-struct TGetTableHistoryResult {
-  1: required list<TGetTableHistoryResultItem> result
-}
-
 // Represents one row in the DESCRIBE HISTORY command's result.
 struct TGetTableHistoryResultItem {
   // Timestamp in millis
@@ -298,6 +290,11 @@ struct TGetTableHistoryResultItem {
   4: required bool is_current_ancestor
 }
 
+// Result of the DESCRIBE HISTORY command.
+struct TGetTableHistoryResult {
+  1: required list<TGetTableHistoryResultItem> result
+}
+
 // Parameters for SHOW GRANT ROLE/USER commands
 struct TShowGrantPrincipalParams {
   // The effective user who submitted this request.
@@ -331,7 +328,7 @@ struct TGetFunctionsParams {
   // Session state for the user who initiated this request. If authorization is
   // enabled, only the functions this user has access to will be returned. If not
   // set, access checks will be skipped (used for internal Impala requests)
-  4: optional ImpalaInternalService.TSessionState session
+  4: optional Query.TSessionState session
 }
 
 // getFunctions() returns a list of function signatures
@@ -353,40 +350,6 @@ struct TExplainResult {
   1: required list<Data.TResultRow> results
 }
 
-// Metadata required to finalize a query - that is, to clean up after the query is done.
-// Only relevant for INSERT queries.
-struct TFinalizeParams {
-  // True if the INSERT query was OVERWRITE, rather than INTO
-  1: required bool is_overwrite
-
-  // The base directory in hdfs of the table targeted by this INSERT
-  2: required string hdfs_base_dir
-
-  // The target table name
-  3: required string table_name
-
-  // The target table database
-  4: required string table_db
-
-  // The full path in HDFS of a directory under which temporary files may be written
-  // during an INSERT. For a query with id a:b, files are written to <staging_dir>/.a_b/,
-  // and that entire directory is removed after the INSERT completes.
-  5: optional string staging_dir
-
-  // Identifier for the target table in the query-wide descriptor table (see
-  // TDescriptorTable and TTableDescriptor).
-  6: optional i64 table_id;
-
-  // Stores the ACID transaction id of the target table for transactional INSERTs.
-  7: optional i64 transaction_id;
-
-  // Stores the ACID write id of the target table for transactional INSERTs.
-  8: optional i64 write_id;
-
-  // Stores the Iceberg spec id of the partition spec used for this INSERT.
-  9: optional i32 spec_id;
-}
-
 // Request for a LOAD DATA statement. LOAD DATA is only supported for HDFS backed tables.
 struct TLoadDataReq {
   // Fully qualified table name to load data into.
@@ -413,67 +376,6 @@ struct TLoadDataResp {
   1: required Data.TResultRow load_summary
 }
 
-// Execution parameters for a single plan; component of TQueryExecRequest
-struct TPlanExecInfo {
-  // fragments[i] may consume the output of fragments[j > i];
-  // fragments[0] is the root fragment and also the coordinator fragment, if
-  // it is unpartitioned.
-  1: required list<Planner.TPlanFragment> fragments
-
-  // A map from scan node ids to a scan range specification.
-  // The node ids refer to scan nodes in fragments[].plan
-  2: optional map<Types.TPlanNodeId, Planner.TScanRangeSpec>
-      per_node_scan_ranges
-}
-
-// Result of call to ImpalaPlanService/JniFrontend.CreateQueryRequest()
-struct TQueryExecRequest {
-  // exec info for all plans; the first one materializes the query result and subsequent
-  // ones materialize join builds that are input for preceding plans in the list.
-  1: optional list<TPlanExecInfo> plan_exec_info
-
-  // Metadata of the query result set (only for select)
-  2: optional Results.TResultSetMetadata result_set_metadata
-
-  // Set if the query needs finalization after it executes
-  3: optional TFinalizeParams finalize_params
-
-  4: required ImpalaInternalService.TQueryCtx query_ctx
-
-  // The same as the output of 'explain <query>'
-  5: optional string query_plan
-
-  // The statement type governs when the coordinator can judge a query to be finished.
-  // DML queries are complete after Wait(), SELECTs may not be. Generally matches
-  // the stmt_type of the parent TExecRequest, but in some cases (such as CREATE TABLE
-  // AS SELECT), these may differ.
-  6: required Types.TStmtType stmt_type
-
-  // List of replica hosts.  Used by the host_idx field of TScanRangeLocation.
-  7: required list<Types.TNetworkAddress> host_list
-
-  // Column lineage graph
-  8: optional LineageGraph.TLineageGraph lineage_graph
-
-  // Estimated per-host peak memory consumption in bytes. Used by admission control.
-  // TODO: Remove when AC doesn't rely on this any more.
-  9: optional i64 per_host_mem_estimate
-
-  // Maximum possible (in the case all fragments are scheduled on all hosts with
-  // max DOP) minimum memory reservation required per host, in bytes.
-  10: optional i64 max_per_host_min_mem_reservation;
-
-  // Maximum possible (in the case all fragments are scheduled on all hosts with
-  // max DOP) required threads per host, i.e. the number of threads that this query
-  // needs to execute successfully. Does not include "optional" threads.
-  11: optional i64 max_per_host_thread_reservation;
-
-  // Estimated coordinator's memory consumption in bytes assuming that the coordinator
-  // fragment will run on a dedicated coordinator. Set by the planner and used by
-  // admission control.
-  12: optional i64 dedicated_coord_mem_estimate;
-}
-
 enum TCatalogOpType {
   SHOW_TABLES = 0
   SHOW_DBS = 1
@@ -622,7 +524,7 @@ struct TMetadataOpRequest {
   // Session state for the user who initiated this request. If authorization is
   // enabled, only the server objects this user has access to will be returned.
   // If not set, access checks will be skipped (used for internal Impala requests)
-  10: optional ImpalaInternalService.TSessionState session
+  10: optional Query.TSessionState session
   11: optional TCLIService.TGetPrimaryKeysReq get_primary_keys_req
   12: optional TCLIService.TGetCrossReferenceReq get_cross_reference_req
 }
@@ -647,11 +549,11 @@ struct TExecRequest {
   1: required Types.TStmtType stmt_type
 
   // Copied from the corresponding TClientRequest
-  2: required ImpalaInternalService.TQueryOptions query_options
+  2: required Query.TQueryOptions query_options
 
   // TQueryExecRequest for the backend
   // Set iff stmt_type is QUERY or DML
-  3: optional TQueryExecRequest query_exec_request
+  3: optional Query.TQueryExecRequest query_exec_request
 
   // Set if stmt_type is DDL
   4: optional TCatalogOpRequest catalog_op_request
@@ -692,6 +594,9 @@ struct TExecRequest {
 
   // Set iff stmt_type is TESTCASE
   15: optional string testcase_data_path
+
+  // Coordinator time when plan was submitted by external frontend
+  16: optional i64 remote_submit_time
 }
 
 // Parameters to FeSupport.cacheJar().
@@ -1014,4 +919,4 @@ struct TWrappedHttpResponse {
   4: required map<string, string> cookies
   5: optional string content
   6: optional string content_type
-}
\ No newline at end of file
+}
diff --git a/common/thrift/ImpalaInternalService.thrift b/common/thrift/ImpalaInternalService.thrift
index 668d183..1f95d72 100644
--- a/common/thrift/ImpalaInternalService.thrift
+++ b/common/thrift/ImpalaInternalService.thrift
@@ -34,506 +34,11 @@ include "Results.thrift"
 include "RuntimeProfile.thrift"
 include "ImpalaService.thrift"
 include "Data.thrift"
-
-// constants for TQueryOptions.num_nodes
-const i32 NUM_NODES_ALL = 0
-const i32 NUM_NODES_ALL_RACKS = -1
+include "Query.thrift"
 
 // constants for TPlanNodeId
 const i32 INVALID_PLAN_NODE_ID = -1
 
-enum TParquetFallbackSchemaResolution {
-  POSITION = 0
-  NAME = 1
-  // Valid for Iceberg tables
-  FIELD_ID = 2
-}
-
-// The order of the enum values needs to be kept in sync with
-// ParquetMetadataUtils::ORDERED_ARRAY_ENCODINGS in parquet-metadata-utils.cc.
-enum TParquetArrayResolution {
-  THREE_LEVEL = 0
-  TWO_LEVEL = 1
-  TWO_LEVEL_THEN_THREE_LEVEL = 2
-}
-
-enum TJoinDistributionMode {
-  BROADCAST = 0
-  SHUFFLE = 1
-}
-
-// Consistency level options for Kudu scans.
-enum TKuduReadMode {
-  DEFAULT = 0
-  READ_LATEST = 1
-  READ_AT_SNAPSHOT = 2
-}
-
-// Physical type and unit used when writing timestamps in Parquet.
-enum TParquetTimestampType {
-  INT96_NANOS,
-  INT64_MILLIS,
-  INT64_MICROS,
-  INT64_NANOS
-}
-
-// A table's Hive ACID type.
-enum TTransactionalType {
-  NONE,
-  INSERT_ONLY
-}
-
-// Query options that correspond to ImpalaService.ImpalaQueryOptions, with their
-// respective defaults. Query options can be set in the following ways:
-//
-// 1) Process-wide defaults (via the impalad arg --default_query_options)
-// 2) Resource pool defaults (via resource pool configuration)
-// 3) Session settings (via the SET command or the HS2 OpenSession RPC)
-// 4) HS2/Beeswax configuration 'overlay' in the request metadata
-//
-// (1) and (2) are set by administrators and provide the default query options for a
-// session, in that order, so options set in (2) override those in (1). The user
-// can specify query options with (3) to override the preceding layers; these
-// overrides are stored in SessionState. Finally, the client can pass a config
-// 'overlay' (4) in the request metadata which overrides everything else.
-//
-// Session options (level 3, above) can be set by the user with SET <key>=<value>
-// or in the OpenSession RPC. They can be unset with SET <key>="". When unset,
-// it's unset in that level, and the values as specified by the defaults,
-// and levels 1 and 2 above take hold.
-//
-// Because of the ambiguity between null and the empty string here, string-typed
-// options where the empty string is a valid value can cause problems as follows:
-// * If their default is not the empty string, a user can't set it to the
-//   empty string with SET.
-// * Even if their default is the empty string, they may be set to something
-//   else via process defaults or resource pool defaults, and the user
-//   may not be able to override them back to the empty string.
-struct TQueryOptions {
-  1: optional bool abort_on_error = 0
-  2: optional i32 max_errors = 100
-  3: optional bool disable_codegen = 0
-  4: optional i32 batch_size = 0
-  5: optional i32 num_nodes = NUM_NODES_ALL
-  6: optional i64 max_scan_range_length = 0
-  7: optional i32 num_scanner_threads = 0
-  11: optional string debug_action = ""
-  12: optional i64 mem_limit = 0
-  14: optional CatalogObjects.TCompressionCodec compression_codec
-  15: optional i32 hbase_caching = 0
-  16: optional bool hbase_cache_blocks = 0
-  17: optional i64 parquet_file_size = 0
-  18: optional Types.TExplainLevel explain_level = 1
-  19: optional bool sync_ddl = 0
-
-  // Request pool this request should be submitted to. If not set
-  // the pool is determined based on the user.
-  20: optional string request_pool
-
-  // test hook to disable topn on the outermost select block.
-  24: optional bool disable_outermost_topn = 0
-
-  // Time, in s, before a query will be timed out if it is inactive. May not exceed
-  // --idle_query_timeout if that flag > 0. If 0, falls back to --idle_query_timeout.
-  26: optional i32 query_timeout_s = 0
-
-  // test hook to cap max memory for spilling operators (to force them to spill).
-  27: optional i64 buffer_pool_limit
-
-  // If true, transforms all count(distinct) aggregations into NDV()
-  28: optional bool appx_count_distinct = 0
-
-  // If true, allows Impala to internally disable spilling for potentially
-  // disastrous query plans. Impala will excercise this option if a query
-  // has no plan hints, and at least one table is missing relevant stats.
-  29: optional bool disable_unsafe_spills = 0
-
-  // If the number of rows that are processed for a single query is below the
-  // threshold, it will be executed on the coordinator only with codegen disabled
-  31: optional i32 exec_single_node_rows_threshold = 100
-
-  // If true, use the table's metadata to produce the partition columns instead of table
-  // scans whenever possible. This option is opt-in by default as this optimization may
-  // produce different results than the scan based approach in some edge cases.
-  32: optional bool optimize_partition_key_scans = 0
-
-  // Specify the prefered locality level of replicas during scan scheduling.
-  // Replicas with an equal or better locality will be preferred.
-  33: optional PlanNodes.TReplicaPreference replica_preference =
-      PlanNodes.TReplicaPreference.CACHE_LOCAL
-
-  // Configure whether scan ranges with local replicas will be assigned by starting from
-  // the same replica for every query or by starting with a new, pseudo-random replica for
-  // subsequent queries. The default is to start with the same replica for every query.
-  34: optional bool schedule_random_replica = 0
-
-  // If true, the planner will not generate plans with streaming preaggregations.
-  36: optional bool disable_streaming_preaggregations = 0
-
-  // If true, runtime filter propagation is enabled
-  37: optional Types.TRuntimeFilterMode runtime_filter_mode = 2
-
-  // Size in bytes of Bloom Filters used for runtime filters. Actual size of filter will
-  // be rounded up to the nearest power of two.
-  38: optional i32 runtime_bloom_filter_size = 1048576
-
-  // Time in ms to wait until runtime filters are delivered. If 0, the default defined
-  // by the startup flag of the same name is used.
-  39: optional i32 runtime_filter_wait_time_ms = 0
-
-  // If true, per-row runtime filtering is disabled
-  40: optional bool disable_row_runtime_filtering = false
-
-  // Maximum number of bloom runtime filters allowed per query
-  41: optional i32 max_num_runtime_filters = 10
-
-  // If true, use UTF-8 annotation for string columns. Note that char and varchar columns
-  // always use the annotation.
-  //
-  // This is disabled by default in order to preserve the existing behavior of legacy
-  // workloads. In addition, Impala strings are not necessarily UTF8-encoded.
-  42: optional bool parquet_annotate_strings_utf8 = false
-
-  // Determines how to resolve Parquet files' schemas in the absence of field IDs (which
-  // is always, since fields IDs are NYI). Valid values are "position" (default) and
-  // "name".
-  43: optional TParquetFallbackSchemaResolution parquet_fallback_schema_resolution = 0
-
-  // Multi-threaded execution: degree of parallelism (= number of active threads) per
-  // query per backend.
-  // > 0: multi-threaded execution mode, with given dop
-  // 0: single-threaded execution mode
-  // unset: may be set automatically to > 0 in createExecRequest(), otherwise same as 0
-  44: optional i32 mt_dop
-
-  // If true, INSERT writes to S3 go directly to their final location rather than being
-  // copied there by the coordinator. We cannot do this for INSERT OVERWRITES because for
-  // those queries, the coordinator deletes all files in the final location before copying
-  // the files there.
-  45: optional bool s3_skip_insert_staging = true
-
-  // Minimum runtime bloom filter size, in bytes
-  46: optional i32 runtime_filter_min_size = 1048576
-
-  // Maximum runtime bloom filter size, in bytes
-  47: optional i32 runtime_filter_max_size = 16777216
-
-  // Prefetching behavior during hash tables' building and probing.
-  48: optional Types.TPrefetchMode prefetch_mode = Types.TPrefetchMode.HT_BUCKET
-
-  // Additional strict handling of invalid data parsing and type conversions.
-  49: optional bool strict_mode = false
-
-  // A limit on the amount of scratch directory space that can be used;
-  50: optional i64 scratch_limit = -1
-
-  // Indicates whether the FE should rewrite Exprs for optimization purposes.
-  // It's sometimes useful to disable rewrites for testing, e.g., expr-test.cc.
-  51: optional bool enable_expr_rewrites = true
-
-  // Indicates whether to use the new decimal semantics.
-  52: optional bool decimal_v2 = true
-
-  // Indicates whether to use dictionary filtering for Parquet files
-  53: optional bool parquet_dictionary_filtering = true
-
-  // Policy for resolving nested array fields in Parquet files.
-  54: optional TParquetArrayResolution parquet_array_resolution =
-    TParquetArrayResolution.THREE_LEVEL
-
-  // Indicates whether to read statistics from Parquet files and use them during query
-  // processing. This includes skipping data based on the statistics and computing query
-  // results like "select min()".
-  55: optional bool parquet_read_statistics = true
-
-  // Join distribution mode that is used when the join inputs have an unknown
-  // cardinality, e.g., because of missing table statistics.
-  56: optional TJoinDistributionMode default_join_distribution_mode =
-    TJoinDistributionMode.BROADCAST
-
-  // If the number of rows processed per node is below the threshold codegen will be
-  // automatically disabled by the planner.
-  57: optional i32 disable_codegen_rows_threshold = 50000
-
-  // The default spillable buffer size in bytes, which may be overridden by the planner.
-  // Defaults to 2MB.
-  58: optional i64 default_spillable_buffer_size = 2097152;
-
-  // The minimum spillable buffer to use. The planner will not choose a size smaller than
-  // this. Defaults to 64KB.
-  59: optional i64 min_spillable_buffer_size = 65536;
-
-  // The maximum size of row that the query will reserve memory to process. Processing
-  // rows larger than this may result in a query failure. Defaults to 512KB, e.g.
-  // enough for a row with 15 32KB strings or many smaller columns.
-  //
-  // Different operators handle this option in different ways. E.g. some simply increase
-  // the size of all their buffers to fit this row size, whereas others may use more
-  // sophisticated strategies - e.g. reserving a small number of buffers large enough to
-  // fit maximum-sized rows.
-  60: optional i64 max_row_size = 524288;
-
-  // The time, in seconds, that a session may be idle for before it is closed (and all
-  // running queries cancelled) by Impala. If 0, idle sessions never expire.
-  // The default session timeout is set by the command line flag of the same name.
-  61: optional i32 idle_session_timeout;
-
-  // Minimum number of bytes that will be scanned in COMPUTE STATS TABLESAMPLE,
-  // regardless of the user-supplied sampling percent. Default value: 1GB
-  62: optional i64 compute_stats_min_sample_size = 1073741824;
-
-  // Time limit, in s, before a query will be timed out after it starts executing. Does
-  // not include time spent in planning, scheduling or admission control. A value of 0
-  // means no time limit.
-  63: optional i32 exec_time_limit_s = 0;
-
-  // When a query has both grouping and distinct exprs, impala can optionally include the
-  // distinct exprs in the hash exchange of the first aggregation phase to spread the data
-  // among more nodes. However, this plan requires another hash exchange on the grouping
-  // exprs in the second phase which is not required when omitting the distinct exprs in
-  // the first phase. Shuffling by both is better if the grouping exprs have low NDVs.
-  64: optional bool shuffle_distinct_exprs = true;
-
-  // See comment in ImpalaService.thrift.
-  65: optional i64 max_mem_estimate_for_admission = 0;
-
-  // See comment in ImpalaService.thrift.
-  // The default values is set fairly high based on empirical data - queries with up to
-  // this number of reserved threads have run successfully as part of production
-  // workloads but with very degraded performance.
-  66: optional i32 thread_reservation_limit = 3000;
-
-  // See comment in ImpalaService.thrift.
-  67: optional i32 thread_reservation_aggregate_limit = 0;
-
-  // See comment in ImpalaService.thrift.
-  68: optional TKuduReadMode kudu_read_mode = TKuduReadMode.DEFAULT;
-
-  // Allow reading of erasure coded files in HDFS.
-  69: optional bool allow_erasure_coded_files = false;
-
-  // See comment in ImpalaService.thrift.
-  70: optional string timezone = ""
-
-  // See comment in ImpalaService.thrift.
-  71: optional i64 scan_bytes_limit = 0;
-
-  // See comment in ImpalaService.thrift.
-  72: optional i64 cpu_limit_s = 0;
-
-  // See comment in ImpalaService.thrift
-  // The default value is set to 512MB based on empirical data
-  73: optional i64 topn_bytes_limit = 536870912;
-
-  // See comment in ImpalaService.thrift
-  74: optional string client_identifier;
-
-  75: optional double resource_trace_ratio = 0;
-
-  // See comment in ImpalaService.thrift.
-  // The default value is set to 3 as this is the default value of HDFS replicas.
-  76: optional i32 num_remote_executor_candidates = 3;
-
-  // See comment in ImpalaService.thrift.
-  77: optional i64 num_rows_produced_limit = 0;
-
-  // See comment in ImpalaService.thrift
-  78: optional bool planner_testcase_mode = false;
-
-  // See comment in ImpalaService.thrift.
-  79: optional CatalogObjects.THdfsFileFormat default_file_format =
-      CatalogObjects.THdfsFileFormat.TEXT;
-
-  // See comment in ImpalaService.thrift.
-  80: optional TParquetTimestampType parquet_timestamp_type =
-      TParquetTimestampType.INT96_NANOS;
-
-  // See comment in ImpalaService.thrift.
-  81: optional bool parquet_read_page_index = true;
-
-  // See comment in ImpalaService.thrift.
-  82: optional bool parquet_write_page_index = true;
-
-  // See comment in ImpalaService.thrift.
-  83: optional i32 parquet_page_row_count_limit;
-
-  // Disable the attempt to compute an estimated number of rows in an
-  // hdfs table.
-  84: optional bool disable_hdfs_num_rows_estimate = false;
-
-  // See comment in ImpalaService.thrift.
-  85: optional string default_hints_insert_statement;
-
-  // See comment in ImpalaService.thrift
-  86: optional bool spool_query_results = true;
-
-  // See comment in ImpalaService.thrift
-  87: optional TTransactionalType default_transactional_type = TTransactionalType.NONE;
-
-  // See comment in ImpalaService.thrift.
-  // The default of 250,000 is set to a high value to avoid impacting existing users, but
-  // testing indicates a statement with this number of expressions can run.
-  88: optional i32 statement_expression_limit = 250000
-
-  // See comment in ImpalaService.thrift
-  // The default is set to 16MB. It is likely that a statement of this size would exceed
-  // the statement expression limit. Setting a limit on the total statement size avoids
-  // the cost of parsing and analyzing the statement, which is required to enforce the
-  // statement expression limit.
-  89: optional i32 max_statement_length_bytes = 16777216
-
-  // If true, skip using the data cache for this query session.
-  90: optional bool disable_data_cache = false;
-
-  // See comment in ImpalaService.thrift
-  91: optional i64 max_result_spooling_mem = 104857600;
-
-  // See comment in ImpalaService.thrift
-  92: optional i64 max_spilled_result_spooling_mem = 1073741824;
-
-  // See comment in ImpalaService.thrift
-  93: optional bool disable_hbase_num_rows_estimate = false;
-
-  // See comment in ImpalaService.thrift
-  94: optional i64 fetch_rows_timeout_ms = 10000;
-
-  // For testing purposes
-  95: optional string now_string = "";
-
-  // See comment in ImpalaService.thrift
-  96: optional i64 parquet_object_store_split_size = 268435456;
-
-  // See comment in ImpalaService.thrift
-  97: optional i64 mem_limit_executors = 0;
-
-  // See comment in ImpalaService.thrift
-  // The default value is set to 32 GB
-  98: optional i64 broadcast_bytes_limit = 34359738368;
-
-  // See comment in ImpalaService.thrift
-  99: optional i64 preagg_bytes_limit = -1;
-
-  // See comment in ImpalaService.thrift
-  100: optional bool enable_cnf_rewrites = true;
-
-  // See comment in ImpalaService.thrift
-  101: optional i32 max_cnf_exprs = 200;
-
-  // See comment in ImpalaService.thrift
-  102: optional i64 kudu_snapshot_read_timestamp_micros = 0;
-
-  // See comment in ImpalaService.thrift
-  103: optional bool retry_failed_queries = false;
-
-  // See comment in ImpalaService.thrift
-  104: optional PlanNodes.TEnabledRuntimeFilterTypes enabled_runtime_filter_types =
-      PlanNodes.TEnabledRuntimeFilterTypes.ALL;
-
-  // See comment in ImpalaService.thrift
-  105: optional bool async_codegen = false;
-
-  // See comment in ImpalaService.thrift
-  106: optional bool enable_distinct_semi_join_optimization = true;
-
-  // See comment in ImpalaService.thrift
-  107: optional i64 sort_run_bytes_limit = -1;
-
-  // See comment in ImpalaService.thrift
-  108: optional i32 max_fs_writers = 0;
-
-  // See comment in ImpalaService.thrift
-  109: optional bool refresh_updated_hms_partitions = false;
-
-  // See comment in ImpalaService.thrift
-  110: optional bool spool_all_results_for_retries = true;
-
-  // See comment in ImpalaService.thrift
-  111: optional double runtime_filter_error_rate;
-
-  // See comment in ImpalaService.thrift
-  112: optional bool use_local_tz_for_unix_timestamp_conversions = false;
-
-  // See comment in ImpalaService.thrift
-  113: optional bool convert_legacy_hive_parquet_utc_timestamps = false;
-
-  // See comment in ImpalaService.thrift
-  114: optional bool enable_outer_join_to_inner_transformation = false;
-
-  // Initialized with -1 to indicate it is unspecified.
-  // See comment in ImpalaService.thrift
-  115: optional i64 targeted_kudu_scan_range_length = -1;
-
-  // See comment in ImpalaService.thrift
-  116: optional double report_skew_limit = 1.0;
-
-  // See comment in ImpalaService.thrift
-  117: optional bool optimize_simple_limit = false;
-
-  // See comment in ImpalaService.thrift
-  118: optional bool use_dop_for_costing = true;
-
-  // See comment in ImpalaService.thrift
-  119: optional double broadcast_to_partition_factor = 1.0;
-
-  // See comment in ImpalaService.thrift
-  120: optional i64 join_rows_produced_limit = 0;
-
-  // See comment in ImpalaService.thrift
-  121: optional bool utf8_mode = false;
-
-  // See comment in ImpalaService.thrift
-  122: optional i64 analytic_rank_pushdown_threshold = 1000;
-
-  // See comment in ImpalaService.thrift
-  123: optional double minmax_filter_threshold = 0.0;
-
-  // See comment in ImpalaService.thrift
-  124: optional PlanNodes.TMinmaxFilteringLevel minmax_filtering_level =
-      PlanNodes.TMinmaxFilteringLevel.ROW_GROUP;
-}
-
-// Impala currently has two types of sessions: Beeswax and HiveServer2
-enum TSessionType {
-  BEESWAX = 0
-  HIVESERVER2 = 1
-}
-
-// Per-client session state
-struct TSessionState {
-  // A unique identifier for this session
-  3: required Types.TUniqueId session_id
-
-  // Session Type (Beeswax or HiveServer2)
-  5: required TSessionType session_type
-
-  // The default database for the session
-  1: required string database
-
-  // The user to whom this session belongs
-  2: required string connected_user
-
-  // If set, the user we are delegating for the current session
-  6: optional string delegated_user;
-
-  // Client network address
-  4: required Types.TNetworkAddress network_address
-
-  // If set, the latest Kudu timestamp observed within this session.
-  7: optional i64 kudu_latest_observed_ts;
-}
-
-// Client request including stmt to execute and query options.
-struct TClientRequest {
-  // SQL stmt to be executed
-  1: required string stmt
-
-  // query options
-  2: required TQueryOptions query_options
-
-  // Redacted SQL stmt
-  3: optional string redacted_stmt
-}
-
 // Debug options: perform some action in a particular phase of a particular node
 // TODO: find a better name
 struct TDebugOptions {
@@ -546,128 +51,6 @@ struct TDebugOptions {
   4: optional string action_param
 }
 
-// Context of this query, including the client request, session state and
-// global query parameters needed for consistent expr evaluation (e.g., now()).
-//
-// TODO: Separate into FE/BE initialized vars.
-struct TQueryCtx {
-  // Client request containing stmt to execute and query options.
-  1: required TClientRequest client_request
-
-  // A globally unique id assigned to the entire query in the BE.
-  // The bottom 4 bytes are 0 (for details see be/src/util/uid-util.h).
-  2: required Types.TUniqueId query_id
-
-  // Session state including user.
-  3: required TSessionState session
-
-  // String containing a timestamp (in local timezone) set as the query submission time.
-  4: required string now_string
-
-  // Process ID of the impalad to which the user is connected.
-  5: required i32 pid
-
-  // The coordinator's hostname.
-  // TODO: determine whether we can get this somehow via the Thrift rpc mechanism.
-  6: optional string coord_hostname
-
-  // The initiating coordinator's address of its KRPC based ImpalaInternalService.
-  7: optional Types.TNetworkAddress coord_ip_address
-
-  // List of tables missing relevant table and/or column stats. Used for
-  // populating query-profile fields consumed by CM as well as warning messages.
-  8: optional list<CatalogObjects.TTableName> tables_missing_stats
-
-  // Internal flag to disable spilling. Used as a guard against potentially
-  // disastrous query plans. The rationale is that cancelling queries, e.g.,
-  // with a huge join build is preferable over spilling "forever".
-  9: optional bool disable_spilling
-
-  // Set if this is a child query (e.g. a child of a COMPUTE STATS request)
-  10: optional Types.TUniqueId parent_query_id
-
-  // List of tables suspected to have corrupt stats
-  11: optional list<CatalogObjects.TTableName> tables_with_corrupt_stats
-
-  // The snapshot timestamp as of which to execute the query
-  // When the backing storage engine supports snapshot timestamps (such as Kudu) this
-  // allows to select a snapshot timestamp on which to perform the scan, making sure that
-  // results returned from multiple scan nodes are consistent.
-  // This defaults to -1 when no timestamp is specified.
-  12: optional i64 snapshot_timestamp = -1;
-
-  // Optional for frontend tests.
-  // The descriptor table can be included in one of two forms:
-  //  - TDescriptorTable - standard Thrift object
-  //  - TDescriptorTableSerialized - binary blob with a serialized TDescriptorTable
-  // Normal end-to-end query execution uses the serialized form to avoid copying a large
-  // number of objects when sending RPCs. For this case, desc_tbl_serialized is set and
-  // desc_tbl_testonly is not set. See IMPALA-8732.
-  // Frontend tests cannot use the serialized form, because some frontend tests deal with
-  // incomplete structures (e.g. THdfsTable without the required nullPartitionKeyValue
-  // field) that cannot be serialized. In this case, desc_tbl_testonly is set and
-  // desc_tbl_serialized is not set. See Frontend.PlanCtx.serializeDescTbl_.
-  13: optional Descriptors.TDescriptorTable desc_tbl_testonly
-  24: optional Descriptors.TDescriptorTableSerialized desc_tbl_serialized
-
-  // Milliseconds since UNIX epoch at the start of query execution.
-  14: required i64 start_unix_millis
-
-  // Hint to disable codegen. Set by planner for single-node optimization or by the
-  // backend in NativeEvalExprsWithoutRow() in FESupport. This flag is only advisory to
-  // avoid the overhead of codegen and can be ignored if codegen is needed functionally.
-  15: optional bool disable_codegen_hint = false;
-
-  // List of tables with scan ranges that map to blocks with missing disk IDs.
-  16: optional list<CatalogObjects.TTableName> tables_missing_diskids
-
-  // The resolved admission control pool to which this request will be submitted. May be
-  // unset for statements that aren't subjected to admission control (e.g. USE, SET).
-  17: optional string request_pool
-
-  // String containing a timestamp (in UTC) set as the query submission time. It
-  // represents the same point in time as now_string
-  18: required string utc_timestamp_string
-
-  // String containing name of the local timezone.
-  // It is guaranteed to be a valid timezone on the coordinator (but not necessarily on
-  // the executor, since in theory the executor could have a different timezone db).
-  // TODO(Csaba): adding timezone as a query option made this property redundant. It
-  //   still has an effect if TimezoneDatabase::LocalZoneName() cannot find the
-  //   system's local timezone and falls back to UTC. This logic will be removed in
-  //   IMPALA-7359, which will make this member completely obsolete.
-  19: required string local_time_zone
-
-  // Disables the code that estimates HBase scan cardinality from key ranges.
-  // When disabled, scan cardinality is estimated from HMS table row count
-  // stats and key column predicate selectivity. Generally only disabled
-  // for testing.
-  20: optional bool disable_hbase_num_rows_estimate = false;
-
-  // Flag to enable tracing of resource usage consumption for all fragment instances of a
-  // query. Set in ImpalaServer::PrepareQueryContext().
-  21: required bool trace_resource_usage = false
-
-  // Taken from the flags of the same name. The coordinator uses these to decide how long
-  // to wait for a report before cancelling a backend, so we want to ensure that the
-  // coordinator and executors for a given query always agree this value.
-  22: optional i32 status_report_interval_ms
-  23: optional i32 status_report_max_retry_s
-
-  // Stores the transaction id if the query is transactional.
-  25: optional i64 transaction_id
-
-  // If mt_dop was overridden by admission control's max mt_dop setting, then this
-  // is set to the original value. If mt_dop was not overridden, then this is not set.
-  26: optional i32 overridden_mt_dop_value
-
-  // The initiating coordinator's backend_id.
-  27: optional Types.TUniqueId coord_backend_id
-
-  // True if the new runtime profile format added by IMPALA-9382 should be generated
-  // by this query.
-  28: optional bool gen_aggregated_profile
-}
 
 // Descriptor that indicates that a runtime filter is produced by a plan node.
 struct TRuntimeFilterSource {
diff --git a/common/thrift/ImpalaService.thrift b/common/thrift/ImpalaService.thrift
index 0a48f80..c403055 100644
--- a/common/thrift/ImpalaService.thrift
+++ b/common/thrift/ImpalaService.thrift
@@ -24,6 +24,7 @@ include "Types.thrift"
 include "beeswax.thrift"
 include "TCLIService.thrift"
 include "RuntimeProfile.thrift"
+include "Frontend.thrift"
 
 // ImpalaService accepts query execution options through beeswax.Query.configuration in
 // key:value form. For example, the list of strings could be:
@@ -696,6 +697,9 @@ struct TPingImpalaHS2ServiceResp {
 
   // The Impalad's webserver address.
   3: optional string webserver_address
+
+  // The Impalad's local monotonic time
+  4: optional i64 timestamp
 }
 
 // CloseImpalaOperation()
@@ -806,6 +810,20 @@ struct TGetRuntimeProfileResp {
   5: optional list<RuntimeProfile.TRuntimeProfileTree> failed_thrift_profiles
 }
 
+// ExecutePlannedStatement()
+//
+// Execute a statement where the ExecRequest has been externally supplied.
+// The returned OperationHandle can be used to check on the
+// status of the plan, and to fetch results once the
+// plan has finished executing.
+struct TExecutePlannedStatementReq {
+  1: required TCLIService.TExecuteStatementReq statementReq
+
+  // The plan to be executed
+  2: required Frontend.TExecRequest plan
+}
+
+
 service ImpalaHiveServer2Service extends TCLIService.TCLIService {
   // Returns the exec summary for the given query. The exec summary is only valid for
   // queries that execute with Impala's backend, i.e. QUERY, DML and COMPUTE_STATS
@@ -822,4 +840,7 @@ service ImpalaHiveServer2Service extends TCLIService.TCLIService {
 
   // Same as HS2 CloseOperation but can return additional information.
   TCloseImpalaOperationResp CloseImpalaOperation(1:TCloseImpalaOperationReq req);
+  // Execute statement with supplied ExecRequest
+  TCLIService.TExecuteStatementResp ExecutePlannedStatement(
+      1:TExecutePlannedStatementReq req);
 }
diff --git a/common/thrift/ImpalaInternalService.thrift b/common/thrift/Query.thrift
similarity index 79%
copy from common/thrift/ImpalaInternalService.thrift
copy to common/thrift/Query.thrift
index 668d183..31c0e13 100644
--- a/common/thrift/ImpalaInternalService.thrift
+++ b/common/thrift/Query.thrift
@@ -15,32 +15,16 @@
 // specific language governing permissions and limitations
 // under the License.
 
-//
-// This file contains the details of the protocol between coordinators and backends.
-
 namespace cpp impala
 namespace java org.apache.impala.thrift
 
-include "Status.thrift"
-include "ErrorCodes.thrift"
 include "Types.thrift"
-include "Exprs.thrift"
-include "CatalogObjects.thrift"
-include "Descriptors.thrift"
 include "PlanNodes.thrift"
 include "Planner.thrift"
-include "DataSinks.thrift"
+include "Descriptors.thrift"
 include "Results.thrift"
-include "RuntimeProfile.thrift"
-include "ImpalaService.thrift"
-include "Data.thrift"
-
-// constants for TQueryOptions.num_nodes
-const i32 NUM_NODES_ALL = 0
-const i32 NUM_NODES_ALL_RACKS = -1
-
-// constants for TPlanNodeId
-const i32 INVALID_PLAN_NODE_ID = -1
+include "CatalogObjects.thrift"
+include "LineageGraph.thrift"
 
 enum TParquetFallbackSchemaResolution {
   POSITION = 0
@@ -49,17 +33,10 @@ enum TParquetFallbackSchemaResolution {
   FIELD_ID = 2
 }
 
-// The order of the enum values needs to be kept in sync with
-// ParquetMetadataUtils::ORDERED_ARRAY_ENCODINGS in parquet-metadata-utils.cc.
-enum TParquetArrayResolution {
-  THREE_LEVEL = 0
-  TWO_LEVEL = 1
-  TWO_LEVEL_THEN_THREE_LEVEL = 2
-}
-
-enum TJoinDistributionMode {
-  BROADCAST = 0
-  SHUFFLE = 1
+// A table's Hive ACID type.
+enum TTransactionalType {
+  NONE,
+  INSERT_ONLY
 }
 
 // Consistency level options for Kudu scans.
@@ -69,6 +46,19 @@ enum TKuduReadMode {
   READ_AT_SNAPSHOT = 2
 }
 
+enum TJoinDistributionMode {
+  BROADCAST = 0
+  SHUFFLE = 1
+}
+
+// The order of the enum values needs to be kept in sync with
+// ParquetMetadataUtils::ORDERED_ARRAY_ENCODINGS in parquet-metadata-utils.cc.
+enum TParquetArrayResolution {
+  THREE_LEVEL = 0
+  TWO_LEVEL = 1
+  TWO_LEVEL_THEN_THREE_LEVEL = 2
+}
+
 // Physical type and unit used when writing timestamps in Parquet.
 enum TParquetTimestampType {
   INT96_NANOS,
@@ -77,11 +67,9 @@ enum TParquetTimestampType {
   INT64_NANOS
 }
 
-// A table's Hive ACID type.
-enum TTransactionalType {
-  NONE,
-  INSERT_ONLY
-}
+// constants for TQueryOptions.num_nodes
+const i32 NUM_NODES_ALL = 0
+const i32 NUM_NODES_ALL_RACKS = -1
 
 // Query options that correspond to ImpalaService.ImpalaQueryOptions, with their
 // respective defaults. Query options can be set in the following ways:
@@ -498,6 +486,18 @@ enum TSessionType {
   HIVESERVER2 = 1
 }
 
+// Client request including stmt to execute and query options.
+struct TClientRequest {
+  // SQL stmt to be executed
+  1: required string stmt
+
+  // query options
+  2: required TQueryOptions query_options
+
+  // Redacted SQL stmt
+  3: optional string redacted_stmt
+}
+
 // Per-client session state
 struct TSessionState {
   // A unique identifier for this session
@@ -522,30 +522,6 @@ struct TSessionState {
   7: optional i64 kudu_latest_observed_ts;
 }
 
-// Client request including stmt to execute and query options.
-struct TClientRequest {
-  // SQL stmt to be executed
-  1: required string stmt
-
-  // query options
-  2: required TQueryOptions query_options
-
-  // Redacted SQL stmt
-  3: optional string redacted_stmt
-}
-
-// Debug options: perform some action in a particular phase of a particular node
-// TODO: find a better name
-struct TDebugOptions {
-  // The plan node that this action should be applied to. If -1 it is applied to all plan
-  // nodes.
-  1: optional Types.TPlanNodeId node_id
-  2: optional PlanNodes.TExecNodePhase phase
-  3: optional PlanNodes.TDebugAction action
-  // Optional parameter that goes along with the action.
-  4: optional string action_param
-}
-
 // Context of this query, including the client request, session state and
 // global query parameters needed for consistent expr evaluation (e.g., now()).
 //
@@ -608,7 +584,6 @@ struct TQueryCtx {
   // field) that cannot be serialized. In this case, desc_tbl_testonly is set and
   // desc_tbl_serialized is not set. See Frontend.PlanCtx.serializeDescTbl_.
   13: optional Descriptors.TDescriptorTable desc_tbl_testonly
-  24: optional Descriptors.TDescriptorTableSerialized desc_tbl_serialized
 
   // Milliseconds since UNIX epoch at the start of query execution.
   14: required i64 start_unix_millis
@@ -652,8 +627,11 @@ struct TQueryCtx {
   // to wait for a report before cancelling a backend, so we want to ensure that the
   // coordinator and executors for a given query always agree this value.
   22: optional i32 status_report_interval_ms
+
   23: optional i32 status_report_max_retry_s
 
+  24: optional Descriptors.TDescriptorTableSerialized desc_tbl_serialized
+
   // Stores the transaction id if the query is transactional.
   25: optional i64 transaction_id
 
@@ -669,157 +647,98 @@ struct TQueryCtx {
   28: optional bool gen_aggregated_profile
 }
 
-// Descriptor that indicates that a runtime filter is produced by a plan node.
-struct TRuntimeFilterSource {
-  1: required Types.TPlanNodeId src_node_id
-  2: required i32 filter_id
-}
 
-// The Thrift portion of the execution parameters of a single fragment instance. Every
-// fragment instance will also have a corresponding PlanFragmentInstanceCtxPB with the
-// same fragment_idx.
-// TODO: convert the rest of this struct to protobuf
-struct TPlanFragmentInstanceCtx {
-  // TPlanFragment.idx
-  1: required Types.TFragmentIdx fragment_idx
-
-  // The globally unique fragment instance id.
-  // Format: query id + query-wide fragment instance index
-  // The query-wide fragment instance index enumerates all fragment instances of a
-  // particular query. It starts at 0, so that the query id and the id of the first
-  // fragment instance are identical.
-  // If there is a coordinator instance, it is the first one, with index 0.
-  // Range: [0, TExecQueryFInstancesParams.fragment_instance_ctxs.size()-1]
-  2: required Types.TUniqueId fragment_instance_id
-
-  // Index of this fragment instance across all instances of its parent fragment
-  // (TPlanFragment with idx = TPlanFragmentInstanceCtx.fragment_idx).
-  // Range: [0, <# of instances of parent fragment> - 1]
-  3: required i32 per_fragment_instance_idx
-
-  // Number of senders for ExchangeNodes contained in TPlanFragment.plan_tree;
-  // needed to create a DataStreamRecvr
-  // TODO for per-query exec rpc: move these to PlanFragmentCtxPB
-  5: required map<Types.TPlanNodeId, i32> per_exch_num_senders
-
-  // Id of this instance in its role as a sender.
-  6: optional i32 sender_id
-
-  7: optional TDebugOptions debug_options
-
-  // List of runtime filters produced by nodes in the finstance.
-  8: optional list<TRuntimeFilterSource> filters_produced
-
-  // If this is a join build fragment, the number of fragment instances that consume the
-  // join build. -1 = invalid.
-  10: optional i32 num_join_build_outputs
-
-  // Number of backends executing the same fragment plan. Can be used by executors to do
-  // some estimations.
-  11: optional i32 num_backends;
+// Execution parameters for a single plan; component of TQueryExecRequest
+struct TPlanExecInfo {
+  // fragments[i] may consume the output of fragments[j > i];
+  // fragments[0] is the root fragment and also the coordinator fragment, if
+  // it is unpartitioned.
+  1: required list<Planner.TPlanFragment> fragments
+
+  // A map from scan node ids to a scan range specification.
+  // The node ids refer to scan nodes in fragments[].plan
+  2: optional map<Types.TPlanNodeId, Planner.TScanRangeSpec>
+      per_node_scan_ranges
 }
 
+// Metadata required to finalize a query - that is, to clean up after the query is done.
+// Only relevant for INSERT queries.
+struct TFinalizeParams {
+  // True if the INSERT query was OVERWRITE, rather than INTO
+  1: required bool is_overwrite
 
-// Service Protocol Details
+  // The base directory in hdfs of the table targeted by this INSERT
+  2: required string hdfs_base_dir
 
-enum ImpalaInternalServiceVersion {
-  V1 = 0
-}
+  // The target table name
+  3: required string table_name
 
-// The following contains the per-rpc structs for the parameters and the result.
+  // The target table database
+  4: required string table_db
 
-// Contains info about plan fragment execution needed for the ExecQueryFInstances rpc.
-// Rather than fully coverting this to protobuf, which would be a large change, for now we
-// serialize it ourselves and send it with ExecQueryFInstances as a sidecar.
-// TODO: investigate if it's worth converting this fully to protobuf
-struct TExecPlanFragmentInfo {
-  1: optional list<Planner.TPlanFragment> fragments
+  // The full path in HDFS of a directory under which temporary files may be written
+  // during an INSERT. For a query with id a:b, files are written to <staging_dir>/.a_b/,
+  // and that entire directory is removed after the INSERT completes.
+  5: optional string staging_dir
 
-  // the order corresponds to the order of fragments in 'fragments'
-  2: optional list<TPlanFragmentInstanceCtx> fragment_instance_ctxs
-}
+  // Identifier for the target table in the query-wide descriptor table (see
+  // TDescriptorTable and TTableDescriptor).
+  6: optional i64 table_id;
 
-// Parameters for RequestPoolService.resolveRequestPool()
-// TODO: why is this here?
-struct TResolveRequestPoolParams {
-  // User to resolve to a pool via the allocation placement policy and
-  // authorize for pool access.
-  1: required string user
+  // Stores the ACID transaction id of the target table for transactional INSERTs.
+  7: optional i64 transaction_id;
 
-  // Pool name specified by the user. The allocation placement policy may
-  // return a different pool.
-  2: required string requested_pool
+  // Stores the ACID write id of the target table for transactional INSERTs.
+  8: optional i64 write_id;
+
+  // Stores the Iceberg spec id of the partition spec used for this INSERT.
+  9: optional i32 spec_id;
 }
 
-// Returned by RequestPoolService.resolveRequestPool()
-struct TResolveRequestPoolResult {
-  // Actual pool to use, as determined by the pool allocation policy. Not set
-  // if no pool was resolved.
-  1: optional string resolved_pool
+// Result of call to ImpalaPlanService/JniFrontend.CreateQueryRequest()
+struct TQueryExecRequest {
+  // exec info for all plans; the first one materializes the query result
+  1: optional list<TPlanExecInfo> plan_exec_info
 
-  // True if the user has access to submit requests to the resolved_pool. Not set
-  // if no pool was resolved.
-  2: optional bool has_access
+  // Metadata of the query result set (only for select)
+  2: optional Results.TResultSetMetadata result_set_metadata
 
-  3: optional Status.TStatus status
-}
+  // Set if the query needs finalization after it executes
+  3: optional TFinalizeParams finalize_params
 
-// Parameters for RequestPoolService.getPoolConfig()
-// TODO: why is this here?
-struct TPoolConfigParams {
-  // Pool name
-  1: required string pool
-}
+  4: required TQueryCtx query_ctx
 
-// Returned by RequestPoolService.getPoolConfig()
-struct TPoolConfig {
-  // Maximum number of placed requests before incoming requests are queued.
-  // A value of 0 effectively disables the pool. -1 indicates no limit.
-  1: required i64 max_requests
-
-  // Maximum number of queued requests before incoming requests are rejected.
-  // Any non-positive number (<= 0) disables queuing, i.e. requests are rejected instead
-  // of queued.
-  2: required i64 max_queued
-
-  // Maximum memory resources of the pool in bytes.
-  // A value of 0 effectively disables the pool. -1 indicates no limit.
-  3: required i64 max_mem_resources
-
-  // Maximum amount of time (in milliseconds) that a request will wait to be admitted
-  // before timing out. Optional, if not set then the process default (set via gflags) is
-  // used.
-  4: optional i64 queue_timeout_ms;
-
-  // Default query options that are applied to requests mapped to this pool.
-  5: required string default_query_options;
-
-  // Maximum amount of memory that can be assigned to a query (in bytes).
-  // 0 indicates no limit. If both max_query_mem_limit and min_query_mem_limit are zero
-  // then the admission controller will fall back on old behavior, which is to not set
-  // any backend mem limit if mem_limit is not set in the query options.
-  6: required i64 max_query_mem_limit = 0;
-
-  // Minimum amount of memory that can be assigned to a query (in bytes).
-  // 0 indicates no limit.
-  7: required i64 min_query_mem_limit = 0;
-
-  // If false, the mem_limit query option will not be bounded by the max/min query mem
-  // limits specified for the pool. Default is true.
-  8: required bool clamp_mem_limit_query_option = true;
-
-  // Maximum value for the mt_dop query option. If the mt_dop is set and exceeds this
-  // maximum, the mt_dop setting is reduced to the maximum. If the max_mt_dop is
-  // negative, no limit is enforced.
-  9: required i64 max_mt_dop = -1;
-}
+  // The same as the output of 'explain <query>'
+  5: optional string query_plan
+
+  // The statement type governs when the coordinator can judge a query to be finished.
+  // DML queries are complete after Wait(), SELECTs may not be. Generally matches
+  // the stmt_type of the parent TExecRequest, but in some cases (such as CREATE TABLE
+  // AS SELECT), these may differ.
+  6: required Types.TStmtType stmt_type
+
+  // List of replica hosts.  Used by the host_idx field of TScanRangeLocation.
+  7: required list<Types.TNetworkAddress> host_list
 
-struct TParseDateStringResult {
-  // True iff date string was successfully parsed
-  1: required bool valid
-  // Number of days since 1970-01-01. Used only if 'valid' is true.
-  2: optional i32 days_since_epoch
-  // Canonical date string (formed as 'yyyy-MM-dd'). Used only if 'valid' is true and the
-  // parsed date string was not in a canonical form.
-  3: optional string canonical_date_string
+  // Column lineage graph
+  8: optional LineageGraph.TLineageGraph lineage_graph
+
+  // Estimated per-host peak memory consumption in bytes. Used by admission control.
+  // TODO: Remove when AC doesn't rely on this any more.
+  9: optional i64 per_host_mem_estimate
+
+  // Maximum possible (in the case all fragments are scheduled on all hosts with
+  // max DOP) minimum memory reservation required per host, in bytes.
+  10: optional i64 max_per_host_min_mem_reservation;
+
+  // Maximum possible (in the case all fragments are scheduled on all hosts with
+  // max DOP) required threads per host, i.e. the number of threads that this query
+  // needs to execute successfully. Does not include "optional" threads.
+  11: optional i64 max_per_host_thread_reservation;
+
+  // Estimated coordinator's memory consumption in bytes assuming that the coordinator
+  // fragment will run on a dedicated coordinator. Set by the planner and used by
+  // admission control.
+  12: optional i64 dedicated_coord_mem_estimate;
 }
+
diff --git a/fe/pom.xml b/fe/pom.xml
index 70579e3..e100ff3 100644
--- a/fe/pom.xml
+++ b/fe/pom.xml
@@ -430,6 +430,11 @@ under the License.
         </exclusion>
       </exclusions>
     </dependency>
+    <dependency>
+      <groupId>org.apache.hive</groupId>
+      <artifactId>hive-classification</artifactId>
+      <version>${hive.version}</version>
+    </dependency>
 
     <dependency>
       <groupId>org.apache.hive</groupId>
diff --git a/fe/src/main/java/org/apache/impala/analysis/Analyzer.java b/fe/src/main/java/org/apache/impala/analysis/Analyzer.java
index a4633c8..1432d02 100644
--- a/fe/src/main/java/org/apache/impala/analysis/Analyzer.java
+++ b/fe/src/main/java/org/apache/impala/analysis/Analyzer.java
@@ -1077,7 +1077,7 @@ public class Analyzer {
         TableName tblName = candidateTbls.get(tblNameIdx);
         FeTable tbl = null;
         try {
-          tbl = getTable(tblName.getDb(), tblName.getTbl());
+          tbl = getTable(tblName.getDb(), tblName.getTbl(), /* must_exist */ false);
         } catch (AnalysisException e) {
           // Ignore to allow path resolution to continue.
         }
@@ -2847,11 +2847,14 @@ public class Analyzer {
    * Throws a TableLoadingException if the registered table failed to load.
    * Does not register authorization requests or access events.
    */
-  public FeTable getTable(String dbName, String tableName)
+  public FeTable getTable(String dbName, String tableName, boolean mustExist)
       throws AnalysisException, TableLoadingException {
     TableName tblName = new TableName(dbName, tableName);
     FeTable table = globalState_.stmtTableCache.tables.get(tblName);
     if (table == null) {
+      if (!mustExist) {
+        return null;
+      }
       if (!globalState_.stmtTableCache.dbs.contains(tblName.getDb())) {
         throw new AnalysisException(DB_DOES_NOT_EXIST_ERROR_MSG + tblName.getDb());
       } else {
@@ -2972,7 +2975,7 @@ public class Analyzer {
       }
     }
     // Propagate the AnalysisException if the table/db does not exist.
-    table = getTable(fqTableName.getDb(), fqTableName.getTbl());
+    table = getTable(fqTableName.getDb(), fqTableName.getTbl(), /* must_exist */ true);
     Preconditions.checkNotNull(table);
     if (addAccessEvent) {
       // Add an audit event for this access
diff --git a/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java b/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
index 41a96a0..af578c7 100644
--- a/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
+++ b/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
@@ -280,7 +280,7 @@ public class PrivilegeSpec extends StmtNode {
     try {
       dbName_ = analyzer.getTargetDbName(tableName_);
       Preconditions.checkNotNull(dbName_);
-      table = analyzer.getTable(dbName_, tableName_.getTbl());
+      table = analyzer.getTable(dbName_, tableName_.getTbl(), /* must_exist */ true);
     } catch (TableLoadingException e) {
       throw new AnalysisException(e.getMessage(), e);
     } catch (AnalysisException e) {
diff --git a/fe/src/main/java/org/apache/impala/analysis/ResetMetadataStmt.java b/fe/src/main/java/org/apache/impala/analysis/ResetMetadataStmt.java
index 13dd361..c892a2e 100644
--- a/fe/src/main/java/org/apache/impala/analysis/ResetMetadataStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/ResetMetadataStmt.java
@@ -157,7 +157,8 @@ public class ResetMetadataStmt extends StatementBase {
           if (partitionSpec_ != null) {
             try {
               // Get local table info without reaching out to HMS
-              FeTable table = analyzer.getTable(dbName, tableName_.getTbl());
+              FeTable table = analyzer.getTable(dbName, tableName_.getTbl(),
+                  /* must_exist */ true);
               if (AcidUtils.isTransactionalTable(
                       table.getMetaStoreTable().getParameters())) {
                 throw new AnalysisException("Refreshing a partition is not allowed on " +
diff --git a/fe/src/test/java/org/apache/impala/planner/PlannerTestBase.java b/fe/src/test/java/org/apache/impala/planner/PlannerTestBase.java
index e9dcdae..8472d27 100644
--- a/fe/src/test/java/org/apache/impala/planner/PlannerTestBase.java
+++ b/fe/src/test/java/org/apache/impala/planner/PlannerTestBase.java
@@ -47,6 +47,7 @@ import org.apache.impala.testutil.TestFileParser.TestCase;
 import org.apache.impala.testutil.TestUtils;
 import org.apache.impala.testutil.TestUtils.ResultFilter;
 import org.apache.impala.thrift.ImpalaInternalServiceConstants;
+import org.apache.impala.thrift.QueryConstants;
 import org.apache.impala.thrift.TDescriptorTable;
 import org.apache.impala.thrift.TExecRequest;
 import org.apache.impala.thrift.TExplainLevel;
@@ -492,7 +493,7 @@ public class PlannerTestBase extends FrontendTestBase {
     } else {
       // for distributed and parallel execution we want to run on all available nodes
       queryOptions.setNum_nodes(
-          ImpalaInternalServiceConstants.NUM_NODES_ALL);
+          QueryConstants.NUM_NODES_ALL);
     }
     if (section == Section.PARALLELPLANS
         && (!queryOptions.isSetMt_dop() || queryOptions.getMt_dop() == 0)) {


[impala] 01/08: IMPALA-9218: Add support for locally compiled Hive

Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit a29d06db533e371eb28fc2a4afe8fd2e1803dcad
Author: John Sherman <jf...@cloudera.com>
AuthorDate: Sat Feb 20 17:04:24 2021 +0000

    IMPALA-9218: Add support for locally compiled Hive
    
    - Add HIVE_VERSION_OVERRIDE, HIVE_STORAGE_API_VERSION_OVERRIDE,
      HIVE_METASTORE_THRIFT_DIR_OVERRIDE, HIVE_HOME_OVERRIDE environment
      variable support to impala-config.sh
    - When used together with HIVE_SRC_DIR_OVERRIDE allows a user to
      specify a locally compiled version of Hive for development and the
      minicluster
    - Hive jars are expected to have been installed into the local maven
      repository
    - Currently only version 3 of Hive is supported due to the absence of
      API shims for Hive 4.0
    Example:
      ~/hive $ mvn package install -Pdist -DskipTests
    
    Example configuration:
    export HIVE_VERSION_OVERRIDE=3.1.0-SNAPSHOT
    export HIVE_STORAGE_API_VERSION_OVERRIDE=2.6.0
    export HIVE_HOME_OVERRIDE=\
    ~/hive/packaging/target/apache-hive-3.1.0-SNAPSHOT-bin/apache-hive-3.1.0-SNAPSHOT-bin
    export HIVE_SRC_DIR_OVERRIDE=~/hive
    export HIVE_METASTORE_THRIFT_DIR_OVERRIDE=~/hive/standalone-metastore/src/main/thrift/
    
    Change-Id: I21892c153c445e3a5d93f2bc8f5e0b799929dd34
    Reviewed-on: http://gerrit.cloudera.org:8080/17094
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 README-build.md            | 11 +++++++++++
 bin/bootstrap_toolchain.py |  9 ++++++++-
 bin/impala-config.sh       | 11 ++++++-----
 java/pom.xml               |  2 +-
 4 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/README-build.md b/README-build.md
index d9833df..1659551 100644
--- a/README-build.md
+++ b/README-build.md
@@ -66,3 +66,14 @@ can do so through the environment variables and scripts listed below.
 | HBASE_HOME           | "${CDP_COMPONENTS_HOME}/hbase-${IMPALA_HBASE_VERSION}/" | |
 | THRIFT_HOME          | "${IMPALA_TOOLCHAIN}/thrift-${IMPALA_THRIFT_VERSION}" | |
 
+## Hive Dependency Overrides
+Typically used together to specify a local build of Apache Hive. Care should be taken
+while using these variables since they take precedence over the defaults in
+impala-config.sh, they may cause confusion when switching between branches or versions of
+Apache Impala.
+
+| Environment variable | Description |
+| HIVE_VERSION_OVERRIDE | Used to specify different Hive version from default |
+| HIVE_STORAGE_API_VERSION_OVERRIDE | Used to specify different Hive Storage API version from default |
+| HIVE_METASTORE_THRIFT_DIR_OVERRIDE | Used to specify location of metastore thrift files to use during Thrift compilation |
+| HIVE_HOME_OVERRIDE | Used to specify location of Hive |
diff --git a/bin/bootstrap_toolchain.py b/bin/bootstrap_toolchain.py
index 494b97c..baef199 100755
--- a/bin/bootstrap_toolchain.py
+++ b/bin/bootstrap_toolchain.py
@@ -466,7 +466,14 @@ def get_hadoop_downloads():
                           unpack_directory_tmpl="hive-${version}")
   tez = CdpComponent("tez", archive_basename_tmpl="tez-${version}-minimal",
                      makedir=True)
-  cluster_components.extend([hadoop, hbase, hive, hive_src, tez])
+  use_override_hive = \
+      "HIVE_VERSION_OVERRIDE" in os.environ and os.environ["HIVE_VERSION_OVERRIDE"] != ""
+  # If we are using a locally built Hive we do not have a need to pull hive as a
+  # dependency
+  if use_override_hive:
+    cluster_components.extend([hadoop, hbase, tez])
+  else:
+    cluster_components.extend([hadoop, hbase, hive, hive_src, tez])
   # Ranger is always CDP
   cluster_components.append(CdpComponent("ranger",
                                          archive_basename_tmpl="ranger-${version}-admin"))
diff --git a/bin/impala-config.sh b/bin/impala-config.sh
index d38770d..133851a 100755
--- a/bin/impala-config.sh
+++ b/bin/impala-config.sh
@@ -239,7 +239,7 @@ export IMPALA_HADOOP_URL=${CDP_HADOOP_URL-}
 export HADOOP_HOME="$CDP_COMPONENTS_HOME/hadoop-${IMPALA_HADOOP_VERSION}/"
 export IMPALA_HBASE_VERSION=${CDP_HBASE_VERSION}
 export IMPALA_HBASE_URL=${CDP_HBASE_URL-}
-export IMPALA_HIVE_VERSION=${CDP_HIVE_VERSION}
+export IMPALA_HIVE_VERSION=${HIVE_VERSION_OVERRIDE:-"$CDP_HIVE_VERSION"}
 export IMPALA_HIVE_URL=${CDP_HIVE_URL-}
 export IMPALA_HIVE_SOURCE_URL=${CDP_HIVE_SOURCE_URL-}
 export IMPALA_ICEBERG_VERSION=${CDP_ICEBERG_VERSION}
@@ -251,6 +251,7 @@ export IMPALA_RANGER_VERSION=${CDP_RANGER_VERSION}
 export IMPALA_RANGER_URL=${CDP_RANGER_URL-}
 export IMPALA_TEZ_VERSION=${CDP_TEZ_VERSION}
 export IMPALA_TEZ_URL=${CDP_TEZ_URL-}
+export IMPALA_HIVE_STORAGE_API_VERSION=${HIVE_STORAGE_API_VERSION_OVERRIDE:-"2.3.0.$IMPALA_HIVE_VERSION"}
 
 # Extract the first component of the hive version.
 # Allow overriding of Hive source location in case we want to build Impala without
@@ -362,11 +363,11 @@ export LOCAL_FS="file:${WAREHOUSE_LOCATION_PREFIX}"
 export IMPALA_CLUSTER_NODES_DIR="${IMPALA_CLUSTER_NODES_DIR-$IMPALA_HOME/testdata/cluster/cdh$CDH_MAJOR_VERSION}"
 
 ESCAPED_IMPALA_HOME=$(sed "s/[^0-9a-zA-Z]/_/g" <<< "$IMPALA_HOME")
-export HIVE_HOME="$CDP_COMPONENTS_HOME/apache-hive-${IMPALA_HIVE_VERSION}-bin"
-export HIVE_SRC_DIR=${HIVE_SRC_DIR_OVERRIDE:-"${CDP_COMPONENTS_HOME}/hive-\
-${IMPALA_HIVE_VERSION}"}
+export HIVE_HOME=${HIVE_HOME_OVERRIDE:-"$CDP_COMPONENTS_HOME/apache-hive-${IMPALA_HIVE_VERSION}-bin"}
+export HIVE_SRC_DIR=${HIVE_SRC_DIR_OVERRIDE:-"${CDP_COMPONENTS_HOME}/hive-${IMPALA_HIVE_VERSION}"}
 # Set the path to the hive_metastore.thrift which is used to build thrift code
-export HIVE_METASTORE_THRIFT_DIR=$HIVE_SRC_DIR/standalone-metastore/src/main/thrift
+export HIVE_METASTORE_THRIFT_DIR=${HIVE_METASTORE_THRIFT_DIR_OVERRIDE:-\
+"$HIVE_SRC_DIR/standalone-metastore/src/main/thrift"}
 export TEZ_HOME="$CDP_COMPONENTS_HOME/tez-${IMPALA_TEZ_VERSION}-minimal"
 export HBASE_HOME="$CDP_COMPONENTS_HOME/hbase-${IMPALA_HBASE_VERSION}/"
 # Previously, there were multiple configurations and the "_cdp" included below
diff --git a/java/pom.xml b/java/pom.xml
index bc936fd..6fb10a1 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -32,7 +32,7 @@ under the License.
     <jacoco.report.dir>${env.IMPALA_FE_TEST_COVERAGE_DIR}</jacoco.report.dir>
     <hadoop.version>${env.IMPALA_HADOOP_VERSION}</hadoop.version>
     <hive.version>${env.IMPALA_HIVE_VERSION}</hive.version>
-    <hive.storage.api.version>2.3.0.${env.IMPALA_HIVE_VERSION}</hive.storage.api.version>
+    <hive.storage.api.version>${env.IMPALA_HIVE_STORAGE_API_VERSION}</hive.storage.api.version>
     <hive.major.version>${env.IMPALA_HIVE_MAJOR_VERSION}</hive.major.version>
     <hudi.version>${env.IMPALA_HUDI_VERSION}</hudi.version>
     <ranger.version>${env.IMPALA_RANGER_VERSION}</ranger.version>


[impala] 02/08: IMPALA-10377: Improve the accuracy of resource estimation

Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit 1a01bfe831b548204cde8087def51a2f27b40cb4
Author: liuyao <54...@163.com>
AuthorDate: Wed Dec 9 17:59:51 2020 +0800

    IMPALA-10377: Improve the accuracy of resource estimation
    
    PlanNode does not consider some factors when estimating memory,
    this will cause a large error rate
    
    AggregationNode
    1.MemoryEstimate = Ndv * (AvgRowSize + SizeOfBucket)
    2.When estimating the Ndv of merge aggregation, Ndv should be
      divided only once.
    3.If there is no grouping exprs, MemoryEstimate =
      MIN_PLAIN_AGG_MEM
    
    SortNode
    1.MemoryEstimate = Cardinality * AvgRowSize. Memory used when
      there is enough memory
    
    HashJoinNode
    1.MemoryEstimate= DataRows + Buckets + DuplicateNodes,
      DataRows = RightTableCardinality * AvgRowSize,
      Buckets= roundUpToPowerOf2(RightTableCardinality) *
               SizeOfBucket,
      DuplicateNodes = (RightTableCardinality - RightNdv) *
                        SizeOfDuplicateNode
    
    KuduScanNode
    1.MemoryEstimate = Columns * BytesPerColumn * MaxScannerThreads,
      Columns are scanned in query, not all the columns of the table
    
    UnitTest
    1.CardinalityTest adds test cases to test memory estimation.
      Modify existing test cases related to memory estimation
    
    Change-Id: Ic01db168ff2c6d6de33ee553a8175599f035d7a1
    Reviewed-on: http://gerrit.cloudera.org:8080/16842
    Reviewed-by: Zoltan Borok-Nagy <bo...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 be/src/exec/hash-table.h                           |   5 +
 .../org/apache/impala/planner/AggregationNode.java |  48 ++-
 .../org/apache/impala/planner/HashJoinNode.java    |  30 +-
 .../java/org/apache/impala/planner/JoinNode.java   |   2 +-
 .../org/apache/impala/planner/KuduScanNode.java    |   3 +-
 .../org/apache/impala/planner/PlanFragment.java    |   6 +-
 .../java/org/apache/impala/planner/PlanNode.java   |  11 +
 .../org/apache/impala/planner/PlannerContext.java  |   5 +
 .../java/org/apache/impala/planner/SortNode.java   |  12 +-
 .../org/apache/impala/planner/CardinalityTest.java | 196 +++++++++++
 .../PlannerTest/bloom-filter-assignment.test       |  30 +-
 .../queries/PlannerTest/constant-folding.test      |  12 +-
 .../queries/PlannerTest/constant-propagation.test  |  54 +--
 .../queries/PlannerTest/disable-codegen.test       |  18 +-
 ...k-join-detection-hdfs-num-rows-est-enabled.test |   8 +-
 .../queries/PlannerTest/fk-pk-join-detection.test  |  16 +-
 .../queries/PlannerTest/max-row-size.test          |  48 +--
 ...-runtime-filters-hdfs-num-rows-est-enabled.test |   4 +-
 .../PlannerTest/min-max-runtime-filters.test       |  18 +-
 .../queries/PlannerTest/mt-dop-validation.test     |  38 +--
 .../PlannerTest/parquet-filtering-disabled.test    |  16 +-
 .../queries/PlannerTest/parquet-filtering.test     |  32 +-
 .../queries/PlannerTest/partition-pruning.test     |  10 +-
 .../queries/PlannerTest/preagg-bytes-limit.test    |  12 +-
 .../queries/PlannerTest/resource-requirements.test | 372 ++++++++++-----------
 .../queries/PlannerTest/result-spooling.test       |  12 +-
 .../PlannerTest/runtime-filter-query-options.test  | 116 +++----
 .../PlannerTest/sort-expr-materialization.test     |  18 +-
 .../PlannerTest/spillable-buffer-sizing.test       | 116 +++----
 .../queries/PlannerTest/tpcds/tpcds-q01.test       |  44 +--
 .../queries/PlannerTest/tpcds/tpcds-q02.test       |  38 +--
 .../queries/PlannerTest/tpcds/tpcds-q04.test       | 172 +++++-----
 .../queries/PlannerTest/tpcds/tpcds-q05.test       |  30 +-
 .../queries/PlannerTest/tpcds/tpcds-q06.test       |  56 ++--
 .../queries/PlannerTest/tpcds/tpcds-q07.test       |  36 +-
 .../queries/PlannerTest/tpcds/tpcds-q08.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q09.test       | 278 +++++++--------
 .../queries/PlannerTest/tpcds/tpcds-q10a.test      |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q11.test       | 128 +++----
 .../queries/PlannerTest/tpcds/tpcds-q12.test       |  38 +--
 .../queries/PlannerTest/tpcds/tpcds-q13.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q14a.test      | 274 +++++++--------
 .../queries/PlannerTest/tpcds/tpcds-q14b.test      | 190 +++++------
 .../queries/PlannerTest/tpcds/tpcds-q15.test       |  38 +--
 .../queries/PlannerTest/tpcds/tpcds-q16.test       |  44 +--
 .../queries/PlannerTest/tpcds/tpcds-q17.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q18.test       |  74 ++--
 .../queries/PlannerTest/tpcds/tpcds-q19.test       |  12 +-
 .../queries/PlannerTest/tpcds/tpcds-q20.test       |  48 +--
 .../queries/PlannerTest/tpcds/tpcds-q21.test       |  12 +-
 .../queries/PlannerTest/tpcds/tpcds-q22.test       |  46 +--
 .../queries/PlannerTest/tpcds/tpcds-q23a.test      | 182 +++++-----
 .../queries/PlannerTest/tpcds/tpcds-q23b.test      | 172 +++++-----
 .../queries/PlannerTest/tpcds/tpcds-q24a.test      |  86 ++---
 .../queries/PlannerTest/tpcds/tpcds-q24b.test      |  86 ++---
 .../queries/PlannerTest/tpcds/tpcds-q25.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q26.test       |  36 +-
 .../queries/PlannerTest/tpcds/tpcds-q27.test       |  36 +-
 .../queries/PlannerTest/tpcds/tpcds-q28.test       | 112 +++----
 .../queries/PlannerTest/tpcds/tpcds-q29.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q31.test       | 200 +++++------
 .../queries/PlannerTest/tpcds/tpcds-q32.test       |  22 +-
 .../queries/PlannerTest/tpcds/tpcds-q34.test       |   6 +-
 .../queries/PlannerTest/tpcds/tpcds-q35a.test      |  70 ++--
 .../queries/PlannerTest/tpcds/tpcds-q36.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q37.test       |  24 +-
 .../queries/PlannerTest/tpcds/tpcds-q38.test       | 118 +++----
 .../queries/PlannerTest/tpcds/tpcds-q39a.test      |  68 ++--
 .../queries/PlannerTest/tpcds/tpcds-q39b.test      |  68 ++--
 .../queries/PlannerTest/tpcds/tpcds-q40.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q43.test       |   0
 .../queries/PlannerTest/tpcds/tpcds-q44.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q45.test       |  56 ++--
 .../queries/PlannerTest/tpcds/tpcds-q46.test       |  50 +--
 .../queries/PlannerTest/tpcds/tpcds-q47.test       | 126 +++----
 .../queries/PlannerTest/tpcds/tpcds-q48.test       |  40 +--
 .../queries/PlannerTest/tpcds/tpcds-q49.test       |  20 +-
 .../queries/PlannerTest/tpcds/tpcds-q50.test       |  50 +--
 .../queries/PlannerTest/tpcds/tpcds-q51.test       |  74 ++--
 .../queries/PlannerTest/tpcds/tpcds-q54.test       |  60 ++--
 .../queries/PlannerTest/tpcds/tpcds-q56.test       |   8 +-
 .../queries/PlannerTest/tpcds/tpcds-q57.test       |  74 ++--
 .../queries/PlannerTest/tpcds/tpcds-q58.test       |  80 ++---
 .../queries/PlannerTest/tpcds/tpcds-q59.test       |  72 ++--
 .../queries/PlannerTest/tpcds/tpcds-q60.test       |   8 +-
 .../queries/PlannerTest/tpcds/tpcds-q61.test       |  56 ++--
 .../queries/PlannerTest/tpcds/tpcds-q64.test       | 178 +++++-----
 .../queries/PlannerTest/tpcds/tpcds-q65.test       |  42 +--
 .../queries/PlannerTest/tpcds/tpcds-q66.test       |  56 ++--
 .../queries/PlannerTest/tpcds/tpcds-q67.test       |  46 +--
 .../queries/PlannerTest/tpcds/tpcds-q68.test       |  50 +--
 .../queries/PlannerTest/tpcds/tpcds-q69.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q71.test       |  42 +--
 .../queries/PlannerTest/tpcds/tpcds-q72.test       |  76 ++---
 .../queries/PlannerTest/tpcds/tpcds-q73.test       |  28 +-
 .../queries/PlannerTest/tpcds/tpcds-q74.test       | 122 +++----
 .../queries/PlannerTest/tpcds/tpcds-q75.test       |  88 ++---
 .../queries/PlannerTest/tpcds/tpcds-q76.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q77.test       |  22 +-
 .../queries/PlannerTest/tpcds/tpcds-q78.test       |  68 ++--
 .../queries/PlannerTest/tpcds/tpcds-q79.test       |  24 +-
 .../queries/PlannerTest/tpcds/tpcds-q80.test       |  68 ++--
 .../queries/PlannerTest/tpcds/tpcds-q81.test       |  56 ++--
 .../queries/PlannerTest/tpcds/tpcds-q82.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q83.test       |  80 ++---
 .../queries/PlannerTest/tpcds/tpcds-q85.test       |  28 +-
 .../queries/PlannerTest/tpcds/tpcds-q86.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q87.test       | 118 +++----
 .../queries/PlannerTest/tpcds/tpcds-q88.test       | 148 ++++----
 .../queries/PlannerTest/tpcds/tpcds-q90.test       |  40 +--
 .../queries/PlannerTest/tpcds/tpcds-q91.test       |  26 +-
 .../queries/PlannerTest/tpcds/tpcds-q92.test       |  22 +-
 .../queries/PlannerTest/tpcds/tpcds-q93.test       |  28 +-
 .../queries/PlannerTest/tpcds/tpcds-q94.test       |  34 +-
 .../queries/PlannerTest/tpcds/tpcds-q95.test       |  68 ++--
 .../queries/PlannerTest/tpcds/tpcds-q96.test       |  22 +-
 .../queries/PlannerTest/tpcds/tpcds-q97.test       |  42 +--
 .../queries/PlannerTest/tpcds/tpcds-q98.test       |  46 +--
 .../queries/PlannerTest/tpch-all.test              | 192 +++++------
 .../queries/PlannerTest/tpch-kudu.test             |  80 ++---
 .../queries/PlannerTest/tpch-nested.test           | 210 ++++++------
 .../QueryTest/admission-max-min-mem-limits.test    |   4 +-
 .../QueryTest/admission-reject-mem-estimate.test   |   2 +-
 .../admission-reject-min-reservation.test          |   8 +-
 .../QueryTest/dedicated-coord-mem-estimates.test   |   6 +-
 .../queries/QueryTest/explain-level2.test          |   4 +-
 tests/query_test/test_mem_usage_scaling.py         |   2 +-
 127 files changed, 3854 insertions(+), 3586 deletions(-)

diff --git a/be/src/exec/hash-table.h b/be/src/exec/hash-table.h
index 2bfd68c..6f49408 100644
--- a/be/src/exec/hash-table.h
+++ b/be/src/exec/hash-table.h
@@ -645,6 +645,9 @@ class HashTable {
     Tuple* tuple;
   };
 
+  /// struct DuplicateNode is referenced by SIZE_OF_DUPLICATENODE of
+  /// planner/PlannerContext.java. If struct DuplicateNode is modified, please modify
+  /// SIZE_OF_DUPLICATENODE synchronously.
   /// Linked list of entries used for duplicates.
   struct DuplicateNode {
     /// Used for full outer and right {outer, anti, semi} joins. Indicates whether the
@@ -659,6 +662,8 @@ class HashTable {
     HtData htdata;
   };
 
+  /// struct Bucket is referenced by SIZE_OF_BUCKET of planner/PlannerContext.java.
+  /// If struct Bucket is modified, please modify SIZE_OF_BUCKET synchronously.
   struct Bucket {
     /// Whether this bucket contains a vaild entry, or it is empty.
     bool filled;
diff --git a/fe/src/main/java/org/apache/impala/planner/AggregationNode.java b/fe/src/main/java/org/apache/impala/planner/AggregationNode.java
index 3a75c66..50b7bb1 100644
--- a/fe/src/main/java/org/apache/impala/planner/AggregationNode.java
+++ b/fe/src/main/java/org/apache/impala/planner/AggregationNode.java
@@ -58,9 +58,6 @@ public class AggregationNode extends PlanNode {
   // TODO: Come up with a more useful heuristic.
   private final static long DEFAULT_PER_INSTANCE_MEM = 128L * 1024L * 1024L;
 
-  // Conservative minimum size of hash table for low-cardinality aggregations.
-  private final static long MIN_HASH_TBL_MEM = 10L * 1024L * 1024L;
-
   // Default skew factor to account for data skew among fragment instances.
   private final static double DEFAULT_SKEW_FACTOR = 1.5;
 
@@ -82,6 +79,14 @@ public class AggregationNode extends PlanNode {
   // Resource profiles for each aggregation class.
   private List<ResourceProfile> resourceProfiles_;
 
+  // Conservative minimum size of hash table for low-cardinality aggregations.
+  protected final static long MIN_HASH_TBL_MEM = 10L * 1024L * 1024L;
+
+  // If the group clause is empty ( aggInfo.getGroupingExprs() is empty ),
+  // the hash table will not be created.
+  // Peak memory is at least 16k, which is an empirical value
+  protected final static long MIN_PLAIN_AGG_MEM = 16L * 1024L;
+
   public AggregationNode(
       PlanNodeId id, PlanNode input, MultiAggregateInfo multiAggInfo, AggPhase aggPhase) {
     super(id, "AGGREGATE");
@@ -530,19 +535,44 @@ public class AggregationNode extends PlanNode {
         long numInstances = fragment_.getNumInstances();
         long perInstanceInputCardinality;
         if (numInstances > 1) {
-          perInstanceInputCardinality =
+          if (useStreamingPreagg_) {
+            // A skew factor was added to account for data skew among
+            // multiple fragment instances.
+            // This number was derived using empirical analysis of real-world
+            // and benchmark (tpch, tpcds) queries.
+            perInstanceInputCardinality =
               (long) Math.ceil((inputCardinality / numInstances) * DEFAULT_SKEW_FACTOR);
+          } else {
+            // The data is distributed through hash, it will be more balanced.
+            perInstanceInputCardinality =
+              (long) Math.ceil(inputCardinality / numInstances);
+          }
         } else {
           // When numInstances is 1 or unknown(-1), perInstanceInputCardinality is the
           // same as inputCardinality.
           perInstanceInputCardinality = inputCardinality;
         }
-        perInstanceCardinality =
-            Math.min(perInstanceCardinality, perInstanceInputCardinality);
+
+        if (useStreamingPreagg_) {
+          // A reduction factor of 2 (input rows divided by output rows) was
+          // added to grow hash tables. If the reduction factor is lower than 2,
+          // only part of the data will be inserted into the hash table.
+          perInstanceCardinality =
+              Math.min(perInstanceCardinality, perInstanceInputCardinality / 2);
+        } else {
+          perInstanceCardinality =
+              Math.min(perInstanceCardinality, perInstanceInputCardinality);
+        }
+      }
+      // The memory of the data stored in hash table and the memory of the
+      // hash table‘s structure
+      perInstanceDataBytes = (long)Math.ceil(perInstanceCardinality *
+                                  (avgRowSize_ + PlannerContext.SIZE_OF_BUCKET));
+      if (aggInfo.getGroupingExprs().isEmpty()) {
+        perInstanceMemEstimate = MIN_PLAIN_AGG_MEM;
+      } else {
+        perInstanceMemEstimate = (long)Math.max(perInstanceDataBytes, MIN_HASH_TBL_MEM);
       }
-      perInstanceDataBytes = (long)Math.ceil(perInstanceCardinality * avgRowSize_);
-      perInstanceMemEstimate = (long)Math.max(perInstanceDataBytes *
-          PlannerContext.HASH_TBL_SPACE_OVERHEAD, MIN_HASH_TBL_MEM);
     }
 
     // Must be kept in sync with GroupingAggregator::MinReservation() in backend.
diff --git a/fe/src/main/java/org/apache/impala/planner/HashJoinNode.java b/fe/src/main/java/org/apache/impala/planner/HashJoinNode.java
index cef15a6..254c242 100644
--- a/fe/src/main/java/org/apache/impala/planner/HashJoinNode.java
+++ b/fe/src/main/java/org/apache/impala/planner/HashJoinNode.java
@@ -216,6 +216,11 @@ public class HashJoinNode extends JoinNode {
     return output.toString();
   }
 
+  /**
+   * Helper method to compute the resource requirements for the join that can be
+   * called from the builder or the join node. Returns a pair of the probe
+   * resource requirements and the build resource requirements.
+   */
   @Override
   public Pair<ResourceProfile, ResourceProfile> computeJoinResourceProfile(
       TQueryOptions queryOptions) {
@@ -227,14 +232,31 @@ public class HashJoinNode extends JoinNode {
       perBuildInstanceMemEstimate = DEFAULT_PER_INSTANCE_MEM;
       perBuildInstanceDataBytes = -1;
     } else {
-      perBuildInstanceDataBytes = (long) Math.ceil(getChild(1).cardinality_
-          * getChild(1).avgRowSize_);
+      long rhsCard = getChild(1).getCardinality();
+      long rhsNdv = 1;
+      // Calculate the ndv of the right child, which is the multiplication of
+      // the ndv of the right child column
+      for (Expr eqJoinPredicate: eqJoinConjuncts_) {
+        long rhsPdNdv = getNdv(eqJoinPredicate.getChild(1));
+        rhsPdNdv = Math.min(rhsPdNdv, rhsCard);
+        if (rhsPdNdv != -1) {
+          rhsNdv = PlanNode.checkedMultiply(rhsNdv, rhsPdNdv);
+        }
+      }
+      // The memory of the data stored in hash table and
+      // the memory of the hash table‘s structure
+      perBuildInstanceDataBytes = (long) Math.ceil(rhsCard * getChild(1).getAvgRowSize() +
+          BitUtil.roundUpToPowerOf2((long) Math.ceil(3 * rhsCard / 2)) *
+          PlannerContext.SIZE_OF_BUCKET);
+      if (rhsNdv > 1 && rhsNdv < rhsCard) {
+        perBuildInstanceDataBytes += (rhsCard - rhsNdv) *
+            PlannerContext.SIZE_OF_DUPLICATENODE;
+      }
       // Assume the rows are evenly divided among instances.
       if (distrMode_ == DistributionMode.PARTITIONED) {
         perBuildInstanceDataBytes /= numInstances;
       }
-      perBuildInstanceMemEstimate = (long) Math.ceil(
-          perBuildInstanceDataBytes * PlannerContext.HASH_TBL_SPACE_OVERHEAD);
+      perBuildInstanceMemEstimate = perBuildInstanceDataBytes;
     }
 
     // Must be kept in sync with PartitionedHashJoinBuilder::MinReservation() in be.
diff --git a/fe/src/main/java/org/apache/impala/planner/JoinNode.java b/fe/src/main/java/org/apache/impala/planner/JoinNode.java
index 7abe428..28db19c 100644
--- a/fe/src/main/java/org/apache/impala/planner/JoinNode.java
+++ b/fe/src/main/java/org/apache/impala/planner/JoinNode.java
@@ -565,7 +565,7 @@ public abstract class JoinNode extends PlanNode {
    * Unwraps the SlotRef in expr and returns the NDVs of it.
    * Returns -1 if the NDVs are unknown or if expr is not a SlotRef.
    */
-  private long getNdv(Expr expr) {
+  protected long getNdv(Expr expr) {
     SlotRef slotRef = expr.unwrapSlotRef(false);
     if (slotRef == null) return -1;
     SlotDescriptor slotDesc = slotRef.getDesc();
diff --git a/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java b/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java
index 7e2d520..67cd5e4 100644
--- a/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java
+++ b/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java
@@ -388,12 +388,11 @@ public class KuduScanNode extends ScanNode {
     int perHostScanRanges = estimatePerHostScanRanges(numOfScanRanges);
     int maxScannerThreads = computeMaxNumberOfScannerThreads(queryOptions,
         perHostScanRanges);
-    int num_cols = desc_.getSlots().size();
     long estimated_bytes_per_column_per_thread = BackendConfig.INSTANCE.getBackendCfg().
         kudu_scanner_thread_estimated_bytes_per_column;
     long max_estimated_bytes_per_thread = BackendConfig.INSTANCE.getBackendCfg().
         kudu_scanner_thread_max_estimated_bytes;
-    long mem_estimate_per_thread = Math.min(num_cols *
+    long mem_estimate_per_thread = Math.min(getNumMaterializedSlots(desc_) *
         estimated_bytes_per_column_per_thread, max_estimated_bytes_per_thread);
     useMtScanNode_ = queryOptions.mt_dop > 0;
     nodeResourceProfile_ = new ResourceProfileBuilder()
diff --git a/fe/src/main/java/org/apache/impala/planner/PlanFragment.java b/fe/src/main/java/org/apache/impala/planner/PlanFragment.java
index c49695a..1093014 100644
--- a/fe/src/main/java/org/apache/impala/planner/PlanFragment.java
+++ b/fe/src/main/java/org/apache/impala/planner/PlanFragment.java
@@ -423,6 +423,7 @@ public class PlanFragment extends TreeNode<PlanFragment> {
     Preconditions.checkState(numInstances >= 0);
     // The number of nodes is zero for empty tables.
     if (numInstances == 0) return 0;
+    boolean partition = false;
     for (Expr expr: exprs) {
       long numDistinct = expr.getNumDistinctValues();
       if (numDistinct == -1) {
@@ -430,10 +431,13 @@ public class PlanFragment extends TreeNode<PlanFragment> {
         break;
       }
       if (dataPartition_.getPartitionExprs().contains(expr)) {
-        numDistinct = (long)Math.max((double) numDistinct / (double) numInstances, 1L);
+        partition = true;
       }
       result = PlanNode.checkedMultiply(result, numDistinct);
     }
+    if (partition) {
+      result = (long)Math.max((double) result / (double) numInstances, 1L);
+    }
     return result;
   }
 
diff --git a/fe/src/main/java/org/apache/impala/planner/PlanNode.java b/fe/src/main/java/org/apache/impala/planner/PlanNode.java
index 52afb59..fe2dd3e 100644
--- a/fe/src/main/java/org/apache/impala/planner/PlanNode.java
+++ b/fe/src/main/java/org/apache/impala/planner/PlanNode.java
@@ -1043,4 +1043,15 @@ abstract public class PlanNode extends TreeNode<PlanNode> {
   }
 
   public boolean allowPartitioned() { return !hasLimit(); }
+
+  public int getNumMaterializedSlots(TupleDescriptor desc) {
+    int numCols = 0;
+    for (SlotDescriptor slot: desc.getSlots()) {
+      // Columns used in this query
+      if (slot.isMaterialized()) {
+        ++numCols;
+      }
+    }
+    return numCols;
+  }
 }
diff --git a/fe/src/main/java/org/apache/impala/planner/PlannerContext.java b/fe/src/main/java/org/apache/impala/planner/PlannerContext.java
index 224e7e0..7b6d361 100644
--- a/fe/src/main/java/org/apache/impala/planner/PlannerContext.java
+++ b/fe/src/main/java/org/apache/impala/planner/PlannerContext.java
@@ -38,6 +38,11 @@ public class PlannerContext {
   // used for determining whether a broadcast join is feasible.
   public final static double HASH_TBL_SPACE_OVERHEAD = 1.1;
 
+  // Bucket is defined in the be/src/exec/hash-table.h
+  public final static double SIZE_OF_BUCKET = 16;
+  // DuplicateNode is defined in the be/src/exec/hash-table.h
+  public final static double SIZE_OF_DUPLICATENODE = 24;
+
   // Assumed average number of items in a nested collection, since we currently have no
   // statistics on nested fields. The motivation for this constant is to avoid
   // pathological plan choices that could result from a SubplanNode having an unknown
diff --git a/fe/src/main/java/org/apache/impala/planner/SortNode.java b/fe/src/main/java/org/apache/impala/planner/SortNode.java
index 225c372..aa0b456 100644
--- a/fe/src/main/java/org/apache/impala/planner/SortNode.java
+++ b/fe/src/main/java/org/apache/impala/planner/SortNode.java
@@ -495,14 +495,10 @@ public class SortNode extends PlanNode {
     } else {
       Preconditions.checkState(type_ == TSortType.TOTAL ||
           type_ == TSortType.PARTITIONED_TOPN);
-      // For an external sort, set the memory cost to be what is required for a 2-phase
-      // sort. If the input to be sorted would take up N blocks in memory, then the
-      // memory required for a 2-phase sort is sqrt(N) blocks. A single run would be of
-      // size sqrt(N) blocks, and we could merge sqrt(N) such runs with sqrt(N) blocks
-      // of memory.
-      double numInputBlocks = Math.ceil(fullInputSize / (bufferSize * pageMultiplier));
-      perInstanceMemEstimate =
-          bufferSize * (long) Math.ceil(Math.sqrt(numInputBlocks));
+      long numInstances = fragment_.getNumInstances();
+      // Data takes up most of the memory
+      perInstanceMemEstimate = fullInputSize < 0 ?
+          PARTIAL_SORT_MEM_LIMIT : (long) Math.ceil(fullInputSize / numInstances);
       perInstanceMinMemReservation = 3 * bufferSize * pageMultiplier;
 
       if (type_ == TSortType.PARTITIONED_TOPN) {
diff --git a/fe/src/test/java/org/apache/impala/planner/CardinalityTest.java b/fe/src/test/java/org/apache/impala/planner/CardinalityTest.java
index 2bbf7da..f634b28 100644
--- a/fe/src/test/java/org/apache/impala/planner/CardinalityTest.java
+++ b/fe/src/test/java/org/apache/impala/planner/CardinalityTest.java
@@ -862,6 +862,147 @@ public class CardinalityTest extends PlannerTestBase {
         path, UnnestNode.class);
   }
 
+  @Test
+  public void testAggregationNodeMemoryEstimate() {
+    // Create the paths to the AggregationNode's of interest
+    // in a distributed plan involving GROUP BY.
+    // Since there are two resulting AggregationNode's, we create two paths.
+    List<Integer> pathToFirstAggregationNode = Arrays.asList(0);
+    List<Integer> pathToSecondAggregationNode = Arrays.asList(0, 0, 0);
+    // Single node execution plan, there is only one AggregationNode
+    List<Integer> pathToAggregationNode = Arrays.asList();
+
+    // There is available statistics in functional.alltypes.
+    // True cardinality of functional.alltypes is 7300.
+    // Ndv of int_col is 10;
+    // MIN_HASH_TBL_MEM is 10M
+    verifyApproxMemoryEstimate("SELECT COUNT(int_col) FROM functional.alltypes "
+        + "GROUP BY int_col", AggregationNode.MIN_HASH_TBL_MEM, true, false,
+        ImmutableSet.of(), pathToFirstAggregationNode, AggregationNode.class);
+    // create a single node plan.
+    verifyApproxMemoryEstimate("SELECT COUNT(int_col) FROM functional.alltypes "
+        + "GROUP BY int_col", AggregationNode.MIN_HASH_TBL_MEM, false, false,
+        ImmutableSet.of(), pathToAggregationNode, AggregationNode.class);
+
+    // FUNCTIONAL.ALLTYPES.ID's Ndv is 7300 and avgRowSize is 4
+    // FUNCTIONAL.ALLTYPESSMALL.TIMESTAMP_COL's Ndv is 100 and avgRowSize is 16
+    // FUNCTIONAL.NULLROWS.BOOL_NULLS's Ndv is 3 and avgRowSize is 1
+    // COUNT(*)'s avgRowSize is 8 and MAX(B.BIGINT_COL) avgRowSize is 8
+    // 2190000 = 7300*100*3
+    verifyApproxMemoryEstimate("SELECT COUNT(*),MAX(B.BIGINT_COL) FROM " +
+        "FUNCTIONAL.ALLTYPES A , FUNCTIONAL.ALLTYPESSMALL B, " +
+        "FUNCTIONAL.NULLROWS C GROUP BY A.ID, B.TIMESTAMP_COL,C.BOOL_NULLS",
+        2190000*(4+16+1+8+8+16), true, true, ImmutableSet.of(),
+        pathToFirstAggregationNode, AggregationNode.class);
+    verifyApproxMemoryEstimate("SELECT COUNT(*),MAX(B.BIGINT_COL) FROM " +
+        "FUNCTIONAL.ALLTYPES A , FUNCTIONAL.ALLTYPESSMALL B, " +
+        "FUNCTIONAL.NULLROWS C GROUP BY A.ID, B.TIMESTAMP_COL,C.BOOL_NULLS",
+        2190000*(4+16+1+8+8+16), true, false, ImmutableSet.of(),
+        pathToSecondAggregationNode, AggregationNode.class);
+    // create a single node plan.
+    verifyApproxMemoryEstimate("SELECT COUNT(*),MAX(B.BIGINT_COL) FROM " +
+        "FUNCTIONAL.ALLTYPES A , FUNCTIONAL.ALLTYPESSMALL B, " +
+        "FUNCTIONAL.NULLROWS C GROUP BY A.ID, B.TIMESTAMP_COL,C.BOOL_NULLS",
+        2190000*(4+16+1+8+8+16), false, false, ImmutableSet.of(),
+        pathToAggregationNode, AggregationNode.class);
+
+    List<Integer> countFirstAggregationNode = Arrays.asList();
+    List<Integer> countSecondAggregationNode = Arrays.asList();
+    // Query has no Group by Clause
+    verifyApproxMemoryEstimate("SELECT COUNT(*) FROM FUNCTIONAL.ALLTYPES A ",
+        AggregationNode.MIN_PLAIN_AGG_MEM, true, false, ImmutableSet.of(),
+        countFirstAggregationNode, AggregationNode.class);
+    verifyApproxMemoryEstimate("SELECT COUNT(*) FROM FUNCTIONAL.ALLTYPES A ",
+        AggregationNode.MIN_PLAIN_AGG_MEM, true, false, ImmutableSet.of(),
+        countSecondAggregationNode, AggregationNode.class);
+    // create a single node plan.
+    verifyApproxMemoryEstimate("SELECT COUNT(*) FROM FUNCTIONAL.ALLTYPES A ",
+        AggregationNode.MIN_PLAIN_AGG_MEM, false, false, ImmutableSet.of(),
+        pathToAggregationNode, AggregationNode.class);
+  }
+
+  @Test
+  public void testSortNodeMemoryEstimate() {
+    List<Integer> pathToSortNode = Arrays.asList(0);
+
+    List<Integer> pathToSortNodeSg = Arrays.asList();
+
+    // FUNCTIONAL.ALLTYPES.ID's Ndv is 7300 and avgRowSize is 4
+    // FUNCTIONAL.ALLTYPESSMALL.TIMESTAMP_COL's Ndv is 100 and avgRowSize is 16
+    verifyApproxMemoryEstimate("SELECT A.TIMESTAMP_COL,B.TIMESTAMP_COL FROM " +
+        "FUNCTIONAL.ALLTYPES A , FUNCTIONAL.ALLTYPESSMALL B " +
+        "ORDER BY A.TIMESTAMP_COL,B.TIMESTAMP_COL",
+        7300*100*(16+16), true, true, ImmutableSet.of(),
+        pathToSortNode, SortNode.class);
+    // create a single node plan.
+    verifyApproxMemoryEstimate("SELECT A.TIMESTAMP_COL,B.TIMESTAMP_COL FROM " +
+        "FUNCTIONAL.ALLTYPES A , FUNCTIONAL.ALLTYPESSMALL B " +
+        "ORDER BY A.TIMESTAMP_COL,B.TIMESTAMP_COL",
+        7300*100*(16+16), false, false, ImmutableSet.of(),
+        pathToSortNodeSg, SortNode.class);
+  }
+
+  @Test
+  public void testHashJoinNodeMemoryEstimate() {
+    List<Integer> pathToJoinNode = Arrays.asList(0);
+    List<Integer> pathToJoinNodeSg = Arrays.asList();
+
+    // FUNCTIONAL.ALLTYPES.ID's Ndv is 7300 and avgRowSize is 4
+    // FUNCTIONAL.ALLTYPES.DATE_STRING_COL's Ndv is 736 and avgRowSize is 8
+    // Cardinality estimate of subquery is 5372800
+    // BitUtil.roundUpToPowerOf2((long) Math.ceil(3 * Cardinality / 2)) is 8388608
+    // Size of Bucket is 16.
+    verifyApproxMemoryEstimate("SELECT A.ID FROM (SELECT A1.ID,B1.DATE_STRING_COL " +
+        "IDB FROM FUNCTIONAL.ALLTYPES A1 , FUNCTIONAL.ALLTYPES B1 GROUP BY A1.ID," +
+        "B1.DATE_STRING_COL) A JOIN (SELECT A1.ID,B1.DATE_STRING_COL IDB FROM " +
+        "FUNCTIONAL.ALLTYPES A1,FUNCTIONAL.ALLTYPES B1 GROUP BY " +
+        "A1.ID,B1.DATE_STRING_COL) B ON A.ID = B.ID AND A.IDB=B.IDB",
+        5372800*(4+8+4+8) + 8388608*16, true, true, ImmutableSet.of(),
+        pathToJoinNode, HashJoinNode.class);
+    // create a single node plan.
+    verifyApproxMemoryEstimate("SELECT A.ID FROM (SELECT A1.ID,B1.DATE_STRING_COL " +
+        "IDB FROM FUNCTIONAL.ALLTYPES A1 , FUNCTIONAL.ALLTYPES B1 GROUP BY A1.ID," +
+        "B1.DATE_STRING_COL) A JOIN (SELECT A1.ID,B1.DATE_STRING_COL IDB FROM " +
+        "FUNCTIONAL.ALLTYPES A1,FUNCTIONAL.ALLTYPES B1 GROUP BY " +
+        "A1.ID,B1.DATE_STRING_COL) B ON A.ID = B.ID AND A.IDB=B.IDB",
+        5372800*(4+8+4+8) + 8388608*16, false, false, ImmutableSet.of(),
+        pathToJoinNodeSg, HashJoinNode.class);
+
+    // FUNCTIONAL.ALLTYPES.ID's Ndv is 7300 and avgRowSize is 4
+    // FUNCTIONAL.ALLTYPES.DATE_STRING_COL's Ndv is 736 and avgRowSize is 8
+    // Cardinality estimate of subquery is 53290000
+    // BitUtil.roundUpToPowerOf2((long) Math.ceil(3 * Cardinality / 2)) is 134217728
+    // Size of Bucket is 16. Size of Duplicatenode is 24
+    // Ndv estimate of subquery is 5372800
+    verifyApproxMemoryEstimate("SELECT A.ID FROM (SELECT A1.ID,B1.DATE_STRING_COL " +
+        "IDB FROM FUNCTIONAL.ALLTYPES A1 , FUNCTIONAL.ALLTYPES B1) A JOIN " +
+        "(SELECT A1.ID,B1.DATE_STRING_COL IDB FROM FUNCTIONAL.ALLTYPES A1," +
+        "FUNCTIONAL.ALLTYPES B1) B ON A.ID = B.ID AND A.IDB=B.IDB",
+        53290000L*(4L+8L+4L+8L)+134217728L*16L+(53290000L-5372800L)*24L, true, true,
+        ImmutableSet.of(), pathToJoinNode, HashJoinNode.class);
+    // create a single node plan.
+    verifyApproxMemoryEstimate("SELECT A.ID FROM (SELECT A1.ID,B1.DATE_STRING_COL " +
+        "IDB FROM FUNCTIONAL.ALLTYPES A1 , FUNCTIONAL.ALLTYPES B1) A JOIN " +
+        "(SELECT A1.ID,B1.DATE_STRING_COL IDB FROM FUNCTIONAL.ALLTYPES A1," +
+        "FUNCTIONAL.ALLTYPES B1) B ON A.ID = B.ID AND A.IDB=B.IDB",
+        53290000L*(4L+8L+4L+8L)+134217728L*16L+(53290000L-5372800L)*24L, false, false,
+        ImmutableSet.of(), pathToJoinNodeSg, HashJoinNode.class);
+  }
+
+  @Test
+  public void testKuduScanNodeMemoryEstimate() {
+    List<Integer> pathToKuduScanNode = Arrays.asList(0);
+    List<Integer> pathToKuduScanNodeSg = Arrays.asList();
+    // Scan 1 column.
+    verifyApproxMemoryEstimate("SELECT ID FROM FUNCTIONAL_KUDU.ALLTYPESSMALL",
+        393216*1*2, true, false,
+        ImmutableSet.of(), pathToKuduScanNode, KuduScanNode.class);
+    // create a single node plan.
+    verifyApproxMemoryEstimate("SELECT ID FROM FUNCTIONAL_KUDU.ALLTYPESSMALL",
+        393216*1*2, false, false,
+        ImmutableSet.of(), pathToKuduScanNodeSg, KuduScanNode.class);
+  }
+
   /**
    * Given a query and an expected cardinality, checks that the root
    * node of the single-fragment plan has the expected cardinality.
@@ -1035,4 +1176,59 @@ public class CardinalityTest extends PlannerTestBase {
     return planCtx.getPlan();
   }
 
+  /**
+  * This method allows us to get a PlanNode located by
+  * path with respect to the root of the retrieved query plan. The class of
+  * the located PlanNode by path will also be checked against cl, the class of
+  * the PlanNode of interest.
+  *
+  * @param query query to test
+  * @param isDistributedPlan set to true if we would like to generate
+  * a distributed plan
+  * @param testOptions specified test options
+  * @param path path to the PlanNode of interest
+  * @param cl class of the PlanNode of interest
+  */
+  protected PlanNode getPlanNode(String query, boolean isDistributedPlan,
+      Set<PlannerTestOption> testOptions, List<Integer> path, Class<?> cl) {
+    List<PlanFragment> plan = getPlan(query, isDistributedPlan, testOptions);
+    // We use the last element on the List of PlanFragment
+    // because this PlanFragment encloses all the PlanNode's
+    // in the query plan (either the single node plan or
+    // the distributed plan).
+    PlanNode currentNode = plan.get(plan.size() - 1).getPlanRoot();
+    for (Integer currentChildIndex: path) {
+      currentNode = currentNode.getChild(currentChildIndex);
+    }
+    assertEquals("PlanNode class not matched: ", cl.getName(),
+        currentNode.getClass().getName());
+    return currentNode;
+  }
+
+  /**
+  * This method allows us to inspect the Memory Estimate of a PlanNode located by
+  * path with respect to the root of the retrieved query plan. The class of
+  * the located PlanNode by path will also be checked against cl, the class of
+  * the PlanNode of interest.
+  *
+  * @param query query to test
+  * @param expected expected Memory at the PlanNode of interest
+  * @param isDistributedPlan set to true if we would like to generate
+  * a distributed plan
+  * @param testOptions specified test options
+  * @param path path to the PlanNode of interest
+  * @param cl class of the PlanNode of interest
+  */
+  protected void verifyApproxMemoryEstimate(String query, long expected,
+      boolean isDistributedPlan, boolean isMultiNodes,
+      Set<PlannerTestOption> testOptions, List<Integer> path, Class<?> cl) {
+    PlanNode pNode = getPlanNode(query, isDistributedPlan, testOptions, path, cl);
+    long result = pNode.getNodeResourceProfile().getMemEstimateBytes();
+    if (isMultiNodes) {
+      result = (long)Math.ceil(result * pNode.getFragment().getNumInstances());
+    }
+    assertEquals("Memory Estimate error for: " + query, expected, result,
+        expected * CARDINALITY_TOLERANCE);
+  }
+
 }
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/bloom-filter-assignment.test b/testdata/workloads/functional-planner/queries/PlannerTest/bloom-filter-assignment.test
index be01aa7..cc53eca 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/bloom-filter-assignment.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/bloom-filter-assignment.test
@@ -14,7 +14,7 @@ PLAN-ROOT SINK
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -58,14 +58,14 @@ ENABLED_RUNTIME_FILTER_TYPES=BLOOM
 EXPLAIN_LEVEL=2
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=13.69MB mem-reservation=2.94MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=4.44MB mem-reservation=2.94MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -97,14 +97,14 @@ ENABLED_RUNTIME_FILTER_TYPES=BLOOM
 EXPLAIN_LEVEL=2
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=28.94MB mem-reservation=2.95MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=19.69MB mem-reservation=2.95MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -149,7 +149,7 @@ PLAN-ROOT SINK
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -187,14 +187,14 @@ ENABLED_RUNTIME_FILTER_TYPES=BLOOM
 EXPLAIN_LEVEL=2
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=28.94MB mem-reservation=2.95MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=19.69MB mem-reservation=2.95MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -239,7 +239,7 @@ PLAN-ROOT SINK
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -284,7 +284,7 @@ PLAN-ROOT SINK
 |
 05:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=8B cardinality=1
 |  in pipelines: 05(GETNEXT), 00(OPEN)
 |
@@ -355,7 +355,7 @@ PLAN-ROOT SINK
 |
 05:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=8B cardinality=1
 |  in pipelines: 05(GETNEXT), 00(OPEN)
 |
@@ -425,7 +425,7 @@ PLAN-ROOT SINK
 |
 05:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=8B cardinality=1
 |  in pipelines: 05(GETNEXT), 00(OPEN)
 |
@@ -489,14 +489,14 @@ ENABLED_RUNTIME_FILTER_TYPES=BLOOM
 EXPLAIN_LEVEL=2
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=32.88MB mem-reservation=6.89MB thread-reservation=4 runtime-filters-memory=3.00MB
+|  Per-Host Resources: mem-estimate=24.38MB mem-reservation=6.89MB thread-reservation=4 runtime-filters-memory=3.00MB
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 05:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=8B cardinality=1
 |  in pipelines: 05(GETNEXT), 00(OPEN)
 |
@@ -510,7 +510,7 @@ PLAN-ROOT SINK
 |
 |--02:SCAN KUDU [functional_kudu.alltypes c]
 |     kudu predicates: c.id < CAST(100 AS INT)
-|     mem-estimate=1.50MB mem-reservation=0B thread-reservation=1
+|     mem-estimate=768.00KB mem-reservation=0B thread-reservation=1
 |     tuple-ids=2 row-size=16B cardinality=730
 |     in pipelines: 02(GETNEXT)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/constant-folding.test b/testdata/workloads/functional-planner/queries/PlannerTest/constant-folding.test
index 173d5aa..5982c3e 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/constant-folding.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/constant-folding.test
@@ -59,14 +59,14 @@ PLAN-ROOT SINK
 |     in pipelines: 00(GETNEXT)
 |
 00:SCAN HDFS [tpch_nested_parquet.customer c]
-   HDFS partitions=1/1 files=4 size=289.14MB
+   HDFS partitions=1/1 files=4 size=289.07MB
    predicates: c_custkey > CAST(10 AS BIGINT), !empty(c.c_orders)
    predicates on o: !empty(o.o_lineitems), o_orderkey = CAST(4 AS BIGINT)
    predicates on o_lineitems: CAST(20 AS BIGINT) + CAST(l_linenumber AS BIGINT) < CAST(0 AS BIGINT)
    stored statistics:
-     table: rows=150.00K size=289.14MB
+     table: rows=150.00K size=289.07MB
      columns missing stats: c_orders
-   extrapolated-rows=disabled max-scan-range-rows=50.03K
+   extrapolated-rows=disabled max-scan-range-rows=50.61K
    parquet statistics predicates: c_custkey > CAST(10 AS BIGINT)
    parquet statistics predicates on o: o_orderkey = CAST(4 AS BIGINT)
    parquet dictionary predicates: c_custkey > CAST(10 AS BIGINT)
@@ -322,7 +322,7 @@ PLAN-ROOT SINK
 02:AGGREGATE [FINALIZE]
 |  output: sum(2 + id), count:merge(*)
 |  having: CAST(1048576 AS BIGINT) * zeroifnull(count(*)) % CAST(2 AS BIGINT) = CAST(0 AS BIGINT)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=16B cardinality=1
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
@@ -460,14 +460,14 @@ id, CAST(10 AS INT) + CAST(c2 AS INT) c3 FROM (SELECT id, CAST(20 AS SMALLINT) +
 CAST(c1 AS SMALLINT) c2 FROM (SELECT id, CAST(30 AS TINYINT) c1 FROM
 functional.alltypes LIMIT CAST(2 AS TINYINT)) v1) v2) v3
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=138.00MB mem-reservation=4.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=128.02MB mem-reservation=4.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: sum(id + c3)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: sum(CAST(id AS BIGINT) + CAST(CAST(10 AS INT) + CAST(CAST(20 AS SMALLINT) + CAST(30 AS SMALLINT) AS INT) AS BIGINT))
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=4 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/constant-propagation.test b/testdata/workloads/functional-planner/queries/PlannerTest/constant-propagation.test
index 5e645c9..0af632a 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/constant-propagation.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/constant-propagation.test
@@ -17,9 +17,9 @@ where a.int_col1 = 10 and a.int_col2 = a.int_col1 + 1 and a.int_col3 = a.int_col
 PLAN-ROOT SINK
 |
 00:SCAN HDFS [functional.widetable_250_cols a]
-   partitions=1/1 files=1 size=28.69KB
+   HDFS partitions=1/1 files=1 size=28.69KB
    predicates: a.int_col1 = 10, a.int_col2 = 11, a.int_col3 = 55, a.int_col4 = 110
-   row-size=1.21KB cardinality=unavailable
+   row-size=1.21KB cardinality=2
 ====
 # Test multiple forward propagation
 select * from functional.widetable_250_cols a
@@ -29,9 +29,9 @@ where a.int_col1 = 10 and a.int_col2 = a.int_col1 + 1 and a.int_col3 = a.int_col
 PLAN-ROOT SINK
 |
 00:SCAN HDFS [functional.widetable_250_cols a]
-   partitions=1/1 files=1 size=28.69KB
+   HDFS partitions=1/1 files=1 size=28.69KB
    predicates: a.int_col1 = 10, a.int_col2 = 11, a.int_col3 = 55, a.int_col4 = -385
-   row-size=1.21KB cardinality=unavailable
+   row-size=1.21KB cardinality=2
 ====
 # Test multiple forward propagation
 select * from functional.widetable_250_cols a
@@ -41,9 +41,9 @@ where a.int_col1 = 10 and a.int_col2 = a.int_col1 + 1 and a.int_col2 * 5 = a.int
 PLAN-ROOT SINK
 |
 00:SCAN HDFS [functional.widetable_250_cols a]
-   partitions=1/1 files=1 size=28.69KB
+   HDFS partitions=1/1 files=1 size=28.69KB
    predicates: a.int_col1 = 10, a.int_col2 = 11, a.int_col3 = 55, a.int_col4 = -495
-   row-size=1.21KB cardinality=unavailable
+   row-size=1.21KB cardinality=2
 ====
 # Test multiple forward propagation, and a reversed propagation
 # (which fails as we can't rewrite 55 = a.int_col4 / 10)
@@ -54,9 +54,9 @@ where a.int_col1 = 10 and a.int_col2 = a.int_col1 + 1 and a.int_col3 = a.int_col
 PLAN-ROOT SINK
 |
 00:SCAN HDFS [functional.widetable_250_cols a]
-   partitions=1/1 files=1 size=28.69KB
+   HDFS partitions=1/1 files=1 size=28.69KB
    predicates: a.int_col1 = 10, a.int_col2 = 11, a.int_col3 = 55, a.int_col4 / 10 = 55
-   row-size=1.21KB cardinality=unavailable
+   row-size=1.21KB cardinality=2
 ====
 # Another impossibility (a.int_col3 = a.int_col2 * 5 = a.int_col2 * -7)
 select * from functional.widetable_250_cols a
@@ -76,7 +76,7 @@ PLAN-ROOT SINK
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  row-size=8B cardinality=0
+|  row-size=8B cardinality=1
 |
 00:EMPTYSET
 ====
@@ -89,7 +89,7 @@ PLAN-ROOT SINK
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  row-size=8B cardinality=0
+|  row-size=8B cardinality=1
 |
 00:EMPTYSET
 ====
@@ -100,7 +100,7 @@ where cast(a.int_col as string) = 'abc' and cast(int_col as string) > 'xyz'
 PLAN-ROOT SINK
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    predicates: CAST(a.int_col AS STRING) = 'abc', CAST(int_col AS STRING) > 'xyz'
    row-size=89B cardinality=231
 ====
@@ -122,11 +122,11 @@ PLAN-ROOT SINK
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  row-size=8B cardinality=0
+|  row-size=8B cardinality=1
 |
 02:SELECT
 |  predicates: int_col = 12, int_col > 1
-|  row-size=4B cardinality=0
+|  row-size=4B cardinality=1
 |
 01:AGGREGATE [FINALIZE]
 |  group by: int_col
@@ -134,7 +134,7 @@ PLAN-ROOT SINK
 |  row-size=4B cardinality=10
 |
 00:SCAN HDFS [functional.alltypes]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    predicates: int_col = 10
    row-size=4B cardinality=730
 ====
@@ -151,7 +151,7 @@ PLAN-ROOT SINK
 |  row-size=8B cardinality=1
 |
 00:SCAN HDFS [functional.alltypes]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    predicates: int_col = 10
    row-size=4B cardinality=730
 ====
@@ -167,7 +167,7 @@ PLAN-ROOT SINK
 |  row-size=8B cardinality=1
 |
 00:SCAN HDFS [functional.alltypes]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    row-size=0B cardinality=7.30K
 ====
 # Many redundant / duplicate predicates
@@ -222,7 +222,7 @@ PLAN-ROOT SINK
 |  row-size=8B cardinality=1
 |
 00:SCAN HDFS [functional.alltypes]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    predicates: int_col = 10
    row-size=4B cardinality=730
 ====
@@ -236,7 +236,7 @@ PLAN-ROOT SINK
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  row-size=8B cardinality=0
+|  row-size=8B cardinality=1
 |
 00:EMPTYSET
 ====
@@ -254,7 +254,7 @@ PLAN-ROOT SINK
 |  row-size=8B cardinality=1
 |
 00:SCAN HDFS [functional.alltypes]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    predicates: int_col = 10
    row-size=4B cardinality=730
 ====
@@ -272,7 +272,7 @@ PLAN-ROOT SINK
 |  row-size=8B cardinality=1
 |
 00:SCAN HDFS [functional.alltypes]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    predicates: int_col = 10, TRUE OR 10 + random() * functional.alltypes.tinyint_col = 100
    row-size=5B cardinality=231
 ====
@@ -308,7 +308,7 @@ PLAN-ROOT SINK
 |     row-size=0B cardinality=10
 |
 00:SCAN HDFS [tpch_nested_parquet.customer c]
-   partitions=1/1 files=4 size=288.99MB
+   HDFS partitions=1/1 files=4 size=289.08MB
    predicates: c.c_nationkey = 10, !empty(c.c_orders)
    predicates on o: !empty(o.o_lineitems), o_orderkey = 4
    predicates on o_lineitems: l_partkey < 10, l_suppkey = 10
@@ -348,7 +348,7 @@ PLAN-ROOT SINK
 |     row-size=0B cardinality=10
 |
 00:SCAN HDFS [tpch_nested_parquet.customer c]
-   partitions=1/1 files=4 size=288.99MB
+   HDFS partitions=1/1 files=4 size=289.08MB
    predicates: c.c_nationkey = 10, !empty(c.c_orders)
    predicates on o: !empty(o.o_lineitems), o.o_orderkey = 10, o.o_shippriority = 10
    predicates on o_lineitems: l_partkey < 10, l_suppkey = 10
@@ -362,7 +362,7 @@ PLAN-ROOT SINK
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  row-size=8B cardinality=0
+|  row-size=8B cardinality=1
 |
 00:EMPTYSET
 ====
@@ -373,7 +373,7 @@ PLAN-ROOT SINK
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  row-size=8B cardinality=0
+|  row-size=8B cardinality=1
 |
 00:EMPTYSET
 ====
@@ -388,9 +388,9 @@ PLAN-ROOT SINK
 |  row-size=8B cardinality=1
 |
 00:SCAN HDFS [functional.alltypes]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    predicates: bool_col IS NULL, functional.alltypes.id IS NULL, id > 0, functional.alltypes.bool_col > 0, id = bool_col
-   row-size=5B cardinality=730
+   row-size=5B cardinality=1
 ====
 # = NULL and >
 select count(*) from functional.alltypes where id > 0 and bool_col = null
@@ -400,7 +400,7 @@ PLAN-ROOT SINK
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  row-size=8B cardinality=0
+|  row-size=8B cardinality=1
 |
 00:EMPTYSET
 ====
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/disable-codegen.test b/testdata/workloads/functional-planner/queries/PlannerTest/disable-codegen.test
index c92204a..6e955a5 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/disable-codegen.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/disable-codegen.test
@@ -2,7 +2,7 @@
 select count(*) from functional.alltypes
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=32.00KB Threads=3
-Per-Host Resource Estimates: Memory=148MB
+Per-Host Resource Estimates: Memory=128MB
 Codegen disabled by planner
 
 PLAN-ROOT SINK
@@ -25,7 +25,7 @@ PLAN-ROOT SINK
 select count(*) from functional.alltypesagg
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=128.00KB Threads=3
-Per-Host Resource Estimates: Memory=100MB
+Per-Host Resource Estimates: Memory=80MB
 
 PLAN-ROOT SINK
 |
@@ -47,7 +47,7 @@ PLAN-ROOT SINK
 select count(*) from functional_parquet.alltypes
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=16.00KB Threads=3
-Per-Host Resource Estimates: Memory=21MB
+Per-Host Resource Estimates: Memory=10MB
 WARNING: The following tables are missing relevant table and/or column statistics.
 functional_parquet.alltypes
 
@@ -89,7 +89,7 @@ from functional.alltypes t1
 join functional.alltypestiny t2 on t1.id = t2.id
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=2.98MB Threads=5
-Per-Host Resource Estimates: Memory=183MB
+Per-Host Resource Estimates: Memory=163MB
 Codegen disabled by planner
 
 PLAN-ROOT SINK
@@ -124,7 +124,7 @@ PLAN-ROOT SINK
 select count(*) from functional.alltypes t1, functional.alltypes t2
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=64.00KB Threads=5
-Per-Host Resource Estimates: Memory=276MB
+Per-Host Resource Estimates: Memory=256MB
 
 PLAN-ROOT SINK
 |
@@ -158,7 +158,7 @@ select count(*) from (
   select * from functional.alltypestiny) v
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=32.00KB Threads=3
-Per-Host Resource Estimates: Memory=148MB
+Per-Host Resource Estimates: Memory=128MB
 Codegen disabled by planner
 
 PLAN-ROOT SINK
@@ -192,7 +192,7 @@ select count(*) from (
   select * from functional.alltypes) v
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=32.00KB Threads=3
-Per-Host Resource Estimates: Memory=148MB
+Per-Host Resource Estimates: Memory=128MB
 
 PLAN-ROOT SINK
 |
@@ -224,7 +224,7 @@ select sum(l_discount)
 from (select * from tpch.lineitem limit 1000) v
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=8.00MB Threads=3
-Per-Host Resource Estimates: Memory=274MB
+Per-Host Resource Estimates: Memory=264MB
 Codegen disabled by planner
 
 PLAN-ROOT SINK
@@ -247,7 +247,7 @@ select sum(l_discount)
 from (select * from tpch.lineitem where l_orderkey > 100 limit 1000) v
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=8.00MB Threads=3
-Per-Host Resource Estimates: Memory=274MB
+Per-Host Resource Estimates: Memory=264MB
 
 PLAN-ROOT SINK
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection-hdfs-num-rows-est-enabled.test b/testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection-hdfs-num-rows-est-enabled.test
index c5dcf6e..4c9008b 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection-hdfs-num-rows-est-enabled.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection-hdfs-num-rows-est-enabled.test
@@ -10,7 +10,7 @@ tpcds.store_sales inner join tpcds_seq_snap.customer
 on ss_customer_sk = c_customer_sk
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=178.94MB mem-reservation=18.94MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=194.00MB mem-reservation=34.00MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: CAST(1 AS TINYINT)
 |  mem-estimate=21.98MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -19,7 +19,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_customer_sk = c_customer_sk
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF000[bloom] <- c_customer_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=8B cardinality=2.88M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -51,7 +51,7 @@ tpcds_seq_snap.store_sales inner join tpcds.customer
 on ss_customer_sk = c_customer_sk
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=178.94MB mem-reservation=18.94MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=185.50MB mem-reservation=25.50MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: CAST(1 AS TINYINT)
 |  mem-estimate=61.64MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -60,7 +60,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_customer_sk = c_customer_sk
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF000[bloom] <- c_customer_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=0,1 row-size=8B cardinality=7.99M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection.test b/testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection.test
index ad7077e..720d423 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection.test
@@ -177,7 +177,7 @@ tpcds.store_sales inner join tpcds.web_sales
 on ss_sold_time_sk = ws_sold_time_sk
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=397.67MB mem-reservation=51.00MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=435.35MB mem-reservation=51.00MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: tpcds.store_sales.ss_sold_time_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_customer_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_quantity, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_sales_price, tpcds.store_sales.ss_ext_discount_amt, tpcds.store_ [...]
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -186,7 +186,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_sold_time_sk = ws_sold_time_sk
 |  fk/pk conjuncts: none
 |  runtime filters: RF000[bloom] <- ws_sold_time_sk
-|  mem-estimate=108.67MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=146.35MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=244B cardinality=44.14M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -265,7 +265,7 @@ where ss_item_sk = sr_item_sk and ss_ticket_number = sr_ticket_number
   and d1.d_fy_week_seq = 1000
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=362.81MB mem-reservation=50.81MB thread-reservation=6 runtime-filters-memory=5.00MB
+|  Per-Host Resources: mem-estimate=372.19MB mem-reservation=60.19MB thread-reservation=6 runtime-filters-memory=5.00MB
 PLAN-ROOT SINK
 |  output exprs: CAST(1 AS TINYINT)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -274,7 +274,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_addr_sk = c_current_addr_sk
 |  fk/pk conjuncts: none
 |  runtime filters: RF000[bloom] <- c_current_addr_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=1,0,3,4,2 row-size=60B cardinality=19.36K
 |  in pipelines: 01(GETNEXT), 02(OPEN)
 |
@@ -292,7 +292,7 @@ PLAN-ROOT SINK
 |  hash predicates: sr_returned_date_sk = d2.d_date_sk
 |  fk/pk conjuncts: sr_returned_date_sk = d2.d_date_sk
 |  runtime filters: RF002[bloom] <- d2.d_date_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=1,0,3,4 row-size=56B cardinality=8.13K
 |  in pipelines: 01(GETNEXT), 04(OPEN)
 |
@@ -445,7 +445,7 @@ tpcds_seq_snap.store_sales inner join tpcds.customer
 on ss_customer_sk = c_customer_sk
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=178.94MB mem-reservation=18.94MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=185.50MB mem-reservation=25.50MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: CAST(1 AS TINYINT)
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -454,7 +454,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_customer_sk = c_customer_sk
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF000[bloom] <- c_customer_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=0,1 row-size=8B cardinality=unavailable
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -497,7 +497,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_sold_time_sk = ws_sold_time_sk
 |  fk/pk conjuncts: none
 |  runtime filters: RF000[bloom] <- ws_sold_time_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,2 row-size=104B cardinality=2.44M
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/max-row-size.test b/testdata/workloads/functional-planner/queries/PlannerTest/max-row-size.test
index 36e2de6..0559ff9 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/max-row-size.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/max-row-size.test
@@ -65,7 +65,7 @@ from tpch_parquet.lineitem
     left join tpch_parquet.orders on l_orderkey = o_orderkey
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=126.00MB Threads=5
-Per-Host Resource Estimates: Memory=510MB
+Per-Host Resource Estimates: Memory=550MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.lineitem LEFT
 OUTER JOIN tpch_parquet.orders ON l_orderkey = o_orderkey
 
@@ -81,11 +81,11 @@ PLAN-ROOT SINK
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=359.29MB mem-reservation=86.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=398.84MB mem-reservation=86.00MB thread-reservation=2
 02:HASH JOIN [LEFT OUTER JOIN, BROADCAST]
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
-|  mem-estimate=268.94MB mem-reservation=46.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=308.49MB mem-reservation=46.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1N row-size=402B cardinality=6.00M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -121,8 +121,8 @@ Per-Host Resources: mem-estimate=359.29MB mem-reservation=86.00MB thread-reserva
 select * from tpch_parquet.lineitem
 where l_orderkey not in (select o_orderkey from tpch_parquet.orders)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=94.00MB Threads=5
-Per-Host Resource Estimates: Memory=275MB
+Max Per-Host Resource Reservation: Memory=112.00MB Threads=5
+Per-Host Resource Estimates: Memory=320MB
 Analyzed query: SELECT * FROM tpch_parquet.lineitem NULL AWARE LEFT ANTI JOIN
 (SELECT o_orderkey FROM tpch_parquet.orders) `$a$1` (`$c$1`) ON l_orderkey =
 `$a$1`.`$c$1`
@@ -139,10 +139,10 @@ PLAN-ROOT SINK
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=124.02MB mem-reservation=74.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=169.47MB mem-reservation=92.00MB thread-reservation=2
 02:HASH JOIN [NULL AWARE LEFT ANTI JOIN, BROADCAST]
 |  hash predicates: l_orderkey = o_orderkey
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=79.44MB mem-reservation=52.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0 row-size=231B cardinality=6.00M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -181,8 +181,8 @@ from tpch_parquet.lineitem
 group by 1, 2
 having count(*) = 1
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=126.00MB Threads=7
-Per-Host Resource Estimates: Memory=372MB
+Max Per-Host Resource Reservation: Memory=156.00MB Threads=7
+Per-Host Resource Estimates: Memory=437MB
 Analyzed query: SELECT /* +straight_join */ l_orderkey, o_orderstatus, count(*)
 FROM tpch_parquet.lineitem INNER JOIN tpch_parquet.orders ON o_orderkey =
 l_orderkey GROUP BY l_orderkey, o_orderstatus HAVING count(*) = CAST(1 AS
@@ -200,12 +200,12 @@ PLAN-ROOT SINK
 |  in pipelines: 07(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(l_orderkey,o_orderstatus)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=41.10MB mem-reservation=31.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=77.19MB mem-reservation=46.00MB thread-reservation=1
 07:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
 |  group by: l_orderkey, o_orderstatus
 |  having: count(*) = CAST(1 AS BIGINT)
-|  mem-estimate=31.00MB mem-reservation=31.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=67.10MB mem-reservation=46.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=29B cardinality=4.69M
 |  in pipelines: 07(GETNEXT), 00(OPEN)
 |
@@ -215,11 +215,11 @@ Per-Host Resources: mem-estimate=41.10MB mem-reservation=31.00MB thread-reservat
 |  in pipelines: 00(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=99.65MB mem-reservation=66.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=128.86MB mem-reservation=81.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 03:AGGREGATE [STREAMING]
 |  output: count(*)
 |  group by: l_orderkey, o_orderstatus
-|  mem-estimate=47.56MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=61.77MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=29B cardinality=4.69M
 |  in pipelines: 00(GETNEXT)
 |
@@ -227,7 +227,7 @@ Per-Host Resources: mem-estimate=99.65MB mem-reservation=66.00MB thread-reservat
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF000[bloom] <- o_orderkey
-|  mem-estimate=31.00MB mem-reservation=31.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=46.00MB mem-reservation=46.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=29B cardinality=5.76M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -272,7 +272,7 @@ select distinct *
 from tpch_parquet.lineitem
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=136.00MB Threads=4
-Per-Host Resource Estimates: Memory=1.62GB
+Per-Host Resource Estimates: Memory=1.00GB
 Analyzed query: SELECT DISTINCT * FROM tpch_parquet.lineitem
 
 F02:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
@@ -287,10 +287,10 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(tpch_parquet.lineitem.l_orderkey,tpch_parquet.lineitem.l_partkey,tpch_parquet.lineitem.l_suppkey,tpch_parquet.lineitem.l_linenumber,tpch_parquet.lineitem.l_quantity,tpch_parquet.lineitem.l_extendedprice,tpch_parquet.lineitem.l_discount,tpch_parquet.lineitem.l_tax,tpch_parquet.lineitem.l_returnflag,tpch_parquet.lineitem.l_linestatus,tpch_parquet.lineitem.l_shipdate,tpch_parquet.lineitem.l_commitdate,tpch_parquet.lineitem.l_receiptdate,tpch_parquet.lineitem.l_shipin [...]
-Per-Host Resources: mem-estimate=737.12MB mem-reservation=46.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=481.48MB mem-reservation=46.00MB thread-reservation=1
 03:AGGREGATE [FINALIZE]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
-|  mem-estimate=726.43MB mem-reservation=46.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=470.79MB mem-reservation=46.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -300,10 +300,10 @@ Per-Host Resources: mem-estimate=737.12MB mem-reservation=46.00MB thread-reserva
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=806.43MB mem-reservation=74.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=433.09MB mem-reservation=74.00MB thread-reservation=2
 01:AGGREGATE [STREAMING]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
-|  mem-estimate=726.43MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=353.09MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 00(GETNEXT)
 |
@@ -324,7 +324,7 @@ from tpch_parquet.lineitem
 group by 1, 2
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=114.00MB Threads=4
-Per-Host Resource Estimates: Memory=376MB
+Per-Host Resource Estimates: Memory=347MB
 Analyzed query: SELECT l_orderkey, l_partkey, group_concat(l_linestatus, ',')
 FROM tpch_parquet.lineitem GROUP BY l_orderkey, l_partkey
 
@@ -340,11 +340,11 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(l_orderkey,l_partkey)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=98.23MB mem-reservation=48.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=94.03MB mem-reservation=48.00MB thread-reservation=1
 03:AGGREGATE [FINALIZE]
 |  output: group_concat:merge(l_linestatus, ',')
 |  group by: l_orderkey, l_partkey
-|  mem-estimate=88.14MB mem-reservation=48.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=83.94MB mem-reservation=48.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=28B cardinality=6.00M
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -354,11 +354,11 @@ Per-Host Resources: mem-estimate=98.23MB mem-reservation=48.00MB thread-reservat
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=168.14MB mem-reservation=50.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=142.96MB mem-reservation=50.00MB thread-reservation=2
 01:AGGREGATE [STREAMING]
 |  output: group_concat(l_linestatus, ',')
 |  group by: l_orderkey, l_partkey
-|  mem-estimate=88.14MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=62.96MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=28B cardinality=6.00M
 |  in pipelines: 00(GETNEXT)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/min-max-runtime-filters-hdfs-num-rows-est-enabled.test b/testdata/workloads/functional-planner/queries/PlannerTest/min-max-runtime-filters-hdfs-num-rows-est-enabled.test
index 4d4821a..37fe50b 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/min-max-runtime-filters-hdfs-num-rows-est-enabled.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/min-max-runtime-filters-hdfs-num-rows-est-enabled.test
@@ -8,14 +8,14 @@ select count(*) from functional_kudu.alltypes a, functional_parquet.alltypes b,
 where a.int_col = b.int_col and a.int_col = c.int_col
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=31.88MB mem-reservation=5.89MB thread-reservation=4 runtime-filters-memory=2.00MB
+|  Per-Host Resources: mem-estimate=23.38MB mem-reservation=5.89MB thread-reservation=4 runtime-filters-memory=2.00MB
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 05:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=8B cardinality=1
 |  in pipelines: 05(GETNEXT), 01(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/min-max-runtime-filters.test b/testdata/workloads/functional-planner/queries/PlannerTest/min-max-runtime-filters.test
index 685ac15..f436ff7 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/min-max-runtime-filters.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/min-max-runtime-filters.test
@@ -3,14 +3,14 @@ select count(*) from functional_kudu.alltypes a, functional_kudu.alltypestiny b
 where a.int_col = b.tinyint_col + 1 and a.string_col = b.string_col
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=13.44MB mem-reservation=1.94MB thread-reservation=3
+|  Per-Host Resources: mem-estimate=4.94MB mem-reservation=1.94MB thread-reservation=3
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -41,14 +41,14 @@ where a.int_col + 1 = b.int_col
     and a.tinyint_col is not distinct from b.tinyint_col
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.19MB mem-reservation=1.94MB thread-reservation=3
+|  Per-Host Resources: mem-estimate=6.44MB mem-reservation=1.94MB thread-reservation=3
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -78,14 +78,14 @@ where a.tinyint_col = b.bigint_col
     and cast(a.float_col as double) = b.double_col
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.94MB mem-reservation=1.94MB thread-reservation=3
+|  Per-Host Resources: mem-estimate=7.94MB mem-reservation=1.94MB thread-reservation=3
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -121,7 +121,7 @@ PLAN-ROOT SINK
 |
 05:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=8B cardinality=1
 |  in pipelines: 05(GETNEXT), 00(OPEN)
 |
@@ -171,14 +171,14 @@ select STRAIGHT_JOIN count(*) from functional_kudu.date_tbl a,
 where a.date_col = b.date_col and b.id_col = c.id_col
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.62MB mem-reservation=3.88MB thread-reservation=4
+|  Per-Host Resources: mem-estimate=6.88MB mem-reservation=3.88MB thread-reservation=4
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 05:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=8B cardinality=1
 |  in pipelines: 05(GETNEXT), 00(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/mt-dop-validation.test b/testdata/workloads/functional-planner/queries/PlannerTest/mt-dop-validation.test
index 96197c9..d99cc03 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/mt-dop-validation.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/mt-dop-validation.test
@@ -4,14 +4,14 @@ functional_parquet.alltypestiny a,
 functional_parquet.alltypestiny b
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=2.04GB mem-reservation=16.00KB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=2.03GB mem-reservation=16.00KB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -43,14 +43,14 @@ PLAN-ROOT SINK
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 F02:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=116.00KB mem-reservation=0B thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 06:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 06(GETNEXT), 03(OPEN)
 |
@@ -60,10 +60,10 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=4
-Per-Instance Resources: mem-estimate=26.00MB mem-reservation=8.00KB thread-reservation=1
+Per-Instance Resources: mem-estimate=16.10MB mem-reservation=8.00KB thread-reservation=1
 03:AGGREGATE
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -122,7 +122,7 @@ PLAN-ROOT SINK
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -158,14 +158,14 @@ PLAN-ROOT SINK
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 F02:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=116.00KB mem-reservation=0B thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 06:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 06(GETNEXT), 03(OPEN)
 |
@@ -176,10 +176,10 @@ PLAN-ROOT SINK
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=4
 Per-Host Shared Resources: mem-estimate=1.00MB mem-reservation=1.00MB thread-reservation=0 runtime-filters-memory=1.00MB
-Per-Instance Resources: mem-estimate=26.00MB mem-reservation=8.00KB thread-reservation=1
+Per-Instance Resources: mem-estimate=16.10MB mem-reservation=8.00KB thread-reservation=1
 03:AGGREGATE
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -234,7 +234,7 @@ insert into functional_parquet.alltypes partition(year,month)
 select * from functional_parquet.alltypessmall
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=1.01GB mem-reservation=12.09MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=1.12GB mem-reservation=12.09MB thread-reservation=1
 WRITE TO HDFS [functional_parquet.alltypes, OVERWRITE=false, PARTITION-KEYS=(year,month)]
 |  partitions=4
 |  output exprs: id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, float_col, double_col, date_string_col, string_col, timestamp_col, year, month
@@ -242,7 +242,7 @@ WRITE TO HDFS [functional_parquet.alltypes, OVERWRITE=false, PARTITION-KEYS=(yea
 |
 01:SORT
 |  order by: year ASC NULLS LAST, month ASC NULLS LAST
-|  mem-estimate=12.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=128.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=80B cardinality=unavailable
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -258,7 +258,7 @@ WRITE TO HDFS [functional_parquet.alltypes, OVERWRITE=false, PARTITION-KEYS=(yea
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=4
-|  Per-Instance Resources: mem-estimate=1.01GB mem-reservation=12.09MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=1.12GB mem-reservation=12.09MB thread-reservation=1
 WRITE TO HDFS [functional_parquet.alltypes, OVERWRITE=false, PARTITION-KEYS=(year,month)]
 |  partitions=4
 |  output exprs: id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, float_col, double_col, date_string_col, string_col, timestamp_col, year, month
@@ -266,7 +266,7 @@ WRITE TO HDFS [functional_parquet.alltypes, OVERWRITE=false, PARTITION-KEYS=(yea
 |
 01:SORT
 |  order by: year ASC NULLS LAST, month ASC NULLS LAST
-|  mem-estimate=12.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=128.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=80B cardinality=unavailable
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -422,7 +422,7 @@ from functional_parquet.alltypes
 where id < 10
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=10.02MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=148.00MB mem-reservation=10.02MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: row_number()
 |  mem-estimate=10.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -438,7 +438,7 @@ PLAN-ROOT SINK
 |
 01:SORT
 |  order by: int_col ASC NULLS LAST, id ASC
-|  mem-estimate=6.00MB mem-reservation=6.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=128.00MB mem-reservation=6.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=4 row-size=8B cardinality=unavailable
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -468,7 +468,7 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(int_col)] hosts=3 instances=9
-Per-Instance Resources: mem-estimate=10.11MB mem-reservation=10.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=132.11MB mem-reservation=10.00MB thread-reservation=1
 02:ANALYTIC
 |  functions: row_number()
 |  partition by: int_col
@@ -480,7 +480,7 @@ Per-Instance Resources: mem-estimate=10.11MB mem-reservation=10.00MB thread-rese
 |
 01:SORT
 |  order by: int_col ASC NULLS LAST, id ASC
-|  mem-estimate=6.00MB mem-reservation=6.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=128.00MB mem-reservation=6.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=4 row-size=8B cardinality=unavailable
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/parquet-filtering-disabled.test b/testdata/workloads/functional-planner/queries/PlannerTest/parquet-filtering-disabled.test
index 54a1e8b..eb95d34 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/parquet-filtering-disabled.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/parquet-filtering-disabled.test
@@ -9,14 +9,14 @@ where int_col > 1 and int_col * rand() > 50 and int_col is null
 and int_col > tinyint_col;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=16.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.10MB mem-reservation=16.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -47,14 +47,14 @@ and timestamp_cmp(timestamp_col, '2016-11-20 00:00:00') = 1
 and year > 2000 and month < 12;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=138.00MB mem-reservation=88.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=128.10MB mem-reservation=88.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -79,14 +79,14 @@ and mod(int_col,50) IN (0,1)
 and id IN (int_col);
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=58.00MB mem-reservation=24.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=48.10MB mem-reservation=24.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -329,14 +329,14 @@ and timestamp_cmp(timestamp_col, '2016-11-20 00:00:00') = 1
 and year > 2000 and month < 12;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=138.00MB mem-reservation=88.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=128.10MB mem-reservation=88.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/parquet-filtering.test b/testdata/workloads/functional-planner/queries/PlannerTest/parquet-filtering.test
index 95923d9..051f579 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/parquet-filtering.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/parquet-filtering.test
@@ -8,14 +8,14 @@ where int_col > 1 and int_col * rand() > 50 and int_col is null
 and int_col > tinyint_col;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=16.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.10MB mem-reservation=16.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -39,14 +39,14 @@ where int_col > 1 and int_col * rand() > 50 and int_col is null
 and int_col > tinyint_col;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=138.00MB mem-reservation=32.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=128.10MB mem-reservation=32.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -72,14 +72,14 @@ and timestamp_cmp(timestamp_col, '2016-11-20 00:00:00') = 1
 and year > 2000 and month < 12;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=138.00MB mem-reservation=88.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=128.10MB mem-reservation=88.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -108,14 +108,14 @@ and timestamp_cmp(timestamp_col, '2016-11-20 00:00:00') = 1
 and year > 2000 and month < 12;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=138.00MB mem-reservation=32.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=128.10MB mem-reservation=32.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -143,14 +143,14 @@ and mod(int_col,50) IN (0,1)
 and id IN (int_col);
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=58.00MB mem-reservation=24.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=48.10MB mem-reservation=24.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -455,14 +455,14 @@ select count(*) from functional_parquet.complextypestbl c left outer join
 (select * from c.int_array where item > 10) v;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=26.00MB mem-reservation=8.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=16.10MB mem-reservation=8.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 05:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=8B cardinality=1
 |  in pipelines: 05(GETNEXT), 00(OPEN)
 |
@@ -583,14 +583,14 @@ and timestamp_cmp(timestamp_col, '2016-11-20 00:00:00') = 1
 and year > 2000 and month < 12;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=138.00MB mem-reservation=88.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=128.10MB mem-reservation=88.00KB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -620,14 +620,14 @@ and timestamp_cmp(timestamp_col, '2016-11-20 00:00:00') = 1
 and year != 2009 and month != 4;
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.00MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=100.00KB mem-reservation=0B thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=100.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/partition-pruning.test b/testdata/workloads/functional-planner/queries/PlannerTest/partition-pruning.test
index dfc4533..db0c19b 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/partition-pruning.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/partition-pruning.test
@@ -38,7 +38,7 @@ PLAN-ROOT SINK
      partitions: 1/1 rows=1
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=4
-   mem-estimate=16.00MB mem-reservation=8.00KB thread-reservation=1
+   mem-estimate=32.00MB mem-reservation=8.00KB thread-reservation=1
    tuple-ids=0 row-size=16B cardinality=1
    in pipelines: 00(GETNEXT)
 ====
@@ -59,7 +59,7 @@ PLAN-ROOT SINK
      partitions: 1/1 rows=1
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=4
-   mem-estimate=16.00MB mem-reservation=8.00KB thread-reservation=1
+   mem-estimate=32.00MB mem-reservation=8.00KB thread-reservation=1
    tuple-ids=0 row-size=16B cardinality=1
    in pipelines: 00(GETNEXT)
 ====
@@ -80,7 +80,7 @@ PLAN-ROOT SINK
      partitions: 1/1 rows=1
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=4
-   mem-estimate=16.00MB mem-reservation=8.00KB thread-reservation=1
+   mem-estimate=32.00MB mem-reservation=8.00KB thread-reservation=1
    tuple-ids=0 row-size=16B cardinality=1
    in pipelines: 00(GETNEXT)
 ====
@@ -101,7 +101,7 @@ PLAN-ROOT SINK
      partitions: 1/1 rows=1
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=4
-   mem-estimate=16.00MB mem-reservation=8.00KB thread-reservation=1
+   mem-estimate=32.00MB mem-reservation=8.00KB thread-reservation=1
    tuple-ids=0 row-size=16B cardinality=1
    in pipelines: 00(GETNEXT)
 ====
@@ -122,7 +122,7 @@ PLAN-ROOT SINK
      partitions: 2/2 rows=2
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=2
-   mem-estimate=16.00MB mem-reservation=8.00KB thread-reservation=1
+   mem-estimate=32.00MB mem-reservation=8.00KB thread-reservation=1
    tuple-ids=0 row-size=16B cardinality=2
    in pipelines: 00(GETNEXT)
 ====
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/preagg-bytes-limit.test b/testdata/workloads/functional-planner/queries/PlannerTest/preagg-bytes-limit.test
index c9a2c7a..51d62a0 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/preagg-bytes-limit.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/preagg-bytes-limit.test
@@ -13,10 +13,10 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(l_orderkey,l_partkey,l_suppkey)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=85.63MB mem-reservation=34.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=86.39MB mem-reservation=34.00MB thread-reservation=1
 03:AGGREGATE [FINALIZE]
 |  group by: l_orderkey, l_partkey, l_suppkey
-|  mem-estimate=75.55MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=76.31MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=24B cardinality=6.00M
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -26,10 +26,10 @@ Per-Host Resources: mem-estimate=85.63MB mem-reservation=34.00MB thread-reservat
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=304.00MB mem-reservation=50.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=297.23MB mem-reservation=50.00MB thread-reservation=2
 01:AGGREGATE [STREAMING]
 |  group by: l_orderkey, l_partkey, l_suppkey
-|  mem-estimate=64.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=57.23MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=24B cardinality=6.00M
 |  in pipelines: 00(GETNEXT)
 |
@@ -118,10 +118,10 @@ Per-Host Resources: mem-estimate=146.08MB mem-reservation=136.00MB thread-reserv
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=376.00MB mem-reservation=152.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=308.00MB mem-reservation=84.00MB thread-reservation=2
 01:AGGREGATE [STREAMING]
 |  group by: l_orderkey, l_partkey, l_suppkey
-|  mem-estimate=136.00MB mem-reservation=136.00MB spill-buffer=8.00MB thread-reservation=0
+|  mem-estimate=68.00MB mem-reservation=68.00MB spill-buffer=4.00MB thread-reservation=0
 |  tuple-ids=1 row-size=24B cardinality=6.00M
 |  in pipelines: 00(GETNEXT)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/resource-requirements.test b/testdata/workloads/functional-planner/queries/PlannerTest/resource-requirements.test
index cae299a..8981e6b 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/resource-requirements.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/resource-requirements.test
@@ -2002,12 +2002,12 @@ from tpch_parquet.lineitem
 group by l_orderkey
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=38.00MB Threads=2
-Per-Host Resource Estimates: Memory=114MB
+Per-Host Resource Estimates: Memory=128MB
 Analyzed query: SELECT l_orderkey, count(*) FROM tpch_parquet.lineitem GROUP BY
 l_orderkey
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=114.00MB mem-reservation=38.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=127.71MB mem-reservation=38.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: l_orderkey, count(*)
 |  mem-estimate=23.86MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -2015,7 +2015,7 @@ PLAN-ROOT SINK
 01:AGGREGATE [FINALIZE]
 |  output: count(*)
 |  group by: l_orderkey
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=47.71MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=16B cardinality=1.56M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -2029,8 +2029,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=8B cardinality=6.00M
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=50.50MB Threads=4
-Per-Host Resource Estimates: Memory=164MB
+Max Per-Host Resource Reservation: Memory=59.00MB Threads=4
+Per-Host Resource Estimates: Memory=183MB
 Analyzed query: SELECT l_orderkey, count(*) FROM tpch_parquet.lineitem GROUP BY
 l_orderkey
 
@@ -2046,11 +2046,11 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=18.01MB mem-reservation=8.50MB thread-reservation=1
+Per-Host Resources: mem-estimate=25.01MB mem-reservation=17.00MB thread-reservation=1
 03:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
 |  group by: l_orderkey
-|  mem-estimate=10.00MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=1 row-size=16B cardinality=1.56M
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -2060,11 +2060,11 @@ Per-Host Resources: mem-estimate=18.01MB mem-reservation=8.50MB thread-reservati
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=114.00MB mem-reservation=38.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=125.79MB mem-reservation=38.00MB thread-reservation=2
 01:AGGREGATE [STREAMING]
 |  output: count(*)
 |  group by: l_orderkey
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=45.79MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=16B cardinality=1.56M
 |  in pipelines: 00(GETNEXT)
 |
@@ -2078,8 +2078,8 @@ Per-Host Resources: mem-estimate=114.00MB mem-reservation=38.00MB thread-reserva
    tuple-ids=0 row-size=8B cardinality=6.00M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=50.50MB Threads=3
-Per-Host Resource Estimates: Memory=164MB
+Max Per-Host Resource Reservation: Memory=59.00MB Threads=3
+Per-Host Resource Estimates: Memory=183MB
 Analyzed query: SELECT l_orderkey, count(*) FROM tpch_parquet.lineitem GROUP BY
 l_orderkey
 
@@ -2095,11 +2095,11 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=18.01MB mem-reservation=8.50MB thread-reservation=1
+Per-Instance Resources: mem-estimate=25.01MB mem-reservation=17.00MB thread-reservation=1
 03:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
 |  group by: l_orderkey
-|  mem-estimate=10.00MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=1 row-size=16B cardinality=1.56M
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -2109,11 +2109,11 @@ Per-Instance Resources: mem-estimate=18.01MB mem-reservation=8.50MB thread-reser
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=114.00MB mem-reservation=38.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=125.79MB mem-reservation=38.00MB thread-reservation=1
 01:AGGREGATE [STREAMING]
 |  output: count(*)
 |  group by: l_orderkey
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=45.79MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=16B cardinality=1.56M
 |  in pipelines: 00(GETNEXT)
 |
@@ -2131,18 +2131,18 @@ Per-Instance Resources: mem-estimate=114.00MB mem-reservation=38.00MB thread-res
 select count(*) from tpch_parquet.lineitem
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=4.00MB Threads=2
-Per-Host Resource Estimates: Memory=14MB
+Per-Host Resource Estimates: Memory=10MB
 Analyzed query: SELECT count(*) FROM tpch_parquet.lineitem
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.00MB mem-reservation=4.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: sum_init_zero(tpch_parquet.lineitem.stats: num_rows)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -2157,18 +2157,18 @@ PLAN-ROOT SINK
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=4.12MB Threads=3
-Per-Host Resource Estimates: Memory=25MB
+Per-Host Resource Estimates: Memory=10MB
 Analyzed query: SELECT count(*) FROM tpch_parquet.lineitem
 
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.00MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 01(OPEN)
 |
@@ -2178,10 +2178,10 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=11.00MB mem-reservation=128.00KB thread-reservation=2
+Per-Host Resources: mem-estimate=1.02MB mem-reservation=128.00KB thread-reservation=2
 01:AGGREGATE
 |  output: sum_init_zero(tpch_parquet.lineitem.stats: num_rows)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -2196,18 +2196,18 @@ Per-Host Resources: mem-estimate=11.00MB mem-reservation=128.00KB thread-reserva
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=4.12MB Threads=2
-Per-Host Resource Estimates: Memory=104MB
+Per-Host Resource Estimates: Memory=84MB
 Analyzed query: SELECT count(*) FROM tpch_parquet.lineitem
 
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=14.00MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 01(OPEN)
 |
@@ -2217,10 +2217,10 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=90.00MB mem-reservation=128.00KB thread-reservation=1
+Per-Instance Resources: mem-estimate=80.02MB mem-reservation=128.00KB thread-reservation=1
 01:AGGREGATE
 |  output: sum_init_zero(tpch_parquet.lineitem.stats: num_rows)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -2240,18 +2240,18 @@ from tpch_parquet.lineitem
 order by l_comment
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=52.00MB Threads=2
-Per-Host Resource Estimates: Memory=138MB
+Per-Host Resource Estimates: Memory=1.39GB
 Analyzed query: SELECT * FROM tpch_parquet.lineitem ORDER BY l_comment ASC
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=138.00MB mem-reservation=52.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=1.39GB mem-reservation=52.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:SORT
 |  order by: l_comment ASC
-|  mem-estimate=38.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=1.29GB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -2266,7 +2266,7 @@ PLAN-ROOT SINK
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=56.00MB Threads=3
-Per-Host Resource Estimates: Memory=249MB
+Per-Host Resource Estimates: Memory=651MB
 Analyzed query: SELECT * FROM tpch_parquet.lineitem ORDER BY l_comment ASC
 
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
@@ -2282,10 +2282,10 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=118.00MB mem-reservation=52.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=520.26MB mem-reservation=52.00MB thread-reservation=2
 01:SORT
 |  order by: l_comment ASC
-|  mem-estimate=38.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=440.26MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -2300,7 +2300,7 @@ Per-Host Resources: mem-estimate=118.00MB mem-reservation=52.00MB thread-reserva
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=56.00MB Threads=2
-Per-Host Resource Estimates: Memory=249MB
+Per-Host Resource Estimates: Memory=651MB
 Analyzed query: SELECT * FROM tpch_parquet.lineitem ORDER BY l_comment ASC
 
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
@@ -2316,10 +2316,10 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=118.00MB mem-reservation=52.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=520.26MB mem-reservation=52.00MB thread-reservation=1
 01:SORT
 |  order by: l_comment ASC
-|  mem-estimate=38.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=440.26MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -2634,12 +2634,12 @@ select *
 from tpch.lineitem inner join tpch.orders on l_orderkey = o_orderkey
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=51.00MB Threads=3
-Per-Host Resource Estimates: Memory=458MB
+Per-Host Resource Estimates: Memory=497MB
 Analyzed query: SELECT * FROM tpch.lineitem INNER JOIN tpch.orders ON l_orderkey
 = o_orderkey
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=457.94MB mem-reservation=51.00MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=497.49MB mem-reservation=51.00MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: tpch.lineitem.l_orderkey, tpch.lineitem.l_partkey, tpch.lineitem.l_suppkey, tpch.lineitem.l_linenumber, tpch.lineitem.l_quantity, tpch.lineitem.l_extendedprice, tpch.lineitem.l_discount, tpch.lineitem.l_tax, tpch.lineitem.l_returnflag, tpch.lineitem.l_linestatus, tpch.lineitem.l_shipdate, tpch.lineitem.l_commitdate, tpch.lineitem.l_receiptdate, tpch.lineitem.l_shipinstruct, tpch.lineitem.l_shipmode, tpch.lineitem.l_comment, tpch.orders.o_orderkey, tpch.orders.o_custkey,  [...]
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -2648,7 +2648,7 @@ PLAN-ROOT SINK
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF000[bloom] <- o_orderkey
-|  mem-estimate=268.94MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=308.49MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=402B cardinality=5.76M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -2674,7 +2674,7 @@ PLAN-ROOT SINK
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=55.00MB Threads=5
-Per-Host Resource Estimates: Memory=567MB
+Per-Host Resource Estimates: Memory=607MB
 Analyzed query: SELECT * FROM tpch.lineitem INNER JOIN tpch.orders ON l_orderkey
 = o_orderkey
 
@@ -2690,12 +2690,12 @@ PLAN-ROOT SINK
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=368.29MB mem-reservation=43.00MB thread-reservation=2 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=407.84MB mem-reservation=43.00MB thread-reservation=2 runtime-filters-memory=1.00MB
 02:HASH JOIN [INNER JOIN, BROADCAST]
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF000[bloom] <- o_orderkey
-|  mem-estimate=268.94MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=308.49MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=402B cardinality=5.76M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -2728,7 +2728,7 @@ Per-Host Resources: mem-estimate=368.29MB mem-reservation=43.00MB thread-reserva
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=98.00MB Threads=5
-Per-Host Resource Estimates: Memory=658MB
+Per-Host Resource Estimates: Memory=697MB
 Analyzed query: SELECT * FROM tpch.lineitem INNER JOIN tpch.orders ON l_orderkey
 = o_orderkey
 
@@ -2755,12 +2755,12 @@ Per-Instance Resources: mem-estimate=88.00MB mem-reservation=8.00MB thread-reser
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F03:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=280.29MB mem-reservation=69.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=319.84MB mem-reservation=69.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: o_orderkey
 |  |  runtime filters: RF000[bloom] <- o_orderkey
-|  |  mem-estimate=268.94MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=308.49MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  03:EXCHANGE [BROADCAST]
 |  |  mem-estimate=10.34MB mem-reservation=0B thread-reservation=0
@@ -2795,12 +2795,12 @@ select *
 from tpch.lineitem inner join /* +shuffle */ tpch.orders on l_orderkey = o_orderkey
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=51.00MB Threads=3
-Per-Host Resource Estimates: Memory=458MB
+Per-Host Resource Estimates: Memory=497MB
 Analyzed query: SELECT * FROM tpch.lineitem INNER JOIN /* +shuffle */
 tpch.orders ON l_orderkey = o_orderkey
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=457.94MB mem-reservation=51.00MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=497.49MB mem-reservation=51.00MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: tpch.lineitem.l_orderkey, tpch.lineitem.l_partkey, tpch.lineitem.l_suppkey, tpch.lineitem.l_linenumber, tpch.lineitem.l_quantity, tpch.lineitem.l_extendedprice, tpch.lineitem.l_discount, tpch.lineitem.l_tax, tpch.lineitem.l_returnflag, tpch.lineitem.l_linestatus, tpch.lineitem.l_shipdate, tpch.lineitem.l_commitdate, tpch.lineitem.l_receiptdate, tpch.lineitem.l_shipinstruct, tpch.lineitem.l_shipmode, tpch.lineitem.l_comment, tpch.orders.o_orderkey, tpch.orders.o_custkey,  [...]
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -2809,7 +2809,7 @@ PLAN-ROOT SINK
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF000[bloom] <- o_orderkey
-|  mem-estimate=268.94MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=308.49MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=402B cardinality=5.76M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -2835,7 +2835,7 @@ PLAN-ROOT SINK
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=56.00MB Threads=6
-Per-Host Resource Estimates: Memory=400MB
+Per-Host Resource Estimates: Memory=413MB
 Analyzed query: SELECT * FROM tpch.lineitem INNER JOIN /* +shuffle */
 tpch.orders ON l_orderkey = o_orderkey
 
@@ -2851,12 +2851,12 @@ PLAN-ROOT SINK
 |  in pipelines: 00(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=111.68MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=124.86MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 02:HASH JOIN [INNER JOIN, PARTITIONED]
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF000[bloom] <- o_orderkey
-|  mem-estimate=89.65MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=102.83MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=402B cardinality=5.76M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -2896,7 +2896,7 @@ Per-Host Resources: mem-estimate=89.00MB mem-reservation=9.00MB thread-reservati
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=99.00MB Threads=8
-Per-Host Resource Estimates: Memory=512MB
+Per-Host Resource Estimates: Memory=526MB
 Analyzed query: SELECT * FROM tpch.lineitem INNER JOIN /* +shuffle */
 tpch.orders ON l_orderkey = o_orderkey
 
@@ -2922,12 +2922,12 @@ Per-Instance Resources: mem-estimate=11.38MB mem-reservation=0B thread-reservati
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F04:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=56.17MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=62.76MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: o_orderkey
 |  |  runtime filters: RF000[bloom] <- o_orderkey
-|  |  mem-estimate=44.82MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=51.42MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  04:EXCHANGE [HASH(o_orderkey)]
 |  |  mem-estimate=10.34MB mem-reservation=0B thread-reservation=0
@@ -3308,13 +3308,13 @@ select *, row_number() over (order by o_totalprice) rnum_price,
 from tpch_parquet.orders
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=48.00MB Threads=2
-Per-Host Resource Estimates: Memory=122MB
+Per-Host Resource Estimates: Memory=531MB
 Analyzed query: SELECT *, row_number() OVER (ORDER BY o_totalprice ASC)
 rnum_price, row_number() OVER (ORDER BY o_orderdate ASC) rnum_date, row_number()
 OVER (ORDER BY o_orderpriority ASC) rnum_priority FROM tpch_parquet.orders
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=122.00MB mem-reservation=48.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=531.32MB mem-reservation=48.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: o_orderkey, o_custkey, o_orderstatus, o_totalprice, o_orderdate, o_orderpriority, o_clerk, o_shippriority, o_comment, row_number(), row_number(), row_number()
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -3329,7 +3329,7 @@ PLAN-ROOT SINK
 |
 05:SORT
 |  order by: o_orderpriority ASC
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=267.38MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=10 row-size=187B cardinality=1.50M
 |  in pipelines: 05(GETNEXT), 03(OPEN)
 |
@@ -3343,7 +3343,7 @@ PLAN-ROOT SINK
 |
 03:SORT
 |  order by: o_orderdate ASC
-|  mem-estimate=16.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=255.94MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=8 row-size=179B cardinality=1.50M
 |  in pipelines: 03(GETNEXT), 01(OPEN)
 |
@@ -3357,7 +3357,7 @@ PLAN-ROOT SINK
 |
 01:SORT
 |  order by: o_totalprice ASC
-|  mem-estimate=16.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=244.49MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=6 row-size=171B cardinality=1.50M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -3372,13 +3372,13 @@ PLAN-ROOT SINK
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=68.00MB Threads=3
-Per-Host Resource Estimates: Memory=178MB
+Per-Host Resource Estimates: Memory=694MB
 Analyzed query: SELECT *, row_number() OVER (ORDER BY o_totalprice ASC)
 rnum_price, row_number() OVER (ORDER BY o_orderdate ASC) rnum_date, row_number()
 OVER (ORDER BY o_orderpriority ASC) rnum_priority FROM tpch_parquet.orders
 
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=122.00MB mem-reservation=32.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=531.32MB mem-reservation=32.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: o_orderkey, o_custkey, o_orderstatus, o_totalprice, o_orderdate, o_orderpriority, o_clerk, o_shippriority, o_comment, row_number(), row_number(), row_number()
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -3393,7 +3393,7 @@ PLAN-ROOT SINK
 |
 05:SORT
 |  order by: o_orderpriority ASC
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=267.38MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=10 row-size=187B cardinality=1.50M
 |  in pipelines: 05(GETNEXT), 03(OPEN)
 |
@@ -3407,7 +3407,7 @@ PLAN-ROOT SINK
 |
 03:SORT
 |  order by: o_orderdate ASC
-|  mem-estimate=16.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=255.94MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=8 row-size=179B cardinality=1.50M
 |  in pipelines: 03(GETNEXT), 01(OPEN)
 |
@@ -3426,10 +3426,10 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-Per-Host Resources: mem-estimate=56.00MB mem-reservation=36.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=162.25MB mem-reservation=36.00MB thread-reservation=2
 01:SORT
 |  order by: o_totalprice ASC
-|  mem-estimate=16.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=122.25MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=6 row-size=171B cardinality=1.50M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -3444,13 +3444,13 @@ Per-Host Resources: mem-estimate=56.00MB mem-reservation=36.00MB thread-reservat
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=68.00MB Threads=2
-Per-Host Resource Estimates: Memory=178MB
+Per-Host Resource Estimates: Memory=694MB
 Analyzed query: SELECT *, row_number() OVER (ORDER BY o_totalprice ASC)
 rnum_price, row_number() OVER (ORDER BY o_orderdate ASC) rnum_date, row_number()
 OVER (ORDER BY o_orderpriority ASC) rnum_priority FROM tpch_parquet.orders
 
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=122.00MB mem-reservation=32.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=531.32MB mem-reservation=32.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: o_orderkey, o_custkey, o_orderstatus, o_totalprice, o_orderdate, o_orderpriority, o_clerk, o_shippriority, o_comment, row_number(), row_number(), row_number()
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -3465,7 +3465,7 @@ PLAN-ROOT SINK
 |
 05:SORT
 |  order by: o_orderpriority ASC
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=267.38MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=10 row-size=187B cardinality=1.50M
 |  in pipelines: 05(GETNEXT), 03(OPEN)
 |
@@ -3479,7 +3479,7 @@ PLAN-ROOT SINK
 |
 03:SORT
 |  order by: o_orderdate ASC
-|  mem-estimate=16.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=255.94MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=8 row-size=179B cardinality=1.50M
 |  in pipelines: 03(GETNEXT), 01(OPEN)
 |
@@ -3498,10 +3498,10 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-Per-Instance Resources: mem-estimate=56.00MB mem-reservation=36.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=162.25MB mem-reservation=36.00MB thread-reservation=1
 01:SORT
 |  order by: o_totalprice ASC
-|  mem-estimate=16.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=122.25MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=6 row-size=171B cardinality=1.50M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -3528,8 +3528,8 @@ select l_orderkey, l_partkey, l_suppkey, l_linenumber, l_comment
 from tpch_parquet.lineitem join tpch_parquet.orders on l_orderkey = o_orderkey
 where l_shipmode = 'F'
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=82.00MB Threads=3
-Per-Host Resource Estimates: Memory=240MB
+Max Per-Host Resource Reservation: Memory=99.00MB Threads=3
+Per-Host Resource Estimates: Memory=304MB
 Analyzed query: SELECT DISTINCT l_orderkey, l_partkey, l_suppkey, l_linenumber,
 l_comment FROM tpch_parquet.lineitem INNER JOIN tpch_parquet.orders ON
 l_orderkey = o_orderkey WHERE l_tax > CAST(10 AS DECIMAL(3,0)) UNION ALL SELECT
@@ -3540,7 +3540,7 @@ l_suppkey, l_linenumber, l_comment FROM tpch_parquet.lineitem INNER JOIN
 tpch_parquet.orders ON l_orderkey = o_orderkey WHERE l_shipmode = 'F'
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=240.16MB mem-reservation=82.00MB thread-reservation=3 runtime-filters-memory=3.00MB
+|  Per-Host Resources: mem-estimate=303.74MB mem-reservation=99.00MB thread-reservation=3 runtime-filters-memory=3.00MB
 PLAN-ROOT SINK
 |  output exprs: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_comment
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -3555,7 +3555,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: l_orderkey = o_orderkey
 |  |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  |  runtime filters: RF004[bloom] <- o_orderkey
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=75.44MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=5,6 row-size=91B cardinality=822.53K
 |  |  in pipelines: 08(GETNEXT), 09(OPEN)
 |  |
@@ -3587,7 +3587,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: l_orderkey = o_orderkey
 |  |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  |  runtime filters: RF002[bloom] <- o_orderkey
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3,4 row-size=95B cardinality=1.15M
 |  |  in pipelines: 05(GETNEXT), 06(OPEN)
 |  |
@@ -3617,7 +3617,7 @@ PLAN-ROOT SINK
 |
 04:AGGREGATE [FINALIZE]
 |  group by: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_comment
-|  mem-estimate=40.16MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=45.30MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=66B cardinality=575.77K
 |  in pipelines: 04(GETNEXT), 01(OPEN)
 |
@@ -3625,7 +3625,7 @@ PLAN-ROOT SINK
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF000[bloom] <- o_orderkey
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=75.44MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=82B cardinality=575.77K
 |  in pipelines: 01(GETNEXT), 02(OPEN)
 |
@@ -3653,8 +3653,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=74B cardinality=600.12K
    in pipelines: 01(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=127.75MB Threads=12
-Per-Host Resource Estimates: Memory=476MB
+Max Per-Host Resource Reservation: Memory=157.00MB Threads=12
+Per-Host Resource Estimates: Memory=547MB
 Analyzed query: SELECT DISTINCT l_orderkey, l_partkey, l_suppkey, l_linenumber,
 l_comment FROM tpch_parquet.lineitem INNER JOIN tpch_parquet.orders ON
 l_orderkey = o_orderkey WHERE l_tax > CAST(10 AS DECIMAL(3,0)) UNION ALL SELECT
@@ -3676,7 +3676,7 @@ PLAN-ROOT SINK
 |  in pipelines: 14(GETNEXT), 05(GETNEXT), 08(GETNEXT)
 |
 F08:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=109.02MB mem-reservation=43.00MB thread-reservation=2 runtime-filters-memory=2.00MB
+Per-Host Resources: mem-estimate=167.47MB mem-reservation=60.00MB thread-reservation=2 runtime-filters-memory=2.00MB
 00:UNION
 |  pass-through-operands: 14
 |  mem-estimate=0B mem-reservation=0B thread-reservation=0
@@ -3687,7 +3687,7 @@ Per-Host Resources: mem-estimate=109.02MB mem-reservation=43.00MB thread-reserva
 |  |  hash predicates: l_orderkey = o_orderkey
 |  |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  |  runtime filters: RF004[bloom] <- o_orderkey
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=75.44MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=5,6 row-size=91B cardinality=822.53K
 |  |  in pipelines: 08(GETNEXT), 09(OPEN)
 |  |
@@ -3726,7 +3726,7 @@ Per-Host Resources: mem-estimate=109.02MB mem-reservation=43.00MB thread-reserva
 |  |  hash predicates: l_orderkey = o_orderkey
 |  |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  |  runtime filters: RF002[bloom] <- o_orderkey
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3,4 row-size=95B cardinality=1.15M
 |  |  in pipelines: 05(GETNEXT), 06(OPEN)
 |  |
@@ -3763,7 +3763,7 @@ Per-Host Resources: mem-estimate=109.02MB mem-reservation=43.00MB thread-reserva
 |
 14:AGGREGATE [FINALIZE]
 |  group by: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_comment
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=2 row-size=66B cardinality=575.77K
 |  in pipelines: 14(GETNEXT), 01(OPEN)
 |
@@ -3773,10 +3773,10 @@ Per-Host Resources: mem-estimate=109.02MB mem-reservation=43.00MB thread-reserva
 |  in pipelines: 01(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=55.73MB mem-reservation=39.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=67.98MB mem-reservation=52.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 04:AGGREGATE [STREAMING]
 |  group by: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_comment
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=2 row-size=66B cardinality=575.77K
 |  in pipelines: 01(GETNEXT)
 |
@@ -3784,7 +3784,7 @@ Per-Host Resources: mem-estimate=55.73MB mem-reservation=39.75MB thread-reservat
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF000[bloom] <- o_orderkey
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=82B cardinality=575.77K
 |  in pipelines: 01(GETNEXT), 02(OPEN)
 |
@@ -3826,8 +3826,8 @@ Per-Host Resources: mem-estimate=81.00MB mem-reservation=25.00MB thread-reservat
    tuple-ids=0 row-size=74B cardinality=600.12K
    in pipelines: 01(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=190.75MB Threads=10
-Per-Host Resource Estimates: Memory=537MB
+Max Per-Host Resource Reservation: Memory=261.00MB Threads=10
+Per-Host Resource Estimates: Memory=625MB
 Analyzed query: SELECT DISTINCT l_orderkey, l_partkey, l_suppkey, l_linenumber,
 l_comment FROM tpch_parquet.lineitem INNER JOIN tpch_parquet.orders ON
 l_orderkey = o_orderkey WHERE l_tax > CAST(10 AS DECIMAL(3,0)) UNION ALL SELECT
@@ -3850,7 +3850,7 @@ PLAN-ROOT SINK
 |
 F08:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
 Per-Host Shared Resources: mem-estimate=2.00MB mem-reservation=2.00MB thread-reservation=0 runtime-filters-memory=2.00MB
-Per-Instance Resources: mem-estimate=80.00MB mem-reservation=34.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=80.00MB mem-reservation=24.00MB thread-reservation=1
 00:UNION
 |  pass-through-operands: 14
 |  mem-estimate=0B mem-reservation=0B thread-reservation=0
@@ -3861,17 +3861,17 @@ Per-Instance Resources: mem-estimate=80.00MB mem-reservation=34.00MB thread-rese
 |  |  hash-table-id=01
 |  |  hash predicates: l_orderkey = o_orderkey
 |  |  fk/pk conjuncts: l_orderkey = o_orderkey
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=5,6 row-size=91B cardinality=822.53K
 |  |  in pipelines: 08(GETNEXT), 09(OPEN)
 |  |
 |  |--F11:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=45.02MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  |  Per-Instance Resources: mem-estimate=86.47MB mem-reservation=69.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  |  JOIN BUILD
 |  |  |  join-table-id=01 plan-id=02 cohort-id=01
 |  |  |  build expressions: o_orderkey
 |  |  |  runtime filters: RF004[bloom] <- o_orderkey
-|  |  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  |  mem-estimate=75.44MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  |
 |  |  16:EXCHANGE [BROADCAST]
 |  |  |  mem-estimate=10.02MB mem-reservation=0B thread-reservation=0
@@ -3908,17 +3908,17 @@ Per-Instance Resources: mem-estimate=80.00MB mem-reservation=34.00MB thread-rese
 |  |  hash-table-id=00
 |  |  hash predicates: l_orderkey = o_orderkey
 |  |  fk/pk conjuncts: l_orderkey = o_orderkey
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3,4 row-size=95B cardinality=1.15M
 |  |  in pipelines: 05(GETNEXT), 06(OPEN)
 |  |
 |  |--F10:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=43.19MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  |  Per-Instance Resources: mem-estimate=77.19MB mem-reservation=69.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  |  JOIN BUILD
 |  |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  |  build expressions: o_orderkey
 |  |  |  runtime filters: RF002[bloom] <- o_orderkey
-|  |  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  |  mem-estimate=68.00MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  |
 |  |  15:EXCHANGE [BROADCAST]
 |  |  |  mem-estimate=8.19MB mem-reservation=0B thread-reservation=0
@@ -3953,7 +3953,7 @@ Per-Instance Resources: mem-estimate=80.00MB mem-reservation=34.00MB thread-rese
 |
 14:AGGREGATE [FINALIZE]
 |  group by: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_comment
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=2 row-size=66B cardinality=575.77K
 |  in pipelines: 14(GETNEXT), 01(OPEN)
 |
@@ -3963,10 +3963,10 @@ Per-Instance Resources: mem-estimate=80.00MB mem-reservation=34.00MB thread-rese
 |  in pipelines: 01(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=44.23MB mem-reservation=34.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=27.23MB mem-reservation=17.00MB thread-reservation=1
 04:AGGREGATE [STREAMING]
 |  group by: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_comment
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=2 row-size=66B cardinality=575.77K
 |  in pipelines: 01(GETNEXT)
 |
@@ -3974,17 +3974,17 @@ Per-Instance Resources: mem-estimate=44.23MB mem-reservation=34.00MB thread-rese
 |  hash-table-id=02
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
-|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=82B cardinality=575.77K
 |  in pipelines: 01(GETNEXT), 02(OPEN)
 |
 |--F12:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=11.50MB mem-reservation=5.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=40.75MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=02 plan-id=03 cohort-id=01
 |  |  build expressions: o_orderkey
 |  |  runtime filters: RF000[bloom] <- o_orderkey
-|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  12:EXCHANGE [HASH(o_orderkey)]
 |  |  mem-estimate=5.75MB mem-reservation=0B thread-reservation=0
@@ -4061,8 +4061,8 @@ order by
   o_orderdate
 limit 100
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=111.50MB Threads=5
-Per-Host Resource Estimates: Memory=419MB
+Max Per-Host Resource Reservation: Memory=120.50MB Threads=5
+Per-Host Resource Estimates: Memory=505MB
 Analyzed query: SELECT c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice,
 sum(l_quantity) FROM tpch.customer, tpch.orders, tpch.lineitem LEFT SEMI JOIN
 (SELECT l_orderkey FROM tpch.lineitem GROUP BY l_orderkey HAVING sum(l_quantity)
@@ -4072,7 +4072,7 @@ c_custkey, o_orderkey, o_orderdate, o_totalprice ORDER BY o_totalprice DESC,
 o_orderdate ASC LIMIT CAST(100 AS TINYINT)
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=419.25MB mem-reservation=111.50MB thread-reservation=5 runtime-filters-memory=3.00MB
+|  Per-Host Resources: mem-estimate=505.44MB mem-reservation=120.50MB thread-reservation=5 runtime-filters-memory=3.00MB
 PLAN-ROOT SINK
 |  output exprs: c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -4086,14 +4086,14 @@ PLAN-ROOT SINK
 08:AGGREGATE [FINALIZE]
 |  output: sum(l_quantity)
 |  group by: c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice
-|  mem-estimate=57.92MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=61.81MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=6 row-size=92B cardinality=600.12K
 |  in pipelines: 08(GETNEXT), 02(OPEN)
 |
 07:HASH JOIN [LEFT SEMI JOIN]
 |  hash predicates: o_orderkey = l_orderkey
 |  runtime filters: RF000[bloom] <- l_orderkey
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=100B cardinality=600.12K
 |  in pipelines: 02(GETNEXT), 04(OPEN)
 |
@@ -4101,7 +4101,7 @@ PLAN-ROOT SINK
 |  |  output: sum(l_quantity)
 |  |  group by: l_orderkey
 |  |  having: sum(l_quantity) > CAST(300 AS DECIMAL(5,0))
-|  |  mem-estimate=39.36MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=59.64MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=4 row-size=24B cardinality=156.34K
 |  |  in pipelines: 04(GETNEXT), 03(OPEN)
 |  |
@@ -4119,7 +4119,7 @@ PLAN-ROOT SINK
 |  hash predicates: o_custkey = c_custkey
 |  fk/pk conjuncts: o_custkey = c_custkey
 |  runtime filters: RF002[bloom] <- c_custkey
-|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=100B cardinality=5.76M
 |  in pipelines: 02(GETNEXT), 00(OPEN)
 |
@@ -4137,7 +4137,7 @@ PLAN-ROOT SINK
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF004[bloom] <- o_orderkey
-|  mem-estimate=72.38MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=129.80MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2,1 row-size=62B cardinality=5.76M
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
@@ -4163,8 +4163,8 @@ PLAN-ROOT SINK
    tuple-ids=2 row-size=16B cardinality=6.00M
    in pipelines: 02(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=224.38MB Threads=11
-Per-Host Resource Estimates: Memory=537MB
+Max Per-Host Resource Reservation: Memory=217.75MB Threads=11
+Per-Host Resource Estimates: Memory=556MB
 Analyzed query: SELECT c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice,
 sum(l_quantity) FROM tpch.customer, tpch.orders, tpch.lineitem LEFT SEMI JOIN
 (SELECT l_orderkey FROM tpch.lineitem GROUP BY l_orderkey HAVING sum(l_quantity)
@@ -4207,18 +4207,18 @@ Per-Host Resources: mem-estimate=44.28MB mem-reservation=34.00MB thread-reservat
 |  in pipelines: 02(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=149.22MB mem-reservation=116.38MB thread-reservation=1 runtime-filters-memory=3.00MB
+Per-Host Resources: mem-estimate=149.98MB mem-reservation=109.75MB thread-reservation=1 runtime-filters-memory=3.00MB
 08:AGGREGATE [STREAMING]
 |  output: sum(l_quantity)
 |  group by: c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=6 row-size=92B cardinality=600.12K
 |  in pipelines: 02(GETNEXT)
 |
 07:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  hash predicates: o_orderkey = l_orderkey
 |  runtime filters: RF000[bloom] <- l_orderkey
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=100B cardinality=600.12K
 |  in pipelines: 02(GETNEXT), 14(OPEN)
 |
@@ -4236,11 +4236,11 @@ Per-Host Resources: mem-estimate=149.22MB mem-reservation=116.38MB thread-reserv
 |  |  in pipelines: 03(GETNEXT)
 |  |
 |  F04:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=127.36MB mem-reservation=42.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=145.23MB mem-reservation=42.00MB thread-reservation=2
 |  04:AGGREGATE [STREAMING]
 |  |  output: sum(l_quantity)
 |  |  group by: l_orderkey
-|  |  mem-estimate=39.36MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=57.23MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=4 row-size=24B cardinality=1.56M
 |  |  in pipelines: 03(GETNEXT)
 |  |
@@ -4258,7 +4258,7 @@ Per-Host Resources: mem-estimate=149.22MB mem-reservation=116.38MB thread-reserv
 |  hash predicates: o_custkey = c_custkey
 |  fk/pk conjuncts: o_custkey = c_custkey
 |  runtime filters: RF002[bloom] <- c_custkey
-|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=100B cardinality=5.76M
 |  in pipelines: 02(GETNEXT), 00(OPEN)
 |
@@ -4283,7 +4283,7 @@ Per-Host Resources: mem-estimate=149.22MB mem-reservation=116.38MB thread-reserv
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF004[bloom] <- o_orderkey
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=43.27MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2,1 row-size=62B cardinality=5.76M
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
@@ -4323,8 +4323,8 @@ Per-Host Resources: mem-estimate=90.00MB mem-reservation=10.00MB thread-reservat
    tuple-ids=2 row-size=16B cardinality=6.00M
    in pipelines: 02(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=285.88MB Threads=16
-Per-Host Resource Estimates: Memory=801MB
+Max Per-Host Resource Reservation: Memory=322.75MB Threads=16
+Per-Host Resource Estimates: Memory=830MB
 Analyzed query: SELECT c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice,
 sum(l_quantity) FROM tpch.customer, tpch.orders, tpch.lineitem LEFT SEMI JOIN
 (SELECT l_orderkey FROM tpch.lineitem GROUP BY l_orderkey HAVING sum(l_quantity)
@@ -4367,28 +4367,28 @@ Per-Instance Resources: mem-estimate=27.56MB mem-reservation=17.00MB thread-rese
 |  in pipelines: 02(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=6
-Per-Instance Resources: mem-estimate=27.12MB mem-reservation=17.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=20.12MB mem-reservation=9.00MB thread-reservation=1
 08:AGGREGATE [STREAMING]
 |  output: sum(l_quantity)
 |  group by: c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=10.00MB mem-reservation=9.00MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=6 row-size=92B cardinality=600.12K
 |  in pipelines: 02(GETNEXT)
 |
 07:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  hash-table-id=00
 |  hash predicates: o_orderkey = l_orderkey
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=100B cardinality=600.12K
 |  in pipelines: 02(GETNEXT), 14(OPEN)
 |
 |--F08:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=28.16MB mem-reservation=19.94MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=28.16MB mem-reservation=20.88MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: l_orderkey
 |  |  runtime filters: RF000[bloom] <- l_orderkey
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  14:AGGREGATE [FINALIZE]
 |  |  output: sum:merge(l_quantity)
@@ -4404,11 +4404,11 @@ Per-Instance Resources: mem-estimate=27.12MB mem-reservation=17.00MB thread-rese
 |  |  in pipelines: 03(GETNEXT)
 |  |
 |  F04:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=125.77MB mem-reservation=42.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=122.00MB mem-reservation=42.00MB thread-reservation=1
 |  04:AGGREGATE [STREAMING]
 |  |  output: sum(l_quantity)
 |  |  group by: l_orderkey
-|  |  mem-estimate=37.77MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=4 row-size=24B cardinality=1.56M
 |  |  in pipelines: 03(GETNEXT)
 |  |
@@ -4426,17 +4426,17 @@ Per-Instance Resources: mem-estimate=27.12MB mem-reservation=17.00MB thread-rese
 |  hash-table-id=01
 |  hash predicates: o_custkey = c_custkey
 |  fk/pk conjuncts: o_custkey = c_custkey
-|  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=100B cardinality=5.76M
 |  in pipelines: 02(GETNEXT), 00(OPEN)
 |
 |--F09:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=23.48MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=40.48MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=01 plan-id=02 cohort-id=01
 |  |  build expressions: c_custkey
 |  |  runtime filters: RF002[bloom] <- c_custkey
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=1.00MB thread-reservation=0
 |  |
 |  12:EXCHANGE [BROADCAST]
 |  |  mem-estimate=5.48MB mem-reservation=0B thread-reservation=0
@@ -4459,17 +4459,17 @@ Per-Instance Resources: mem-estimate=27.12MB mem-reservation=17.00MB thread-rese
 |  hash-table-id=02
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
-|  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2,1 row-size=62B cardinality=5.76M
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
 |--F10:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=28.10MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=45.10MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=02 plan-id=03 cohort-id=01
 |  |  build expressions: o_orderkey
 |  |  runtime filters: RF004[bloom] <- o_orderkey
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  11:EXCHANGE [HASH(o_orderkey)]
 |  |  mem-estimate=10.10MB mem-reservation=0B thread-reservation=0
@@ -4603,11 +4603,11 @@ partitioned by (l_partkey) as
 select l_comment, l_partkey from tpch.lineitem
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=20.00MB Threads=2
-Per-Host Resource Estimates: Memory=106MB
+Per-Host Resource Estimates: Memory=354MB
 Analyzed query: SELECT l_comment, l_partkey FROM tpch.lineitem
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=106.00MB mem-reservation=20.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=354.10MB mem-reservation=20.00MB thread-reservation=2
 WRITE TO HDFS [default.dummy_insert, OVERWRITE=false, PARTITION-KEYS=(l_partkey)]
 |  partitions=200516
 |  output exprs: l_comment, l_partkey
@@ -4615,7 +4615,7 @@ WRITE TO HDFS [default.dummy_insert, OVERWRITE=false, PARTITION-KEYS=(l_partkey)
 |
 01:SORT
 |  order by: l_partkey ASC NULLS LAST
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=266.10MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=46B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -4630,11 +4630,11 @@ WRITE TO HDFS [default.dummy_insert, OVERWRITE=false, PARTITION-KEYS=(l_partkey)
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=20.00MB Threads=3
-Per-Host Resource Estimates: Memory=116MB
+Per-Host Resource Estimates: Memory=187MB
 Analyzed query: SELECT l_comment, l_partkey FROM tpch.lineitem
 
 F01:PLAN FRAGMENT [HASH(l_partkey)] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=28.15MB mem-reservation=12.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=98.85MB mem-reservation=12.00MB thread-reservation=1
 WRITE TO HDFS [default.dummy_insert, OVERWRITE=false, PARTITION-KEYS=(l_partkey)]
 |  partitions=200516
 |  output exprs: l_comment, l_partkey
@@ -4642,7 +4642,7 @@ WRITE TO HDFS [default.dummy_insert, OVERWRITE=false, PARTITION-KEYS=(l_partkey)
 |
 02:SORT
 |  order by: l_partkey ASC NULLS LAST
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=88.70MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=46B cardinality=6.00M
 |  in pipelines: 02(GETNEXT), 00(OPEN)
 |
@@ -4664,11 +4664,11 @@ Per-Host Resources: mem-estimate=88.00MB mem-reservation=8.00MB thread-reservati
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=40.00MB Threads=4
-Per-Host Resource Estimates: Memory=233MB
+Per-Host Resource Estimates: Memory=285MB
 Analyzed query: SELECT l_comment, l_partkey FROM tpch.lineitem
 
 F01:PLAN FRAGMENT [HASH(l_partkey)] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=28.30MB mem-reservation=12.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=54.65MB mem-reservation=12.00MB thread-reservation=1
 WRITE TO HDFS [default.dummy_insert, OVERWRITE=false, PARTITION-KEYS=(l_partkey)]
 |  partitions=200516
 |  output exprs: l_comment, l_partkey
@@ -4676,7 +4676,7 @@ WRITE TO HDFS [default.dummy_insert, OVERWRITE=false, PARTITION-KEYS=(l_partkey)
 |
 02:SORT
 |  order by: l_partkey ASC NULLS LAST
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=44.35MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=46B cardinality=6.00M
 |  in pipelines: 02(GETNEXT), 00(OPEN)
 |
@@ -4864,8 +4864,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=54B cardinality=150.00K
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=123.94MB Threads=4
-Per-Host Resource Estimates: Memory=566MB
+Max Per-Host Resource Reservation: Memory=91.88MB Threads=4
+Per-Host Resource Estimates: Memory=448MB
 Analyzed query: SELECT DISTINCT c_name, v.o_orderkey, v.o_orderstatus FROM
 tpch_nested_parquet.customer c, (SELECT DISTINCT o1.o_orderkey, o2.o_orderstatus
 FROM c.c_orders o1 INNER JOIN c.c_orders o2 ON o1.o_orderkey = o2.o_orderkey
@@ -4883,10 +4883,10 @@ PLAN-ROOT SINK
 |  in pipelines: 11(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(c_name,v.o_orderkey,v.o_orderstatus)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=138.16MB mem-reservation=34.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=20.16MB mem-reservation=1.94MB thread-reservation=1
 11:AGGREGATE [FINALIZE]
 |  group by: c_name, v.o_orderkey, v.o_orderstatus
-|  mem-estimate=128.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
 |  tuple-ids=6 row-size=50B cardinality=1.50M
 |  in pipelines: 11(GETNEXT), 00(OPEN)
 |
@@ -4960,8 +4960,8 @@ Per-Host Resources: mem-estimate=345.94MB mem-reservation=85.94MB thread-reserva
    tuple-ids=0 row-size=54B cardinality=150.00K
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=243.88MB Threads=5
-Per-Host Resource Estimates: Memory=1.03GB
+Max Per-Host Resource Reservation: Memory=179.75MB Threads=5
+Per-Host Resource Estimates: Memory=814MB
 Analyzed query: SELECT DISTINCT c_name, v.o_orderkey, v.o_orderstatus FROM
 tpch_nested_parquet.customer c, (SELECT DISTINCT o1.o_orderkey, o2.o_orderstatus
 FROM c.c_orders o1 INNER JOIN c.c_orders o2 ON o1.o_orderkey = o2.o_orderkey
@@ -4979,10 +4979,10 @@ PLAN-ROOT SINK
 |  in pipelines: 11(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(c_name,v.o_orderkey,v.o_orderstatus)] hosts=3 instances=4
-Per-Instance Resources: mem-estimate=138.21MB mem-reservation=34.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=20.21MB mem-reservation=1.94MB thread-reservation=1
 11:AGGREGATE [FINALIZE]
 |  group by: c_name, v.o_orderkey, v.o_orderstatus
-|  mem-estimate=128.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
 |  tuple-ids=6 row-size=50B cardinality=1.50M
 |  in pipelines: 11(GETNEXT), 00(OPEN)
 |
@@ -5354,8 +5354,8 @@ join (
   ) v2 on v2.k3 = t2.o_orderkey
 ) v1 on v1.k3 = t1.o_orderkey
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=99.00MB Threads=5
-Per-Host Resource Estimates: Memory=181MB
+Max Per-Host Resource Reservation: Memory=103.00MB Threads=5
+Per-Host Resource Estimates: Memory=285MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.orders t1 INNER
 JOIN (SELECT /* +straight_join */ t2.o_orderkey k2, k3, k4 FROM
 tpch_parquet.orders t2 INNER JOIN (SELECT /* +straight_join */ t3.o_orderkey k3,
@@ -5364,7 +5364,7 @@ ON t3.o_orderkey = t4.o_orderkey) v2 ON v2.k3 = t2.o_orderkey) v1 ON v1.k3 =
 t1.o_orderkey
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=180.77MB mem-reservation=99.00MB thread-reservation=5 runtime-filters-memory=3.00MB
+|  Per-Host Resources: mem-estimate=285.33MB mem-reservation=103.00MB thread-reservation=5 runtime-filters-memory=3.00MB
 PLAN-ROOT SINK
 |  output exprs: t1.o_orderkey, t1.o_custkey, t1.o_orderstatus, t1.o_totalprice, t1.o_orderdate, t1.o_orderpriority, t1.o_clerk, t1.o_shippriority, t1.o_comment, t2.o_orderkey, t3.o_orderkey, t4.o_orderkey
 |  mem-estimate=100.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -5373,7 +5373,7 @@ PLAN-ROOT SINK
 |  hash predicates: t1.o_orderkey = t3.o_orderkey
 |  fk/pk conjuncts: t1.o_orderkey = t3.o_orderkey
 |  runtime filters: RF000[bloom] <- t3.o_orderkey
-|  mem-estimate=37.77MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=98.33MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1,2,3 row-size=195B cardinality=1.50M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -5381,7 +5381,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: t2.o_orderkey = t3.o_orderkey
 |  |  fk/pk conjuncts: t2.o_orderkey = t3.o_orderkey
 |  |  runtime filters: RF002[bloom] <- t3.o_orderkey
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=86.89MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=1,2,3 row-size=24B cardinality=1.50M
 |  |  in pipelines: 01(GETNEXT), 02(OPEN)
 |  |
@@ -5389,7 +5389,7 @@ PLAN-ROOT SINK
 |  |  |  hash predicates: t3.o_orderkey = t4.o_orderkey
 |  |  |  fk/pk conjuncts: t3.o_orderkey = t4.o_orderkey
 |  |  |  runtime filters: RF004[bloom] <- t4.o_orderkey
-|  |  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  |  mem-estimate=75.44MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=2,3 row-size=16B cardinality=1.50M
 |  |  |  in pipelines: 02(GETNEXT), 03(OPEN)
 |  |  |
@@ -5436,8 +5436,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=171B cardinality=1.50M
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=104.50MB Threads=10
-Per-Host Resource Estimates: Memory=360MB
+Max Per-Host Resource Reservation: Memory=147.00MB Threads=10
+Per-Host Resource Estimates: Memory=476MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.orders t1 INNER
 JOIN (SELECT /* +straight_join */ t2.o_orderkey k2, k3, k4 FROM
 tpch_parquet.orders t2 INNER JOIN (SELECT /* +straight_join */ t3.o_orderkey k3,
@@ -5457,12 +5457,12 @@ PLAN-ROOT SINK
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-Per-Host Resources: mem-estimate=88.84MB mem-reservation=59.00MB thread-reservation=2 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=149.40MB mem-reservation=59.00MB thread-reservation=2 runtime-filters-memory=1.00MB
 06:HASH JOIN [INNER JOIN, BROADCAST]
 |  hash predicates: t1.o_orderkey = t3.o_orderkey
 |  fk/pk conjuncts: t1.o_orderkey = t3.o_orderkey
 |  runtime filters: RF000[bloom] <- t3.o_orderkey
-|  mem-estimate=37.77MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=98.33MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1,2,3 row-size=195B cardinality=1.50M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -5472,12 +5472,12 @@ Per-Host Resources: mem-estimate=88.84MB mem-reservation=59.00MB thread-reservat
 |  |  in pipelines: 01(GETNEXT)
 |  |
 |  F04:PLAN FRAGMENT [HASH(t3.o_orderkey)] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=38.99MB mem-reservation=27.50MB thread-reservation=1 runtime-filters-memory=2.00MB
+|  Per-Host Resources: mem-estimate=94.66MB mem-reservation=70.00MB thread-reservation=1 runtime-filters-memory=2.00MB
 |  05:HASH JOIN [INNER JOIN, PARTITIONED]
 |  |  hash predicates: t2.o_orderkey = t3.o_orderkey
 |  |  fk/pk conjuncts: t2.o_orderkey = t3.o_orderkey
 |  |  runtime filters: RF002[bloom] <- t3.o_orderkey
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=43.44MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=1,2,3 row-size=24B cardinality=1.50M
 |  |  in pipelines: 01(GETNEXT), 02(OPEN)
 |  |
@@ -5485,7 +5485,7 @@ Per-Host Resources: mem-estimate=88.84MB mem-reservation=59.00MB thread-reservat
 |  |  |  hash predicates: t3.o_orderkey = t4.o_orderkey
 |  |  |  fk/pk conjuncts: t3.o_orderkey = t4.o_orderkey
 |  |  |  runtime filters: RF004[bloom] <- t4.o_orderkey
-|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  |  mem-estimate=37.72MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=2,3 row-size=16B cardinality=1.50M
 |  |  |  in pipelines: 02(GETNEXT), 03(OPEN)
 |  |  |
@@ -5553,8 +5553,8 @@ Per-Host Resources: mem-estimate=88.84MB mem-reservation=59.00MB thread-reservat
    tuple-ids=0 row-size=171B cardinality=1.50M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=139.50MB Threads=9
-Per-Host Resource Estimates: Memory=397MB
+Max Per-Host Resource Reservation: Memory=182.00MB Threads=9
+Per-Host Resource Estimates: Memory=483MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.orders t1 INNER
 JOIN (SELECT /* +straight_join */ t2.o_orderkey k2, k3, k4 FROM
 tpch_parquet.orders t2 INNER JOIN (SELECT /* +straight_join */ t3.o_orderkey k3,
@@ -5585,12 +5585,12 @@ Per-Instance Resources: mem-estimate=40.00MB mem-reservation=24.00MB thread-rese
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F06:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  Per-Instance Resources: mem-estimate=79.07MB mem-reservation=69.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=109.40MB mem-reservation=69.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: t3.o_orderkey
 |  |  runtime filters: RF000[bloom] <- t3.o_orderkey
-|  |  mem-estimate=68.00MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=98.33MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  10:EXCHANGE [BROADCAST]
 |  |  mem-estimate=10.07MB mem-reservation=0B thread-reservation=0
@@ -5603,33 +5603,33 @@ Per-Instance Resources: mem-estimate=40.00MB mem-reservation=24.00MB thread-rese
 |  |  hash-table-id=01
 |  |  hash predicates: t2.o_orderkey = t3.o_orderkey
 |  |  fk/pk conjuncts: t2.o_orderkey = t3.o_orderkey
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=1,2,3 row-size=24B cardinality=1.50M
 |  |  in pipelines: 01(GETNEXT), 02(OPEN)
 |  |
 |  |--F07:PLAN FRAGMENT [HASH(t3.o_orderkey)] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=23.75MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  |  Per-Instance Resources: mem-estimate=50.19MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  |  JOIN BUILD
 |  |  |  join-table-id=01 plan-id=02 cohort-id=02
 |  |  |  build expressions: t3.o_orderkey
 |  |  |  runtime filters: RF002[bloom] <- t3.o_orderkey
-|  |  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  |  mem-estimate=43.44MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  |
 |  |  04:HASH JOIN [INNER JOIN, PARTITIONED]
 |  |  |  hash-table-id=02
 |  |  |  hash predicates: t3.o_orderkey = t4.o_orderkey
 |  |  |  fk/pk conjuncts: t3.o_orderkey = t4.o_orderkey
-|  |  |  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  |  |  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=2,3 row-size=16B cardinality=1.50M
 |  |  |  in pipelines: 02(GETNEXT), 03(OPEN)
 |  |  |
 |  |  |--F08:PLAN FRAGMENT [HASH(t3.o_orderkey)] hosts=2 instances=2
-|  |  |  |  Per-Instance Resources: mem-estimate=15.25MB mem-reservation=9.50MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  |  |  Per-Instance Resources: mem-estimate=44.47MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  |  |  JOIN BUILD
 |  |  |  |  join-table-id=02 plan-id=03 cohort-id=03
 |  |  |  |  build expressions: t4.o_orderkey
 |  |  |  |  runtime filters: RF004[bloom] <- t4.o_orderkey
-|  |  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  |  |  mem-estimate=37.72MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  |  |
 |  |  |  08:EXCHANGE [HASH(t4.o_orderkey)]
 |  |  |  |  mem-estimate=5.75MB mem-reservation=0B thread-reservation=0
@@ -6108,19 +6108,19 @@ PLAN-ROOT SINK
 select count(*) from functional_kudu.alltypes
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=4.00MB Threads=2
-Per-Host Resource Estimates: Memory=14MB
+Per-Host Resource Estimates: Memory=10MB
 Codegen disabled by planner
 Analyzed query: SELECT count(*) FROM functional_kudu.alltypes
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.00MB mem-reservation=4.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 01:AGGREGATE [FINALIZE]
 |  output: sum_init_zero(functional_kudu.alltypes.stats: num_rows)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=8B cardinality=1
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -6155,12 +6155,12 @@ from tpch_parquet.lineitem
 limit 5
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=74.00MB Threads=2
-Per-Host Resource Estimates: Memory=1.50GB
+Per-Host Resource Estimates: Memory=1.46GB
 Analyzed query: SELECT DISTINCT * FROM tpch_parquet.lineitem LIMIT CAST(5 AS
 TINYINT)
 
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=1.50GB mem-reservation=74.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=1.46GB mem-reservation=74.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ [...]
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -6168,7 +6168,7 @@ PLAN-ROOT SINK
 01:AGGREGATE [FINALIZE]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
 |  limit: 5
-|  mem-estimate=1.42GB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=1.38GB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=5
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -6183,7 +6183,7 @@ PLAN-ROOT SINK
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=112.00MB Threads=4
-Per-Host Resource Estimates: Memory=1.51GB
+Per-Host Resource Estimates: Memory=919MB
 Analyzed query: SELECT DISTINCT * FROM tpch_parquet.lineitem LIMIT CAST(5 AS
 TINYINT)
 
@@ -6200,11 +6200,11 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(tpch_parquet.lineitem.l_orderkey,tpch_parquet.lineitem.l_partkey,tpch_parquet.lineitem.l_suppkey,tpch_parquet.lineitem.l_linenumber,tpch_parquet.lineitem.l_quantity,tpch_parquet.lineitem.l_extendedprice,tpch_parquet.lineitem.l_discount,tpch_parquet.lineitem.l_tax,tpch_parquet.lineitem.l_returnflag,tpch_parquet.lineitem.l_linestatus,tpch_parquet.lineitem.l_shipdate,tpch_parquet.lineitem.l_commitdate,tpch_parquet.lineitem.l_receiptdate,tpch_parquet.lineitem.l_shipin [...]
-Per-Host Resources: mem-estimate=737.12MB mem-reservation=34.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=481.48MB mem-reservation=34.00MB thread-reservation=1
 03:AGGREGATE [FINALIZE]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
 |  limit: 5
-|  mem-estimate=726.43MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=470.79MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=5
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -6214,10 +6214,10 @@ Per-Host Resources: mem-estimate=737.12MB mem-reservation=34.00MB thread-reserva
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=806.43MB mem-reservation=74.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=433.09MB mem-reservation=74.00MB thread-reservation=2
 01:AGGREGATE [STREAMING]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
-|  mem-estimate=726.43MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=353.09MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 00(GETNEXT)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/result-spooling.test b/testdata/workloads/functional-planner/queries/PlannerTest/result-spooling.test
index e4cc307..88d1669 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/result-spooling.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/result-spooling.test
@@ -75,7 +75,7 @@ Per-Instance Resources: mem-estimate=16.00MB mem-reservation=32.00KB thread-rese
 select * from tpch.lineitem order by l_orderkey
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=24.00MB Threads=3
-Per-Host Resource Estimates: Memory=257MB
+Per-Host Resource Estimates: Memory=659MB
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=130.69MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -89,10 +89,10 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=126.00MB mem-reservation=20.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=528.26MB mem-reservation=20.00MB thread-reservation=2
 01:SORT
 |  order by: l_orderkey ASC
-|  mem-estimate=38.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=440.26MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -107,7 +107,7 @@ Per-Host Resources: mem-estimate=126.00MB mem-reservation=20.00MB thread-reserva
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=44.00MB Threads=3
-Per-Host Resource Estimates: Memory=413MB
+Per-Host Resource Estimates: Memory=778MB
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=161.38MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -121,10 +121,10 @@ PLAN-ROOT SINK
 |  in pipelines: 01(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-Per-Instance Resources: mem-estimate=126.00MB mem-reservation=20.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=308.13MB mem-reservation=20.00MB thread-reservation=1
 01:SORT
 |  order by: l_orderkey ASC
-|  mem-estimate=38.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=220.13MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/runtime-filter-query-options.test b/testdata/workloads/functional-planner/queries/PlannerTest/runtime-filter-query-options.test
index 3735b37..0d25f65 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/runtime-filter-query-options.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/runtime-filter-query-options.test
@@ -18,7 +18,7 @@ PLAN-ROOT SINK
 |  row-size=74B cardinality=16.21G
 |
 |--03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 05:HASH JOIN [INNER JOIN]
@@ -27,7 +27,7 @@ PLAN-ROOT SINK
 |  row-size=69B cardinality=4.44M
 |
 |--02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN]
@@ -36,11 +36,11 @@ PLAN-ROOT SINK
 |  row-size=61B cardinality=7.30K
 |
 |--01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF000 -> a.`year`, RF001 -> a.bool_col, RF004 -> a.`month`, RF005 -> a.int_col, RF008 -> a.id, RF009 -> a.date_string_col
    row-size=37B cardinality=7.30K
 ---- DISTRIBUTEDPLAN
@@ -64,7 +64,7 @@ PLAN-ROOT SINK
 |--11:EXCHANGE [HASH(d.`year`,d.bool_col)]
 |  |
 |  03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 10:EXCHANGE [HASH(a.`year`,a.bool_col)]
@@ -77,7 +77,7 @@ PLAN-ROOT SINK
 |--09:EXCHANGE [BROADCAST]
 |  |
 |  02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN, BROADCAST]
@@ -88,11 +88,11 @@ PLAN-ROOT SINK
 |--08:EXCHANGE [BROADCAST]
 |  |
 |  01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF000 -> a.`year`, RF001 -> a.bool_col, RF004 -> a.`month`, RF005 -> a.int_col, RF008 -> a.id, RF009 -> a.date_string_col
    row-size=37B cardinality=7.30K
 ====
@@ -127,7 +127,7 @@ PLAN-ROOT SINK
 |--11:EXCHANGE [HASH(d.`year`,d.bool_col)]
 |  |
 |  03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 10:EXCHANGE [HASH(a.`year`,a.bool_col)]
@@ -140,7 +140,7 @@ PLAN-ROOT SINK
 |--09:EXCHANGE [BROADCAST]
 |  |
 |  02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN, BROADCAST]
@@ -151,11 +151,11 @@ PLAN-ROOT SINK
 |--08:EXCHANGE [BROADCAST]
 |  |
 |  01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF008 -> a.id, RF009 -> a.date_string_col, RF004 -> a.`month`, RF005 -> a.int_col
    row-size=37B cardinality=7.30K
 ====
@@ -181,7 +181,7 @@ PLAN-ROOT SINK
 |  row-size=74B cardinality=16.21G
 |
 |--03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 05:HASH JOIN [INNER JOIN]
@@ -190,7 +190,7 @@ PLAN-ROOT SINK
 |  row-size=69B cardinality=4.44M
 |
 |--02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN]
@@ -198,11 +198,11 @@ PLAN-ROOT SINK
 |  row-size=61B cardinality=7.30K
 |
 |--01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF000 -> a.`year`, RF004 -> a.`month`
    row-size=37B cardinality=7.30K
 ====
@@ -230,7 +230,7 @@ PLAN-ROOT SINK
 |  row-size=74B cardinality=16.21G
 |
 |--03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 05:HASH JOIN [INNER JOIN]
@@ -239,7 +239,7 @@ PLAN-ROOT SINK
 |  row-size=69B cardinality=4.44M
 |
 |--02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN]
@@ -247,11 +247,11 @@ PLAN-ROOT SINK
 |  row-size=61B cardinality=7.30K
 |
 |--01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF000 -> a.`year`, RF004 -> a.`month`
    row-size=37B cardinality=7.30K
 ====
@@ -277,7 +277,7 @@ PLAN-ROOT SINK
 |  row-size=74B cardinality=16.21G
 |
 |--03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 05:HASH JOIN [INNER JOIN]
@@ -286,7 +286,7 @@ PLAN-ROOT SINK
 |  row-size=69B cardinality=4.44M
 |
 |--02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN]
@@ -295,11 +295,11 @@ PLAN-ROOT SINK
 |  row-size=61B cardinality=7.30K
 |
 |--01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF000 -> a.`year`, RF001 -> a.bool_col, RF004 -> a.`month`, RF005 -> a.int_col, RF008 -> a.id, RF009 -> a.date_string_col
    row-size=37B cardinality=7.30K
 ---- DISTRIBUTEDPLAN
@@ -322,7 +322,7 @@ PLAN-ROOT SINK
 |--11:EXCHANGE [HASH(d.`year`,d.bool_col)]
 |  |
 |  03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 10:EXCHANGE [HASH(a.`year`,a.bool_col)]
@@ -335,7 +335,7 @@ PLAN-ROOT SINK
 |--09:EXCHANGE [BROADCAST]
 |  |
 |  02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN, BROADCAST]
@@ -346,11 +346,11 @@ PLAN-ROOT SINK
 |--08:EXCHANGE [BROADCAST]
 |  |
 |  01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF004 -> a.`month`, RF005 -> a.int_col, RF008 -> a.id, RF009 -> a.date_string_col
    row-size=37B cardinality=7.30K
 ====
@@ -378,7 +378,7 @@ PLAN-ROOT SINK
 |  row-size=74B cardinality=16.21G
 |
 |--03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 05:HASH JOIN [INNER JOIN]
@@ -387,7 +387,7 @@ PLAN-ROOT SINK
 |  row-size=69B cardinality=4.44M
 |
 |--02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN]
@@ -396,11 +396,11 @@ PLAN-ROOT SINK
 |  row-size=61B cardinality=7.30K
 |
 |--01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF008 -> a.id, RF009 -> a.date_string_col, RF004 -> a.`month`
    row-size=37B cardinality=7.30K
 ---- DISTRIBUTEDPLAN
@@ -423,7 +423,7 @@ PLAN-ROOT SINK
 |--11:EXCHANGE [HASH(d.`year`,d.bool_col)]
 |  |
 |  03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 10:EXCHANGE [HASH(a.`year`,a.bool_col)]
@@ -436,7 +436,7 @@ PLAN-ROOT SINK
 |--09:EXCHANGE [BROADCAST]
 |  |
 |  02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN, BROADCAST]
@@ -447,11 +447,11 @@ PLAN-ROOT SINK
 |--08:EXCHANGE [BROADCAST]
 |  |
 |  01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF008 -> a.id, RF009 -> a.date_string_col, RF004 -> a.`month`
    row-size=37B cardinality=7.30K
 ====
@@ -479,7 +479,7 @@ PLAN-ROOT SINK
 |  row-size=74B cardinality=16.21G
 |
 |--03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 05:HASH JOIN [INNER JOIN]
@@ -488,7 +488,7 @@ PLAN-ROOT SINK
 |  row-size=69B cardinality=4.44M
 |
 |--02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN]
@@ -496,11 +496,11 @@ PLAN-ROOT SINK
 |  row-size=61B cardinality=7.30K
 |
 |--01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF000 -> a.`year`, RF004 -> a.`month`
    row-size=37B cardinality=7.30K
 ---- DISTRIBUTEDPLAN
@@ -523,7 +523,7 @@ PLAN-ROOT SINK
 |--11:EXCHANGE [HASH(d.`year`,d.bool_col)]
 |  |
 |  03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 10:EXCHANGE [HASH(a.`year`,a.bool_col)]
@@ -536,7 +536,7 @@ PLAN-ROOT SINK
 |--09:EXCHANGE [BROADCAST]
 |  |
 |  02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN, BROADCAST]
@@ -546,11 +546,11 @@ PLAN-ROOT SINK
 |--08:EXCHANGE [BROADCAST]
 |  |
 |  01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    runtime filters: RF004 -> a.`month`
    row-size=37B cardinality=7.30K
 ====
@@ -575,7 +575,7 @@ PLAN-ROOT SINK
 |  row-size=74B cardinality=16.21G
 |
 |--03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 05:HASH JOIN [INNER JOIN]
@@ -583,7 +583,7 @@ PLAN-ROOT SINK
 |  row-size=69B cardinality=4.44M
 |
 |--02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN]
@@ -591,11 +591,11 @@ PLAN-ROOT SINK
 |  row-size=61B cardinality=7.30K
 |
 |--01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    row-size=37B cardinality=7.30K
 ====
 # MAX_NUM_RUNTIME_FILTERS is 0: no filters are applied
@@ -619,7 +619,7 @@ PLAN-ROOT SINK
 |  row-size=74B cardinality=16.21G
 |
 |--03:SCAN HDFS [functional.alltypes d]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=5B cardinality=7.30K
 |
 05:HASH JOIN [INNER JOIN]
@@ -627,7 +627,7 @@ PLAN-ROOT SINK
 |  row-size=69B cardinality=4.44M
 |
 |--02:SCAN HDFS [functional.alltypes c]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=8B cardinality=7.30K
 |
 04:HASH JOIN [INNER JOIN]
@@ -635,11 +635,11 @@ PLAN-ROOT SINK
 |  row-size=61B cardinality=7.30K
 |
 |--01:SCAN HDFS [functional.alltypes b]
-|     partitions=24/24 files=24 size=478.45KB
+|     HDFS partitions=24/24 files=24 size=478.45KB
 |     row-size=24B cardinality=7.30K
 |
 00:SCAN HDFS [functional.alltypes a]
-   partitions=24/24 files=24 size=478.45KB
+   HDFS partitions=24/24 files=24 size=478.45KB
    row-size=37B cardinality=7.30K
 ====
 # DISABLE_ROW_RUNTIME_FILTERING completely disables filters for Kudu.
@@ -673,14 +673,14 @@ ENABLED_RUNTIME_FILTER_TYPES=BLOOM
 EXPLAIN_LEVEL=2
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=15.00MB mem-reservation=5.00MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=5.02MB mem-reservation=5.00MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -712,14 +712,14 @@ ENABLED_RUNTIME_FILTER_TYPES=MIN_MAX
 EXPLAIN_LEVEL=2
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.00MB mem-reservation=4.00MB thread-reservation=3
+|  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=3
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -751,14 +751,14 @@ ENABLED_RUNTIME_FILTER_TYPES=ALL
 EXPLAIN_LEVEL=2
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=15.00MB mem-reservation=5.00MB thread-reservation=3 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=5.02MB mem-reservation=5.00MB thread-reservation=3 runtime-filters-memory=1.00MB
 PLAN-ROOT SINK
 |  output exprs: count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 03:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/sort-expr-materialization.test b/testdata/workloads/functional-planner/queries/PlannerTest/sort-expr-materialization.test
index a6e56f7..a18e80d 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/sort-expr-materialization.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/sort-expr-materialization.test
@@ -291,14 +291,14 @@ WHERE
 ORDER BY rn
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=422.00MB mem-reservation=32.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=713.05MB mem-reservation=32.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: l_orderkey, l_partkey, l_linenumber, l_quantity, evt_ts, rn
 |  mem-estimate=22.89MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 04:SORT
 |  order by: rn ASC
-|  mem-estimate=8.00MB mem-reservation=6.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=22.89MB mem-reservation=6.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=4 row-size=40B cardinality=600.12K
 |  in pipelines: 04(GETNEXT), 01(OPEN)
 |
@@ -319,7 +319,7 @@ PLAN-ROOT SINK
 01:SORT
 |  order by: CAST(l_shipdate AS DATE) DESC
 |  materialized: CAST(l_shipdate AS DATE)
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=309.05MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=7 row-size=54B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -354,14 +354,14 @@ WHERE
 ORDER BY rn
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=422.00MB mem-reservation=32.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=690.16MB mem-reservation=32.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: l_orderkey, l_partkey, lno_f, l_quantity, evt_ts, rn
 |  mem-estimate=22.89MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 04:SORT
 |  order by: rn ASC
-|  mem-estimate=8.00MB mem-reservation=6.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=22.89MB mem-reservation=6.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=4 row-size=40B cardinality=600.12K
 |  in pipelines: 04(GETNEXT), 01(OPEN)
 |
@@ -381,7 +381,7 @@ PLAN-ROOT SINK
 |
 01:SORT
 |  order by: CAST(l_linenumber AS FLOAT) DESC
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=286.16MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=7 row-size=50B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
@@ -416,14 +416,14 @@ WHERE
 ORDER BY rn
 ---- PLAN
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=422.00MB mem-reservation=32.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=690.16MB mem-reservation=32.00MB thread-reservation=2
 PLAN-ROOT SINK
 |  output exprs: l_orderkey, l_partkey, l_linenumber, l_quantity, evt_ts, rn
 |  mem-estimate=33.19MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 04:SORT
 |  order by: rn ASC
-|  mem-estimate=12.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=33.19MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=4 row-size=58B cardinality=600.12K
 |  in pipelines: 04(GETNEXT), 01(OPEN)
 |
@@ -443,7 +443,7 @@ PLAN-ROOT SINK
 |
 01:SORT
 |  order by: CAST(l_shipdate AS VARCHAR(20)) DESC
-|  mem-estimate=18.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=286.16MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=7 row-size=50B cardinality=6.00M
 |  in pipelines: 01(GETNEXT), 00(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/spillable-buffer-sizing.test b/testdata/workloads/functional-planner/queries/PlannerTest/spillable-buffer-sizing.test
index 2bf1c74..9ef064d 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/spillable-buffer-sizing.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/spillable-buffer-sizing.test
@@ -126,7 +126,7 @@ from tpch_parquet.lineitem
     left join tpch_parquet.orders on l_orderkey = o_orderkey
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=102.00MB Threads=5
-Per-Host Resource Estimates: Memory=510MB
+Per-Host Resource Estimates: Memory=550MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.lineitem LEFT
 OUTER JOIN tpch_parquet.orders ON l_orderkey = o_orderkey
 
@@ -142,11 +142,11 @@ PLAN-ROOT SINK
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=359.29MB mem-reservation=74.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=398.84MB mem-reservation=74.00MB thread-reservation=2
 02:HASH JOIN [LEFT OUTER JOIN, BROADCAST]
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
-|  mem-estimate=268.94MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=308.49MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1N row-size=402B cardinality=6.00M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -168,9 +168,9 @@ Per-Host Resources: mem-estimate=359.29MB mem-reservation=74.00MB thread-reserva
 |     in pipelines: 01(GETNEXT)
 |
 00:SCAN HDFS [tpch_parquet.lineitem, RANDOM]
-   HDFS partitions=1/1 files=3 size=194.00MB
+   HDFS partitions=1/1 files=3 size=193.98MB
    stored statistics:
-     table: rows=6.00M size=194.00MB
+     table: rows=6.00M size=193.98MB
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=2.14M
    mem-estimate=80.00MB mem-reservation=40.00MB thread-reservation=1
@@ -178,7 +178,7 @@ Per-Host Resources: mem-estimate=359.29MB mem-reservation=74.00MB thread-reserva
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=136.00MB Threads=4
-Per-Host Resource Estimates: Memory=510MB
+Per-Host Resource Estimates: Memory=550MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.lineitem LEFT
 OUTER JOIN tpch_parquet.orders ON l_orderkey = o_orderkey
 
@@ -204,11 +204,11 @@ Per-Instance Resources: mem-estimate=80.00MB mem-reservation=40.00MB thread-rese
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F03:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=279.29MB mem-reservation=68.00MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=318.84MB mem-reservation=68.00MB thread-reservation=1
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: o_orderkey
-|  |  mem-estimate=268.94MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=308.49MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  03:EXCHANGE [BROADCAST]
 |  |  mem-estimate=10.34MB mem-reservation=0B thread-reservation=0
@@ -228,9 +228,9 @@ Per-Instance Resources: mem-estimate=80.00MB mem-reservation=40.00MB thread-rese
 |     in pipelines: 01(GETNEXT)
 |
 00:SCAN HDFS [tpch_parquet.lineitem, RANDOM]
-   HDFS partitions=1/1 files=3 size=194.00MB
+   HDFS partitions=1/1 files=3 size=193.98MB
    stored statistics:
-     table: rows=6.00M size=194.00MB
+     table: rows=6.00M size=193.98MB
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=2.14M
    mem-estimate=80.00MB mem-reservation=40.00MB thread-reservation=0
@@ -242,8 +242,8 @@ select straight_join *
 from tpch_parquet.orders
     join /*+shuffle*/ tpch_parquet.customer on o_custkey = c_custkey
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=63.00MB Threads=6
-Per-Host Resource Estimates: Memory=214MB
+Max Per-Host Resource Reservation: Memory=80.00MB Threads=6
+Per-Host Resource Estimates: Memory=231MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.orders INNER
 JOIN /* +shuffle */ tpch_parquet.customer ON o_custkey = c_custkey
 
@@ -259,12 +259,12 @@ PLAN-ROOT SINK
 |  in pipelines: 00(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(o_custkey)] hosts=2 instances=2
-Per-Host Resources: mem-estimate=38.68MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=55.56MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 02:HASH JOIN [INNER JOIN, PARTITIONED]
 |  hash predicates: o_custkey = c_custkey
 |  fk/pk conjuncts: o_custkey = c_custkey
 |  runtime filters: RF000[bloom] <- c_custkey
-|  mem-estimate=17.12MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=388B cardinality=1.50M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -303,8 +303,8 @@ Per-Host Resources: mem-estimate=41.00MB mem-reservation=25.00MB thread-reservat
    tuple-ids=0 row-size=171B cardinality=1.50M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=63.00MB Threads=5
-Per-Host Resource Estimates: Memory=214MB
+Max Per-Host Resource Reservation: Memory=80.00MB Threads=5
+Per-Host Resource Estimates: Memory=231MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.orders INNER
 JOIN /* +shuffle */ tpch_parquet.customer ON o_custkey = c_custkey
 
@@ -325,17 +325,17 @@ Per-Instance Resources: mem-estimate=10.34MB mem-reservation=0B thread-reservati
 |  hash-table-id=00
 |  hash predicates: o_custkey = c_custkey
 |  fk/pk conjuncts: o_custkey = c_custkey
-|  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=388B cardinality=1.50M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F04:PLAN FRAGMENT [HASH(o_custkey)] hosts=2 instances=2
-|  |  Per-Instance Resources: mem-estimate=28.33MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=45.22MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: c_custkey
 |  |  runtime filters: RF000[bloom] <- c_custkey
-|  |  mem-estimate=17.12MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  04:EXCHANGE [HASH(c_custkey)]
 |  |  mem-estimate=10.22MB mem-reservation=0B thread-reservation=0
@@ -379,7 +379,7 @@ from tpch_parquet.orders
     join /*+broadcast*/ tpch_parquet.customer on o_custkey = c_custkey
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=79.00MB Threads=5
-Per-Host Resource Estimates: Memory=220MB
+Per-Host Resource Estimates: Memory=221MB
 Analyzed query: SELECT /* +straight_join */ * FROM tpch_parquet.orders INNER
 JOIN /* +broadcast */ tpch_parquet.customer ON o_custkey = c_custkey
 
@@ -395,12 +395,12 @@ PLAN-ROOT SINK
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-Per-Host Resources: mem-estimate=85.45MB mem-reservation=59.00MB thread-reservation=2 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=86.34MB mem-reservation=59.00MB thread-reservation=2 runtime-filters-memory=1.00MB
 02:HASH JOIN [INNER JOIN, BROADCAST]
 |  hash predicates: o_custkey = c_custkey
 |  fk/pk conjuncts: o_custkey = c_custkey
 |  runtime filters: RF000[bloom] <- c_custkey
-|  mem-estimate=34.23MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=35.12MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=388B cardinality=1.50M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -546,7 +546,7 @@ Per-Host Resources: mem-estimate=2.02GB mem-reservation=34.09MB thread-reservati
 |     in pipelines: 01(GETNEXT)
 |
 00:SCAN HDFS [functional_parquet.alltypes, RANDOM]
-   HDFS partitions=24/24 files=24 size=201.93KB
+   HDFS partitions=24/24 files=24 size=202.07KB
    stored statistics:
      table: rows=unavailable size=unavailable
      partitions: 0/24 rows=unavailable
@@ -610,7 +610,7 @@ Per-Instance Resources: mem-estimate=16.00MB mem-reservation=88.00KB thread-rese
 |     in pipelines: 01(GETNEXT)
 |
 00:SCAN HDFS [functional_parquet.alltypes, RANDOM]
-   HDFS partitions=24/24 files=24 size=201.93KB
+   HDFS partitions=24/24 files=24 size=202.07KB
    stored statistics:
      table: rows=unavailable size=unavailable
      partitions: 0/24 rows=unavailable
@@ -730,8 +730,8 @@ from tpch_parquet.lineitem
 group by 1, 2
 having count(*) = 1
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=86.00MB Threads=7
-Per-Host Resource Estimates: Memory=344MB
+Max Per-Host Resource Reservation: Memory=120.00MB Threads=7
+Per-Host Resource Estimates: Memory=425MB
 Analyzed query: SELECT /* +straight_join */ l_orderkey, o_orderstatus, count(*)
 FROM tpch_parquet.lineitem INNER JOIN tpch_parquet.orders ON o_orderkey =
 l_orderkey GROUP BY l_orderkey, o_orderstatus HAVING count(*) = CAST(1 AS
@@ -749,12 +749,12 @@ PLAN-ROOT SINK
 |  in pipelines: 07(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(l_orderkey,o_orderstatus)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=27.10MB mem-reservation=17.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=77.19MB mem-reservation=34.00MB thread-reservation=1
 07:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
 |  group by: l_orderkey, o_orderstatus
 |  having: count(*) = CAST(1 AS BIGINT)
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=67.10MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=29B cardinality=4.69M
 |  in pipelines: 07(GETNEXT), 00(OPEN)
 |
@@ -764,11 +764,11 @@ Per-Host Resources: mem-estimate=27.10MB mem-reservation=17.00MB thread-reservat
 |  in pipelines: 00(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=85.65MB mem-reservation=52.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=116.86MB mem-reservation=69.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 03:AGGREGATE [STREAMING]
 |  output: count(*)
 |  group by: l_orderkey, o_orderstatus
-|  mem-estimate=47.56MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=61.77MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=29B cardinality=4.69M
 |  in pipelines: 00(GETNEXT)
 |
@@ -776,7 +776,7 @@ Per-Host Resources: mem-estimate=85.65MB mem-reservation=52.00MB thread-reservat
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
 |  runtime filters: RF000[bloom] <- o_orderkey
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=29B cardinality=5.76M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -805,18 +805,18 @@ Per-Host Resources: mem-estimate=85.65MB mem-reservation=52.00MB thread-reservat
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
 Per-Host Resources: mem-estimate=81.00MB mem-reservation=5.00MB thread-reservation=2 runtime-filters-memory=1.00MB
 00:SCAN HDFS [tpch_parquet.lineitem, RANDOM]
-   HDFS partitions=1/1 files=3 size=194.00MB
+   HDFS partitions=1/1 files=3 size=193.98MB
    runtime filters: RF000[bloom] -> l_orderkey
    stored statistics:
-     table: rows=6.00M size=194.00MB
+     table: rows=6.00M size=193.98MB
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=2.14M
    mem-estimate=80.00MB mem-reservation=4.00MB thread-reservation=1
    tuple-ids=0 row-size=8B cardinality=6.00M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=86.00MB Threads=6
-Per-Host Resource Estimates: Memory=344MB
+Max Per-Host Resource Reservation: Memory=120.00MB Threads=6
+Per-Host Resource Estimates: Memory=425MB
 Analyzed query: SELECT /* +straight_join */ l_orderkey, o_orderstatus, count(*)
 FROM tpch_parquet.lineitem INNER JOIN tpch_parquet.orders ON o_orderkey =
 l_orderkey GROUP BY l_orderkey, o_orderstatus HAVING count(*) = CAST(1 AS
@@ -834,12 +834,12 @@ PLAN-ROOT SINK
 |  in pipelines: 07(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(l_orderkey,o_orderstatus)] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=27.10MB mem-reservation=17.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=77.19MB mem-reservation=34.00MB thread-reservation=1
 07:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
 |  group by: l_orderkey, o_orderstatus
 |  having: count(*) = CAST(1 AS BIGINT)
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=67.10MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=29B cardinality=4.69M
 |  in pipelines: 07(GETNEXT), 00(OPEN)
 |
@@ -849,11 +849,11 @@ Per-Instance Resources: mem-estimate=27.10MB mem-reservation=17.00MB thread-rese
 |  in pipelines: 00(GETNEXT)
 |
 F02:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=57.60MB mem-reservation=34.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=71.81MB mem-reservation=34.00MB thread-reservation=1
 03:AGGREGATE [STREAMING]
 |  output: count(*)
 |  group by: l_orderkey, o_orderstatus
-|  mem-estimate=47.56MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=61.77MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=29B cardinality=4.69M
 |  in pipelines: 00(GETNEXT)
 |
@@ -861,17 +861,17 @@ Per-Instance Resources: mem-estimate=57.60MB mem-reservation=34.00MB thread-rese
 |  hash-table-id=00
 |  hash predicates: l_orderkey = o_orderkey
 |  fk/pk conjuncts: l_orderkey = o_orderkey
-|  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,1 row-size=29B cardinality=5.76M
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F05:PLAN FRAGMENT [HASH(l_orderkey)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=28.05MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=45.05MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: o_orderkey
 |  |  runtime filters: RF000[bloom] <- o_orderkey
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  05:EXCHANGE [HASH(o_orderkey)]
 |  |  mem-estimate=10.05MB mem-reservation=0B thread-reservation=0
@@ -899,10 +899,10 @@ F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
 Per-Host Shared Resources: mem-estimate=1.00MB mem-reservation=1.00MB thread-reservation=0 runtime-filters-memory=1.00MB
 Per-Instance Resources: mem-estimate=80.00MB mem-reservation=4.00MB thread-reservation=1
 00:SCAN HDFS [tpch_parquet.lineitem, RANDOM]
-   HDFS partitions=1/1 files=3 size=194.00MB
+   HDFS partitions=1/1 files=3 size=193.98MB
    runtime filters: RF000[bloom] -> l_orderkey
    stored statistics:
-     table: rows=6.00M size=194.00MB
+     table: rows=6.00M size=193.98MB
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=2.14M
    mem-estimate=80.00MB mem-reservation=4.00MB thread-reservation=0
@@ -914,7 +914,7 @@ select distinct *
 from tpch_parquet.lineitem
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=112.00MB Threads=4
-Per-Host Resource Estimates: Memory=1.62GB
+Per-Host Resource Estimates: Memory=1.00GB
 Analyzed query: SELECT DISTINCT * FROM tpch_parquet.lineitem
 
 F02:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
@@ -929,10 +929,10 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(tpch_parquet.lineitem.l_orderkey,tpch_parquet.lineitem.l_partkey,tpch_parquet.lineitem.l_suppkey,tpch_parquet.lineitem.l_linenumber,tpch_parquet.lineitem.l_quantity,tpch_parquet.lineitem.l_extendedprice,tpch_parquet.lineitem.l_discount,tpch_parquet.lineitem.l_tax,tpch_parquet.lineitem.l_returnflag,tpch_parquet.lineitem.l_linestatus,tpch_parquet.lineitem.l_shipdate,tpch_parquet.lineitem.l_commitdate,tpch_parquet.lineitem.l_receiptdate,tpch_parquet.lineitem.l_shipin [...]
-Per-Host Resources: mem-estimate=737.12MB mem-reservation=34.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=481.48MB mem-reservation=34.00MB thread-reservation=1
 03:AGGREGATE [FINALIZE]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
-|  mem-estimate=726.43MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=470.79MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -942,17 +942,17 @@ Per-Host Resources: mem-estimate=737.12MB mem-reservation=34.00MB thread-reserva
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=806.43MB mem-reservation=74.00MB thread-reservation=2
+Per-Host Resources: mem-estimate=433.09MB mem-reservation=74.00MB thread-reservation=2
 01:AGGREGATE [STREAMING]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
-|  mem-estimate=726.43MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=353.09MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 00(GETNEXT)
 |
 00:SCAN HDFS [tpch_parquet.lineitem, RANDOM]
-   HDFS partitions=1/1 files=3 size=194.00MB
+   HDFS partitions=1/1 files=3 size=193.98MB
    stored statistics:
-     table: rows=6.00M size=194.00MB
+     table: rows=6.00M size=193.98MB
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=2.14M
    mem-estimate=80.00MB mem-reservation=40.00MB thread-reservation=1
@@ -960,7 +960,7 @@ Per-Host Resources: mem-estimate=806.43MB mem-reservation=74.00MB thread-reserva
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=112.00MB Threads=3
-Per-Host Resource Estimates: Memory=1.62GB
+Per-Host Resource Estimates: Memory=1.00GB
 Analyzed query: SELECT DISTINCT * FROM tpch_parquet.lineitem
 
 F02:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
@@ -975,10 +975,10 @@ PLAN-ROOT SINK
 |  in pipelines: 03(GETNEXT)
 |
 F01:PLAN FRAGMENT [HASH(tpch_parquet.lineitem.l_orderkey,tpch_parquet.lineitem.l_partkey,tpch_parquet.lineitem.l_suppkey,tpch_parquet.lineitem.l_linenumber,tpch_parquet.lineitem.l_quantity,tpch_parquet.lineitem.l_extendedprice,tpch_parquet.lineitem.l_discount,tpch_parquet.lineitem.l_tax,tpch_parquet.lineitem.l_returnflag,tpch_parquet.lineitem.l_linestatus,tpch_parquet.lineitem.l_shipdate,tpch_parquet.lineitem.l_commitdate,tpch_parquet.lineitem.l_receiptdate,tpch_parquet.lineitem.l_shipin [...]
-Per-Instance Resources: mem-estimate=737.12MB mem-reservation=34.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=481.48MB mem-reservation=34.00MB thread-reservation=1
 03:AGGREGATE [FINALIZE]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
-|  mem-estimate=726.43MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=470.79MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 03(GETNEXT), 00(OPEN)
 |
@@ -988,17 +988,17 @@ Per-Instance Resources: mem-estimate=737.12MB mem-reservation=34.00MB thread-res
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=806.43MB mem-reservation=74.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=433.09MB mem-reservation=74.00MB thread-reservation=1
 01:AGGREGATE [STREAMING]
 |  group by: tpch_parquet.lineitem.l_orderkey, tpch_parquet.lineitem.l_partkey, tpch_parquet.lineitem.l_suppkey, tpch_parquet.lineitem.l_linenumber, tpch_parquet.lineitem.l_quantity, tpch_parquet.lineitem.l_extendedprice, tpch_parquet.lineitem.l_discount, tpch_parquet.lineitem.l_tax, tpch_parquet.lineitem.l_returnflag, tpch_parquet.lineitem.l_linestatus, tpch_parquet.lineitem.l_shipdate, tpch_parquet.lineitem.l_commitdate, tpch_parquet.lineitem.l_receiptdate, tpch_parquet.lineitem.l_ship [...]
-|  mem-estimate=726.43MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=353.09MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=1 row-size=231B cardinality=6.00M
 |  in pipelines: 00(GETNEXT)
 |
 00:SCAN HDFS [tpch_parquet.lineitem, RANDOM]
-   HDFS partitions=1/1 files=3 size=194.00MB
+   HDFS partitions=1/1 files=3 size=193.98MB
    stored statistics:
-     table: rows=6.00M size=194.00MB
+     table: rows=6.00M size=193.98MB
      columns: all
    extrapolated-rows=disabled max-scan-range-rows=2.14M
    mem-estimate=80.00MB mem-reservation=40.00MB thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q01.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q01.test
index 9a3b5c1..4ad01d4 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q01.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q01.test
@@ -23,10 +23,10 @@ WHERE ctr1.ctr_total_return >
 ORDER BY c_customer_id
 LIMIT 100
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=26.58MB Threads=7
+Max Per-Host Resource Reservation: Memory=30.33MB Threads=7
 Per-Host Resource Estimates: Memory=331MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=330.81MB mem-reservation=26.58MB thread-reservation=7 runtime-filters-memory=5.00MB
+|  Per-Host Resources: mem-estimate=330.81MB mem-reservation=30.33MB thread-reservation=7 runtime-filters-memory=5.00MB
 PLAN-ROOT SINK
 |  output exprs: c_customer_id
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -55,7 +55,7 @@ PLAN-ROOT SINK
 |  09:AGGREGATE [FINALIZE]
 |  |  output: sum(sr_return_amt)
 |  |  group by: sr_customer_sk, sr_store_sk
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=8 row-size=24B cardinality=53.81K
 |  |  in pipelines: 09(GETNEXT), 06(OPEN)
 |  |
@@ -117,14 +117,14 @@ PLAN-ROOT SINK
 |  hash predicates: c_customer_sk = sr_customer_sk
 |  fk/pk conjuncts: none
 |  runtime filters: RF004[bloom] <- sr_customer_sk, RF005[min_max] <- sr_customer_sk
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=5,2 row-size=56B cardinality=53.81K
 |  in pipelines: 05(GETNEXT), 03(OPEN)
 |
 |--03:AGGREGATE [FINALIZE]
 |  |  output: sum(sr_return_amt)
 |  |  group by: sr_customer_sk, sr_store_sk
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=2 row-size=24B cardinality=53.81K
 |  |  in pipelines: 03(GETNEXT), 00(OPEN)
 |  |
@@ -171,8 +171,8 @@ PLAN-ROOT SINK
    tuple-ids=5 row-size=32B cardinality=100.00K
    in pipelines: 05(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=49.33MB Threads=16
-Per-Host Resource Estimates: Memory=406MB
+Max Per-Host Resource Reservation: Memory=54.95MB Threads=16
+Per-Host Resource Estimates: Memory=408MB
 F09:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -187,7 +187,7 @@ PLAN-ROOT SINK
 |  in pipelines: 14(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
-Per-Host Resources: mem-estimate=43.04MB mem-reservation=11.75MB thread-reservation=2 runtime-filters-memory=3.00MB
+Per-Host Resources: mem-estimate=44.92MB mem-reservation=13.62MB thread-reservation=2 runtime-filters-memory=3.00MB
 14:TOP-N [LIMIT=100]
 |  order by: c_customer_id ASC
 |  mem-estimate=2.73KB mem-reservation=0B thread-reservation=0
@@ -222,7 +222,7 @@ Per-Host Resources: mem-estimate=43.04MB mem-reservation=11.75MB thread-reservat
 |  |  in pipelines: 22(GETNEXT)
 |  |
 |  F07:PLAN FRAGMENT [HASH(sr_customer_sk,sr_store_sk)] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=21.26MB mem-reservation=4.88MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=21.26MB mem-reservation=6.75MB thread-reservation=1
 |  10:AGGREGATE [STREAMING]
 |  |  output: avg(sum(sr_return_amt))
 |  |  group by: sr_store_sk
@@ -233,7 +233,7 @@ Per-Host Resources: mem-estimate=43.04MB mem-reservation=11.75MB thread-reservat
 |  22:AGGREGATE [FINALIZE]
 |  |  output: sum:merge(sr_return_amt)
 |  |  group by: sr_customer_sk, sr_store_sk
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=8 row-size=24B cardinality=53.81K
 |  |  in pipelines: 22(GETNEXT), 06(OPEN)
 |  |
@@ -323,7 +323,7 @@ Per-Host Resources: mem-estimate=43.04MB mem-reservation=11.75MB thread-reservat
 |  hash predicates: c_customer_sk = sr_customer_sk
 |  fk/pk conjuncts: none
 |  runtime filters: RF004[bloom] <- sr_customer_sk, RF005[min_max] <- sr_customer_sk
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=5,2 row-size=56B cardinality=53.81K
 |  in pipelines: 05(GETNEXT), 17(OPEN)
 |
@@ -333,11 +333,11 @@ Per-Host Resources: mem-estimate=43.04MB mem-reservation=11.75MB thread-reservat
 |  |  in pipelines: 17(GETNEXT)
 |  |
 |  F03:PLAN FRAGMENT [HASH(sr_customer_sk,sr_store_sk)] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=11.26MB mem-reservation=2.88MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=11.26MB mem-reservation=4.75MB thread-reservation=1
 |  17:AGGREGATE [FINALIZE]
 |  |  output: sum:merge(sr_return_amt)
 |  |  group by: sr_customer_sk, sr_store_sk
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=2 row-size=24B cardinality=53.81K
 |  |  in pipelines: 17(GETNEXT), 00(OPEN)
 |  |
@@ -405,8 +405,8 @@ Per-Host Resources: mem-estimate=43.04MB mem-reservation=11.75MB thread-reservat
    tuple-ids=5 row-size=32B cardinality=100.00K
    in pipelines: 05(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=62.95MB Threads=15
-Per-Host Resource Estimates: Memory=212MB
+Max Per-Host Resource Reservation: Memory=70.45MB Threads=15
+Per-Host Resource Estimates: Memory=216MB
 F09:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -465,7 +465,7 @@ Per-Instance Resources: mem-estimate=16.00MB mem-reservation=2.00MB thread-reser
 |  |  in pipelines: 22(GETNEXT)
 |  |
 |  F07:PLAN FRAGMENT [HASH(sr_customer_sk,sr_store_sk)] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=21.26MB mem-reservation=4.88MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=21.26MB mem-reservation=6.75MB thread-reservation=1
 |  10:AGGREGATE [STREAMING]
 |  |  output: avg(sum(sr_return_amt))
 |  |  group by: sr_store_sk
@@ -476,7 +476,7 @@ Per-Instance Resources: mem-estimate=16.00MB mem-reservation=2.00MB thread-reser
 |  22:AGGREGATE [FINALIZE]
 |  |  output: sum:merge(sr_return_amt)
 |  |  group by: sr_customer_sk, sr_store_sk
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=8 row-size=24B cardinality=53.81K
 |  |  in pipelines: 22(GETNEXT), 06(OPEN)
 |  |
@@ -584,17 +584,17 @@ Per-Instance Resources: mem-estimate=16.00MB mem-reservation=2.00MB thread-reser
 |  hash-table-id=03
 |  hash predicates: c_customer_sk = sr_customer_sk
 |  fk/pk conjuncts: none
-|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=5,2 row-size=56B cardinality=53.81K
 |  in pipelines: 05(GETNEXT), 17(OPEN)
 |
 |--F13:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
-|  |  Per-Instance Resources: mem-estimate=8.01MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=11.76MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=03 plan-id=04 cohort-id=01
 |  |  build expressions: sr_customer_sk
 |  |  runtime filters: RF004[bloom] <- sr_customer_sk, RF005[min_max] <- sr_customer_sk
-|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  18:EXCHANGE [BROADCAST]
 |  |  mem-estimate=1.26MB mem-reservation=0B thread-reservation=0
@@ -602,11 +602,11 @@ Per-Instance Resources: mem-estimate=16.00MB mem-reservation=2.00MB thread-reser
 |  |  in pipelines: 17(GETNEXT)
 |  |
 |  F03:PLAN FRAGMENT [HASH(sr_customer_sk,sr_store_sk)] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=11.26MB mem-reservation=2.88MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=11.26MB mem-reservation=4.75MB thread-reservation=1
 |  17:AGGREGATE [FINALIZE]
 |  |  output: sum:merge(sr_return_amt)
 |  |  group by: sr_customer_sk, sr_store_sk
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=2 row-size=24B cardinality=53.81K
 |  |  in pipelines: 17(GETNEXT), 00(OPEN)
 |  |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q02.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q02.test
index 0a196c6..1880579 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q02.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q02.test
@@ -79,10 +79,10 @@ FROM
 WHERE d_week_seq1 = d_week_seq2-53
 ORDER BY d_week_seq1;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=28.88MB Threads=7
-Per-Host Resource Estimates: Memory=367MB
+Max Per-Host Resource Reservation: Memory=32.62MB Threads=7
+Per-Host Resource Estimates: Memory=370MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=366.62MB mem-reservation=28.88MB thread-reservation=7 runtime-filters-memory=5.00MB
+|  Per-Host Resources: mem-estimate=370.38MB mem-reservation=32.62MB thread-reservation=7 runtime-filters-memory=5.00MB
 PLAN-ROOT SINK
 |  output exprs: d_week_seq1, round(sun_sales1 / sun_sales2, CAST(2 AS TINYINT)), round(mon_sales1 / mon_sales2, CAST(2 AS TINYINT)), round(tue_sales1 / tue_sales2, CAST(2 AS TINYINT)), round(wed_sales1 / wed_sales2, CAST(2 AS TINYINT)), round(thu_sales1 / thu_sales2, CAST(2 AS TINYINT)), round(fri_sales1 / fri_sales2, CAST(2 AS TINYINT)), round(sat_sales1 / sat_sales2, CAST(2 AS TINYINT))
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -133,7 +133,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: sold_date_sk = d_date_sk
 |  |  fk/pk conjuncts: assumed fk/pk
 |  |  runtime filters: RF008[bloom] <- d_date_sk, RF009[min_max] <- d_date_sk
-|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=12,15 row-size=35B cardinality=2.16M
 |  |  in pipelines: 09(GETNEXT), 10(GETNEXT), 11(OPEN)
 |  |
@@ -209,7 +209,7 @@ PLAN-ROOT SINK
 |  hash predicates: sold_date_sk = d_date_sk
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF004[bloom] <- d_date_sk, RF005[min_max] <- d_date_sk
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,5 row-size=35B cardinality=2.16M
 |  in pipelines: 01(GETNEXT), 02(GETNEXT), 03(OPEN)
 |
@@ -252,8 +252,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=8B cardinality=719.38K
    in pipelines: 01(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=49.94MB Threads=15
-Per-Host Resource Estimates: Memory=428MB
+Max Per-Host Resource Reservation: Memory=53.69MB Threads=15
+Per-Host Resource Estimates: Memory=432MB
 F12:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.87MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -330,7 +330,7 @@ Per-Host Resources: mem-estimate=21.88MB mem-reservation=13.81MB thread-reservat
 |  |  in pipelines: 09(GETNEXT), 10(GETNEXT)
 |  |
 |  F08:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=111.80MB mem-reservation=10.88MB thread-reservation=2 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=113.67MB mem-reservation=12.75MB thread-reservation=2 runtime-filters-memory=1.00MB
 |  13:AGGREGATE [STREAMING]
 |  |  output: sum(CASE WHEN (d_day_name = 'Sunday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Monday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Tuesday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Wednesday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Thursday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Friday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Saturday') THEN s [...]
 |  |  group by: d_week_seq
@@ -342,7 +342,7 @@ Per-Host Resources: mem-estimate=21.88MB mem-reservation=13.81MB thread-reservat
 |  |  hash predicates: sold_date_sk = d_date_sk
 |  |  fk/pk conjuncts: assumed fk/pk
 |  |  runtime filters: RF008[bloom] <- d_date_sk, RF009[min_max] <- d_date_sk
-|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=12,15 row-size=35B cardinality=2.16M
 |  |  in pipelines: 09(GETNEXT), 10(GETNEXT), 11(OPEN)
 |  |
@@ -434,7 +434,7 @@ Per-Host Resources: mem-estimate=21.88MB mem-reservation=13.81MB thread-reservat
 |  in pipelines: 01(GETNEXT), 02(GETNEXT)
 |
 F02:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=111.80MB mem-reservation=10.88MB thread-reservation=2 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=113.67MB mem-reservation=12.75MB thread-reservation=2 runtime-filters-memory=1.00MB
 05:AGGREGATE [STREAMING]
 |  output: sum(CASE WHEN (d_day_name = 'Sunday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Monday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Tuesday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Wednesday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Thursday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Friday') THEN sales_price ELSE NULL END), sum(CASE WHEN (d_day_name = 'Saturday') THEN sale [...]
 |  group by: d_week_seq
@@ -446,7 +446,7 @@ Per-Host Resources: mem-estimate=111.80MB mem-reservation=10.88MB thread-reserva
 |  hash predicates: sold_date_sk = d_date_sk
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF004[bloom] <- d_date_sk, RF005[min_max] <- d_date_sk
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,5 row-size=35B cardinality=2.16M
 |  in pipelines: 01(GETNEXT), 02(GETNEXT), 03(OPEN)
 |
@@ -496,8 +496,8 @@ Per-Host Resources: mem-estimate=111.80MB mem-reservation=10.88MB thread-reserva
    tuple-ids=0 row-size=8B cardinality=719.38K
    in pipelines: 01(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=57.69MB Threads=14
-Per-Host Resource Estimates: Memory=244MB
+Max Per-Host Resource Reservation: Memory=65.19MB Threads=14
+Per-Host Resource Estimates: Memory=252MB
 F12:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.87MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -603,17 +603,17 @@ Per-Instance Resources: mem-estimate=16.00MB mem-reservation=7.94MB thread-reser
 |  |  hash-table-id=02
 |  |  hash predicates: sold_date_sk = d_date_sk
 |  |  fk/pk conjuncts: assumed fk/pk
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=12,15 row-size=35B cardinality=2.16M
 |  |  in pipelines: 09(GETNEXT), 10(GETNEXT), 11(OPEN)
 |  |
 |  |--F15:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=8.67MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  |  Per-Instance Resources: mem-estimate=12.42MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  |  JOIN BUILD
 |  |  |  join-table-id=02 plan-id=03 cohort-id=02
 |  |  |  build expressions: d_date_sk
 |  |  |  runtime filters: RF008[bloom] <- d_date_sk, RF009[min_max] <- d_date_sk
-|  |  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |  |
 |  |  22:EXCHANGE [BROADCAST]
 |  |  |  mem-estimate=1.92MB mem-reservation=0B thread-reservation=0
@@ -726,17 +726,17 @@ Per-Instance Resources: mem-estimate=58.00MB mem-reservation=7.00MB thread-reser
 |  hash-table-id=04
 |  hash predicates: sold_date_sk = d_date_sk
 |  fk/pk conjuncts: assumed fk/pk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,5 row-size=35B cardinality=2.16M
 |  in pipelines: 01(GETNEXT), 02(GETNEXT), 03(OPEN)
 |
 |--F17:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=8.67MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=12.42MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=04 plan-id=05 cohort-id=01
 |  |  build expressions: d_date_sk
 |  |  runtime filters: RF004[bloom] <- d_date_sk, RF005[min_max] <- d_date_sk
-|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  18:EXCHANGE [BROADCAST]
 |  |  mem-estimate=1.92MB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q04.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q04.test
index 127e80b..1500f1b 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q04.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q04.test
@@ -119,10 +119,10 @@ ORDER BY t_s_secyear.customer_id,
          t_s_secyear.customer_preferred_cust_flag
 LIMIT 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=377.94MB Threads=19
-Per-Host Resource Estimates: Memory=2.12GB
+Max Per-Host Resource Reservation: Memory=495.00MB Threads=19
+Per-Host Resource Estimates: Memory=2.19GB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=2.12GB mem-reservation=377.94MB thread-reservation=19 runtime-filters-memory=10.00MB
+|  Per-Host Resources: mem-estimate=2.19GB mem-reservation=495.00MB thread-reservation=19 runtime-filters-memory=10.00MB
 PLAN-ROOT SINK
 |  output exprs: customer_id, customer_first_name, customer_last_name, customer_preferred_cust_flag
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -138,7 +138,7 @@ PLAN-ROOT SINK
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END
 |  runtime filters: RF000[bloom] <- customer_id, RF001[min_max] <- customer_id
-|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=26,12,40,54,68,82 row-size=313B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 41(OPEN)
 |
@@ -158,7 +158,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: c_customer_sk = ws_bill_customer_sk
 |  |  fk/pk conjuncts: c_customer_sk = ws_bill_customer_sk
 |  |  runtime filters: RF031[min_max] <- ws_bill_customer_sk
-|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=78,79,80 row-size=185B cardinality=148.00K
 |  |  in pipelines: 36(GETNEXT), 37(OPEN)
 |  |
@@ -209,7 +209,7 @@ PLAN-ROOT SINK
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF002[bloom] <- customer_id, RF003[min_max] <- customer_id
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=26,12,40,54,68 row-size=269B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 34(OPEN)
 |
@@ -230,7 +230,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: c_customer_sk = ws_bill_customer_sk
 |  |  fk/pk conjuncts: c_customer_sk = ws_bill_customer_sk
 |  |  runtime filters: RF027[min_max] <- ws_bill_customer_sk
-|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=64,65,66 row-size=185B cardinality=148.00K
 |  |  in pipelines: 29(GETNEXT), 30(OPEN)
 |  |
@@ -282,7 +282,7 @@ PLAN-ROOT SINK
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END
 |  runtime filters: RF004[bloom] <- customer_id, RF005[min_max] <- customer_id
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=26,12,40,54 row-size=225B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 27(OPEN)
 |
@@ -294,7 +294,7 @@ PLAN-ROOT SINK
 |  27:AGGREGATE [FINALIZE]
 |  |  output: sum((((cs_ext_list_price - cs_ext_wholesale_cost - cs_ext_discount_amt) + cs_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=52.27MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=52.01MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=49 row-size=169B cardinality=294.63K
 |  |  in pipelines: 27(GETNEXT), 22(OPEN)
 |  |
@@ -302,7 +302,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: c_customer_sk = cs_bill_customer_sk
 |  |  fk/pk conjuncts: c_customer_sk = cs_bill_customer_sk
 |  |  runtime filters: RF023[min_max] <- cs_bill_customer_sk
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=46,47,48 row-size=185B cardinality=294.63K
 |  |  in pipelines: 22(GETNEXT), 23(OPEN)
 |  |
@@ -353,7 +353,7 @@ PLAN-ROOT SINK
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF006[bloom] <- customer_id, RF007[min_max] <- customer_id
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=26,12,40 row-size=181B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 20(OPEN)
 |
@@ -366,7 +366,7 @@ PLAN-ROOT SINK
 |  |  output: sum((((cs_ext_list_price - cs_ext_wholesale_cost - cs_ext_discount_amt) + cs_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum((((cs_ext_list_price - cs_ext_wholesale_cost - cs_ext_discount_amt) + cs_ext_sales_price) / 2)) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=52.27MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=52.01MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=35 row-size=169B cardinality=29.46K
 |  |  in pipelines: 20(GETNEXT), 15(OPEN)
 |  |
@@ -374,7 +374,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: c_customer_sk = cs_bill_customer_sk
 |  |  fk/pk conjuncts: c_customer_sk = cs_bill_customer_sk
 |  |  runtime filters: RF019[min_max] <- cs_bill_customer_sk
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=32,33,34 row-size=185B cardinality=294.63K
 |  |  in pipelines: 15(GETNEXT), 16(OPEN)
 |  |
@@ -425,7 +425,7 @@ PLAN-ROOT SINK
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF009[min_max] <- customer_id
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=26,12 row-size=137B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 06(OPEN)
 |
@@ -438,7 +438,7 @@ PLAN-ROOT SINK
 |  |  output: sum(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / CAST(2 AS DECIMAL(3,0)))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / 2) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=104.50MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=103.99MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3 row-size=169B cardinality=58.90K
 |  |  in pipelines: 06(GETNEXT), 02(OPEN)
 |  |
@@ -446,7 +446,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: ss_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: ss_customer_sk = c_customer_sk
 |  |  runtime filters: RF015[min_max] <- c_customer_sk
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=1,2,0 row-size=185B cardinality=589.03K
 |  |  in pipelines: 02(GETNEXT), 01(OPEN)
 |  |
@@ -502,7 +502,7 @@ PLAN-ROOT SINK
 13:AGGREGATE [FINALIZE]
 |  output: sum(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / CAST(2 AS DECIMAL(3,0)))
 |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  mem-estimate=104.50MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=103.99MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=17 row-size=169B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 09(OPEN)
 |
@@ -510,7 +510,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_customer_sk = c_customer_sk
 |  fk/pk conjuncts: ss_customer_sk = c_customer_sk
 |  runtime filters: RF011[min_max] <- c_customer_sk
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=15,16,14 row-size=185B cardinality=589.03K
 |  in pipelines: 09(GETNEXT), 08(OPEN)
 |
@@ -558,8 +558,8 @@ PLAN-ROOT SINK
    tuple-ids=15 row-size=24B cardinality=2.88M
    in pipelines: 09(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=656.69MB Threads=49
-Per-Host Resource Estimates: Memory=2.79GB
+Max Per-Host Resource Reservation: Memory=603.75MB Threads=49
+Per-Host Resource Estimates: Memory=2.67GB
 F36:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.03MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -574,7 +574,7 @@ PLAN-ROOT SINK
 |  in pipelines: 47(GETNEXT)
 |
 F05:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reservation=1 runtime-filters-memory=4.00MB
+Per-Host Resources: mem-estimate=137.44MB mem-reservation=105.12MB thread-reservation=1 runtime-filters-memory=4.00MB
 47:TOP-N [LIMIT=100]
 |  order by: customer_id ASC, customer_first_name ASC, customer_last_name ASC, customer_preferred_cust_flag ASC
 |  mem-estimate=7.52KB mem-reservation=0B thread-reservation=0
@@ -586,7 +586,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END
 |  runtime filters: RF000[bloom] <- customer_id, RF001[min_max] <- customer_id
-|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=26,12,40,54,68,82 row-size=313B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 81(OPEN)
 |
@@ -596,7 +596,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  in pipelines: 81(GETNEXT)
 |  |
 |  F35:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=44.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=27.34MB mem-reservation=17.00MB thread-reservation=1
 |  35:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=82 row-size=44B cardinality=148.00K
@@ -605,7 +605,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  81:AGGREGATE [FINALIZE]
 |  |  output: sum:merge((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / 2))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=81 row-size=169B cardinality=148.00K
 |  |  in pipelines: 81(GETNEXT), 37(OPEN)
 |  |
@@ -615,11 +615,11 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  in pipelines: 37(GETNEXT)
 |  |
 |  F33:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=54.99MB mem-reservation=42.50MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=46.49MB mem-reservation=34.00MB thread-reservation=1
 |  41:AGGREGATE [STREAMING]
 |  |  output: sum((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=81 row-size=169B cardinality=148.00K
 |  |  in pipelines: 37(GETNEXT)
 |  |
@@ -627,7 +627,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  hash predicates: ws_bill_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: ws_bill_customer_sk = c_customer_sk
 |  |  runtime filters: RF031[min_max] <- c_customer_sk
-|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=79,80,78 row-size=185B cardinality=148.00K
 |  |  in pipelines: 37(GETNEXT), 36(OPEN)
 |  |
@@ -698,7 +698,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF002[bloom] <- customer_id, RF003[min_max] <- customer_id
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=26,12,40,54,68 row-size=269B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 75(OPEN)
 |
@@ -708,7 +708,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  in pipelines: 75(GETNEXT)
 |  |
 |  F29:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=44.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=27.34MB mem-reservation=17.00MB thread-reservation=1
 |  28:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=68 row-size=44B cardinality=14.80K
@@ -718,7 +718,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  output: sum:merge((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / 2))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / 2)) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=67 row-size=169B cardinality=14.80K
 |  |  in pipelines: 75(GETNEXT), 30(OPEN)
 |  |
@@ -728,11 +728,11 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  in pipelines: 30(GETNEXT)
 |  |
 |  F27:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=54.99MB mem-reservation=42.50MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=46.49MB mem-reservation=34.00MB thread-reservation=1
 |  34:AGGREGATE [STREAMING]
 |  |  output: sum((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=67 row-size=169B cardinality=148.00K
 |  |  in pipelines: 30(GETNEXT)
 |  |
@@ -740,7 +740,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  hash predicates: ws_bill_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: ws_bill_customer_sk = c_customer_sk
 |  |  runtime filters: RF027[min_max] <- c_customer_sk
-|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=65,66,64 row-size=185B cardinality=148.00K
 |  |  in pipelines: 30(GETNEXT), 29(OPEN)
 |  |
@@ -813,7 +813,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END
 |  runtime filters: RF004[bloom] <- customer_id, RF005[min_max] <- customer_id
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=26,12,40,54 row-size=225B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 69(OPEN)
 |
@@ -842,11 +842,11 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  in pipelines: 23(GETNEXT)
 |  |
 |  F21:PLAN FRAGMENT [HASH(cs_bill_customer_sk)] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=55.77MB mem-reservation=42.50MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=38.77MB mem-reservation=25.50MB thread-reservation=1
 |  27:AGGREGATE [STREAMING]
 |  |  output: sum((((cs_ext_list_price - cs_ext_wholesale_cost - cs_ext_discount_amt) + cs_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=49 row-size=169B cardinality=294.63K
 |  |  in pipelines: 23(GETNEXT)
 |  |
@@ -926,7 +926,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF006[bloom] <- customer_id, RF007[min_max] <- customer_id
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=26,12,40 row-size=181B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 63(OPEN)
 |
@@ -956,11 +956,11 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  in pipelines: 16(GETNEXT)
 |  |
 |  F15:PLAN FRAGMENT [HASH(cs_bill_customer_sk)] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=55.77MB mem-reservation=42.50MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=38.77MB mem-reservation=25.50MB thread-reservation=1
 |  20:AGGREGATE [STREAMING]
 |  |  output: sum((((cs_ext_list_price - cs_ext_wholesale_cost - cs_ext_discount_amt) + cs_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=35 row-size=169B cardinality=294.63K
 |  |  in pipelines: 16(GETNEXT)
 |  |
@@ -1040,7 +1040,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF009[min_max] <- customer_id
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=26,12 row-size=137B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 57(OPEN)
 |
@@ -1050,7 +1050,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  in pipelines: 57(GETNEXT)
 |  |
 |  F11:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=62.76MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=45.17MB mem-reservation=34.00MB thread-reservation=1
 |  00:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=12 row-size=44B cardinality=58.90K
@@ -1060,7 +1060,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  output: sum:merge(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / 2)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / 2) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=52.25MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=34.66MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3 row-size=169B cardinality=58.90K
 |  |  in pipelines: 57(GETNEXT), 02(OPEN)
 |  |
@@ -1070,11 +1070,11 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  |  in pipelines: 02(GETNEXT)
 |  |
 |  F09:PLAN FRAGMENT [HASH(ss_customer_sk)] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=77.01MB mem-reservation=42.50MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=58.76MB mem-reservation=42.50MB thread-reservation=1
 |  06:AGGREGATE [STREAMING]
 |  |  output: sum(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / CAST(2 AS DECIMAL(3,0)))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=52.25MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3 row-size=169B cardinality=589.03K
 |  |  in pipelines: 02(GETNEXT)
 |  |
@@ -1159,7 +1159,7 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 52:AGGREGATE [FINALIZE]
 |  output: sum:merge(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / 2)
 |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  mem-estimate=52.25MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=34.66MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=17 row-size=169B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 09(OPEN)
 |
@@ -1169,11 +1169,11 @@ Per-Host Resources: mem-estimate=122.97MB mem-reservation=73.06MB thread-reserva
 |  in pipelines: 09(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(ss_customer_sk)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=77.01MB mem-reservation=42.50MB thread-reservation=1
+Per-Host Resources: mem-estimate=58.76MB mem-reservation=42.50MB thread-reservation=1
 13:AGGREGATE [STREAMING]
 |  output: sum(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / CAST(2 AS DECIMAL(3,0)))
 |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  mem-estimate=52.25MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=17 row-size=169B cardinality=589.03K
 |  in pipelines: 09(GETNEXT)
 |
@@ -1250,8 +1250,8 @@ Per-Host Resources: mem-estimate=82.95MB mem-reservation=6.94MB thread-reservati
    tuple-ids=15 row-size=24B cardinality=2.88M
    in pipelines: 09(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=855.38MB Threads=56
-Per-Host Resource Estimates: Memory=1.33GB
+Max Per-Host Resource Reservation: Memory=766.50MB Threads=56
+Per-Host Resource Estimates: Memory=1.25GB
 F36:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.05MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -1278,17 +1278,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END
-|  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=26,12,40,54,68,82 row-size=313B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 81(OPEN)
 |
 |--F37:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=24.30MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=41.30MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: customer_id
 |  |  runtime filters: RF000[bloom] <- customer_id, RF001[min_max] <- customer_id
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=1.00MB thread-reservation=0
 |  |
 |  82:EXCHANGE [BROADCAST]
 |  |  mem-estimate=6.30MB mem-reservation=0B thread-reservation=0
@@ -1296,7 +1296,7 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 81(GETNEXT)
 |  |
 |  F35:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Instance Resources: mem-estimate=44.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=27.34MB mem-reservation=17.00MB thread-reservation=1
 |  35:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=82 row-size=44B cardinality=148.00K
@@ -1305,7 +1305,7 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  81:AGGREGATE [FINALIZE]
 |  |  output: sum:merge((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / 2))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=81 row-size=169B cardinality=148.00K
 |  |  in pipelines: 81(GETNEXT), 37(OPEN)
 |  |
@@ -1315,11 +1315,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 37(GETNEXT)
 |  |
 |  F33:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  Per-Instance Resources: mem-estimate=36.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=19.34MB mem-reservation=17.00MB thread-reservation=1
 |  41:AGGREGATE [STREAMING]
 |  |  output: sum((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=81 row-size=169B cardinality=148.00K
 |  |  in pipelines: 37(GETNEXT)
 |  |
@@ -1327,17 +1327,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  hash-table-id=01
 |  |  hash predicates: ws_bill_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: ws_bill_customer_sk = c_customer_sk
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=79,80,78 row-size=185B cardinality=148.00K
 |  |  in pipelines: 37(GETNEXT), 36(OPEN)
 |  |
 |  |--F38:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=18.65MB mem-reservation=8.50MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=27.15MB mem-reservation=17.00MB thread-reservation=1
 |  |  JOIN BUILD
 |  |  |  join-table-id=01 plan-id=02 cohort-id=02
 |  |  |  build expressions: c_customer_sk
 |  |  |  runtime filters: RF031[min_max] <- c_customer_sk
-|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  |
 |  |  79:EXCHANGE [HASH(c_customer_sk)]
 |  |  |  mem-estimate=10.15MB mem-reservation=0B thread-reservation=0
@@ -1415,17 +1415,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  hash-table-id=03
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=26,12,40,54,68 row-size=269B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 75(OPEN)
 |
 |--F40:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.59MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=7.46MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=03 plan-id=04 cohort-id=01
 |  |  build expressions: customer_id
 |  |  runtime filters: RF002[bloom] <- customer_id, RF003[min_max] <- customer_id
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  76:EXCHANGE [BROADCAST]
 |  |  mem-estimate=731.94KB mem-reservation=0B thread-reservation=0
@@ -1433,7 +1433,7 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 75(GETNEXT)
 |  |
 |  F29:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Instance Resources: mem-estimate=44.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=27.34MB mem-reservation=17.00MB thread-reservation=1
 |  28:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=68 row-size=44B cardinality=14.80K
@@ -1443,7 +1443,7 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  output: sum:merge((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / 2))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / 2)) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=67 row-size=169B cardinality=14.80K
 |  |  in pipelines: 75(GETNEXT), 30(OPEN)
 |  |
@@ -1453,11 +1453,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 30(GETNEXT)
 |  |
 |  F27:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  Per-Instance Resources: mem-estimate=36.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=19.34MB mem-reservation=17.00MB thread-reservation=1
 |  34:AGGREGATE [STREAMING]
 |  |  output: sum((((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=67 row-size=169B cardinality=148.00K
 |  |  in pipelines: 30(GETNEXT)
 |  |
@@ -1465,17 +1465,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  hash-table-id=04
 |  |  hash predicates: ws_bill_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: ws_bill_customer_sk = c_customer_sk
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=65,66,64 row-size=185B cardinality=148.00K
 |  |  in pipelines: 30(GETNEXT), 29(OPEN)
 |  |
 |  |--F41:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=18.65MB mem-reservation=8.50MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=27.15MB mem-reservation=17.00MB thread-reservation=1
 |  |  JOIN BUILD
 |  |  |  join-table-id=04 plan-id=05 cohort-id=03
 |  |  |  build expressions: c_customer_sk
 |  |  |  runtime filters: RF027[min_max] <- c_customer_sk
-|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  |
 |  |  73:EXCHANGE [HASH(c_customer_sk)]
 |  |  |  mem-estimate=10.15MB mem-reservation=0B thread-reservation=0
@@ -1556,17 +1556,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN year_total / year_total ELSE NULL END
-|  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=26,12,40,54 row-size=225B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 69(OPEN)
 |
 |--F43:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=45.14MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=79.14MB mem-reservation=69.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=06 plan-id=07 cohort-id=01
 |  |  build expressions: customer_id
 |  |  runtime filters: RF004[bloom] <- customer_id, RF005[min_max] <- customer_id
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=68.00MB mem-reservation=68.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  70:EXCHANGE [BROADCAST]
 |  |  mem-estimate=10.14MB mem-reservation=0B thread-reservation=0
@@ -1593,11 +1593,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 23(GETNEXT)
 |  |
 |  F21:PLAN FRAGMENT [HASH(cs_bill_customer_sk)] hosts=3 instances=3
-|  Per-Instance Resources: mem-estimate=37.11MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=20.11MB mem-reservation=17.00MB thread-reservation=1
 |  27:AGGREGATE [STREAMING]
 |  |  output: sum((((cs_ext_list_price - cs_ext_wholesale_cost - cs_ext_discount_amt) + cs_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=49 row-size=169B cardinality=294.63K
 |  |  in pipelines: 23(GETNEXT)
 |  |
@@ -1695,17 +1695,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  hash-table-id=09
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=26,12,40 row-size=181B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 63(OPEN)
 |
 |--F46:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=8.13MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=11.88MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=09 plan-id=10 cohort-id=01
 |  |  build expressions: customer_id
 |  |  runtime filters: RF006[bloom] <- customer_id, RF007[min_max] <- customer_id
-|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  64:EXCHANGE [BROADCAST]
 |  |  mem-estimate=1.38MB mem-reservation=0B thread-reservation=0
@@ -1733,11 +1733,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 16(GETNEXT)
 |  |
 |  F15:PLAN FRAGMENT [HASH(cs_bill_customer_sk)] hosts=3 instances=3
-|  Per-Instance Resources: mem-estimate=37.11MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=20.11MB mem-reservation=17.00MB thread-reservation=1
 |  20:AGGREGATE [STREAMING]
 |  |  output: sum((((cs_ext_list_price - cs_ext_wholesale_cost - cs_ext_discount_amt) + cs_ext_sales_price) / CAST(2 AS DECIMAL(3,0))))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=35 row-size=169B cardinality=294.63K
 |  |  in pipelines: 16(GETNEXT)
 |  |
@@ -1835,17 +1835,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  hash-table-id=12
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=26,12 row-size=137B cardinality=589.03K
 |  in pipelines: 52(GETNEXT), 57(OPEN)
 |
 |--F49:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=12.25MB mem-reservation=9.50MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=19.75MB mem-reservation=17.00MB thread-reservation=1
 |  JOIN BUILD
 |  |  join-table-id=12 plan-id=13 cohort-id=01
 |  |  build expressions: customer_id
 |  |  runtime filters: RF009[min_max] <- customer_id
-|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=512.00KB thread-reservation=0
 |  |
 |  58:EXCHANGE [BROADCAST]
 |  |  mem-estimate=2.75MB mem-reservation=0B thread-reservation=0
@@ -1873,11 +1873,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 02(GETNEXT)
 |  |
 |  F09:PLAN FRAGMENT [HASH(ss_customer_sk)] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=40.23MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=23.23MB mem-reservation=17.00MB thread-reservation=1
 |  06:AGGREGATE [STREAMING]
 |  |  output: sum(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / CAST(2 AS DECIMAL(3,0)))
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=3 row-size=169B cardinality=589.03K
 |  |  in pipelines: 02(GETNEXT)
 |  |
@@ -1990,11 +1990,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  in pipelines: 09(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(ss_customer_sk)] hosts=3 instances=6
-Per-Instance Resources: mem-estimate=40.23MB mem-reservation=34.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=23.23MB mem-reservation=17.00MB thread-reservation=1
 13:AGGREGATE [STREAMING]
 |  output: sum(((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / CAST(2 AS DECIMAL(3,0)))
 |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=17 row-size=169B cardinality=589.03K
 |  in pipelines: 09(GETNEXT)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q05.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q05.test
index a9255e7..3160b91 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q05.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q05.test
@@ -125,10 +125,10 @@ with ssr as
          ,id
  limit 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=31.38MB Threads=5
+Max Per-Host Resource Reservation: Memory=33.19MB Threads=5
 Per-Host Resource Estimates: Memory=298MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=297.88MB mem-reservation=31.38MB thread-reservation=5 runtime-filters-memory=8.00MB
+|  Per-Host Resources: mem-estimate=297.88MB mem-reservation=33.19MB thread-reservation=5 runtime-filters-memory=8.00MB
 PLAN-ROOT SINK
 |  output exprs: CASE valid_tid(27,28,29) WHEN 27 THEN channel WHEN 28 THEN channel WHEN 29 THEN NULL END, CASE valid_tid(27,28,29) WHEN 27 THEN id WHEN 28 THEN NULL WHEN 29 THEN NULL END, aggif(valid_tid(27,28,29) IN (27, 28, 29), CASE valid_tid(27,28,29) WHEN 27 THEN sum(sales) WHEN 28 THEN sum(sales) WHEN 29 THEN sum(sales) END), aggif(valid_tid(27,28,29) IN (27, 28, 29), CASE valid_tid(27,28,29) WHEN 27 THEN sum(`returns`) WHEN 28 THEN sum(`returns`) WHEN 29 THEN sum(`returns`) END), [...]
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -142,7 +142,7 @@ PLAN-ROOT SINK
 28:AGGREGATE [FINALIZE]
 |  output: aggif(valid_tid(27,28,29) IN (CAST(27 AS INT), CAST(28 AS INT), CAST(29 AS INT)), CASE valid_tid(27,28,29) WHEN CAST(27 AS INT) THEN sum(sales) WHEN CAST(28 AS INT) THEN sum(sales) WHEN CAST(29 AS INT) THEN sum(sales) END), aggif(valid_tid(27,28,29) IN (CAST(27 AS INT), CAST(28 AS INT), CAST(29 AS INT)), CASE valid_tid(27,28,29) WHEN CAST(27 AS INT) THEN sum(`returns`) WHEN CAST(28 AS INT) THEN sum(`returns`) WHEN CAST(29 AS INT) THEN sum(`returns`) END), aggif(valid_tid(27,28 [...]
 |  group by: CASE valid_tid(27,28,29) WHEN CAST(27 AS INT) THEN channel WHEN CAST(28 AS INT) THEN channel WHEN CAST(29 AS INT) THEN NULL END, CASE valid_tid(27,28,29) WHEN CAST(27 AS INT) THEN id WHEN CAST(28 AS INT) THEN NULL WHEN CAST(29 AS INT) THEN NULL END, CASE valid_tid(27,28,29) WHEN CAST(27 AS INT) THEN CAST(27 AS INT) WHEN CAST(28 AS INT) THEN CAST(28 AS INT) WHEN CAST(29 AS INT) THEN CAST(29 AS INT) END
-|  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=30 row-size=76B cardinality=11.56K
 |  in pipelines: 28(GETNEXT), 27(OPEN)
 |
@@ -220,7 +220,7 @@ PLAN-ROOT SINK
 |  |  |  hash predicates: ws_item_sk = wr_item_sk, ws_order_number = wr_order_number
 |  |  |  fk/pk conjuncts: ws_item_sk = wr_item_sk, ws_order_number = wr_order_number
 |  |  |  runtime filters: RF012[bloom] <- wr_item_sk, RF013[bloom] <- wr_order_number, RF014[min_max] <- wr_item_sk, RF015[min_max] <- wr_order_number
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=18N,17 row-size=48B cardinality=71.76K
 |  |  |  in pipelines: 20(GETNEXT), 19(OPEN)
 |  |  |
@@ -404,7 +404,7 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=16B cardinality=2.88M
    in pipelines: 02(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=81.53MB Threads=25
+Max Per-Host Resource Reservation: Memory=79.59MB Threads=25
 Per-Host Resource Estimates: Memory=923MB
 F22:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
@@ -420,7 +420,7 @@ PLAN-ROOT SINK
 |  in pipelines: 29(GETNEXT)
 |
 F21:PLAN FRAGMENT [HASH(CASE valid_tid(27,28,29) WHEN 27 THEN murmur_hash(channel) WHEN 28 THEN murmur_hash(channel) WHEN 29 THEN murmur_hash(NULL) END,CASE valid_tid(27,28,29) WHEN 27 THEN murmur_hash(id) WHEN 28 THEN murmur_hash(NULL) WHEN 29 THEN murmur_hash(NULL) END)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=40.00MB mem-reservation=8.69MB thread-reservation=1
+Per-Host Resources: mem-estimate=40.00MB mem-reservation=7.75MB thread-reservation=1
 29:TOP-N [LIMIT=100]
 |  order by: CASE valid_tid(27,28,29) WHEN 27 THEN channel WHEN 28 THEN channel WHEN 29 THEN NULL END ASC, CASE valid_tid(27,28,29) WHEN 27 THEN id WHEN 28 THEN NULL WHEN 29 THEN NULL END ASC
 |  mem-estimate=7.03KB mem-reservation=0B thread-reservation=0
@@ -444,7 +444,7 @@ Per-Host Resources: mem-estimate=40.00MB mem-reservation=8.69MB thread-reservati
 |  Class 2
 |    output: sum:merge(sales), sum:merge(`returns`), sum:merge(profit)
 |    group by: NULL, NULL
-|  mem-estimate=30.00MB mem-reservation=6.75MB thread-reservation=0
+|  mem-estimate=30.00MB mem-reservation=5.81MB thread-reservation=0
 |  tuple-ids=27N,28N,29N row-size=216B cardinality=11.56K
 |  in pipelines: 45(GETNEXT), 33(OPEN), 37(OPEN), 43(OPEN)
 |
@@ -454,7 +454,7 @@ Per-Host Resources: mem-estimate=40.00MB mem-reservation=8.69MB thread-reservati
 |  in pipelines: 33(GETNEXT), 37(GETNEXT), 43(GETNEXT)
 |
 F20:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=40.62MB mem-reservation=8.94MB thread-reservation=1
+Per-Host Resources: mem-estimate=40.62MB mem-reservation=7.94MB thread-reservation=1
 27:AGGREGATE [STREAMING]
 |  Class 0
 |    output: sum(sales), sum(returns), sum(profit)
@@ -465,7 +465,7 @@ Per-Host Resources: mem-estimate=40.62MB mem-reservation=8.94MB thread-reservati
 |  Class 2
 |    output: sum(sales), sum(returns), sum(profit)
 |    group by: NULL, NULL
-|  mem-estimate=30.00MB mem-reservation=7.00MB thread-reservation=0
+|  mem-estimate=30.00MB mem-reservation=6.00MB thread-reservation=0
 |  tuple-ids=27N,28N,29N row-size=216B cardinality=11.56K
 |  in pipelines: 33(GETNEXT), 37(GETNEXT), 43(GETNEXT)
 |
@@ -557,7 +557,7 @@ Per-Host Resources: mem-estimate=40.62MB mem-reservation=8.94MB thread-reservati
 |  |  |  hash predicates: ws_item_sk = wr_item_sk, ws_order_number = wr_order_number
 |  |  |  fk/pk conjuncts: ws_item_sk = wr_item_sk, ws_order_number = wr_order_number
 |  |  |  runtime filters: RF012[bloom] <- wr_item_sk, RF013[bloom] <- wr_order_number, RF014[min_max] <- wr_item_sk, RF015[min_max] <- wr_order_number
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=18N,17 row-size=48B cardinality=71.76K
 |  |  |  in pipelines: 20(GETNEXT), 19(OPEN)
 |  |  |
@@ -811,8 +811,8 @@ Per-Host Resources: mem-estimate=112.10MB mem-reservation=11.88MB thread-reserva
    tuple-ids=0 row-size=16B cardinality=2.88M
    in pipelines: 02(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=120.84MB Threads=24
-Per-Host Resource Estimates: Memory=523MB
+Max Per-Host Resource Reservation: Memory=121.78MB Threads=24
+Per-Host Resource Estimates: Memory=524MB
 F22:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.05MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -981,17 +981,17 @@ Per-Instance Resources: mem-estimate=40.62MB mem-reservation=7.94MB thread-reser
 |  |  |  hash-table-id=06
 |  |  |  hash predicates: ws_item_sk = wr_item_sk, ws_order_number = wr_order_number
 |  |  |  fk/pk conjuncts: ws_item_sk = wr_item_sk, ws_order_number = wr_order_number
-|  |  |  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=18N,17 row-size=48B cardinality=71.76K
 |  |  |  in pipelines: 20(GETNEXT), 19(OPEN)
 |  |  |
 |  |  |--F29:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  |  |  Per-Instance Resources: mem-estimate=5.89MB mem-reservation=3.94MB thread-reservation=1 runtime-filters-memory=2.00MB
+|  |  |  |  Per-Instance Resources: mem-estimate=6.82MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=2.00MB
 |  |  |  JOIN BUILD
 |  |  |  |  join-table-id=06 plan-id=07 cohort-id=03
 |  |  |  |  build expressions: wr_item_sk, wr_order_number
 |  |  |  |  runtime filters: RF012[bloom] <- wr_item_sk, RF013[bloom] <- wr_order_number, RF014[min_max] <- wr_item_sk, RF015[min_max] <- wr_order_number
-|  |  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |
 |  |  |  39:EXCHANGE [HASH(wr_item_sk,wr_order_number)]
 |  |  |  |  mem-estimate=1.95MB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q06.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q06.test
index e7d5ba0..9fd3a28 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q06.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q06.test
@@ -25,10 +25,10 @@ select * from (
  having count(*) >= 10
  order by cnt limit 100) as t
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=24.50MB Threads=8
-Per-Host Resource Estimates: Memory=290MB
+Max Per-Host Resource Reservation: Memory=37.62MB Threads=8
+Per-Host Resource Estimates: Memory=303MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=289.75MB mem-reservation=24.50MB thread-reservation=8 runtime-filters-memory=6.00MB
+|  Per-Host Resources: mem-estimate=302.88MB mem-reservation=37.62MB thread-reservation=8 runtime-filters-memory=6.00MB
 PLAN-ROOT SINK
 |  output exprs: a.ca_state, count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -103,7 +103,7 @@ PLAN-ROOT SINK
 |  hash predicates: s.ss_item_sk = i.i_item_sk
 |  fk/pk conjuncts: s.ss_item_sk = i.i_item_sk
 |  runtime filters: RF004[bloom] <- i.i_item_sk, RF005[min_max] <- i.i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=2,1,0,3,4 row-size=80B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 04(OPEN)
 |
@@ -122,7 +122,7 @@ PLAN-ROOT SINK
 |  hash predicates: s.ss_sold_date_sk = d.d_date_sk
 |  fk/pk conjuncts: s.ss_sold_date_sk = d.d_date_sk
 |  runtime filters: RF006[bloom] <- d.d_date_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,1,0,3 row-size=50B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 03(OPEN)
 |
@@ -141,7 +141,7 @@ PLAN-ROOT SINK
 |  hash predicates: c.c_current_addr_sk = a.ca_address_sk
 |  fk/pk conjuncts: c.c_current_addr_sk = a.ca_address_sk
 |  runtime filters: RF008[bloom] <- a.ca_address_sk, RF009[min_max] <- a.ca_address_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=42B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 00(OPEN)
 |
@@ -159,7 +159,7 @@ PLAN-ROOT SINK
 |  hash predicates: s.ss_customer_sk = c.c_customer_sk
 |  fk/pk conjuncts: s.ss_customer_sk = c.c_customer_sk
 |  runtime filters: RF010[bloom] <- c.c_customer_sk, RF011[min_max] <- c.c_customer_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=2,1 row-size=24B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
@@ -186,8 +186,8 @@ PLAN-ROOT SINK
    tuple-ids=2 row-size=16B cardinality=2.88M
    in pipelines: 02(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=39.81MB Threads=19
-Per-Host Resource Estimates: Memory=344MB
+Max Per-Host Resource Reservation: Memory=52.94MB Threads=19
+Per-Host Resource Estimates: Memory=357MB
 F11:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -223,7 +223,7 @@ Per-Host Resources: mem-estimate=10.02MB mem-reservation=1.94MB thread-reservati
 |  in pipelines: 02(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=62.43MB mem-reservation=20.62MB thread-reservation=2 runtime-filters-memory=6.00MB
+Per-Host Resources: mem-estimate=75.55MB mem-reservation=33.75MB thread-reservation=2 runtime-filters-memory=6.00MB
 15:AGGREGATE [STREAMING]
 |  output: count(*)
 |  group by: a.ca_state
@@ -336,7 +336,7 @@ Per-Host Resources: mem-estimate=62.43MB mem-reservation=20.62MB thread-reservat
 |  hash predicates: s.ss_item_sk = i.i_item_sk
 |  fk/pk conjuncts: s.ss_item_sk = i.i_item_sk
 |  runtime filters: RF004[bloom] <- i.i_item_sk, RF005[min_max] <- i.i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=2,1,0,3,4 row-size=80B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 04(OPEN)
 |
@@ -362,7 +362,7 @@ Per-Host Resources: mem-estimate=62.43MB mem-reservation=20.62MB thread-reservat
 |  hash predicates: s.ss_sold_date_sk = d.d_date_sk
 |  fk/pk conjuncts: s.ss_sold_date_sk = d.d_date_sk
 |  runtime filters: RF006[bloom] <- d.d_date_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,1,0,3 row-size=50B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 03(OPEN)
 |
@@ -388,7 +388,7 @@ Per-Host Resources: mem-estimate=62.43MB mem-reservation=20.62MB thread-reservat
 |  hash predicates: c.c_current_addr_sk = a.ca_address_sk
 |  fk/pk conjuncts: c.c_current_addr_sk = a.ca_address_sk
 |  runtime filters: RF008[bloom] <- a.ca_address_sk, RF009[min_max] <- a.ca_address_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=42B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 00(OPEN)
 |
@@ -413,7 +413,7 @@ Per-Host Resources: mem-estimate=62.43MB mem-reservation=20.62MB thread-reservat
 |  hash predicates: s.ss_customer_sk = c.c_customer_sk
 |  fk/pk conjuncts: s.ss_customer_sk = c.c_customer_sk
 |  runtime filters: RF010[bloom] <- c.c_customer_sk, RF011[min_max] <- c.c_customer_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=2,1 row-size=24B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
@@ -447,8 +447,8 @@ Per-Host Resources: mem-estimate=62.43MB mem-reservation=20.62MB thread-reservat
    tuple-ids=2 row-size=16B cardinality=2.88M
    in pipelines: 02(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=59.38MB Threads=20
-Per-Host Resource Estimates: Memory=250MB
+Max Per-Host Resource Reservation: Memory=85.62MB Threads=20
+Per-Host Resource Estimates: Memory=276MB
 F11:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -614,17 +614,17 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  hash-table-id=02
 |  hash predicates: s.ss_item_sk = i.i_item_sk
 |  fk/pk conjuncts: s.ss_item_sk = i.i_item_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=2,1,0,3,4 row-size=80B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 04(OPEN)
 |
 |--F14:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.42MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=7.30MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=02 plan-id=03 cohort-id=01
 |  |  build expressions: i.i_item_sk
 |  |  runtime filters: RF004[bloom] <- i.i_item_sk, RF005[min_max] <- i.i_item_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  20:EXCHANGE [BROADCAST]
 |  |  mem-estimate=559.39KB mem-reservation=0B thread-reservation=0
@@ -649,17 +649,17 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  hash-table-id=03
 |  hash predicates: s.ss_sold_date_sk = d.d_date_sk
 |  fk/pk conjuncts: s.ss_sold_date_sk = d.d_date_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,1,0,3 row-size=50B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 03(OPEN)
 |
 |--F15:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.44MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=11.07MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=03 plan-id=04 cohort-id=01
 |  |  build expressions: d.d_date_sk
 |  |  runtime filters: RF006[bloom] <- d.d_date_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  19:EXCHANGE [BROADCAST]
 |  |  mem-estimate=582.70KB mem-reservation=0B thread-reservation=0
@@ -684,17 +684,17 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  hash-table-id=04
 |  hash predicates: c.c_current_addr_sk = a.ca_address_sk
 |  fk/pk conjuncts: c.c_current_addr_sk = a.ca_address_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=2,1,0 row-size=42B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 00(OPEN)
 |
 |--F16:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.75MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=11.38MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=04 plan-id=05 cohort-id=01
 |  |  build expressions: a.ca_address_sk
 |  |  runtime filters: RF008[bloom] <- a.ca_address_sk, RF009[min_max] <- a.ca_address_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  18:EXCHANGE [BROADCAST]
 |  |  mem-estimate=900.91KB mem-reservation=0B thread-reservation=0
@@ -717,17 +717,17 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  hash-table-id=05
 |  hash predicates: s.ss_customer_sk = c.c_customer_sk
 |  fk/pk conjuncts: s.ss_customer_sk = c.c_customer_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=2,1 row-size=24B cardinality=2.88M
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
 |--F17:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.65MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=18.77MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=05 plan-id=06 cohort-id=01
 |  |  build expressions: c.c_customer_sk
 |  |  runtime filters: RF010[bloom] <- c.c_customer_sk, RF011[min_max] <- c.c_customer_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=512.00KB thread-reservation=0
 |  |
 |  17:EXCHANGE [BROADCAST]
 |  |  mem-estimate=793.25KB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q07.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q07.test
index 32254b5..1667c36 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q07.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q07.test
@@ -28,10 +28,10 @@ order by
   i_item_id
 limit 100
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=31.34MB Threads=6
-Per-Host Resource Estimates: Memory=306MB
+Max Per-Host Resource Reservation: Memory=40.78MB Threads=6
+Per-Host Resource Estimates: Memory=316MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=306.31MB mem-reservation=31.34MB thread-reservation=6 runtime-filters-memory=4.00MB
+|  Per-Host Resources: mem-estimate=315.75MB mem-reservation=40.78MB thread-reservation=6 runtime-filters-memory=4.00MB
 PLAN-ROOT SINK
 |  output exprs: i_item_id, avg(ss_quantity), avg(ss_list_price), avg(ss_coupon_amt), avg(ss_sales_price)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -53,7 +53,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_item_sk = i_item_sk
 |  fk/pk conjuncts: ss_item_sk = i_item_sk
 |  runtime filters: RF000[bloom] <- i_item_sk, RF001[min_max] <- i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,2,1,4,3 row-size=162B cardinality=261.60K
 |  in pipelines: 00(GETNEXT), 03(OPEN)
 |
@@ -90,7 +90,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_cdemo_sk = cd_demo_sk
 |  fk/pk conjuncts: ss_cdemo_sk = cd_demo_sk
 |  runtime filters: RF004[bloom] <- cd_demo_sk, RF005[min_max] <- cd_demo_sk
-|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=0,2,1 row-size=96B cardinality=263.34K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -140,8 +140,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=36B cardinality=2.88M
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=39.28MB Threads=12
-Per-Host Resource Estimates: Memory=336MB
+Max Per-Host Resource Reservation: Memory=48.72MB Threads=12
+Per-Host Resource Estimates: Memory=346MB
 F06:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -176,7 +176,7 @@ Per-Host Resources: mem-estimate=10.36MB mem-reservation=1.94MB thread-reservati
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=145.85MB mem-reservation=24.31MB thread-reservation=2 runtime-filters-memory=4.00MB
+Per-Host Resources: mem-estimate=155.29MB mem-reservation=33.75MB thread-reservation=2 runtime-filters-memory=4.00MB
 09:AGGREGATE [STREAMING]
 |  output: avg(CAST(ss_quantity AS BIGINT)), avg(ss_list_price), avg(ss_coupon_amt), avg(ss_sales_price)
 |  group by: i_item_id
@@ -188,7 +188,7 @@ Per-Host Resources: mem-estimate=145.85MB mem-reservation=24.31MB thread-reserva
 |  hash predicates: ss_item_sk = i_item_sk
 |  fk/pk conjuncts: ss_item_sk = i_item_sk
 |  runtime filters: RF000[bloom] <- i_item_sk, RF001[min_max] <- i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,2,1,4,3 row-size=162B cardinality=261.60K
 |  in pipelines: 00(GETNEXT), 03(OPEN)
 |
@@ -239,7 +239,7 @@ Per-Host Resources: mem-estimate=145.85MB mem-reservation=24.31MB thread-reserva
 |  hash predicates: ss_cdemo_sk = cd_demo_sk
 |  fk/pk conjuncts: ss_cdemo_sk = cd_demo_sk
 |  runtime filters: RF004[bloom] <- cd_demo_sk, RF005[min_max] <- cd_demo_sk
-|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=0,2,1 row-size=96B cardinality=263.34K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -303,8 +303,8 @@ Per-Host Resources: mem-estimate=145.85MB mem-reservation=24.31MB thread-reserva
    tuple-ids=0 row-size=36B cardinality=2.88M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=65.53MB Threads=13
-Per-Host Resource Estimates: Memory=183MB
+Max Per-Host Resource Reservation: Memory=84.41MB Threads=13
+Per-Host Resource Estimates: Memory=202MB
 F06:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.04MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -352,17 +352,17 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=6.00MB thread-reser
 |  hash-table-id=00
 |  hash predicates: ss_item_sk = i_item_sk
 |  fk/pk conjuncts: ss_item_sk = i_item_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,2,1,4,3 row-size=162B cardinality=261.60K
 |  in pipelines: 00(GETNEXT), 03(OPEN)
 |
 |--F07:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.53MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=7.41MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: i_item_sk
 |  |  runtime filters: RF000[bloom] <- i_item_sk, RF001[min_max] <- i_item_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  14:EXCHANGE [BROADCAST]
 |  |  mem-estimate=672.81KB mem-reservation=0B thread-reservation=0
@@ -419,17 +419,17 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=6.00MB thread-reser
 |  hash-table-id=02
 |  hash predicates: ss_cdemo_sk = cd_demo_sk
 |  fk/pk conjuncts: ss_cdemo_sk = cd_demo_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=0,2,1 row-size=96B cardinality=263.34K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F09:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=22.84MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=39.84MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=02 plan-id=03 cohort-id=01
 |  |  build expressions: cd_demo_sk
 |  |  runtime filters: RF004[bloom] <- cd_demo_sk, RF005[min_max] <- cd_demo_sk
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=1.00MB thread-reservation=0
 |  |
 |  12:EXCHANGE [BROADCAST]
 |  |  mem-estimate=4.84MB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q08.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q08.test
index b995a50..f7290e3 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q08.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q08.test
@@ -78,10 +78,10 @@ GROUP BY s_store_name
 ORDER BY s_store_name
 LIMIT 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=15.84MB Threads=7
-Per-Host Resource Estimates: Memory=228MB
+Max Per-Host Resource Reservation: Memory=18.65MB Threads=7
+Per-Host Resource Estimates: Memory=231MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=227.81MB mem-reservation=15.84MB thread-reservation=7 runtime-filters-memory=4.00MB
+|  Per-Host Resources: mem-estimate=230.62MB mem-reservation=18.65MB thread-reservation=7 runtime-filters-memory=4.00MB
 PLAN-ROOT SINK
 |  output exprs: s_store_name, sum(ss_net_profit)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -125,7 +125,7 @@ PLAN-ROOT SINK
 |  |  |  hash predicates: ca_address_sk = c_current_addr_sk
 |  |  |  fk/pk conjuncts: none
 |  |  |  runtime filters: RF006[bloom] <- c_current_addr_sk, RF007[min_max] <- c_current_addr_sk
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=6,7 row-size=38B cardinality=51.30K
 |  |  |  in pipelines: 05(GETNEXT), 06(OPEN)
 |  |  |
@@ -223,8 +223,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=12B cardinality=2.88M
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=33.15MB Threads=15
-Per-Host Resource Estimates: Memory=288MB
+Max Per-Host Resource Reservation: Memory=35.96MB Threads=15
+Per-Host Resource Estimates: Memory=290MB
 F09:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -302,7 +302,7 @@ Per-Host Resources: mem-estimate=50.86MB mem-reservation=11.81MB thread-reservat
 |  |  |  in pipelines: 05(GETNEXT)
 |  |  |
 |  |  F05:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
-|  |  Per-Host Resources: mem-estimate=45.77MB mem-reservation=5.44MB thread-reservation=2 runtime-filters-memory=1.00MB
+|  |  Per-Host Resources: mem-estimate=48.58MB mem-reservation=8.25MB thread-reservation=2 runtime-filters-memory=1.00MB
 |  |  08:AGGREGATE [STREAMING]
 |  |  |  output: count(*)
 |  |  |  group by: substring(ca_zip, CAST(1 AS BIGINT), CAST(5 AS BIGINT))
@@ -314,7 +314,7 @@ Per-Host Resources: mem-estimate=50.86MB mem-reservation=11.81MB thread-reservat
 |  |  |  hash predicates: ca_address_sk = c_current_addr_sk
 |  |  |  fk/pk conjuncts: none
 |  |  |  runtime filters: RF006[bloom] <- c_current_addr_sk, RF007[min_max] <- c_current_addr_sk
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=6,7 row-size=38B cardinality=51.30K
 |  |  |  in pipelines: 05(GETNEXT), 06(OPEN)
 |  |  |
@@ -446,8 +446,8 @@ Per-Host Resources: mem-estimate=50.86MB mem-reservation=11.81MB thread-reservat
    tuple-ids=0 row-size=12B cardinality=2.88M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=48.84MB Threads=16
-Per-Host Resource Estimates: Memory=222MB
+Max Per-Host Resource Reservation: Memory=54.46MB Threads=16
+Per-Host Resource Estimates: Memory=228MB
 F09:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -555,17 +555,17 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  |  |  hash-table-id=02
 |  |  |  hash predicates: ca_address_sk = c_current_addr_sk
 |  |  |  fk/pk conjuncts: none
-|  |  |  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=6,7 row-size=38B cardinality=51.30K
 |  |  |  in pipelines: 05(GETNEXT), 06(OPEN)
 |  |  |
 |  |  |--F12:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
-|  |  |  |  Per-Instance Resources: mem-estimate=5.71MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  |  |  Per-Instance Resources: mem-estimate=11.33MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  |  |  JOIN BUILD
 |  |  |  |  join-table-id=02 plan-id=03 cohort-id=03
 |  |  |  |  build expressions: c_current_addr_sk
 |  |  |  |  runtime filters: RF006[bloom] <- c_current_addr_sk, RF007[min_max] <- c_current_addr_sk
-|  |  |  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |
 |  |  |  19:EXCHANGE [BROADCAST]
 |  |  |  |  mem-estimate=851.08KB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q09.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q09.test
index 3bf7d73..5692647 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q09.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q09.test
@@ -48,9 +48,9 @@ from reason
 where r_reason_sk = 1
 ---- PLAN
 Max Per-Host Resource Reservation: Memory=10.63MB Threads=17
-Per-Host Resource Estimates: Memory=566MB
+Per-Host Resource Estimates: Memory=416MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=566.00MB mem-reservation=10.63MB thread-reservation=17
+|  Per-Host Resources: mem-estimate=416.23MB mem-reservation=10.63MB thread-reservation=17
 PLAN-ROOT SINK
 |  output exprs: CASE WHEN count(*) > CAST(74129 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(122840 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(56580 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(10097 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(165306 AS BIGINT) THEN avg(ss_ext_discou [...]
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -62,7 +62,7 @@ PLAN-ROOT SINK
 |
 |--30:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=54 row-size=8B cardinality=1
 |  |  in pipelines: 30(GETNEXT), 29(OPEN)
 |  |
@@ -87,7 +87,7 @@ PLAN-ROOT SINK
 |
 |--28:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=50 row-size=8B cardinality=1
 |  |  in pipelines: 28(GETNEXT), 27(OPEN)
 |  |
@@ -112,7 +112,7 @@ PLAN-ROOT SINK
 |
 |--26:AGGREGATE [FINALIZE]
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=46 row-size=8B cardinality=1
 |  |  in pipelines: 26(GETNEXT), 25(OPEN)
 |  |
@@ -137,7 +137,7 @@ PLAN-ROOT SINK
 |
 |--24:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=43 row-size=8B cardinality=1
 |  |  in pipelines: 24(GETNEXT), 23(OPEN)
 |  |
@@ -162,7 +162,7 @@ PLAN-ROOT SINK
 |
 |--22:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=39 row-size=8B cardinality=1
 |  |  in pipelines: 22(GETNEXT), 21(OPEN)
 |  |
@@ -187,7 +187,7 @@ PLAN-ROOT SINK
 |
 |--20:AGGREGATE [FINALIZE]
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=35 row-size=8B cardinality=1
 |  |  in pipelines: 20(GETNEXT), 19(OPEN)
 |  |
@@ -212,7 +212,7 @@ PLAN-ROOT SINK
 |
 |--18:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=32 row-size=8B cardinality=1
 |  |  in pipelines: 18(GETNEXT), 17(OPEN)
 |  |
@@ -237,7 +237,7 @@ PLAN-ROOT SINK
 |
 |--16:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=28 row-size=8B cardinality=1
 |  |  in pipelines: 16(GETNEXT), 15(OPEN)
 |  |
@@ -262,7 +262,7 @@ PLAN-ROOT SINK
 |
 |--14:AGGREGATE [FINALIZE]
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=24 row-size=8B cardinality=1
 |  |  in pipelines: 14(GETNEXT), 13(OPEN)
 |  |
@@ -287,7 +287,7 @@ PLAN-ROOT SINK
 |
 |--12:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=21 row-size=8B cardinality=1
 |  |  in pipelines: 12(GETNEXT), 11(OPEN)
 |  |
@@ -312,7 +312,7 @@ PLAN-ROOT SINK
 |
 |--10:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=17 row-size=8B cardinality=1
 |  |  in pipelines: 10(GETNEXT), 09(OPEN)
 |  |
@@ -337,7 +337,7 @@ PLAN-ROOT SINK
 |
 |--08:AGGREGATE [FINALIZE]
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=13 row-size=8B cardinality=1
 |  |  in pipelines: 08(GETNEXT), 07(OPEN)
 |  |
@@ -362,7 +362,7 @@ PLAN-ROOT SINK
 |
 |--06:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=10 row-size=8B cardinality=1
 |  |  in pipelines: 06(GETNEXT), 05(OPEN)
 |  |
@@ -387,7 +387,7 @@ PLAN-ROOT SINK
 |
 |--04:AGGREGATE [FINALIZE]
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=6 row-size=8B cardinality=1
 |  |  in pipelines: 04(GETNEXT), 03(OPEN)
 |  |
@@ -425,7 +425,7 @@ PLAN-ROOT SINK
 |
 02:AGGREGATE [FINALIZE]
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
@@ -444,9 +444,9 @@ PLAN-ROOT SINK
    in pipelines: 01(GETNEXT)
 ---- DISTRIBUTEDPLAN
 Max Per-Host Resource Reservation: Memory=14.63MB Threads=47
-Per-Host Resource Estimates: Memory=720MB
+Per-Host Resource Estimates: Memory=421MB
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.23MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=4.25MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: CASE WHEN count(*) > CAST(74129 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(122840 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(56580 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(10097 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(165306 AS BIGINT) THEN avg(ss_ext_discou [...]
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -462,10 +462,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 89(GETNEXT)
 |  |
 |  F30:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  89:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=54 row-size=8B cardinality=1
 |  |  in pipelines: 89(GETNEXT), 30(OPEN)
 |  |
@@ -475,10 +475,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 30(GETNEXT)
 |  |
 |  F29:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  30:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=53 row-size=8B cardinality=1
 |  |  in pipelines: 30(GETNEXT), 29(OPEN)
 |  |
@@ -507,10 +507,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 86(GETNEXT)
 |  |
 |  F28:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  86:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=50 row-size=8B cardinality=1
 |  |  in pipelines: 86(GETNEXT), 28(OPEN)
 |  |
@@ -520,10 +520,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 28(GETNEXT)
 |  |
 |  F27:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  28:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=49 row-size=8B cardinality=1
 |  |  in pipelines: 28(GETNEXT), 27(OPEN)
 |  |
@@ -552,10 +552,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 83(GETNEXT)
 |  |
 |  F26:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  83:AGGREGATE [FINALIZE]
 |  |  output: count:merge(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=46 row-size=8B cardinality=1
 |  |  in pipelines: 83(GETNEXT), 26(OPEN)
 |  |
@@ -565,10 +565,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 26(GETNEXT)
 |  |
 |  F25:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=2
 |  26:AGGREGATE
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=46 row-size=8B cardinality=1
 |  |  in pipelines: 26(GETNEXT), 25(OPEN)
 |  |
@@ -597,10 +597,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 80(GETNEXT)
 |  |
 |  F24:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  80:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=43 row-size=8B cardinality=1
 |  |  in pipelines: 80(GETNEXT), 24(OPEN)
 |  |
@@ -610,10 +610,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 24(GETNEXT)
 |  |
 |  F23:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  24:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=42 row-size=8B cardinality=1
 |  |  in pipelines: 24(GETNEXT), 23(OPEN)
 |  |
@@ -642,10 +642,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 77(GETNEXT)
 |  |
 |  F22:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  77:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=39 row-size=8B cardinality=1
 |  |  in pipelines: 77(GETNEXT), 22(OPEN)
 |  |
@@ -655,10 +655,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 22(GETNEXT)
 |  |
 |  F21:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  22:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=38 row-size=8B cardinality=1
 |  |  in pipelines: 22(GETNEXT), 21(OPEN)
 |  |
@@ -687,10 +687,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 74(GETNEXT)
 |  |
 |  F20:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  74:AGGREGATE [FINALIZE]
 |  |  output: count:merge(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=35 row-size=8B cardinality=1
 |  |  in pipelines: 74(GETNEXT), 20(OPEN)
 |  |
@@ -700,10 +700,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 20(GETNEXT)
 |  |
 |  F19:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=2
 |  20:AGGREGATE
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=35 row-size=8B cardinality=1
 |  |  in pipelines: 20(GETNEXT), 19(OPEN)
 |  |
@@ -732,10 +732,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 71(GETNEXT)
 |  |
 |  F18:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  71:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=32 row-size=8B cardinality=1
 |  |  in pipelines: 71(GETNEXT), 18(OPEN)
 |  |
@@ -745,10 +745,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 18(GETNEXT)
 |  |
 |  F17:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  18:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=31 row-size=8B cardinality=1
 |  |  in pipelines: 18(GETNEXT), 17(OPEN)
 |  |
@@ -777,10 +777,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 68(GETNEXT)
 |  |
 |  F16:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  68:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=28 row-size=8B cardinality=1
 |  |  in pipelines: 68(GETNEXT), 16(OPEN)
 |  |
@@ -790,10 +790,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 16(GETNEXT)
 |  |
 |  F15:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  16:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=27 row-size=8B cardinality=1
 |  |  in pipelines: 16(GETNEXT), 15(OPEN)
 |  |
@@ -822,10 +822,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 65(GETNEXT)
 |  |
 |  F14:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  65:AGGREGATE [FINALIZE]
 |  |  output: count:merge(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=24 row-size=8B cardinality=1
 |  |  in pipelines: 65(GETNEXT), 14(OPEN)
 |  |
@@ -835,10 +835,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 14(GETNEXT)
 |  |
 |  F13:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=2
 |  14:AGGREGATE
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=24 row-size=8B cardinality=1
 |  |  in pipelines: 14(GETNEXT), 13(OPEN)
 |  |
@@ -867,10 +867,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 62(GETNEXT)
 |  |
 |  F12:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  62:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=21 row-size=8B cardinality=1
 |  |  in pipelines: 62(GETNEXT), 12(OPEN)
 |  |
@@ -880,10 +880,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 12(GETNEXT)
 |  |
 |  F11:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  12:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=20 row-size=8B cardinality=1
 |  |  in pipelines: 12(GETNEXT), 11(OPEN)
 |  |
@@ -912,10 +912,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 59(GETNEXT)
 |  |
 |  F10:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  59:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=17 row-size=8B cardinality=1
 |  |  in pipelines: 59(GETNEXT), 10(OPEN)
 |  |
@@ -925,10 +925,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 10(GETNEXT)
 |  |
 |  F09:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  10:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=16 row-size=8B cardinality=1
 |  |  in pipelines: 10(GETNEXT), 09(OPEN)
 |  |
@@ -957,10 +957,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 56(GETNEXT)
 |  |
 |  F08:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  56:AGGREGATE [FINALIZE]
 |  |  output: count:merge(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=13 row-size=8B cardinality=1
 |  |  in pipelines: 56(GETNEXT), 08(OPEN)
 |  |
@@ -970,10 +970,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 08(GETNEXT)
 |  |
 |  F07:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=2
+|  Per-Host Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=2
 |  08:AGGREGATE
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=13 row-size=8B cardinality=1
 |  |  in pipelines: 08(GETNEXT), 07(OPEN)
 |  |
@@ -1002,10 +1002,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 53(GETNEXT)
 |  |
 |  F06:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  53:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=10 row-size=8B cardinality=1
 |  |  in pipelines: 53(GETNEXT), 06(OPEN)
 |  |
@@ -1015,10 +1015,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 06(GETNEXT)
 |  |
 |  F05:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  06:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=9 row-size=8B cardinality=1
 |  |  in pipelines: 06(GETNEXT), 05(OPEN)
 |  |
@@ -1047,10 +1047,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 50(GETNEXT)
 |  |
 |  F04:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  50:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=6 row-size=8B cardinality=1
 |  |  in pipelines: 50(GETNEXT), 04(OPEN)
 |  |
@@ -1060,10 +1060,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 04(GETNEXT)
 |  |
 |  F03:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=42.00MB mem-reservation=1.00MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=32.02MB mem-reservation=1.00MB thread-reservation=2
 |  04:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=5 row-size=8B cardinality=1
 |  |  in pipelines: 04(GETNEXT), 03(OPEN)
 |  |
@@ -1108,7 +1108,7 @@ PLAN-ROOT SINK
 |
 47:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 47(GETNEXT), 02(OPEN)
 |
@@ -1118,10 +1118,10 @@ PLAN-ROOT SINK
 |  in pipelines: 02(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=2
+Per-Host Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=2
 02:AGGREGATE
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
@@ -1140,9 +1140,9 @@ Per-Host Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reserva
    in pipelines: 01(GETNEXT)
 ---- PARALLELPLANS
 Max Per-Host Resource Reservation: Memory=25.26MB Threads=61
-Per-Host Resource Estimates: Memory=950MB
+Per-Host Resource Estimates: Memory=501MB
 F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=14.00MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: CASE WHEN count(*) > CAST(74129 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(122840 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(56580 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(10097 AS BIGINT) THEN avg(ss_ext_discount_amt) ELSE avg(ss_net_profit) END, CASE WHEN count(*) > CAST(165306 AS BIGINT) THEN avg(ss_ext_discou [...]
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -1165,10 +1165,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 89(GETNEXT)
 |  |
 |  F30:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  89:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=54 row-size=8B cardinality=1
 |  |  in pipelines: 89(GETNEXT), 30(OPEN)
 |  |
@@ -1178,10 +1178,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 30(GETNEXT)
 |  |
 |  F29:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  30:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=53 row-size=8B cardinality=1
 |  |  in pipelines: 30(GETNEXT), 29(OPEN)
 |  |
@@ -1217,10 +1217,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 86(GETNEXT)
 |  |
 |  F28:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  86:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=50 row-size=8B cardinality=1
 |  |  in pipelines: 86(GETNEXT), 28(OPEN)
 |  |
@@ -1230,10 +1230,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 28(GETNEXT)
 |  |
 |  F27:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  28:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=49 row-size=8B cardinality=1
 |  |  in pipelines: 28(GETNEXT), 27(OPEN)
 |  |
@@ -1269,10 +1269,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 83(GETNEXT)
 |  |
 |  F26:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  83:AGGREGATE [FINALIZE]
 |  |  output: count:merge(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=46 row-size=8B cardinality=1
 |  |  in pipelines: 83(GETNEXT), 26(OPEN)
 |  |
@@ -1282,10 +1282,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 26(GETNEXT)
 |  |
 |  F25:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=1
 |  26:AGGREGATE
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=46 row-size=8B cardinality=1
 |  |  in pipelines: 26(GETNEXT), 25(OPEN)
 |  |
@@ -1321,10 +1321,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 80(GETNEXT)
 |  |
 |  F24:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  80:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=43 row-size=8B cardinality=1
 |  |  in pipelines: 80(GETNEXT), 24(OPEN)
 |  |
@@ -1334,10 +1334,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 24(GETNEXT)
 |  |
 |  F23:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  24:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=42 row-size=8B cardinality=1
 |  |  in pipelines: 24(GETNEXT), 23(OPEN)
 |  |
@@ -1373,10 +1373,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 77(GETNEXT)
 |  |
 |  F22:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  77:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=39 row-size=8B cardinality=1
 |  |  in pipelines: 77(GETNEXT), 22(OPEN)
 |  |
@@ -1386,10 +1386,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 22(GETNEXT)
 |  |
 |  F21:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  22:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=38 row-size=8B cardinality=1
 |  |  in pipelines: 22(GETNEXT), 21(OPEN)
 |  |
@@ -1425,10 +1425,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 74(GETNEXT)
 |  |
 |  F20:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  74:AGGREGATE [FINALIZE]
 |  |  output: count:merge(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=35 row-size=8B cardinality=1
 |  |  in pipelines: 74(GETNEXT), 20(OPEN)
 |  |
@@ -1438,10 +1438,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 20(GETNEXT)
 |  |
 |  F19:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=1
 |  20:AGGREGATE
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=35 row-size=8B cardinality=1
 |  |  in pipelines: 20(GETNEXT), 19(OPEN)
 |  |
@@ -1477,10 +1477,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 71(GETNEXT)
 |  |
 |  F18:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  71:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=32 row-size=8B cardinality=1
 |  |  in pipelines: 71(GETNEXT), 18(OPEN)
 |  |
@@ -1490,10 +1490,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 18(GETNEXT)
 |  |
 |  F17:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  18:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=31 row-size=8B cardinality=1
 |  |  in pipelines: 18(GETNEXT), 17(OPEN)
 |  |
@@ -1529,10 +1529,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 68(GETNEXT)
 |  |
 |  F16:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  68:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=28 row-size=8B cardinality=1
 |  |  in pipelines: 68(GETNEXT), 16(OPEN)
 |  |
@@ -1542,10 +1542,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 16(GETNEXT)
 |  |
 |  F15:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  16:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=27 row-size=8B cardinality=1
 |  |  in pipelines: 16(GETNEXT), 15(OPEN)
 |  |
@@ -1581,10 +1581,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 65(GETNEXT)
 |  |
 |  F14:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  65:AGGREGATE [FINALIZE]
 |  |  output: count:merge(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=24 row-size=8B cardinality=1
 |  |  in pipelines: 65(GETNEXT), 14(OPEN)
 |  |
@@ -1594,10 +1594,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 14(GETNEXT)
 |  |
 |  F13:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=1
 |  14:AGGREGATE
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=24 row-size=8B cardinality=1
 |  |  in pipelines: 14(GETNEXT), 13(OPEN)
 |  |
@@ -1633,10 +1633,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 62(GETNEXT)
 |  |
 |  F12:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  62:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=21 row-size=8B cardinality=1
 |  |  in pipelines: 62(GETNEXT), 12(OPEN)
 |  |
@@ -1646,10 +1646,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 12(GETNEXT)
 |  |
 |  F11:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  12:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=20 row-size=8B cardinality=1
 |  |  in pipelines: 12(GETNEXT), 11(OPEN)
 |  |
@@ -1685,10 +1685,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 59(GETNEXT)
 |  |
 |  F10:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  59:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=17 row-size=8B cardinality=1
 |  |  in pipelines: 59(GETNEXT), 10(OPEN)
 |  |
@@ -1698,10 +1698,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 10(GETNEXT)
 |  |
 |  F09:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  10:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=16 row-size=8B cardinality=1
 |  |  in pipelines: 10(GETNEXT), 09(OPEN)
 |  |
@@ -1737,10 +1737,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 56(GETNEXT)
 |  |
 |  F08:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  56:AGGREGATE [FINALIZE]
 |  |  output: count:merge(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=13 row-size=8B cardinality=1
 |  |  in pipelines: 56(GETNEXT), 08(OPEN)
 |  |
@@ -1750,10 +1750,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 08(GETNEXT)
 |  |
 |  F07:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=1
 |  08:AGGREGATE
 |  |  output: count(*)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=13 row-size=8B cardinality=1
 |  |  in pipelines: 08(GETNEXT), 07(OPEN)
 |  |
@@ -1789,10 +1789,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 53(GETNEXT)
 |  |
 |  F06:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  53:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=10 row-size=8B cardinality=1
 |  |  in pipelines: 53(GETNEXT), 06(OPEN)
 |  |
@@ -1802,10 +1802,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 06(GETNEXT)
 |  |
 |  F05:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  06:AGGREGATE
 |  |  output: avg(ss_net_profit)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=9 row-size=8B cardinality=1
 |  |  in pipelines: 06(GETNEXT), 05(OPEN)
 |  |
@@ -1841,10 +1841,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 50(GETNEXT)
 |  |
 |  F04:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  50:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=6 row-size=8B cardinality=1
 |  |  in pipelines: 50(GETNEXT), 04(OPEN)
 |  |
@@ -1854,10 +1854,10 @@ PLAN-ROOT SINK
 |  |  in pipelines: 04(GETNEXT)
 |  |
 |  F03:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=1.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=16.02MB mem-reservation=1.00MB thread-reservation=1
 |  04:AGGREGATE
 |  |  output: avg(ss_ext_discount_amt)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=5 row-size=8B cardinality=1
 |  |  in pipelines: 04(GETNEXT), 03(OPEN)
 |  |
@@ -1909,7 +1909,7 @@ PLAN-ROOT SINK
 |
 47:AGGREGATE [FINALIZE]
 |  output: count:merge(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 47(GETNEXT), 02(OPEN)
 |
@@ -1919,10 +1919,10 @@ PLAN-ROOT SINK
 |  in pipelines: 02(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-Per-Instance Resources: mem-estimate=26.00MB mem-reservation=128.00KB thread-reservation=1
+Per-Instance Resources: mem-estimate=16.02MB mem-reservation=128.00KB thread-reservation=1
 02:AGGREGATE
 |  output: count(*)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=2 row-size=8B cardinality=1
 |  in pipelines: 02(GETNEXT), 01(OPEN)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q10a.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q10a.test
index 163587c..99f1487 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q10a.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q10a.test
@@ -59,10 +59,10 @@ select
           cd_dep_college_count
 limit 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=31.69MB Threads=8
-Per-Host Resource Estimates: Memory=432MB
+Max Per-Host Resource Reservation: Memory=37.31MB Threads=8
+Per-Host Resource Estimates: Memory=437MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=431.69MB mem-reservation=31.69MB thread-reservation=8 runtime-filters-memory=7.00MB
+|  Per-Host Resources: mem-estimate=437.31MB mem-reservation=37.31MB thread-reservation=8 runtime-filters-memory=7.00MB
 PLAN-ROOT SINK
 |  output exprs: cd_gender, cd_marital_status, cd_education_status, count(*), cd_purchase_estimate, count(*), cd_credit_rating, count(*), cd_dep_count, count(*), cd_dep_employed_count, count(*), cd_dep_college_count, count(*)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -119,7 +119,7 @@ PLAN-ROOT SINK
 |  |  |  hash predicates: cd_demo_sk = c.c_current_cdemo_sk
 |  |  |  fk/pk conjuncts: none
 |  |  |  runtime filters: RF012[bloom] <- c.c_current_cdemo_sk, RF013[min_max] <- c.c_current_cdemo_sk
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=2,0 row-size=99B cardinality=100.00K
 |  |  |  in pipelines: 02(GETNEXT), 00(OPEN)
 |  |  |
@@ -247,8 +247,8 @@ PLAN-ROOT SINK
    tuple-ids=6 row-size=8B cardinality=719.38K
    in pipelines: 07(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=47.00MB Threads=19
-Per-Host Resource Estimates: Memory=513MB
+Max Per-Host Resource Reservation: Memory=52.62MB Threads=19
+Per-Host Resource Estimates: Memory=519MB
 F12:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.03MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -311,7 +311,7 @@ Per-Host Resources: mem-estimate=17.34MB mem-reservation=7.88MB thread-reservati
 |  |  |  in pipelines: 02(GETNEXT)
 |  |  |
 |  |  F07:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
-|  |  Per-Host Resources: mem-estimate=135.99MB mem-reservation=14.81MB thread-reservation=2 runtime-filters-memory=2.00MB
+|  |  Per-Host Resources: mem-estimate=141.61MB mem-reservation=20.44MB thread-reservation=2 runtime-filters-memory=2.00MB
 |  |  14:HASH JOIN [INNER JOIN, BROADCAST]
 |  |  |  hash predicates: c.c_current_addr_sk = ca.ca_address_sk
 |  |  |  fk/pk conjuncts: c.c_current_addr_sk = ca.ca_address_sk
@@ -344,7 +344,7 @@ Per-Host Resources: mem-estimate=17.34MB mem-reservation=7.88MB thread-reservati
 |  |  |  hash predicates: cd_demo_sk = c.c_current_cdemo_sk
 |  |  |  fk/pk conjuncts: none
 |  |  |  runtime filters: RF012[bloom] <- c.c_current_cdemo_sk, RF013[min_max] <- c.c_current_cdemo_sk
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=2,0 row-size=99B cardinality=100.00K
 |  |  |  in pipelines: 02(GETNEXT), 00(OPEN)
 |  |  |
@@ -514,8 +514,8 @@ Per-Host Resources: mem-estimate=100.95MB mem-reservation=8.94MB thread-reservat
    tuple-ids=6 row-size=8B cardinality=719.38K
    in pipelines: 07(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=64.06MB Threads=19
-Per-Host Resource Estimates: Memory=242MB
+Max Per-Host Resource Reservation: Memory=75.31MB Threads=19
+Per-Host Resource Estimates: Memory=253MB
 F12:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.03MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -636,17 +636,17 @@ Per-Instance Resources: mem-estimate=10.20MB mem-reservation=2.00MB thread-reser
 |  |  |  hash-table-id=03
 |  |  |  hash predicates: cd_demo_sk = c.c_current_cdemo_sk
 |  |  |  fk/pk conjuncts: none
-|  |  |  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=2,0 row-size=99B cardinality=100.00K
 |  |  |  in pipelines: 02(GETNEXT), 00(OPEN)
 |  |  |
 |  |  |--F16:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
-|  |  |  |  Per-Instance Resources: mem-estimate=7.91MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  |  |  Per-Instance Resources: mem-estimate=19.16MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  |  |  JOIN BUILD
 |  |  |  |  join-table-id=03 plan-id=04 cohort-id=03
 |  |  |  |  build expressions: c.c_current_cdemo_sk
 |  |  |  |  runtime filters: RF012[bloom] <- c.c_current_cdemo_sk, RF013[min_max] <- c.c_current_cdemo_sk
-|  |  |  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  |
 |  |  |  22:EXCHANGE [BROADCAST]
 |  |  |  |  mem-estimate=1.16MB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q11.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q11.test
index 5da19b0..0bf5521 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q11.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q11.test
@@ -80,10 +80,10 @@ ORDER BY t_s_secyear.customer_id,
          t_s_secyear.customer_preferred_cust_flag
 LIMIT 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=265.06MB Threads=13
-Per-Host Resource Estimates: Memory=1.11GB
+Max Per-Host Resource Reservation: Memory=346.25MB Threads=13
+Per-Host Resource Estimates: Memory=1.25GB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=1.11GB mem-reservation=265.06MB thread-reservation=13 runtime-filters-memory=10.00MB
+|  Per-Host Resources: mem-estimate=1.25GB mem-reservation=346.25MB thread-reservation=13 runtime-filters-memory=10.00MB
 PLAN-ROOT SINK
 |  output exprs: customer_id, customer_first_name, customer_last_name, customer_preferred_cust_flag
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -99,7 +99,7 @@ PLAN-ROOT SINK
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN (year_total * CAST(1.0000 AS DECIMAL(5,4))) / year_total ELSE CAST(0 AS DECIMAL(38,6)) END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN (year_total * CAST(1.0000 AS DECIMAL(5,4))) / year_total ELSE CAST(0 AS DECIMAL(38,6)) END
 |  runtime filters: RF000[bloom] <- customer_id, RF001[min_max] <- customer_id
-|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=18,8,28,38 row-size=225B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 27(OPEN)
 |
@@ -140,7 +140,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: c_customer_sk = ws_bill_customer_sk
 |  |  fk/pk conjuncts: none
 |  |  runtime filters: RF021[min_max] <- ws_bill_customer_sk
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=58.42MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=34,35 row-size=169B cardinality=719.38K
 |  |  in pipelines: 22(GETNEXT), 23(OPEN)
 |  |
@@ -170,7 +170,7 @@ PLAN-ROOT SINK
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF002[bloom] <- customer_id, RF003[min_max] <- customer_id
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=18,8,28 row-size=181B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 20(OPEN)
 |
@@ -212,7 +212,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: c_customer_sk = ws_bill_customer_sk
 |  |  fk/pk conjuncts: none
 |  |  runtime filters: RF016[bloom] <- ws_bill_customer_sk, RF017[min_max] <- ws_bill_customer_sk
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=58.42MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=24,25 row-size=169B cardinality=719.38K
 |  |  in pipelines: 15(GETNEXT), 16(OPEN)
 |  |
@@ -242,7 +242,7 @@ PLAN-ROOT SINK
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF004[bloom] <- customer_id, RF005[min_max] <- customer_id
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=18,8 row-size=137B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 06(OPEN)
 |
@@ -255,7 +255,7 @@ PLAN-ROOT SINK
 |  |  output: sum(ss_ext_list_price - ss_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum(ss_ext_list_price - ss_ext_discount_amt) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=104.50MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=103.99MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3 row-size=169B cardinality=58.90K
 |  |  in pipelines: 06(GETNEXT), 01(OPEN)
 |  |
@@ -263,7 +263,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: c_customer_sk = ss_customer_sk
 |  |  fk/pk conjuncts: c_customer_sk = ss_customer_sk
 |  |  runtime filters: RF010[bloom] <- ss_customer_sk, RF011[min_max] <- ss_customer_sk
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  |  mem-estimate=40.89MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=0,1,2 row-size=177B cardinality=589.03K
 |  |  in pipelines: 01(GETNEXT), 02(OPEN)
 |  |
@@ -319,7 +319,7 @@ PLAN-ROOT SINK
 13:AGGREGATE [FINALIZE]
 |  output: sum(ss_ext_list_price - ss_ext_discount_amt)
 |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  mem-estimate=104.50MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=103.99MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=13 row-size=169B cardinality=589.03K
 |  in pipelines: 13(GETNEXT), 08(OPEN)
 |
@@ -327,7 +327,7 @@ PLAN-ROOT SINK
 |  hash predicates: c_customer_sk = ss_customer_sk
 |  fk/pk conjuncts: c_customer_sk = ss_customer_sk
 |  runtime filters: RF006[bloom] <- ss_customer_sk, RF007[min_max] <- ss_customer_sk
-|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
+|  mem-estimate=40.89MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=10,11,12 row-size=177B cardinality=589.03K
 |  in pipelines: 08(GETNEXT), 09(OPEN)
 |
@@ -375,8 +375,8 @@ PLAN-ROOT SINK
    tuple-ids=10 row-size=153B cardinality=100.00K
    in pipelines: 08(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=407.94MB Threads=33
-Per-Host Resource Estimates: Memory=1.50GB
+Max Per-Host Resource Reservation: Memory=370.12MB Threads=33
+Per-Host Resource Estimates: Memory=1.39GB
 F24:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.03MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -391,7 +391,7 @@ PLAN-ROOT SINK
 |  in pipelines: 31(GETNEXT)
 |
 F05:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservation=1 runtime-filters-memory=3.00MB
+Per-Host Resources: mem-estimate=86.18MB mem-reservation=65.38MB thread-reservation=1 runtime-filters-memory=3.00MB
 31:TOP-N [LIMIT=100]
 |  order by: customer_id ASC, customer_first_name ASC, customer_last_name ASC, customer_preferred_cust_flag ASC
 |  mem-estimate=7.52KB mem-reservation=0B thread-reservation=0
@@ -403,7 +403,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN (year_total * CAST(1.0000 AS DECIMAL(5,4))) / year_total ELSE CAST(0 AS DECIMAL(38,6)) END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN (year_total * CAST(1.0000 AS DECIMAL(5,4))) / year_total ELSE CAST(0 AS DECIMAL(38,6)) END
 |  runtime filters: RF000[bloom] <- customer_id, RF001[min_max] <- customer_id
-|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=18,8,28,38 row-size=225B cardinality=589.03K
 |  in pipelines: 36(GETNEXT), 53(OPEN)
 |
@@ -413,7 +413,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  in pipelines: 53(GETNEXT)
 |  |
 |  F23:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=44.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=27.34MB mem-reservation=17.00MB thread-reservation=1
 |  21:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=38 row-size=44B cardinality=148.00K
@@ -422,7 +422,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  53:AGGREGATE [FINALIZE]
 |  |  output: sum:merge(ws_ext_list_price - ws_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=37 row-size=169B cardinality=148.00K
 |  |  in pipelines: 53(GETNEXT), 23(OPEN)
 |  |
@@ -432,11 +432,11 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  in pipelines: 23(GETNEXT)
 |  |
 |  F20:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=61.13MB mem-reservation=45.44MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=52.63MB mem-reservation=36.94MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  27:AGGREGATE [STREAMING]
 |  |  output: sum(ws_ext_list_price - ws_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=37 row-size=169B cardinality=148.00K
 |  |  in pipelines: 23(GETNEXT)
 |  |
@@ -472,7 +472,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  hash predicates: ws_bill_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: none
 |  |  runtime filters: RF021[min_max] <- c_customer_sk
-|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=35,34 row-size=169B cardinality=719.38K
 |  |  in pipelines: 23(GETNEXT), 22(OPEN)
 |  |
@@ -515,7 +515,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF002[bloom] <- customer_id, RF003[min_max] <- customer_id
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=18,8,28 row-size=181B cardinality=589.03K
 |  in pipelines: 36(GETNEXT), 47(OPEN)
 |
@@ -525,7 +525,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  in pipelines: 47(GETNEXT)
 |  |
 |  F17:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=44.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=27.34MB mem-reservation=17.00MB thread-reservation=1
 |  14:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=28 row-size=44B cardinality=14.80K
@@ -535,7 +535,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  output: sum:merge(ws_ext_list_price - ws_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum(ws_ext_list_price - ws_ext_discount_amt) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=27 row-size=169B cardinality=14.80K
 |  |  in pipelines: 47(GETNEXT), 16(OPEN)
 |  |
@@ -545,11 +545,11 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  in pipelines: 16(GETNEXT)
 |  |
 |  F14:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=62.13MB mem-reservation=46.44MB thread-reservation=1 runtime-filters-memory=2.00MB
+|  Per-Host Resources: mem-estimate=53.63MB mem-reservation=37.94MB thread-reservation=1 runtime-filters-memory=2.00MB
 |  20:AGGREGATE [STREAMING]
 |  |  output: sum(ws_ext_list_price - ws_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=27 row-size=169B cardinality=148.00K
 |  |  in pipelines: 16(GETNEXT)
 |  |
@@ -585,7 +585,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  hash predicates: ws_bill_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: none
 |  |  runtime filters: RF016[bloom] <- c_customer_sk, RF017[min_max] <- c_customer_sk
-|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=25,24 row-size=169B cardinality=719.38K
 |  |  in pipelines: 16(GETNEXT), 15(OPEN)
 |  |
@@ -629,7 +629,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  runtime filters: RF004[bloom] <- customer_id, RF005[min_max] <- customer_id
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=18,8 row-size=137B cardinality=589.03K
 |  in pipelines: 36(GETNEXT), 41(OPEN)
 |
@@ -639,7 +639,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  in pipelines: 41(GETNEXT)
 |  |
 |  F11:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=62.76MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=45.17MB mem-reservation=34.00MB thread-reservation=1
 |  00:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=8 row-size=44B cardinality=58.90K
@@ -649,7 +649,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  output: sum:merge(ss_ext_list_price - ss_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum(ss_ext_list_price - ss_ext_discount_amt) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=52.25MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=34.66MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3 row-size=169B cardinality=58.90K
 |  |  in pipelines: 41(GETNEXT), 02(OPEN)
 |  |
@@ -659,11 +659,11 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  |  in pipelines: 02(GETNEXT)
 |  |
 |  F09:PLAN FRAGMENT [HASH(ss_customer_sk)] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=76.49MB mem-reservation=43.50MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=58.24MB mem-reservation=43.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  06:AGGREGATE [STREAMING]
 |  |  output: sum(ss_ext_list_price - ss_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=52.25MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=3 row-size=169B cardinality=589.03K
 |  |  in pipelines: 02(GETNEXT)
 |  |
@@ -748,7 +748,7 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 36:AGGREGATE [FINALIZE]
 |  output: sum:merge(ss_ext_list_price - ss_ext_discount_amt)
 |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  mem-estimate=52.25MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=34.66MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=13 row-size=169B cardinality=589.03K
 |  in pipelines: 36(GETNEXT), 09(OPEN)
 |
@@ -758,11 +758,11 @@ Per-Host Resources: mem-estimate=90.58MB mem-reservation=52.19MB thread-reservat
 |  in pipelines: 09(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(ss_customer_sk)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=76.49MB mem-reservation=43.50MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=58.24MB mem-reservation=43.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 13:AGGREGATE [STREAMING]
 |  output: sum(ss_ext_list_price - ss_ext_discount_amt)
 |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  mem-estimate=52.25MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=13 row-size=169B cardinality=589.03K
 |  in pipelines: 09(GETNEXT)
 |
@@ -839,8 +839,8 @@ Per-Host Resources: mem-estimate=51.95MB mem-reservation=5.94MB thread-reservati
    tuple-ids=11 row-size=16B cardinality=2.88M
    in pipelines: 09(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=576.88MB Threads=40
-Per-Host Resource Estimates: Memory=940MB
+Max Per-Host Resource Reservation: Memory=484.25MB Threads=40
+Per-Host Resource Estimates: Memory=848MB
 F24:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.05MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -867,17 +867,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
 |  other predicates: CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN (year_total * CAST(1.0000 AS DECIMAL(5,4))) / year_total ELSE CAST(0 AS DECIMAL(38,6)) END > CASE WHEN year_total > CAST(0 AS DECIMAL(3,0)) THEN (year_total * CAST(1.0000 AS DECIMAL(5,4))) / year_total ELSE CAST(0 AS DECIMAL(38,6)) END
-|  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=18,8,28,38 row-size=225B cardinality=589.03K
 |  in pipelines: 36(GETNEXT), 53(OPEN)
 |
 |--F25:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=24.30MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=41.30MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: customer_id
 |  |  runtime filters: RF000[bloom] <- customer_id, RF001[min_max] <- customer_id
-|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=1.00MB thread-reservation=0
 |  |
 |  54:EXCHANGE [BROADCAST]
 |  |  mem-estimate=6.30MB mem-reservation=0B thread-reservation=0
@@ -885,7 +885,7 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 53(GETNEXT)
 |  |
 |  F23:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Instance Resources: mem-estimate=44.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=27.34MB mem-reservation=17.00MB thread-reservation=1
 |  21:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=38 row-size=44B cardinality=148.00K
@@ -894,7 +894,7 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  53:AGGREGATE [FINALIZE]
 |  |  output: sum:merge(ws_ext_list_price - ws_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=37 row-size=169B cardinality=148.00K
 |  |  in pipelines: 53(GETNEXT), 23(OPEN)
 |  |
@@ -904,11 +904,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 23(GETNEXT)
 |  |
 |  F20:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  Per-Instance Resources: mem-estimate=39.53MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=22.53MB mem-reservation=17.00MB thread-reservation=1
 |  27:AGGREGATE [STREAMING]
 |  |  output: sum(ws_ext_list_price - ws_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=37 row-size=169B cardinality=148.00K
 |  |  in pipelines: 23(GETNEXT)
 |  |
@@ -952,17 +952,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  hash-table-id=02
 |  |  hash predicates: ws_bill_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: none
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=35,34 row-size=169B cardinality=719.38K
 |  |  in pipelines: 23(GETNEXT), 22(OPEN)
 |  |
 |  |--F27:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=18.65MB mem-reservation=8.50MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=27.15MB mem-reservation=17.00MB thread-reservation=1
 |  |  JOIN BUILD
 |  |  |  join-table-id=02 plan-id=03 cohort-id=02
 |  |  |  build expressions: c_customer_sk
 |  |  |  runtime filters: RF021[min_max] <- c_customer_sk
-|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  |
 |  |  50:EXCHANGE [HASH(c_customer_sk)]
 |  |  |  mem-estimate=10.15MB mem-reservation=0B thread-reservation=0
@@ -1004,17 +1004,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  hash-table-id=03
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=18,8,28 row-size=181B cardinality=589.03K
 |  in pipelines: 36(GETNEXT), 47(OPEN)
 |
 |--F28:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.59MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=7.46MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=03 plan-id=04 cohort-id=01
 |  |  build expressions: customer_id
 |  |  runtime filters: RF002[bloom] <- customer_id, RF003[min_max] <- customer_id
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  48:EXCHANGE [BROADCAST]
 |  |  mem-estimate=731.94KB mem-reservation=0B thread-reservation=0
@@ -1022,7 +1022,7 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 47(GETNEXT)
 |  |
 |  F17:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Instance Resources: mem-estimate=44.34MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=27.34MB mem-reservation=17.00MB thread-reservation=1
 |  14:UNION
 |  |  mem-estimate=0B mem-reservation=0B thread-reservation=0
 |  |  tuple-ids=28 row-size=44B cardinality=14.80K
@@ -1032,7 +1032,7 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  output: sum:merge(ws_ext_list_price - ws_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
 |  |  having: sum(ws_ext_list_price - ws_ext_discount_amt) > CAST(0 AS DECIMAL(3,0))
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=27 row-size=169B cardinality=14.80K
 |  |  in pipelines: 47(GETNEXT), 16(OPEN)
 |  |
@@ -1042,11 +1042,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 16(GETNEXT)
 |  |
 |  F14:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  Per-Instance Resources: mem-estimate=39.53MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=22.53MB mem-reservation=17.00MB thread-reservation=1
 |  20:AGGREGATE [STREAMING]
 |  |  output: sum(ws_ext_list_price - ws_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=27 row-size=169B cardinality=148.00K
 |  |  in pipelines: 16(GETNEXT)
 |  |
@@ -1090,17 +1090,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  hash-table-id=05
 |  |  hash predicates: ws_bill_customer_sk = c_customer_sk
 |  |  fk/pk conjuncts: none
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=25,24 row-size=169B cardinality=719.38K
 |  |  in pipelines: 16(GETNEXT), 15(OPEN)
 |  |
 |  |--F30:PLAN FRAGMENT [HASH(ws_bill_customer_sk)] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=19.65MB mem-reservation=9.50MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  |  Per-Instance Resources: mem-estimate=28.15MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  |  JOIN BUILD
 |  |  |  join-table-id=05 plan-id=06 cohort-id=03
 |  |  |  build expressions: c_customer_sk
 |  |  |  runtime filters: RF016[bloom] <- c_customer_sk, RF017[min_max] <- c_customer_sk
-|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  |
 |  |  44:EXCHANGE [HASH(c_customer_sk)]
 |  |  |  mem-estimate=10.15MB mem-reservation=0B thread-reservation=0
@@ -1144,17 +1144,17 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  hash-table-id=06
 |  hash predicates: customer_id = customer_id
 |  fk/pk conjuncts: assumed fk/pk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=18,8 row-size=137B cardinality=589.03K
 |  in pipelines: 36(GETNEXT), 41(OPEN)
 |
 |--F31:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=13.25MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=20.75MB mem-reservation=18.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=06 plan-id=07 cohort-id=01
 |  |  build expressions: customer_id
 |  |  runtime filters: RF004[bloom] <- customer_id, RF005[min_max] <- customer_id
-|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=512.00KB thread-reservation=0
 |  |
 |  42:EXCHANGE [BROADCAST]
 |  |  mem-estimate=2.75MB mem-reservation=0B thread-reservation=0
@@ -1182,11 +1182,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  |  in pipelines: 02(GETNEXT)
 |  |
 |  F09:PLAN FRAGMENT [HASH(ss_customer_sk)] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=38.68MB mem-reservation=34.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=21.68MB mem-reservation=17.00MB thread-reservation=1
 |  06:AGGREGATE [STREAMING]
 |  |  output: sum(ss_ext_list_price - ss_ext_discount_amt)
 |  |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  tuple-ids=3 row-size=169B cardinality=589.03K
 |  |  in pipelines: 02(GETNEXT)
 |  |
@@ -1299,11 +1299,11 @@ Per-Instance Resources: mem-estimate=45.02MB mem-reservation=34.00MB thread-rese
 |  in pipelines: 09(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(ss_customer_sk)] hosts=3 instances=6
-Per-Instance Resources: mem-estimate=38.68MB mem-reservation=34.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=21.68MB mem-reservation=17.00MB thread-reservation=1
 13:AGGREGATE [STREAMING]
 |  output: sum(ss_ext_list_price - ss_ext_discount_amt)
 |  group by: c_customer_id, c_first_name, c_last_name, c_preferred_cust_flag, c_birth_country, c_login, c_email_address, d_year
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=13 row-size=169B cardinality=589.03K
 |  in pipelines: 09(GETNEXT)
 |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q12.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q12.test
index 2dd2044..bbe3c7b 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q12.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q12.test
@@ -27,10 +27,10 @@ ORDER BY i_category,
          revenueratio
 LIMIT 100
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=52.00MB Threads=4
-Per-Host Resource Estimates: Memory=234MB
+Max Per-Host Resource Reservation: Memory=52.81MB Threads=4
+Per-Host Resource Estimates: Memory=235MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=233.88MB mem-reservation=52.00MB thread-reservation=4 runtime-filters-memory=2.00MB
+|  Per-Host Resources: mem-estimate=234.81MB mem-reservation=52.81MB thread-reservation=4 runtime-filters-memory=2.00MB
 PLAN-ROOT SINK
 |  output exprs: i_item_id, i_item_desc, i_category, i_class, i_current_price, sum(ws_ext_sales_price), sum(ws_ext_sales_price) * CAST(100.0000 AS DECIMAL(7,4)) / sum(sum(ws_ext_sales_price))
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -50,14 +50,14 @@ PLAN-ROOT SINK
 |
 06:SORT
 |  order by: i_class ASC NULLS LAST
-|  mem-estimate=12.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=40.77MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=10 row-size=198B cardinality=215.82K
 |  in pipelines: 06(GETNEXT), 05(OPEN)
 |
 05:AGGREGATE [FINALIZE]
 |  output: sum(ws_ext_sales_price)
 |  group by: i_item_id, i_item_desc, i_category, i_class, i_current_price
-|  mem-estimate=44.85MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=44.07MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=3 row-size=198B cardinality=215.82K
 |  in pipelines: 05(GETNEXT), 00(OPEN)
 |
@@ -86,7 +86,7 @@ PLAN-ROOT SINK
 |  hash predicates: ws_item_sk = i_item_sk
 |  fk/pk conjuncts: ws_item_sk = i_item_sk
 |  runtime filters: RF002[bloom] <- i_item_sk, RF003[min_max] <- i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,1 row-size=206B cardinality=215.82K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -114,8 +114,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=16B cardinality=719.38K
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=104.88MB Threads=8
-Per-Host Resource Estimates: Memory=319MB
+Max Per-Host Resource Reservation: Memory=105.81MB Threads=8
+Per-Host Resource Estimates: Memory=329MB
 F04:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.05MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -130,7 +130,7 @@ PLAN-ROOT SINK
 |  in pipelines: 08(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(i_class)] hosts=2 instances=2
-Per-Host Resources: mem-estimate=50.00MB mem-reservation=50.00MB thread-reservation=1
+Per-Host Resources: mem-estimate=58.39MB mem-reservation=50.00MB thread-reservation=1
 08:TOP-N [LIMIT=100]
 |  order by: i_category ASC, i_class ASC, i_item_id ASC, i_item_desc ASC, sum(ws_ext_sales_price) * 100.0000 / sum(sum(ws_ext_sales_price)) ASC
 |  mem-estimate=20.91KB mem-reservation=0B thread-reservation=0
@@ -146,7 +146,7 @@ Per-Host Resources: mem-estimate=50.00MB mem-reservation=50.00MB thread-reservat
 |
 06:SORT
 |  order by: i_class ASC NULLS LAST
-|  mem-estimate=12.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=20.39MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=10 row-size=198B cardinality=215.82K
 |  in pipelines: 06(GETNEXT), 12(OPEN)
 |
@@ -163,7 +163,7 @@ Per-Host Resources: mem-estimate=50.00MB mem-reservation=50.00MB thread-reservat
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-Per-Host Resources: mem-estimate=137.25MB mem-reservation=47.88MB thread-reservation=2 runtime-filters-memory=2.00MB
+Per-Host Resources: mem-estimate=138.19MB mem-reservation=48.81MB thread-reservation=2 runtime-filters-memory=2.00MB
 05:AGGREGATE [STREAMING]
 |  output: sum(ws_ext_sales_price)
 |  group by: i_item_id, i_item_desc, i_category, i_class, i_current_price
@@ -203,7 +203,7 @@ Per-Host Resources: mem-estimate=137.25MB mem-reservation=47.88MB thread-reserva
 |  hash predicates: ws_item_sk = i_item_sk
 |  fk/pk conjuncts: ws_item_sk = i_item_sk
 |  runtime filters: RF002[bloom] <- i_item_sk, RF003[min_max] <- i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,1 row-size=206B cardinality=215.82K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -238,8 +238,8 @@ Per-Host Resources: mem-estimate=137.25MB mem-reservation=47.88MB thread-reserva
    tuple-ids=0 row-size=16B cardinality=719.38K
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=110.75MB Threads=7
-Per-Host Resource Estimates: Memory=165MB
+Max Per-Host Resource Reservation: Memory=112.62MB Threads=7
+Per-Host Resource Estimates: Memory=175MB
 F04:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.05MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -254,7 +254,7 @@ PLAN-ROOT SINK
 |  in pipelines: 08(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(i_class)] hosts=2 instances=2
-Per-Instance Resources: mem-estimate=50.00MB mem-reservation=50.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=58.39MB mem-reservation=50.00MB thread-reservation=1
 08:TOP-N [LIMIT=100]
 |  order by: i_category ASC, i_class ASC, i_item_id ASC, i_item_desc ASC, sum(ws_ext_sales_price) * 100.0000 / sum(sum(ws_ext_sales_price)) ASC
 |  mem-estimate=20.91KB mem-reservation=0B thread-reservation=0
@@ -270,7 +270,7 @@ Per-Instance Resources: mem-estimate=50.00MB mem-reservation=50.00MB thread-rese
 |
 06:SORT
 |  order by: i_class ASC NULLS LAST
-|  mem-estimate=12.00MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=20.39MB mem-reservation=12.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=10 row-size=198B cardinality=215.82K
 |  in pipelines: 06(GETNEXT), 12(OPEN)
 |
@@ -336,17 +336,17 @@ Per-Instance Resources: mem-estimate=66.00MB mem-reservation=42.00MB thread-rese
 |  hash-table-id=01
 |  hash predicates: ws_item_sk = i_item_sk
 |  fk/pk conjuncts: ws_item_sk = i_item_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,1 row-size=206B cardinality=215.82K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F06:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  Per-Instance Resources: mem-estimate=6.04MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=7.92MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=01 plan-id=02 cohort-id=01
 |  |  build expressions: i_item_sk
 |  |  runtime filters: RF002[bloom] <- i_item_sk, RF003[min_max] <- i_item_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  09:EXCHANGE [BROADCAST]
 |  |  mem-estimate=1.17MB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q13.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q13.test
index cf3f03b..891583c 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q13.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q13.test
@@ -58,7 +58,7 @@ PLAN-ROOT SINK
 |
 11:AGGREGATE [FINALIZE]
 |  output: avg(CAST(ss_quantity AS BIGINT)), avg(ss_ext_sales_price), avg(ss_ext_wholesale_cost), sum(ss_ext_wholesale_cost)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=7 row-size=40B cardinality=1
 |  in pipelines: 11(GETNEXT), 02(OPEN)
 |
@@ -180,17 +180,17 @@ PLAN-ROOT SINK
    tuple-ids=2 row-size=39B cardinality=181.75K
    in pipelines: 02(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=36.33MB Threads=14
-Per-Host Resource Estimates: Memory=348MB
+Max Per-Host Resource Reservation: Memory=40.08MB Threads=14
+Per-Host Resource Estimates: Memory=339MB
 F07:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=14.00MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: avg(ss_quantity), avg(ss_ext_sales_price), avg(ss_ext_wholesale_cost), sum(ss_ext_wholesale_cost)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 19:AGGREGATE [FINALIZE]
 |  output: avg:merge(ss_quantity), avg:merge(ss_ext_sales_price), avg:merge(ss_ext_wholesale_cost), sum:merge(ss_ext_wholesale_cost)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=7 row-size=40B cardinality=1
 |  in pipelines: 19(GETNEXT), 11(OPEN)
 |
@@ -200,10 +200,10 @@ PLAN-ROOT SINK
 |  in pipelines: 11(GETNEXT)
 |
 F05:PLAN FRAGMENT [HASH(ss_cdemo_sk)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=19.12MB mem-reservation=8.69MB thread-reservation=1 runtime-filters-memory=2.00MB
+Per-Host Resources: mem-estimate=19.61MB mem-reservation=12.44MB thread-reservation=1 runtime-filters-memory=2.00MB
 11:AGGREGATE
 |  output: avg(CAST(ss_quantity AS BIGINT)), avg(ss_ext_sales_price), avg(ss_ext_wholesale_cost), sum(ss_ext_wholesale_cost)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=6 row-size=40B cardinality=1
 |  in pipelines: 11(GETNEXT), 00(OPEN)
 |
@@ -237,7 +237,7 @@ Per-Host Resources: mem-estimate=19.12MB mem-reservation=8.69MB thread-reservati
 |  fk/pk conjuncts: ss_cdemo_sk = cd_demo_sk
 |  other predicates: cd_education_status = 'Advanced Degree' OR cd_marital_status = 'S' AND cd_education_status = 'College' OR hd_dep_count = CAST(1 AS INT), cd_marital_status = 'M' OR cd_marital_status = 'S' AND cd_education_status = 'College' OR hd_dep_count = CAST(1 AS INT), hd_dep_count = CAST(3 AS INT) OR cd_education_status = 'College' OR hd_dep_count = CAST(1 AS INT), cd_education_status = 'Advanced Degree' OR hd_dep_count = CAST(1 AS INT) OR hd_dep_count = CAST(1 AS INT), hd_dep_ [...]
 |  runtime filters: RF002[bloom] <- cd_demo_sk, RF003[min_max] <- cd_demo_sk
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=0,4,5,3,2 row-size=138B cardinality=2.55K
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
@@ -366,17 +366,17 @@ Per-Host Resources: mem-estimate=139.26MB mem-reservation=14.81MB thread-reserva
    tuple-ids=0 row-size=40B cardinality=288.04K
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=53.08MB Threads=16
-Per-Host Resource Estimates: Memory=194MB
+Max Per-Host Resource Reservation: Memory=56.83MB Threads=16
+Per-Host Resource Estimates: Memory=168MB
 F07:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=14.00MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: avg(ss_quantity), avg(ss_ext_sales_price), avg(ss_ext_wholesale_cost), sum(ss_ext_wholesale_cost)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
 |
 19:AGGREGATE [FINALIZE]
 |  output: avg:merge(ss_quantity), avg:merge(ss_ext_sales_price), avg:merge(ss_ext_wholesale_cost), sum:merge(ss_ext_wholesale_cost)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=7 row-size=40B cardinality=1
 |  in pipelines: 19(GETNEXT), 11(OPEN)
 |
@@ -386,10 +386,10 @@ PLAN-ROOT SINK
 |  in pipelines: 11(GETNEXT)
 |
 F05:PLAN FRAGMENT [HASH(ss_cdemo_sk)] hosts=3 instances=6
-Per-Instance Resources: mem-estimate=10.77MB mem-reservation=0B thread-reservation=1
+Per-Instance Resources: mem-estimate=804.39KB mem-reservation=0B thread-reservation=1
 11:AGGREGATE
 |  output: avg(CAST(ss_quantity AS BIGINT)), avg(ss_ext_sales_price), avg(ss_ext_wholesale_cost), sum(ss_ext_wholesale_cost)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=6 row-size=40B cardinality=1
 |  in pipelines: 11(GETNEXT), 00(OPEN)
 |
@@ -431,17 +431,17 @@ Per-Instance Resources: mem-estimate=10.77MB mem-reservation=0B thread-reservati
 |  hash predicates: ss_cdemo_sk = cd_demo_sk
 |  fk/pk conjuncts: ss_cdemo_sk = cd_demo_sk
 |  other predicates: cd_education_status = 'Advanced Degree' OR cd_marital_status = 'S' AND cd_education_status = 'College' OR hd_dep_count = CAST(1 AS INT), cd_marital_status = 'M' OR cd_marital_status = 'S' AND cd_education_status = 'College' OR hd_dep_count = CAST(1 AS INT), hd_dep_count = CAST(3 AS INT) OR cd_education_status = 'College' OR hd_dep_count = CAST(1 AS INT), cd_education_status = 'Advanced Degree' OR hd_dep_count = CAST(1 AS INT) OR hd_dep_count = CAST(1 AS INT), hd_dep_ [...]
-|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,4,5,3,2 row-size=138B cardinality=2.55K
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
 |--F09:PLAN FRAGMENT [HASH(ss_cdemo_sk)] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=10.60MB mem-reservation=3.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=12.48MB mem-reservation=5.75MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=01 plan-id=02 cohort-id=01
 |  |  build expressions: cd_demo_sk
 |  |  runtime filters: RF002[bloom] <- cd_demo_sk, RF003[min_max] <- cd_demo_sk
-|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  16:EXCHANGE [HASH(cd_demo_sk)]
 |  |  mem-estimate=6.73MB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14a.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14a.test
index b869d51..16e822e 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14a.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14a.test
@@ -101,10 +101,10 @@ with  cross_items as
  order by channel,i_brand_id,i_class_id,i_category_id
 LIMIT 100
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=130.75MB Threads=16
-Per-Host Resource Estimates: Memory=1.19GB
+Max Per-Host Resource Reservation: Memory=139.50MB Threads=16
+Per-Host Resource Estimates: Memory=1.17GB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=1.19GB mem-reservation=130.75MB thread-reservation=16 runtime-filters-memory=10.00MB
+|  Per-Host Resources: mem-estimate=1.17GB mem-reservation=139.50MB thread-reservation=16 runtime-filters-memory=10.00MB
 PLAN-ROOT SINK
 |  output exprs: CASE valid_tid(104,105,106,107,108) WHEN 104 THEN channel WHEN 105 THEN channel WHEN 106 THEN channel WHEN 107 THEN channel WHEN 108 THEN NULL END, CASE valid_tid(104,105,106,107,108) WHEN 104 THEN i_brand_id WHEN 105 THEN i_brand_id WHEN 106 THEN i_brand_id WHEN 107 THEN NULL WHEN 108 THEN NULL END, CASE valid_tid(104,105,106,107,108) WHEN 104 THEN i_class_id WHEN 105 THEN i_class_id WHEN 106 THEN NULL WHEN 107 THEN NULL WHEN 108 THEN NULL END, CASE valid_tid(104,105,10 [...]
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -118,7 +118,7 @@ PLAN-ROOT SINK
 128:AGGREGATE [FINALIZE]
 |  output: aggif(valid_tid(104,105,106,107,108) IN (CAST(104 AS INT), CAST(105 AS INT), CAST(106 AS INT), CAST(107 AS INT), CAST(108 AS INT)), CASE valid_tid(104,105,106,107,108) WHEN CAST(104 AS INT) THEN sum(sales) WHEN CAST(105 AS INT) THEN sum(sales) WHEN CAST(106 AS INT) THEN sum(sales) WHEN CAST(107 AS INT) THEN sum(sales) WHEN CAST(108 AS INT) THEN sum(sales) END), aggif(valid_tid(104,105,106,107,108) IN (CAST(104 AS INT), CAST(105 AS INT), CAST(106 AS INT), CAST(107 AS INT), CAST [...]
 |  group by: CASE valid_tid(104,105,106,107,108) WHEN CAST(104 AS INT) THEN channel WHEN CAST(105 AS INT) THEN channel WHEN CAST(106 AS INT) THEN channel WHEN CAST(107 AS INT) THEN channel WHEN CAST(108 AS INT) THEN NULL END, CASE valid_tid(104,105,106,107,108) WHEN CAST(104 AS INT) THEN i_brand_id WHEN CAST(105 AS INT) THEN i_brand_id WHEN CAST(106 AS INT) THEN i_brand_id WHEN CAST(107 AS INT) THEN NULL WHEN CAST(108 AS INT) THEN NULL END, CASE valid_tid(104,105,106,107,108) WHEN CAST(1 [...]
-|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=36.47MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=109 row-size=52B cardinality=562.30K
 |  in pipelines: 128(GETNEXT), 127(OPEN)
 |
@@ -138,7 +138,7 @@ PLAN-ROOT SINK
 |  Class 4
 |    output: sum(sales), sum(number_sales)
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=169.46MB mem-reservation=74.75MB thread-reservation=0
+|  mem-estimate=165.24MB mem-reservation=76.62MB thread-reservation=0
 |  tuple-ids=104N,105N,106N,107N,108N row-size=240B cardinality=562.30K
 |  in pipelines: 127(GETNEXT), 30(OPEN), 72(OPEN), 114(OPEN)
 |
@@ -155,7 +155,7 @@ PLAN-ROOT SINK
 |  |
 |  |--125:AGGREGATE [FINALIZE]
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=99 row-size=16B cardinality=1
 |  |  |  in pipelines: 125(GETNEXT), 116(OPEN), 119(OPEN), 122(OPEN)
 |  |  |
@@ -262,7 +262,7 @@ PLAN-ROOT SINK
 |  114:AGGREGATE [FINALIZE]
 |  |  output: sum(CAST(ws_quantity AS DECIMAL(10,0)) * ws_list_price), count(*)
 |  |  group by: i_brand_id, i_class_id, i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=88 row-size=36B cardinality=42.85K
 |  |  in pipelines: 114(GETNEXT), 85(OPEN)
 |  |
@@ -299,13 +299,13 @@ PLAN-ROOT SINK
 |  |  |
 |  |  108:HASH JOIN [LEFT SEMI JOIN]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=75 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 94(GETNEXT), 107(OPEN)
 |  |  |
 |  |  |--107:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=169 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 107(GETNEXT), 100(OPEN)
 |  |  |  |
@@ -361,13 +361,13 @@ PLAN-ROOT SINK
 |  |  |
 |  |  106:HASH JOIN [LEFT SEMI JOIN]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=75 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 94(GETNEXT), 105(OPEN)
 |  |  |
 |  |  |--105:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=168 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 105(GETNEXT), 95(OPEN)
 |  |  |  |
@@ -423,7 +423,7 @@ PLAN-ROOT SINK
 |  |  |
 |  |  94:AGGREGATE [FINALIZE]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=75 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 94(GETNEXT), 89(OPEN)
 |  |  |
@@ -537,7 +537,7 @@ PLAN-ROOT SINK
 |  |
 |  |--83:AGGREGATE [FINALIZE]
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=65 row-size=16B cardinality=1
 |  |  |  in pipelines: 83(GETNEXT), 74(OPEN), 77(OPEN), 80(OPEN)
 |  |  |
@@ -644,7 +644,7 @@ PLAN-ROOT SINK
 |  72:AGGREGATE [FINALIZE]
 |  |  output: sum(CAST(cs_quantity AS DECIMAL(10,0)) * cs_list_price), count(*)
 |  |  group by: i_brand_id, i_class_id, i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  tuple-ids=54 row-size=36B cardinality=85.31K
 |  |  in pipelines: 72(GETNEXT), 43(OPEN)
 |  |
@@ -681,13 +681,13 @@ PLAN-ROOT SINK
 |  |  |
 |  |  66:HASH JOIN [LEFT SEMI JOIN]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=41 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 52(GETNEXT), 65(OPEN)
 |  |  |
 |  |  |--65:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=147 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 65(GETNEXT), 58(OPEN)
 |  |  |  |
@@ -743,13 +743,13 @@ PLAN-ROOT SINK
 |  |  |
 |  |  64:HASH JOIN [LEFT SEMI JOIN]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=41 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 52(GETNEXT), 63(OPEN)
 |  |  |
 |  |  |--63:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=146 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 63(GETNEXT), 53(OPEN)
 |  |  |  |
@@ -805,7 +805,7 @@ PLAN-ROOT SINK
 |  |  |
 |  |  52:AGGREGATE [FINALIZE]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=41 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 52(GETNEXT), 47(OPEN)
 |  |  |
@@ -919,7 +919,7 @@ PLAN-ROOT SINK
 |
 |--41:AGGREGATE [FINALIZE]
 |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=31 row-size=16B cardinality=1
 |  |  in pipelines: 41(GETNEXT), 32(OPEN), 35(OPEN), 38(OPEN)
 |  |
@@ -1064,13 +1064,13 @@ PLAN-ROOT SINK
 |  24:HASH JOIN [LEFT SEMI JOIN]
 |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
 |  |  runtime filters: RF012[bloom] <- iws.i_brand_id, RF013[bloom] <- iws.i_category_id
-|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 10(GETNEXT), 23(OPEN)
 |  |
 |  |--23:AGGREGATE [FINALIZE]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=125 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 23(GETNEXT), 16(OPEN)
 |  |  |
@@ -1126,13 +1126,13 @@ PLAN-ROOT SINK
 |  |
 |  22:HASH JOIN [LEFT SEMI JOIN]
 |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 10(GETNEXT), 21(OPEN)
 |  |
 |  |--21:AGGREGATE [FINALIZE]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=124 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 21(GETNEXT), 11(OPEN)
 |  |  |
@@ -1188,7 +1188,7 @@ PLAN-ROOT SINK
 |  |
 |  10:AGGREGATE [FINALIZE]
 |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 10(GETNEXT), 05(OPEN)
 |  |
@@ -1295,8 +1295,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=20B cardinality=2.88M
    in pipelines: 01(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=395.06MB Threads=120
-Per-Host Resource Estimates: Memory=3.66GB
+Max Per-Host Resource Reservation: Memory=430.00MB Threads=120
+Per-Host Resource Estimates: Memory=3.56GB
 F80:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -1311,7 +1311,7 @@ PLAN-ROOT SINK
 |  in pipelines: 129(GETNEXT)
 |
 F79:PLAN FRAGMENT [HASH(CASE valid_tid(104,105,106,107,108) WHEN 104 THEN murmur_hash(channel) WHEN 105 THEN murmur_hash(channel) WHEN 106 THEN murmur_hash(channel) WHEN 107 THEN murmur_hash(channel) WHEN 108 THEN murmur_hash(NULL) END,CASE valid_tid(104,105,106,107,108) WHEN 104 THEN murmur_hash(i_brand_id) WHEN 105 THEN murmur_hash(i_brand_id) WHEN 106 THEN murmur_hash(i_brand_id) WHEN 107 THEN murmur_hash(NULL) WHEN 108 THEN murmur_hash(NULL) END,CASE valid_tid(104,105,106,107,108) WH [...]
-Per-Host Resources: mem-estimate=188.57MB mem-reservation=91.75MB thread-reservation=1
+Per-Host Resources: mem-estimate=138.52MB mem-reservation=93.62MB thread-reservation=1
 129:TOP-N [LIMIT=100]
 |  order by: CASE valid_tid(104,105,106,107,108) WHEN 104 THEN channel WHEN 105 THEN channel WHEN 106 THEN channel WHEN 107 THEN channel WHEN 108 THEN NULL END ASC, CASE valid_tid(104,105,106,107,108) WHEN 104 THEN i_brand_id WHEN 105 THEN i_brand_id WHEN 106 THEN i_brand_id WHEN 107 THEN NULL WHEN 108 THEN NULL END ASC, CASE valid_tid(104,105,106,107,108) WHEN 104 THEN i_class_id WHEN 105 THEN i_class_id WHEN 106 THEN NULL WHEN 107 THEN NULL WHEN 108 THEN NULL END ASC, CASE valid_tid(10 [...]
 |  mem-estimate=4.69KB mem-reservation=0B thread-reservation=0
@@ -1341,7 +1341,7 @@ Per-Host Resources: mem-estimate=188.57MB mem-reservation=91.75MB thread-reserva
 |  Class 4
 |    output: sum:merge(sales), sum:merge(number_sales)
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=171.57MB mem-reservation=74.75MB thread-reservation=0
+|  mem-estimate=121.52MB mem-reservation=76.62MB thread-reservation=0
 |  tuple-ids=104N,105N,106N,107N,108N row-size=240B cardinality=562.30K
 |  in pipelines: 215(GETNEXT), 151(OPEN), 179(OPEN), 207(OPEN)
 |
@@ -1351,7 +1351,7 @@ Per-Host Resources: mem-estimate=188.57MB mem-reservation=91.75MB thread-reserva
 |  in pipelines: 151(GETNEXT), 179(GETNEXT), 207(GETNEXT)
 |
 F78:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reservation=1
+Per-Host Resources: mem-estimate=109.84MB mem-reservation=81.75MB thread-reservation=1
 127:AGGREGATE [STREAMING]
 |  Class 0
 |    output: sum(sales), sum(number_sales)
@@ -1368,7 +1368,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  Class 4
 |    output: sum(sales), sum(number_sales)
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=99.73MB mem-reservation=75.00MB thread-reservation=0
+|  mem-estimate=98.00MB mem-reservation=77.00MB thread-reservation=0
 |  tuple-ids=104N,105N,106N,107N,108N row-size=240B cardinality=562.30K
 |  in pipelines: 151(GETNEXT), 179(GETNEXT), 207(GETNEXT)
 |
@@ -1389,10 +1389,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  in pipelines: 212(GETNEXT)
 |  |  |
 |  |  F77:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  |  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  |  212:AGGREGATE [FINALIZE]
 |  |  |  output: avg:merge(quantity * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=99 row-size=16B cardinality=1
 |  |  |  in pipelines: 212(GETNEXT), 125(OPEN)
 |  |  |
@@ -1402,10 +1402,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  in pipelines: 125(GETNEXT)
 |  |  |
 |  |  F76:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=156.00MB mem-reservation=5.94MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=146.02MB mem-reservation=5.94MB thread-reservation=2
 |  |  125:AGGREGATE
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=98 row-size=16B cardinality=1
 |  |  |  in pipelines: 125(GETNEXT), 116(OPEN), 119(OPEN), 122(OPEN)
 |  |  |
@@ -1543,11 +1543,11 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  in pipelines: 85(GETNEXT)
 |  |
 |  F52:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  Per-Host Resources: mem-estimate=145.37MB mem-reservation=13.81MB thread-reservation=2 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=145.37MB mem-reservation=12.81MB thread-reservation=2 runtime-filters-memory=1.00MB
 |  114:AGGREGATE [STREAMING]
 |  |  output: sum(CAST(ws_quantity AS DECIMAL(10,0)) * ws_list_price), count(*)
 |  |  group by: i_brand_id, i_class_id, i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=2.00MB spill-buffer=64.00KB thread-reservation=0
 |  |  tuple-ids=88 row-size=36B cardinality=42.85K
 |  |  in pipelines: 85(GETNEXT)
 |  |
@@ -1577,7 +1577,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  in pipelines: 191(GETNEXT)
 |  |  |
 |  |  F58:PLAN FRAGMENT [HASH(iss.i_brand_id,iss.i_class_id,iss.i_category_id)] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=28.29MB mem-reservation=9.75MB thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=30.17MB mem-reservation=12.56MB thread-reservation=1
 |  |  112:AGGREGATE [STREAMING]
 |  |  |  group by: tpcds_parquet.item.i_item_sk
 |  |  |  mem-estimate=10.00MB mem-reservation=2.00MB spill-buffer=64.00KB thread-reservation=0
@@ -1611,7 +1611,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |
 |  |  108:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=75 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 191(GETNEXT), 200(OPEN)
 |  |  |
@@ -1621,10 +1621,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  |  in pipelines: 200(GETNEXT)
 |  |  |  |
 |  |  |  F66:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  200:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=169 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 200(GETNEXT), 100(OPEN)
 |  |  |  |
@@ -1634,10 +1634,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  |  in pipelines: 100(GETNEXT)
 |  |  |  |
 |  |  |  F63:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  |  107:AGGREGATE [STREAMING]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=169 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 100(GETNEXT)
 |  |  |  |
@@ -1707,7 +1707,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |
 |  |  106:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=75 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 191(GETNEXT), 195(OPEN)
 |  |  |
@@ -1717,10 +1717,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  |  in pipelines: 195(GETNEXT)
 |  |  |  |
 |  |  |  F62:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  195:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=168 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 195(GETNEXT), 95(OPEN)
 |  |  |  |
@@ -1730,10 +1730,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  |  in pipelines: 95(GETNEXT)
 |  |  |  |
 |  |  |  F59:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  |  105:AGGREGATE [STREAMING]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=168 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 95(GETNEXT)
 |  |  |  |
@@ -1803,7 +1803,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |
 |  |  191:AGGREGATE [FINALIZE]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=75 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 191(GETNEXT), 89(OPEN)
 |  |  |
@@ -1813,10 +1813,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  in pipelines: 89(GETNEXT)
 |  |  |
 |  |  F55:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=30.31MB mem-reservation=7.38MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=30.31MB mem-reservation=9.38MB thread-reservation=2
 |  |  94:AGGREGATE [STREAMING]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=75 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 89(GETNEXT)
 |  |  |
@@ -1962,10 +1962,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  in pipelines: 184(GETNEXT)
 |  |  |
 |  |  F51:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  |  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  |  184:AGGREGATE [FINALIZE]
 |  |  |  output: avg:merge(quantity * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=65 row-size=16B cardinality=1
 |  |  |  in pipelines: 184(GETNEXT), 83(OPEN)
 |  |  |
@@ -1975,10 +1975,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  in pipelines: 83(GETNEXT)
 |  |  |
 |  |  F50:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=156.00MB mem-reservation=5.94MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=146.02MB mem-reservation=5.94MB thread-reservation=2
 |  |  83:AGGREGATE
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=64 row-size=16B cardinality=1
 |  |  |  in pipelines: 83(GETNEXT), 74(OPEN), 77(OPEN), 80(OPEN)
 |  |  |
@@ -2150,7 +2150,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  in pipelines: 163(GETNEXT)
 |  |  |
 |  |  F32:PLAN FRAGMENT [HASH(iss.i_brand_id,iss.i_class_id,iss.i_category_id)] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=28.29MB mem-reservation=9.75MB thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=30.17MB mem-reservation=12.56MB thread-reservation=1
 |  |  70:AGGREGATE [STREAMING]
 |  |  |  group by: tpcds_parquet.item.i_item_sk
 |  |  |  mem-estimate=10.00MB mem-reservation=2.00MB spill-buffer=64.00KB thread-reservation=0
@@ -2184,7 +2184,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |
 |  |  66:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=41 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 163(GETNEXT), 172(OPEN)
 |  |  |
@@ -2194,10 +2194,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  |  in pipelines: 172(GETNEXT)
 |  |  |  |
 |  |  |  F40:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  172:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=147 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 172(GETNEXT), 58(OPEN)
 |  |  |  |
@@ -2207,10 +2207,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  |  in pipelines: 58(GETNEXT)
 |  |  |  |
 |  |  |  F37:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  |  65:AGGREGATE [STREAMING]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=147 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 58(GETNEXT)
 |  |  |  |
@@ -2280,7 +2280,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |
 |  |  64:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=41 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 163(GETNEXT), 167(OPEN)
 |  |  |
@@ -2290,10 +2290,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  |  in pipelines: 167(GETNEXT)
 |  |  |  |
 |  |  |  F36:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  167:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=146 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 167(GETNEXT), 53(OPEN)
 |  |  |  |
@@ -2303,10 +2303,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  |  in pipelines: 53(GETNEXT)
 |  |  |  |
 |  |  |  F33:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  |  63:AGGREGATE [STREAMING]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=146 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 53(GETNEXT)
 |  |  |  |
@@ -2376,7 +2376,7 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |
 |  |  163:AGGREGATE [FINALIZE]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=41 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 163(GETNEXT), 47(OPEN)
 |  |  |
@@ -2386,10 +2386,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  |  in pipelines: 47(GETNEXT)
 |  |  |
 |  |  F29:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=30.31MB mem-reservation=7.38MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=30.31MB mem-reservation=9.38MB thread-reservation=2
 |  |  52:AGGREGATE [STREAMING]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=41 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 47(GETNEXT)
 |  |  |
@@ -2535,10 +2535,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  in pipelines: 156(GETNEXT)
 |  |
 |  F25:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  156:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(quantity * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=31 row-size=16B cardinality=1
 |  |  in pipelines: 156(GETNEXT), 41(OPEN)
 |  |
@@ -2548,10 +2548,10 @@ Per-Host Resources: mem-estimate=111.57MB mem-reservation=79.75MB thread-reserva
 |  |  in pipelines: 41(GETNEXT)
 |  |
 |  F24:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=156.00MB mem-reservation=5.94MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=146.02MB mem-reservation=5.94MB thread-reservation=2
 |  41:AGGREGATE
 |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=30 row-size=16B cardinality=1
 |  |  in pipelines: 41(GETNEXT), 32(OPEN), 35(OPEN), 38(OPEN)
 |  |
@@ -2723,7 +2723,7 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  |  in pipelines: 135(GETNEXT)
 |  |
 |  F06:PLAN FRAGMENT [HASH(iss.i_brand_id,iss.i_class_id,iss.i_category_id)] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=33.29MB mem-reservation=14.75MB thread-reservation=1 runtime-filters-memory=5.00MB
+|  Per-Host Resources: mem-estimate=35.17MB mem-reservation=17.56MB thread-reservation=1 runtime-filters-memory=5.00MB
 |  28:AGGREGATE [STREAMING]
 |  |  group by: tpcds_parquet.item.i_item_sk
 |  |  mem-estimate=10.00MB mem-reservation=2.00MB spill-buffer=64.00KB thread-reservation=0
@@ -2758,7 +2758,7 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  24:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
 |  |  runtime filters: RF012[bloom] <- iws.i_brand_id, RF013[bloom] <- iws.i_category_id
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 135(GETNEXT), 144(OPEN)
 |  |
@@ -2768,10 +2768,10 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  |  |  in pipelines: 144(GETNEXT)
 |  |  |
 |  |  F14:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  144:AGGREGATE [FINALIZE]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=125 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 144(GETNEXT), 16(OPEN)
 |  |  |
@@ -2781,10 +2781,10 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  |  |  in pipelines: 16(GETNEXT)
 |  |  |
 |  |  F11:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  23:AGGREGATE [STREAMING]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=125 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 16(GETNEXT)
 |  |  |
@@ -2854,7 +2854,7 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  |
 |  22:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 135(GETNEXT), 139(OPEN)
 |  |
@@ -2864,10 +2864,10 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  |  |  in pipelines: 139(GETNEXT)
 |  |  |
 |  |  F10:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  139:AGGREGATE [FINALIZE]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=124 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 139(GETNEXT), 11(OPEN)
 |  |  |
@@ -2877,10 +2877,10 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  |  |  in pipelines: 11(GETNEXT)
 |  |  |
 |  |  F07:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  21:AGGREGATE [STREAMING]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=124 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 11(GETNEXT)
 |  |  |
@@ -2950,7 +2950,7 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  |
 |  135:AGGREGATE [FINALIZE]
 |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 135(GETNEXT), 05(OPEN)
 |  |
@@ -2960,10 +2960,10 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
 |  |  in pipelines: 05(GETNEXT)
 |  |
 |  F03:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=30.31MB mem-reservation=7.38MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=30.31MB mem-reservation=9.38MB thread-reservation=2
 |  10:AGGREGATE [STREAMING]
 |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 05(GETNEXT)
 |  |
@@ -3098,8 +3098,8 @@ Per-Host Resources: mem-estimate=67.37MB mem-reservation=14.81MB thread-reservat
    tuple-ids=0 row-size=20B cardinality=2.88M
    in pipelines: 01(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=628.75MB Threads=141
-Per-Host Resource Estimates: Memory=2.35GB
+Max Per-Host Resource Reservation: Memory=665.12MB Threads=141
+Per-Host Resource Estimates: Memory=2.26GB
 F80:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.03MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -3114,7 +3114,7 @@ PLAN-ROOT SINK
 |  in pipelines: 129(GETNEXT)
 |
 F79:PLAN FRAGMENT [HASH(CASE valid_tid(104,105,106,107,108) WHEN 104 THEN murmur_hash(channel) WHEN 105 THEN murmur_hash(channel) WHEN 106 THEN murmur_hash(channel) WHEN 107 THEN murmur_hash(channel) WHEN 108 THEN murmur_hash(NULL) END,CASE valid_tid(104,105,106,107,108) WHEN 104 THEN murmur_hash(i_brand_id) WHEN 105 THEN murmur_hash(i_brand_id) WHEN 106 THEN murmur_hash(i_brand_id) WHEN 107 THEN murmur_hash(NULL) WHEN 108 THEN murmur_hash(NULL) END,CASE valid_tid(104,105,106,107,108) WH [...]
-Per-Instance Resources: mem-estimate=112.31MB mem-reservation=83.25MB thread-reservation=1
+Per-Instance Resources: mem-estimate=109.52MB mem-reservation=85.12MB thread-reservation=1
 129:TOP-N [LIMIT=100]
 |  order by: CASE valid_tid(104,105,106,107,108) WHEN 104 THEN channel WHEN 105 THEN channel WHEN 106 THEN channel WHEN 107 THEN channel WHEN 108 THEN NULL END ASC, CASE valid_tid(104,105,106,107,108) WHEN 104 THEN i_brand_id WHEN 105 THEN i_brand_id WHEN 106 THEN i_brand_id WHEN 107 THEN NULL WHEN 108 THEN NULL END ASC, CASE valid_tid(104,105,106,107,108) WHEN 104 THEN i_class_id WHEN 105 THEN i_class_id WHEN 106 THEN NULL WHEN 107 THEN NULL WHEN 108 THEN NULL END ASC, CASE valid_tid(10 [...]
 |  mem-estimate=4.69KB mem-reservation=0B thread-reservation=0
@@ -3144,7 +3144,7 @@ Per-Instance Resources: mem-estimate=112.31MB mem-reservation=83.25MB thread-res
 |  Class 4
 |    output: sum:merge(sales), sum:merge(number_sales)
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=100.78MB mem-reservation=74.75MB thread-reservation=0
+|  mem-estimate=98.00MB mem-reservation=76.62MB thread-reservation=0
 |  tuple-ids=104N,105N,106N,107N,108N row-size=240B cardinality=562.30K
 |  in pipelines: 215(GETNEXT), 151(OPEN), 179(OPEN), 207(OPEN)
 |
@@ -3154,7 +3154,7 @@ Per-Instance Resources: mem-estimate=112.31MB mem-reservation=83.25MB thread-res
 |  in pipelines: 151(GETNEXT), 179(GETNEXT), 207(GETNEXT)
 |
 F78:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-reservation=1
+Per-Instance Resources: mem-estimate=75.94MB mem-reservation=45.88MB thread-reservation=1
 127:AGGREGATE [STREAMING]
 |  Class 0
 |    output: sum(sales), sum(number_sales)
@@ -3171,7 +3171,7 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  Class 4
 |    output: sum(sales), sum(number_sales)
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=64.87MB mem-reservation=41.00MB thread-reservation=0
+|  mem-estimate=64.00MB mem-reservation=43.00MB thread-reservation=0
 |  tuple-ids=104N,105N,106N,107N,108N row-size=240B cardinality=562.30K
 |  in pipelines: 151(GETNEXT), 179(GETNEXT), 207(GETNEXT)
 |
@@ -3199,10 +3199,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  in pipelines: 212(GETNEXT)
 |  |  |
 |  |  F77:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  |  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  |  212:AGGREGATE [FINALIZE]
 |  |  |  output: avg:merge(quantity * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=99 row-size=16B cardinality=1
 |  |  |  in pipelines: 212(GETNEXT), 125(OPEN)
 |  |  |
@@ -3212,10 +3212,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  in pipelines: 125(GETNEXT)
 |  |  |
 |  |  F76:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=4.00MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=48.02MB mem-reservation=4.00MB thread-reservation=1
 |  |  125:AGGREGATE
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=98 row-size=16B cardinality=1
 |  |  |  in pipelines: 125(GETNEXT), 116(OPEN), 119(OPEN), 122(OPEN)
 |  |  |
@@ -3378,11 +3378,11 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |
 |  F52:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
 |  Per-Host Shared Resources: mem-estimate=1.00MB mem-reservation=1.00MB thread-reservation=0 runtime-filters-memory=1.00MB
-|  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=7.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=6.00MB thread-reservation=1
 |  114:AGGREGATE [STREAMING]
 |  |  output: sum(CAST(ws_quantity AS DECIMAL(10,0)) * ws_list_price), count(*)
 |  |  group by: i_brand_id, i_class_id, i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=2.00MB spill-buffer=64.00KB thread-reservation=0
 |  |  tuple-ids=88 row-size=36B cardinality=42.85K
 |  |  in pipelines: 85(GETNEXT)
 |  |
@@ -3480,10 +3480,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  |  in pipelines: 200(GETNEXT)
 |  |  |  |
 |  |  |  F66:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  200:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=169 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 200(GETNEXT), 100(OPEN)
 |  |  |  |
@@ -3493,10 +3493,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  |  in pipelines: 100(GETNEXT)
 |  |  |  |
 |  |  |  F63:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  |  107:AGGREGATE [STREAMING]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=169 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 100(GETNEXT)
 |  |  |  |
@@ -3600,10 +3600,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  |  in pipelines: 195(GETNEXT)
 |  |  |  |
 |  |  |  F62:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  195:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=168 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 195(GETNEXT), 95(OPEN)
 |  |  |  |
@@ -3613,10 +3613,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  |  in pipelines: 95(GETNEXT)
 |  |  |  |
 |  |  |  F59:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  |  105:AGGREGATE [STREAMING]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=168 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 95(GETNEXT)
 |  |  |  |
@@ -3712,10 +3712,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  in pipelines: 89(GETNEXT)
 |  |  |
 |  |  F55:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.50MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=5.50MB thread-reservation=1
 |  |  94:AGGREGATE [STREAMING]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=75 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 89(GETNEXT)
 |  |  |
@@ -3900,10 +3900,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  in pipelines: 184(GETNEXT)
 |  |  |
 |  |  F51:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  |  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  |  184:AGGREGATE [FINALIZE]
 |  |  |  output: avg:merge(quantity * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=65 row-size=16B cardinality=1
 |  |  |  in pipelines: 184(GETNEXT), 83(OPEN)
 |  |  |
@@ -3913,10 +3913,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  in pipelines: 83(GETNEXT)
 |  |  |
 |  |  F50:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=4.00MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=48.02MB mem-reservation=4.00MB thread-reservation=1
 |  |  83:AGGREGATE
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=64 row-size=16B cardinality=1
 |  |  |  in pipelines: 83(GETNEXT), 74(OPEN), 77(OPEN), 80(OPEN)
 |  |  |
@@ -4181,10 +4181,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  |  in pipelines: 172(GETNEXT)
 |  |  |  |
 |  |  |  F40:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  172:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=147 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 172(GETNEXT), 58(OPEN)
 |  |  |  |
@@ -4194,10 +4194,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  |  in pipelines: 58(GETNEXT)
 |  |  |  |
 |  |  |  F37:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  |  65:AGGREGATE [STREAMING]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=147 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 58(GETNEXT)
 |  |  |  |
@@ -4301,10 +4301,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  |  in pipelines: 167(GETNEXT)
 |  |  |  |
 |  |  |  F36:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  167:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=146 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 167(GETNEXT), 53(OPEN)
 |  |  |  |
@@ -4314,10 +4314,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  |  in pipelines: 53(GETNEXT)
 |  |  |  |
 |  |  |  F33:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  |  63:AGGREGATE [STREAMING]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=146 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 53(GETNEXT)
 |  |  |  |
@@ -4413,10 +4413,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  |  in pipelines: 47(GETNEXT)
 |  |  |
 |  |  F29:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.50MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=5.50MB thread-reservation=1
 |  |  52:AGGREGATE [STREAMING]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=41 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 47(GETNEXT)
 |  |  |
@@ -4601,10 +4601,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  in pipelines: 156(GETNEXT)
 |  |
 |  F25:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  156:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(quantity * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=31 row-size=16B cardinality=1
 |  |  in pipelines: 156(GETNEXT), 41(OPEN)
 |  |
@@ -4614,10 +4614,10 @@ Per-Instance Resources: mem-estimate=76.80MB mem-reservation=43.88MB thread-rese
 |  |  in pipelines: 41(GETNEXT)
 |  |
 |  F24:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=48.02MB mem-reservation=4.00MB thread-reservation=1
 |  41:AGGREGATE
 |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=30 row-size=16B cardinality=1
 |  |  in pipelines: 41(GETNEXT), 32(OPEN), 35(OPEN), 38(OPEN)
 |  |
@@ -4883,10 +4883,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=4.00MB thread-reser
 |  |  |  in pipelines: 144(GETNEXT)
 |  |  |
 |  |  F14:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  144:AGGREGATE [FINALIZE]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=125 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 144(GETNEXT), 16(OPEN)
 |  |  |
@@ -4896,10 +4896,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=4.00MB thread-reser
 |  |  |  in pipelines: 16(GETNEXT)
 |  |  |
 |  |  F11:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  23:AGGREGATE [STREAMING]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=125 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 16(GETNEXT)
 |  |  |
@@ -5003,10 +5003,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=4.00MB thread-reser
 |  |  |  in pipelines: 139(GETNEXT)
 |  |  |
 |  |  F10:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  139:AGGREGATE [FINALIZE]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=124 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 139(GETNEXT), 11(OPEN)
 |  |  |
@@ -5016,10 +5016,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=4.00MB thread-reser
 |  |  |  in pipelines: 11(GETNEXT)
 |  |  |
 |  |  F07:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  21:AGGREGATE [STREAMING]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=124 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 11(GETNEXT)
 |  |  |
@@ -5115,10 +5115,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=4.00MB thread-reser
 |  |  in pipelines: 05(GETNEXT)
 |  |
 |  F03:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.50MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=5.50MB thread-reservation=1
 |  10:AGGREGATE [STREAMING]
 |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 05(GETNEXT)
 |  |
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14b.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14b.test
index af05b6e..12e663c 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14b.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14b.test
@@ -129,10 +129,10 @@ ORDER BY this_year.channel,
          this_year.i_category_id
 LIMIT 100
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=99.88MB Threads=33
-Per-Host Resource Estimates: Memory=1.85GB
+Max Per-Host Resource Reservation: Memory=119.25MB Threads=33
+Per-Host Resource Estimates: Memory=1.83GB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=1.85GB mem-reservation=99.88MB thread-reservation=33 runtime-filters-memory=10.00MB
+|  Per-Host Resources: mem-estimate=1.83GB mem-reservation=119.25MB thread-reservation=33 runtime-filters-memory=10.00MB
 PLAN-ROOT SINK
 |  output exprs: channel, i_brand_id, i_class_id, i_category_id, sales, number_sales, channel, i_brand_id, i_class_id, i_category_id, sales, number_sales
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -159,7 +159,7 @@ PLAN-ROOT SINK
 |  |
 |  |--88:AGGREGATE [FINALIZE]
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=70 row-size=16B cardinality=1
 |  |  |  in pipelines: 88(GETNEXT), 79(OPEN), 82(OPEN), 85(OPEN)
 |  |  |
@@ -330,13 +330,13 @@ PLAN-ROOT SINK
 |  |  |
 |  |  68:HASH JOIN [LEFT SEMI JOIN]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=44 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 54(GETNEXT), 67(OPEN)
 |  |  |
 |  |  |--67:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=112 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 67(GETNEXT), 60(OPEN)
 |  |  |  |
@@ -392,13 +392,13 @@ PLAN-ROOT SINK
 |  |  |
 |  |  66:HASH JOIN [LEFT SEMI JOIN]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  |  tuple-ids=44 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 54(GETNEXT), 65(OPEN)
 |  |  |
 |  |  |--65:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=111 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 65(GETNEXT), 55(OPEN)
 |  |  |  |
@@ -454,7 +454,7 @@ PLAN-ROOT SINK
 |  |  |
 |  |  54:AGGREGATE [FINALIZE]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=44 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 54(GETNEXT), 49(OPEN)
 |  |  |
@@ -512,7 +512,7 @@ PLAN-ROOT SINK
 |  73:HASH JOIN [INNER JOIN]
 |  |  hash predicates: ss_sold_date_sk = d_date_sk
 |  |  fk/pk conjuncts: ss_sold_date_sk = d_date_sk
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=37,38,39 row-size=48B cardinality=2.88M
 |  |  in pipelines: 45(GETNEXT), 47(OPEN)
 |  |
@@ -566,7 +566,7 @@ PLAN-ROOT SINK
 |
 |--43:AGGREGATE [FINALIZE]
 |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=33 row-size=16B cardinality=1
 |  |  in pipelines: 43(GETNEXT), 34(OPEN), 37(OPEN), 40(OPEN)
 |  |
@@ -737,13 +737,13 @@ PLAN-ROOT SINK
 |  |
 |  23:HASH JOIN [LEFT SEMI JOIN]
 |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
-|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 09(GETNEXT), 22(OPEN)
 |  |
 |  |--22:AGGREGATE [FINALIZE]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=89 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 22(GETNEXT), 15(OPEN)
 |  |  |
@@ -799,13 +799,13 @@ PLAN-ROOT SINK
 |  |
 |  21:HASH JOIN [LEFT SEMI JOIN]
 |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 09(GETNEXT), 20(OPEN)
 |  |
 |  |--20:AGGREGATE [FINALIZE]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=88 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 20(GETNEXT), 10(OPEN)
 |  |  |
@@ -861,7 +861,7 @@ PLAN-ROOT SINK
 |  |
 |  09:AGGREGATE [FINALIZE]
 |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 09(GETNEXT), 04(OPEN)
 |  |
@@ -920,7 +920,7 @@ PLAN-ROOT SINK
 |  hash predicates: ss_sold_date_sk = d_date_sk
 |  fk/pk conjuncts: ss_sold_date_sk = d_date_sk
 |  runtime filters: RF010[bloom] <- d_date_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,1,2 row-size=48B cardinality=2.88M
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
@@ -966,8 +966,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=20B cardinality=2.88M
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=161.06MB Threads=86
-Per-Host Resource Estimates: Memory=2.23GB
+Max Per-Host Resource Reservation: Memory=188.06MB Threads=86
+Per-Host Resource Estimates: Memory=2.20GB
 F56:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -1009,10 +1009,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |  in pipelines: 150(GETNEXT)
 |  |  |
 |  |  F55:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  |  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  |  150:AGGREGATE [FINALIZE]
 |  |  |  output: avg:merge(quantity * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=70 row-size=16B cardinality=1
 |  |  |  in pipelines: 150(GETNEXT), 88(OPEN)
 |  |  |
@@ -1022,10 +1022,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |  in pipelines: 88(GETNEXT)
 |  |  |
 |  |  F54:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=156.00MB mem-reservation=5.94MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=146.02MB mem-reservation=5.94MB thread-reservation=2
 |  |  88:AGGREGATE
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=69 row-size=16B cardinality=1
 |  |  |  in pipelines: 88(GETNEXT), 79(OPEN), 82(OPEN), 85(OPEN)
 |  |  |
@@ -1163,7 +1163,7 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  in pipelines: 45(GETNEXT)
 |  |
 |  F28:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=67.87MB mem-reservation=11.75MB thread-reservation=2 runtime-filters-memory=1.00MB
+|  Per-Host Resources: mem-estimate=70.69MB mem-reservation=14.56MB thread-reservation=2 runtime-filters-memory=1.00MB
 |  77:AGGREGATE [STREAMING]
 |  |  output: sum(CAST(ss_quantity AS DECIMAL(10,0)) * ss_list_price), count(*)
 |  |  group by: i_brand_id, i_class_id, i_category_id
@@ -1239,7 +1239,7 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |  in pipelines: 127(GETNEXT)
 |  |  |
 |  |  F34:PLAN FRAGMENT [HASH(iss.i_brand_id,iss.i_class_id,iss.i_category_id)] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=28.29MB mem-reservation=9.75MB thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=30.17MB mem-reservation=12.56MB thread-reservation=1
 |  |  74:AGGREGATE [STREAMING]
 |  |  |  group by: tpcds_parquet.item.i_item_sk
 |  |  |  mem-estimate=10.00MB mem-reservation=2.00MB spill-buffer=64.00KB thread-reservation=0
@@ -1273,7 +1273,7 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |
 |  |  68:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=44 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 127(GETNEXT), 136(OPEN)
 |  |  |
@@ -1283,10 +1283,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |  |  in pipelines: 136(GETNEXT)
 |  |  |  |
 |  |  |  F42:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  136:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=112 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 136(GETNEXT), 60(OPEN)
 |  |  |  |
@@ -1296,10 +1296,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |  |  in pipelines: 60(GETNEXT)
 |  |  |  |
 |  |  |  F39:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  |  67:AGGREGATE [STREAMING]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=112 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 60(GETNEXT)
 |  |  |  |
@@ -1369,7 +1369,7 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |
 |  |  66:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=44 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 127(GETNEXT), 131(OPEN)
 |  |  |
@@ -1379,10 +1379,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |  |  in pipelines: 131(GETNEXT)
 |  |  |  |
 |  |  |  F38:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  131:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=111 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 131(GETNEXT), 55(OPEN)
 |  |  |  |
@@ -1392,10 +1392,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |  |  in pipelines: 55(GETNEXT)
 |  |  |  |
 |  |  |  F35:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  |  65:AGGREGATE [STREAMING]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=111 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 55(GETNEXT)
 |  |  |  |
@@ -1465,7 +1465,7 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |
 |  |  127:AGGREGATE [FINALIZE]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=44 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 127(GETNEXT), 49(OPEN)
 |  |  |
@@ -1475,10 +1475,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  |  in pipelines: 49(GETNEXT)
 |  |  |
 |  |  F31:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=30.31MB mem-reservation=7.38MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=30.31MB mem-reservation=9.38MB thread-reservation=2
 |  |  54:AGGREGATE [STREAMING]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=44 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 49(GETNEXT)
 |  |  |
@@ -1550,7 +1550,7 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  73:HASH JOIN [INNER JOIN, BROADCAST]
 |  |  hash predicates: ss_sold_date_sk = d_date_sk
 |  |  fk/pk conjuncts: ss_sold_date_sk = d_date_sk
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=37,38,39 row-size=48B cardinality=2.88M
 |  |  in pipelines: 45(GETNEXT), 47(OPEN)
 |  |
@@ -1622,10 +1622,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  in pipelines: 120(GETNEXT)
 |  |
 |  F27:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Host Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  120:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(quantity * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=33 row-size=16B cardinality=1
 |  |  in pipelines: 120(GETNEXT), 43(OPEN)
 |  |
@@ -1635,10 +1635,10 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  |  in pipelines: 43(GETNEXT)
 |  |
 |  F26:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=156.00MB mem-reservation=5.94MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=146.02MB mem-reservation=5.94MB thread-reservation=2
 |  43:AGGREGATE
 |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=32 row-size=16B cardinality=1
 |  |  in pipelines: 43(GETNEXT), 34(OPEN), 37(OPEN), 40(OPEN)
 |  |
@@ -1776,7 +1776,7 @@ Per-Host Resources: mem-estimate=25.00MB mem-reservation=8.81MB thread-reservati
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservation=2 runtime-filters-memory=4.00MB
+Per-Host Resources: mem-estimate=73.69MB mem-reservation=17.56MB thread-reservation=2 runtime-filters-memory=4.00MB
 32:AGGREGATE [STREAMING]
 |  output: sum(CAST(ss_quantity AS DECIMAL(10,0)) * ss_list_price), count(*)
 |  group by: i_brand_id, i_class_id, i_category_id
@@ -1852,7 +1852,7 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |  in pipelines: 97(GETNEXT)
 |  |
 |  F06:PLAN FRAGMENT [HASH(iss.i_brand_id,iss.i_class_id,iss.i_category_id)] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=30.29MB mem-reservation=11.75MB thread-reservation=1 runtime-filters-memory=2.00MB
+|  Per-Host Resources: mem-estimate=32.17MB mem-reservation=14.56MB thread-reservation=1 runtime-filters-memory=2.00MB
 |  29:AGGREGATE [STREAMING]
 |  |  group by: tpcds_parquet.item.i_item_sk
 |  |  mem-estimate=10.00MB mem-reservation=2.00MB spill-buffer=64.00KB thread-reservation=0
@@ -1886,7 +1886,7 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |
 |  23:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM iws.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM iws.i_category_id, iss.i_class_id IS NOT DISTINCT FROM iws.i_class_id
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 97(GETNEXT), 106(OPEN)
 |  |
@@ -1896,10 +1896,10 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |  |  in pipelines: 106(GETNEXT)
 |  |  |
 |  |  F14:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  106:AGGREGATE [FINALIZE]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=89 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 106(GETNEXT), 15(OPEN)
 |  |  |
@@ -1909,10 +1909,10 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |  |  in pipelines: 15(GETNEXT)
 |  |  |
 |  |  F11:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=78.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  22:AGGREGATE [STREAMING]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=89 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 15(GETNEXT)
 |  |  |
@@ -1982,7 +1982,7 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |
 |  21:HASH JOIN [LEFT SEMI JOIN, PARTITIONED]
 |  |  hash predicates: iss.i_brand_id IS NOT DISTINCT FROM ics.i_brand_id, iss.i_category_id IS NOT DISTINCT FROM ics.i_category_id, iss.i_class_id IS NOT DISTINCT FROM ics.i_class_id
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 97(GETNEXT), 101(OPEN)
 |  |
@@ -1992,10 +1992,10 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |  |  in pipelines: 101(GETNEXT)
 |  |  |
 |  |  F10:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Host Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  101:AGGREGATE [FINALIZE]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=88 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 101(GETNEXT), 10(OPEN)
 |  |  |
@@ -2005,10 +2005,10 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |  |  in pipelines: 10(GETNEXT)
 |  |  |
 |  |  F07:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=10.88MB thread-reservation=2
+|  |  Per-Host Resources: mem-estimate=110.31MB mem-reservation=12.88MB thread-reservation=2
 |  |  20:AGGREGATE [STREAMING]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=88 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 10(GETNEXT)
 |  |  |
@@ -2078,7 +2078,7 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |
 |  97:AGGREGATE [FINALIZE]
 |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 97(GETNEXT), 04(OPEN)
 |  |
@@ -2088,10 +2088,10 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  |  in pipelines: 04(GETNEXT)
 |  |
 |  F03:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=30.31MB mem-reservation=7.38MB thread-reservation=2
+|  Per-Host Resources: mem-estimate=30.31MB mem-reservation=9.38MB thread-reservation=2
 |  09:AGGREGATE [STREAMING]
 |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 04(GETNEXT)
 |  |
@@ -2164,7 +2164,7 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
 |  hash predicates: ss_sold_date_sk = d_date_sk
 |  fk/pk conjuncts: ss_sold_date_sk = d_date_sk
 |  runtime filters: RF010[bloom] <- d_date_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,1,2 row-size=48B cardinality=2.88M
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
@@ -2224,8 +2224,8 @@ Per-Host Resources: mem-estimate=70.87MB mem-reservation=14.75MB thread-reservat
    tuple-ids=0 row-size=20B cardinality=2.88M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=277.38MB Threads=103
-Per-Host Resource Estimates: Memory=1.42GB
+Max Per-Host Resource Reservation: Memory=308.38MB Threads=103
+Per-Host Resource Estimates: Memory=1.37GB
 F56:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -2282,10 +2282,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  |  in pipelines: 150(GETNEXT)
 |  |  |
 |  |  F55:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  |  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  |  150:AGGREGATE [FINALIZE]
 |  |  |  output: avg:merge(quantity * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=70 row-size=16B cardinality=1
 |  |  |  in pipelines: 150(GETNEXT), 88(OPEN)
 |  |  |
@@ -2295,10 +2295,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  |  in pipelines: 88(GETNEXT)
 |  |  |
 |  |  F54:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=4.00MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=48.02MB mem-reservation=4.00MB thread-reservation=1
 |  |  88:AGGREGATE
 |  |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  |  tuple-ids=69 row-size=16B cardinality=1
 |  |  |  in pipelines: 88(GETNEXT), 79(OPEN), 82(OPEN), 85(OPEN)
 |  |  |
@@ -2612,10 +2612,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  |  |  in pipelines: 136(GETNEXT)
 |  |  |  |
 |  |  |  F42:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  136:AGGREGATE [FINALIZE]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=112 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 136(GETNEXT), 60(OPEN)
 |  |  |  |
@@ -2625,10 +2625,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  |  |  in pipelines: 60(GETNEXT)
 |  |  |  |
 |  |  |  F39:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  |  67:AGGREGATE [STREAMING]
 |  |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=112 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 60(GETNEXT)
 |  |  |  |
@@ -2732,10 +2732,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  |  |  in pipelines: 131(GETNEXT)
 |  |  |  |
 |  |  |  F38:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  |  131:AGGREGATE [FINALIZE]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  |  tuple-ids=111 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 131(GETNEXT), 55(OPEN)
 |  |  |  |
@@ -2745,10 +2745,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  |  |  in pipelines: 55(GETNEXT)
 |  |  |  |
 |  |  |  F35:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  |  65:AGGREGATE [STREAMING]
 |  |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  |  tuple-ids=111 row-size=12B cardinality=148.80K
 |  |  |  |  in pipelines: 55(GETNEXT)
 |  |  |  |
@@ -2844,10 +2844,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  |  in pipelines: 49(GETNEXT)
 |  |  |
 |  |  F31:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  |  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.50MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=5.50MB thread-reservation=1
 |  |  54:AGGREGATE [STREAMING]
 |  |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=44 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 49(GETNEXT)
 |  |  |
@@ -2936,16 +2936,16 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  hash-table-id=16
 |  |  hash predicates: ss_sold_date_sk = d_date_sk
 |  |  fk/pk conjuncts: ss_sold_date_sk = d_date_sk
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=37,38,39 row-size=48B cardinality=2.88M
 |  |  in pipelines: 45(GETNEXT), 47(OPEN)
 |  |
 |  |--F73:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  |  Per-Instance Resources: mem-estimate=4.44MB mem-reservation=3.88MB thread-reservation=1
+|  |  |  Per-Instance Resources: mem-estimate=10.07MB mem-reservation=9.50MB thread-reservation=1
 |  |  JOIN BUILD
 |  |  |  join-table-id=16 plan-id=17 cohort-id=02
 |  |  |  build expressions: d_date_sk
-|  |  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |  |
 |  |  123:EXCHANGE [BROADCAST]
 |  |  |  mem-estimate=582.70KB mem-reservation=0B thread-reservation=0
@@ -3031,10 +3031,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  in pipelines: 120(GETNEXT)
 |  |
 |  F27:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=0B thread-reservation=1
+|  Per-Instance Resources: mem-estimate=32.00KB mem-reservation=0B thread-reservation=1
 |  120:AGGREGATE [FINALIZE]
 |  |  output: avg:merge(quantity * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=33 row-size=16B cardinality=1
 |  |  in pipelines: 120(GETNEXT), 43(OPEN)
 |  |
@@ -3044,10 +3044,10 @@ Per-Instance Resources: mem-estimate=10.07MB mem-reservation=1.94MB thread-reser
 |  |  in pipelines: 43(GETNEXT)
 |  |
 |  F26:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=48.02MB mem-reservation=4.00MB thread-reservation=1
 |  43:AGGREGATE
 |  |  output: avg(CAST(quantity AS DECIMAL(10,0)) * list_price)
-|  |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  |  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  |  tuple-ids=32 row-size=16B cardinality=1
 |  |  in pipelines: 43(GETNEXT), 34(OPEN), 37(OPEN), 40(OPEN)
 |  |
@@ -3362,10 +3362,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  |  |  in pipelines: 106(GETNEXT)
 |  |  |
 |  |  F14:PLAN FRAGMENT [HASH(iws.i_brand_id,iws.i_class_id,iws.i_category_id)] hosts=2 instances=2
-|  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=10.88MB mem-reservation=2.88MB thread-reservation=1
 |  |  106:AGGREGATE [FINALIZE]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=89 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 106(GETNEXT), 15(OPEN)
 |  |  |
@@ -3375,10 +3375,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  |  |  in pipelines: 15(GETNEXT)
 |  |  |
 |  |  F11:PLAN FRAGMENT [RANDOM] hosts=2 instances=2
-|  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=42.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  22:AGGREGATE [STREAMING]
 |  |  |  group by: iws.i_brand_id, iws.i_class_id, iws.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=89 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 15(GETNEXT)
 |  |  |
@@ -3482,10 +3482,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  |  |  in pipelines: 101(GETNEXT)
 |  |  |
 |  |  F10:PLAN FRAGMENT [HASH(ics.i_brand_id,ics.i_class_id,ics.i_category_id)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=10.61MB mem-reservation=2.88MB thread-reservation=1
 |  |  101:AGGREGATE [FINALIZE]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |  |  tuple-ids=88 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 101(GETNEXT), 10(OPEN)
 |  |  |
@@ -3495,10 +3495,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  |  |  in pipelines: 10(GETNEXT)
 |  |  |
 |  |  F07:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=7.00MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=58.00MB mem-reservation=9.00MB thread-reservation=1
 |  |  20:AGGREGATE [STREAMING]
 |  |  |  group by: ics.i_brand_id, ics.i_class_id, ics.i_category_id
-|  |  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=88 row-size=12B cardinality=148.80K
 |  |  |  in pipelines: 10(GETNEXT)
 |  |  |
@@ -3594,10 +3594,10 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  |  in pipelines: 04(GETNEXT)
 |  |
 |  F03:PLAN FRAGMENT [RANDOM] hosts=3 instances=6
-|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.50MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=26.00MB mem-reservation=5.50MB thread-reservation=1
 |  09:AGGREGATE [STREAMING]
 |  |  group by: iss.i_brand_id, iss.i_class_id, iss.i_category_id
-|  |  mem-estimate=10.00MB mem-reservation=3.00MB spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=10.00MB mem-reservation=5.00MB spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=7 row-size=12B cardinality=148.80K
 |  |  in pipelines: 04(GETNEXT)
 |  |
@@ -3687,17 +3687,17 @@ Per-Instance Resources: mem-estimate=26.00MB mem-reservation=3.00MB thread-reser
 |  hash-table-id=33
 |  hash predicates: ss_sold_date_sk = d_date_sk
 |  fk/pk conjuncts: ss_sold_date_sk = d_date_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,1,2 row-size=48B cardinality=2.88M
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
 |--F90:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.44MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=11.07MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=33 plan-id=34 cohort-id=01
 |  |  build expressions: d_date_sk
 |  |  runtime filters: RF010[bloom] <- d_date_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  93:EXCHANGE [BROADCAST]
 |  |  mem-estimate=582.70KB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q15.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q15.test
index f8c3ecd..6ceb4d3 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q15.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q15.test
@@ -27,10 +27,10 @@ GROUP BY ca_zip
 ORDER BY ca_zip
 LIMIT 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=15.75MB Threads=5
-Per-Host Resource Estimates: Memory=282MB
+Max Per-Host Resource Reservation: Memory=24.19MB Threads=5
+Per-Host Resource Estimates: Memory=290MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=281.75MB mem-reservation=15.75MB thread-reservation=5 runtime-filters-memory=3.00MB
+|  Per-Host Resources: mem-estimate=290.19MB mem-reservation=24.19MB thread-reservation=5 runtime-filters-memory=3.00MB
 PLAN-ROOT SINK
 |  output exprs: ca_zip, sum(cs_sales_price)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -53,7 +53,7 @@ PLAN-ROOT SINK
 |  fk/pk conjuncts: c_current_addr_sk = ca_address_sk
 |  other predicates: (substring(ca_zip, CAST(1 AS BIGINT), CAST(5 AS BIGINT)) IN ('85669', '86197', '88274', '83405', '86475', '85392', '85460', '80348', '81792') OR ca_state IN ('CA', 'WA', 'GA') OR cs_sales_price > CAST(500 AS DECIMAL(5,0)))
 |  runtime filters: RF000[bloom] <- ca_address_sk, RF001[min_max] <- ca_address_sk
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,3,1,2 row-size=67B cardinality=146.92K
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
@@ -71,7 +71,7 @@ PLAN-ROOT SINK
 |  hash predicates: cs_bill_customer_sk = c_customer_sk
 |  fk/pk conjuncts: cs_bill_customer_sk = c_customer_sk
 |  runtime filters: RF002[bloom] <- c_customer_sk, RF003[min_max] <- c_customer_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=0,3,1 row-size=32B cardinality=146.92K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -118,8 +118,8 @@ PLAN-ROOT SINK
    tuple-ids=0 row-size=12B cardinality=1.44M
    in pipelines: 00(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=24.75MB Threads=12
-Per-Host Resource Estimates: Memory=312MB
+Max Per-Host Resource Reservation: Memory=26.62MB Threads=12
+Per-Host Resource Estimates: Memory=314MB
 F07:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -154,7 +154,7 @@ Per-Host Resources: mem-estimate=10.15MB mem-reservation=1.94MB thread-reservati
 |  in pipelines: 00(GETNEXT)
 |
 F05:PLAN FRAGMENT [HASH(c_current_addr_sk)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=16.27MB mem-reservation=4.94MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=17.21MB mem-reservation=5.88MB thread-reservation=1 runtime-filters-memory=1.00MB
 07:AGGREGATE [STREAMING]
 |  output: sum(cs_sales_price)
 |  group by: ca_zip
@@ -167,7 +167,7 @@ Per-Host Resources: mem-estimate=16.27MB mem-reservation=4.94MB thread-reservati
 |  fk/pk conjuncts: c_current_addr_sk = ca_address_sk
 |  other predicates: (substring(ca_zip, CAST(1 AS BIGINT), CAST(5 AS BIGINT)) IN ('85669', '86197', '88274', '83405', '86475', '85392', '85460', '80348', '81792') OR ca_state IN ('CA', 'WA', 'GA') OR cs_sales_price > CAST(500 AS DECIMAL(5,0)))
 |  runtime filters: RF000[bloom] <- ca_address_sk, RF001[min_max] <- ca_address_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,3,1,2 row-size=67B cardinality=146.92K
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
@@ -194,12 +194,12 @@ Per-Host Resources: mem-estimate=16.27MB mem-reservation=4.94MB thread-reservati
 |  in pipelines: 00(GETNEXT)
 |
 F03:PLAN FRAGMENT [HASH(cs_bill_customer_sk)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=4.93MB mem-reservation=2.94MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=5.86MB mem-reservation=3.88MB thread-reservation=1 runtime-filters-memory=1.00MB
 05:HASH JOIN [INNER JOIN, PARTITIONED]
 |  hash predicates: cs_bill_customer_sk = c_customer_sk
 |  fk/pk conjuncts: cs_bill_customer_sk = c_customer_sk
 |  runtime filters: RF002[bloom] <- c_customer_sk, RF003[min_max] <- c_customer_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,3,1 row-size=32B cardinality=146.92K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -267,8 +267,8 @@ Per-Host Resources: mem-estimate=147.95MB mem-reservation=7.94MB thread-reservat
    tuple-ids=0 row-size=12B cardinality=1.44M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=27.69MB Threads=11
-Per-Host Resource Estimates: Memory=139MB
+Max Per-Host Resource Reservation: Memory=29.56MB Threads=11
+Per-Host Resource Estimates: Memory=141MB
 F07:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.02MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -316,17 +316,17 @@ Per-Instance Resources: mem-estimate=11.62MB mem-reservation=2.00MB thread-reser
 |  hash predicates: c_current_addr_sk = ca_address_sk
 |  fk/pk conjuncts: c_current_addr_sk = ca_address_sk
 |  other predicates: (substring(ca_zip, CAST(1 AS BIGINT), CAST(5 AS BIGINT)) IN ('85669', '86197', '88274', '83405', '86475', '85392', '85460', '80348', '81792') OR ca_state IN ('CA', 'WA', 'GA') OR cs_sales_price > CAST(500 AS DECIMAL(5,0)))
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,3,1,2 row-size=67B cardinality=146.92K
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
 |--F08:PLAN FRAGMENT [HASH(c_current_addr_sk)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=4.64MB mem-reservation=2.94MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=5.58MB mem-reservation=3.88MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: ca_address_sk
 |  |  runtime filters: RF000[bloom] <- ca_address_sk, RF001[min_max] <- ca_address_sk
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  13:EXCHANGE [HASH(ca_address_sk)]
 |  |  mem-estimate=1.71MB mem-reservation=0B thread-reservation=0
@@ -356,17 +356,17 @@ Per-Instance Resources: mem-estimate=1.21MB mem-reservation=0B thread-reservatio
 |  hash-table-id=01
 |  hash predicates: cs_bill_customer_sk = c_customer_sk
 |  fk/pk conjuncts: cs_bill_customer_sk = c_customer_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,3,1 row-size=32B cardinality=146.92K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F09:PLAN FRAGMENT [HASH(cs_bill_customer_sk)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=3.71MB mem-reservation=2.94MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=4.65MB mem-reservation=3.88MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=01 plan-id=02 cohort-id=01
 |  |  build expressions: c_customer_sk
 |  |  runtime filters: RF002[bloom] <- c_customer_sk, RF003[min_max] <- c_customer_sk
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  11:EXCHANGE [HASH(c_customer_sk)]
 |  |  mem-estimate=793.25KB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q16.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q16.test
index 2786e23..29a5446 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q16.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q16.test
@@ -24,10 +24,10 @@ WHERE d_date BETWEEN '2002-02-01' AND cast('2002-04-02' AS date)
 ORDER BY count(DISTINCT cs_order_number)
 LIMIT 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=39.44MB Threads=7
-Per-Host Resource Estimates: Memory=565MB
+Max Per-Host Resource Reservation: Memory=48.81MB Threads=7
+Per-Host Resource Estimates: Memory=570MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=564.69MB mem-reservation=39.44MB thread-reservation=7 runtime-filters-memory=4.00MB
+|  Per-Host Resources: mem-estimate=570.31MB mem-reservation=48.81MB thread-reservation=7 runtime-filters-memory=4.00MB
 PLAN-ROOT SINK
 |  output exprs: count(cs_order_number), sum(cs_ext_ship_cost), sum(cs_net_profit)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -40,7 +40,7 @@ PLAN-ROOT SINK
 |
 12:AGGREGATE [FINALIZE]
 |  output: count(cs_order_number), sum:merge(cs_ext_ship_cost), sum:merge(cs_net_profit)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=9 row-size=40B cardinality=1
 |  in pipelines: 12(GETNEXT), 11(OPEN)
 |
@@ -53,7 +53,7 @@ PLAN-ROOT SINK
 |
 10:HASH JOIN [LEFT ANTI JOIN]
 |  hash predicates: cs1.cs_order_number = cr1.cr_order_number
-|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=0,2,1,3 row-size=109B cardinality=30.02K
 |  in pipelines: 04(GETNEXT), 05(OPEN)
 |
@@ -71,7 +71,7 @@ PLAN-ROOT SINK
 |  hash predicates: cs2.cs_order_number = cs1.cs_order_number
 |  other join predicates: cs1.cs_warehouse_sk != cs2.cs_warehouse_sk
 |  runtime filters: RF000[bloom] <- cs1.cs_order_number, RF001[min_max] <- cs1.cs_order_number
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=0,2,1,3 row-size=109B cardinality=30.02K
 |  in pipelines: 04(GETNEXT), 00(OPEN)
 |
@@ -160,10 +160,10 @@ PLAN-ROOT SINK
    tuple-ids=4 row-size=12B cardinality=1.44M
    in pipelines: 04(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=44.83MB Threads=14
-Per-Host Resource Estimates: Memory=593MB
+Max Per-Host Resource Reservation: Memory=47.64MB Threads=14
+Per-Host Resource Estimates: Memory=590MB
 F07:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=10.02MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Host Resources: mem-estimate=4.00MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: count(cs_order_number), sum(cs_ext_ship_cost), sum(cs_net_profit)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -176,7 +176,7 @@ PLAN-ROOT SINK
 |
 21:AGGREGATE [FINALIZE]
 |  output: count:merge(cs_order_number), sum:merge(cs_ext_ship_cost), sum:merge(cs_net_profit)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=9 row-size=40B cardinality=1
 |  in pipelines: 21(GETNEXT), 12(OPEN)
 |
@@ -186,10 +186,10 @@ PLAN-ROOT SINK
 |  in pipelines: 12(GETNEXT)
 |
 F05:PLAN FRAGMENT [HASH(cs1.cs_order_number)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=21.36MB mem-reservation=7.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=24.17MB mem-reservation=10.56MB thread-reservation=1 runtime-filters-memory=1.00MB
 12:AGGREGATE
 |  output: count(cs_order_number), sum:merge(cs_ext_ship_cost), sum:merge(cs_net_profit)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=9 row-size=40B cardinality=1
 |  in pipelines: 12(GETNEXT), 11(OPEN)
 |
@@ -202,7 +202,7 @@ Per-Host Resources: mem-estimate=21.36MB mem-reservation=7.75MB thread-reservati
 |
 10:HASH JOIN [LEFT ANTI JOIN, PARTITIONED]
 |  hash predicates: cs1.cs_order_number = cr1.cr_order_number
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,2,1,3 row-size=109B cardinality=30.02K
 |  in pipelines: 04(GETNEXT), 05(OPEN)
 |
@@ -351,10 +351,10 @@ Per-Host Resources: mem-estimate=97.00MB mem-reservation=5.00MB thread-reservati
    tuple-ids=4 row-size=12B cardinality=1.44M
    in pipelines: 04(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=53.64MB Threads=13
-Per-Host Resource Estimates: Memory=225MB
+Max Per-Host Resource Reservation: Memory=56.45MB Threads=13
+Per-Host Resource Estimates: Memory=218MB
 F07:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Instance Resources: mem-estimate=10.02MB mem-reservation=4.00MB thread-reservation=1
+|  Per-Instance Resources: mem-estimate=4.00MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
 |  output exprs: count(cs_order_number), sum(cs_ext_ship_cost), sum(cs_net_profit)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -367,7 +367,7 @@ PLAN-ROOT SINK
 |
 21:AGGREGATE [FINALIZE]
 |  output: count:merge(cs_order_number), sum:merge(cs_ext_ship_cost), sum:merge(cs_net_profit)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=9 row-size=40B cardinality=1
 |  in pipelines: 21(GETNEXT), 12(OPEN)
 |
@@ -377,10 +377,10 @@ PLAN-ROOT SINK
 |  in pipelines: 12(GETNEXT)
 |
 F05:PLAN FRAGMENT [HASH(cs1.cs_order_number)] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=20.00MB mem-reservation=1.94MB thread-reservation=1
+Per-Instance Resources: mem-estimate=15.55MB mem-reservation=1.94MB thread-reservation=1
 12:AGGREGATE
 |  output: count(cs_order_number), sum:merge(cs_ext_ship_cost), sum:merge(cs_net_profit)
-|  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
+|  mem-estimate=16.00KB mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=9 row-size=40B cardinality=1
 |  in pipelines: 12(GETNEXT), 11(OPEN)
 |
@@ -394,16 +394,16 @@ Per-Instance Resources: mem-estimate=20.00MB mem-reservation=1.94MB thread-reser
 10:HASH JOIN [LEFT ANTI JOIN, PARTITIONED]
 |  hash-table-id=00
 |  hash predicates: cs1.cs_order_number = cr1.cr_order_number
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,2,1,3 row-size=109B cardinality=30.02K
 |  in pipelines: 04(GETNEXT), 05(OPEN)
 |
 |--F08:PLAN FRAGMENT [HASH(cs1.cs_order_number)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=3.05MB mem-reservation=1.94MB thread-reservation=1
+|  |  Per-Instance Resources: mem-estimate=5.86MB mem-reservation=4.75MB thread-reservation=1
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: cr1.cr_order_number
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  19:EXCHANGE [HASH(cr1.cr_order_number)]
 |  |  mem-estimate=1.11MB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q17.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q17.test
index d49d8af..46f3e91 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q17.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q17.test
@@ -47,10 +47,10 @@ ORDER BY i_item_id,
          s_state
 LIMIT 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=49.27MB Threads=9
+Max Per-Host Resource Reservation: Memory=57.77MB Threads=9
 Per-Host Resource Estimates: Memory=586MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=585.75MB mem-reservation=49.27MB thread-reservation=9 runtime-filters-memory=10.00MB
+|  Per-Host Resources: mem-estimate=585.75MB mem-reservation=57.77MB thread-reservation=9 runtime-filters-memory=10.00MB
 PLAN-ROOT SINK
 |  output exprs: i_item_id, i_item_desc, s_state, count(ss_quantity), avg(ss_quantity), stddev_samp(ss_quantity), stddev_samp(ss_quantity) / avg(ss_quantity), count(sr_return_quantity), avg(sr_return_quantity), stddev_samp(sr_return_quantity), stddev_samp(sr_return_quantity) / avg(sr_return_quantity), count(cs_quantity), avg(cs_quantity), stddev_samp(cs_quantity), stddev_samp(cs_quantity) / avg(cs_quantity)
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -148,7 +148,7 @@ PLAN-ROOT SINK
 |  |  |  hash predicates: sr_customer_sk = ss_customer_sk, sr_item_sk = ss_item_sk, sr_ticket_number = ss_ticket_number
 |  |  |  fk/pk conjuncts: sr_customer_sk = ss_customer_sk, sr_item_sk = ss_item_sk, sr_ticket_number = ss_ticket_number
 |  |  |  runtime filters: RF012[bloom] <- ss_customer_sk, RF013[bloom] <- ss_item_sk, RF014[bloom] <- ss_ticket_number, RF015[min_max] <- ss_customer_sk, RF016[min_max] <- ss_item_sk, RF017[min_max] <- ss_ticket_number
-|  |  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  |  |  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  |  |  tuple-ids=1,0,3 row-size=82B cardinality=105.69K
 |  |  |  in pipelines: 01(GETNEXT), 00(OPEN)
 |  |  |
@@ -218,8 +218,8 @@ PLAN-ROOT SINK
    tuple-ids=7 row-size=148B cardinality=18.00K
    in pipelines: 07(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=66.77MB Threads=20
-Per-Host Resource Estimates: Memory=644MB
+Max Per-Host Resource Reservation: Memory=71.45MB Threads=20
+Per-Host Resource Estimates: Memory=648MB
 F11:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.07MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -254,7 +254,7 @@ Per-Host Resources: mem-estimate=10.82MB mem-reservation=1.94MB thread-reservati
 |  in pipelines: 02(GETNEXT)
 |
 F09:PLAN FRAGMENT [HASH(ss_item_sk)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=16.30MB mem-reservation=4.94MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=17.24MB mem-reservation=5.88MB thread-reservation=1 runtime-filters-memory=1.00MB
 15:AGGREGATE [STREAMING]
 |  output: count(ss_quantity), avg(CAST(ss_quantity AS BIGINT)), stddev_samp(ss_quantity), count(sr_return_quantity), avg(CAST(sr_return_quantity AS BIGINT)), stddev_samp(sr_return_quantity), count(cs_quantity), avg(CAST(cs_quantity AS BIGINT)), stddev_samp(cs_quantity)
 |  group by: i_item_id, i_item_desc, s_state
@@ -266,7 +266,7 @@ Per-Host Resources: mem-estimate=16.30MB mem-reservation=4.94MB thread-reservati
 |  hash predicates: ss_item_sk = i_item_sk
 |  fk/pk conjuncts: ss_item_sk = i_item_sk
 |  runtime filters: RF000[bloom] <- i_item_sk, RF001[min_max] <- i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=2,0,3,1,4,5,6,7 row-size=312B cardinality=2.02K
 |  in pipelines: 02(GETNEXT), 07(OPEN)
 |
@@ -361,7 +361,7 @@ Per-Host Resources: mem-estimate=205.57MB mem-reservation=19.75MB thread-reserva
 |  |  in pipelines: 00(GETNEXT)
 |  |
 |  F04:PLAN FRAGMENT [HASH(ss_customer_sk,ss_item_sk,ss_ticket_number)] hosts=3 instances=3
-|  Per-Host Resources: mem-estimate=21.06MB mem-reservation=10.69MB thread-reservation=1 runtime-filters-memory=4.00MB
+|  Per-Host Resources: mem-estimate=24.81MB mem-reservation=14.44MB thread-reservation=1 runtime-filters-memory=4.00MB
 |  10:HASH JOIN [INNER JOIN, BROADCAST]
 |  |  hash predicates: sr_returned_date_sk = d2.d_date_sk
 |  |  fk/pk conjuncts: sr_returned_date_sk = d2.d_date_sk
@@ -394,7 +394,7 @@ Per-Host Resources: mem-estimate=205.57MB mem-reservation=19.75MB thread-reserva
 |  |  hash predicates: ss_customer_sk = sr_customer_sk, ss_item_sk = sr_item_sk, ss_ticket_number = sr_ticket_number
 |  |  fk/pk conjuncts: ss_customer_sk = sr_customer_sk, ss_item_sk = sr_item_sk, ss_ticket_number = sr_ticket_number
 |  |  runtime filters: RF012[bloom] <- sr_customer_sk, RF013[bloom] <- sr_item_sk, RF014[bloom] <- sr_ticket_number, RF015[min_max] <- sr_customer_sk, RF016[min_max] <- sr_item_sk, RF017[min_max] <- sr_ticket_number
-|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  tuple-ids=0,3,1 row-size=82B cardinality=105.69K
 |  |  in pipelines: 00(GETNEXT), 01(OPEN)
 |  |
@@ -474,8 +474,8 @@ Per-Host Resources: mem-estimate=205.57MB mem-reservation=19.75MB thread-reserva
    tuple-ids=2 row-size=20B cardinality=1.44M
    in pipelines: 02(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=89.39MB Threads=22
-Per-Host Resource Estimates: Memory=289MB
+Max Per-Host Resource Reservation: Memory=94.08MB Threads=22
+Per-Host Resource Estimates: Memory=294MB
 F11:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.07MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -522,17 +522,17 @@ Per-Instance Resources: mem-estimate=10.67MB mem-reservation=2.00MB thread-reser
 |  hash-table-id=00
 |  hash predicates: ss_item_sk = i_item_sk
 |  fk/pk conjuncts: ss_item_sk = i_item_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=2,0,3,1,4,5,6,7 row-size=312B cardinality=2.02K
 |  in pipelines: 02(GETNEXT), 07(OPEN)
 |
 |--F12:PLAN FRAGMENT [HASH(ss_item_sk)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.63MB mem-reservation=2.94MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=6.57MB mem-reservation=3.88MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: i_item_sk
 |  |  runtime filters: RF000[bloom] <- i_item_sk, RF001[min_max] <- i_item_sk
-|  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  25:EXCHANGE [HASH(i_item_sk)]
 |  |  mem-estimate=2.70MB mem-reservation=0B thread-reservation=0
@@ -691,17 +691,17 @@ Per-Instance Resources: mem-estimate=48.00MB mem-reservation=8.00MB thread-reser
 |  |  hash-table-id=05
 |  |  hash predicates: ss_customer_sk = sr_customer_sk, ss_item_sk = sr_item_sk, ss_ticket_number = sr_ticket_number
 |  |  fk/pk conjuncts: ss_customer_sk = sr_customer_sk, ss_item_sk = sr_item_sk, ss_ticket_number = sr_ticket_number
-|  |  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
+|  |  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  |  tuple-ids=0,3,1 row-size=82B cardinality=105.69K
 |  |  in pipelines: 00(GETNEXT), 01(OPEN)
 |  |
 |  |--F17:PLAN FRAGMENT [HASH(ss_customer_sk,ss_item_sk,ss_ticket_number)] hosts=3 instances=6
-|  |  |  Per-Instance Resources: mem-estimate=13.58MB mem-reservation=5.88MB thread-reservation=1 runtime-filters-memory=3.00MB
+|  |  |  Per-Instance Resources: mem-estimate=15.46MB mem-reservation=7.75MB thread-reservation=1 runtime-filters-memory=3.00MB
 |  |  JOIN BUILD
 |  |  |  join-table-id=05 plan-id=06 cohort-id=02
 |  |  |  build expressions: sr_customer_sk, sr_item_sk, sr_ticket_number
 |  |  |  runtime filters: RF012[bloom] <- sr_customer_sk, RF013[bloom] <- sr_item_sk, RF014[bloom] <- sr_ticket_number, RF015[min_max] <- sr_customer_sk, RF016[min_max] <- sr_item_sk, RF017[min_max] <- sr_ticket_number
-|  |  |  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
+|  |  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |
 |  |  19:EXCHANGE [HASH(sr_customer_sk,sr_item_sk,sr_ticket_number)]
 |  |  |  mem-estimate=7.71MB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q18.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q18.test
index b8e2562..9c4c09a 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q18.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q18.test
@@ -31,10 +31,10 @@ select  i_item_id,
         i_item_id
  limit 100;
 ---- PLAN
-Max Per-Host Resource Reservation: Memory=107.38MB Threads=8
-Per-Host Resource Estimates: Memory=686MB
+Max Per-Host Resource Reservation: Memory=109.94MB Threads=8
+Per-Host Resource Estimates: Memory=690MB
 F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
-|  Per-Host Resources: mem-estimate=685.75MB mem-reservation=107.38MB thread-reservation=8 runtime-filters-memory=6.00MB
+|  Per-Host Resources: mem-estimate=689.50MB mem-reservation=109.94MB thread-reservation=8 runtime-filters-memory=6.00MB
 PLAN-ROOT SINK
 |  output exprs: CASE valid_tid(16,8,10,12,14) WHEN 8 THEN i_item_id WHEN 10 THEN i_item_id WHEN 12 THEN i_item_id WHEN 14 THEN i_item_id WHEN 16 THEN NULL END, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_country WHEN 10 THEN ca_country WHEN 12 THEN ca_country WHEN 14 THEN NULL WHEN 16 THEN NULL END, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_state WHEN 10 THEN ca_state WHEN 12 THEN NULL WHEN 14 THEN NULL WHEN 16 THEN NULL END, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_county WHEN  [...]
 |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
@@ -48,7 +48,7 @@ PLAN-ROOT SINK
 14:AGGREGATE [FINALIZE]
 |  output: aggif(valid_tid(16,8,10,12,14) IN (CAST(8 AS INT), CAST(10 AS INT), CAST(12 AS INT), CAST(14 AS INT), CAST(16 AS INT)), CASE valid_tid(16,8,10,12,14) WHEN CAST(8 AS INT) THEN avg(CAST(cs_quantity AS DECIMAL(12,2))) WHEN CAST(10 AS INT) THEN avg(CAST(cs_quantity AS DECIMAL(12,2))) WHEN CAST(12 AS INT) THEN avg(CAST(cs_quantity AS DECIMAL(12,2))) WHEN CAST(14 AS INT) THEN avg(CAST(cs_quantity AS DECIMAL(12,2))) WHEN CAST(16 AS INT) THEN avg(CAST(cs_quantity AS DECIMAL(12,2))) EN [...]
 |  group by: CASE valid_tid(16,8,10,12,14) WHEN CAST(8 AS INT) THEN i_item_id WHEN CAST(10 AS INT) THEN i_item_id WHEN CAST(12 AS INT) THEN i_item_id WHEN CAST(14 AS INT) THEN i_item_id WHEN CAST(16 AS INT) THEN NULL END, CASE valid_tid(16,8,10,12,14) WHEN CAST(8 AS INT) THEN ca_country WHEN CAST(10 AS INT) THEN ca_country WHEN CAST(12 AS INT) THEN ca_country WHEN CAST(14 AS INT) THEN NULL WHEN CAST(16 AS INT) THEN NULL END, CASE valid_tid(16,8,10,12,14) WHEN CAST(8 AS INT) THEN ca_state [...]
-|  mem-estimate=10.00MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
+|  mem-estimate=17.00MB mem-reservation=17.00MB spill-buffer=1.00MB thread-reservation=0
 |  tuple-ids=17 row-size=108B cardinality=75.61K
 |  in pipelines: 14(GETNEXT), 13(OPEN)
 |
@@ -76,7 +76,7 @@ PLAN-ROOT SINK
 |  hash predicates: cs_item_sk = i_item_sk
 |  fk/pk conjuncts: cs_item_sk = i_item_sk
 |  runtime filters: RF000[bloom] <- i_item_sk, RF001[min_max] <- i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=2,1,0,5,3,4,6 row-size=220B cardinality=28.95K
 |  in pipelines: 02(GETNEXT), 06(OPEN)
 |
@@ -102,7 +102,7 @@ PLAN-ROOT SINK
 |  |  hash predicates: cd1.cd_demo_sk = cs_bill_cdemo_sk
 |  |  fk/pk conjuncts: cd1.cd_demo_sk = cs_bill_cdemo_sk
 |  |  runtime filters: RF004[bloom] <- cs_bill_cdemo_sk, RF005[min_max] <- cs_bill_cdemo_sk
-|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |  tuple-ids=1,0,5,3,4 row-size=180B cardinality=28.95K
 |  |  in pipelines: 01(GETNEXT), 00(OPEN)
 |  |
@@ -131,7 +131,7 @@ PLAN-ROOT SINK
 |  |  |  hash predicates: cs_bill_customer_sk = c_customer_sk
 |  |  |  fk/pk conjuncts: cs_bill_customer_sk = c_customer_sk
 |  |  |  runtime filters: RF008[bloom] <- c_customer_sk, RF009[min_max] <- c_customer_sk
-|  |  |  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  |  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  |  |  tuple-ids=0,5,3 row-size=68B cardinality=181.77K
 |  |  |  in pipelines: 00(GETNEXT), 03(OPEN)
 |  |  |
@@ -206,8 +206,8 @@ PLAN-ROOT SINK
    tuple-ids=2 row-size=4B cardinality=1.92M
    in pipelines: 02(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=208.44MB Threads=18
-Per-Host Resource Estimates: Memory=899MB
+Max Per-Host Resource Reservation: Memory=195.19MB Threads=18
+Per-Host Resource Estimates: Memory=887MB
 F10:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.03MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -222,7 +222,7 @@ PLAN-ROOT SINK
 |  in pipelines: 15(GETNEXT)
 |
 F09:PLAN FRAGMENT [HASH(CASE valid_tid(7,9,11,13,15) WHEN 7 THEN murmur_hash(i_item_id) WHEN 9 THEN murmur_hash(i_item_id) WHEN 11 THEN murmur_hash(i_item_id) WHEN 13 THEN murmur_hash(i_item_id) WHEN 15 THEN murmur_hash(NULL) END,CASE valid_tid(7,9,11,13,15) WHEN 7 THEN murmur_hash(ca_country) WHEN 9 THEN murmur_hash(ca_country) WHEN 11 THEN murmur_hash(ca_country) WHEN 13 THEN murmur_hash(NULL) WHEN 15 THEN murmur_hash(NULL) END,CASE valid_tid(7,9,11,13,15) WHEN 7 THEN murmur_hash(ca_st [...]
-Per-Host Resources: mem-estimate=109.94MB mem-reservation=91.69MB thread-reservation=1
+Per-Host Resources: mem-estimate=75.94MB mem-reservation=57.69MB thread-reservation=1
 15:TOP-N [LIMIT=100]
 |  order by: CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_country WHEN 10 THEN ca_country WHEN 12 THEN ca_country WHEN 14 THEN NULL WHEN 16 THEN NULL END ASC, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_state WHEN 10 THEN ca_state WHEN 12 THEN NULL WHEN 14 THEN NULL WHEN 16 THEN NULL END ASC, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_county WHEN 10 THEN NULL WHEN 12 THEN NULL WHEN 14 THEN NULL WHEN 16 THEN NULL END ASC, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN i_item_id WHEN 10 THEN [...]
 |  mem-estimate=10.16KB mem-reservation=0B thread-reservation=0
@@ -252,7 +252,7 @@ Per-Host Resources: mem-estimate=109.94MB mem-reservation=91.69MB thread-reserva
 |  Class 4
 |    output: avg:merge(CAST(cs_quantity AS DECIMAL(12,2))), avg:merge(CAST(cs_list_price AS DECIMAL(12,2))), avg:merge(CAST(cs_coupon_amt AS DECIMAL(12,2))), avg:merge(CAST(cs_sales_price AS DECIMAL(12,2))), avg:merge(CAST(cs_net_profit AS DECIMAL(12,2))), avg:merge(CAST(c_birth_year AS DECIMAL(12,2))), avg:merge(CAST(cd1.cd_dep_count AS DECIMAL(12,2)))
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=98.00MB mem-reservation=86.94MB thread-reservation=0
+|  mem-estimate=64.00MB mem-reservation=52.94MB thread-reservation=0
 |  tuple-ids=8N,10N,12N,14N,16N row-size=641B cardinality=75.61K
 |  in pipelines: 25(GETNEXT), 00(OPEN)
 |
@@ -262,7 +262,7 @@ Per-Host Resources: mem-estimate=109.94MB mem-reservation=91.69MB thread-reserva
 |  in pipelines: 00(GETNEXT)
 |
 F07:PLAN FRAGMENT [HASH(c_current_cdemo_sk)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=82.92MB mem-reservation=62.69MB thread-reservation=1 runtime-filters-memory=2.00MB
+Per-Host Resources: mem-estimate=99.10MB mem-reservation=76.88MB thread-reservation=1 runtime-filters-memory=2.00MB
 13:AGGREGATE [STREAMING]
 |  Class 0
 |    output: avg(CAST(cs_quantity AS DECIMAL(12,2))), avg(CAST(cs_list_price AS DECIMAL(12,2))), avg(CAST(cs_coupon_amt AS DECIMAL(12,2))), avg(CAST(cs_sales_price AS DECIMAL(12,2))), avg(CAST(cs_net_profit AS DECIMAL(12,2))), avg(CAST(c_birth_year AS DECIMAL(12,2))), avg(CAST(cd1.cd_dep_count AS DECIMAL(12,2)))
@@ -279,7 +279,7 @@ Per-Host Resources: mem-estimate=82.92MB mem-reservation=62.69MB thread-reservat
 |  Class 4
 |    output: avg(CAST(cs_quantity AS DECIMAL(12,2))), avg(CAST(cs_list_price AS DECIMAL(12,2))), avg(CAST(cs_coupon_amt AS DECIMAL(12,2))), avg(CAST(cs_sales_price AS DECIMAL(12,2))), avg(CAST(cs_net_profit AS DECIMAL(12,2))), avg(CAST(c_birth_year AS DECIMAL(12,2))), avg(CAST(cd1.cd_dep_count AS DECIMAL(12,2)))
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=64.00MB mem-reservation=54.00MB thread-reservation=0
+|  mem-estimate=50.00MB mem-reservation=38.00MB thread-reservation=0
 |  tuple-ids=7N,9N,11N,13N,15N row-size=641B cardinality=75.61K
 |  in pipelines: 00(GETNEXT)
 |
@@ -287,7 +287,7 @@ Per-Host Resources: mem-estimate=82.92MB mem-reservation=62.69MB thread-reservat
 |  hash predicates: cs_item_sk = i_item_sk
 |  fk/pk conjuncts: cs_item_sk = i_item_sk
 |  runtime filters: RF000[bloom] <- i_item_sk, RF001[min_max] <- i_item_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=2.88MB mem-reservation=2.88MB spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,5,3,4,1,2,6 row-size=220B cardinality=28.95K
 |  in pipelines: 00(GETNEXT), 06(OPEN)
 |
@@ -312,7 +312,7 @@ Per-Host Resources: mem-estimate=82.92MB mem-reservation=62.69MB thread-reservat
 |  hash predicates: c_current_cdemo_sk = cd2.cd_demo_sk
 |  fk/pk conjuncts: c_current_cdemo_sk = cd2.cd_demo_sk
 |  runtime filters: RF002[bloom] <- cd2.cd_demo_sk, RF003[min_max] <- cd2.cd_demo_sk
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,5,3,4,1,2 row-size=184B cardinality=28.95K
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
@@ -339,12 +339,12 @@ Per-Host Resources: mem-estimate=82.92MB mem-reservation=62.69MB thread-reservat
 |  in pipelines: 00(GETNEXT)
 |
 F05:PLAN FRAGMENT [HASH(cs_bill_cdemo_sk)] hosts=3 instances=3
-Per-Host Resources: mem-estimate=15.38MB mem-reservation=5.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+Per-Host Resources: mem-estimate=19.13MB mem-reservation=9.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 10:HASH JOIN [INNER JOIN, PARTITIONED]
 |  hash predicates: cs_bill_cdemo_sk = cd1.cd_demo_sk
 |  fk/pk conjuncts: cs_bill_cdemo_sk = cd1.cd_demo_sk
 |  runtime filters: RF004[bloom] <- cd1.cd_demo_sk, RF005[min_max] <- cd1.cd_demo_sk
-|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=0,5,3,4,1 row-size=180B cardinality=28.95K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
@@ -374,7 +374,7 @@ Per-Host Resources: mem-estimate=15.38MB mem-reservation=5.75MB thread-reservati
 |  in pipelines: 00(GETNEXT)
 |
 F00:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-Per-Host Resources: mem-estimate=396.33MB mem-reservation=26.81MB thread-reservation=2 runtime-filters-memory=5.00MB
+Per-Host Resources: mem-estimate=399.14MB mem-reservation=29.62MB thread-reservation=2 runtime-filters-memory=5.00MB
 09:HASH JOIN [INNER JOIN, BROADCAST]
 |  hash predicates: c_current_addr_sk = ca_address_sk
 |  fk/pk conjuncts: c_current_addr_sk = ca_address_sk
@@ -407,7 +407,7 @@ Per-Host Resources: mem-estimate=396.33MB mem-reservation=26.81MB thread-reserva
 |  hash predicates: cs_bill_customer_sk = c_customer_sk
 |  fk/pk conjuncts: cs_bill_customer_sk = c_customer_sk
 |  runtime filters: RF008[bloom] <- c_customer_sk, RF009[min_max] <- c_customer_sk
-|  mem-estimate=1.94MB mem-reservation=1.94MB spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,5,3 row-size=68B cardinality=181.77K
 |  in pipelines: 00(GETNEXT), 03(OPEN)
 |
@@ -471,8 +471,8 @@ Per-Host Resources: mem-estimate=396.33MB mem-reservation=26.81MB thread-reserva
    tuple-ids=0 row-size=40B cardinality=1.44M
    in pipelines: 00(GETNEXT)
 ---- PARALLELPLANS
-Max Per-Host Resource Reservation: Memory=218.19MB Threads=17
-Per-Host Resource Estimates: Memory=380MB
+Max Per-Host Resource Reservation: Memory=208.69MB Threads=17
+Per-Host Resource Estimates: Memory=373MB
 F10:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Instance Resources: mem-estimate=4.03MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -487,7 +487,7 @@ PLAN-ROOT SINK
 |  in pipelines: 15(GETNEXT)
 |
 F09:PLAN FRAGMENT [HASH(CASE valid_tid(7,9,11,13,15) WHEN 7 THEN murmur_hash(i_item_id) WHEN 9 THEN murmur_hash(i_item_id) WHEN 11 THEN murmur_hash(i_item_id) WHEN 13 THEN murmur_hash(i_item_id) WHEN 15 THEN murmur_hash(NULL) END,CASE valid_tid(7,9,11,13,15) WHEN 7 THEN murmur_hash(ca_country) WHEN 9 THEN murmur_hash(ca_country) WHEN 11 THEN murmur_hash(ca_country) WHEN 13 THEN murmur_hash(NULL) WHEN 15 THEN murmur_hash(NULL) END,CASE valid_tid(7,9,11,13,15) WHEN 7 THEN murmur_hash(ca_st [...]
-Per-Instance Resources: mem-estimate=109.94MB mem-reservation=91.69MB thread-reservation=1
+Per-Instance Resources: mem-estimate=75.94MB mem-reservation=57.69MB thread-reservation=1
 15:TOP-N [LIMIT=100]
 |  order by: CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_country WHEN 10 THEN ca_country WHEN 12 THEN ca_country WHEN 14 THEN NULL WHEN 16 THEN NULL END ASC, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_state WHEN 10 THEN ca_state WHEN 12 THEN NULL WHEN 14 THEN NULL WHEN 16 THEN NULL END ASC, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN ca_county WHEN 10 THEN NULL WHEN 12 THEN NULL WHEN 14 THEN NULL WHEN 16 THEN NULL END ASC, CASE valid_tid(16,8,10,12,14) WHEN 8 THEN i_item_id WHEN 10 THEN [...]
 |  mem-estimate=10.16KB mem-reservation=0B thread-reservation=0
@@ -517,7 +517,7 @@ Per-Instance Resources: mem-estimate=109.94MB mem-reservation=91.69MB thread-res
 |  Class 4
 |    output: avg:merge(CAST(cs_quantity AS DECIMAL(12,2))), avg:merge(CAST(cs_list_price AS DECIMAL(12,2))), avg:merge(CAST(cs_coupon_amt AS DECIMAL(12,2))), avg:merge(CAST(cs_sales_price AS DECIMAL(12,2))), avg:merge(CAST(cs_net_profit AS DECIMAL(12,2))), avg:merge(CAST(c_birth_year AS DECIMAL(12,2))), avg:merge(CAST(cd1.cd_dep_count AS DECIMAL(12,2)))
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=98.00MB mem-reservation=86.94MB thread-reservation=0
+|  mem-estimate=64.00MB mem-reservation=52.94MB thread-reservation=0
 |  tuple-ids=8N,10N,12N,14N,16N row-size=641B cardinality=75.61K
 |  in pipelines: 25(GETNEXT), 00(OPEN)
 |
@@ -527,7 +527,7 @@ Per-Instance Resources: mem-estimate=109.94MB mem-reservation=91.69MB thread-res
 |  in pipelines: 00(GETNEXT)
 |
 F07:PLAN FRAGMENT [HASH(c_current_cdemo_sk)] hosts=3 instances=3
-Per-Instance Resources: mem-estimate=66.24MB mem-reservation=54.00MB thread-reservation=1
+Per-Instance Resources: mem-estimate=52.24MB mem-reservation=38.00MB thread-reservation=1
 13:AGGREGATE [STREAMING]
 |  Class 0
 |    output: avg(CAST(cs_quantity AS DECIMAL(12,2))), avg(CAST(cs_list_price AS DECIMAL(12,2))), avg(CAST(cs_coupon_amt AS DECIMAL(12,2))), avg(CAST(cs_sales_price AS DECIMAL(12,2))), avg(CAST(cs_net_profit AS DECIMAL(12,2))), avg(CAST(c_birth_year AS DECIMAL(12,2))), avg(CAST(cd1.cd_dep_count AS DECIMAL(12,2)))
@@ -544,7 +544,7 @@ Per-Instance Resources: mem-estimate=66.24MB mem-reservation=54.00MB thread-rese
 |  Class 4
 |    output: avg(CAST(cs_quantity AS DECIMAL(12,2))), avg(CAST(cs_list_price AS DECIMAL(12,2))), avg(CAST(cs_coupon_amt AS DECIMAL(12,2))), avg(CAST(cs_sales_price AS DECIMAL(12,2))), avg(CAST(cs_net_profit AS DECIMAL(12,2))), avg(CAST(c_birth_year AS DECIMAL(12,2))), avg(CAST(cd1.cd_dep_count AS DECIMAL(12,2)))
 |    group by: NULL, NULL, NULL, NULL
-|  mem-estimate=64.00MB mem-reservation=54.00MB thread-reservation=0
+|  mem-estimate=50.00MB mem-reservation=38.00MB thread-reservation=0
 |  tuple-ids=7N,9N,11N,13N,15N row-size=641B cardinality=75.61K
 |  in pipelines: 00(GETNEXT)
 |
@@ -552,17 +552,17 @@ Per-Instance Resources: mem-estimate=66.24MB mem-reservation=54.00MB thread-rese
 |  hash-table-id=00
 |  hash predicates: cs_item_sk = i_item_sk
 |  fk/pk conjuncts: cs_item_sk = i_item_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=128.00KB thread-reservation=0
 |  tuple-ids=0,5,3,4,1,2,6 row-size=220B cardinality=28.95K
 |  in pipelines: 00(GETNEXT), 06(OPEN)
 |
 |--F11:PLAN FRAGMENT [HASH(c_current_cdemo_sk)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.53MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=7.41MB mem-reservation=6.75MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=00 plan-id=01 cohort-id=01
 |  |  build expressions: i_item_sk
 |  |  runtime filters: RF000[bloom] <- i_item_sk, RF001[min_max] <- i_item_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=5.75MB mem-reservation=5.75MB spill-buffer=128.00KB thread-reservation=0
 |  |
 |  23:EXCHANGE [BROADCAST]
 |  |  mem-estimate=672.81KB mem-reservation=0B thread-reservation=0
@@ -585,17 +585,17 @@ Per-Instance Resources: mem-estimate=66.24MB mem-reservation=54.00MB thread-rese
 |  hash-table-id=01
 |  hash predicates: c_current_cdemo_sk = cd2.cd_demo_sk
 |  fk/pk conjuncts: c_current_cdemo_sk = cd2.cd_demo_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=2.00MB thread-reservation=0
 |  tuple-ids=0,5,3,4,1,2 row-size=184B cardinality=28.95K
 |  in pipelines: 00(GETNEXT), 02(OPEN)
 |
 |--F12:PLAN FRAGMENT [HASH(c_current_cdemo_sk)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=13.09MB mem-reservation=5.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=42.34MB mem-reservation=35.00MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=01 plan-id=02 cohort-id=01
 |  |  build expressions: cd2.cd_demo_sk
 |  |  runtime filters: RF002[bloom] <- cd2.cd_demo_sk, RF003[min_max] <- cd2.cd_demo_sk
-|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  |  mem-estimate=34.00MB mem-reservation=34.00MB spill-buffer=2.00MB thread-reservation=0
 |  |
 |  22:EXCHANGE [HASH(cd2.cd_demo_sk)]
 |  |  mem-estimate=7.34MB mem-reservation=0B thread-reservation=0
@@ -625,17 +625,17 @@ Per-Instance Resources: mem-estimate=1.71MB mem-reservation=0B thread-reservatio
 |  hash-table-id=02
 |  hash predicates: cs_bill_cdemo_sk = cd1.cd_demo_sk
 |  fk/pk conjuncts: cs_bill_cdemo_sk = cd1.cd_demo_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=512.00KB thread-reservation=0
 |  tuple-ids=0,5,3,4,1 row-size=180B cardinality=28.95K
 |  in pipelines: 00(GETNEXT), 01(OPEN)
 |
 |--F13:PLAN FRAGMENT [HASH(cs_bill_cdemo_sk)] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=13.67MB mem-reservation=5.75MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=17.42MB mem-reservation=9.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=02 plan-id=03 cohort-id=01
 |  |  build expressions: cd1.cd_demo_sk
 |  |  runtime filters: RF004[bloom] <- cd1.cd_demo_sk, RF005[min_max] <- cd1.cd_demo_sk
-|  |  mem-estimate=4.75MB mem-reservation=4.75MB spill-buffer=256.00KB thread-reservation=0
+|  |  mem-estimate=8.50MB mem-reservation=8.50MB spill-buffer=512.00KB thread-reservation=0
 |  |
 |  20:EXCHANGE [HASH(cd1.cd_demo_sk)]
 |  |  mem-estimate=7.92MB mem-reservation=0B thread-reservation=0
@@ -705,17 +705,17 @@ Per-Instance Resources: mem-estimate=48.00MB mem-reservation=16.00MB thread-rese
 |  hash-table-id=04
 |  hash predicates: cs_bill_customer_sk = c_customer_sk
 |  fk/pk conjuncts: cs_bill_customer_sk = c_customer_sk
-|  mem-estimate=0B mem-reservation=0B spill-buffer=64.00KB thread-reservation=0
+|  mem-estimate=0B mem-reservation=0B spill-buffer=256.00KB thread-reservation=0
 |  tuple-ids=0,5,3 row-size=68B cardinality=181.77K
 |  in pipelines: 00(GETNEXT), 03(OPEN)
 |
 |--F15:PLAN FRAGMENT [RANDOM] hosts=3 instances=3
-|  |  Per-Instance Resources: mem-estimate=5.85MB mem-reservation=4.88MB thread-reservation=1 runtime-filters-memory=1.00MB
+|  |  Per-Instance Resources: mem-estimate=11.48MB mem-reservation=10.50MB thread-reservation=1 runtime-filters-memory=1.00MB
 |  JOIN BUILD
 |  |  join-table-id=04 plan-id=05 cohort-id=01
 |  |  build expressions: c_customer_sk
 |  |  runtime filters: RF008[bloom] <- c_customer_sk, RF009[min_max] <- c_customer_sk
-|  |  mem-estimate=3.88MB mem-reservation=3.88MB spill-buffer=64.00KB thread-reservation=0
+|  |  mem-estimate=9.50MB mem-reservation=9.50MB spill-buffer=256.00KB thread-reservation=0
 |  |
 |  17:EXCHANGE [BROADCAST]
 |  |  mem-estimate=1000.56KB mem-reservation=0B thread-reservation=0
diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q19.test b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q19.test
index 7d617d9..29440e9 100644
--- a/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q19.test
+++ b/testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q19.test
@@ -167,8 +167,8 @@ PLAN-ROOT SINK
    tuple-ids=4 row-size=21B cardinality=50.00K
    in pipelines: 04(GETNEXT)
 ---- DISTRIBUTEDPLAN
-Max Per-Host Resource Reservation: Memory=30.14MB Threads=16
-Per-Host Resource Estimates: Memory=349MB
+Max Per-Host Resource Reservation: Memory=32.02MB Threads=16
+Per-Host Resource Estimates: Memory=351MB
 F09:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
 |  Per-Host Resources: mem-estimate=4.03MB mem-reservation=4.00MB thread-reservation=1
 PLAN-ROOT SINK
@@ -203,7 +203,7 @@ Per-Host Resources: mem-estimate=10.27MB mem-reservation=1.94MB thread-reservati
 |  in pipelines: 01(GETNEXT)
 |
... 16886 lines suppressed ...