Skip to content

Commit 1abad21

Browse files
committed
Improve addColumnMasks efficiency
This improves plan rewrite for column masks to only build a new root node once, instead of creating a plan builder for each mask. Add documentation for row filters and column masks access control implementation.
1 parent 8f789ec commit 1abad21

2 files changed

Lines changed: 33 additions & 16 deletions

File tree

presto-docs/src/main/sphinx/develop/system-access-control.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ name which is used by the administrator in a Presto configuration.
2929
The implementation of ``SystemAccessControl`` and ``SystemAccessControlFactory``
3030
must be wrapped as a plugin and installed on the Presto cluster.
3131

32+
Row Filters and Column Masks
33+
----------------------------
34+
35+
The access control implementation can optionally provide row filters and column masks to
36+
control viewing of specific rows or mask sensitive values in columns. The filters
37+
and masks are retrieved per table from the given ``Identity``, schema, table, and
38+
column names. The returned filters and masks will be in the form of a ``ViewExpression``
39+
that is then applied to the query plan before execution. Filters and masks can also be
40+
supplied at the connector level from a ``ConnectorAccessControl`` implementation.
41+
3242
Configuration
3343
-------------
3444

presto-main-base/src/main/java/com/facebook/presto/sql/planner/RelationPlanner.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -249,34 +249,41 @@ private RelationPlan addColumnMasks(Table table, RelationPlan plan, SqlPlannerCo
249249
{
250250
Map<String, Expression> columnMasks = analysis.getColumnMasks(table);
251251

252+
PlanBuilder planBuilder = initializePlanBuilder(plan);
252253
List<VariableReferenceExpression> mappings = plan.getFieldMappings();
253-
TranslationMap translations = new TranslationMap(plan, analysis, lambdaDeclarationToVariableMap);
254-
translations.setFieldMappings(mappings);
254+
ImmutableList.Builder<VariableReferenceExpression> newMappings = ImmutableList.builder();
255255

256-
PlanBuilder planBuilder = new PlanBuilder(translations, plan.getRoot());
256+
Assignments.Builder assignments = new Assignments.Builder();
257+
for (VariableReferenceExpression variableReferenceExpression : planBuilder.getRoot().getOutputVariables()) {
258+
assignments.put(variableReferenceExpression, rowExpression(new SymbolReference(variableReferenceExpression.getName()), context));
259+
}
257260

258261
for (int i = 0; i < plan.getDescriptor().getAllFieldCount(); i++) {
259262
Field field = plan.getDescriptor().getFieldByIndex(i);
260263

264+
VariableReferenceExpression fieldMapping;
265+
RowExpression rowExpression;
261266
if (field.getName().isPresent() && columnMasks.containsKey(field.getName().get())) {
262267
Expression mask = columnMasks.get(field.getName().get());
263-
264268
planBuilder = subqueryPlanner.handleSubqueries(planBuilder, mask, mask, context);
265-
266-
Map<VariableReferenceExpression, RowExpression> assignments = new LinkedHashMap<>();
267-
for (VariableReferenceExpression variableReferenceExpression : planBuilder.getRoot().getOutputVariables()) {
268-
assignments.put(variableReferenceExpression, rowExpression(new SymbolReference(variableReferenceExpression.getName()), context));
269-
}
270-
assignments.put(mappings.get(i), rowExpression(translations.rewrite(mask), context));
271-
272-
planBuilder = planBuilder.withNewRoot(new ProjectNode(
273-
idAllocator.getNextId(),
274-
planBuilder.getRoot(),
275-
Assignments.copyOf(assignments)));
269+
fieldMapping = newVariable(variableAllocator, field);
270+
rowExpression = rowExpression(planBuilder.rewrite(mask), context);
276271
}
272+
else {
273+
fieldMapping = mappings.get(i);
274+
rowExpression = rowExpression(createSymbolReference(fieldMapping), context);
275+
}
276+
277+
assignments.put(fieldMapping, rowExpression);
278+
newMappings.add(fieldMapping);
277279
}
278280

279-
return new RelationPlan(planBuilder.getRoot(), plan.getScope(), mappings);
281+
planBuilder = planBuilder.withNewRoot(new ProjectNode(
282+
idAllocator.getNextId(),
283+
planBuilder.getRoot(),
284+
assignments.build()));
285+
286+
return new RelationPlan(planBuilder.getRoot(), plan.getScope(), newMappings.build());
280287
}
281288

282289
@Override

0 commit comments

Comments
 (0)