17 #include <boost/lexical_cast.hpp>
27 using namespace impala;
28 using namespace impala_udf;
35 #define CAST_FUNCTION(from_type, to_type) \
36 to_type CastFunctions::CastTo##to_type(FunctionContext* ctx, const from_type& val) { \
37 if (val.is_null) return to_type::null(); \
38 return to_type(val.val); \
90 #define CAST_FROM_STRING(num_type, native_type, string_parser_fn) \
91 num_type CastFunctions::CastTo##num_type(FunctionContext* ctx, const StringVal& val) { \
92 if (val.is_null) return num_type::null(); \
93 StringParser::ParseResult result; \
95 ret.val = StringParser::string_parser_fn<native_type>( \
96 reinterpret_cast<char*>(val.ptr), val.len, &result); \
97 if (UNLIKELY(result != StringParser::PARSE_SUCCESS)) return num_type::null(); \
108 #define CAST_TO_STRING(num_type) \
109 StringVal CastFunctions::CastToStringVal(FunctionContext* ctx, const num_type& val) { \
110 if (val.is_null) return StringVal::null(); \
111 ColumnType rtype = AnyValUtil::TypeDescToColumnType(ctx->GetReturnType()); \
112 StringVal sv = AnyValUtil::FromString(ctx, lexical_cast<string>(val.val)); \
113 AnyValUtil::TruncateIfNecessary(rtype, &sv); \
122 #define CAST_FLOAT_TO_STRING(float_type, format) \
123 StringVal CastFunctions::CastToStringVal(FunctionContext* ctx, const float_type& val) { \
124 if (val.is_null) return StringVal::null(); \
126 if (isnan(val.val)) return StringVal("nan"); \
128 StringVal sv(ctx, MAX_FLOAT_CHARS + 1); \
129 sv.len = snprintf(reinterpret_cast<char*>(sv.ptr), sv.len, format, val.val); \
130 DCHECK_GT(sv.len, 0); \
131 DCHECK_LE(sv.len, MAX_FLOAT_CHARS); \
132 ColumnType return_type = AnyValUtil::TypeDescToColumnType(ctx->GetReturnType()); \
133 AnyValUtil::TruncateIfNecessary(return_type, &sv); \
146 if (val.
is_null)
return StringVal::null();
147 int64_t tmp_val = val.
val;
155 if (val.
is_null)
return StringVal::null();
164 if (val.
is_null)
return StringVal::null();
174 if (val.
is_null)
return StringVal::null();
178 DCHECK_GE(type.
len, 1);
182 memcpy(cptr, val.
ptr, min(type.
len, val.
len));
185 cptr =
reinterpret_cast<char*
>(val.
ptr);
188 sv.
ptr =
reinterpret_cast<uint8_t*
>(cptr);
193 #define CAST_FROM_TIMESTAMP(to_type) \
194 to_type CastFunctions::CastTo##to_type( \
195 FunctionContext* ctx, const TimestampVal& val) { \
196 if (val.is_null) return to_type::null(); \
197 TimestampValue tv = TimestampValue::FromTimestampVal(val); \
198 if (!tv.HasDate()) return to_type::null(); \
199 return to_type(tv.ToUnixTime()); \
208 #define CAST_FROM_SUBSECOND_TIMESTAMP(to_type) \
209 to_type CastFunctions::CastTo##to_type( \
210 FunctionContext* ctx, const TimestampVal& val) { \
211 if (val.is_null) return to_type::null(); \
212 TimestampValue tv = TimestampValue::FromTimestampVal(val); \
213 if (!tv.HasDate()) return to_type::null(); \
214 return to_type(tv.ToSubsecondUnixTime()); \
220 #define CAST_TO_TIMESTAMP(from_type) \
221 TimestampVal CastFunctions::CastToTimestampVal(FunctionContext* ctx, \
222 const from_type& val) { \
223 if (val.is_null) return TimestampVal::null(); \
224 TimestampValue timestamp_value(val.val); \
225 if (!timestamp_value.HasDate()) return TimestampVal::null(); \
226 TimestampVal result; \
227 timestamp_value.ToTimestampVal(&result); \
241 if (val.
is_null)
return TimestampVal::null();
244 if (!timestamp_value.
HasDateOrTime())
return TimestampVal::null();
static void TruncateIfNecessary(const ColumnType &type, StringVal *val)
impala::FunctionContextImpl * impl()
TODO: Add mechanism for UDAs to update stats similar to runtime profile counters. ...
const TypeDesc & GetReturnType() const
#define CAST_TO_STRING(num_type)
static ColumnType TypeDescToColumnType(const FunctionContext::TypeDesc &type)
#define CAST_FUNCTION(from_type, to_type)
static TimestampVal CastToTimestampVal(FunctionContext *context, const BooleanVal &val)
#define CAST_FLOAT_TO_STRING(float_type, format)
bool HasDateOrTime() const
static void PadWithSpaces(char *cptr, int64_t cptr_len, int64_t num_chars)
#define CAST_TO_TIMESTAMP(from_type)
#define CAST_FROM_TIMESTAMP(to_type)
This object has a compatible storage format with boost::ptime.
static StringVal CastToChar(FunctionContext *context, const StringVal &val)
void ToTimestampVal(impala_udf::TimestampVal *tv) const
#define CAST_FROM_SUBSECOND_TIMESTAMP(to_type)
int len
Only set if type == TYPE_CHAR or type == TYPE_VARCHAR.
static StringVal FromString(FunctionContext *ctx, const std::string &s)
#define CAST_FROM_STRING(num_type, native_type, string_parser_fn)
static TimestampValue FromTimestampVal(const impala_udf::TimestampVal &udf_value)
uint8_t * AllocateLocal(int byte_size)
const int MAX_FLOAT_CHARS
static StringVal CastToStringVal(FunctionContext *context, const BooleanVal &val)