@@ -84,7 +84,7 @@ std::pair<TExprNode::TPtr, TExprNode::TPtr> SplitByPredicate(TPositionHandle pos
84
84
}
85
85
86
86
TExprNode::TPtr JoinColumns (TPositionHandle pos, const TExprNode::TPtr& list1, const TExprNode::TPtr& list2,
87
- TExprNode::TPtr leftJoinColumns, ui32 subLinkId, TExprContext& ctx, const TString& leftPrefix = {}) {
87
+ TExprNode::TPtr leftJoinColumns, TMaybe< ui32> subLinkId, TExprContext& ctx, const TString& leftPrefix = {}) {
88
88
auto join = ctx.Builder (pos)
89
89
.Callable (" EquiJoin" )
90
90
.List (0 )
@@ -116,8 +116,8 @@ TExprNode::TPtr JoinColumns(TPositionHandle pos, const TExprNode::TPtr& list1, c
116
116
if (leftJoinColumns) {
117
117
for (ui32 i = 0 ; i < leftJoinColumns->ChildrenSize (); ++i) {
118
118
parent.Atom (2 * i, " b" );
119
- parent.Atom (2 * i + 1 , TString (" _yql_join_sublink_" ) + ToString (subLinkId) +
120
- " _" + leftJoinColumns->Child (i)->Content () );
119
+ parent.Atom (2 * i + 1 , subLinkId ? TString (" _yql_join_sublink_" ) + ToString (* subLinkId) +
120
+ " _" + leftJoinColumns->Child (i)->Content () : leftJoinColumns-> ChildPtr (i)-> Content () );
121
121
}
122
122
}
123
123
@@ -133,8 +133,8 @@ TExprNode::TPtr JoinColumns(TPositionHandle pos, const TExprNode::TPtr& list1, c
133
133
for (ui32 i = 0 ; i < leftJoinColumns->ChildrenSize (); ++i) {
134
134
parent.List (i)
135
135
.Atom (0 , " rename" )
136
- .Atom (1 , TString (" b._yql_join_sublink_" ) + ToString (subLinkId) +
137
- " _" + leftJoinColumns->Child (i)->Content ())
136
+ .Atom (1 , TString (" b." ) + (subLinkId ? ( TString ( " _yql_join_sublink_" ) + ToString (* subLinkId) +
137
+ " _" ) : " " ) + leftJoinColumns->Child (i)->Content ())
138
138
.Atom (2 , " " )
139
139
.Seal ();
140
140
}
@@ -1335,7 +1335,7 @@ TExprNode::TPtr BuildSingleInputPredicateJoin(TPositionHandle pos, TStringBuf jo
1335
1335
.Seal ()
1336
1336
.Build ();
1337
1337
1338
- auto main = JoinColumns (pos, filteredLeft, right, nullptr , 0 , ctx);
1338
+ auto main = JoinColumns (pos, filteredLeft, right, nullptr , {} , ctx);
1339
1339
1340
1340
auto extraLeft = [&]() {
1341
1341
return ctx.Builder (pos)
@@ -1514,7 +1514,7 @@ std::tuple<TVector<ui32>, TExprNode::TListType> BuildJoinGroups(TPositionHandle
1514
1514
// current = join current & with
1515
1515
auto join = groupTuple->Child (i);
1516
1516
auto joinType = join->Child (0 )->Content ();
1517
- auto cartesian = JoinColumns (pos, current, with, nullptr , 0 , ctx);
1517
+ auto cartesian = JoinColumns (pos, current, with, nullptr , {} , ctx);
1518
1518
if (joinType == " cross" ) {
1519
1519
current = cartesian;
1520
1520
continue ;
@@ -1944,7 +1944,8 @@ TExprNode::TPtr BuildAggregationTraits(TPositionHandle pos, bool onWindow, const
1944
1944
1945
1945
TExprNode::TPtr BuildGroup (TPositionHandle pos, TExprNode::TPtr list,
1946
1946
const TAggs& aggs, const TExprNode::TPtr& groupExprs, const TExprNode::TPtr& groupSets,
1947
- const TExprNode::TPtr& finalExtTypes, TExprContext& ctx, TOptimizeContext& optCtx) {
1947
+ const TExprNode::TPtr& finalExtTypes, const TExprNode::TPtr& joinedUniqueExt,
1948
+ TExprContext& ctx, TOptimizeContext& optCtx) {
1948
1949
1949
1950
bool needRemapForDistinct = false ;
1950
1951
for (ui32 i = 0 ; i < aggs.size (); ++i) {
@@ -2008,7 +2009,12 @@ TExprNode::TPtr BuildGroup(TPositionHandle pos, TExprNode::TPtr list,
2008
2009
.Build ();
2009
2010
2010
2011
TExprNode::TListType payloadItems;
2012
+ TVector<ui32> nonNullDefAggs;
2011
2013
for (ui32 i = 0 ; i < aggs.size (); ++i) {
2014
+ if (aggs[i].first ->Head ().Content () == " count" && aggs[i].first ->ChildrenSize () == 2 ) {
2015
+ nonNullDefAggs.push_back (i);
2016
+ }
2017
+
2012
2018
const bool distinct = GetSetting (*aggs[i].first ->Child (1 ), " distinct" ) != nullptr ;
2013
2019
auto traits = BuildAggregationTraits (pos, false , distinct ? " _yql_distinct_" + ToString (i) : " " , aggs[i], listTypeNode, nullptr , ctx, optCtx);
2014
2020
if (distinct) {
@@ -2129,6 +2135,50 @@ TExprNode::TPtr BuildGroup(TPositionHandle pos, TExprNode::TPtr list,
2129
2135
.Seal ()
2130
2136
.Build ();
2131
2137
2138
+ if (!extKeysItems.empty () && !nonNullDefAggs.empty ()) {
2139
+ // restore aggregation keys
2140
+ auto joinColumns = ctx.NewList (pos, TExprNode::TListType (extKeysItems));
2141
+ auto joined = JoinColumns (pos, joinedUniqueExt, aggregate, joinColumns, {}, ctx);
2142
+
2143
+ auto pgZero = ctx.Builder (pos)
2144
+ .Callable (" PgConst" )
2145
+ .Atom (0 , " 0" )
2146
+ .Callable (1 , " PgType" )
2147
+ .Atom (0 , " int8" )
2148
+ .Seal ()
2149
+ .Seal ()
2150
+ .Build ();
2151
+
2152
+ auto arg = ctx.NewArgument (pos, " row" );
2153
+ auto root = arg;
2154
+ for (ui32 i = 0 ; i < nonNullDefAggs.size (); ++i) {
2155
+ auto column = ToString (" _yql_agg_" ) + ToString (nonNullDefAggs[i]);
2156
+ root = ctx.Builder (pos)
2157
+ .Callable (" ReplaceMember" )
2158
+ .Add (0 , root)
2159
+ .Atom (1 , column)
2160
+ .Callable (2 , " Coalesce" )
2161
+ .Callable (0 , " Member" )
2162
+ .Add (0 , root)
2163
+ .Atom (1 , column)
2164
+ .Seal ()
2165
+ .Add (1 , pgZero)
2166
+ .Seal ()
2167
+ .Seal ()
2168
+ .Build ();
2169
+ }
2170
+
2171
+ auto coalesceLambda = ctx.NewLambda (pos, ctx.NewArguments (pos, { arg }), std::move (root));
2172
+
2173
+ // replace nulls with def values
2174
+ aggregate = ctx.Builder (pos)
2175
+ .Callable (" OrderedMap" )
2176
+ .Add (0 , joined)
2177
+ .Add (1 , coalesceLambda)
2178
+ .Seal ()
2179
+ .Build ();
2180
+ }
2181
+
2132
2182
if (currentKeys.size () < groupExprs->Tail ().ChildrenSize ()) {
2133
2183
// mark missing columns
2134
2184
aggregate = ctx.Builder (pos)
@@ -2971,12 +3021,13 @@ TExprNode::TPtr RemoveExtraSortColumns(const TExprNode::TPtr& list, const TExprN
2971
3021
.Build ();
2972
3022
}
2973
3023
2974
- TExprNode::TPtr JoinOuter (TPositionHandle pos, TExprNode::TPtr list,
3024
+ std::pair< TExprNode::TPtr, TExprNode::TPtr> JoinOuter (TPositionHandle pos, TExprNode::TPtr list,
2975
3025
const TExprNode::TPtr& finalExtTypes, const TExprNode::TListType& outerInputs,
2976
3026
const TVector<TString>& outerInputAliases,
2977
3027
TExprNode::TListType& cleanedInputs, TVector<TString>& inputAliases, TExprContext& ctx) {
2978
3028
YQL_ENSURE (finalExtTypes);
2979
3029
YQL_ENSURE (outerInputs.size () == finalExtTypes->Tail ().ChildrenSize ());
3030
+ TExprNode::TPtr joinedUniqueExt;
2980
3031
for (ui32 index = 0 ; index < finalExtTypes->Tail ().ChildrenSize (); ++index ) {
2981
3032
const auto & input = finalExtTypes->Tail ().Child (index );
2982
3033
const auto & inputAlias = input->Head ().Content ();
@@ -3018,10 +3069,18 @@ TExprNode::TPtr JoinOuter(TPositionHandle pos, TExprNode::TPtr list,
3018
3069
.Seal ()
3019
3070
.Build ();
3020
3071
3021
- list = JoinColumns (pos, list, uniqueOuterInput, nullptr , 0 , ctx);
3072
+ if (!joinedUniqueExt) {
3073
+ joinedUniqueExt = uniqueOuterInput;
3074
+ } else {
3075
+ joinedUniqueExt = JoinColumns (pos, joinedUniqueExt, uniqueOuterInput, nullptr , {}, ctx);
3076
+ }
3077
+ }
3078
+
3079
+ if (joinedUniqueExt) {
3080
+ list = JoinColumns (pos, list, joinedUniqueExt, nullptr , {}, ctx);
3022
3081
}
3023
3082
3024
- return list;
3083
+ return { list, joinedUniqueExt } ;
3025
3084
}
3026
3085
3027
3086
TExprNode::TPtr CombineSetItems (TPositionHandle pos, const TExprNode::TPtr& left, const TExprNode::TPtr& right, const TStringBuf& op, TExprContext& ctx) {
@@ -3328,8 +3387,9 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
3328
3387
}
3329
3388
}
3330
3389
3390
+ TExprNode::TPtr joinedUniqueExt;
3331
3391
if (!outerInputs.empty () && finalExtTypes && 0 < finalExtTypes->Tail ().ChildrenSize ()) {
3332
- list = JoinOuter (node->Pos (), list, finalExtTypes, outerInputs, outerInputAliases, cleanedInputs, inputAliases, ctx);
3392
+ std::tie ( list, joinedUniqueExt) = JoinOuter (node->Pos (), list, finalExtTypes, outerInputs, outerInputAliases, cleanedInputs, inputAliases, ctx);
3333
3393
}
3334
3394
3335
3395
if (filter) {
@@ -3368,7 +3428,7 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
3368
3428
}
3369
3429
3370
3430
if (groupExprs) {
3371
- list = BuildGroup (node->Pos (), list, aggs, groupExprs, groupSets, finalExtTypes, ctx, optCtx);
3431
+ list = BuildGroup (node->Pos (), list, aggs, groupExprs, groupSets, finalExtTypes, joinedUniqueExt, ctx, optCtx);
3372
3432
}
3373
3433
3374
3434
if (having) {
0 commit comments