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

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


The following commit(s) were added to refs/heads/master by this push:
     new 24179d46c IMPALA-13793: Always close expressions
24179d46c is described below

commit 24179d46cce2a1ff063f9ae37f0291f2dd23d8ed
Author: Daniel Becker <[email protected]>
AuthorDate: Fri Feb 21 09:50:33 2025 +0100

    IMPALA-13793: Always close expressions
    
    The Expr class has a Close() method, which is currently only used for
    releasing 'cache_entry_', which is used for UDF or UDAF functions. If
    Close() is not called for an Expr that uses 'cache_entry_', a DCHECK
    fails in the destructor of Expr. However, if an Expr does not use
    'cache_entry_' is not closed, nothing happens.
    
    Classes holding Expr objects should always close
    expressions because they may use 'cache_entry_'. However, if tests fail
    to include cases where 'cache_entry_' is used, bugs may not be detected:
    one such case was IMPALA-13770.
    
    In debug builds, this change adds a new field, 'closed_', to the Expr
    class, which is set to true in Close(). A DCHECK in the destructor fires
    if Close() has not been called, regardless of whether 'cache_entry_' is
    used. This makes it easier to detect cases where expressions are not
    closed.
    
    To avoid increasing the size of expressions, the 'closed_' field is not
    added in release mode.
    
    Existing cases where expressions are not closed are fixed in this
    change.
    
    Testing:
     - tests are updated to close expressions
    
    Change-Id: I9784652f5e135f1f8cd7f0fa6df471e64d27c477
    Reviewed-on: http://gerrit.cloudera.org:8080/22528
    Reviewed-by: Impala Public Jenkins <[email protected]>
    Tested-by: Impala Public Jenkins <[email protected]>
---
 be/src/exec/nested-loop-join-builder.cc | 7 +++++++
 be/src/exprs/expr-codegen-test.cc       | 1 +
 be/src/exprs/expr-test.cc               | 7 +++++++
 be/src/exprs/expr.cc                    | 6 ++++++
 be/src/exprs/expr.h                     | 4 ++++
 be/src/runtime/data-stream-test.cc      | 1 +
 be/src/util/tuple-row-compare-test.cc   | 1 +
 7 files changed, 27 insertions(+)

diff --git a/be/src/exec/nested-loop-join-builder.cc 
b/be/src/exec/nested-loop-join-builder.cc
index d40ce225c..35b4c5515 100644
--- a/be/src/exec/nested-loop-join-builder.cc
+++ b/be/src/exec/nested-loop-join-builder.cc
@@ -244,6 +244,13 @@ void NljBuilder::Close(RuntimeState* state) {
     if (ctx.expr_eval != nullptr) ctx.expr_eval->Close(state);
   }
 
+  if (!is_separate_build_) {
+    // If we are using embedded mode, the sink config is created by
+    // NljBuilder::CreateEmbeddedBuilder, so we must close it ourselves.
+    // TODO: Remove const-cast.
+    const_cast<DataSinkConfig&>(sink_config_).Close();
+  }
+
   DataSink::Close(state);
   closed_ = true;
 }
diff --git a/be/src/exprs/expr-codegen-test.cc 
b/be/src/exprs/expr-codegen-test.cc
index 377740b7f..c4934a435 100644
--- a/be/src/exprs/expr-codegen-test.cc
+++ b/be/src/exprs/expr-codegen-test.cc
@@ -357,6 +357,7 @@ TEST_F(ExprCodegenTest, TestInlineConstFnAttrs) {
   EXPECT_EQ(result.is_null, false);
   EXPECT_EQ(result.val8, 100003);
   CheckFnAttr();
+  expr->Close();
   codegen->Close();
 }
 
diff --git a/be/src/exprs/expr-test.cc b/be/src/exprs/expr-test.cc
index b966abfa7..21be6c6a5 100644
--- a/be/src/exprs/expr-test.cc
+++ b/be/src/exprs/expr-test.cc
@@ -1524,6 +1524,7 @@ TEST_P(ExprTest, NullLiteral) {
     EXPECT_OK(eval->Open(&state));
     EXPECT_TRUE(eval->GetValue(nullptr) == nullptr);
     eval->Close(&state);
+    expr.Close();
     state.ReleaseResources();
   }
 }
