You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2016/12/02 17:06:51 UTC
[2/2] incubator-impala git commit: IMPALA-4525: follow-on: cleanup
error handling
IMPALA-4525: follow-on: cleanup error handling
Testing:
Ran exhaustive build. There is already some test coverage in
test_exprs.py for errors returned during constant expr evaluation by the
frontend.
Change-Id: Ifb2e532381c3e6c7b2e3ef37c2d91fbebb2db2d0
Reviewed-on: http://gerrit.cloudera.org:8080/5212
Reviewed-by: Tim Armstrong <ta...@cloudera.com>
Tested-by: Impala Public Jenkins
Project: http://git-wip-us.apache.org/repos/asf/incubator-impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-impala/commit/d44df836
Tree: http://git-wip-us.apache.org/repos/asf/incubator-impala/tree/d44df836
Diff: http://git-wip-us.apache.org/repos/asf/incubator-impala/diff/d44df836
Branch: refs/heads/master
Commit: d44df83689f6cd0cb5c93d3893beaff4f7c9342a
Parents: 48983b3
Author: Tim Armstrong <ta...@cloudera.com>
Authored: Wed Nov 23 15:48:55 2016 -0800
Committer: Impala Public Jenkins <im...@gerrit.cloudera.org>
Committed: Fri Dec 2 11:37:14 2016 +0000
----------------------------------------------------------------------
be/src/exprs/expr-context.cc | 4 +--
be/src/exprs/expr-context.h | 3 ++
be/src/service/fe-support.cc | 67 +++++++++++++++++----------------------
3 files changed, 34 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/d44df836/be/src/exprs/expr-context.cc
----------------------------------------------------------------------
diff --git a/be/src/exprs/expr-context.cc b/be/src/exprs/expr-context.cc
index 27c61c1..94c652a 100644
--- a/be/src/exprs/expr-context.cc
+++ b/be/src/exprs/expr-context.cc
@@ -71,9 +71,9 @@ Status ExprContext::Open(RuntimeState* state) {
}
void ExprContext::Close(RuntimeState* state) {
- DCHECK(!closed_);
+ if (closed_) return;
FunctionContext::FunctionStateScope scope =
- is_clone_? FunctionContext::THREAD_LOCAL : FunctionContext::FRAGMENT_LOCAL;
+ is_clone_ ? FunctionContext::THREAD_LOCAL : FunctionContext::FRAGMENT_LOCAL;
root_->Close(state, this, scope);
for (int i = 0; i < fn_contexts_.size(); ++i) {
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/d44df836/be/src/exprs/expr-context.h
----------------------------------------------------------------------
diff --git a/be/src/exprs/expr-context.h b/be/src/exprs/expr-context.h
index e765b87..f7e1239 100644
--- a/be/src/exprs/expr-context.h
+++ b/be/src/exprs/expr-context.h
@@ -49,6 +49,8 @@ class ExprContext {
/// Prepare expr tree for evaluation.
/// Allocations from this context will be counted against 'tracker'.
+ /// If Prepare() is called, Close() must be called before destruction to release
+ /// resources, regardless of whether Prepare() succeeded.
Status Prepare(RuntimeState* state, const RowDescriptor& row_desc,
MemTracker* tracker);
@@ -68,6 +70,7 @@ class ExprContext {
Status Clone(RuntimeState* state, ExprContext** new_context);
/// Closes all FunctionContexts. Must be called on every ExprContext, including clones.
+ /// Has no effect if already closed.
void Close(RuntimeState* state);
/// Calls the appropriate Get*Val() function on this context's expr tree and stores the
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/d44df836/be/src/service/fe-support.cc
----------------------------------------------------------------------
diff --git a/be/src/service/fe-support.cc b/be/src/service/fe-support.cc
index 93eff4b..b3e3d0c 100644
--- a/be/src/service/fe-support.cc
+++ b/be/src/service/fe-support.cc
@@ -79,11 +79,13 @@ JNIEXPORT jbyteArray JNICALL
Java_org_apache_impala_service_FeSupport_NativeEvalConstExprs(
JNIEnv* env, jclass caller_class, jbyteArray thrift_expr_batch,
jbyteArray thrift_query_ctx_bytes) {
+ Status status;
jbyteArray result_bytes = NULL;
TQueryCtx query_ctx;
TExprBatch expr_batch;
JniLocalFrame jni_frame;
TResultRow expr_results;
+ vector<TColumnValue> results;
ObjectPool obj_pool;
DeserializeThriftMsg(env, thrift_expr_batch, &expr_batch);
@@ -113,71 +115,60 @@ Java_org_apache_impala_service_FeSupport_NativeEvalConstExprs(
vector<ExprContext*> expr_ctxs;
for (const TExpr& texpr : texprs) {
ExprContext* ctx;
- THROW_IF_ERROR_RET(Expr::CreateExprTree(&obj_pool, texpr, &ctx), env,
- JniUtil::internal_exc_class(), result_bytes);
- Status prepare_status =
- ctx->Prepare(&state, RowDescriptor(), state.query_mem_tracker());
+ status = Expr::CreateExprTree(&obj_pool, texpr, &ctx);
+ if (!status.ok()) goto error;
+
+ // Add 'ctx' to vector so it will be closed if Prepare() fails.
expr_ctxs.push_back(ctx);
- if (!prepare_status.ok()) {
- for (ExprContext* ctx: expr_ctxs) ctx->Close(&state);
- (env)->ThrowNew(JniUtil::internal_exc_class(), prepare_status.GetDetail().c_str());
- return result_bytes;
- }
+ status = ctx->Prepare(&state, RowDescriptor(), state.query_mem_tracker());
+ if (!status.ok()) goto error;
}
// UDFs which cannot be interpreted need to be handled by codegen.
if (state.ScalarFnNeedsCodegen()) {
- THROW_IF_ERROR_RET(
- state.CreateCodegen(), env, JniUtil::internal_exc_class(), result_bytes);
+ status = state.CreateCodegen();
+ if (!status.ok()) goto error;
LlvmCodeGen* codegen = state.codegen();
DCHECK(codegen != NULL);
state.CodegenScalarFns();
codegen->EnableOptimizations(false);
Status status = codegen->FinalizeModule();
- if (!status.ok()) {
- for (int i = 0; i < expr_ctxs.size(); ++i) {
- expr_ctxs[i]->Close(&state);
- }
- (env)->ThrowNew(JniUtil::internal_exc_class(), status.GetDetail().c_str());
- return result_bytes;
- }
+ if (!status.ok()) goto error;
}
// Open() and evaluate the exprs. Always Close() the exprs even in case of errors.
- vector<TColumnValue> results;
- Status status;
- int i;
- for (i = 0; i < expr_ctxs.size(); ++i) {
- status = expr_ctxs[i]->Open(&state);
- if (!status.ok()) break;
+ for (ExprContext* expr_ctx : expr_ctxs) {
+ status = expr_ctx->Open(&state);
+ if (!status.ok()) goto error;
TColumnValue val;
- expr_ctxs[i]->GetConstantValue(&val);
- status = expr_ctxs[i]->root()->GetFnContextError(expr_ctxs[i]);
- if (!status.ok()) break;
+ expr_ctx->GetConstantValue(&val);
+ status = expr_ctx->root()->GetFnContextError(expr_ctx);
+ if (!status.ok()) goto error;
// Check for mem limit exceeded.
status = state.CheckQueryState();
- if (!status.ok()) break;
+ if (!status.ok()) goto error;
// Check for warnings registered in the runtime state.
if (state.HasErrors()) {
status = Status(state.ErrorLog());
- break;
+ goto error;
}
- expr_ctxs[i]->Close(&state);
+ expr_ctx->Close(&state);
results.push_back(val);
}
- // Convert status to exception. Close all remaining expr contexts.
- if (!status.ok()) {
- for (int j = i; j < expr_ctxs.size(); ++j) expr_ctxs[j]->Close(&state);
- (env)->ThrowNew(JniUtil::internal_exc_class(), status.GetDetail().c_str());
- return result_bytes;
- }
expr_results.__set_colVals(results);
- THROW_IF_ERROR_RET(SerializeThriftMsg(env, &expr_results, &result_bytes), env,
- JniUtil::internal_exc_class(), result_bytes);
+ status = SerializeThriftMsg(env, &expr_results, &result_bytes);
+ if (!status.ok()) goto error;
+ return result_bytes;
+
+error:
+ DCHECK(!status.ok());
+ // Convert status to exception. Close all remaining expr contexts.
+ for (ExprContext* expr_ctx : expr_ctxs) expr_ctx->Close(&state);
+ (env)->ThrowNew(JniUtil::internal_exc_class(), status.GetDetail().c_str());
return result_bytes;
}