# Databricks row filters and column masks: policy metrics now hidden

> Databricks Runtime 19 hides row filter and column mask internals from Spark Connect metrics. What stays visible, and how we would tune protected tables.

By Sergey Ustimenko, 23 October 2026. Databricks Field Guide, TechFabric. Canonical: https://databricks.techfabric.com/notes/databricks-runtime-19-october-19-2026/

When a query against a table with a row filter runs slowly, the first thing an engineer wants to know is whether the time went into the policy or into the query. On Spark Connect, the quickest way to look from code is `df.executionInfo.metrics`, the execution details a DataFrame carries after its query runs ([PySpark reference](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.DataFrame.executionInfo.html)). The [Databricks Runtime 19 update of 19 October 2026](https://docs.databricks.com/aws/en/release-notes/runtime/19#databricks-runtime-19-october-19-2026) hides the internal operators and metrics tied to row filters and column masks from that view, including its text form, while the boundary of the protected part of the plan keeps its own metrics and query results don't change.

## The second half of a change that started in August

We'd read this alongside the [10 August 2026 entry](https://docs.databricks.com/aws/en/release-notes/runtime/19#databricks-runtime-19-august-10-2026) on the same page, which stopped query plans from exposing row filter and column mask policy logic unless the user holds the `INSPECT_POLICY_EXECUTION` metastore privilege. Plans were one window into a policy and execution metrics were the other, and Runtime 19 has now shut both. We think that's the right call. A policy exists to decide what a reader may see, and counts or timings from operators inside it describe data the reader was filtered away from. For plans, we'd keep `INSPECT_POLICY_EXECUTION` with the small group that writes and reviews policy functions, the same people who own them in the repository as the [Unity Catalog chapter](09-unity-catalog.md#how-do-row-filters-and-column-masks-work-in-unity-catalog) recommends, and away from analysts who only query the tables.

The October entry names no privilege that brings the hidden metrics back, so we wouldn't plan on one.

```mermaid What df.executionInfo.metrics shows on a protected table in Runtime 19
flowchart TD
  A["Query from a Spark Connect client"] --> B["Operators above the policy, visible"]
  B --> C["Protected boundary, visible with its own metrics"]
  C --> D["Row filter and column mask operators, hidden"]
  E["df.executionInfo.metrics"] -.-> B
  E -.-> C
```

## What we'd still tune with

Losing the inside of the policy may cost less than it sounds, because Databricks' [performance guide for row filter and column mask policies](https://docs.databricks.com/aws/en/data-governance/unity-catalog/abac/performance) calls predicate pushdown the most common source of performance issues with protected tables. A SecureView barrier sits on every protected table, and a predicate that calls a function or forces an implicit cast stays above it, which can block partition pruning and liquid clustering and force a full scan. That happens even when the policy resolves to true for everyone. The guide's own example is `WHERE date_format(o_orderdate, 'yyyy-MM-dd') = '1995-07-29'`, which moves above the barrier, against `WHERE o_orderdate = '1995-07-29'`, which still reaches the scan.

That's a question about where a predicate lands relative to the policy boundary, and the release note says only that the boundary of the protected portion of the plan stays visible. The tuning loop we'd run on a slow protected query stays the same. We'd check whether the filter reached the scan, rewrite it as a plain comparison on the partition or clustering column if it didn't, swap error-prone expressions such as `/` for `try_divide`, and use the policy's `EXCEPT` clause for exempt groups, which the guide says removes the barrier for them entirely. The UDF side of the work is design-time, in the policy function itself, and the [security chapter](34-security.md#how-do-abac-row-filters-and-column-masks-work) already argues for computing an expensive decision into a column in the pipeline.

## Who has something to change

Anything that parses `executionInfo.metrics`. It's a Spark Connect API, and Databricks lists where Spark Connect runs: [serverless compute, standard compute notebooks, Databricks Connect and Lakeflow pipelines with environment versions](https://docs.databricks.com/aws/en/spark/connect-vs-classic). A home-grown profiler that logs per-operator row counts to a table, or a test that asserts on a specific operator's metrics, will see fewer operators on protected tables and may need updating. Clusters on Runtime 19 pick the change up when they restart, and Databricks stages releases, so a workspace can lag the date by a few days.

> **Our position**: We'd keep tuning protected tables the way Databricks' performance guide describes, starting with whether a predicate reaches the scan, because none of those fixes needs a view inside the policy. We'd find and fix any monitoring code that reads metrics from inside protected subplans now, before a restart quietly empties its numbers.
