Skip to content

Commit

Permalink
IMPALA-589: Add sql function returning the impalad coordinator hostname.
Browse files Browse the repository at this point in the history
In every execution of an Impala query, one of the impalad daemons acts
as the coordinator node. In some cases, such as when using a proxy, a
user cannot predict which host will act as the coordinator. To aid in
diagnosis, we provide a sql function which returns the name of the host
on which the coordinator is running.

EXTERNAL DESCRIPTION:

Add a builtin function called coordinator(), which returns the name of
the host which is running the impalad that is acting as the coordinator
for the current query.

TESTING:
- Added a basic unit test for the new function.
- Added a unit test which simulates the case when coord_address is
  unset.
- Added a query that uses coordinator() to exprs.test
- Hand tested in a development deployment.
- Ran regression tests and got a clean run.

Change-Id: I94d6e2664ba659b48df53c5c06f67b502c533e47
Reviewed-on: http://gerrit.cloudera.org:8080/11459
Reviewed-by: Thomas Marshall <[email protected]>
Tested-by: Impala Public Jenkins <[email protected]>
  • Loading branch information
bartash authored and cloudera-hudson committed Sep 24, 2018
1 parent e6473fb commit ab9e8b2
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 0 deletions.
27 changes: 27 additions & 0 deletions be/src/exprs/expr-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "codegen/llvm-codegen.h"
#include "common/init.h"
#include "common/object-pool.h"
#include "exprs/anyval-util.h"
#include "exprs/is-null-predicate.h"
#include "exprs/like-predicate.h"
#include "exprs/literal.h"
Expand Down Expand Up @@ -65,6 +66,7 @@
#include "util/string-parser.h"
#include "util/string-util.h"
#include "util/test-info.h"
#include "utility-functions.h"

#include "common/names.h"

