Separate Date type from Datetime type. - Beginning from the parser to the operator execution level, treat Date type sepearately than the Datetime type. - Provide support for the extract function when applied on the Date type, implemented in the DateExtractOperation. - Modified the tests.
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/1d104229 Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/1d104229 Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/1d104229 Branch: refs/heads/partitioned-aggregation Commit: 1d10422913d7b2ea613c5853585fcea333534ec5 Parents: cdc1e05 Author: Harshad Deshmukh <hbdeshm...@apache.org> Authored: Mon Aug 29 14:03:52 2016 -0500 Committer: Harshad Deshmukh <hbdeshm...@apache.org> Committed: Mon Sep 5 11:02:26 2016 -0500 ---------------------------------------------------------------------- parser/SqlParser.ypp | 2 +- parser/tests/Select.test | 28 +-- parser/tests/TPCH.test | 47 ++-- .../tests/execution_generator/Insert.test | 19 ++ .../tests/execution_generator/Select.test | 32 +-- query_optimizer/tests/resolver/Select.test | 71 ++++-- types/DateOperatorOverloads.hpp | 63 ++++- types/DatetimeLit.hpp | 8 + .../binary_operations/AddBinaryOperation.cpp | 84 ++++++- .../operations/binary_operations/CMakeLists.txt | 2 + .../SubtractBinaryOperation.cpp | 81 +++++- .../tests/AddBinaryOperation_unittest.cpp | 23 +- .../tests/BinaryOperationTestUtil.hpp | 4 +- .../tests/SubtractBinaryOperation_unittest.cpp | 23 +- .../operations/unary_operations/CMakeLists.txt | 2 + .../unary_operations/DateExtractOperation.cpp | 246 ++++++++++++++++--- .../unary_operations/DateExtractOperation.hpp | 52 +++- .../tests/DateExtractOperation_unittest.cpp | 93 +++++-- 18 files changed, 708 insertions(+), 172 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/parser/SqlParser.ypp ---------------------------------------------------------------------- diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp index 3f0cc80..547bb40 100644 --- a/parser/SqlParser.ypp +++ b/parser/SqlParser.ypp @@ -760,7 +760,7 @@ data_type: YYERROR; } | TOKEN_DATE { - $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime)); + $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDate)); } | TOKEN_DATETIME { $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime)); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/parser/tests/Select.test ---------------------------------------------------------------------- diff --git a/parser/tests/Select.test b/parser/tests/Select.test index b614a99..8e47519 100644 --- a/parser/tests/Select.test +++ b/parser/tests/Select.test @@ -961,7 +961,7 @@ SelectStatement | | +-StringLiteral[value=1998-12-01] | +-SelectListItem | +-Literal - | +-StringLiteral[value=1998-12-01,explicit_type=Datetime] + | +-StringLiteral[value=1998-12-01,explicit_type=Date] +-from_clause= +-TableReference[table=test] == @@ -975,10 +975,10 @@ SelectStatement +-select_clause=SelectList | +-SelectListItem | | +-Literal - | | +-StringLiteral[value=1960-12-12,explicit_type=Datetime] + | | +-StringLiteral[value=1960-12-12,explicit_type=Date] | +-SelectListItem | +-Literal - | +-StringLiteral[value=1901-12-14,explicit_type=Datetime] + | +-StringLiteral[value=1901-12-14,explicit_type=Date] +-from_clause= +-TableReference[table=test] == @@ -990,10 +990,10 @@ SelectStatement +-select_clause=SelectList | +-SelectListItem | | +-Literal - | | +-StringLiteral[value=1998-2-12,explicit_type=Datetime] + | | +-StringLiteral[value=1998-2-12,explicit_type=Date] | +-SelectListItem | +-Literal - | +-StringLiteral[value=1998-12-2,explicit_type=Datetime] + | +-StringLiteral[value=1998-12-2,explicit_type=Date] +-from_clause= +-TableReference[table=test] == @@ -1007,10 +1007,10 @@ SelectStatement +-select_clause=SelectList | +-SelectListItem | | +-Literal - | | +-StringLiteral[value=+1921-12-12,explicit_type=Datetime] + | | +-StringLiteral[value=+1921-12-12,explicit_type=Date] | +-SelectListItem | +-Literal - | +-StringLiteral[value=+10001-12-12,explicit_type=Datetime] + | +-StringLiteral[value=+10001-12-12,explicit_type=Date] +-from_clause= +-TableReference[table=test] == @@ -1059,13 +1059,13 @@ SelectStatement +-select_clause=SelectList | +-SelectListItem | | +-Literal - | | +-StringLiteral[value=1996-02-29,explicit_type=Datetime] + | | +-StringLiteral[value=1996-02-29,explicit_type=Date] | +-SelectListItem | | +-Literal - | | +-StringLiteral[value=1997-03-31,explicit_type=Datetime] + | | +-StringLiteral[value=1997-03-31,explicit_type=Date] | +-SelectListItem | +-Literal - | +-StringLiteral[value=1998-04-30,explicit_type=Datetime] + | +-StringLiteral[value=1998-04-30,explicit_type=Date] +-from_clause= +-TableReference[table=test] == @@ -1077,9 +1077,9 @@ SELECT DATE '1999-02-29' FROM test ^ == -# Quickstep accepts time in the DATE type. -SELECT DATE '2007-05-08 12:35:29', - DATE '2007-05-08 12:35:29.010' +# Quickstep accepts time in the DATETIME type. +SELECT DATETIME '2007-05-08 12:35:29', + DATETIME '2007-05-08 12:35:29.010' FROM test -- SelectStatement @@ -1114,7 +1114,7 @@ SelectStatement | +-left_operand=AttributeReference[attribute_name=attr_date] | +-right_operand=Subtract | +-left_operand=Literal - | | +-StringLiteral[value=1998-12-01,explicit_type=Datetime] + | | +-StringLiteral[value=1998-12-01,explicit_type=Date] | +-right_operand=Literal | +-StringLiteral[value=96 day,explicit_type=DatetimeInterval] +-from_clause= http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/parser/tests/TPCH.test ---------------------------------------------------------------------- diff --git a/parser/tests/TPCH.test b/parser/tests/TPCH.test index e30d373..f0ffaa9 100644 --- a/parser/tests/TPCH.test +++ b/parser/tests/TPCH.test @@ -87,7 +87,7 @@ SelectStatement | +-left_operand=AttributeReference[attribute_name=l_shipdate] | +-right_operand=Subtract | +-left_operand=Literal - | | +-StringLiteral[value=1998-12-01,explicit_type=Datetime] + | | +-StringLiteral[value=1998-12-01,explicit_type=Date] | +-right_operand=Literal | +-StringLiteral[value=96 day,explicit_type=DatetimeInterval] +-group_by=GroupBy @@ -297,11 +297,11 @@ SelectStatement | +-Less | | +-left_operand=AttributeReference[attribute_name=o_orderdate] | | +-right_operand=Literal - | | +-StringLiteral[value=1995-03-17,explicit_type=Datetime] + | | +-StringLiteral[value=1995-03-17,explicit_type=Date] | +-Greater | +-left_operand=AttributeReference[attribute_name=l_shipdate] | +-right_operand=Literal - | +-StringLiteral[value=1995-03-17,explicit_type=Datetime] + | +-StringLiteral[value=1995-03-17,explicit_type=Date] +-group_by=GroupBy | +-AttributeReference[attribute_name=l_orderkey] | +-AttributeReference[attribute_name=o_orderdate] @@ -353,12 +353,12 @@ SelectStatement | +-GreaterOrEqual | | +-left_operand=AttributeReference[attribute_name=o_orderdate] | | +-right_operand=Literal - | | +-StringLiteral[value=1995-08-01,explicit_type=Datetime] + | | +-StringLiteral[value=1995-08-01,explicit_type=Date] | +-Less | | +-left_operand=AttributeReference[attribute_name=o_orderdate] | | +-right_operand=Add | | +-left_operand=Literal - | | | +-StringLiteral[value=1995-08-01,explicit_type=Datetime] + | | | +-StringLiteral[value=1995-08-01,explicit_type=Date] | | +-right_operand=Literal | | +-StringLiteral[value=3 month,explicit_type=YearMonthInterval] | +-Exists @@ -448,12 +448,12 @@ SelectStatement | +-GreaterOrEqual | | +-left_operand=AttributeReference[attribute_name=o_orderdate] | | +-right_operand=Literal - | | +-StringLiteral[value=1997-01-01,explicit_type=Datetime] + | | +-StringLiteral[value=1997-01-01,explicit_type=Date] | +-Less | +-left_operand=AttributeReference[attribute_name=o_orderdate] | +-right_operand=Add | +-left_operand=Literal - | | +-StringLiteral[value=1997-01-01,explicit_type=Datetime] + | | +-StringLiteral[value=1997-01-01,explicit_type=Date] | +-right_operand=Literal | +-StringLiteral[value=1 year,explicit_type=YearMonthInterval] +-group_by=GroupBy @@ -493,12 +493,12 @@ SelectStatement | +-GreaterOrEqual | | +-left_operand=AttributeReference[attribute_name=l_shipdate] | | +-right_operand=Literal - | | +-StringLiteral[value=1997-01-01,explicit_type=Datetime] + | | +-StringLiteral[value=1997-01-01,explicit_type=Date] | +-Less | | +-left_operand=AttributeReference[attribute_name=l_shipdate] | | +-right_operand=Add | | +-left_operand=Literal - | | | +-StringLiteral[value=1997-01-01,explicit_type=Datetime] + | | | +-StringLiteral[value=1997-01-01,explicit_type=Date] | | +-right_operand=Literal | | +-StringLiteral[value=1 year,explicit_type=YearMonthInterval] | +-Between @@ -649,9 +649,9 @@ SelectStatement | +-Between | +-check_operand=AttributeReference[attribute_name=l_shipdate] | +-lower_bound_operand=Literal - | | +-StringLiteral[value=1995-01-01,explicit_type=Datetime] + | | +-StringLiteral[value=1995-01-01,explicit_type=Date] | +-upper_bound_operand=Literal - | +-StringLiteral[value=1996-12-31,explicit_type=Datetime] + | +-StringLiteral[value=1996-12-31,explicit_type=Date] +-from_clause= +-TableReference[table=supplier] +-TableReference[table=lineitem] @@ -777,9 +777,9 @@ SelectStatement | +-Between | | +-check_operand=AttributeReference[attribute_name=o_orderdate] | | +-lower_bound_operand=Literal - | | | +-StringLiteral[value=1995-01-01,explicit_type=Datetime] + | | | +-StringLiteral[value=1995-01-01,explicit_type=Date] | | +-upper_bound_operand=Literal - | | +-StringLiteral[value=1996-12-31,explicit_type=Datetime] + | | +-StringLiteral[value=1996-12-31,explicit_type=Date] | +-Equal | +-left_operand=AttributeReference[attribute_name=p_type] | +-right_operand=Literal @@ -973,12 +973,12 @@ SelectStatement | +-GreaterOrEqual | | +-left_operand=AttributeReference[attribute_name=o_orderdate] | | +-right_operand=Literal - | | +-StringLiteral[value=1994-03-01,explicit_type=Datetime] + | | +-StringLiteral[value=1994-03-01,explicit_type=Date] | +-Less | | +-left_operand=AttributeReference[attribute_name=o_orderdate] | | +-right_operand=Add | | +-left_operand=Literal - | | | +-StringLiteral[value=1994-03-01,explicit_type=Datetime] + | | | +-StringLiteral[value=1994-03-01,explicit_type=Date] | | +-right_operand=Literal | | +-StringLiteral[value=3 month,explicit_type=YearMonthInterval] | +-Equal @@ -1198,12 +1198,12 @@ SelectStatement | +-GreaterOrEqual | | +-left_operand=AttributeReference[attribute_name=l_receiptdate] | | +-right_operand=Literal - | | +-StringLiteral[value=1997-01-01,explicit_type=Datetime] + | | +-StringLiteral[value=1997-01-01,explicit_type=Date] | +-Less | +-left_operand=AttributeReference[attribute_name=l_receiptdate] | +-right_operand=Add | +-left_operand=Literal - | | +-StringLiteral[value=1997-01-01,explicit_type=Datetime] + | | +-StringLiteral[value=1997-01-01,explicit_type=Date] | +-right_operand=Literal | +-StringLiteral[value=1 year,explicit_type=YearMonthInterval] +-group_by=GroupBy @@ -1335,12 +1335,12 @@ SelectStatement | +-GreaterOrEqual | | +-left_operand=AttributeReference[attribute_name=l_shipdate] | | +-right_operand=Literal - | | +-StringLiteral[value=1994-11-01,explicit_type=Datetime] + | | +-StringLiteral[value=1994-11-01,explicit_type=Date] | +-Less | +-left_operand=AttributeReference[attribute_name=l_shipdate] | +-right_operand=Add | +-left_operand=Literal - | | +-StringLiteral[value=1994-11-01,explicit_type=Datetime] + | | +-StringLiteral[value=1994-11-01,explicit_type=Date] | +-right_operand=Literal | +-StringLiteral[value=1 month,explicit_type=YearMonthInterval] +-from_clause= @@ -1433,12 +1433,12 @@ SelectStatement | +-GreaterOrEqual | | +-left_operand=AttributeReference[attribute_name=l_shipdate] | | +-right_operand=Literal - | | +-StringLiteral[value=1996-11-01,explicit_type=Datetime] + | | +-StringLiteral[value=1996-11-01,explicit_type=Date] | +-Less | +-left_operand=AttributeReference[attribute_name=l_shipdate] | +-right_operand=Add | +-left_operand=Literal - | | +-StringLiteral[value=1996-11-01,explicit_type=Datetime] + | | +-StringLiteral[value=1996-11-01,explicit_type=Date] | +-right_operand=Literal | +-StringLiteral[value=3 month,explicit_type=YearMonthInterval] +-group_by=GroupBy @@ -1996,14 +1996,13 @@ SelectStatement | | | | | +-left_operand=AttributeReference[ | | | | | | attribute_name=l_shipdate] | | | | | +-right_operand=Literal - | | | | | +-StringLiteral[value=1993-01-01,explicit_type=Datetime] + | | | | | +-StringLiteral[value=1993-01-01,explicit_type=Date] | | | | +-Less | | | | +-left_operand=AttributeReference[ | | | | | attribute_name=l_shipdate] | | | | +-right_operand=Add | | | | +-left_operand=Literal - | | | | | +-StringLiteral[value=1993-01-01, - | | | | | explicit_type=Datetime] + | | | | | +-StringLiteral[value=1993-01-01,explicit_type=Date] | | | | +-right_operand=Literal | | | | +-StringLiteral[value=1 year, | | | | explicit_type=YearMonthInterval] http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/query_optimizer/tests/execution_generator/Insert.test ---------------------------------------------------------------------- diff --git a/query_optimizer/tests/execution_generator/Insert.test b/query_optimizer/tests/execution_generator/Insert.test index 152e2a3..1be7be9 100644 --- a/query_optimizer/tests/execution_generator/Insert.test +++ b/query_optimizer/tests/execution_generator/Insert.test @@ -103,6 +103,25 @@ FROM generate_series(1, 5) AS gs(i); SELECT * FROM bar3; -- ++-----------+------------+------------------------+--------------------------------+ +|x |y |z |w | ++-----------+------------+------------------------+--------------------------------+ +| 1| 2016-01-01| NULL| abc| +| 2| 2016-01-01| NULL| abc| +| 3| 2016-01-01| NULL| abc| +| 4| 2016-01-01| NULL| abc| +| 5| 2016-01-01| NULL| abc| ++-----------+------------+------------------------+--------------------------------+ +== + +CREATE TABLE bar4 (x INT, y DATETIME, z DOUBLE NULL, w VARCHAR(32)); + +INSERT INTO bar4 +SELECT i, DATETIME '2016-1-1T00:00:00', NULL, 'abc' +FROM generate_series(1, 5) AS gs(i); + +SELECT * FROM bar4; +-- +-----------+-----------------------------------------+------------------------+--------------------------------+ |x |y |z |w | +-----------+-----------------------------------------+------------------------+--------------------------------+ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/query_optimizer/tests/execution_generator/Select.test ---------------------------------------------------------------------- diff --git a/query_optimizer/tests/execution_generator/Select.test b/query_optimizer/tests/execution_generator/Select.test index 7d662e9..494e759 100644 --- a/query_optimizer/tests/execution_generator/Select.test +++ b/query_optimizer/tests/execution_generator/Select.test @@ -482,20 +482,20 @@ SELECT DATE '2000-02-29' + INTERVAL '1 year', DATE '1998-03-31' + INTERVAL '1 month', DATE '2000-03-31' - INTERVAL '1 month', DATE '2000-01-31' + INTERVAL '1 month', - DATE '2000-02-29' + INTERVAL '1 day', + DATETIME '2000-02-29' + INTERVAL '1 day', DATE '2000-02-29' - INTERVAL '1 year' FROM test WHERE int_col = 2; -- -+----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ -|(Datetime('2000-02-29')+YearMonthInterval('1 year'))|(Datetime('1998-03-31')+YearMonthInterval('1 month'))|(Datetime('2000-03-31')-YearMonthInterval('1 month'))|(Datetime('2000-01-31')+YearMonthInterval('1 month'))|(Datetime('2000-02-29')+DatetimeInterval('1 day'))|(Datetime('2000-02-29')-YearMonthInterval('1 year'))| -+----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ -| 2001-02-28T00:00:00| 1998-04-30T00:00:00| 2000-02-29T00:00:00| 2000-02-29T00:00:00| 2000-03-01T00:00:00| 1999-02-28T00:00:00| -+----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ ++------------------------------------------------+-------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+------------------------------------------------+ +|(Date('2000-02-29')+YearMonthInterval('1 year'))|(Date('1998-03-31')+YearMonthInterval('1 month'))|(Date('2000-03-31')-YearMonthInterval('1 month'))|(Date('2000-01-31')+YearMonthInterval('1 month'))|(Datetime('2000-02-29')+DatetimeInterval('1 day'))|(Date('2000-02-29')-YearMonthInterval('1 year'))| ++------------------------------------------------+-------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+------------------------------------------------+ +| 2001-02-28| 1998-04-30| 2000-02-29| 2000-02-29| 2000-03-01T00:00:00| 1999-02-28| ++------------------------------------------------+-------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+------------------------------------------------+ == -SELECT DATE '2000-02-29' - DATE '2000-02-28', - DATE '2000-02-29' - DATE '1999-02-28' +SELECT DATETIME '2000-02-29' - DATETIME '2000-02-28', + DATETIME '2000-02-29' - DATETIME '1999-02-28' FROM test WHERE int_col = 2; -- @@ -524,11 +524,11 @@ SELECT DATE '+1980-02-29' + INTERVAL '1 year' FROM test WHERE int_col = 2; -- -+-----------------------------------------------------+ -|(Datetime('+1980-02-29')+YearMonthInterval('1 year'))| -+-----------------------------------------------------+ -| 1981-02-28T00:00:00| -+-----------------------------------------------------+ ++-------------------------------------------------+ +|(Date('+1980-02-29')+YearMonthInterval('1 year'))| ++-------------------------------------------------+ +| 1981-02-28| ++-------------------------------------------------+ == SELECT int_col @@ -633,9 +633,9 @@ ORDER BY group_col1, CREATE TABLE dates (value DATETIME); -INSERT INTO dates VALUES (DATE '2016-01-02 10:20:30'); -INSERT INTO dates VALUES (DATE '2016-02-03 11:21:31'); -INSERT INTO dates VALUES (DATE '2016-03-04 12:22:32'); +INSERT INTO dates VALUES (DATETIME '2016-01-02 10:20:30'); +INSERT INTO dates VALUES (DATETIME '2016-02-03 11:21:31'); +INSERT INTO dates VALUES (DATETIME '2016-03-04 12:22:32'); SELECT EXTRACT(YEAR FROM value) * 10000 + EXTRACT(MONTH FROM value) * 100 + http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/query_optimizer/tests/resolver/Select.test ---------------------------------------------------------------------- diff --git a/query_optimizer/tests/resolver/Select.test b/query_optimizer/tests/resolver/Select.test index 7033dec..facb3a1 100644 --- a/query_optimizer/tests/resolver/Select.test +++ b/query_optimizer/tests/resolver/Select.test @@ -2148,10 +2148,10 @@ name ,relation=,type=Float] == -select date '1998-12-12' + interval '5 day', +select datetime '1998-12-12' + interval '5 day', date '1998-12-12' - interval '5 month', interval '5 year' + date '1998-12-12', - date '1998-12-12' - date '1998-12-11', + datetime '1998-12-12' - datetime '1998-12-11', interval '10 day' + interval '11 day', interval '30 month' + interval '1 year', interval '30 month' - interval '1 year' @@ -2172,18 +2172,16 @@ TopLevelPlan | | +-Add | | +-Literal[value=1998-12-12T00:00:00,type=Datetime] | | +-Literal[value=5 days 00:00:00,type=DatetimeInterval] -| +-Alias[id=7,name=, -| | alias=(Datetime('1998-12-12')-YearMonthInterval('5 month')),relation=, -| | type=Datetime] +| +-Alias[id=7,name=,alias=(Date('1998-12-12')-YearMonthInterval('5 month')), +| | relation=,type=Date] | | +-Subtract -| | +-Literal[value=1998-12-12T00:00:00,type=Datetime] +| | +-Literal[value=1998-12-12,type=Date] | | +-Literal[value=5 mons,type=YearMonthInterval] -| +-Alias[id=8,name=, -| | alias=(YearMonthInterval('5 year')+Datetime('1998-12-12')),relation=, -| | type=Datetime] +| +-Alias[id=8,name=,alias=(YearMonthInterval('5 year')+Date('1998-12-12')), +| | relation=,type=Date] | | +-Add | | +-Literal[value=5 years,type=YearMonthInterval] -| | +-Literal[value=1998-12-12T00:00:00,type=Datetime] +| | +-Literal[value=1998-12-12,type=Date] | +-Alias[id=9,name=,alias=(Datetime('1998-12-12')-Datetime('1998-12-11')), | | relation=,type=DatetimeInterval] | | +-Subtract @@ -2212,11 +2210,9 @@ TopLevelPlan | alias=(Datetime('1998-12-12')+DatetimeInterval('5 day')),relation=, | type=Datetime] +-AttributeReference[id=7,name=, - | alias=(Datetime('1998-12-12')-YearMonthInterval('5 month')),relation=, - | type=Datetime] + | alias=(Date('1998-12-12')-YearMonthInterval('5 month')),relation=,type=Date] +-AttributeReference[id=8,name=, - | alias=(YearMonthInterval('5 year')+Datetime('1998-12-12')),relation=, - | type=Datetime] + | alias=(YearMonthInterval('5 year')+Date('1998-12-12')),relation=,type=Date] +-AttributeReference[id=9,name=, | alias=(Datetime('1998-12-12')-Datetime('1998-12-11')),relation=, | type=DatetimeInterval] @@ -2270,9 +2266,9 @@ TopLevelPlan relation=,type=YearMonthInterval] == -SELECT EXTRACT(YEAR FROM DATE '2016-01-02 10:20:30') * 10000 + - EXTRACT(MONTH FROM DATE '2016-01-02 10:20:30') * 100 + - EXTRACT(DAY FROM DATE '2016-01-02 10:20:30') AS date_digits +SELECT EXTRACT(YEAR FROM DATETIME '2016-01-02 10:20:30') * 10000 + + EXTRACT(MONTH FROM DATETIME '2016-01-02 10:20:30') * 100 + + EXTRACT(DAY FROM DATETIME '2016-01-02 10:20:30') AS date_digits FROM generate_series(1, 1); -- TopLevelPlan @@ -2445,27 +2441,51 @@ select interval '4 day' + interval '5 year' select date '1998-12-12' + date '1998-12-12' from test -- -ERROR: Can not apply binary operation "Add" to arguments of types Datetime and Datetime (1 : 26) +ERROR: Can not apply binary operation "Add" to arguments of types Date and Date (1 : 26) select date '1998-12-12' + date '1998-12-12' ^ == +select datetime '1998-12-12' + datetime '1998-12-12' +from test +-- +ERROR: Can not apply binary operation "Add" to arguments of types Datetime and Datetime (1 : 30) +select datetime '1998-12-12' + datetime '1998-12-12' + ^ +== + select date '1998-12-12' * date '1998-12-12' from test -- -ERROR: Can not apply binary operation "Multiply" to arguments of types Datetime and Datetime (1 : 26) +ERROR: Can not apply binary operation "Multiply" to arguments of types Date and Date (1 : 26) select date '1998-12-12' * date '1998-12-12' ^ == +select datetime '1998-12-12' * datetime '1998-12-12' +from test +-- +ERROR: Can not apply binary operation "Multiply" to arguments of types Datetime and Datetime (1 : 30) +select datetime '1998-12-12' * datetime '1998-12-12' + ^ +== + select interval '5 day' - date '1998-12-12' from test -- -ERROR: Can not apply binary operation "Subtract" to arguments of types DatetimeInterval and Datetime (1 : 25) +ERROR: Can not apply binary operation "Subtract" to arguments of types DatetimeInterval and Date (1 : 25) select interval '5 day' - date '1998-12-12' ^ == +select interval '5 day' - datetime '1998-12-12' +from test +-- +ERROR: Can not apply binary operation "Subtract" to arguments of types DatetimeInterval and Datetime (1 : 25) +select interval '5 day' - datetime '1998-12-12' + ^ +== + select (interval '10 day' + interval '3 day') + 5 from test -- @@ -2477,11 +2497,20 @@ ERROR: Can not apply binary operation "Add" to arguments of types DatetimeInterv select 5 / (date '1999-10-12' + yearmonth interval '10 year') from test -- -ERROR: Can not apply binary operation "Divide" to arguments of types Int and Datetime (1 : 10) +ERROR: Can not apply binary operation "Divide" to arguments of types Int and Date (1 : 10) select 5 / (date '1999-10-12' + yearmont... ^ == +select 5 / (datetime '1999-10-12' + yearmonth interval '10 year') +from test +-- +ERROR: Can not apply binary operation "Divide" to arguments of types Int and Datetime (1 : 10) +select 5 / (datetime '1999-10-12' + yearmont... + ^ +== + + # CASE expressions. SELECT CASE int_col%2 WHEN 1 THEN 'odd' http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/DateOperatorOverloads.hpp ---------------------------------------------------------------------- diff --git a/types/DateOperatorOverloads.hpp b/types/DateOperatorOverloads.hpp index 5cf8990..b04f44e 100644 --- a/types/DateOperatorOverloads.hpp +++ b/types/DateOperatorOverloads.hpp @@ -20,6 +20,7 @@ #ifndef QUICKSTEP_TYPES_DATE_BINARY_OPERATORS_HPP_ #define QUICKSTEP_TYPES_DATE_BINARY_OPERATORS_HPP_ +#include <cstdint> #include <ctime> #include "types/DatetimeLit.hpp" @@ -36,7 +37,29 @@ namespace quickstep { */ // Month arithmetic clamps to the actual last day of a given month. -inline void ClampDayOfMonth(struct tm *timeinfo) { +inline int ClampDayOfMonth(const int year, const int month, const int day) { + DCHECK_LT(day, 32); + switch (month) { + case 2: { + const int days_in_february = + (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ? 29 + : 28; + return (day > days_in_february) ? days_in_february : day; + } + case 4: + case 6: + case 9: + case 11: { + return day == 31 ? 30 : day; + } + default: + return day; + } +} + +// We have a separate function here because timeinfo's months begin from 0. +inline void ClampDayOfMonthStructTM(struct tm *timeinfo) { DCHECK_LT(timeinfo->tm_mday, 32); switch (timeinfo->tm_mon) { case 1: { @@ -87,7 +110,7 @@ inline DatetimeLit operator+(const DatetimeLit &lhs, const YearMonthIntervalLit ++timeinfo.tm_year; } - ClampDayOfMonth(&timeinfo); + ClampDayOfMonthStructTM(&timeinfo); DatetimeLit datetime(DatetimeLit::FromEpochTime(quickstep::timegm(&timeinfo))); datetime.ticks += lhs.subseconds(); @@ -98,6 +121,25 @@ inline DatetimeLit operator+(const YearMonthIntervalLit &lhs, const DatetimeLit return rhs + lhs; } +inline DateLit operator+(const DateLit &lhs, const YearMonthIntervalLit &rhs) { + std::int32_t result_year = lhs.year + (rhs.months / 12); + std::uint8_t result_month = lhs.month + (rhs.months % 12); + + if (result_month > 11) { + result_month -= 12; + ++result_year; + } + + const std::uint8_t result_day = static_cast<std::uint8_t>( + ClampDayOfMonth(result_year, result_month, lhs.day)); + + return DateLit::Create(result_year, result_month, result_day); +} + +inline DateLit operator+(const YearMonthIntervalLit &lhs, const DateLit &rhs) { + return rhs + lhs; +} + inline DatetimeIntervalLit operator+(const DatetimeIntervalLit &lhs, const DatetimeIntervalLit &rhs) { DatetimeIntervalLit interval(lhs); interval += rhs; @@ -137,13 +179,28 @@ inline DatetimeLit operator-(const DatetimeLit &lhs, const YearMonthIntervalLit timeinfo.tm_mon += 12; } - ClampDayOfMonth(&timeinfo); + ClampDayOfMonthStructTM(&timeinfo); DatetimeLit datetime(DatetimeLit::FromEpochTime(quickstep::timegm(&timeinfo))); datetime.ticks += lhs.subseconds(); return datetime; // Datetime in GMT. } +inline DateLit operator-(const DateLit &lhs, const YearMonthIntervalLit &rhs) { + std::int32_t result_year = lhs.year - (rhs.months / 12); + std::int8_t result_month = lhs.month - (rhs.months % 12); + + if (result_month < 0) { + --result_year; + result_month += 12; + } + + const std::uint8_t result_day = static_cast<std::uint8_t>( + ClampDayOfMonth(result_year, result_month, lhs.day)); + + return DateLit::Create(result_year, result_month, result_day); +} + inline DatetimeIntervalLit operator-(const DatetimeIntervalLit &lhs, const DatetimeIntervalLit &rhs) { DatetimeIntervalLit interval(lhs); interval -= rhs; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/DatetimeLit.hpp ---------------------------------------------------------------------- diff --git a/types/DatetimeLit.hpp b/types/DatetimeLit.hpp index 580a0ed..58c852f 100644 --- a/types/DatetimeLit.hpp +++ b/types/DatetimeLit.hpp @@ -91,6 +91,14 @@ struct DateLit { inline bool operator!=(const DateLit& rhs) const { return !(*this == rhs); } + + inline std::int32_t yearField() const { + return year; + } + + inline std::int32_t monthField() const { + return static_cast<std::int32_t>(month); + } }; /** http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/binary_operations/AddBinaryOperation.cpp ---------------------------------------------------------------------- diff --git a/types/operations/binary_operations/AddBinaryOperation.cpp b/types/operations/binary_operations/AddBinaryOperation.cpp index 2ee551b..8f56a61 100644 --- a/types/operations/binary_operations/AddBinaryOperation.cpp +++ b/types/operations/binary_operations/AddBinaryOperation.cpp @@ -23,8 +23,9 @@ #include <utility> #include "types/DateOperatorOverloads.hpp" -#include "types/DatetimeLit.hpp" +#include "types/DateType.hpp" #include "types/DatetimeIntervalType.hpp" +#include "types/DatetimeLit.hpp" #include "types/DatetimeType.hpp" #include "types/IntervalLit.hpp" #include "types/Type.hpp" @@ -47,6 +48,9 @@ bool AddBinaryOperation::canApplyToTypes(const Type &left, const Type &right) co case kDouble: { return (right.getSuperTypeID() == Type::kNumeric); } + case kDate: { + return (right.getTypeID() == kYearMonthInterval); + } case kDatetime: { return (right.getTypeID() == kDatetimeInterval || right.getTypeID() == kYearMonthInterval); @@ -56,7 +60,8 @@ bool AddBinaryOperation::canApplyToTypes(const Type &left, const Type &right) co right.getTypeID() == kDatetimeInterval); } case kYearMonthInterval: { - return (right.getTypeID() == kDatetime || + return (right.getTypeID() == kDate || + right.getTypeID() == kDatetime || right.getTypeID() == kYearMonthInterval); } default: @@ -72,6 +77,9 @@ const Type* AddBinaryOperation::resultTypeForArgumentTypes(const Type &left, con (left.getTypeID() == kDatetime && right.getTypeID() == kYearMonthInterval) || (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kDatetime)) { return &(DatetimeType::Instance(left.isNullable() || right.isNullable())); + } else if ((left.getTypeID() == kDate && right.getTypeID() == kYearMonthInterval) || + (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kDate)) { + return &(DateType::Instance(left.isNullable() || right.isNullable())); } else if (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval) { return &(DatetimeIntervalType::Instance(left.isNullable() || right.isNullable())); } else if (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval) { @@ -102,6 +110,10 @@ const Type* AddBinaryOperation::resultTypeForPartialArgumentTypes(const Type *le // Datetime can be added with either interval type, and always yields // Datetime. return &TypeFactory::GetType(kDatetime, true); + case kDate: + // Date can be added with YearMonthInterval type only, and always yields + // Date. + return &TypeFactory::GetType(kDate, true); default: // Ambiguous or inapplicable. return nullptr; @@ -121,9 +133,15 @@ bool AddBinaryOperation::partialTypeSignatureIsPlausible( // Type is not plausible with unknown arguments. return false; } else { - return QUICKSTEP_EQUALS_ANY_CONSTANT( - result_type->getTypeID(), - kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval); + return QUICKSTEP_EQUALS_ANY_CONSTANT(result_type->getTypeID(), + kInt, + kLong, + kFloat, + kDouble, + kDate, + kDatetime, + kDatetimeInterval, + kYearMonthInterval); } } @@ -148,9 +166,15 @@ bool AddBinaryOperation::partialTypeSignatureIsPlausible( ? left_argument_type : right_argument_type; if (result_type == nullptr) { - return QUICKSTEP_EQUALS_ANY_CONSTANT( - known_argument_type->getTypeID(), - kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval); + return QUICKSTEP_EQUALS_ANY_CONSTANT(known_argument_type->getTypeID(), + kInt, + kLong, + kFloat, + kDouble, + kDate, + kDatetime, + kDatetimeInterval, + kYearMonthInterval); } if (!result_type->isNullable()) { @@ -176,10 +200,12 @@ bool AddBinaryOperation::partialTypeSignatureIsPlausible( return QUICKSTEP_EQUALS_ANY_CONSTANT( known_argument_type->getTypeID(), kInt, kLong, kFloat, kDouble); + case kDate: + return (known_argument_type->getTypeID() == kDate); case kDatetime: return QUICKSTEP_EQUALS_ANY_CONSTANT( known_argument_type->getTypeID(), - kDatetime, kDatetimeInterval, kYearMonthInterval); + kDatetime, kDatetimeInterval); case kDatetimeInterval: return (known_argument_type->getTypeID() == kDatetimeInterval); case kYearMonthInterval: @@ -208,6 +234,10 @@ std::pair<const Type*, const Type*> AddBinaryOperation::pushDownTypeHint( // choose the highest-precision suitable Type (i.e. the same as the // result type) in such cases. return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint); + case kDate: + // Hint is ambiguous: one argument should be a Date, other has to be + // kYearMonthInterval, but order is not important. + return std::pair<const Type*, const Type*>(nullptr, nullptr); case kDatetime: // Hint is ambiguous: one argument should be a Datetime, the other should // be one of the interval types, but either order is acceptable. @@ -242,6 +272,16 @@ TypedValue AddBinaryOperation::applyToChecked(const TypedValue &left, } break; } + case kDate: { + if (right_type.getTypeID() == kYearMonthInterval) { + if (left.isNull() || right.isNull()) { + return TypedValue(kDate); + } + + return TypedValue(left.getLiteral<DateLit>() + right.getLiteral<YearMonthIntervalLit>()); + } + break; + } case kDatetime: { if (right_type.getTypeID() == kDatetimeInterval) { if (left.isNull() || right.isNull()) { @@ -275,7 +315,13 @@ TypedValue AddBinaryOperation::applyToChecked(const TypedValue &left, break; } case kYearMonthInterval: { - if (right_type.getTypeID() == kDatetime) { + if (right_type.getTypeID() == kDate) { + if (left.isNull() || right.isNull()) { + return TypedValue(kDatetime); + } + + return TypedValue(left.getLiteral<YearMonthIntervalLit>() + right.getLiteral<DateLit>()); + } else if (right_type.getTypeID() == kDatetime) { if (left.isNull() || right.isNull()) { return TypedValue(kDatetime); } @@ -310,6 +356,16 @@ UncheckedBinaryOperator* AddBinaryOperation::makeUncheckedBinaryOperatorForTypes } break; } + case kDate: { + if (right.getTypeID() == kYearMonthInterval) { + return makeDateBinaryOperatorOuterHelper< + AddArithmeticUncheckedBinaryOperator, + DateType, + DateLit, + YearMonthIntervalLit>(left, right); + } + break; + } case kDatetime: { if (right.getTypeID() == kDatetimeInterval) { return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator, @@ -335,7 +391,13 @@ UncheckedBinaryOperator* AddBinaryOperation::makeUncheckedBinaryOperatorForTypes break; } case kYearMonthInterval: { - if (right.getTypeID() == kDatetime) { + if (right.getTypeID() == kDate) { + return makeDateBinaryOperatorOuterHelper< + AddArithmeticUncheckedBinaryOperator, + DateType, + YearMonthIntervalLit, + DateLit>(left, right); + } else if (right.getTypeID() == kDatetime) { return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator, DatetimeType, YearMonthIntervalLit, DatetimeLit>(left, right); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/binary_operations/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/types/operations/binary_operations/CMakeLists.txt b/types/operations/binary_operations/CMakeLists.txt index 071e9fb..4d26b75 100644 --- a/types/operations/binary_operations/CMakeLists.txt +++ b/types/operations/binary_operations/CMakeLists.txt @@ -51,6 +51,7 @@ add_library(quickstep_types_operations_binaryoperations_SubtractBinaryOperation target_link_libraries(quickstep_types_operations_binaryoperations_AddBinaryOperation glog quickstep_types_DateOperatorOverloads + quickstep_types_DateType quickstep_types_DatetimeIntervalType quickstep_types_DatetimeLit quickstep_types_DatetimeType @@ -164,6 +165,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_MultiplyBinary target_link_libraries(quickstep_types_operations_binaryoperations_SubtractBinaryOperation glog quickstep_types_DateOperatorOverloads + quickstep_types_DateType quickstep_types_DatetimeIntervalType quickstep_types_DatetimeLit quickstep_types_DatetimeType http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/binary_operations/SubtractBinaryOperation.cpp ---------------------------------------------------------------------- diff --git a/types/operations/binary_operations/SubtractBinaryOperation.cpp b/types/operations/binary_operations/SubtractBinaryOperation.cpp index fe8644a..53e4266 100644 --- a/types/operations/binary_operations/SubtractBinaryOperation.cpp +++ b/types/operations/binary_operations/SubtractBinaryOperation.cpp @@ -23,8 +23,9 @@ #include <utility> #include "types/DateOperatorOverloads.hpp" -#include "types/DatetimeLit.hpp" +#include "types/DateType.hpp" #include "types/DatetimeIntervalType.hpp" +#include "types/DatetimeLit.hpp" #include "types/DatetimeType.hpp" #include "types/IntervalLit.hpp" #include "types/Type.hpp" @@ -47,6 +48,9 @@ bool SubtractBinaryOperation::canApplyToTypes(const Type &left, const Type &righ case kDouble: { return (right.getSuperTypeID() == Type::kNumeric); } + case kDate: { + return (right.getTypeID() == kYearMonthInterval); + } case kDatetime: { return (right.getTypeID() == kDatetime || right.getTypeID() == kDatetimeInterval || @@ -56,7 +60,8 @@ bool SubtractBinaryOperation::canApplyToTypes(const Type &left, const Type &righ return (right.getTypeID() == kDatetimeInterval); } case kYearMonthInterval: { - return (right.getTypeID() == kYearMonthInterval); + return (right.getTypeID() == kYearMonthInterval || + right.getTypeID() == kDate); } default: return false; @@ -66,6 +71,9 @@ bool SubtractBinaryOperation::canApplyToTypes(const Type &left, const Type &righ const Type* SubtractBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const { if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) { return TypeFactory::GetUnifyingType(left, right); + } else if ((left.getTypeID() == kDate && right.getTypeID() == kYearMonthInterval)) { + // For DATE type, only one possibility: DATE - YEAR-MONTH-INTERVAL. + return &(DateType::Instance(left.isNullable() || right.isNullable())); } else if ((left.getTypeID() == kDatetime && right.getTypeID() == kDatetime) || (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval)) { // NOTE(zuyu): we set the result type of the Subtract @@ -108,6 +116,10 @@ const Type* SubtractBinaryOperation::resultTypeForPartialArgumentTypes( case kDouble: // Double has highest precedence of numeric types. return &TypeFactory::GetType(kDouble, true); + case kDate: + // If left is a Date, right must be a YearMonthInterval and the result + // must be a Date. + return &TypeFactory::GetType(kDate, true); case kDatetimeInterval: // If minuend is a DatetimeInterval, the subtrahend and result must // also be DatetimeInterval. @@ -149,9 +161,15 @@ bool SubtractBinaryOperation::partialTypeSignatureIsPlausible( } else { // Only result type is known, just check that it is one of the types // that can possibly be returned. - return QUICKSTEP_EQUALS_ANY_CONSTANT( - result_type->getTypeID(), - kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval); + return QUICKSTEP_EQUALS_ANY_CONSTANT(result_type->getTypeID(), + kInt, + kLong, + kFloat, + kDouble, + kDate, + kDatetime, + kDatetimeInterval, + kYearMonthInterval); } } @@ -159,9 +177,14 @@ bool SubtractBinaryOperation::partialTypeSignatureIsPlausible( // Right (minuend) argument type is known, left (subtrahend) argument and // result types are unknown. Just check that right (minuend) type can be // subtracted. - return QUICKSTEP_EQUALS_ANY_CONSTANT( - right_argument_type->getTypeID(), - kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval); + return QUICKSTEP_EQUALS_ANY_CONSTANT(right_argument_type->getTypeID(), + kInt, + kLong, + kFloat, + kDouble, + kDatetime, + kDatetimeInterval, + kYearMonthInterval); } // Return type and right (minuend) argument type are known, left @@ -182,6 +205,8 @@ bool SubtractBinaryOperation::partialTypeSignatureIsPlausible( kFloat, kDouble); case kDouble: return (result_type->getTypeID() == kDouble); + case kDate: + return (result_type->getTypeID() == kDate); case kDatetime: return (result_type->getTypeID() == kDatetimeInterval); case kDatetimeInterval: @@ -191,7 +216,7 @@ bool SubtractBinaryOperation::partialTypeSignatureIsPlausible( case kYearMonthInterval: return QUICKSTEP_EQUALS_ANY_CONSTANT( result_type->getTypeID(), - kDatetime, kYearMonthInterval); + kDate, kDatetime, kYearMonthInterval); default: return false; } @@ -201,9 +226,15 @@ bool SubtractBinaryOperation::partialTypeSignatureIsPlausible( // Left (subtrahend) argument type is known, right (minuend) argument // type and result type are unknown. Just check that the left // (subtrahend) type can be subtracted from. - return QUICKSTEP_EQUALS_ANY_CONSTANT( - left_argument_type->getTypeID(), - kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval); + return QUICKSTEP_EQUALS_ANY_CONSTANT(left_argument_type->getTypeID(), + kInt, + kLong, + kFloat, + kDouble, + kDate, + kDatetime, + kDatetimeInterval, + kYearMonthInterval); } // Result type and left (subtrahend) argument type are known, but right @@ -224,6 +255,8 @@ bool SubtractBinaryOperation::partialTypeSignatureIsPlausible( kFloat, kDouble); case kDouble: return (result_type->getTypeID() == kDouble); + case kDate: + return (result_type->getTypeID() == kDate); case kDatetime: return QUICKSTEP_EQUALS_ANY_CONSTANT( result_type->getTypeID(), @@ -267,6 +300,10 @@ std::pair<const Type*, const Type*> SubtractBinaryOperation::pushDownTypeHint( case kDouble: case kYearMonthInterval: return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint); + case kDate: + // Left should be a Date, right should be YearMonthInterval. + return std::pair<const Type *, const Type *>( + result_type_hint, &TypeFactory::GetType(kYearMonthInterval, true)); case kDatetime: // Left should be a Datetime, right may be either interval type. return std::pair<const Type*, const Type*>(result_type_hint, nullptr); @@ -294,6 +331,16 @@ TypedValue SubtractBinaryOperation::applyToChecked(const TypedValue &left, } break; } + case kDate: { + if (right_type.getTypeID() == kYearMonthInterval) { + if (left.isNull() || right.isNull()) { + return TypedValue(kDate); + } + + return TypedValue(left.getLiteral<DateLit>() - right.getLiteral<YearMonthIntervalLit>()); + } + break; + } case kDatetime: { if (right_type.getTypeID() == kDatetime) { // NOTE(zuyu): The result type of the Subtract between two Datetimes is DatetimeInterval, @@ -358,6 +405,16 @@ UncheckedBinaryOperator* SubtractBinaryOperation::makeUncheckedBinaryOperatorFor } break; } + case kDate: { + if (right.getTypeID() == kYearMonthInterval) { + return makeDateBinaryOperatorOuterHelper< + SubtractArithmeticUncheckedBinaryOperator, + DateType, + DateLit, + YearMonthIntervalLit>(left, right); + } + break; + } case kDatetime: { if (right.getTypeID() == kDatetime) { // NOTE(zuyu): The result type of the Subtract between two Datetimes is DatetimeInterval, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/binary_operations/tests/AddBinaryOperation_unittest.cpp ---------------------------------------------------------------------- diff --git a/types/operations/binary_operations/tests/AddBinaryOperation_unittest.cpp b/types/operations/binary_operations/tests/AddBinaryOperation_unittest.cpp index e6b0484..4d6b54e 100644 --- a/types/operations/binary_operations/tests/AddBinaryOperation_unittest.cpp +++ b/types/operations/binary_operations/tests/AddBinaryOperation_unittest.cpp @@ -62,6 +62,13 @@ TEST(AddBinaryOperationTest, ResultTypeForPartialArgumentTypesTest) { ASSERT_NE(result_type, nullptr); EXPECT_TRUE(TypeFactory::GetType(kDouble, true).equals(*result_type)); + // A Date can be added with only YearMonthIntervalType resulting in a Date. + result_type = + AddBinaryOperation::Instance().resultTypeForPartialArgumentTypes( + &TypeFactory::GetType(kDate, true), nullptr); + ASSERT_NE(result_type, nullptr); + EXPECT_TRUE(TypeFactory::GetType(kDate, true).equals(*result_type)); + // If one of the arguments is a Datetime, then it can be added with either // interval type and will always yield a Datetime. result_type = AddBinaryOperation::Instance().resultTypeForPartialArgumentTypes( @@ -143,13 +150,13 @@ TEST(AddBinaryOperationTest, PartialTypeSignatureIsPlausibleTest) { // might possibly return is plausible. BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndUnknownArguments( AddBinaryOperation::Instance(), - {kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval}); + {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}); // -------------------------------------------------------------------------- // Result type unknown, one argument type known. BinaryOperationTestUtil::CheckPlausibilityWithUnknownResultAndSingleKnownArgument( AddBinaryOperation::Instance(), - {kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval}, + {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}, true, true); @@ -165,7 +172,10 @@ TEST(AddBinaryOperationTest, PartialTypeSignatureIsPlausibleTest) { AddBinaryOperation::Instance(), kDouble, {kInt, kLong, kFloat, kDouble}, true, true); BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( AddBinaryOperation::Instance(), - kDatetime, {kDatetime, kDatetimeInterval, kYearMonthInterval}, true, true); + kDate, {kDate}, true, true); + BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( + AddBinaryOperation::Instance(), + kDatetime, {kDatetime, kDatetimeInterval}, true, true); BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( AddBinaryOperation::Instance(), kDatetimeInterval, {kDatetimeInterval}, true, true); BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( @@ -200,6 +210,13 @@ TEST(AddBinaryOperationTest, PushDownTypeHintTest) { EXPECT_TRUE(result_type->equals(*hints.second)); } + // A hint of Date is ambiguous, because one argument should be Date and other + // should be YearMonthInterval, but the order does not matter. + result_type = &TypeFactory::GetType(kDate, false); + hints = AddBinaryOperation::Instance().pushDownTypeHint(result_type); + EXPECT_EQ(nullptr, hints.first); + EXPECT_EQ(nullptr, hints.second); + // A hint of Datetime is ambiguous, because one argument should be Datetime // and the other should be some interval type. result_type = &TypeFactory::GetType(kDatetime, false); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/binary_operations/tests/BinaryOperationTestUtil.hpp ---------------------------------------------------------------------- diff --git a/types/operations/binary_operations/tests/BinaryOperationTestUtil.hpp b/types/operations/binary_operations/tests/BinaryOperationTestUtil.hpp index e23057c..11abe20 100644 --- a/types/operations/binary_operations/tests/BinaryOperationTestUtil.hpp +++ b/types/operations/binary_operations/tests/BinaryOperationTestUtil.hpp @@ -92,7 +92,7 @@ class BinaryOperationTestUtil { const bool check_left_argument, const bool check_right_argument) { for (const TypeID argument_type_id - : {kInt, kLong, kFloat, kDouble, kChar, kVarChar, kDatetime, + : {kInt, kLong, kFloat, kDouble, kChar, kVarChar, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) { const Type *argument_type = TypeFactory::TypeRequiresLengthParameter(argument_type_id) ? &TypeFactory::GetType(argument_type_id, 10, false) @@ -159,7 +159,7 @@ class BinaryOperationTestUtil { const Type *result_type_nullable = &result_type->getNullableVersion(); for (const TypeID argument_type_id - : {kInt, kLong, kFloat, kDouble, kChar, kVarChar, kDatetime, + : {kInt, kLong, kFloat, kDouble, kChar, kVarChar, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) { const Type *argument_type = TypeFactory::TypeRequiresLengthParameter(argument_type_id) ? &TypeFactory::GetType(argument_type_id, 10, false) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/binary_operations/tests/SubtractBinaryOperation_unittest.cpp ---------------------------------------------------------------------- diff --git a/types/operations/binary_operations/tests/SubtractBinaryOperation_unittest.cpp b/types/operations/binary_operations/tests/SubtractBinaryOperation_unittest.cpp index 50ac967..15436d8 100644 --- a/types/operations/binary_operations/tests/SubtractBinaryOperation_unittest.cpp +++ b/types/operations/binary_operations/tests/SubtractBinaryOperation_unittest.cpp @@ -63,6 +63,13 @@ TEST(SubtractBinaryOperationTest, ResultTypeForPartialArgumentTypesTest) { ASSERT_NE(result_type, nullptr); EXPECT_TRUE(TypeFactory::GetType(kDouble, true).equals(*result_type)); + // If the left argument is a Date, then the result should be a Date. + result_type = + SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes( + &TypeFactory::GetType(kDate, false), nullptr); + ASSERT_NE(result_type, nullptr); + EXPECT_TRUE(TypeFactory::GetType(kDate, true).equals(*result_type)); + // If the left argument (the minuend) is an interval, then the subtrahend and // the result must also be the same kind of interval. result_type = SubtractBinaryOperation::Instance().resultTypeForPartialArgumentTypes( @@ -150,8 +157,14 @@ TEST(SubtractBinaryOperationTest, PartialTypeSignatureIsPlausibleTest) { // Result type unknown, one argument type known. BinaryOperationTestUtil::CheckPlausibilityWithUnknownResultAndSingleKnownArgument( SubtractBinaryOperation::Instance(), - {kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval}, + {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}, true, + false); + + BinaryOperationTestUtil::CheckPlausibilityWithUnknownResultAndSingleKnownArgument( + SubtractBinaryOperation::Instance(), + {kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval}, + false, true); // -------------------------------------------------------------------------- @@ -165,6 +178,8 @@ TEST(SubtractBinaryOperationTest, PartialTypeSignatureIsPlausibleTest) { BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( SubtractBinaryOperation::Instance(), kDouble, {kInt, kLong, kFloat, kDouble}, true, false); BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( + SubtractBinaryOperation::Instance(), kDate, {kDate}, true, false); + BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( SubtractBinaryOperation::Instance(), kDatetime, {kDatetime}, true, false); BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( SubtractBinaryOperation::Instance(), @@ -224,6 +239,12 @@ TEST(SubtractBinaryOperationTest, PushDownTypeHintTest) { EXPECT_TRUE(result_type->equals(*hints.second)); } + result_type = &TypeFactory::GetType(kDate, false); + hints = SubtractBinaryOperation::Instance().pushDownTypeHint(result_type); + ASSERT_NE(hints.first, nullptr); + EXPECT_TRUE(result_type->equals(*hints.first)); + EXPECT_EQ(&TypeFactory::GetType(kYearMonthInterval, true), hints.second); + // A hint of Datetime means the left argument should be Datetime and the // right could be either interval type. result_type = &TypeFactory::GetType(kDatetime, false); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/unary_operations/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt index d612464..6e1923a 100644 --- a/types/operations/unary_operations/CMakeLists.txt +++ b/types/operations/unary_operations/CMakeLists.txt @@ -60,6 +60,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOper quickstep_storage_ValueAccessor quickstep_storage_ValueAccessorUtil quickstep_types_DatetimeLit + quickstep_types_IntType quickstep_types_LongType quickstep_types_Type quickstep_types_TypeFactory @@ -164,5 +165,6 @@ target_link_libraries(UnaryOperation_tests quickstep_types_operations_unaryoperations_UnaryOperation quickstep_types_operations_unaryoperations_UnaryOperationFactory quickstep_types_operations_unaryoperations_UnaryOperationID + quickstep_utility_EqualsAnyConstant quickstep_utility_Macros) add_test(UnaryOperation_tests UnaryOperation_tests) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/unary_operations/DateExtractOperation.cpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp index ad8a0aa..c99e403 100644 --- a/types/operations/unary_operations/DateExtractOperation.cpp +++ b/types/operations/unary_operations/DateExtractOperation.cpp @@ -23,6 +23,7 @@ #include <cstdint> #include <memory> #include <string> +#include <type_traits> #ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN #include <utility> @@ -35,6 +36,7 @@ #include "storage/ValueAccessor.hpp" #include "storage/ValueAccessorUtil.hpp" #include "types/DatetimeLit.hpp" +#include "types/IntType.hpp" #include "types/LongType.hpp" #include "types/Type.hpp" #include "types/TypeFactory.hpp" @@ -46,12 +48,13 @@ #include "glog/logging.h" +using std::int32_t; using std::int64_t; namespace quickstep { template <DateExtractUnit unit, bool argument_nullable> -TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue( +TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue( const TypedValue &argument) const { if (argument_nullable && argument.isNull()) { return TypedValue(kLong); @@ -61,7 +64,17 @@ TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToTypedVa } template <DateExtractUnit unit, bool argument_nullable> -TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const { +TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue( + const TypedValue &argument) const { + if (argument_nullable && argument.isNull()) { + return TypedValue(kInt); + } + + return TypedValue(dateExtract(argument.getLiteral<DateLit>())); +} + +template <DateExtractUnit unit, bool argument_nullable> +TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const { if (argument_nullable && argument == nullptr) { return TypedValue(kLong); } @@ -70,7 +83,16 @@ TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr } template <DateExtractUnit unit, bool argument_nullable> -ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector( +TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const { + if (argument_nullable && argument == nullptr) { + return TypedValue(kInt); + } + + return TypedValue(dateExtract(*static_cast<const DateLit*>(argument))); +} + +template <DateExtractUnit unit, bool argument_nullable> +ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector( const ColumnVector &argument) const { // Datetime are usable with NativeColumnVector, so 'argument' should always // be native. @@ -96,9 +118,36 @@ ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToColu return result.release(); } +template <DateExtractUnit unit, bool argument_nullable> +ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector( + const ColumnVector &argument) const { + // Date is usable with NativeColumnVector, so 'argument' should always + // be native. + DCHECK(argument.isNative()); + + const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument); + std::unique_ptr<NativeColumnVector> result( + new NativeColumnVector(IntType::Instance(argument_nullable), native_argument.size())); + + for (std::size_t pos = 0; + pos < native_argument.size(); + ++pos) { + const DateLit *date_arg = + static_cast<const DateLit*>(native_argument.getUntypedValue<argument_nullable>(pos)); + if (argument_nullable && (date_arg == nullptr)) { + result->appendNullValue(); + } else { + *static_cast<int32_t*>(result->getPtrForDirectWrite()) + = dateExtract(*date_arg); + } + } + + return result.release(); +} + #ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION template <DateExtractUnit unit, bool argument_nullable> -ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor( +ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor( ValueAccessor *accessor, const attribute_id argument_attr_id) const { return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter( @@ -121,11 +170,36 @@ ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValu return result.release(); }); } + +template <DateExtractUnit unit, bool argument_nullable> +ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor( + ValueAccessor *accessor, + const attribute_id argument_attr_id) const { + return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter( + accessor, + [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11) + std::unique_ptr<NativeColumnVector> result( + new NativeColumnVector(IntType::Instance(argument_nullable), accessor->getNumTuples())); + accessor->beginIteration(); + while (accessor->next()) { + const DateLit *date_arg = + static_cast<const DateLit*>( + accessor->template getUntypedValue<argument_nullable>(argument_attr_id)); + if (argument_nullable && (date_arg == nullptr)) { + result->appendNullValue(); + } else { + *static_cast<int32_t*>(result->getPtrForDirectWrite()) + = this->dateExtract(*date_arg); + } + } + return result.release(); + }); +} #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION #ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN template <DateExtractUnit unit, bool argument_nullable> -ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin( +ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin( ValueAccessor *accessor, const bool use_left_relation, const attribute_id argument_attr_id, @@ -151,10 +225,40 @@ ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValu return result.release(); }); } + +template <DateExtractUnit unit, bool argument_nullable> +ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin( + ValueAccessor *accessor, + const bool use_left_relation, + const attribute_id argument_attr_id, + const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const { + std::unique_ptr<NativeColumnVector> result( + new NativeColumnVector(IntType::Instance(argument_nullable), joined_tuple_ids.size())); + return InvokeOnValueAccessorNotAdapter( + accessor, + [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11) + for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) { + const DateLit *date_arg = + static_cast<const DateLit*>( + accessor->template getUntypedValueAtAbsolutePosition<argument_nullable>( + argument_attr_id, + use_left_relation ? joined_pair.first : joined_pair.second)); + if (argument_nullable && (date_arg == nullptr)) { + result->appendNullValue(); + } else { + *static_cast<int32_t*>(result->getPtrForDirectWrite()) + = this->dateExtract(*date_arg); + } + } + return result.release(); + }); +} #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN template <DateExtractUnit unit, bool argument_nullable> -inline int64_t DateExtractUncheckedOperator<unit, argument_nullable>::dateExtract(const DatetimeLit &argument) const { +inline int64_t +DatetimeExtractUncheckedOperator<unit, argument_nullable>::dateExtract( + const DatetimeLit &argument) const { switch (unit) { case DateExtractUnit::kYear: return argument.yearField(); @@ -169,6 +273,18 @@ inline int64_t DateExtractUncheckedOperator<unit, argument_nullable>::dateExtrac case DateExtractUnit::kSecond: return argument.secondField(); default: + FATAL_ERROR("Unsupported DateExtractUnit in DatetimeExtractUncheckedOperator::dateExtract."); + } +} + +template <DateExtractUnit unit, bool argument_nullable> +inline int32_t DateExtractUncheckedOperator<unit, argument_nullable>::dateExtract(const DateLit &argument) const { + switch (unit) { + case DateExtractUnit::kYear: + return argument.yearField(); + case DateExtractUnit::kMonth: + return argument.monthField(); + default: FATAL_ERROR("Unsupported DateExtractUnit in DateExtractUncheckedOperator::dateExtract."); } } @@ -270,7 +386,20 @@ const Type* DateExtractOperation::pushDownTypeHint(const Type *type_hint) const } if (type_hint->getTypeID() == kLong) { - return &TypeFactory::GetType(kDatetime, type_hint->isNullable()); + switch (unit_) { + case DateExtractUnit::kYear: // Fall through. + case DateExtractUnit::kMonth: + // There are two possibilities for the return type, based on whether we + // have Datetime or Date as the underlying date implementation. + return nullptr; + case DateExtractUnit::kDay: // Fall through. + case DateExtractUnit::kHour: + case DateExtractUnit::kMinute: + case DateExtractUnit::kSecond: + return &TypeFactory::GetType(kDatetime, type_hint->isNullable()); + default: + return nullptr; + } } else { return nullptr; } @@ -278,8 +407,10 @@ const Type* DateExtractOperation::pushDownTypeHint(const Type *type_hint) const TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument, const Type &argument_type) const { - if ((argument.getTypeID() != TypeID::kDatetime) - || (argument_type.getTypeID() != TypeID::kDatetime)) { + if (((argument.getTypeID() != TypeID::kDatetime) || + (argument_type.getTypeID() != TypeID::kDatetime)) && + ((argument.getTypeID() != TypeID::kDate) || + (argument_type.getTypeID() != TypeID::kDate))) { LOG(FATAL) << "UnaryOperation " << getName() << " is only applicable to Type " << kTypeNames[TypeID::kDatetime] << ", but applyToChecked() was " << "called with 'argument' of Type " << kTypeNames[argument.getTypeID()] @@ -288,14 +419,34 @@ TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument, } if (argument.isNull()) { - return TypedValue(kLong); + if (argument.getTypeID() == TypeID::kDatetime) { + return TypedValue(kLong); + } else { + // argument type is kDate. + DCHECK_EQ(TypeID::kDate, argument.getTypeID()); + return TypedValue(kInt); + } } switch (unit_) { - case DateExtractUnit::kYear: - return TypedValue(argument.getLiteral<DatetimeLit>().yearField()); - case DateExtractUnit::kMonth: - return TypedValue(argument.getLiteral<DatetimeLit>().monthField()); + case DateExtractUnit::kYear: { + if (argument.getTypeID() == TypeID::kDatetime) { + return TypedValue(argument.getLiteral<DatetimeLit>().yearField()); + } else { + // argument type is kDate. + DCHECK_EQ(TypeID::kDate, argument.getTypeID()); + return TypedValue(argument.getLiteral<DateLit>().yearField()); + } + } + case DateExtractUnit::kMonth: { + if (argument.getTypeID() == TypeID::kDatetime) { + return TypedValue(argument.getLiteral<DatetimeLit>().monthField()); + } else { + // argument type is kDate. + DCHECK_EQ(TypeID::kDate, argument.getTypeID()); + return TypedValue(argument.getLiteral<DateLit>().monthField()); + } + } case DateExtractUnit::kDay: return TypedValue(argument.getLiteral<DatetimeLit>().dayField()); case DateExtractUnit::kHour: @@ -312,45 +463,80 @@ TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument, UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper(const Type &type) const { switch (unit_) { - case DateExtractUnit::kYear: - if (type.isNullable()) { - return new DateExtractUncheckedOperator<DateExtractUnit::kYear, true>(); + case DateExtractUnit::kYear: { + if (type.getTypeID() == TypeID::kDatetime) { + if (type.isNullable()) { + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kYear, true>(); + } else { + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kYear, false>(); + } } else { - return new DateExtractUncheckedOperator<DateExtractUnit::kYear, false>(); + DCHECK_EQ(TypeID::kDate, type.getTypeID()); + // type is kDate. + if (type.isNullable()) { + return new DateExtractUncheckedOperator<DateExtractUnit::kYear, true>(); + } else { + return new DateExtractUncheckedOperator<DateExtractUnit::kYear, false>(); + } } - case DateExtractUnit::kMonth: - if (type.isNullable()) { - return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, true>(); + } + case DateExtractUnit::kMonth: { + if (type.getTypeID() == TypeID::kDatetime) { + if (type.isNullable()) { + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMonth, true>(); + } else { + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMonth, false>(); + } } else { - return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, false>(); + // type is kDate. + DCHECK_EQ(TypeID::kDate, type.getTypeID()); + if (type.isNullable()) { + return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, true>(); + } else { + return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, false>(); + } } + } case DateExtractUnit::kDay: if (type.isNullable()) { - return new DateExtractUncheckedOperator<DateExtractUnit::kDay, true>(); + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, true>(); } else { - return new DateExtractUncheckedOperator<DateExtractUnit::kDay, false>(); + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, false>(); } case DateExtractUnit::kHour: if (type.isNullable()) { - return new DateExtractUncheckedOperator<DateExtractUnit::kHour, true>(); + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, true>(); } else { - return new DateExtractUncheckedOperator<DateExtractUnit::kHour, false>(); + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, false>(); } case DateExtractUnit::kMinute: if (type.isNullable()) { - return new DateExtractUncheckedOperator<DateExtractUnit::kMinute, true>(); + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, true>(); } else { - return new DateExtractUncheckedOperator<DateExtractUnit::kMinute, false>(); + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, false>(); } case DateExtractUnit::kSecond: if (type.isNullable()) { - return new DateExtractUncheckedOperator<DateExtractUnit::kSecond, true>(); + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, true>(); } else { - return new DateExtractUncheckedOperator<DateExtractUnit::kSecond, false>(); + return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, false>(); } default: FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper."); } } +const Type* DateExtractOperation::resultTypeForArgumentType(const Type &type) const { + if (canApplyToType(type)) { + if (type.getTypeID() == kDatetime) { + return &LongType::Instance(type.isNullable()); + } else { + DCHECK_EQ(kDate, type.getTypeID()); + return &IntType::Instance(type.isNullable()); + } + } else { + return nullptr; + } +} + } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1d104229/types/operations/unary_operations/DateExtractOperation.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/DateExtractOperation.hpp b/types/operations/unary_operations/DateExtractOperation.hpp index fd12bed..f8c091b 100644 --- a/types/operations/unary_operations/DateExtractOperation.hpp +++ b/types/operations/unary_operations/DateExtractOperation.hpp @@ -61,6 +61,40 @@ enum class DateExtractUnit { }; /** + * @brief UncheckedUnaryOperator for Datetime Extract. + */ +template <DateExtractUnit unit, bool argument_nullable> +class DatetimeExtractUncheckedOperator : public UncheckedUnaryOperator { + public: + DatetimeExtractUncheckedOperator() + : UncheckedUnaryOperator() {} + + TypedValue applyToTypedValue(const TypedValue &argument) const override; + + TypedValue applyToDataPtr(const void *argument) const override; + + ColumnVector* applyToColumnVector(const ColumnVector &argument) const override; + +#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION + ColumnVector* applyToValueAccessor(ValueAccessor *accessor, + const attribute_id argument_attr_id) const override; +#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION + +#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN + ColumnVector* applyToValueAccessorForJoin( + ValueAccessor *accessor, + const bool use_left_relation, + const attribute_id argument_attr_id, + const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override; +#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN + + private: + inline std::int64_t dateExtract(const DatetimeLit &argument) const; + + DISALLOW_COPY_AND_ASSIGN(DatetimeExtractUncheckedOperator); +}; + +/** * @brief UncheckedUnaryOperator for Date Extract. */ template <DateExtractUnit unit, bool argument_nullable> @@ -89,7 +123,7 @@ class DateExtractUncheckedOperator : public UncheckedUnaryOperator { #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN private: - inline std::int64_t dateExtract(const DatetimeLit &argument) const; + inline std::int32_t dateExtract(const DateLit &argument) const; DISALLOW_COPY_AND_ASSIGN(DateExtractUncheckedOperator); }; @@ -114,23 +148,17 @@ class DateExtractOperation : public UnaryOperation { std::string getName() const override; bool canApplyToType(const Type &type) const override { - return type.getTypeID() == TypeID::kDatetime; + return type.getTypeID() == TypeID::kDatetime || type.getTypeID() == kDate; } - const Type* resultTypeForArgumentType(const Type &type) const override { - if (canApplyToType(type)) { - return &LongType::Instance(type.isNullable()); - } else { - return nullptr; - } - } + const Type* resultTypeForArgumentType(const Type &type) const override; const Type* fixedNullableResultType() const override { - return &LongType::InstanceNullable(); + return nullptr; } bool resultTypeIsPlausible(const Type &result_type) const override { - return (result_type.getTypeID() == kLong); + return result_type.getTypeID() == kLong || result_type.getTypeID() == kInt; } const Type* pushDownTypeHint(const Type *type_hint) const override; @@ -139,7 +167,7 @@ class DateExtractOperation : public UnaryOperation { const Type &argument_type) const override; UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override { - DCHECK_EQ(TypeID::kDatetime, type.getTypeID()); + DCHECK(canApplyToType(type)); return makeUncheckedUnaryOperatorForTypeHelper(type); }