DataConnectors icon indicating copy to clipboard operation
DataConnectors copied to clipboard

Overriding Behaviors with Layered Table.Views

Open bgribaudo opened this issue 2 years ago • 0 comments

Hello,

As we know, Table.View can be used to override a table's existing behaviors.

However, from what I'm seeing, if a table view handler declines a folding request by raising an error, folding does not fall back to the underlying parent table view's behaviors. Instead, folding stops. This is, instead of falling back to the appropriate operation-specific handler on the parent view, Power Query fetches rows then performs the operation internally itself.

For example, below, the folding of CustomViewFunction does not fall back to View1's OnInvoke. Instead, CustomViewFunction isn't folded.

let
    CustomViewFunction = Table.ViewFunction((input as table) => "hi"),
    View1 = Table.View(
        null,
        [
            GetType = () => Value.Type(GetRows()), 
            GetRows = () => #table(null, {{1}}),
            OnInvoke = (func, args, index) =>            
                if func = CustomViewFunction
                then "here"
                else ...            
        ]
    ),
    View2 = Table.View(
        View1, 
        [
            OnInvoke = (func, args, index) =>
                if func = Table.ApproximateRowCount
                then 10
                else ...
        ]
    )
in
    CustomViewFunction(View2) // returns "hi", indicating that the actual function ran instead of it being folded by View1
    // CustomViewFunction(View1) // returns "here", indicating that folding into View1 worked (as expected)

Similarly, below, getting the row count does not fall back to View1's GetRowCount. Instead, that method is skipped and Power Query counts the rows returned by GetRows itself.

let
    View1 = Table.View(
        null, 
        [
            GetType = () => Value.Type(GetRows()), 
            GetRows = () => #table(null, {{1}}), 
            GetRowCount = () => 2000
        ]
    ),
    View2 = Table.View(
        View1, 
        [
            GetRowCount = () => ...
        ]
    )
in
    Table.RowCount(View2) // returns 1, not the 2,000 specified by View1's GetRowCount
    // Table.RowCount(View1) // returns 2,000 - the value from View1's GetRowCount

Is this expected or should Power Query actually be falling back to using the appropriate handler on the parent view?

Thanks, Ben

bgribaudo avatar Jan 21 '22 16:01 bgribaudo