@@ -9165,7 +9166,9 @@ TEST_P(ExprTest, ResultsLayoutTest) {
 
   expected_offsets.clear();
   for (const ColumnType& t: types) {
+    ScalarExpr::Close(exprs);
     exprs.clear();
+
     expected_offsets.clear();
     // With one expr, all offsets should be 0.
     expected_offsets[t.GetByteSize()] = set<int>({0});
@@ -9184,6 +9187,8 @@ TEST_P(ExprTest, ResultsLayoutTest) {
   int expected_byte_size = 0;
   int expected_var_begin = 0;
   expected_offsets.clear();
+
+  ScalarExpr::Close(exprs);
   exprs.clear();
 
   // Test layout adding a bunch of exprs.  Previously, this triggered padding.
@@ -9259,6 +9264,8 @@ TEST_P(ExprTest, ResultsLayoutTest) {
     std::random_shuffle(exprs.begin(), exprs.end());
     ValidateLayout(exprs, expected_byte_size, expected_var_begin, 
expected_offsets);
   }
+
+  ScalarExpr::Close(exprs);
 }
 
 // TODO: is there an easy way to templatize/parametrize these tests?
diff --git a/be/src/exprs/expr.cc b/be/src/exprs/expr.cc
index 68f1c4235..a591e0d1c 100644
--- a/be/src/exprs/expr.cc
+++ b/be/src/exprs/expr.cc
@@ -44,6 +44,9 @@ Expr::Expr(const TExprNode& node)
 }
 
 Expr::~Expr() {
+#ifndef NDEBUG
+  DCHECK(closed_);
+#endif
   DCHECK(cache_entry_ == nullptr);
 }
 
@@ -97,6 +100,9 @@ void Expr::Close() {
     LibCache::instance()->DecrementUseCount(cache_entry_);
     cache_entry_ = nullptr;
   }
+#ifndef NDEBUG
+  closed_ = true;
+#endif
 }
 
 }
diff --git a/be/src/exprs/expr.h b/be/src/exprs/expr.h
index 5903cc6a1..65855486c 100644
--- a/be/src/exprs/expr.h
+++ b/be/src/exprs/expr.h
@@ -118,6 +118,10 @@ class Expr {
   friend class ExprTest;
   friend class ExprCodegenTest;
 
+#ifndef NDEBUG
+  bool closed_ = false;
+#endif
+
   /// Creates an expression tree rooted at 'root' via depth-first traversal.
   /// Called recursively to create children expr trees for sub-expressions.
   ///
diff --git a/be/src/runtime/data-stream-test.cc 
b/be/src/runtime/data-stream-test.cc
index 1334f973a..d1ebc1050 100644
--- a/be/src/runtime/data-stream-test.cc
+++ b/be/src/runtime/data-stream-test.cc
@@ -674,6 +674,7 @@ class DataStreamTest : public testing::Test {
     sender->Close(&state);
     info->num_bytes_sent = static_cast<KrpcDataStreamSender*>(
         sender.get())->GetNumDataBytesSent();
+    data_sink->Close();
 
     batch->Reset();
     state.ReleaseResources();
diff --git a/be/src/util/tuple-row-compare-test.cc 
b/be/src/util/tuple-row-compare-test.cc
index df2e4b4bc..47882f310 100644
--- a/be/src/util/tuple-row-compare-test.cc
+++ b/be/src/util/tuple-row-compare-test.cc
@@ -90,6 +90,7 @@ class TupleRowCompareTest : public testing::Test {
 
   template <typename... Types>
   void CreateComperator(Types... types) {
+    ScalarExpr::Close(ordering_exprs_);
     ordering_exprs_.clear();
     LoadComperator(1, types...);
   }

Reply via email to