The purpose of making this .cc only is to avoid moving the code of CastDirection into the .h file
| 226 | // The purpose of making this .cc only is to avoid moving the code of |
| 227 | // CastDirection into the .h file |
| 228 | void UnixAndFromUnixPrepare(FunctionContext* context, |
| 229 | FunctionContext::FunctionStateScope scope, CastDirection cast_mode) { |
| 230 | if (scope != FunctionContext::THREAD_LOCAL) return; |
| 231 | DateTimeFormatContext* dt_ctx = NULL; |
| 232 | if (context->IsArgConstant(1)) { |
| 233 | StringVal fmt_val = *reinterpret_cast<StringVal*>(context->GetConstantArg(1)); |
| 234 | const StringValue& fmt_ref = StringValue::FromStringVal(fmt_val); |
| 235 | if (fmt_val.is_null || fmt_ref.Len() == 0) { |
| 236 | ReportBadFormat(context, datetime_parse_util::GENERAL_ERROR, fmt_val, true); |
| 237 | return; |
| 238 | } |
| 239 | dt_ctx = new DateTimeFormatContext(fmt_ref.Ptr(), fmt_ref.Len()); |
| 240 | bool parse_result = SimpleDateFormatTokenizer::Tokenize(dt_ctx, cast_mode); |
| 241 | if (!parse_result) { |
| 242 | delete dt_ctx; |
| 243 | ReportBadFormat(context, datetime_parse_util::GENERAL_ERROR, fmt_val, true); |
| 244 | return; |
| 245 | } |
| 246 | } else { |
| 247 | // If our format string is constant, then we benefit from it only being parsed once in |
| 248 | // the code above. If it's not constant, then we can reuse a context by resetting it. |
| 249 | // This is much cheaper vs alloc/dealloc'ing a context for each evaluation. |
| 250 | dt_ctx = new DateTimeFormatContext(); |
| 251 | } |
| 252 | dt_ctx->SetCenturyBreakAndCurrentTime(*context->impl()->state()->now()); |
| 253 | context->SetFunctionState(scope, dt_ctx); |
| 254 | } |
| 255 | |
| 256 | void TimestampFunctions::UnixAndFromUnixClose(FunctionContext* context, |
| 257 | FunctionContext::FunctionStateScope scope) { |
no test coverage detected