NF/UDF with Delegation warning is not passed on when NF/UDF is used (#2692)

1. UDF():DS = Filter(DS, Sqrt(Value) > 5));
2. use UDF() elsewhere, no delegation warning is shown

This has always been the case for named formulas as well, change for NF
delegation warning flag is in other repo so test cannot be written to
for that scenario.
This commit is contained in:
rick-nguyen 2024-10-14 08:19:43 -07:00 коммит произвёл GitHub
Родитель 0fd9e3e130
Коммит b89656de2e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 112 добавлений и 3 удалений

Просмотреть файл

@ -2940,7 +2940,13 @@ namespace Microsoft.PowerFx.Core.Binding
_txb.SetSetMutable(node, nameSymbol?.Props.CanSetMutate ?? false);
if (lookupInfo.Data is IExternalNamedFormula formula)
{
isConstantNamedFormula = formula.IsConstant;
isConstantNamedFormula = formula.IsConstant;
// If the definition of the named formula has a delegation warning, every use should also inherit this warning
if (formula.HasDelegationWarning)
{
_txb.ErrorContainer.EnsureError(DocumentErrorSeverity.Warning, node, TexlStrings.SuggestRemoteExecutionHint_NF, node.Ident.Name);
}
}
}
else if (lookupInfo.Kind == BindKind.Data)
@ -4871,6 +4877,12 @@ namespace Microsoft.PowerFx.Core.Binding
{
_txb.ErrorContainer.EnsureError(node, errorKey, badAncestor.Head.Name);
}
}
// If the definition of the user-defined function has a delegation warning, every usage should also inherit this warning
if (func is UserDefinedFunction udf && udf.HasDelegationWarning)
{
_txb.ErrorContainer.EnsureError(DocumentErrorSeverity.Warning, node, TexlStrings.SuggestRemoteExecutionHint_UDF, udf.Name);
}
_txb.CheckAndMarkAsDelegatable(node);

Просмотреть файл

@ -13,6 +13,8 @@ namespace Microsoft.PowerFx.Core.Entities
bool IsConstant { get; }
bool ContainsReferenceToView { get; }
bool ContainsReferenceToView { get; }
bool HasDelegationWarning { get; }
}
}

Просмотреть файл

@ -75,6 +75,8 @@ namespace Microsoft.PowerFx.Core.Functions
return TryGetExternalDataSource(out dsInfo);
}
public bool HasDelegationWarning => _binding?.ErrorContainer.GetErrors().Any(error => error.MessageKey.Contains("SuggestRemoteExecutionHint")) ?? false;
/// <summary>
/// Initializes a new instance of the <see cref="UserDefinedFunction"/> class.
/// </summary>

Просмотреть файл

@ -758,6 +758,8 @@ namespace Microsoft.PowerFx.Core.Localization
public static ErrorResourceKey SuggestRemoteExecutionHint_InOpRhs = new ErrorResourceKey("SuggestRemoteExecutionHint_InOpRhs");
public static ErrorResourceKey SuggestRemoteExecutionHint_StringMatchSecondParam = new ErrorResourceKey("SuggestRemoteExecutionHint_StringMatchSecondParam");
public static ErrorResourceKey SuggestRemoteExecutionHint_InOpInvalidColumn = new ErrorResourceKey("SuggestRemoteExecutionHint_InOpInvalidColumn");
public static ErrorResourceKey SuggestRemoteExecutionHint_NF = new ErrorResourceKey("SuggestRemoteExecutionHint_NF");
public static ErrorResourceKey SuggestRemoteExecutionHint_UDF = new ErrorResourceKey("SuggestRemoteExecutionHint_UDF");
public static ErrorResourceKey OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn = new ErrorResourceKey("SuggestRemoteExecutionHint_OpNotSupportedByColumn");
public static ErrorResourceKey OpNotSupportedByServiceSuggestionMessage_OpNotSupportedByService = new ErrorResourceKey("SuggestRemoteExecutionHint_OpNotSupportedByService");
public static ErrorResourceKey OpNotSupportedByClientSuggestionMessage_OpNotSupportedByClient = new ErrorResourceKey("SuggestRemoteExecutionHint_OpNotSupportedByClient");

Просмотреть файл

@ -173,7 +173,7 @@ namespace Microsoft.PowerFx
List<TexlError> bindErrors = new List<TexlError>();
if (binding.ErrorContainer.HasErrors())
if (binding.ErrorContainer.GetErrors().Any(error => error.Severity > DocumentErrorSeverity.Warning))
{
_errors.AddRange(ExpressionError.New(binding.ErrorContainer.GetErrors(), _defaultErrorCulture));
}

Просмотреть файл

