1
1
#include " type_ann_match_recognize.h"
2
2
3
+ #include < yql/essentials/core/expr_nodes/yql_expr_nodes.h>
3
4
#include < yql/essentials/core/sql_types/match_recognize.h>
4
5
#include < yql/essentials/core/yql_match_recognize.h>
5
6
6
7
namespace NYql ::NTypeAnnImpl {
7
8
9
+ using namespace NNodes ;
10
+
8
11
namespace {
9
12
10
13
const TStructExprType* GetMatchedRowsRangesType (const TExprNode::TPtr& patternVars, TContext &ctx) {
@@ -72,15 +75,14 @@ IGraphTransformer::TStatus MatchRecognizeWrapper(const TExprNode::TPtr& input, T
72
75
return IGraphTransformer::TStatus::Ok;
73
76
}
74
77
75
- IGraphTransformer::TStatus MatchRecognizeMeasuresAggregatesWrapper (const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
76
- if (!EnsureMinArgsCount (*input, 4 , ctx.Expr )) {
78
+ IGraphTransformer::TStatus MatchRecognizeMeasuresCallablesWrapper (const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
79
+ if (!EnsureArgsCount (*input, 4 , ctx.Expr )) {
77
80
return IGraphTransformer::TStatus::Error;
78
81
}
79
82
const auto inputRowType = input->Child (0 );
80
83
const auto patternVars = input->Child (1 );
81
84
const auto names = input->Child (2 );
82
- const auto vars = input->Child (3 );
83
- constexpr size_t FirstLambdaIndex = 4 ;
85
+ const auto callablesItems = input->Child (3 );
84
86
85
87
if (!EnsureType (*inputRowType, ctx.Expr )) {
86
88
return IGraphTransformer::TStatus::Error;
@@ -91,42 +93,85 @@ IGraphTransformer::TStatus MatchRecognizeMeasuresAggregatesWrapper(const TExprNo
91
93
if (!EnsureTupleOfAtoms (*names, ctx.Expr )) {
92
94
return IGraphTransformer::TStatus::Error;
93
95
}
94
- if (!EnsureTupleOfAtoms (*vars , ctx.Expr )) {
96
+ if (!EnsureTupleSize (*callablesItems, names-> ChildrenSize () , ctx.Expr )) {
95
97
return IGraphTransformer::TStatus::Error;
96
98
}
97
- if (!EnsureArgsCount (*vars, names->ChildrenSize (), ctx.Expr )) {
99
+
100
+ TVector<const TItemExprType*> items;
101
+ for (size_t i = 0 ; i < callablesItems->ChildrenSize (); ++i) {
102
+ const auto name = names->Child (i)->Content ();
103
+ const auto type = callablesItems->Child (i)->GetTypeAnn ();
104
+ items.push_back (ctx.Expr .MakeType <TItemExprType>(name, type));
105
+ }
106
+ input->SetTypeAnn (ctx.Expr .MakeType <TStructExprType>(items));
107
+ return IGraphTransformer::TStatus::Ok;
108
+ }
109
+
110
+ IGraphTransformer::TStatus MatchRecognizeMeasuresCallableWrapper (const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
111
+ if (!EnsureArgsCount (*input, 3 , ctx.Expr )) {
98
112
return IGraphTransformer::TStatus::Error;
99
113
}
100
- if (!EnsureArgsCount (*input, FirstLambdaIndex + names->ChildrenSize (), ctx.Expr )) {
114
+ auto & lambda = input->ChildRef (0 );
115
+ const auto vars = input->Child (1 );
116
+ const auto aggregates = input->Child (2 );
117
+
118
+ if (!EnsureTuple (*aggregates, ctx.Expr )) {
119
+ return IGraphTransformer::TStatus::Error;
120
+ }
121
+ if (!EnsureTupleOfAtoms (*vars, ctx.Expr )) {
122
+ return IGraphTransformer::TStatus::Error;
123
+ }
124
+ if (!EnsureTupleSize (*aggregates, vars->ChildrenSize (), ctx.Expr )) {
101
125
return IGraphTransformer::TStatus::Error;
102
126
}
103
127
104
128
TVector<const TItemExprType*> items;
105
- for (size_t i = 0 ; i < names->ChildrenSize (); ++i) {
106
- auto lambda = input->Child (FirstLambdaIndex + i);
107
- if (const auto varName = vars->Child (i)->Content ()) {
108
- const auto traits = input->Child (FirstLambdaIndex + i);
109
- if (!EnsureTupleMinSize (*traits, 2 , ctx.Expr )) {
110
- return IGraphTransformer::TStatus::Error;
111
- }
112
- if (!EnsureTupleMaxSize (*traits, 3 , ctx.Expr )) {
113
- return IGraphTransformer::TStatus::Error;
114
- }
115
- if (!EnsureAtom (traits->Head (), ctx.Expr )) {
116
- return IGraphTransformer::TStatus::Error;
117
- }
118
- lambda = traits->Child (1 )->Child (NNodes::TCoAggregationTraits::idx_FinishHandler);
129
+ for (const auto & aggregate : aggregates->Children ()) {
130
+ if (!EnsureTupleMinSize (*aggregate, 2 , ctx.Expr )) {
131
+ return IGraphTransformer::TStatus::Error;
119
132
}
120
- if (auto type = lambda-> GetTypeAnn ( )) {
121
- if (type-> GetKind () != ETypeAnnotationKind::Optional) {
122
- type = ctx. Expr . MakeType <TOptionalExprType>(type);
123
- }
124
- items. push_back (ctx. Expr . MakeType <TItemExprType>(names ->Child (i)-> Content (), type) );
125
- } else {
126
- return IGraphTransformer::TStatus::Repeat ;
133
+ if (! EnsureTupleMaxSize (*aggregate, 3 , ctx. Expr )) {
134
+ return IGraphTransformer::TStatus::Error;
135
+ }
136
+
137
+ const auto key = aggregate ->Child (0 );
138
+ if (! EnsureAtom (*key, ctx. Expr )) {
139
+ return IGraphTransformer::TStatus::Error ;
127
140
}
141
+
142
+ const auto traits = aggregate->Child (1 );
143
+ if (!traits->IsCallable (TCoAggregationTraits::CallableName ())) {
144
+ ctx.Expr .AddError (TIssue (ctx.Expr .GetPosition (aggregate->Pos ()), TStringBuilder ()
145
+ << " Expected AggregationTraits, but got: " << aggregate->Content ()));
146
+ return IGraphTransformer::TStatus::Error;
147
+ }
148
+
149
+ if (aggregate->ChildrenSize () == 3 && !EnsureAtom (*aggregate->Child (2 ), ctx.Expr )) {
150
+ return IGraphTransformer::TStatus::Error;
151
+ }
152
+
153
+ auto finishType = traits->Child (TCoAggregationTraits::idx_DefVal)->IsCallable (" Null" )
154
+ ? traits->Child (TCoAggregationTraits::idx_FinishHandler)->GetTypeAnn ()
155
+ : traits->Child (TCoAggregationTraits::idx_DefVal)->GetTypeAnn ();
156
+ if (!finishType->IsOptionalOrNull ()) {
157
+ finishType = ctx.Expr .MakeType <TOptionalExprType>(finishType);
158
+ }
159
+ items.push_back (ctx.Expr .MakeType <TItemExprType>(key->Content (), finishType));
128
160
}
129
- input->SetTypeAnn (ctx.Expr .MakeType <TStructExprType>(items));
161
+ const auto status = ConvertToLambda (lambda, ctx.Expr , 1 , 1 );
162
+ if (status != IGraphTransformer::TStatus::Ok) {
163
+ return status;
164
+ }
165
+ if (!UpdateLambdaAllArgumentsTypes (lambda, {ctx.Expr .MakeType <TStructExprType>(items)}, ctx.Expr )) {
166
+ return IGraphTransformer::TStatus::Error;
167
+ }
168
+ if (!lambda->GetTypeAnn ()) {
169
+ return IGraphTransformer::TStatus::Repeat;
170
+ }
171
+ if (!EnsureComputableType (lambda->Pos (), *lambda->GetTypeAnn (), ctx.Expr )) {
172
+ return IGraphTransformer::TStatus::Error;
173
+ }
174
+ input->SetTypeAnn (lambda->GetTypeAnn ());
130
175
return IGraphTransformer::TStatus::Ok;
131
176
}
132
177
@@ -140,13 +185,13 @@ IGraphTransformer::TStatus MatchRecognizeParamsWrapper(const TExprNode::TPtr& in
140
185
}
141
186
142
187
IGraphTransformer::TStatus MatchRecognizeMeasuresWrapper (const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
143
- if (!EnsureMinArgsCount (*input, 3 , ctx.Expr )) {
188
+ constexpr size_t FirstLambdaIndex = 3 ;
189
+ if (!EnsureMinArgsCount (*input, FirstLambdaIndex, ctx.Expr )) {
144
190
return IGraphTransformer::TStatus::Error;
145
191
}
146
192
const auto inputRowType = input->Child (0 );
147
193
const auto patternVars = input->Child (1 );
148
194
const auto names = input->Child (2 );
149
- constexpr size_t FirstLambdaIndex = 3 ;
150
195
151
196
if (!EnsureType (*inputRowType, ctx.Expr )) {
152
197
return IGraphTransformer::TStatus::Error;
@@ -190,11 +235,13 @@ IGraphTransformer::TStatus MatchRecognizeMeasuresWrapper(const TExprNode::TPtr&
190
235
ctx.Expr )) {
191
236
return IGraphTransformer::TStatus::Error;
192
237
}
193
- if (auto type = lambda->GetTypeAnn ()) {
194
- items.push_back (ctx.Expr .MakeType <TItemExprType>(names->Child (i)->Content (), type));
195
- } else {
238
+ if (!lambda->GetTypeAnn ()) {
196
239
return IGraphTransformer::TStatus::Repeat;
197
240
}
241
+ if (!EnsureComputableType (lambda->Pos (), *lambda->GetTypeAnn (), ctx.Expr )) {
242
+ return IGraphTransformer::TStatus::Error;
243
+ }
244
+ items.push_back (ctx.Expr .MakeType <TItemExprType>(names->Child (i)->Content (), lambda->GetTypeAnn ()));
198
245
}
199
246
input->SetTypeAnn (ctx.Expr .MakeType <TStructExprType>(items));
200
247
return IGraphTransformer::TStatus::Ok;
@@ -206,13 +253,13 @@ IGraphTransformer::TStatus MatchRecognizePatternWrapper(const TExprNode::TPtr& i
206
253
}
207
254
208
255
IGraphTransformer::TStatus MatchRecognizeDefinesWrapper (const TExprNode::TPtr& input, TExprNode::TPtr&, TContext &ctx) {
209
- if (!EnsureMinArgsCount (*input, 3 , ctx.Expr )) {
256
+ constexpr size_t FirstLambdaIndex = 3 ;
257
+ if (!EnsureMinArgsCount (*input, FirstLambdaIndex, ctx.Expr )) {
210
258
return IGraphTransformer::TStatus::Error;
211
259
}
212
260
const auto inputRowType = input->Child (0 );
213
261
const auto patternVars = input->Child (1 );
214
262
const auto names = input->Child (2 );
215
- constexpr size_t FirstLambdaIndex = 3 ;
216
263
217
264
if (!EnsureType (*inputRowType, ctx.Expr )) {
218
265
return IGraphTransformer::TStatus::Error;
@@ -246,16 +293,14 @@ IGraphTransformer::TStatus MatchRecognizeDefinesWrapper(const TExprNode::TPtr& i
246
293
ctx.Expr )) {
247
294
return IGraphTransformer::TStatus::Error;
248
295
}
249
- if (auto type = lambda->GetTypeAnn ()) {
250
- if (IsBoolLike (*type)) {
251
- items.push_back (ctx.Expr .MakeType <TItemExprType>(names->Child (i)->Content (), type));
252
- } else {
253
- ctx.Expr .AddError (TIssue (ctx.Expr .GetPosition (lambda->Pos ()), " DEFINE expression must be a predicate" ));
254
- return IGraphTransformer::TStatus::Error;
255
- }
256
- } else {
296
+ if (!lambda->GetTypeAnn ()) {
257
297
return IGraphTransformer::TStatus::Repeat;
258
298
}
299
+ if (!IsBoolLike (*lambda->GetTypeAnn ())) {
300
+ ctx.Expr .AddError (TIssue (ctx.Expr .GetPosition (lambda->Pos ()), " DEFINE expression must be a predicate" ));
301
+ return IGraphTransformer::TStatus::Error;
302
+ }
303
+ items.push_back (ctx.Expr .MakeType <TItemExprType>(names->Child (i)->Content (), lambda->GetTypeAnn ()));
259
304
}
260
305
input->SetTypeAnn (ctx.Expr .MakeType <TStructExprType>(items));
261
306
return IGraphTransformer::TStatus::Ok;
0 commit comments