1#include <Functions/extractTimeZoneFromFunctionArguments.h>
2#include <Functions/FunctionHelpers.h>
3#include <Core/Block.h>
4#include <DataTypes/DataTypeDateTime.h>
5#include <DataTypes/DataTypeDateTime64.h>
6#include <Columns/ColumnString.h>
7#include <common/DateLUT.h>
8
9
10namespace DB
11{
12
13namespace ErrorCodes
14{
15 extern const int ILLEGAL_COLUMN;
16}
17
18
19static std::string extractTimeZoneNameFromColumn(const IColumn & column)
20{
21 const ColumnConst * time_zone_column = checkAndGetColumnConst<ColumnString>(&column);
22
23 if (!time_zone_column)
24 throw Exception("Illegal column " + column.getName()
25 + " of time zone argument of function, must be constant string",
26 ErrorCodes::ILLEGAL_COLUMN);
27
28 return time_zone_column->getValue<String>();
29}
30
31
32std::string extractTimeZoneNameFromFunctionArguments(const ColumnsWithTypeAndName & arguments, size_t time_zone_arg_num, size_t datetime_arg_num)
33{
34 /// Explicit time zone may be passed in last argument.
35 if (arguments.size() == time_zone_arg_num + 1 && arguments[time_zone_arg_num].column)
36 {
37 return extractTimeZoneNameFromColumn(*arguments[time_zone_arg_num].column);
38 }
39 else
40 {
41 if (!arguments.size())
42 return {};
43
44 /// If time zone is attached to an argument of type DateTime.
45 if (const DataTypeDateTime * type = checkAndGetDataType<DataTypeDateTime>(arguments[datetime_arg_num].type.get()))
46 return type->getTimeZone().getTimeZone();
47 if (const DataTypeDateTime64 * type = checkAndGetDataType<DataTypeDateTime64>(arguments[datetime_arg_num].type.get()))
48 return type->getTimeZone().getTimeZone();
49
50 return {};
51 }
52}
53
54const DateLUTImpl & extractTimeZoneFromFunctionArguments(Block & block, const ColumnNumbers & arguments, size_t time_zone_arg_num, size_t datetime_arg_num)
55{
56 if (arguments.size() == time_zone_arg_num + 1)
57 return DateLUT::instance(extractTimeZoneNameFromColumn(*block.getByPosition(arguments[time_zone_arg_num]).column));
58 else
59 {
60 if (!arguments.size())
61 return DateLUT::instance();
62
63 /// If time zone is attached to an argument of type DateTime.
64 if (const DataTypeDateTime * type = checkAndGetDataType<DataTypeDateTime>(block.getByPosition(arguments[datetime_arg_num]).type.get()))
65 return type->getTimeZone();
66
67 return DateLUT::instance();
68 }
69}
70
71}
72
73