You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ay...@apache.org on 2022/07/08 08:52:17 UTC

[hive] branch master updated: HIVE-26378: Improve error message for masking over complex data types (#3421). (Alessandro Solimando reviewed by Ayush Saxena)

This is an automated email from the ASF dual-hosted git repository.

ayushsaxena pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new edc341c0b9a HIVE-26378: Improve error message for masking over complex data types (#3421).  (Alessandro Solimando reviewed by Ayush Saxena)
edc341c0b9a is described below

commit edc341c0b9a3d3f02458c8783e89f5ee93aafa37
Author: Alessandro Solimando <al...@gmail.com>
AuthorDate: Fri Jul 8 10:52:06 2022 +0200

    HIVE-26378: Improve error message for masking over complex data types (#3421).  (Alessandro Solimando reviewed by Ayush Saxena)
---
 .../java/org/apache/hadoop/hive/ql/ErrorMsg.java   |  2 ++
 .../org/apache/hadoop/hive/ql/parse/TableMask.java | 11 ++++++--
 .../queries/clientnegative/masking_complex_type.q  | 32 ++++++++++++++++++++++
 .../clientnegative/masking_complex_type.q.out      | 13 +++++++++
 4 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/common/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java b/common/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java
index 4a61c2d2c95..d22cc7288de 100644
--- a/common/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java
+++ b/common/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java
@@ -384,6 +384,8 @@ public enum ErrorMsg {
   MASKING_FILTERING_ON_MATERIALIZED_VIEWS_SOURCES(10288,
       "Querying directly materialized view contents is not supported since we detected {0}.{1} " +
           "used by materialized view has row masking/column filtering enabled", true),
+  MASKING_COMPLEX_TYPE_NOT_SUPPORTED(10289,
+      "Masking complex types is not supported, found a masking expression {0} over column {1}:{2}", true),
 
   UPDATEDELETE_PARSE_ERROR(10290, "Encountered parse error while parsing rewritten merge/update or " +
       "delete query"),
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/TableMask.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/TableMask.java
index b1db5477cf9..0b5ff28875b 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/TableMask.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/TableMask.java
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.antlr.runtime.TokenRewriteStream;
 import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.ErrorMsg;
 import org.apache.hadoop.hive.ql.metadata.HiveUtils;
 import org.apache.hadoop.hive.ql.metadata.VirtualColumn;
 import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizer;
@@ -110,7 +111,7 @@ public class TableMask {
     return false;
   }
 
-  public String create(HivePrivilegeObject privObject, MaskAndFilterInfo maskAndFilterInfo) {
+  public String create(HivePrivilegeObject privObject, MaskAndFilterInfo maskAndFilterInfo) throws SemanticException {
     boolean doColumnMasking = false;
     StringBuilder sb = new StringBuilder();
     sb.append("(SELECT ");
@@ -126,9 +127,14 @@ public class TableMask {
           firstOne = false;
         }
         String colName = privObject.getColumns().get(index);
+        String colType = colTypes.get(index);
         if (!expr.equals(colName)) {
+          if (colType.contains("<")) {
+            throw new SemanticException(ErrorMsg.MASKING_COMPLEX_TYPE_NOT_SUPPORTED,
+                expr, colName, colType);
+          }
           // CAST(expr AS COLTYPE) AS COLNAME
-          sb.append("CAST(" + expr + " AS " + colTypes.get(index) + ") AS "
+          sb.append("CAST(" + expr + " AS " + colType + ") AS "
               + HiveUtils.unparseIdentifier(colName, conf));
           doColumnMasking = true;
         } else {
@@ -180,5 +186,4 @@ public class TableMask {
   public void setNeedsRewrite(boolean needsRewrite) {
     this.needsRewrite = needsRewrite;
   }
-
 }
diff --git a/ql/src/test/queries/clientnegative/masking_complex_type.q b/ql/src/test/queries/clientnegative/masking_complex_type.q
new file mode 100644
index 00000000000..1a812442113
--- /dev/null
+++ b/ql/src/test/queries/clientnegative/masking_complex_type.q
@@ -0,0 +1,32 @@
+--! qt:dataset:srcpart
+--! qt:dataset:src
+-- SORT_QUERY_RESULTS
+
+set hive.mapred.mode=nonstrict;
+set hive.security.authorization.enabled=true;
+set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactoryForTest;
+
+create table masking_test_n8 as select cast(key as int) as key, map('F1','2022','F2','2222') as value from src;
+
+explain select * from masking_test_n8;
+select * from masking_test_n8;
+
+explain select * from masking_test_n8 where key > 0;
+select * from masking_test_n8 where key > 0;
+
+explain select key from masking_test_n8 where key > 0;
+select key from masking_test_n8 where key > 0;
+
+explain select value from masking_test_n8 where key > 0;
+select value from masking_test_n8 where key > 0;
+
+explain select * from masking_test_n8 join srcpart on (masking_test_n8.key = srcpart.key);
+select * from masking_test_n8 join srcpart on (masking_test_n8.key = srcpart.key);
+
+explain select * from default.masking_test_n8 where key > 0;
+select * from default.masking_test_n8 where key > 0;
+
+explain select * from masking_test_n8 where masking_test_n8.key > 0;
+select * from masking_test_n8 where masking_test_n8.key > 0;
+
+explain select key, value from (select key, value from (select key, upper(value) as value from src where key > 0) t where key < 10) t2 where key % 2 = 0;
diff --git a/ql/src/test/results/clientnegative/masking_complex_type.q.out b/ql/src/test/results/clientnegative/masking_complex_type.q.out
new file mode 100644
index 00000000000..9c98a55bcae
--- /dev/null
+++ b/ql/src/test/results/clientnegative/masking_complex_type.q.out
@@ -0,0 +1,13 @@
+PREHOOK: query: create table masking_test_n8 as select cast(key as int) as key, map('F1','2022','F2','2222') as value from src
+PREHOOK: type: CREATETABLE_AS_SELECT
+PREHOOK: Input: default@src
+PREHOOK: Output: database:default
+PREHOOK: Output: default@masking_test_n8
+POSTHOOK: query: create table masking_test_n8 as select cast(key as int) as key, map('F1','2022','F2','2222') as value from src
+POSTHOOK: type: CREATETABLE_AS_SELECT
+POSTHOOK: Input: default@src
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@masking_test_n8
+POSTHOOK: Lineage: masking_test_n8.key EXPRESSION [(src)src.FieldSchema(name:key, type:string, comment:default), ]
+POSTHOOK: Lineage: masking_test_n8.value EXPRESSION []
+FAILED: SemanticException [Error 10289]: Masking complex types is not supported, found a masking expression reverse(value) over column value:map<string,string>