@@ -15,13 +15,50 @@ namespace {
15
15
* We maintain a white list of callables that we consider part of constant expressions
16
16
* All other callables will not be evaluated
17
17
*/
18
- THashSet<TString> constantFoldingWhiteList = {
18
+ THashSet<TString> ConstantFoldingWhiteList = {
19
19
" Concat" , " Just" , " Optional" , " SafeCast" , " AsList" ,
20
20
" +" , " -" , " *" , " /" , " %" };
21
21
22
- THashSet<TString> pgConstantFoldingWhiteList = {
22
+ THashSet<TString> PgConstantFoldingWhiteList = {
23
23
" PgResolvedOp" , " PgResolvedCall" , " PgCast" , " PgConst" , " PgArray" , " PgType" };
24
24
25
+ TVector<TString> UdfBlackList = {
26
+ " RandomNumber" ,
27
+ " Random" ,
28
+ " RandomUuid" ,
29
+ " Now" ,
30
+ " CurrentUtcDate" ,
31
+ " CurrentUtcDatetime" ,
32
+ " CurrentUtcTimestamp"
33
+ };
34
+
35
+ bool IsConstantUdf (const TExprNode::TPtr& input, bool withParams = false ) {
36
+ if (!TCoApply::Match (input.Get ())) {
37
+ return false ;
38
+ }
39
+
40
+ if (input->ChildrenSize ()!=2 ) {
41
+ return false ;
42
+ }
43
+ if (input->Child (0 )->IsCallable (" Udf" )) {
44
+ auto udf = TCoUdf (input->Child (0 ));
45
+ auto udfName = udf.MethodName ().StringValue ();
46
+
47
+ for (auto blck : UdfBlackList) {
48
+ if (udfName.find (blck) != TString::npos) {
49
+ return false ;
50
+ }
51
+ }
52
+
53
+ if (withParams) {
54
+ return IsConstantExprWithParams (input->Child (1 ));
55
+ }
56
+ else {
57
+ return IsConstantExpr (input->Child (1 ));
58
+ }
59
+ }
60
+ return false ;
61
+ }
25
62
26
63
TString RemoveAliases (TString attributeName) {
27
64
if (auto idx = attributeName.find (' .' ); idx != TString::npos) {
@@ -167,7 +204,7 @@ bool IsConstantExprPg(const TExprNode::TPtr& input) {
167
204
return true ;
168
205
}
169
206
170
- if (input->IsCallable (pgConstantFoldingWhiteList ) || input->IsList ()) {
207
+ if (input->IsCallable (PgConstantFoldingWhiteList ) || input->IsList ()) {
171
208
for (size_t i = 0 ; i < input->ChildrenSize (); i++) {
172
209
auto callableInput = input->Child (i);
173
210
if (callableInput->IsLambda () && !IsConstantExprPg (callableInput->Child (1 ))) {
@@ -190,7 +227,7 @@ bool IsConstantExprPg(const TExprNode::TPtr& input) {
190
227
* - If its a callable in the while list and all children are constant expressions, then its a constant expression
191
228
* - If one of the child is a type expression, it also passes the check
192
229
*/
193
- bool IsConstantExpr (const TExprNode::TPtr& input) {
230
+ bool IsConstantExpr (const TExprNode::TPtr& input, bool foldUdfs ) {
194
231
if (input->GetTypeAnn ()->GetKind () == ETypeAnnotationKind::Pg) {
195
232
return IsConstantExprPg (input);
196
233
}
@@ -203,7 +240,7 @@ bool IsConstantExpr(const TExprNode::TPtr& input) {
203
240
return true ;
204
241
}
205
242
206
- else if (input->IsCallable (constantFoldingWhiteList )) {
243
+ else if (input->IsCallable (ConstantFoldingWhiteList )) {
207
244
for (size_t i = 0 ; i < input->ChildrenSize (); i++) {
208
245
auto callableInput = input->Child (i);
209
246
if (callableInput->GetTypeAnn ()->GetKind () != ETypeAnnotationKind::Type && !IsConstantExpr (callableInput)) {
@@ -213,6 +250,10 @@ bool IsConstantExpr(const TExprNode::TPtr& input) {
213
250
return true ;
214
251
}
215
252
253
+ else if (foldUdfs && TCoApply::Match (input.Get ()) && IsConstantUdf (input)) {
254
+ return true ;
255
+ }
256
+
216
257
return false ;
217
258
}
218
259
@@ -233,7 +274,7 @@ bool IsConstantExprWithParams(const TExprNode::TPtr& input) {
233
274
return true ;
234
275
}
235
276
236
- else if (input->IsCallable (constantFoldingWhiteList )) {
277
+ else if (input->IsCallable (ConstantFoldingWhiteList )) {
237
278
for (size_t i = 0 ; i < input->ChildrenSize (); i++) {
238
279
auto callableInput = input->Child (i);
239
280
if (callableInput->GetTypeAnn ()->GetKind () != ETypeAnnotationKind::Type && !IsConstantExprWithParams (callableInput)) {
@@ -243,6 +284,10 @@ bool IsConstantExprWithParams(const TExprNode::TPtr& input) {
243
284
return true ;
244
285
}
245
286
287
+ else if (TCoApply::Match (input.Get ()) && IsConstantUdf (input, true )) {
288
+ return true ;
289
+ }
290
+
246
291
return false ;
247
292
}
248
293
0 commit comments