-----------------------------------------------------------
SELECT '--- YYYYMMDDToDate';

SELECT 'Invalid input types are rejected';
SELECT YYYYMMDDToDate(); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
SELECT YYYYMMDDToDate(toDate('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate(toDate32('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate(toDateTime('2023-09-11 12:18:00')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate(toDateTime64('2023-09-11 12:18:00', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate('2023-09-11'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate(2023, 09, 11); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
SELECT YYYYMMDDToDate(2023, 110); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }

SELECT 'Result type is Date';
SELECT toTypeName(YYYYMMDDToDate(19910824));
SELECT toTypeName(YYYYMMDDToDate(cast(19910824 AS Nullable(UInt64))));

SELECT 'Check correctness, integer arguments';
SELECT YYYYMMDDToDate(19691231);
SELECT YYYYMMDDToDate(19700101);
SELECT YYYYMMDDToDate(20200229); -- leap day
SELECT YYYYMMDDToDate(20230911);
SELECT YYYYMMDDToDate(21490606);
SELECT YYYYMMDDToDate(21490607);
SELECT YYYYMMDDToDate(9223372036854775807); -- huge value

SELECT 'Check correctness, float arguments';
SELECT YYYYMMDDToDate(19691231.1);
SELECT YYYYMMDDToDate(19700101.1);
SELECT YYYYMMDDToDate(20200229.1); -- leap day
SELECT YYYYMMDDToDate(20230911.1);
SELECT YYYYMMDDToDate(21490606.1);
SELECT YYYYMMDDToDate(21490607.1);
SELECT YYYYMMDDToDate(NaN); -- { serverError BAD_ARGUMENTS }
SELECT YYYYMMDDToDate(Inf); -- { serverError BAD_ARGUMENTS }
SELECT YYYYMMDDToDate(-Inf); -- { serverError BAD_ARGUMENTS }

SELECT 'Check correctness, decimal arguments';
SELECT YYYYMMDDToDate(toDecimal64(19691231.1, 5));
SELECT YYYYMMDDToDate(toDecimal64(19700101.1, 5));
SELECT YYYYMMDDToDate(toDecimal64(20200229.1, 5)); -- leap day
SELECT YYYYMMDDToDate(toDecimal64(20230911.1, 5));
SELECT YYYYMMDDToDate(toDecimal64(21490606.1, 5));
SELECT YYYYMMDDToDate(toDecimal64(21490607.1, 5));

SELECT 'Special cases';
SELECT YYYYMMDDToDate(-20230911); -- negative
SELECT YYYYMMDDToDate(110); -- invalid everything
SELECT YYYYMMDDToDate(9999999999999); -- huge value
SELECT YYYYMMDDToDate(15001113); -- year out of range
SELECT YYYYMMDDToDate(35001113); -- year out of range
SELECT YYYYMMDDToDate(20231620); -- invalid month
SELECT YYYYMMDDToDate(20230020); -- invalid month
SELECT YYYYMMDDToDate(20230940); -- invalid day
SELECT YYYYMMDDToDate(20230900); -- invalid day
SELECT YYYYMMDDToDate(20230228); -- leap day when there is none
SELECT YYYYMMDDToDate(True);
SELECT YYYYMMDDToDate(False);
SELECT YYYYMMDDToDate(NULL);
SELECT YYYYMMDDToDate(yyyymmdd) FROM (SELECT 19840121 AS yyyymmdd UNION ALL SELECT 20230911 AS yyyymmdd) ORDER BY yyyymmdd; -- non-const

-----------------------------------------------------------
SELECT '--- YYYYMMDDToDate32';

SELECT 'Invalid input types are rejected';
SELECT YYYYMMDDToDate32(toDate('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate32(toDate32('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate32(toDateTime('2023-09-11 12:18:00')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate32(toDateTime64('2023-09-11 12:18:00', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate32('2023-09-11'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT YYYYMMDDToDate32(2023, 09, 11); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
SELECT YYYYMMDDToDate32(2023, 110); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }

SELECT 'Result type is Date32';
SELECT toTypeName(YYYYMMDDToDate32(19910824));
SELECT toTypeName(YYYYMMDDToDate32(cast(19910824 AS Nullable(UInt64))));

SELECT 'Check correctness, integer arguments';
SELECT YYYYMMDDToDate32(18991231);
SELECT YYYYMMDDToDate32(19000101);
SELECT YYYYMMDDToDate32(20200229); -- leap day
SELECT YYYYMMDDToDate32(20230911);
SELECT YYYYMMDDToDate32(22991231);
SELECT YYYYMMDDToDate32(23000101);
SELECT YYYYMMDDToDate32(9223372036854775807); -- huge value

SELECT 'Check correctness, float arguments';
SELECT YYYYMMDDToDate32(18991231.1);
SELECT YYYYMMDDToDate32(19000101.1);
SELECT YYYYMMDDToDate32(20200229.1); -- leap day
SELECT YYYYMMDDToDate32(20230911.1);
SELECT YYYYMMDDToDate32(22991231.1);
SELECT YYYYMMDDToDate32(23000101.1);
SELECT YYYYMMDDToDate32(NaN); -- { serverError BAD_ARGUMENTS }
SELECT YYYYMMDDToDate32(Inf); -- { serverError BAD_ARGUMENTS }
SELECT YYYYMMDDToDate32(-Inf); -- { serverError BAD_ARGUMENTS }

SELECT 'Check correctness, decimal arguments';
SELECT YYYYMMDDToDate32(toDecimal64(18991231.1, 5));
SELECT YYYYMMDDToDate32(toDecimal64(19000101.1, 5));
SELECT YYYYMMDDToDate32(toDecimal64(20200229.1, 5)); -- leap day
SELECT YYYYMMDDToDate32(toDecimal64(20230911.1, 5));
SELECT YYYYMMDDToDate32(toDecimal64(22991231.1, 5));
SELECT YYYYMMDDToDate32(toDecimal64(23000101.1, 5));

SELECT 'Special cases';
SELECT YYYYMMDDToDate32(-20230911); -- negative
SELECT YYYYMMDDToDate32(110); -- invalid everything
SELECT YYYYMMDDToDate32(9999999999999); -- huge value
SELECT YYYYMMDDToDate32(15001113); -- year out of range
SELECT YYYYMMDDToDate32(35001113); -- year out of range
SELECT YYYYMMDDToDate32(20231620); -- invalid month
SELECT YYYYMMDDToDate32(20230020); -- invalid month
SELECT YYYYMMDDToDate32(20230940); -- invalid day
SELECT YYYYMMDDToDate32(20230900); -- invalid day
SELECT YYYYMMDDToDate32(20230228); -- leap day when there is none
SELECT YYYYMMDDToDate32(True);
SELECT YYYYMMDDToDate32(False);
SELECT YYYYMMDDToDate32(NULL);
SELECT YYYYMMDDToDate32(yyyymmdd) FROM (SELECT 19840121 AS yyyymmdd UNION ALL SELECT 20230911 AS yyyymmdd) ORDER BY yyyymmdd; -- non-const
