diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRelFieldTrimmer.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRelFieldTrimmer.java index c570356d8b..7e5021d11c 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRelFieldTrimmer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRelFieldTrimmer.java @@ -688,6 +688,15 @@ public TrimResult trimFields(Project project, ImmutableBitSet fieldsUsed, public TrimResult trimFields(TableScan tableAccessRel, ImmutableBitSet fieldsUsed, Set extraFields) { final TrimResult result = super.trimFields(tableAccessRel, fieldsUsed, extraFields); + if (this.columnAccessInfo != null) { + // Store information about column accessed by the table so it can be used + // to send only this information for column masking + final RelOptHiveTable tab = (RelOptHiveTable) tableAccessRel.getTable(); + fieldsUsed.asList().stream() + .filter(idx -> idx < tab.getNoOfNonVirtualCols()) + .forEach(idx -> columnAccessInfo.add( + tab.getHiveTableMD().getCompleteName(), tab.getHiveTableMD().getAllCols().get(idx).getName())); + } if (fetchStats) { fetchColStats(result.getKey(), tableAccessRel, fieldsUsed, extraFields); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index 92194aaaee..5d9b0cad24 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -12159,9 +12159,18 @@ private void walkASTMarkTABREF(TableMask tableMask, ASTNode ast, Set cte basicInfos.put(new HivePrivilegeObject(table.getDbName(), table.getTableName(), colNames), null); } } else { - List colNames = new ArrayList<>(); - List colTypes = new ArrayList<>(); - extractColumnInfos(table, colNames, colTypes); + List colNames; + List colTypes; + if (this.columnAccessInfo != null && this.columnAccessInfo.getTableToColumnAccessMap().containsKey(table.getCompleteName())) { + colNames = this.columnAccessInfo.getTableToColumnAccessMap().get(table.getCompleteName()); + Map colNameToType = table.getAllCols().stream() + .collect(Collectors.toMap(FieldSchema::getName, FieldSchema::getType)); + colTypes = colNames.stream().map(colNameToType::get).collect(Collectors.toList()); + } else { + colNames = new ArrayList<>(); + colTypes = new ArrayList<>(); + extractColumnInfos(table, colNames, colTypes); + } basicInfos.put(new HivePrivilegeObject(table.getDbName(), table.getTableName(), colNames), new MaskAndFilterInfo(colTypes, additionalTabInfo.toString(), alias, astNode, table.isView(), table.isNonNative())); @@ -12625,7 +12634,8 @@ void analyzeInternal(ASTNode ast, Supplier pcf) throws SemanticE // takes place during optimization boolean isColumnInfoNeedForAuth = SessionState.get().isAuthorizationModeV2() && HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_AUTHORIZATION_ENABLED); - if (isColumnInfoNeedForAuth + // If CBO is run, the column access information has already been added + if (!isCBOExecuted() && isColumnInfoNeedForAuth || HiveConf.getBoolVar(this.conf, HiveConf.ConfVars.HIVE_STATS_COLLECT_SCANCOLS)) { ColumnAccessAnalyzer columnAccessAnalyzer = new ColumnAccessAnalyzer(pCtx); // view column access info is carried by this.getColumnAccessInfo().