mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-28 10:31:57 +00:00
sql: initial EXTRACT(... FROM ...) support (#2196)
* start * wip * wip * wip * wip * wip * Fix clickhouse-server.postinst * clean * wip * clean * clean * clean * wip * clean * Update dump_variable.cpp
This commit is contained in:
parent
d19a56aa3a
commit
f9cd6a09e6
@ -374,6 +374,69 @@ bool ParserCastExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expect
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ParserExtractExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||||
|
{
|
||||||
|
auto begin = pos;
|
||||||
|
ParserIdentifier id_parser;
|
||||||
|
ASTPtr identifier;
|
||||||
|
|
||||||
|
if (!id_parser.parse(pos, identifier, expected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (pos->type != TokenType::OpeningRoundBracket)
|
||||||
|
return false;
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
ASTPtr expr;
|
||||||
|
const char * function_name = nullptr;
|
||||||
|
|
||||||
|
if (ParserKeyword("SECOND").ignore(pos, expected))
|
||||||
|
function_name = "toSecond";
|
||||||
|
else if (ParserKeyword("MINUTE").ignore(pos, expected))
|
||||||
|
function_name = "toMinute";
|
||||||
|
else if (ParserKeyword("HOUR").ignore(pos, expected))
|
||||||
|
function_name = "toHour";
|
||||||
|
else if (ParserKeyword("DAY").ignore(pos, expected))
|
||||||
|
function_name = "toDayOfMonth";
|
||||||
|
|
||||||
|
// TODO: SELECT toRelativeWeekNum(toDate('2017-06-15')) - toRelativeWeekNum(toStartOfYear(toDate('2017-06-15')))
|
||||||
|
// else if (ParserKeyword("WEEK").ignore(pos, expected))
|
||||||
|
// function_name = "toRelativeWeekNum";
|
||||||
|
|
||||||
|
else if (ParserKeyword("MONTH").ignore(pos, expected))
|
||||||
|
function_name = "toMonth";
|
||||||
|
else if (ParserKeyword("YEAR").ignore(pos, expected))
|
||||||
|
function_name = "toYear";
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ParserKeyword s_from("FROM");
|
||||||
|
if (!s_from.ignore(pos, expected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ParserExpression elem_parser;
|
||||||
|
if (!elem_parser.parse(pos, expr, expected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (pos->type != TokenType::ClosingRoundBracket)
|
||||||
|
return false;
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
auto function = std::make_shared<ASTFunction>();
|
||||||
|
auto exp_list = std::make_shared<ASTExpressionList>();
|
||||||
|
function->range.first = begin->begin;
|
||||||
|
function->range.second = pos->begin;
|
||||||
|
function->name = function_name; //"toYear";
|
||||||
|
function->arguments = exp_list;
|
||||||
|
function->children.push_back(exp_list);
|
||||||
|
exp_list->children.push_back(expr);
|
||||||
|
exp_list->range.first = begin->begin;
|
||||||
|
exp_list->range.second = pos->begin;
|
||||||
|
node = function;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ParserNull::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
bool ParserNull::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||||
{
|
{
|
||||||
@ -677,7 +740,8 @@ bool ParserExpressionElement::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
|
|||||||
ParserArray array_p;
|
ParserArray array_p;
|
||||||
ParserArrayOfLiterals array_lite_p;
|
ParserArrayOfLiterals array_lite_p;
|
||||||
ParserLiteral lit_p;
|
ParserLiteral lit_p;
|
||||||
ParserCastExpression fun_p;
|
ParserExtractExpression extract_p;
|
||||||
|
ParserCastExpression cast_p;
|
||||||
ParserCompoundIdentifier id_p;
|
ParserCompoundIdentifier id_p;
|
||||||
ParserAsterisk asterisk_p;
|
ParserAsterisk asterisk_p;
|
||||||
ParserQualifiedAsterisk qualified_asterisk_p;
|
ParserQualifiedAsterisk qualified_asterisk_p;
|
||||||
@ -697,7 +761,10 @@ bool ParserExpressionElement::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
|
|||||||
if (lit_p.parse(pos, node, expected))
|
if (lit_p.parse(pos, node, expected))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (fun_p.parse(pos, node, expected))
|
if (extract_p.parse(pos, node, expected))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (cast_p.parse(pos, node, expected))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (qualified_asterisk_p.parse(pos, node, expected))
|
if (qualified_asterisk_p.parse(pos, node, expected))
|
||||||
|
@ -99,6 +99,15 @@ protected:
|
|||||||
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ParserExtractExpression : public IParserBase
|
||||||
|
{
|
||||||
|
static constexpr auto name = "EXTRACT";
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char * getName() const override { return name; }
|
||||||
|
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** NULL literal.
|
/** NULL literal.
|
||||||
*/
|
*/
|
||||||
|
22
dbms/src/Parsers/iostream_debug_helpers.cpp
Normal file
22
dbms/src/Parsers/iostream_debug_helpers.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "iostream_debug_helpers.h"
|
||||||
|
#include <Parsers/IParser.h>
|
||||||
|
#include <Parsers/Lexer.h>
|
||||||
|
#include <Parsers/TokenIterator.h>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream & operator<<(std::ostream & stream, const Token & what) {
|
||||||
|
stream << "Token (type="<< static_cast<int>(what.type) <<"){"<< std::string{what.begin, what.end} << "}";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream & operator<<(std::ostream & stream, const Expected & what) {
|
||||||
|
stream << "Expected {variants=";
|
||||||
|
dumpValue(stream, what.variants)
|
||||||
|
<< "; max_parsed_pos=" << what.max_parsed_pos << "}";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
dbms/src/Parsers/iostream_debug_helpers.h
Normal file
14
dbms/src/Parsers/iostream_debug_helpers.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
class Token;
|
||||||
|
std::ostream & operator<<(std::ostream & stream, const Token & what);
|
||||||
|
|
||||||
|
struct Expected;
|
||||||
|
std::ostream & operator<<(std::ostream & stream, const Expected & what);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Core/iostream_debug_helpers.h>
|
10
dbms/tests/queries/0_stateless/00619_extract.reference
Normal file
10
dbms/tests/queries/0_stateless/00619_extract.reference
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
15
|
||||||
|
6
|
||||||
|
2017
|
||||||
|
58
|
||||||
|
59
|
||||||
|
18
|
||||||
|
31
|
||||||
|
12
|
||||||
|
2017
|
||||||
|
2008 10 11 13 23 44
|
39
dbms/tests/queries/0_stateless/00619_extract.sql
Normal file
39
dbms/tests/queries/0_stateless/00619_extract.sql
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
SELECT EXTRACT(DAY FROM toDate('2017-06-15'));
|
||||||
|
SELECT EXTRACT (MONTH FROM toDate('2017-06-15'));
|
||||||
|
SELECT EXTRACT(YEAR FROM toDate('2017-06-15'));
|
||||||
|
SELECT EXTRACT(SECOND FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
SELECT EXTRACT(MINUTE FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
SELECT EXTRACT(HOUR FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
SELECT EXTRACT(DAY from toDateTime('2017-12-31 18:59:58'));
|
||||||
|
SELECT extract(MONTH FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
SELECT EXTRACT(year FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS test.Orders;
|
||||||
|
CREATE TABLE test.Orders (OrderId UInt64, OrderName String, OrderDate DateTime) engine = Log;
|
||||||
|
insert into test.Orders values (1, 'Jarlsberg Cheese', toDateTime('2008-10-11 13:23:44'));
|
||||||
|
SELECT EXTRACT(YEAR FROM OrderDate) AS OrderYear, EXTRACT(MONTH FROM OrderDate) AS OrderMonth, EXTRACT(DAY FROM OrderDate) AS OrderDay,
|
||||||
|
EXTRACT(HOUR FROM OrderDate), EXTRACT(MINUTE FROM OrderDate), EXTRACT(SECOND FROM OrderDate) FROM test.Orders WHERE OrderId=1;
|
||||||
|
DROP TABLE test.Orders;
|
||||||
|
|
||||||
|
|
||||||
|
-- TODO:
|
||||||
|
-- SELECT EXTRACT(WEEK FROM toDate('2017-06-15'));
|
||||||
|
-- SELECT EXTRACT(WEEK FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
-- SELECT EXTRACT(MINUTE_SECOND FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
-- SELECT EXTRACT(HOUR_SECOND FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
-- SELECT EXTRACT(HOUR_MINUTE FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
-- SELECT EXTRACT(DAY_SECOND FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
-- SELECT EXTRACT(DAY_MINUTE FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
-- SELECT EXTRACT(DAY_HOUR FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
-- SELECT EXTRACT(YEAR_MONTH FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
-- SELECT EXTRACT(QUARTER FROM toDate('2017-06-15'));
|
||||||
|
-- SELECT EXTRACT(DAY_SECOND FROM toDate('2017-06-15'));
|
||||||
|
-- SELECT EXTRACT(DAY_MINUTE FROM toDate('2017-06-15'));
|
||||||
|
-- SELECT EXTRACT(DAY_HOUR FROM toDate('2017-06-15'));
|
||||||
|
-- SELECT EXTRACT(YEAR_MONTH FROM toDate('2017-06-15'));
|
||||||
|
-- SELECT EXTRACT(QUARTER FROM toDateTime('2017-12-31 18:59:58'));
|
||||||
|
|
||||||
|
-- Maybe:
|
||||||
|
-- SELECT EXTRACT (YEAR FROM DATE '2014-08-22') AS RESULT;
|
@ -4,6 +4,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -12,6 +13,18 @@
|
|||||||
struct S1;
|
struct S1;
|
||||||
struct S2 {};
|
struct S2 {};
|
||||||
|
|
||||||
|
struct S3
|
||||||
|
{
|
||||||
|
std::set<const char *> m1;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream & operator<<(std::ostream & stream, const S3 & what)
|
||||||
|
{
|
||||||
|
stream << "S3 {m1=";
|
||||||
|
dumpValue(stream, what.m1) << "}";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int, char **)
|
int main(int, char **)
|
||||||
{
|
{
|
||||||
int x = 1;
|
int x = 1;
|
||||||
@ -47,5 +60,11 @@ int main(int, char **)
|
|||||||
|
|
||||||
DUMP(S2());
|
DUMP(S2());
|
||||||
|
|
||||||
|
std::set<const char *> variants = {"hello", "world"};
|
||||||
|
DUMP(variants);
|
||||||
|
|
||||||
|
S3 s3 {{"hello", "world"}};
|
||||||
|
DUMP(s3);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user