Expand Down Expand Up @@ -4874,6 +4876,9 @@ TEST_F(ExprTest, UtilityFunctions) {
TestStringValue("version()", GetVersionString());
TestValue("sleep(100)", TYPE_BOOLEAN, true);
TestIsNull("sleep(NULL)", TYPE_BOOLEAN);
string hostname;
ASSERT_OK(GetHostname(&hostname));
TestStringValue("coordinator()", hostname);

// Test typeOf
TestStringValue("typeOf(!true)", "BOOLEAN");
Expand All @@ -4890,6 +4895,8 @@ TEST_F(ExprTest, UtilityFunctions) {
TestStringValue("typeOf(cast(10 as FLOAT))", "FLOAT");
TestStringValue("typeOf(cast(10 as DOUBLE))", "DOUBLE");
TestStringValue("typeOf(current_database())", "STRING");
TestStringValue("typeOf(version())", "STRING");
TestStringValue("typeOf(coordinator())", "STRING");
TestStringValue("typeOf(now())", "TIMESTAMP");
TestStringValue("typeOf(utc_timestamp())", "TIMESTAMP");
TestStringValue("typeOf(cast(10 as DECIMAL))", "DECIMAL(9,0)");
Expand Down Expand Up @@ -4946,6 +4953,26 @@ TEST_F(ExprTest, UtilityFunctions) {
TestIsNull("fnv_hash(NULL)", TYPE_BIGINT);
}

// Test that UtilityFunctions::Coordinator() will return null if coord_address is unset
TEST_F(ExprTest, CoordinatorFunction) {
// Make a RuntimeState where the query context does not have coord_address set.
// Note that this should never happen in a real impalad.
RuntimeState state(TQueryCtx(), ExecEnv::GetInstance());
MemTracker tracker;
MemPool mem_pool(&tracker);
FunctionContext::TypeDesc return_type;
return_type.type = FunctionContext::Type::TYPE_STRING;
std::vector<FunctionContext::TypeDesc> no_arguments;
FunctionContext* context =
CreateUdfTestContext(return_type, no_arguments, &state, &mem_pool);

StringVal coordinator = UtilityFunctions::Coordinator(context);
ASSERT_TRUE(coordinator.is_null) << "Coordinator() did not return expected null value";

UdfTestHarness::CloseContext(context);
state.ReleaseResources();
}

TEST_F(ExprTest, MurmurHashFunction) {
string s("hello world");
int64_t expected = HashUtil::MurmurHash2_64(s.data(), s.size(),
Expand Down
8 changes: 8 additions & 0 deletions be/src/exprs/utility-functions-ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ StringVal UtilityFunctions::CurrentSession(FunctionContext* ctx) {
return AnyValUtil::FromString(ctx, PrintId(ctx->impl()->state()->session_id()));
}

StringVal UtilityFunctions::Coordinator(FunctionContext* ctx) {
const TQueryCtx& query_ctx = ctx->impl()->state()->query_ctx();
// An empty string indicates the coordinator was not set in the query request.
return query_ctx.__isset.coord_address ?
AnyValUtil::FromString(ctx, query_ctx.coord_address.hostname) :
StringVal::null();
}

template<typename T>
StringVal UtilityFunctions::TypeOf(FunctionContext* ctx, const T& /*input_val*/) {
FunctionContext::TypeDesc type_desc = *(ctx->GetArgType(0));
Expand Down
4 changes: 4 additions & 0 deletions be/src/exprs/utility-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ class UtilityFunctions {
static void UuidClose(FunctionContext* ctx,
FunctionContext::FunctionStateScope scope);

/// Implementation of the coordinator() function.
/// Returns the name of the host where the coordinator is running.
static StringVal Coordinator(FunctionContext* ctx);

/// Implementation of the typeOf() function. Returns the type of the input
/// expression. input_val is not used and it is kept here in order to let
/// the compiler generate the corresponding fully-qualified function name.
Expand Down
1 change: 1 addition & 0 deletions common/function-registry/impala_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ def symbol(class_name, fn_name, templated_type = None):
[['sleep'], 'BOOLEAN', ['INT'], 'impala::UtilityFunctions::Sleep'],
[['pid'], 'INT', [], 'impala::UtilityFunctions::Pid'],
[['version'], 'STRING', [], 'impala::UtilityFunctions::Version'],
[['coordinator'], 'STRING', [], 'impala::UtilityFunctions::Coordinator'],
[['typeOf'], 'STRING', ['BOOLEAN'], '_ZN6impala16UtilityFunctions6TypeOfIN10impala_udf10BooleanValEEENS2_9StringValEPNS2_15FunctionContextERKT_'],
[['typeOf'], 'STRING', ['TINYINT'], '_ZN6impala16UtilityFunctions6TypeOfIN10impala_udf10TinyIntValEEENS2_9StringValEPNS2_15FunctionContextERKT_'],
[['typeOf'], 'STRING', ['SMALLINT'], '_ZN6impala16UtilityFunctions6TypeOfIN10impala_udf11SmallIntValEEENS2_9StringValEPNS2_15FunctionContextERKT_'],
Expand Down
20 changes: 20 additions & 0 deletions docs/topics/impala_misc_functions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,26 @@ select uuid() from four_row_table;
</dd>

</dlentry>



<dlentry id="coordinator">
<dt>
<codeph>coordinator()</codeph>
</dt>

<dd>
<indexterm audience="hidden">coordinator() function</indexterm>
<b>Purpose:</b> Returns the name of the host which is running the
<codeph>impalad</codeph> daemon that is acting as the <codeph>coordinator</codeph>
for the curent query.
<p>
<b>Return type:</b> <codeph>string</codeph>
</p>
</dd>

</dlentry>

</dl>
</conbody>
</concept>
Original file line number Diff line number Diff line change
Expand Up @@ -3007,3 +3007,9 @@ in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
---- TYPES
bigint
====
---- QUERY
# test coordinator() function in a real query
select coordinator(), count(*) from functional.alltypesagg where int_col = 1
---- TYPES
string, bigint
====

0 comments on commit ab9e8b2

Please sign in to comment.