mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-23 08:02:02 +00:00
Merge pull request #49703 from ClickHouse/vdimir/analyzer_join_resolve_nested
Analyzer: Fix resolving subcolumns in JOIN
This commit is contained in:
commit
d2dccf9a22
@ -3140,6 +3140,64 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromJoin(const IdentifierLoo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto check_nested_column_not_in_using = [&join_using_column_name_to_column_node, &identifier_lookup](const QueryTreeNodePtr & node)
|
||||||
|
{
|
||||||
|
/** tldr: When an identifier is resolved into the function `nested` or `getSubcolumn`, and
|
||||||
|
* some column in its argument is in the USING list and its type has to be updated, we throw an error to avoid overcomplication.
|
||||||
|
*
|
||||||
|
* Identifiers can be resolved into functions in case of nested or subcolumns.
|
||||||
|
* For example `t.t.t` can be resolved into `getSubcolumn(t, 't.t')` function in case of `t` is `Tuple`.
|
||||||
|
* So, `t` in USING list is resolved from JOIN itself and has supertype of columns from left and right table.
|
||||||
|
* But `t` in `getSubcolumn` argument is still resolved from table and we need to update its type.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* SELECT t.t FROM (
|
||||||
|
* SELECT ((1, 's'), 's') :: Tuple(t Tuple(t UInt32, s1 String), s1 String) as t
|
||||||
|
* ) AS a FULL JOIN (
|
||||||
|
* SELECT ((1, 's'), 's') :: Tuple(t Tuple(t Int32, s2 String), s2 String) as t
|
||||||
|
* ) AS b USING t;
|
||||||
|
*
|
||||||
|
* Result type of `t` is `Tuple(Tuple(Int64, String), String)` (different type and no names for subcolumns),
|
||||||
|
* so it may be tricky to have a correct type for `t.t` that is resolved into getSubcolumn(t, 't').
|
||||||
|
*
|
||||||
|
* It can be more complicated in case of Nested subcolumns, in that case in query:
|
||||||
|
* SELECT t FROM ... JOIN ... USING (t.t)
|
||||||
|
* Here, `t` is resolved into function `nested(['t', 's'], t.t, t.s) so, `t.t` should be from JOIN and `t.s` should be from table.
|
||||||
|
*
|
||||||
|
* Updating type accordingly is pretty complicated, so just forbid such cases.
|
||||||
|
*
|
||||||
|
* While it still may work for storages that support selecting subcolumns directly without `getSubcolumn` function:
|
||||||
|
* SELECT t, t.t, toTypeName(t), toTypeName(t.t) FROM t1 AS a FULL JOIN t2 AS b USING t.t;
|
||||||
|
* We just support it as a best-effort: `t` will have original type from table, but `t.t` will have super-type from JOIN.
|
||||||
|
* Probably it's good to prohibit such cases as well, but it's not clear how to check it in general case.
|
||||||
|
*/
|
||||||
|
if (node->getNodeType() != QueryTreeNodeType::FUNCTION)
|
||||||
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unexpected node type {}, expected function node", node->getNodeType());
|
||||||
|
|
||||||
|
const auto & function_argument_nodes = node->as<FunctionNode &>().getArguments().getNodes();
|
||||||
|
for (const auto & argument_node : function_argument_nodes)
|
||||||
|
{
|
||||||
|
if (argument_node->getNodeType() == QueryTreeNodeType::COLUMN)
|
||||||
|
{
|
||||||
|
const auto & column_name = argument_node->as<ColumnNode &>().getColumnName();
|
||||||
|
if (join_using_column_name_to_column_node.contains(column_name))
|
||||||
|
throw Exception(ErrorCodes::AMBIGUOUS_IDENTIFIER,
|
||||||
|
"Cannot select subcolumn for identifier '{}' while joining using column '{}'",
|
||||||
|
identifier_lookup.identifier, column_name);
|
||||||
|
}
|
||||||
|
else if (argument_node->getNodeType() == QueryTreeNodeType::CONSTANT)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unexpected node type {} for argument node in {}",
|
||||||
|
argument_node->getNodeType(), node->formatASTForErrorMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
std::optional<JoinTableSide> resolved_side;
|
std::optional<JoinTableSide> resolved_side;
|
||||||
QueryTreeNodePtr resolved_identifier;
|
QueryTreeNodePtr resolved_identifier;
|
||||||
|
|
||||||
@ -3172,13 +3230,24 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromJoin(const IdentifierLoo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (left_resolved_identifier && right_resolved_identifier)
|
if (left_resolved_identifier && right_resolved_identifier)
|
||||||
|
{
|
||||||
|
auto using_column_node_it = join_using_column_name_to_column_node.end();
|
||||||
|
if (left_resolved_identifier->getNodeType() == QueryTreeNodeType::COLUMN && right_resolved_identifier->getNodeType() == QueryTreeNodeType::COLUMN)
|
||||||
{
|
{
|
||||||
auto & left_resolved_column = left_resolved_identifier->as<ColumnNode &>();
|
auto & left_resolved_column = left_resolved_identifier->as<ColumnNode &>();
|
||||||
auto & right_resolved_column = right_resolved_identifier->as<ColumnNode &>();
|
auto & right_resolved_column = right_resolved_identifier->as<ColumnNode &>();
|
||||||
|
if (left_resolved_column.getColumnName() == right_resolved_column.getColumnName())
|
||||||
|
using_column_node_it = join_using_column_name_to_column_node.find(left_resolved_column.getColumnName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (left_resolved_identifier->getNodeType() != QueryTreeNodeType::COLUMN)
|
||||||
|
check_nested_column_not_in_using(left_resolved_identifier);
|
||||||
|
if (right_resolved_identifier->getNodeType() != QueryTreeNodeType::COLUMN)
|
||||||
|
check_nested_column_not_in_using(right_resolved_identifier);
|
||||||
|
}
|
||||||
|
|
||||||
auto using_column_node_it = join_using_column_name_to_column_node.find(left_resolved_column.getColumnName());
|
if (using_column_node_it != join_using_column_name_to_column_node.end())
|
||||||
if (using_column_node_it != join_using_column_name_to_column_node.end()
|
|
||||||
&& left_resolved_column.getColumnName() == right_resolved_column.getColumnName())
|
|
||||||
{
|
{
|
||||||
JoinTableSide using_column_inner_column_table_side = isRight(join_kind) ? JoinTableSide::Right : JoinTableSide::Left;
|
JoinTableSide using_column_inner_column_table_side = isRight(join_kind) ? JoinTableSide::Right : JoinTableSide::Left;
|
||||||
auto & using_column_node = using_column_node_it->second->as<ColumnNode &>();
|
auto & using_column_node = using_column_node_it->second->as<ColumnNode &>();
|
||||||
@ -3253,10 +3322,15 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromJoin(const IdentifierLoo
|
|||||||
else if (left_resolved_identifier)
|
else if (left_resolved_identifier)
|
||||||
{
|
{
|
||||||
resolved_side = JoinTableSide::Left;
|
resolved_side = JoinTableSide::Left;
|
||||||
auto & left_resolved_column = left_resolved_identifier->as<ColumnNode &>();
|
|
||||||
|
|
||||||
resolved_identifier = left_resolved_identifier;
|
resolved_identifier = left_resolved_identifier;
|
||||||
|
|
||||||
|
if (left_resolved_identifier->getNodeType() != QueryTreeNodeType::COLUMN)
|
||||||
|
{
|
||||||
|
check_nested_column_not_in_using(left_resolved_identifier);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto & left_resolved_column = left_resolved_identifier->as<ColumnNode &>();
|
||||||
auto using_column_node_it = join_using_column_name_to_column_node.find(left_resolved_column.getColumnName());
|
auto using_column_node_it = join_using_column_name_to_column_node.find(left_resolved_column.getColumnName());
|
||||||
if (using_column_node_it != join_using_column_name_to_column_node.end() &&
|
if (using_column_node_it != join_using_column_name_to_column_node.end() &&
|
||||||
!using_column_node_it->second->getColumnType()->equals(*left_resolved_column.getColumnType()))
|
!using_column_node_it->second->getColumnType()->equals(*left_resolved_column.getColumnType()))
|
||||||
@ -3265,16 +3339,20 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromJoin(const IdentifierLoo
|
|||||||
left_resolved_column_clone->setColumnType(using_column_node_it->second->getColumnType());
|
left_resolved_column_clone->setColumnType(using_column_node_it->second->getColumnType());
|
||||||
resolved_identifier = std::move(left_resolved_column_clone);
|
resolved_identifier = std::move(left_resolved_column_clone);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
resolved_identifier = left_resolved_identifier;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (right_resolved_identifier)
|
else if (right_resolved_identifier)
|
||||||
{
|
{
|
||||||
resolved_side = JoinTableSide::Right;
|
resolved_side = JoinTableSide::Right;
|
||||||
auto & right_resolved_column = right_resolved_identifier->as<ColumnNode &>();
|
resolved_identifier = right_resolved_identifier;
|
||||||
|
|
||||||
|
if (right_resolved_identifier->getNodeType() != QueryTreeNodeType::COLUMN)
|
||||||
|
{
|
||||||
|
check_nested_column_not_in_using(right_resolved_identifier);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto & right_resolved_column = right_resolved_identifier->as<ColumnNode &>();
|
||||||
auto using_column_node_it = join_using_column_name_to_column_node.find(right_resolved_column.getColumnName());
|
auto using_column_node_it = join_using_column_name_to_column_node.find(right_resolved_column.getColumnName());
|
||||||
if (using_column_node_it != join_using_column_name_to_column_node.end() &&
|
if (using_column_node_it != join_using_column_name_to_column_node.end() &&
|
||||||
!using_column_node_it->second->getColumnType()->equals(*right_resolved_column.getColumnType()))
|
!using_column_node_it->second->getColumnType()->equals(*right_resolved_column.getColumnType()))
|
||||||
@ -3283,9 +3361,6 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromJoin(const IdentifierLoo
|
|||||||
right_resolved_column_clone->setColumnType(using_column_node_it->second->getColumnType());
|
right_resolved_column_clone->setColumnType(using_column_node_it->second->getColumnType());
|
||||||
resolved_identifier = std::move(right_resolved_column_clone);
|
resolved_identifier = std::move(right_resolved_column_clone);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
resolved_identifier = right_resolved_identifier;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,314 @@
|
|||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[(1,'a')] [(1,'a')]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[(1,'a')] 1
|
||||||
|
[(1,'a')] [1]
|
||||||
|
[1]
|
||||||
|
[1]
|
||||||
|
[1]
|
||||||
|
[1] 1 ['a'] 1 ['a']
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[1]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[('a',1)]
|
||||||
|
1 [1] ['a'] ['a'] [1]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[1]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[('a',1)]
|
||||||
|
1 [1] ['a'] 1 ['a'] [1]
|
||||||
|
(1,'s')
|
||||||
|
(1,'s') 1
|
||||||
|
1
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
('a',1)
|
||||||
|
1 1 (1,'a') 1 ('a',1)
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
('a',1)
|
||||||
|
1 (1,'a') ('a',1)
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
('a',1)
|
||||||
|
1 (1,'a') 1 ('a',1)
|
||||||
|
((((1,'s'),'s'),'s'),'s')
|
||||||
|
((((1,'s'),'s'),'s'),'s')
|
||||||
|
((((2,'s'),'s'),'s'),'s')
|
||||||
|
((((2,'s'),'s'),'s'),'s')
|
||||||
|
((1,'s'),'s')
|
||||||
|
((1,'s'),'s')
|
||||||
|
((2,'s'),'s')
|
||||||
|
((2,'s'),'s')
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
((((3,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
((1,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((2,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
1 UInt32
|
||||||
|
2 UInt32
|
||||||
|
0 UInt32
|
||||||
|
(((1,'s'),'s'),'s') s Tuple(Tuple(Tuple(Int64, String), String), String) String
|
||||||
|
(((2,'s'),'s'),'s') s Tuple(Tuple(Tuple(Int64, String), String), String) String
|
||||||
|
(((3,'s'),'s'),'s') s Tuple(Tuple(Tuple(Int64, String), String), String) String
|
||||||
|
((1,'s'),'s') s Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
((2,'s'),'s') s Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
(1,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(2,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(0,'') Tuple(\n t UInt32,\n s String) String
|
||||||
|
1 s UInt32 String
|
||||||
|
2 s UInt32 String
|
||||||
|
0 UInt32 String
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((0,''),''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((1,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((2,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
1 UInt32
|
||||||
|
2 UInt32
|
||||||
|
0 UInt32
|
||||||
|
(((1,'s'),'s'),'s') s Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
(((2,'s'),'s'),'s') s Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
(((0,''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
((1,'s'),'s') s Tuple(Tuple(Int64, String), String) String
|
||||||
|
((2,'s'),'s') s Tuple(Tuple(Int64, String), String) String
|
||||||
|
((3,'s'),'s') s Tuple(Tuple(Int64, String), String) String
|
||||||
|
(1,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(2,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(0,'') Tuple(\n t UInt32,\n s String) String
|
||||||
|
1 s UInt32 String
|
||||||
|
2 s UInt32 String
|
||||||
|
0 UInt32 String
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((0,''),''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((1,'s'),'s') Tuple(Tuple(Int64, String), String)
|
||||||
|
((2,'s'),'s') Tuple(Tuple(Int64, String), String)
|
||||||
|
((3,'s'),'s') Tuple(Tuple(Int64, String), String)
|
||||||
|
1 UInt32
|
||||||
|
2 UInt32
|
||||||
|
0 UInt32
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((0,''),''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((1,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((2,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
1 Int64
|
||||||
|
2 Int64
|
||||||
|
3 Int64
|
||||||
|
(((1,'s'),'s'),'s') s Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
(((2,'s'),'s'),'s') s Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
(((0,''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
((1,'s'),'s') s Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
((2,'s'),'s') s Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
(1,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(2,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(0,'') Tuple(\n t UInt32,\n s String) String
|
||||||
|
1 s UInt32 String
|
||||||
|
2 s UInt32 String
|
||||||
|
0 UInt32 String
|
||||||
|
[([([([(1,'d')],'d')],'s')],'s')]
|
||||||
|
[[[([(1,'d')],'d')]]]
|
||||||
|
[[[[1]]]]
|
||||||
|
[[([([(1,'d')],'d')],'s')]] Array(Array(Tuple(Array(Tuple(Array(Tuple(Int64, String)), String)), String)))
|
||||||
|
[[[([(1,'d')],'d')]]] Array(Array(Nested(t Nested(t Int32, s String), s String)))
|
||||||
|
[[[[1]]]] Array(Array(Array(Array(Int32))))
|
||||||
|
[[[([(1,'d')],'d')]]] [['s']] Array(Array(Array(Tuple(Array(Tuple(Int64, String)), String)))) Array(Array(String))
|
||||||
|
[[[[(1,'d')]]]] [[['d']]] Array(Array(Array(Array(Tuple(\n t Int32,\n s String))))) Array(Array(Array(String)))
|
||||||
|
[[[[1]]]] [[[['d']]]] Array(Array(Array(Array(Int32)))) Array(Array(Array(Array(String))))
|
||||||
|
[([([([(1,'d')],'d')],'s')],'s')] Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Int32,\n s String)),\n s String)),\n s String)),\n s String))
|
||||||
|
[[([([(1,'d')],'d')],'s')]] Array(Nested(t Nested(t Nested(t Int32, s String), s String), s String))
|
||||||
|
[[[([(1,'d')],'d')]]] Array(Array(Array(Tuple(Array(Tuple(Int64, String)), String))))
|
||||||
|
[[[[1]]]] Array(Array(Array(Array(Int32))))
|
||||||
|
[[([([(1,'d')],'d')],'s')]] ['s'] Array(Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Int32,\n s String)),\n s String)),\n s String))) Array(String)
|
||||||
|
[[[([(1,'d')],'d')]]] [['s']] Array(Array(Array(Tuple(\n t Array(Tuple(\n t Int32,\n s String)),\n s String)))) Array(Array(String))
|
||||||
|
[[[[(1,'d')]]]] [[['d']]] Array(Array(Array(Array(Tuple(Int64, String))))) Array(Array(Array(String)))
|
||||||
|
[[[[1]]]] [[[['d']]]] Array(Array(Array(Array(Int32)))) Array(Array(Array(Array(String))))
|
||||||
|
[([([([(1,'d')],'d')],'s')],'s')] Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Int32,\n s String)),\n s String)),\n s String)),\n s String))
|
||||||
|
[[([([(1,'d')],'d')],'s')]] Array(Nested(t Nested(t Nested(t Int32, s String), s String), s String))
|
||||||
|
[[[([(1,'d')],'d')]]] Array(Array(Nested(t Nested(t Int32, s String), s String)))
|
||||||
|
[[[[1]]]] Array(Array(Array(Array(Int64))))
|
||||||
|
[[[[1]]]] [[[['d']]]]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[(1,'a')] [(1,'a')]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[(1,'a')] 1
|
||||||
|
[(1,'a')] [1]
|
||||||
|
[1]
|
||||||
|
[1]
|
||||||
|
[1]
|
||||||
|
[1] 1 ['a'] 1 ['a']
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[1]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[('a',1)]
|
||||||
|
1 [1] ['a'] ['a'] [1]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[1]
|
||||||
|
[(1,'a')]
|
||||||
|
[1]
|
||||||
|
[('a',1)]
|
||||||
|
1 [1] ['a'] 1 ['a'] [1]
|
||||||
|
(1,'s')
|
||||||
|
(1,'s') 1
|
||||||
|
1
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
('a',1)
|
||||||
|
1 1 (1,'a') 1 ('a',1)
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
('a',1)
|
||||||
|
1 (1,'a') ('a',1)
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(1,'a')
|
||||||
|
1
|
||||||
|
('a',1)
|
||||||
|
1 (1,'a') 1 ('a',1)
|
||||||
|
((((1,'s'),'s'),'s'),'s')
|
||||||
|
((((1,'s'),'s'),'s'),'s')
|
||||||
|
((((2,'s'),'s'),'s'),'s')
|
||||||
|
((((2,'s'),'s'),'s'),'s')
|
||||||
|
((1,'s'),'s')
|
||||||
|
((1,'s'),'s')
|
||||||
|
((2,'s'),'s')
|
||||||
|
((2,'s'),'s')
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
((((3,'s'),'s'),'s'),'s') Tuple(Tuple(Tuple(Tuple(Int64, String), String), String), String)
|
||||||
|
((1,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((2,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
1 Nullable(UInt32)
|
||||||
|
2 Nullable(UInt32)
|
||||||
|
\N Nullable(UInt32)
|
||||||
|
(((1,'s'),'s'),'s') s Tuple(Tuple(Tuple(Int64, String), String), String) String
|
||||||
|
(((2,'s'),'s'),'s') s Tuple(Tuple(Tuple(Int64, String), String), String) String
|
||||||
|
(((3,'s'),'s'),'s') s Tuple(Tuple(Tuple(Int64, String), String), String) String
|
||||||
|
((1,'s'),'s') s Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
((2,'s'),'s') s Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
(1,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(2,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(0,'') Tuple(\n t UInt32,\n s String) String
|
||||||
|
1 s UInt32 String
|
||||||
|
2 s UInt32 String
|
||||||
|
0 UInt32 String
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((0,''),''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((1,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((2,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
1 Nullable(UInt32)
|
||||||
|
2 Nullable(UInt32)
|
||||||
|
\N Nullable(UInt32)
|
||||||
|
(((1,'s'),'s'),'s') s Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
(((2,'s'),'s'),'s') s Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
(((0,''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
((1,'s'),'s') s Tuple(Tuple(Int64, String), String) String
|
||||||
|
((2,'s'),'s') s Tuple(Tuple(Int64, String), String) String
|
||||||
|
((3,'s'),'s') s Tuple(Tuple(Int64, String), String) String
|
||||||
|
(1,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(2,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(0,'') Tuple(\n t UInt32,\n s String) String
|
||||||
|
1 s UInt32 String
|
||||||
|
2 s UInt32 String
|
||||||
|
0 UInt32 String
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((0,''),''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((1,'s'),'s') Tuple(Tuple(Int64, String), String)
|
||||||
|
((2,'s'),'s') Tuple(Tuple(Int64, String), String)
|
||||||
|
((3,'s'),'s') Tuple(Tuple(Int64, String), String)
|
||||||
|
1 Nullable(UInt32)
|
||||||
|
2 Nullable(UInt32)
|
||||||
|
\N Nullable(UInt32)
|
||||||
|
((((1,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((2,'s'),'s'),'s'),'s') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((((0,''),''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String),\n s String)
|
||||||
|
((1,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((2,'s'),'s') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String)
|
||||||
|
1 Nullable(Int64)
|
||||||
|
2 Nullable(Int64)
|
||||||
|
3 Nullable(Int64)
|
||||||
|
(((1,'s'),'s'),'s') s Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
(((2,'s'),'s'),'s') s Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
(((0,''),''),'') Tuple(\n t Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String),\n s String) String
|
||||||
|
((1,'s'),'s') s Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
((2,'s'),'s') s Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
((0,''),'') Tuple(\n t Tuple(\n t UInt32,\n s String),\n s String) String
|
||||||
|
(1,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(2,'s') s Tuple(\n t UInt32,\n s String) String
|
||||||
|
(0,'') Tuple(\n t UInt32,\n s String) String
|
||||||
|
1 s UInt32 String
|
||||||
|
2 s UInt32 String
|
||||||
|
0 UInt32 String
|
||||||
|
[([([([(1,'d')],'d')],'s')],'s')]
|
||||||
|
[[[([(1,'d')],'d')]]]
|
||||||
|
[[[[1]]]]
|
||||||
|
[[([([(1,'d')],'d')],'s')]] Array(Array(Tuple(Array(Tuple(Array(Tuple(Int64, String)), String)), String)))
|
||||||
|
[[[([(1,'d')],'d')]]] Array(Array(Nested(t Nested(t Int32, s String), s String)))
|
||||||
|
[[[[1]]]] Array(Array(Array(Array(Int32))))
|
||||||
|
[[[([(1,'d')],'d')]]] [['s']] Array(Array(Array(Tuple(Array(Tuple(Int64, String)), String)))) Array(Array(String))
|
||||||
|
[[[[(1,'d')]]]] [[['d']]] Array(Array(Array(Array(Tuple(\n t Int32,\n s String))))) Array(Array(Array(String)))
|
||||||
|
[[[[1]]]] [[[['d']]]] Array(Array(Array(Array(Int32)))) Array(Array(Array(Array(String))))
|
||||||
|
[([([([(1,'d')],'d')],'s')],'s')] Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Int32,\n s String)),\n s String)),\n s String)),\n s String))
|
||||||
|
[[([([(1,'d')],'d')],'s')]] Array(Nested(t Nested(t Nested(t Int32, s String), s String), s String))
|
||||||
|
[[[([(1,'d')],'d')]]] Array(Array(Array(Tuple(Array(Tuple(Int64, String)), String))))
|
||||||
|
[[[[1]]]] Array(Array(Array(Array(Int32))))
|
||||||
|
[[([([(1,'d')],'d')],'s')]] ['s'] Array(Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Int32,\n s String)),\n s String)),\n s String))) Array(String)
|
||||||
|
[[[([(1,'d')],'d')]]] [['s']] Array(Array(Array(Tuple(\n t Array(Tuple(\n t Int32,\n s String)),\n s String)))) Array(Array(String))
|
||||||
|
[[[[(1,'d')]]]] [[['d']]] Array(Array(Array(Array(Tuple(Int64, String))))) Array(Array(Array(String)))
|
||||||
|
[[[[1]]]] [[[['d']]]] Array(Array(Array(Array(Int32)))) Array(Array(Array(Array(String))))
|
||||||
|
[([([([(1,'d')],'d')],'s')],'s')] Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Array(Tuple(\n t Int32,\n s String)),\n s String)),\n s String)),\n s String))
|
||||||
|
[[([([(1,'d')],'d')],'s')]] Array(Nested(t Nested(t Nested(t Int32, s String), s String), s String))
|
||||||
|
[[[([(1,'d')],'d')]]] Array(Array(Nested(t Nested(t Int32, s String), s String)))
|
||||||
|
[[[[1]]]] Array(Array(Array(Array(Int64))))
|
||||||
|
[[[[1]]]] [[[['d']]]]
|
@ -0,0 +1,219 @@
|
|||||||
|
DROP TABLE IF EXISTS ta;
|
||||||
|
DROP TABLE IF EXISTS tb;
|
||||||
|
DROP TABLE IF EXISTS ttta;
|
||||||
|
DROP TABLE IF EXISTS tttb;
|
||||||
|
DROP TABLE IF EXISTS na;
|
||||||
|
DROP TABLE IF EXISTS nb;
|
||||||
|
DROP TABLE IF EXISTS nnna;
|
||||||
|
DROP TABLE IF EXISTS nnnb;
|
||||||
|
|
||||||
|
CREATE table ta (x Int32, t Tuple(t UInt32, s String)) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO ta VALUES (1, (1, 'a'));
|
||||||
|
|
||||||
|
CREATE table tb (x Int32, t Tuple(s String, t Int32)) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO tb VALUES (1, ('a', 1));
|
||||||
|
|
||||||
|
CREATE table ttta (x Int32, t Tuple(t Tuple(t Tuple(t Tuple(t UInt32, s String), s String), s String), s String)) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO ttta VALUES (1, ((((1, 's'), 's'), 's'), 's')), (2, ((((2, 's'), 's'), 's'), 's'));
|
||||||
|
|
||||||
|
CREATE table tttb (x Int32, t Tuple(t Tuple(t Tuple(t Tuple(t Int32, s String), s String), s String), s String)) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO tttb VALUES (2, ((((2, 's'), 's'), 's'), 's')), (3, ((((3, 's'), 's'), 's'), 's'));
|
||||||
|
|
||||||
|
CREATE table na (x Int32, t Nested(t UInt32, s String)) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO na VALUES (1, [1], ['a']);
|
||||||
|
|
||||||
|
CREATE table nb (x Int32, t Nested(s String, t Int32)) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO nb VALUES (1, ['a'], [1]);
|
||||||
|
|
||||||
|
CREATE TABLE nnna ( x UInt64, t Nested(t Nested(t Nested(t Nested(t Int32, s String), s String), s String), s String) ) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO nnna VALUES (1, [[([([(1,'d')],'d')], 's')]], ['s']);
|
||||||
|
|
||||||
|
CREATE TABLE nnnb ( x UInt64, t Nested(t Nested(t Nested(t Nested(t UInt32, s String), s String), s String), s String) ) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO nnnb VALUES (1, [[([([(1,'d')],'d')], 's')]], ['s']);
|
||||||
|
|
||||||
|
SET allow_experimental_analyzer = 1;
|
||||||
|
|
||||||
|
{% for join_use_nulls in [0, 1] -%}
|
||||||
|
|
||||||
|
SET join_use_nulls = {{ join_use_nulls }};
|
||||||
|
|
||||||
|
SELECT t FROM (SELECT [(1, 'a')] :: Nested(t UInt32, s String) AS t) AS na, (SELECT [(1, 'a')] :: Nested(t Int32, s String) AS t) AS t;
|
||||||
|
SELECT na.t.t FROM (SELECT [(1, 'a')] :: Nested(t UInt32, s String) AS t) AS na, (SELECT [(1, 'a')] :: Nested(t Int32, s String) AS t) AS t;
|
||||||
|
SELECT * FROM (SELECT [(1, 'a')] :: Nested(t UInt32, s String) AS t) AS na, (SELECT [(1, 'a')] :: Nested(t Int32, s String) AS t) AS t;
|
||||||
|
|
||||||
|
SELECT t FROM (SELECT [(1, 'a')] :: Nested(t UInt32, s String) AS t) AS na, (SELECT 1 AS t) AS t;
|
||||||
|
SELECT na.t.t FROM (SELECT [(1, 'a')] :: Nested(t UInt32, s String) AS t) AS na, (SELECT 1 AS t) AS t;
|
||||||
|
SELECT * FROM (SELECT [(1, 'a')] :: Nested(t UInt32, s String) AS t) AS na, (SELECT 1 AS t) AS t;
|
||||||
|
|
||||||
|
SELECT * FROM (SELECT [(1, 'a')] :: Nested(t UInt32, s String) AS t) AS na FULL JOIN (SELECT [1] :: Array(Int32) AS t) AS nb ON nb.t = na.t.t;
|
||||||
|
|
||||||
|
SELECT t FROM na FULL JOIN nb USING (t.t); -- { serverError AMBIGUOUS_IDENTIFIER }
|
||||||
|
SELECT t.t FROM na FULL JOIN nb USING (t.t);
|
||||||
|
SELECT na.t.t FROM na FULL JOIN nb USING (t.t);
|
||||||
|
SELECT na.t FROM na FULL JOIN nb USING (t.t); -- { serverError AMBIGUOUS_IDENTIFIER }
|
||||||
|
SELECT nb.t.t FROM na FULL JOIN nb USING (t.t);
|
||||||
|
SELECT nb.t FROM na FULL JOIN nb USING (t.t); -- { serverError AMBIGUOUS_IDENTIFIER }
|
||||||
|
SELECT * FROM na FULL JOIN nb USING (t.t);
|
||||||
|
|
||||||
|
SELECT t FROM na FULL JOIN nb USING (x);
|
||||||
|
SELECT t.t FROM na FULL JOIN nb USING (x);
|
||||||
|
SELECT na.t.t FROM na FULL JOIN nb USING (x);
|
||||||
|
SELECT na.t FROM na FULL JOIN nb USING (x);
|
||||||
|
SELECT nb.t.t FROM na FULL JOIN nb USING (x);
|
||||||
|
SELECT nb.t FROM na FULL JOIN nb USING (x);
|
||||||
|
SELECT * FROM na FULL JOIN nb USING (x);
|
||||||
|
|
||||||
|
SELECT t FROM na, nb;
|
||||||
|
SELECT t.t FROM na, nb;
|
||||||
|
SELECT na.t.t FROM na, nb;
|
||||||
|
SELECT na.t FROM na, nb;
|
||||||
|
SELECT nb.t.t FROM na, nb;
|
||||||
|
SELECT nb.t FROM na, nb;
|
||||||
|
SELECT * FROM na, nb;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
SELECT * FROM (SELECT (1, 's') :: Tuple(t Int32, s String) as t ) as na FULL JOIN (SELECT (1, 's') :: Tuple(t UInt32, s String) as t ) as nb USING (t);
|
||||||
|
SELECT * FROM (SELECT (1, 's') :: Tuple(t Int32, s String) as t ) as na, (SELECT 1 as t ) as t;
|
||||||
|
|
||||||
|
SELECT t.t FROM (SELECT (1, 's') :: Tuple(t Int32, s String) as t ) as na, (SELECT 1 as t ) as t;
|
||||||
|
|
||||||
|
SELECT t.t FROM (SELECT (1, 's') :: Tuple(t Int32, s String) as t ) as na FULL JOIN (SELECT (1, 's') :: Tuple(t UInt32, s String) as t ) as nb USING (t); -- { serverError AMBIGUOUS_IDENTIFIER }
|
||||||
|
SELECT * FROM (SELECT (1, 's') :: Tuple(t Int32, s String) as t ) as na FULL JOIN (SELECT (1, 's') :: Tuple(t UInt32, s String) as t ) as nb USING (t.t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM (
|
||||||
|
SELECT ((((1, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t UInt32, s String), s String), s String), s String) as t
|
||||||
|
) ttta FULL JOIN (
|
||||||
|
SELECT ((((2, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t Int32, s String), s String), s String), s String) as t
|
||||||
|
) tttb USING (t.t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
|
||||||
|
SELECT t.t as e, toTypeName(e) FROM (
|
||||||
|
SELECT ((((1, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t UInt32, s String), s String), s String), s String) as t
|
||||||
|
) ttta FULL JOIN (
|
||||||
|
SELECT ((((2, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t Int32, s String), s String), s String), s String) as t
|
||||||
|
) tttb USING (t.t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM (
|
||||||
|
SELECT ((((1, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t UInt32, s String), s String), s String), s String) as t
|
||||||
|
) ttta FULL JOIN (
|
||||||
|
SELECT ((((2, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t Int32, s String), s String), s String), s String) as t
|
||||||
|
) tttb USING (t.t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM (
|
||||||
|
SELECT ((((1, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t UInt32, s String), s String), s String), s String) as t
|
||||||
|
) ttta FULL JOIN (
|
||||||
|
SELECT ((((2, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t Int32, s String), s String), s String), s String) as t
|
||||||
|
) tttb USING (t);
|
||||||
|
|
||||||
|
SELECT t.t as e, toTypeName(e) FROM (
|
||||||
|
SELECT ((((1, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t UInt32, s String), s String), s String), s String) as t
|
||||||
|
) ttta FULL JOIN (
|
||||||
|
SELECT ((((2, 's'), 's'), 's'), 's') :: Tuple(t Tuple(t Tuple(t Tuple(t Int32, s String), s String), s String), s String) as t
|
||||||
|
) tttb USING (t); -- { serverError AMBIGUOUS_IDENTIFIER }
|
||||||
|
|
||||||
|
SELECT t FROM ta FULL JOIN tb USING (t.t);
|
||||||
|
SELECT t.t FROM ta FULL JOIN tb USING (t.t);
|
||||||
|
SELECT ta.t.t FROM ta FULL JOIN tb USING (t.t);
|
||||||
|
SELECT ta.t FROM ta FULL JOIN tb USING (t.t);
|
||||||
|
SELECT tb.t.t FROM ta FULL JOIN tb USING (t.t);
|
||||||
|
SELECT tb.t FROM ta FULL JOIN tb USING (t.t);
|
||||||
|
SELECT * FROM ta FULL JOIN tb USING (t.t);
|
||||||
|
|
||||||
|
SELECT t FROM ta FULL JOIN tb USING (x);
|
||||||
|
SELECT t.t FROM ta FULL JOIN tb USING (x);
|
||||||
|
SELECT ta.t.t FROM ta FULL JOIN tb USING (x);
|
||||||
|
SELECT ta.t FROM ta FULL JOIN tb USING (x);
|
||||||
|
SELECT tb.t.t FROM ta FULL JOIN tb USING (x);
|
||||||
|
SELECT tb.t FROM ta FULL JOIN tb USING (x);
|
||||||
|
SELECT * FROM ta FULL JOIN tb USING (x);
|
||||||
|
|
||||||
|
SELECT t FROM ta, tb;
|
||||||
|
SELECT t.t FROM ta, tb;
|
||||||
|
SELECT ta.t.t FROM ta, tb;
|
||||||
|
SELECT ta.t FROM ta, tb;
|
||||||
|
SELECT tb.t.t FROM ta, tb;
|
||||||
|
SELECT tb.t FROM ta, tb;
|
||||||
|
SELECT * FROM ta, tb;
|
||||||
|
|
||||||
|
SELECT t FROM ttta, tttb;
|
||||||
|
SELECT t.t.t FROM ttta, tttb;
|
||||||
|
SELECT t.t.t.t.t FROM ttta, tttb;
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t);
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t);
|
||||||
|
SELECT t.t.t.t.t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t);
|
||||||
|
|
||||||
|
SELECT t.*, t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t);
|
||||||
|
SELECT t.t.*, t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t);
|
||||||
|
SELECT t.t.t.*, t.t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t);
|
||||||
|
SELECT t.t.t.t.*, t.t.t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t);
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t);
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t);
|
||||||
|
SELECT t.t.t.t.t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t);
|
||||||
|
|
||||||
|
SELECT t.*, t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t.t);
|
||||||
|
SELECT t.t.*, t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t.t);
|
||||||
|
SELECT t.t.t.*, t.t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t.t);
|
||||||
|
SELECT t.t.t.t.*, t.t.t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t.t);
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t.t);
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t.t);
|
||||||
|
SELECT t.t.t.t.t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t.t);
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t.t.t.t as e, toTypeName(e) FROM ttta FULL JOIN tttb USING (t.t.t.t.t);
|
||||||
|
|
||||||
|
SELECT t.*, t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t.*, t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t.t.*, t.t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t.t.t.*, t.t.t.t.* APPLY toTypeName FROM ttta FULL JOIN tttb USING (t.t.t.t.t);
|
||||||
|
|
||||||
|
SELECT t FROM nnna, nnnb;
|
||||||
|
SELECT t.t.t FROM nnna, nnnb;
|
||||||
|
SELECT t.t.t.t.t FROM nnna, nnnb;
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
SELECT t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
SELECT t.t.t.t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t); -- { serverError AMBIGUOUS_IDENTIFIER }
|
||||||
|
SELECT t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t);
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t);
|
||||||
|
SELECT t.t.t.t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t);
|
||||||
|
|
||||||
|
SELECT t.*, t.* APPLY toTypeName FROM nnna FULL JOIN nnnb USING (t.t); -- { serverError AMBIGUOUS_IDENTIFIER }
|
||||||
|
SELECT t.t.*, t.t.* APPLY toTypeName FROM nnna FULL JOIN nnnb USING (t.t);
|
||||||
|
SELECT t.t.t.*, t.t.t.* APPLY toTypeName FROM nnna FULL JOIN nnnb USING (t.t);
|
||||||
|
SELECT t.t.t.t.*, t.t.t.t.* APPLY toTypeName FROM nnna FULL JOIN nnnb USING (t.t);
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t.t);
|
||||||
|
SELECT t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t.t);
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t.t);
|
||||||
|
SELECT t.t.t.t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t.t);
|
||||||
|
|
||||||
|
SELECT t.*, t.* APPLY toTypeName FROM nnna FULL JOIN nnnb USING (t.t.t);
|
||||||
|
SELECT t.t.*, t.t.* APPLY toTypeName FROM nnna FULL JOIN nnnb USING (t.t.t);
|
||||||
|
SELECT t.t.t.*, t.t.t.* APPLY toTypeName FROM nnna FULL JOIN nnnb USING (t.t.t);
|
||||||
|
SELECT t.t.t.t.*, t.t.t.t.* APPLY toTypeName FROM nnna FULL JOIN nnnb USING (t.t.t);
|
||||||
|
|
||||||
|
SELECT t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t.t.t.t as e, toTypeName(e) FROM nnna FULL JOIN nnnb USING (t.t.t.t.t);
|
||||||
|
SELECT t.t.t.t.* FROM nnna FULL JOIN nnnb USING (t.t.t.t.t);
|
||||||
|
|
||||||
|
SELECT 1 FROM na FULL JOIN nb USING (t); -- { serverError UNSUPPORTED_METHOD }
|
||||||
|
|
||||||
|
{% endfor -%}
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS ta;
|
||||||
|
DROP TABLE IF EXISTS tb;
|
||||||
|
DROP TABLE IF EXISTS ttta;
|
||||||
|
DROP TABLE IF EXISTS tttb;
|
||||||
|
DROP TABLE IF EXISTS na;
|
||||||
|
DROP TABLE IF EXISTS nb;
|
||||||
|
DROP TABLE IF EXISTS nnna;
|
||||||
|
DROP TABLE IF EXISTS nnnb;
|
Loading…
Reference in New Issue
Block a user