{"record":{"id":"637dcbca00a28c17","repo":"prestodb/presto","slug":"full-data-access-is-restricted-by-row-filters-and","errorCode":null,"errorMessage":"Full data access is restricted by row filters and column masks for table: ","messagePattern":"Full data access is restricted by row filters and column masks for table: ","errorType":"exception","errorClass":"AccessDeniedException","httpStatus":403,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/RewriteWriterTarget.java","lineNumber":200,"sourceCode":"            return planChanged;\n        }\n\n        private void checkFullDataAccessControl(TableHandle tableHandle)\n        {\n            TableMetadata tableMetadata = metadata.getTableMetadata(session, tableHandle);\n            QualifiedObjectName baseTable = new QualifiedObjectName(tableMetadata.getConnectorId().getCatalogName(),\n                    tableMetadata.getTable().getSchemaName(), tableMetadata.getTable().getTableName());\n            String errorMessage = \"Full data access is restricted by row filters and column masks for table: \" + baseTable;\n\n            // Check for row filters on this target table\n            List<ViewExpression> rowFilters = accessControl.getRowFilters(\n                    session.getRequiredTransactionId(),\n                    session.getIdentity(),\n                    session.getAccessControlContext(),\n                    baseTable);\n\n            if (!rowFilters.isEmpty()) {\n                throw new AccessDeniedException(errorMessage);\n            }\n\n            // Check for column masks on this target table\n            Map<String, ColumnHandle> columnHandles = metadata.getColumnHandles(session, tableHandle);\n            List<ColumnMetadata> columnsMetadata = columnHandles.values().stream()\n                    .map(handle -> metadata.getColumnMetadata(session, tableHandle, handle))\n                    .collect(toImmutableList());\n\n            Map<ColumnMetadata, ViewExpression> columnMasks = accessControl.getColumnMasks(\n                    session.getRequiredTransactionId(),\n                    session.getIdentity(),\n                    session.getAccessControlContext(),\n                    baseTable,\n                    columnsMetadata);\n\n            if (!columnMasks.isEmpty()) {\n                throw new AccessDeniedException(errorMessage);\n            }","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/RewriteWriterTarget.java#L182-L218","documentation":"RewriteWriterTarget validates that a table targeted by a distributed-procedure rewrite (e.g. CALL system.sync_partition_metadata-style rewrite of a writer target) is fully accessible. If any row filters (fine-grained access control) apply to the base table, it throws AccessDeniedException: full data access is required to rewrite the target safely, and filtered rows could corrupt the rewrite semantics.","triggerScenarios":"Executing a distributed procedure / writer-target rewrite while the session's identity has row filters defined on the target table via the system access control; checkFullDataAccessControl finds non-empty rowFilters and denies access.","commonSituations":"Environments with fine-grained access control (row-level security policies) where an operator runs maintenance CALL procedures; service accounts that intentionally lack full table access attempting rewrites.","solutions":["Run the procedure as an identity exempt from row filters on the table (admin/service account with full access).","Temporarily adjust the row-level security policy for the target table, run the rewrite, then restore it.","Skip the rewrite for tables protected by row filters and manage them outside restricted access control."],"exampleFix":"-- before\nCALL system.sync_partitions('schema', 'table'); -- fails under row filter\n-- after: run as user without row filters on 'table', or relax the policy first\nALTER POLICY table_filter ... ; -- temporarily exempt the operator identity","handlingStrategy":"try-catch","validationCode":"-- before running the rewrite procedure, check row filters on the target\nSELECT * FROM system.security.table_row_filters WHERE schema_name = ? AND table_name = ?;","typeGuard":null,"tryCatchPattern":"try {\n    execute(\"CALL system.sync_partitions('schema','table')\");\n} catch (AccessDeniedException e) {\n    if (e.getMessage().startsWith(\"Full data access is restricted by row filters\")) {\n        // rerun under an identity exempt from row filters\n        executeAs(adminIdentity, \"CALL system.sync_partitions('schema','table')\");\n    } else throw e;\n}","preventionTips":["Run table maintenance procedures with an administrative identity exempt from row filters","Audit row-filter policies on tables targeted by CALL procedures","Document which service accounts have full data access for maintenance jobs"],"tags":["access-control","row-filters","security","procedure"],"backgroundTag":"row-level-security-access-denied","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}