@ -4026,6 +4026,60 @@
<data name="ErrorResource_SuggestRemoteExecutionHint_InOpInvalidColumn_Link_2_URL" xml:space="preserve">
<value>https://go.microsoft.com/fwlink/?linkid=2132702</value>
<comment>{Locked}</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_NF_ShortMessage" xml:space="preserve">
<value>Delegation warning. The named formula {0} is not delegable so its usage in this formula might not work correctly on large data sets. </value>
<comment>Error Message.</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_NF_LongMessage" xml:space="preserve">
<value>The data source might not be able to process the formula and might return an incomplete data set. Your application might not return correct results or behave correctly if the data set is incomplete.</value>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_NF_HowToFix_1" xml:space="preserve">
<value>Try simplifying the definition for the named formula.</value>
<comment>1 How to fix the error. </comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_NF_Link_1" xml:space="preserve">
<value>Article: Understand delegation in a canvas app</value>
<comment>Article on delegation</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_NF_Link_1_URL" xml:space="preserve">
<value>https://go.microsoft.com/fwlink/?linkid=2132701</value>
<comment>{Locked}</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_NF_Link_2" xml:space="preserve">
<value>Blog: Data row limits for delegation</value>
<comment>Blog: Data row limits for delegation</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_NF_Link_2_URL" xml:space="preserve">
<value>https://go.microsoft.com/fwlink/?linkid=2132702</value>
<comment>{Locked}</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_UDF_ShortMessage" xml:space="preserve">
<value>Delegation warning. The user-defined function {0} is not delegable so its usage in this formula might not work correctly on large data sets. </value>
<comment>Error Message.</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_UDF_LongMessage" xml:space="preserve">
<value>The data source might not be able to process the formula and might return an incomplete data set. Your application might not return correct results or behave correctly if the data set is incomplete.</value>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_UDF_HowToFix_1" xml:space="preserve">
<value>Try simplifying the definition for the user-defined function.</value>
<comment>1 How to fix the error. </comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_UDF_Link_1" xml:space="preserve">
<value>Article: Understand delegation in a canvas app</value>
<comment>Article on delegation</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_UDF_Link_1_URL" xml:space="preserve">
<value>https://go.microsoft.com/fwlink/?linkid=2132701</value>
<comment>{Locked}</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_UDF_Link_2" xml:space="preserve">
<value>Blog: Data row limits for delegation</value>
<comment>Blog: Data row limits for delegation</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_UDF_Link_2_URL" xml:space="preserve">
<value>https://go.microsoft.com/fwlink/?linkid=2132702</value>
<comment>{Locked}</comment>
</data>
<data name="ErrorResource_SuggestRemoteExecutionHint_OpNotSupportedByService_ShortMessage" xml:space="preserve">
<value>Delegation warning. The highlighted part of this formula might not work correctly on large data sets. The "{0}" operation is not supported by this connector.</value>

Просмотреть файл

@ -798,6 +798,43 @@ namespace Microsoft.PowerFx.Tests
// Binding fails for recursive definitions and hence function is not added.
Assert.False(recalcEngine.AddUserDefinedFunction("E():Void = { E(); };", CultureInfo.InvariantCulture, symbolTable: recalcEngine.EngineSymbols, allowSideEffects: true).IsSuccess);
}
[Fact]
public void TestInheritanceOfDelegationWarningsInUDFs()
{
var symbolTable = new DelegatableSymbolTable();
var schema = DType.CreateTable(
new TypedName(DType.Number, new DName("Value")));
symbolTable.AddEntity(new TestDelegableDataSource(
"MyDataSource",
schema,
new TestDelegationMetadata(
new DelegationCapability(DelegationCapability.Filter),
schema,
new FilterOpMetadata(
schema,
new Dictionary<DPath, DelegationCapability>(),
new Dictionary<DPath, DelegationCapability>(),
new DelegationCapability(DelegationCapability.GreaterThan),
null)),
true));
symbolTable.AddType(new DName("MyDataSourceTableType"), FormulaType.Build(schema));
var config = new PowerFxConfig()
{
SymbolTable = symbolTable
};
var engine = new RecalcEngine(config);
var result = engine.AddUserDefinedFunction("NonDelegatableUDF():MyDataSourceTableType = Filter(MyDataSource, Sqrt(Value) > 5);", CultureInfo.InvariantCulture, symbolTable: engine.EngineSymbols, allowSideEffects: true);
Assert.True(result.IsSuccess);
var func = engine.Functions.WithName("NonDelegatableUDF").First() as UserDefinedFunction;
Assert.True(func.HasDelegationWarning);
result = engine.AddUserDefinedFunction("NonDelegatableUDF2():MyDataSourceTableType = NonDelegatableUDF();", CultureInfo.InvariantCulture, symbolTable: engine.EngineSymbols, allowSideEffects: true);
Assert.True(result.IsSuccess);
func = engine.Functions.WithName("NonDelegatableUDF2").First() as UserDefinedFunction;
Assert.True(func.HasDelegationWarning);
}
// Binding to inner functions does not impact outer functions.