Skip to content

Commit

Permalink
Fix custom type declaration on UDF for datasource type
Browse files Browse the repository at this point in the history
  • Loading branch information
yuchenglin committed Jan 16, 2025
1 parent 0fa1968 commit 9b10b0b
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,19 @@ public override bool IsServerDelegatable(CallNode callNode, TexlBinding binding)
{
Contracts.AssertValue(callNode);
Contracts.AssertValue(binding);
Contracts.Assert(binding.GetInfo(callNode).Function is UserDefinedFunction udf && udf.Binding != null);

return base.IsServerDelegatable(callNode, binding) || IsDelegatable;
Contracts.Assert(binding.GetInfo(callNode).Function is UserDefinedFunction udf && udf.Binding != null);

if (binding.DelegationHintProvider?.TryGetWarning(callNode, this, out var warning) ?? false)
{
SuggestDelegationHint(callNode, binding);
}

if (TryGetDataSource(callNode, binding, out var dataSource) && dataSource.IsDelegatable)
{
return true;
}

return IsDelegatable;
}

public override bool SupportsParamCoercion => true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ public bool TryGetRelatedColumn(string selectColumnName, out string additionalCo
}
}

internal class TestDelegableDataSource : TestDataSource
internal class TestDelegableDataSource : TestDataSource, IExternalDelegatableSymbol
{
private readonly TabularDataQueryOptions _queryOptions;
private readonly IDelegationMetadata _delegationMetadata;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -793,30 +793,32 @@ public void DelegableUDFTest()

var recalcEngine = new RecalcEngine(config);

recalcEngine.AddUserDefinedFunction("A():MyDataSourceTableType = Filter(MyDataSource, Value > 10);C():MyDataSourceTableType = A(); B():MyDataSourceTableType = Filter(C(), Value > 11); D():MyDataSourceTableType = { Filter(B(), Value > 12); };", CultureInfo.InvariantCulture, symbolTable: recalcEngine.EngineSymbols, allowSideEffects: true);
var func = recalcEngine.Functions.WithName("A").First() as UserDefinedFunction;
recalcEngine.AddUserDefinedFunction("A():MyDataSourceTableType = Filter(MyDataSource, Value > 10);C():MyDataSourceTableType = A(); B():MyDataSourceTableType = Filter(C(), Value > 11); D():MyDataSourceTableType = { Filter(B(), Value > 12); }; F():MyDataSourceTableType = MyDataSource;", CultureInfo.InvariantCulture, symbolTable: recalcEngine.EngineSymbols, allowSideEffects: true);

var func = recalcEngine.Functions.WithName("A").First() as UserDefinedFunction;
Assert.True(func.IsAsync);
Assert.True(func.IsDelegatable);

func = recalcEngine.Functions.WithName("C").First() as UserDefinedFunction;

Assert.True(func.IsAsync);
Assert.True(func.IsDelegatable);

func = recalcEngine.Functions.WithName("B").First() as UserDefinedFunction;

Assert.True(func.IsAsync);
Assert.True(func.IsDelegatable);

func = recalcEngine.Functions.WithName("D").First() as UserDefinedFunction;

// Imperative function is not delegable
Assert.True(func.IsAsync);
Assert.True(!func.IsDelegatable);

// 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);

func = recalcEngine.Functions.WithName("F").First() as UserDefinedFunction;
Assert.True(func.IsAsync);
Assert.True(func.IsDelegatable);
}

[Fact]
Expand Down

0 comments on commit 9b10b0b

Please sign in to comment.