Skip to content

Commit

Permalink
fix sql format (#385)
Browse files Browse the repository at this point in the history
  • Loading branch information
yl-lisen authored Dec 7, 2023
1 parent 8066de7 commit 16a408e
Show file tree
Hide file tree
Showing 76 changed files with 1,415 additions and 1,549 deletions.
42 changes: 36 additions & 6 deletions src/Common/tests/gtest_ident.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ String convertQueryToFormat(String query,bool one_line)

TEST(indent, stream_name)
{
//test format 'one_line'=false;
/// test format 'one_line'=false;
String query("with it1 as (with it2 as (select * from numbers(10)) select * from it2) select user.id from user,it1 where it1.number=user.id");
String expected_ans("WITH it1 AS\n (\n WITH it2 AS\n (\n SELECT \n *\n FROM \n numbers(10)\n )\n SELECT \n *\n FROM \n it2\n )\nSELECT \n user.id\nFROM \n user,it1\nWHERE \n it1.number = user.id");
String expected_ans("WITH it1 AS\n (\n WITH it2 AS\n (\n SELECT\n *\n FROM\n numbers(10)\n )\n SELECT\n *\n FROM\n it2\n )\nSELECT\n user.id\nFROM\n user, it1\nWHERE\n it1.number = user.id");
String ans = convertQueryToFormat(query,false);
EXPECT_STREQ(expected_ans.c_str(), ans.c_str());

//test DISTINCT JOIN WHERE PARTITION BY GROUP BY HAVING ORDER BY LIMIT EMIT SETTINGS
/// test DISTINCT JOIN WHERE PARTITION BY GROUP BY HAVING ORDER BY LIMIT EMIT SETTINGS
query = "with it1 as (select * from numbers(10)) select distinct user.id from user join it1 on user.id=it1.number group by user.id having id>0 order by id limit 10 emit last 1s settings query_mode='stream'";
expected_ans = "WITH it1 AS\n (\n SELECT \n *\n FROM \n numbers(10)\n )\nSELECT DISTINCT \n user.id\nFROM \n user\nINNER JOIN it1 ON user.id = it1.number\nGROUP BY \n user.id\nHAVING \n id > 0\nORDER BY \n id ASC\nLIMIT 10\nEMIT STREAM LAST 1s\nSETTINGS \n query_mode = 'stream'";
expected_ans = "WITH it1 AS\n (\n SELECT\n *\n FROM\n numbers(10)\n )\nSELECT DISTINCT\n user.id\nFROM\n user\nINNER JOIN it1 ON user.id = it1.number\nGROUP BY\n user.id\nHAVING\n id > 0\nORDER BY\n id ASC\nLIMIT 10\nEMIT STREAM LAST 1s\nSETTINGS\n query_mode = 'stream'";
ans = convertQueryToFormat(query,false);
EXPECT_STREQ(expected_ans.c_str(), ans.c_str());

//test format 'one_line'=true;
/// test format 'one_line'=true;
query = "with it1 as (with it2 as (select * from numbers(10)) select * from it2) select user.id from user,it1 where it1.number=user.id";
expected_ans = "WITH it1 AS (WITH it2 AS (SELECT * FROM numbers(10)) SELECT * FROM it2) SELECT user.id FROM user,it1 WHERE it1.number = user.id";
expected_ans = "WITH it1 AS (WITH it2 AS (SELECT * FROM numbers(10)) SELECT * FROM it2) SELECT user.id FROM user, it1 WHERE it1.number = user.id";
ans = convertQueryToFormat(query,true);
EXPECT_STREQ(expected_ans.c_str(), ans.c_str());

Expand All @@ -45,3 +45,33 @@ TEST(indent, stream_name)
EXPECT_STREQ(expected_ans.c_str(), ans.c_str());

}

TEST(indent, complex_query)
{
/// Covering: WITH SELECT DISTINCT FROM JOIN WHERE PARTITION BY SHUFFLE BY GROUP BY HAVING ORDER BY LIMIT EMIT SETTINGS UNION
/// test format 'one_line'=false;
String query = "with it1 as (select * from numbers(10)), it2 as (select * from it1) select distinct user.id from user join it1 on user.id=it1.number array join it2.number as number where number > 1 or number < 5 partition by user.id group by user.id having id>0 order by id limit 10 emit last 1s settings query_mode='stream' union select * from it2";
String expected_ans = """WITH it1 AS\n (\n SELECT\n *\n FROM\n numbers(10)\n ), it2 AS\n (\n SELECT\n *\n FROM\n it1\n )\nSELECT DISTINCT\n user.id\nFROM\n user\nINNER JOIN it1 ON user.id = it1.number\nARRAY JOIN it2.number AS number\nWHERE\n (number > 1) OR (number < 5)\nPARTITION BY\n user.id\nGROUP BY\n user.id\nHAVING\n id > 0\nORDER BY\n id ASC\nLIMIT 10\nEMIT STREAM LAST 1s\nSETTINGS\n query_mode = 'stream'\nUNION\nSELECT\n *\nFROM\n it2";
String ans = convertQueryToFormat(query,false);
EXPECT_STREQ(expected_ans.c_str(), ans.c_str());

/// test format 'one_line'=true;
expected_ans = "WITH it1 AS (SELECT * FROM numbers(10)), it2 AS (SELECT * FROM it1) SELECT DISTINCT user.id FROM user INNER JOIN it1 ON user.id = it1.number ARRAY JOIN it2.number AS number WHERE (number > 1) OR (number < 5) PARTITION BY user.id GROUP BY user.id HAVING id > 0 ORDER BY id ASC LIMIT 10 EMIT STREAM LAST 1s SETTINGS query_mode = 'stream' UNION SELECT * FROM it2";
ans = convertQueryToFormat(query,true);
EXPECT_STREQ(expected_ans.c_str(), ans.c_str());
}

TEST(indent, join_query)
{
/// Covering: JOIN, INNER JOIN, LEFT JOIN, ASOF JOIN, LEFT ASOF JOIN, INNER ASOF JOIN, LATEST JOIN, LEFT LATEST JOIN, INNER LATEST JOIN, ARRAY JOIN
/// test format 'one_line'=false;
String query = "with tmp as (select * from t1 join t2 using(id) inner join t3 on t1.id=t3.id left join t4 on t1.id = t4.id asof join t as t5 on t1.id=t5.id and t1.time < t5.time array join t1.time as time, t2.time as time2 inner asof join (select * from t6) as t6 on t1.id=t2.id and t1.time < t6.time left asof join t7 on t1.id=t7.id and t1.time > t7.time latest join t8 using(id) inner latest join t9 on t1.id=t9.id left latest join cte as t10 on t1.id=t10.id) select * from tmp";
String expected_ans = "WITH tmp AS\n (\n SELECT\n *\n FROM\n t1\n INNER JOIN t2 USING (id)\n INNER JOIN t3 ON t1.id = t3.id\n LEFT JOIN t4 ON t1.id = t4.id\n ASOF INNER JOIN t AS t5 ON (t1.id = t5.id) AND (t1.time < t5.time)\n ARRAY JOIN t1.time AS time, t2.time AS time2\n ASOF INNER JOIN (\n SELECT\n *\n FROM\n t6\n ) AS t6 ON (t1.id = t2.id) AND (t1.time < t6.time)\n ASOF LEFT JOIN t7 ON (t1.id = t7.id) AND (t1.time > t7.time)\n LATEST INNER JOIN t8 USING (id)\n LATEST INNER JOIN t9 ON t1.id = t9.id\n LATEST LEFT JOIN cte AS t10 ON t1.id = t10.id\n )\nSELECT\n *\nFROM\n tmp";
String ans = convertQueryToFormat(query,false);
EXPECT_STREQ(expected_ans.c_str(), ans.c_str());

/// test format 'one_line'=true;
expected_ans = "WITH tmp AS (SELECT * FROM t1 INNER JOIN t2 USING (id) INNER JOIN t3 ON t1.id = t3.id LEFT JOIN t4 ON t1.id = t4.id ASOF INNER JOIN t AS t5 ON (t1.id = t5.id) AND (t1.time < t5.time) ARRAY JOIN t1.time AS time, t2.time AS time2 ASOF INNER JOIN (SELECT * FROM t6) AS t6 ON (t1.id = t2.id) AND (t1.time < t6.time) ASOF LEFT JOIN t7 ON (t1.id = t7.id) AND (t1.time > t7.time) LATEST INNER JOIN t8 USING (id) LATEST INNER JOIN t9 ON t1.id = t9.id LATEST LEFT JOIN cte AS t10 ON t1.id = t10.id) SELECT * FROM tmp";
ans = convertQueryToFormat(query,true);
EXPECT_STREQ(expected_ans.c_str(), ans.c_str());
}
16 changes: 8 additions & 8 deletions src/Interpreters/Streaming/tests/gtest_eliminate_subquery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ TEST(EliminateSubquery, OptimizedQuery)
EXPECT_EQ(
optimizeSubquery("SELECT count(a.productid) FROM (SELECT a.*, b.* FROM access1 as a, db2.product_info as b WHERE (a.productid = "
"b.productid))"),
"SELECT count(a.productid) FROM access1 AS a,db2.product_info AS b WHERE a.productid = b.productid");
"SELECT count(a.productid) FROM access1 AS a, db2.product_info AS b WHERE a.productid = b.productid");
EXPECT_EQ(
optimizeSubquery("SELECT count(*) FROM (SELECT SIGN FROM (SELECT SIGN, query FROM tablea WHERE query_id='mock-1') WHERE "
"query = "
Expand All @@ -76,7 +76,7 @@ TEST(EliminateSubquery, OptimizedQuery)
optimizeSubquery("SELECT sum(a.price), sum(b.sale) FROM (SELECT a.*, b.* FROM access1 as a, product_info as b WHERE (a.productid "
"= "
"b.productid)) GROUP BY a.name, b.sign"),
"SELECT sum(a.price), sum(b.sale) FROM access1 AS a,product_info AS b WHERE a.productid = b.productid GROUP BY a.name, b.sign");
"SELECT sum(a.price), sum(b.sale) FROM access1 AS a, product_info AS b WHERE a.productid = b.productid GROUP BY a.name, b.sign");
EXPECT_EQ(
optimizeSubquery("SELECT sum(a.price), sum(b.sale) FROM (SELECT a.*, b.* FROM access1 as a JOIN product_info as b ON a.productid "
"= "
Expand All @@ -97,11 +97,11 @@ TEST(EliminateSubquery, OptimizedQuery)
EXPECT_EQ(
optimizeSubquery("SELECT count(b.code) FROM (SELECT a.code, b.code FROM product_info as a, product_info as b WHERE (a.productid = "
"b.productid))"),
"SELECT count(b.code) FROM product_info AS a,product_info AS b WHERE a.productid = b.productid");
"SELECT count(b.code) FROM product_info AS a, product_info AS b WHERE a.productid = b.productid");
EXPECT_EQ(
optimizeSubquery("SELECT count(a.code) FROM (SELECT a.code, b.code FROM product_info as a, product_info as b WHERE (a.productid = "
"b.productid))"),
"SELECT count(a.code) FROM product_info AS a,product_info AS b WHERE a.productid = b.productid");
"SELECT count(a.code) FROM product_info AS a, product_info AS b WHERE a.productid = b.productid");
EXPECT_EQ(
optimizeSubquery("SELECT * FROM (SELECT _raw AS c, t._raw FROM default.frontier_integration_test AS t)"),
"SELECT _raw AS c, t._raw FROM default.frontier_integration_test AS t");
Expand Down Expand Up @@ -187,19 +187,19 @@ TEST(EliminateSubquery, FailedOptimizedQuery)
EXPECT_EQ(
optimizeSubquery("SELECT count(t.code) FROM (SELECT a.code, b.code FROM product_info as a, product_info as b WHERE a.productid = "
"b.productid) AS t"),
"SELECT count(t.code) FROM (SELECT a.code, b.code FROM product_info AS a,product_info AS b WHERE a.productid = b.productid) AS t");
"SELECT count(t.code) FROM (SELECT a.code, b.code FROM product_info AS a, product_info AS b WHERE a.productid = b.productid) AS t");
EXPECT_EQ(
optimizeSubquery("SELECT count(t.b.code) FROM (SELECT a.code, b.code FROM product_info as a, product_info as b WHERE a.productid = "
"b.productid) AS t"),
"SELECT count(t.b.code) FROM (SELECT a.code, b.code FROM product_info AS a,product_info AS b WHERE a.productid = b.productid) AS t");
"SELECT count(t.b.code) FROM (SELECT a.code, b.code FROM product_info AS a, product_info AS b WHERE a.productid = b.productid) AS t");
EXPECT_EQ(
optimizeSubquery(
"SELECT count(t.code) FROM (SELECT code, code FROM product_info as a, product_info as b WHERE a.productid = b.productid) AS t"),
"SELECT count(t.code) FROM (SELECT code, code FROM product_info AS a,product_info AS b WHERE a.productid = b.productid) AS t");
"SELECT count(t.code) FROM (SELECT code, code FROM product_info AS a, product_info AS b WHERE a.productid = b.productid) AS t");
EXPECT_EQ(optimizeSubquery("SELECT _time FROM (SELECT name FROM price)"), "SELECT _time FROM (SELECT name FROM price)");
EXPECT_EQ(
optimizeSubquery(
"SELECT count(code) FROM (SELECT a.code, b.code FROM product_info as a, product_info as b WHERE a.productid = b.productid)"),
"SELECT count(code) FROM (SELECT a.code, b.code FROM product_info AS a,product_info AS b WHERE a.productid = b.productid)");
"SELECT count(code) FROM (SELECT a.code, b.code FROM product_info AS a, product_info AS b WHERE a.productid = b.productid)");
EXPECT_EQ(optimizeSubquery("SELECT b FROM (SELECT b AS a FROM product)"), "SELECT b FROM (SELECT b AS a FROM product)");
}
6 changes: 4 additions & 2 deletions src/Parsers/ASTAlterQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,9 @@ void ASTAlterQuery::formatQueryImpl(const FormatSettings & settings, FormatState
{
frame.need_parens = false;

std::string indent_str = settings.one_line ? "" : std::string(4u * frame.indent, ' ');
/// proton: starts
std::string indent_str = settings.one_line ? "" : std::string(settings.indent_size * frame.indent, ' ');
/// proton: ends
settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str;

switch (alter_object)
Expand All @@ -576,7 +578,7 @@ void ASTAlterQuery::formatQueryImpl(const FormatSettings & settings, FormatState
settings.ostr << indent_str << backQuoteIfNeed(getDatabase());
settings.ostr << ".";
}
settings.ostr << indent_str << backQuoteIfNeed(getTable()) << " ";
settings.ostr << indent_str << backQuoteIfNeed(getTable());
}
else if (alter_object == AlterObjectType::DATABASE && database)
{
Expand Down
4 changes: 3 additions & 1 deletion src/Parsers/ASTCheckQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ struct ASTCheckQuery : public ASTQueryWithTableAndOutput
{
std::string nl_or_nothing = settings.one_line ? "" : "\n";

std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' ');
/// proton: starts
std::string indent_str = settings.one_line ? "" : std::string(settings.indent_size * frame.indent, ' ');
/// proton: ends
std::string nl_or_ws = settings.one_line ? " " : "\n";

settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "CHECK TABLE " << (settings.hilite ? hilite_none : "");
Expand Down
30 changes: 14 additions & 16 deletions src/Parsers/ASTExpressionList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ASTPtr ASTExpressionList::clone() const

void ASTExpressionList::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{
if (frame.expression_list_prepend_whitespace && !settings.one_line )
if (frame.expression_list_prepend_whitespace)
settings.ostr << ' ';

for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it)
Expand All @@ -40,18 +40,19 @@ void ASTExpressionList::formatImpl(const FormatSettings & settings, FormatState

void ASTExpressionList::formatImplMultiline(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{
/// proton: starts. expression list in one line
std::string indent_str = " ";
/// proton: starts.
std::string indent_str = "\n" + std::string(settings.indent_size * (frame.indent + 1), ' ');
if (frame.expression_list_always_start_on_new_line)
settings.ostr << indent_str;
else if (frame.expression_list_prepend_whitespace)
settings.ostr << " ";

std::string element_indent_str
= (children.size() > 1 || frame.expression_list_always_start_on_new_line) && !frame.expression_list_elements_are_always_on_one_line
? indent_str
: " ";
/// proton: ends.

if (frame.expression_list_prepend_whitespace)
{
if (!(children.size() > 1 || frame.expression_list_always_start_on_new_line))
/// proton: starts
settings.ostr << "";
/// proton: ends
}

++frame.indent;

for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it)
Expand All @@ -60,12 +61,9 @@ void ASTExpressionList::formatImplMultiline(const FormatSettings & settings, For
{
if (separator)
settings.ostr << separator;
}

/// proton: starts
if (it != children.begin() && (children.size() > 1 || frame.expression_list_always_start_on_new_line))
/// proton: ends
settings.ostr << indent_str;
settings.ostr << element_indent_str;
}

FormatStateStacked frame_nested = frame;
frame_nested.expression_list_always_start_on_new_line = false;
Expand Down
2 changes: 1 addition & 1 deletion src/Parsers/ASTFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ void ASTFunction::formatImplWithoutAlias(const FormatSettings & settings, Format
{
std::string nl_or_nothing = settings.one_line ? "" : "\n";
/// proton: starts
std::string indent_str = settings.one_line ? "" : std::string(2u * frame.indent, ' ');
std::string indent_str = settings.one_line ? "" : std::string(settings.indent_size * frame.indent, ' ');
/// proton: ends
settings.ostr << (settings.hilite ? hilite_function : "") << name << "(" << nl_or_nothing;
FormatStateStacked frame_nested = frame;
Expand Down
3 changes: 1 addition & 2 deletions src/Parsers/ASTNameTypePair.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ ASTPtr ASTNameTypePair::clone() const
void ASTNameTypePair::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{
/// proton: starts
std::string indent_str = settings.one_line ? "" : std::string(2 * frame.indent, ' ');
std::string indent_str = settings.one_line ? "" : std::string(settings.indent_size * frame.indent, ' ');
/// proton: ends

settings.ostr << indent_str << backQuoteIfNeed(name) << ' ';
type->formatImpl(settings, state, frame);
}
Expand Down
4 changes: 3 additions & 1 deletion src/Parsers/ASTProjectionDeclaration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ ASTPtr ASTProjectionDeclaration::clone() const
void ASTProjectionDeclaration::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{
settings.ostr << backQuoteIfNeed(name);
std::string indent_str = settings.one_line ? "" : std::string(4u * frame.indent, ' ');
/// proton: starts
std::string indent_str = settings.one_line ? "" : std::string(settings.indent_size * frame.indent, ' ');
/// proton: ends
std::string nl_or_nothing = settings.one_line ? "" : "\n";
settings.ostr << nl_or_nothing << indent_str << "(" << nl_or_nothing;
FormatStateStacked frame_nested = frame;
Expand Down
4 changes: 3 additions & 1 deletion src/Parsers/ASTProjectionSelectQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ void ASTProjectionSelectQuery::formatImpl(const FormatSettings & s, FormatState
{
frame.current_select = this;
frame.need_parens = false;
std::string indent_str = s.one_line ? "" : std::string(4 * frame.indent, ' ');
/// proton: starts
std::string indent_str = s.one_line ? "" : std::string(s.indent_size * frame.indent, ' ');
/// proton: ends

if (with())
{
Expand Down
3 changes: 1 addition & 2 deletions src/Parsers/ASTQueryWithOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ void ASTQueryWithOutput::cloneOutputOptions(ASTQueryWithOutput & cloned) const
void ASTQueryWithOutput::formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const
{
formatQueryImpl(s, state, frame);

/// proton: starts
std::string indent_str = s.one_line ? "" : std::string(2u * frame.indent, ' ');
std::string indent_str = s.one_line ? "" : std::string(s.indent_size * frame.indent, ' ');
/// proton: ends

if (out_file)
Expand Down
4 changes: 3 additions & 1 deletion src/Parsers/ASTSelectIntersectExceptQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ ASTPtr ASTSelectIntersectExceptQuery::clone() const

void ASTSelectIntersectExceptQuery::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{
std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' ');
/// proton: starts
std::string indent_str = settings.one_line ? "" : std::string(settings.indent_size * frame.indent, ' ');
/// proton: ends

for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it)
{
Expand Down
Loading

0 comments on commit 16a408e

Please sign in to comment.