ClickHouse/dbms/tests/queries/0_stateless/00921_datetime64_compatibility.python
2019-10-21 17:04:01 +03:00

186 lines
5.6 KiB
Python
Executable File

#!/usr/bin/env python
# encoding: utf-8
import re
import itertools
import sys
# Create SQL statement to verify dateTime64 is accepted as argument to functions taking DateTime.
functions="""
toTimeZone({datetime}, 'UTC')
toYear({datetime})
toQuarter({datetime})
toMonth({datetime})
toDayOfYear({datetime})
toDayOfMonth({datetime})
toDayOfWeek({datetime})
toHour({datetime})
toMinute({datetime})
toSecond({datetime})
toUnixTimestamp({datetime})
toStartOfYear({datetime})
toStartOfISOYear({datetime})
toStartOfQuarter({datetime})
toStartOfMonth({datetime})
toMonday({datetime})
toStartOfWeek({datetime})
toStartOfDay({datetime})
toStartOfHour({datetime})
toStartOfMinute({datetime})
toStartOfFiveMinute({datetime})
toStartOfTenMinutes({datetime})
toStartOfFifteenMinutes({datetime})
toStartOfInterval({datetime}, INTERVAL 1 year)
toStartOfInterval({datetime}, INTERVAL 1 month)
toStartOfInterval({datetime}, INTERVAL 1 day)
toStartOfInterval({datetime}, INTERVAL 15 minute)
toTime({datetime})
toRelativeYearNum({datetime})
toRelativeQuarterNum({datetime})
toRelativeMonthNum({datetime})
toRelativeWeekNum({datetime})
toRelativeDayNum({datetime})
toRelativeHourNum({datetime})
toRelativeMinuteNum({datetime})
toRelativeSecondNum({datetime})
toISOYear({datetime})
toISOWeek({datetime})
toWeek({datetime})
toYearWeek({datetime})
timeSlot({datetime})
toYYYYMM({datetime})
toYYYYMMDD({datetime})
toYYYYMMDDhhmmss({datetime})
addYears({datetime}, 1)
addMonths({datetime}, 1)
addWeeks({datetime}, 1)
addDays({datetime}, 1)
addHours({datetime}, 1)
addMinutes({datetime}, 1)
addSeconds({datetime}, 1)
addQuarters({datetime}, 1)
subtractYears({datetime}, 1)
subtractMonths({datetime}, 1)
subtractWeeks({datetime}, 1)
subtractDays({datetime}, 1)
subtractHours({datetime}, 1)
subtractMinutes({datetime}, 1)
subtractSeconds({datetime}, 1)
subtractQuarters({datetime}, 1)
CAST({datetime} as DateTime)
CAST({datetime} as Date)
CAST({datetime} as UInt64)
CAST({datetime} as DateTime64(0))
CAST({datetime} as DateTime64(3))
CAST({datetime} as DateTime64(6))
CAST({datetime} as DateTime64(9))
CAST({datetime} as DateTime64(12))
CAST({datetime} as DateTime64(18))
formatDateTime({datetime}, '%C %d %D %e %F %H %I %j %m %M %n %p %R %S %t %T %u %V %w %y %Y %%')
""".splitlines()
# filter out empty lines and commented out lines
COMMENTED_OUT_LINE_RE = re.compile(r"^\s*#")
functions = list(filter(lambda f: len(f) != 0 and COMMENTED_OUT_LINE_RE.match(f) == None, functions))
# Expanded later to cartesian product of all arguments.
# NOTE: {N} to be turned into N after str.format() for keys (format string), but not for list of values!
extra_ops =\
[
# With same type:
(
['N {op} N'],
{
'op':
[
'- ', # does not work, but should it?
'+ ', # does not work, but should it?
'!=', '==', # equality and inequality supposed to take sub-second part in account
'< ',
'<=',
'> ',
'>='
]
}
),
# With other DateTime types:
(
[
'N {op} {arg}',
'{arg} {op} N'
],
{
'op':
[
'-', # does not work, but should it?
'!=', '==',
# these are naturally expected to work, but they don't:
'< ',
'<=',
'> ',
'>='
],
'arg': ['DT', 'D', 'DT64'],
}
),
# With arithmetic types
(
[
'N {op} {arg}',
'{arg} {op} N'
],
{
'op':
[
'+ ',
'- ',
'==',
'!=',
'< ',
'<=',
'> ',
'>='
],
'arg':
[
'toUInt8(1)',
'toInt8(-1)',
'toUInt16(1)',
'toInt16(-1)',
'toUInt32(1)',
'toInt32(-1)',
'toUInt64(1)',
'toInt64(-1)'
],
},
),
]
# Expand extra_ops here
for funcs, args in extra_ops:
args_keys = args.keys()
for args_vals in itertools.product(*args.values()):
for func in funcs:
result_func = func.format(**dict(zip(args_keys, args_vals)))
functions.append(result_func)
if sys.version_info[0] > 2:
escape_string_codec = 'unicode_escape'
else:
escape_string_codec = 'string-escape'
def escape_string(s):
return s.encode(escape_string_codec).decode('utf-8')
# TODO: use string.Template here to allow lines that do not contain type, like: SELECT CAST(toDateTime64(1234567890), 'DateTime64')
for func in functions:
func = func.format(datetime='N')
print("""SELECT 'SELECT {func}'""".format(func=escape_string(func))) # for debug only
for dt in ['D', 'DT', 'DT64']:
prologue = """WITH toDateTime64('2019-09-16 19:20:11.234', 3, 'Europe/Minsk') as DT64, toDateTime('2019-09-16 19:20:11', 'Europe/Minsk') as DT, toDate('2019-09-16') as D, {X} as N""".format(X=dt)
# dt64 = func.format(datetime=dt)
# f = "'values match:', ({dt32}) == ({dt64}), 'types match:', toTypeName({dt32}) == toTypeName({dt64})".format(dt32=dt32, dt64=dt64)
print("""{prologue} SELECT toTypeName(r), {func} as r""".format(prologue=prologue, func=func))
# print("""SELECT toTypeName(r), {dt64} as r""".format(dt64=dt64)) # for debug only
# print("""SELECT {f};""".format(f=f))
print("""SELECT '------------------------------------------'""") # for debug only