You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2018/06/30 01:26:50 UTC
[1/3] impala git commit: IMPALA-6802 (part 6): Clean up authorization
tests
Repository: impala
Updated Branches:
refs/heads/master 4ce2af9ff -> 8060f4d50
http://git-wip-us.apache.org/repos/asf/impala/blob/5c880e52/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
index 1ca5a33..2a45c3b 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
@@ -21,13 +21,11 @@ import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.UUID;
import org.apache.hadoop.conf.Configuration;
@@ -38,11 +36,8 @@ import org.apache.impala.authorization.AuthorizationConfig;
import org.apache.impala.authorization.AuthorizeableTable;
import org.apache.impala.authorization.User;
import org.apache.impala.catalog.AuthorizationException;
-import org.apache.impala.catalog.Db;
import org.apache.impala.catalog.FeDb;
import org.apache.impala.catalog.ImpaladCatalog;
-import org.apache.impala.catalog.ScalarFunction;
-import org.apache.impala.catalog.Type;
import org.apache.impala.common.AnalysisException;
import org.apache.impala.common.FrontendTestBase;
import org.apache.impala.common.ImpalaException;
@@ -51,20 +46,14 @@ import org.apache.impala.common.RuntimeEnv;
import org.apache.impala.compat.MiniclusterProfile;
import org.apache.impala.service.Frontend;
import org.apache.impala.testutil.ImpaladTestCatalog;
-import org.apache.impala.thrift.TColumnValue;
-import org.apache.impala.thrift.TDescribeOutputStyle;
-import org.apache.impala.thrift.TDescribeResult;
-import org.apache.impala.thrift.TFunctionBinaryType;
import org.apache.impala.thrift.TMetadataOpRequest;
import org.apache.impala.thrift.TMetadataOpcode;
import org.apache.impala.thrift.TNetworkAddress;
import org.apache.impala.thrift.TPrivilege;
import org.apache.impala.thrift.TPrivilegeLevel;
import org.apache.impala.thrift.TPrivilegeScope;
-import org.apache.impala.thrift.TResultRow;
import org.apache.impala.thrift.TResultSet;
import org.apache.impala.thrift.TSessionState;
-import org.apache.impala.thrift.TTableName;
import org.apache.impala.util.PatternMatcher;
import org.apache.impala.util.SentryPolicyService;
import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
@@ -597,1544 +586,6 @@ public class AuthorizationTest extends FrontendTestBase {
}
@Test
- public void TestSelect() throws ImpalaException {
- // Can select from table that user has privileges on.
- AuthzOk("select * from functional.alltypesagg");
-
- AuthzOk("select * from functional_seq_snap.alltypes");
-
- // Can select from view that user has privileges on even though he/she doesn't
- // have privileges on underlying tables.
- AuthzOk("select * from functional.complex_view");
-
- // User has permission to select the view but not on the view (alltypes_view)
- // referenced in its view definition.
- AuthzOk("select * from functional.view_view");
-
- // User does not have SELECT privileges on this view.
- AuthzError("select * from functional.alltypes_view",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes_view");
-
- // User has SELECT privileges on the view and the join table.
- AuthzOk("select a.id from functional.view_view a "
- + "join functional.alltypesagg b ON (a.id = b.id)");
-
- // User has SELECT privileges on the view, but does not have privileges
- // to select join table.
- AuthzError("select a.id from functional.view_view a "
- + "join functional.alltypes b ON (a.id = b.id)",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // Tests authorization after a statement has been rewritten (IMPALA-3915).
- // User has SELECT privileges on the view which contains a subquery.
- AuthzOk("select * from functional_seq_snap.subquery_view");
-
- // User does not have SELECT privileges on the view which contains a subquery.
- AuthzError("select * from functional_rc.subquery_view",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional_rc.subquery_view");
-
- // Constant select.
- AuthzOk("select 1");
-
- // Unqualified table name.
- AuthzError("select * from alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: default.alltypes");
-
- // Select with no privileges on table.
- AuthzError("select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // Select without referencing a column.
- AuthzError("select 1 from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // Select from non-existent table.
- AuthzError("select 1 from functional.notbl",
- "User '%s' does not have privileges to execute 'SELECT' on: functional.notbl");
-
- // Select from non-existent db.
- AuthzError("select 1 from nodb.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: nodb.alltypes");
-
- // Table within inline view is authorized properly.
- AuthzError("select a.* from (select * from functional.alltypes) a",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
- // Table within inline view is authorized properly (user has permission).
- AuthzOk("select a.* from (select * from functional.alltypesagg) a");
-
- // User has SELECT privileges on all the columns of 'alltypestiny'
- AuthzOk("select * from functional.alltypestiny");
-
- // No SELECT privileges on all the columns of 'alltypessmall'
- AuthzError("select * from functional.alltypessmall", "User '%s' does " +
- "not have privileges to execute 'SELECT' on: functional.alltypessmall");
-
- // No SELECT privileges on table 'alltypessmall'
- AuthzError("select count(*) from functional.alltypessmall", "User '%s' does " +
- "not have privileges to execute 'SELECT' on: functional.alltypessmall");
- AuthzError("select 1 from functional.alltypessmall", "User '%s' does not " +
- "have privileges to execute 'SELECT' on: functional.alltypessmall");
- AuthzOk("select 1, id from functional.alltypessmall");
-
- // No SELECT privileges on column 'month'
- AuthzError("select id, int_col, year, month from functional.alltypessmall",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypessmall");
-
- // User has column-level privileges on all referenced columns
- AuthzOk("select id, count(int_col) from functional.alltypessmall where " +
- "year = 2010 group by id");
-
- // No SELECT privileges on 'int_array_col'
- AuthzError("select a.id, b.item from functional.allcomplextypes a, " +
- "a.int_array_col b", "User '%s' does not have privileges to execute " +
- "'SELECT' on: functional.allcomplextypes");
-
- // Sufficient column-level privileges on both scalar and nested columns
- AuthzOk("select a.int_struct_col.f1 from functional.allcomplextypes a " +
- "where a.id = 1");
- AuthzOk("select pos, item.f1, f2 from functional.allcomplextypes t, " +
- "t.struct_array_col");
- AuthzOk("select * from functional.allcomplextypes.struct_array_col");
- AuthzOk("select key from functional.allcomplextypes.int_map_col");
- AuthzOk("select id, b.key from functional.allcomplextypes a, a.int_map_col b");
-
- // No SELECT privileges on 'alltypessmall'
- AuthzError("select a.* from functional.alltypesagg a cross join " +
- "functional.alltypessmall b", "User '%s' does not have privileges to execute " +
- "'SELECT' on: functional.alltypessmall");
-
- // User has SELECT privileges on all columns referenced in the inline view
- AuthzOk("select * from (select id, int_col from functional.alltypessmall) v");
- }
-
- @Test
- public void TestUnion() throws ImpalaException {
- AuthzOk("select * from functional.alltypesagg union all " +
- "select * from functional.alltypesagg");
-
- AuthzError("select * from functional.alltypesagg union all " +
- "select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- AuthzOk("select id, int_col, year from functional.alltypessmall union all " +
- "select id, int_col, year from functional.alltypestiny");
-
- AuthzError("select * from functional.alltypessmall union all " +
- "select * from functional.alltypestiny", "User '%s' does not have privileges " +
- "to execute 'SELECT' on: functional.alltypessmall");
- }
-
- @Test
- public void TestInsert() throws ImpalaException {
- AuthzOk("insert into functional_parquet.alltypes " +
- "partition(month,year) select * from functional_seq_snap.alltypes");
-
- // Insert + inline view (user has permissions).
- AuthzOk("insert into functional.alltypes partition(month,year) " +
- "select b.* from functional.alltypesagg a join (select * from " +
- "functional_seq_snap.alltypes) b on (a.int_col = b.int_col)");
-
- // User doesn't have INSERT permissions in the target table.
- AuthzError("insert into functional.alltypesagg select 1",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.alltypesagg");
-
- // User doesn't have INSERT permissions in the target view.
- // Inserting into a view is not allowed.
- AuthzError("insert into functional.alltypes_view select 1",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.alltypes_view");
-
- // User doesn't have SELECT permissions on source table.
- AuthzError("insert into functional.alltypes " +
- "select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // User doesn't have permissions on source table within inline view.
- AuthzError("insert into functional.alltypes partition (month, year) " +
- "select id, bool_col, tinyint_col, smallint_col, a.int_col, bigint_col, " +
- "float_col, a.double_col, a.date_string_col, a.string_col, a.timestamp_col, " +
- "a.year, a.month " +
- "from functional_rc.alltypesagg a " +
- "join (select int_col, double_col, date_string_col, string_col, timestamp_col, " +
- "year, month from functional_seq.alltypes) b " +
- "on (a.int_col = b.int_col)", "User '%s' does " +
- "not have privileges to execute 'SELECT' on: functional_rc.alltypesagg");
-
- // User doesn't have INSERT permissions on the target table but has sufficient SELECT
- // permissions on all the referenced columns of the source table
- AuthzError("insert into functional.alltypestiny partition (month, year) " +
- "select * from functional.alltypestiny", "User '%s' does not have " +
- "privileges to execute 'INSERT' on: functional.alltypestiny");
-
- // User has INSERT permissions on target table but insufficient column-level
- // permissions on the source table
- AuthzError("insert into functional.alltypes partition (month, year) " +
- "select * from functional.alltypessmall", "User '%s' does not have " +
- "privileges to execute 'SELECT' on: functional.alltypessmall");
-
- // User has INSERT permissions on the target table and SELECT permissions on
- // all the columns of the source table
- AuthzOk("insert into functional.alltypes partition (month, year) " +
- "select * from functional.alltypestiny where id < 100");
-
- // Same as above with a column permutation
- AuthzOk("insert into table functional.alltypes" +
- "(id, bool_col, string_col, smallint_col, int_col, bigint_col, " +
- "float_col, double_col, date_string_col, tinyint_col, timestamp_col) " +
- "partition (month, year) select id, bool_col, string_col, smallint_col, " +
- "int_col, bigint_col, float_col, double_col, date_string_col, tinyint_col, " +
- "timestamp_col, month, year from functional.alltypestiny");
- }
-
- @Test
- public void TestWithClause() throws ImpalaException {
- // User has SELECT privileges on table in WITH-clause view.
- AuthzOk("with t as (select * from functional.alltypesagg) select * from t");
- // User doesn't have SELECT privileges on table in WITH-clause view.
- AuthzError("with t as (select * from functional.alltypes) select * from t",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
- // User has SELECT privileges on view in WITH-clause view.
- AuthzOk("with t as (select * from functional.complex_view) select * from t");
-
- // User has SELECT privileges on table in WITH-clause view in INSERT.
- AuthzOk("with t as (select * from functional_seq_snap.alltypes) " +
- "insert into functional_parquet.alltypes partition(month,year) select * from t");
- // User doesn't have SELECT privileges on table in WITH-clause view in INSERT.
- AuthzError("with t as (select * from functional_parquet.alltypes) " +
- "insert into functional_parquet.alltypes partition(month,year) select * from t",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional_parquet.alltypes");
- // User doesn't have SELECT privileges on view in WITH-clause view in INSERT.
- AuthzError("with t as (select * from functional.alltypes_view) " +
- "insert into functional_parquet.alltypes partition(month,year) select * from t",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes_view");
-
- // User has SELECT privileges on columns referenced in the WITH-clause view.
- AuthzOk("with t as (select id, int_col from functional.alltypessmall) " +
- "select * from t");
-
- // User does not have SELECT privileges on 'month'
- AuthzError("with t as (select id, int_col from functional.alltypessmall " +
- "where month = 10) select count(*) from t", "User '%s' does not have " +
- "privileges to execute 'SELECT' on: functional.alltypessmall");
- }
-
- @Test
- public void TestExplain() throws ImpalaException {
- AuthzOk("explain select * from functional.alltypesagg");
- AuthzOk("explain insert into functional_parquet.alltypes " +
- "partition(month,year) select * from functional_seq_snap.alltypes");
-
- // Select without permissions.
- AuthzError("explain select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // Insert with no select permissions on source table.
- AuthzError("explain insert into functional_parquet.alltypes " +
- "partition(month,year) select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
- // Insert, user doesn't have permissions on source table.
- AuthzError("explain insert into functional.alltypes " +
- "select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // Test explain on views. User has permissions on all the underlying tables.
- AuthzOk("explain select * from functional_seq_snap.alltypes_view");
- AuthzOk("explain insert into functional_parquet.alltypes " +
- "partition(month,year) select * from functional_seq_snap.alltypes_view");
-
- // Select on view without permissions on view.
- AuthzError("explain select * from functional.alltypes_view",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes_view");
- // Insert into view without permissions on view.
- AuthzError("explain insert into functional.alltypes_view " +
- "select * from functional_seq_snap.alltypes ",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.alltypes_view");
-
- // User has permission on view, but not on underlying tables.
- AuthzError("explain select * from functional.complex_view",
- "User '%s' does not have privileges to EXPLAIN this statement.");
- // User has permission on view in WITH clause, but not on underlying tables.
- AuthzError("explain with t as (select * from functional.complex_view) " +
- "select * from t",
- "User '%s' does not have privileges to EXPLAIN this statement.");
-
- // User has permission on view in WITH clause, but not on underlying tables.
- AuthzError("explain with t as (select * from functional.complex_view) " +
- "select * from t",
- "User '%s' does not have privileges to EXPLAIN this statement.");
- // User has permission on view and on view inside view,
- // but not on tables in view inside view.
- AuthzError("explain select * from functional.view_view",
- "User '%s' does not have privileges to EXPLAIN this statement.");
- // User doesn't have permission on tables in view inside view.
- AuthzError("explain insert into functional_seq_snap.alltypes " +
- "partition(month,year) select * from functional.view_view",
- "User '%s' does not have privileges to EXPLAIN this statement.");
-
- // User has SELECT privileges on the view, but does not have privileges
- // to select join table. Should get standard auth message back.
- AuthzError("explain select a.id from functional.view_view a "
- + "join functional.alltypes b ON (a.id = b.id)",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // User has privileges on tables inside the first view, but not the second
- // view. Should get masked auth error back.
- AuthzError("explain select a.id from functional.view_view a "
- + "join functional.complex_view b ON (a.id = b.id)",
- "User '%s' does not have privileges to EXPLAIN this statement.");
-
- // User has SELECT privileges on all referenced columns
- AuthzOk("explain select * from functional.alltypestiny");
-
- // User doesn't have SELECT privileges on all referenced columns
- AuthzError("explain select * from functional.alltypessmall", "User '%s' " +
- "does not have privileges to execute 'SELECT' on: functional.alltypessmall");
- }
-
- @Test
- public void TestUseDb() throws ImpalaException {
- // Positive cases (user has privileges on these tables).
- AuthzOk("use functional");
- AuthzOk("use functional_avro"); // Database with only column privileges.
- AuthzOk("use tpcds");
- AuthzOk("use tpch");
-
- // Should always be able to use default, even if privilege was not explicitly
- // granted.
- AuthzOk("use default");
-
- AuthzError("use functional_seq",
- "User '%s' does not have privileges to access: functional_seq.*");
-
- // Database does not exist, user does not have access.
- AuthzError("use nodb",
- "User '%s' does not have privileges to access: nodb.*");
-
- // Database does not exist, user has access:
- try {
- AuthzOk("use newdb");
- fail("Expected AnalysisException");
- } catch (AnalysisException e) {
- Assert.assertEquals(e.getMessage(), "Database does not exist: newdb");
- }
-
- // All users should be able to use the system db.
- AuthzOk("use _impala_builtins");
- }
-
- @Test
- public void TestResetMetadata() throws ImpalaException {
- // Positive cases (user has REFRESH privilege on these tables/views).
- AuthzOk("invalidate metadata functional.alltypesagg");
- AuthzOk("refresh functional.alltypesagg");
- AuthzOk("invalidate metadata functional.view_view");
- AuthzOk("refresh functional.view_view");
- // Positive cases for checking refresh partition
- AuthzOk("refresh functional.alltypesagg partition (year=2010, month=1, day=1)");
- AuthzOk("refresh functional_seq_snap.alltypes partition (year=2009, month=1)");
- // User has REFRESH privilege on functional_text_lzo database, =
- // but no privilege at the table level.
- AuthzOk("invalidate metadata functional_text_lzo.alltypes");
- AuthzOk("refresh functional_text_lzo.alltypes");
- AuthzOk("refresh functions functional_text_lzo");
-
- AuthzError("invalidate metadata unknown_db.alltypessmall",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: unknown_db.alltypessmall");
- AuthzError("invalidate metadata functional_seq.alltypessmall",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional_seq.alltypessmall");
- AuthzError("invalidate metadata functional.alltypes_view",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional.alltypes_view");
- AuthzError("invalidate metadata functional.unknown_table",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional.unknown_table");
- AuthzError("invalidate metadata functional.alltypessmall",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional.alltypessmall");
- AuthzError("refresh functional.alltypessmall",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional.alltypessmall");
- AuthzError("refresh functional.alltypes_view",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional.alltypes_view");
- // Only column-level privileges on the table
- AuthzError("invalidate metadata functional.alltypestiny",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional.alltypestiny");
- // Only column-level privileges on the table
- AuthzError("refresh functional.alltypestiny",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional.alltypestiny");
-
- AuthzError("invalidate metadata",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: server");
- AuthzError(
- "refresh functional_rc.alltypesagg partition (year=2010, month=1, day=1)",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional_rc.alltypesagg");
- AuthzError(
- "refresh functional_rc.alltypesagg partition (year=2010, month=1, day=9999)",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional_rc.alltypesagg");
- AuthzError("refresh functions functional_rc",
- "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " +
- "on: functional_rc");
-
- // TODO: Add test support for dynamically changing privileges for
- // file-based policy.
- if (ctx_.authzConfig.isFileBasedPolicy()) return;
- SentryPolicyService sentryService = createSentryService();
-
- try {
- sentryService.grantRoleToGroup(USER, "admin", USER.getName());
- ctx_.catalog.reset();
- AuthzOk("invalidate metadata");
- AuthzOk("invalidate metadata functional.testtbl");
- AuthzOk("refresh functional.testtbl");
- AuthzOk("refresh functional.alltypesagg partition (year=2010, month=1, day=1)");
- AuthzOk("refresh functions functional");
- } finally {
- sentryService.revokeRoleFromGroup(USER, "admin", USER.getName());
- ctx_.catalog.reset();
- }
-
- // User has REFRESH privilege on server.
- String roleName = "refresh_role";
- try {
- sentryService.createRole(USER, roleName, true);
- TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.REFRESH,
- TPrivilegeScope.SERVER, false);
- privilege.setServer_name("server1");
- sentryService.grantRolePrivilege(USER, roleName, privilege);
- sentryService.grantRoleToGroup(USER, roleName, USER.getName());
- ctx_.catalog.reset();
- AuthzOk("invalidate metadata");
- AuthzOk("invalidate metadata functional.testtbl");
- AuthzOk("refresh functional.testtbl");
- AuthzOk("refresh functional.alltypesagg partition (year=2010, month=1, day=1)");
- AuthzOk("refresh functions functional");
- } finally {
- sentryService.dropRole(USER, roleName, true);
- ctx_.catalog.reset();
- }
- }
-
- @Test
- public void TestCreateTable() throws ImpalaException {
- AuthzOk("create table tpch.new_table (i int)");
- AuthzOk("create table tpch.new_lineitem like tpch.lineitem");
- // Create table IF NOT EXISTS, user has permission and table exists.
- AuthzOk("create table if not exists tpch.lineitem (i int)");
- try {
- AuthzOk("create table tpch.lineitem (i int)");
- fail("Expected analysis error.");
- } catch (AnalysisException e) {
- Assert.assertEquals(e.getMessage(), "Table already exists: tpch.lineitem");
- }
- // User has CREATE privilege on functional_text_lzo database.
- AuthzOk("create table functional_text_lzo.new_table (i int)");
-
- // Create table AS SELECT positive and negative cases for SELECT privilege.
- AuthzOk("create table tpch.new_table as select * from functional.alltypesagg");
- // User has CREATE and INSERT privileges on functional_text_lzo database and SELECT
- // privilege on functional.alltypesagg table.
- AuthzOk("create table functional_text_lzo.new_table as " +
- "select * from functional.alltypesagg");
- AuthzError("create table tpch.new_table as select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
- // User has CREATE privilege on functional_text_lzo database, SELECT privilege on
- // functional.alltypes table but no INSERT privilege on functional_text_lzo database.
- AuthzError("create table functional_text_lzo.new_table as " +
- "select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // CTAS with a subquery.
- AuthzOk("create table tpch.new_table as select * from functional.alltypesagg " +
- "where id < (select max(year) from functional.alltypesagg)");
-
- AuthzError("create table functional.tbl tblproperties('a'='b')" +
- " as select 1",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional.tbl");
-
- // Create table IF NOT EXISTS, user does not have permission and table exists.
- AuthzError("create table if not exists functional_seq.alltypes (i int)",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional_seq.alltypes");
-
- // User has permission to create at given location.
- AuthzOk("create table tpch.new_table (i int) location " +
- "'hdfs://localhost:20500/test-warehouse/new_table'");
-
- // No permissions on source table.
- AuthzError("create table tpch.new_lineitem like tpch_seq.lineitem",
- "User '%s' does not have privileges to access: tpch_seq.lineitem");
-
- // No permissions on target table.
- AuthzError("create table tpch_rc.new like tpch.lineitem",
- "User '%s' does not have privileges to execute 'CREATE' on: tpch_rc.new");
-
- // Unqualified table name.
- AuthzError("create table new_table (i int)",
- "User '%s' does not have privileges to execute 'CREATE' on: default.new_table");
-
- // Table already exists (user does not have permission).
- AuthzError("create table functional.alltypes (i int)",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional.alltypes");
-
- // Database does not exist, user does not have access.
- AuthzError("create table nodb.alltypes (i int)",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "nodb.alltypes");
-
- // IMPALA-4000: Only users with ALL privileges on SERVER may create external Kudu
- // tables.
- AuthzError("create external table tpch.kudu_tbl stored as kudu " +
- "TBLPROPERTIES ('kudu.master_addresses'='127.0.0.1', 'kudu.table_name'='tbl')",
- "User '%s' does not have privileges to access: server1");
- AuthzError("create table tpch.kudu_tbl (i int, j int, primary key (i))" +
- " PARTITION BY HASH (i) PARTITIONS 9 stored as kudu TBLPROPERTIES " +
- "('kudu.master_addresses'='127.0.0.1')",
- "User '%s' does not have privileges to access: server1");
-
- // IMPALA-4000: ALL privileges on SERVER are not required to create managed tables.
- AuthzOk("create table tpch.kudu_tbl (i int, j int, primary key (i))" +
- " PARTITION BY HASH (i) PARTITIONS 9 stored as kudu");
-
- // IMPALA-6451: CTAS for Kudu tables on non-external tables and without
- // TBLPROPERTIES ('kudu.master_addresses') should not require ALL privileges
- // on SERVER.
- // User has ALL privilege on tpch database and SELECT privilege on
- // functional.alltypesagg table.
- // The statement below causes the SQL statement to be rewritten.
- AuthzOk("create table tpch.kudu_tbl primary key (bigint_col) stored as kudu as " +
- "select bigint_col, string_col, current_timestamp() as ins_date " +
- "from functional.alltypesagg " +
- "where exists (select 1 from functional.alltypesagg)");
-
- // User does not have permission to create table at the specified location..
- AuthzError("create table tpch.new_table (i int) location " +
- "'hdfs://localhost:20500/test-warehouse/alltypes'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/alltypes");
-
- AuthzError("create table _impala_builtins.tbl(i int)",
- "Cannot modify system database.");
-
- // Check that create like file follows authorization rules for HDFS files
- AuthzError("create table tpch.table_DNE like parquet "
- + "'hdfs://localhost:20500/test-warehouse/alltypes'",
- "User '%s' does not have privileges to access: "
- + "hdfs://localhost:20500/test-warehouse/alltypes");
-
- // Sufficient column-level privileges in the source table
- AuthzOk("create table tpch.new_table as select id, int_col from " +
- "functional.alltypessmall where year = 2010");
-
- // Insufficient column-level privileges in the source table
- AuthzError("create table tpch.new as select * from functional.alltypessmall",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypessmall");
-
- // No permissions on target table but sufficient column-level privileges in the
- // source table
- AuthzError("create table tpch_rc.new_tbl as select * from functional.alltypestiny",
- "User '%s' does not have privileges to execute 'CREATE' on: tpch_rc.new_tbl");
-
- // Try creating an external table on a URI with upper case letters
- AuthzOk("create external table tpch.upper_case (a int) location " +
- "'hdfs://localhost:20500/test-warehouse/UPPER_CASE/test'");
-
- // Try creating table on the same URI in lower case. It should fail
- AuthzError("create external table tpch.upper_case (a int) location " +
- "'hdfs://localhost:20500/test-warehouse/upper_case/test'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/upper_case/test");
- }
-
- @Test
- public void TestCreateView() throws ImpalaException {
- AuthzOk("create view tpch.new_view as select * from functional.alltypesagg");
- AuthzOk("create view tpch.new_view (a, b, c) as " +
- "select int_col, string_col, timestamp_col from functional.alltypesagg");
- // User has CREATE and INSERT privileges on functional_text_lzo database and
- // SELECT privilege on functional.alltypesagg table.
- AuthzOk("create view functional_text_lzo.new_view as " +
- "select * from functional.alltypesagg");
- // Create view IF NOT EXISTS, user has permission and table exists.
- AuthzOk("create view if not exists tpch.lineitem as " +
- "select * from functional.alltypesagg");
- // Create view IF NOT EXISTS, user has permission and table/view exists.
- try {
- AuthzOk("create view tpch.lineitem as select * from functional.alltypesagg");
- fail("Expected analysis error.");
- } catch (AnalysisException e) {
- Assert.assertEquals(e.getMessage(), "Table already exists: tpch.lineitem");
- }
-
- // Create view IF NOT EXISTS, user does not have permission and table/view exists.
- AuthzError("create view if not exists functional_seq.alltypes as " +
- "select * from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional_seq.alltypes");
-
- // No permissions on source table.
- AuthzError("create view tpch.new_view as select * from functional.alltypes",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes");
-
- // No permissions on target table.
- AuthzError("create view tpch_rc.new as select * from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'CREATE' on: tpch_rc.new");
-
- // Unqualified view name.
- AuthzError("create view new_view as select * from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'CREATE' on: default.new_view");
-
- // Table already exists (user does not have permission).
- AuthzError("create view functional.alltypes_view as " +
- "select * from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional.alltypes_view");
-
- // Database does not exist, user does not have access.
- AuthzError("create view nodb.alltypes as select * from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "nodb.alltypes");
-
- AuthzError("create view _impala_builtins.new_view as "
- + "select * from functional.alltypesagg",
- "Cannot modify system database.");
-
- // User has SELECT privileges on the referenced columns of the source table
- AuthzOk("create view tpch.new_view as select * from functional.alltypestiny");
- AuthzOk("create view tpch.new_view as select count(id) from " +
- "functional.alltypessmall");
-
- // No SELECT permissions on all the referenced columns
- AuthzError("create view tpch.new as select id, count(month) from " +
- "functional.alltypessmall where int_col = 1 group by id", "User '%s' does " +
- "not have privileges to execute 'SELECT' on: functional.alltypessmall");
- }
-
- @Test
- public void TestCreateDatabase() throws ImpalaException {
- // Database already exists (no permissions).
- AuthzError("create database functional",
- "User '%s' does not have privileges to execute 'CREATE' on: functional");
-
- // Non existent db (no permissions).
- AuthzError("create database nodb",
- "User '%s' does not have privileges to execute 'CREATE' on: nodb");
-
- // Non existent db (no permissions).
- AuthzError("create database if not exists _impala_builtins",
- "Cannot modify system database.");
-
- // TODO: Add test support for dynamically changing privileges for
- // file-based policy.
- if (ctx_.authzConfig.isFileBasedPolicy()) return;
-
- SentryPolicyService sentryService =
- new SentryPolicyService(ctx_.authzConfig.getSentryConfig());
- try {
- sentryService.grantRoleToGroup(USER, "admin", USER.getName());
- ctx_.catalog.reset();
-
- // User has permissions to create database.
- AuthzOk("create database newdb");
-
- // Create database with location specified explicitly (user has permission).
- // Since create database requires server-level privileges there should never
- // be a case where the user has privileges to create a database does not have
- // privileges on the URI.
- AuthzOk("create database newdb location " +
- "'hdfs://localhost:20500/test-warehouse/new_table'");
- } finally {
- sentryService.revokeRoleFromGroup(USER, "admin", USER.getName());
- ctx_.catalog.reset();
- }
- }
-
- @Test
- public void TestDropDatabase() throws ImpalaException {
- // User has permissions.
- AuthzOk("drop database tpch");
- AuthzOk("drop database tpch cascade");
- AuthzOk("drop database tpch restrict");
- // User has permissions, database does not exists and IF EXISTS specified.
- AuthzOk("drop database if exists newdb");
- AuthzOk("drop database if exists newdb cascade");
- AuthzOk("drop database if exists newdb restrict");
-
- // User has DROP privilege on functional_text_lzo database.
- AuthzOk("drop database functional_text_lzo");
- AuthzOk("drop database functional_text_lzo cascade");
- AuthzOk("drop database functional_text_lzo restrict");
- AuthzOk("drop database if exists functional_text_lzo");
- AuthzOk("drop database if exists functional_text_lzo cascade");
- AuthzOk("drop database if exists functional_text_lzo restrict");
-
- // User has permission, database does not exists, IF EXISTS not specified.
- try {
- AuthzOk("drop database newdb");
- fail("Expected analysis error");
- } catch (AnalysisException e) {
- Assert.assertEquals(e.getMessage(), "Database does not exist: newdb");
- }
- try {
- AuthzOk("drop database newdb cascade");
- fail("Expected analysis error");
- } catch (AnalysisException e) {
- Assert.assertEquals(e.getMessage(), "Database does not exist: newdb");
- }
- try {
- AuthzOk("drop database newdb restrict");
- fail("Expected analysis error");
- } catch (AnalysisException e) {
- Assert.assertEquals(e.getMessage(), "Database does not exist: newdb");
- }
-
- // Database exists, user doesn't have permission to drop.
- AuthzError("drop database functional",
- "User '%s' does not have privileges to execute 'DROP' on: functional");
- AuthzError("drop database if exists functional",
- "User '%s' does not have privileges to execute 'DROP' on: functional");
- AuthzError("drop database if exists functional cascade",
- "User '%s' does not have privileges to execute 'DROP' on: functional");
- AuthzError("drop database if exists functional restrict",
- "User '%s' does not have privileges to execute 'DROP' on: functional");
-
- // Database does not exist, user doesn't have permission to drop.
- AuthzError("drop database nodb",
- "User '%s' does not have privileges to execute 'DROP' on: nodb");
- AuthzError("drop database if exists nodb",
- "User '%s' does not have privileges to execute 'DROP' on: nodb");
- AuthzError("drop database if exists nodb cascade",
- "User '%s' does not have privileges to execute 'DROP' on: nodb");
- AuthzError("drop database if exists nodb restrict",
- "User '%s' does not have privileges to execute 'DROP' on: nodb");
-
- AuthzError("drop database _impala_builtins",
- "Cannot modify system database.");
- }
-
- @Test
- public void TestDropTable() throws ImpalaException {
- // Drop table (user has permission).
- AuthzOk("drop table tpch.lineitem");
- AuthzOk("drop table if exists tpch.lineitem");
-
- // User has DROP privilege on functional.alltypesagg table.
- AuthzOk("drop table functional.alltypesagg");
-
- // Drop table (user does not have permission).
- AuthzError("drop table functional.alltypes",
- "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes");
- AuthzError("drop table if exists functional.alltypes",
- "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes");
- // Drop table when user only has column-level privileges
- AuthzError("drop table if exists functional.alltypestiny", "User '%s' does not " +
- "have privileges to execute 'DROP' on: functional.alltypestiny");
-
- // Drop table with unqualified table name.
- AuthzError("drop table alltypes",
- "User '%s' does not have privileges to execute 'DROP' on: default.alltypes");
-
- // Drop table with non-existent database.
- AuthzError("drop table nodb.alltypes",
- "User '%s' does not have privileges to execute 'DROP' on: nodb.alltypes");
-
- // Drop table with non-existent table.
- AuthzError("drop table functional.notbl",
- "User '%s' does not have privileges to execute 'DROP' on: functional.notbl");
-
- // Using DROP TABLE on a view does not reveal privileged information.
- AuthzError("drop table functional.view_view",
- "User '%s' does not have privileges to execute 'DROP' on: functional.view_view");
-
- // Using DROP TABLE on a view does not reveal privileged information.
- AuthzError("drop table if exists _impala_builtins.tbl",
- "Cannot modify system database.");
- }
-
- @Test
- public void TestDropView() throws ImpalaException {
- // Drop view (user has permission).
- AuthzOk("drop view functional_seq_snap.alltypes_view");
- AuthzOk("drop view if exists functional_seq_snap.alltypes_view");
-
- // User has DROP privilege on functional.alltypes_view view.
- AuthzOk("drop view functional.alltypes_view");
-
- // User does not have DROP privilege on functional.alltypes_view_sub view.
- AuthzError("drop view functional.alltypes_view_sub",
- "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes");
- AuthzError("drop view if exists functional.alltypes_view_sub",
- "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes");
-
- // Drop view with unqualified table name.
- AuthzError("drop view alltypes",
- "User '%s' does not have privileges to execute 'DROP' on: default.alltypes");
-
- // Drop view with non-existent database.
- AuthzError("drop view nodb.alltypes",
- "User '%s' does not have privileges to execute 'DROP' on: nodb.alltypes");
-
- // Drop view with non-existent table.
- AuthzError("drop view functional.notbl",
- "User '%s' does not have privileges to execute 'DROP' on: functional.notbl");
-
- // Using DROP VIEW on a table does not reveal privileged information.
- AuthzError("drop view functional.alltypes",
- "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes");
-
- // Using DROP VIEW on a table does not reveal privileged information.
- AuthzError("drop view _impala_builtins.my_view",
- "Cannot modify system database.");
- }
-
- @Test
- public void TestTruncate() throws ImpalaException {
- AuthzOk("truncate table functional_parquet.alltypes");
-
- // User doesn't have INSERT permissions in the target table.
- AuthzError("truncate table functional.alltypesagg",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.alltypesagg");
-
- // User doesn't have INSERT permissions in the target view.
- // Truncating a view is not allowed.
- AuthzError("truncate table functional.alltypes_view",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.alltypes_view");
-
- // User doesn't have INSERT permissions on the target table but has SELECT permissions
- // on all the columns.
- AuthzError("truncate table functional.alltypestiny", "User '%s' does not have " +
- "privileges to execute 'INSERT' on: functional.alltypestiny");
- }
-
- @Test
- public void TestAlterTable() throws ImpalaException {
- // User has permissions to modify tables.
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes ADD COLUMNS (c1 int)");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes REPLACE COLUMNS (c1 int)");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes CHANGE int_col c1 int");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes DROP int_col");
- // Note: ALTER ... RENAME requires ALTER privileges at the TABLE level and
- // CREATE privileges at the DATABASE level.
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes RENAME TO functional_seq_snap.t1");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET FILEFORMAT PARQUET");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " +
- "'/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET TBLPROPERTIES " +
- "('a'='b', 'c'='d')");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " +
- "'hdfs://localhost:20500/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes PARTITION(year=2009, month=1) " +
- "SET LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET CACHED IN 'testPool'");
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes RECOVER PARTITIONS");
-
- // User has ALTER privilege only to modify tables.
- AuthzOk("ALTER TABLE functional.alltypeserror ADD COLUMNS (c1 int)");
- AuthzOk("ALTER TABLE functional.alltypeserror REPLACE COLUMNS (c1 int)");
- AuthzOk("ALTER TABLE functional.alltypeserror CHANGE id c1 int");
- AuthzOk("ALTER TABLE functional.alltypeserror DROP id");
- AuthzOk("ALTER TABLE functional.alltypeserror RENAME TO functional_seq_snap.t1");
- AuthzOk("ALTER TABLE functional.alltypeserror SET FILEFORMAT PARQUET");
- AuthzOk("ALTER TABLE functional.alltypeserror SET LOCATION " +
- "'/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional.alltypeserror SET TBLPROPERTIES ('a'='b', 'c'='d')");
- AuthzOk("ALTER TABLE functional.alltypeserror SET LOCATION " +
- "'hdfs://localhost:20500/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional.alltypeserror PARTITION(year=2009, month=1) " +
- "SET LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional.alltypeserror SET CACHED IN 'testPool'");
- AuthzOk("ALTER TABLE functional.alltypeserror RECOVER PARTITIONS");
-
- // User has ALTER privilege on functional_text_lzo database.
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror ADD COLUMNS (c1 int)");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror REPLACE COLUMNS (c1 int)");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror CHANGE id c1 int");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror DROP id");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror RENAME TO " +
- "functional_seq_snap.t1");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET FILEFORMAT PARQUET");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET LOCATION " +
- "'/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET TBLPROPERTIES " +
- "('a'='b', 'c'='d')");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET LOCATION " +
- "'hdfs://localhost:20500/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror " +
- "PARTITION(year=2009, month=1) SET LOCATION " +
- "'hdfs://localhost:20500/test-warehouse/new_table'");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET CACHED IN 'testPool'");
- AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror RECOVER PARTITIONS");
-
- // Alter table and set location to a path the user does not have access to.
- // User needs ALTER on table and ALL on URI.
- AuthzError("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " +
- "'hdfs://localhost:20500/test-warehouse/no_access'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/no_access");
- AuthzError("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " +
- "'/test-warehouse/no_access'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/no_access");
- AuthzError("ALTER TABLE functional_seq_snap.alltypes PARTITION(year=2009, month=1) " +
- "SET LOCATION '/test-warehouse/no_access'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/no_access");
-
- AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " +
- "'hdfs://localhost:20500/test-warehouse/no_access'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/no_access");
- AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " +
- "'/test-warehouse/no_access'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/no_access");
- AuthzError("ALTER TABLE functional.alltypeserror " +
- "PARTITION(year=2009, month=1) SET LOCATION '/test-warehouse/no_access'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/no_access");
-
- // Add multiple partitions. User has access to location path.
- AuthzOk("ALTER TABLE functional_seq_snap.alltypes ADD " +
- "PARTITION(year=2011, month=1) " +
- "PARTITION(year=2011, month=2) " +
- "LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'");
- // For one new partition location is set to a path the user does not have access to.
- AuthzError("ALTER TABLE functional_seq_snap.alltypes ADD " +
- "PARTITION(year=2011, month=3) " +
- "PARTITION(year=2011, month=4) LOCATION '/test-warehouse/no_access'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/no_access");
-
- // Different filesystem, user has permission to base path.
- AuthzError("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " +
- "'hdfs://localhost:20510/test-warehouse/new_table'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20510/test-warehouse/new_table");
-
- // ALTER privilege only. Add multiple partitions. User has access to location path.
- AuthzOk("ALTER TABLE functional.alltypeserror ADD " +
- "PARTITION(year=2011, month=1) PARTITION(year=2011, month=2) " +
- "LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'");
- // ALTER privilege only. For one new partition location is set to a path the user
- // does not have access to.
- AuthzError("ALTER TABLE functional.alltypeserror ADD " +
- "PARTITION(year=2011, month=3) PARTITION(year=2011, month=4) " +
- "LOCATION '/test-warehouse/no_access'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/no_access");
- // ALTER privilege only. Different filesystem, user has permission to base path.
- AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " +
- "'hdfs://localhost:20510/test-warehouse/new_table'",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20510/test-warehouse/new_table");
-
- // User does not have ALTER privilege.
- AuthzError("ALTER TABLE functional.alltypes SET FILEFORMAT PARQUET",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes ADD COLUMNS (c1 int)",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes REPLACE COLUMNS (c1 int)",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes CHANGE int_col c1 int",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes DROP int_col",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes rename to functional_seq_snap.t1",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes add partition (year=1, month=1)",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes set cached in 'testPool'",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes set uncached",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("ALTER TABLE functional.alltypes recover partitions",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
-
- // Trying to ALTER TABLE a view does not reveal any privileged information.
- AuthzError("ALTER TABLE functional.view_view SET FILEFORMAT PARQUET",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view");
- AuthzError("ALTER TABLE functional.view_view ADD COLUMNS (c1 int)",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view");
- AuthzError("ALTER TABLE functional.view_view REPLACE COLUMNS (c1 int)",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view");
- AuthzError("ALTER TABLE functional.view_view CHANGE int_col c1 int",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view");
- AuthzError("ALTER TABLE functional.view_view DROP int_col",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view");
- AuthzError("ALTER TABLE functional.view_views rename to functional_seq_snap.t1",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view");
-
- // No privileges on target (existing table).
- AuthzError("ALTER TABLE functional_seq_snap.alltypes rename to functional.alltypes",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional.alltypes");
-
- // No privileges on target (new table).
- AuthzError("ALTER TABLE functional_seq_snap.alltypes rename to functional.newtbl",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional");
-
- // No privileges on target (existing view).
- AuthzError("ALTER TABLE functional_seq_snap.alltypes rename to " +
- "functional.alltypes_view",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional.alltypes");
-
- // ALTER TABLE on a view does not reveal privileged information.
- AuthzError("ALTER TABLE functional.alltypes_view_sub rename to " +
- "functional_seq_snap.new_view",
- "User '%s' does not have privileges to execute 'ALTER' on: " +
- "functional.alltypes_view");
-
- // Rename table that does not exist (no permissions).
- AuthzError("ALTER TABLE functional.notbl rename to functional_seq_snap.newtbl",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl");
-
- // Rename table in db that does not exist (no permissions).
- AuthzError("ALTER TABLE nodb.alltypes rename to functional_seq_snap.newtbl",
- "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes");
-
- // Alter table that does not exist (no permissions).
- AuthzError("ALTER TABLE functional.notbl ADD COLUMNS (c1 int)",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl");
-
- // Alter table in db that does not exist (no permissions).
- AuthzError("ALTER TABLE nodb.alltypes ADD COLUMNS (c1 int)",
- "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes");
-
- // Unqualified table name.
- AuthzError("ALTER TABLE alltypes ADD COLUMNS (c1 int)",
- "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes");
-
- AuthzError("ALTER TABLE alltypes SET TBLPROPERTIES ('a'='b', 'c'='d')",
- "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes");
-
- // Alter table, user only has column-level privileges.
- AuthzError("ALTER TABLE functional.alltypestiny ADD COLUMNS (c1 int)", "User " +
- "'%s' does not have privileges to execute 'ALTER' on: functional.alltypestiny");
-
- // User has column-level privileges on the column being dropped but no table-level
- // privileges
- AuthzError("ALTER TABLE functional.alltypestinyt DROP id", "User '%s' does not " +
- "have privileges to execute 'ALTER' on: functional.alltypestiny");
- }
-
- @Test
- public void TestAlterView() throws ImpalaException {
- AuthzOk("ALTER VIEW functional_seq_snap.alltypes_view rename to " +
- "functional_seq_snap.v1");
- AuthzOk("ALTER VIEW functional.alltypes_view (a, b, c) as " +
- "select int_col, string_col, timestamp_col from functional.alltypesagg");
-
- // ALTER privilege on view only. RENAME also requires CREATE privileges on the DB.
- AuthzOk("ALTER VIEW functional.alltypes_view rename to functional_seq_snap.view_view_1");
-
- // No create privileges on target db
- AuthzError("ALTER VIEW functional.alltypes_view rename to functional.newview",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional");
-
- // No privileges on target (existing table).
- AuthzError("ALTER VIEW functional_seq_snap.alltypes_view rename to " +
- "functional.alltypes",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional.alltypes");
-
- // No privileges on target (existing view).
- AuthzError("ALTER VIEW functional_seq_snap.alltypes_view rename to " +
- "functional.alltypes_view",
- "User '%s' does not have privileges to execute 'CREATE' on: " +
- "functional.alltypes_view");
-
- // ALTER VIEW on a table does not reveal privileged information.
- AuthzError("ALTER VIEW functional.alltypes rename to " +
- "functional_seq_snap.new_view",
- "User '%s' does not have privileges to execute 'ALTER' on: " +
- "functional.alltypes");
- AuthzError("ALTER VIEW functional.alltypes (a, b, c) as " +
- "select int_col, string_col, timestamp_col from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'ALTER' on: " +
- "functional.alltypes");
-
- // Rename view that does not exist (no permissions).
- AuthzError("ALTER VIEW functional.notbl rename to functional_seq_snap.newtbl",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl");
-
- // Rename view in db that does not exist (no permissions).
- AuthzError("ALTER VIEW nodb.alltypes rename to functional_seq_snap.newtbl",
- "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes");
-
- // Alter view that does not exist (no permissions).
- AuthzError("ALTER VIEW functional.notbl rename to functional_seq_snap.new_view",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl");
- AuthzError("ALTER VIEW functional.notbl (a, b, c) as " +
- "select int_col, string_col, timestamp_col from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl");
-
- // Alter view in db that does not exist (no permissions).
- AuthzError("ALTER VIEW nodb.alltypes rename to functional_seq_snap.new_view",
- "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes");
- AuthzError("ALTER VIEW nodb.alltypes (a, b, c) as " +
- "select int_col, string_col, timestamp_col from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes");
-
- // Unqualified view name.
- AuthzError("ALTER VIEW alltypes rename to functional_seq_snap.new_view",
- "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes");
- AuthzError("ALTER VIEW alltypes (a, b, c) as " +
- "select int_col, string_col, timestamp_col from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes");
-
- // No permissions on target view.
- AuthzError("alter view functional.alltypes_view_sub as " +
- "select * from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'ALTER' on: " +
- "functional.alltypes_view");
- AuthzError("alter view functional.alltypes_view_sub (a, b, c) as " +
- "select int_col, string_col, timestamp_col from functional.alltypesagg",
- "User '%s' does not have privileges to execute 'ALTER' on: " +
- "functional.alltypes_view");
-
- // No permissions on source view.
- AuthzError("alter view functional_seq_snap.alltypes_view " +
- "as select * from functional.alltypes_view",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes_view");
- AuthzError("alter view functional_seq_snap.alltypes_view (a, b, c) " +
- "as select int_col, string_col, timestamp_col from functional.alltypes_view",
- "User '%s' does not have privileges to execute 'SELECT' on: " +
- "functional.alltypes_view");
- }
-
- @Test
- public void TestComputeStatsTable() throws ImpalaException {
- AuthzOk("compute stats functional_seq_snap.alltypes");
- // User has ALTER privilege on functional.alltypeserror table.
- AuthzOk("compute stats functional.alltypeserror");
-
- AuthzError("compute stats functional.alltypes",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("compute stats functional.alltypesagg",
- "User '%s' does not have privileges to execute 'ALTER' on: " +
- "functional.alltypesagg");
- // User has column-level privileges on the target table
- AuthzError("compute stats functional.alltypestiny", "User '%s' does not have " +
- "privileges to execute 'ALTER' on: functional.alltypestiny");
- }
-
- @Test
- public void TestDropStats() throws ImpalaException {
- AuthzOk("drop stats functional_seq_snap.alltypes");
- // User has ALTER privilege on functional.alltypeserror table.
- AuthzOk("drop stats functional.alltypeserror");
-
- AuthzError("drop stats functional.alltypes",
- "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
- AuthzError("drop stats functional.alltypesagg",
- "User '%s' does not have privileges to execute 'ALTER' on: " +
- "functional.alltypesagg");
- // User has column-level privileges on the target table
- AuthzError("drop stats functional.alltypestiny", "User '%s' does not have " +
- "privileges to execute 'ALTER' on: functional.alltypestiny");
- }
-
- @Test
- public void TestDescribeDb() throws ImpalaException {
- AuthzOk("describe database functional_seq_snap");
- // User has REFRESH privilege on functional_text_lzo database.
- AuthzOk("describe database functional_text_lzo");
-
- // Database doesn't exist.
- AuthzError("describe database nodb",
- "User '%s' does not have privileges to access: nodb");
- // Insufficient privileges on db.
- AuthzError("describe database functional_rc",
- "User '%s' does not have privileges to access: functional_rc");
- }
-
- @Test
- public void TestDescribe() throws ImpalaException {
- // User has SELECT and REFRESH privileges on functional.alltypesagg table.
- AuthzOk("describe functional.alltypesagg");
- AuthzOk("describe functional.alltypes");
- AuthzOk("describe functional.complex_view");
-
- // Unqualified table name.
- AuthzError("describe alltypes",
- "User '%s' does not have privileges to access: default.alltypes");
- // Database doesn't exist.
- AuthzError("describe nodb.alltypes",
- "User '%s' does not have privileges to access: nodb.alltypes");
- // User has column level privileges
- AuthzOk("describe functional.alltypestiny");
- // User has column level privileges on a subset of table columns
- AuthzOk("describe functional.alltypessmall");
- // User has column level privileges on described column.
- AuthzOk("describe functional.allcomplextypes.int_struct_col");
- // User has column level privileges on another column in table but not this one.
- AuthzError("describe functional.allcomplextypes.complex_struct_col",
- "User '%s' does not have privileges to access: functional.allcomplextypes");
- // User has table level privileges without column level.
- AuthzOk("describe functional_parquet.allcomplextypes.complex_struct_col");
- // Column level privileges will allow describe but with reduced data.
- AuthzOk("describe formatted functional.alltypestiny");
- // Column level privileges will allow describe but with reduced data.
- AuthzOk("describe formatted functional.alltypessmall");
- // Insufficient privileges on table for nested column.
- AuthzError("describe functional.complextypes_fileformat.s",
- "User '%s' does not have privileges to access: functional.complextypes_fileformat");
- // Insufficient privileges on view.
- AuthzError("describe functional.alltypes_view_sub",
- "User '%s' does not have privileges to access: functional.alltypes_view_sub");
- // Insufficient privileges on db.
- AuthzError("describe functional_rc.alltypes",
- "User '%s' does not have privileges to access: functional_rc.alltypes");
- // Insufficient privileges on column that is a complex type, trying to access member.
- AuthzError("describe functional.allcomplextypes.complex_struct_col.f2",
- "User '%s' does not have privileges to access: functional.allcomplextypes");
- // Insufficient privileges on column that is not a complex type, trying to access member.
- AuthzError("describe functional.allcomplextypes.nested_struct_col.f1",
- "User '%s' does not have privileges to access: functional.allcomplextypes");
- }
-
- private static class DescribeResult {
- // List of column names.
- private final List<String> columns_;
- // The value of the describe result's location field.
- private final String location_;
-
- public DescribeResult(List<String> columns, String location) {
- this.columns_ = columns;
- this.location_ = location;
- }
-
- public DescribeResult(List<String> columns) {
- this(columns, null);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- DescribeResult that = (DescribeResult) o;
- return Objects.equals(columns_, that.columns_) &&
- Objects.equals(location_, that.location_);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(columns_, location_);
- }
-
- @Override
- public String toString() {
- return "DescribeResult{" +
- "columns=" + columns_ +
- ", location='" + location_ + '\'' +
- '}';
- }
- }
-
- // Expected output of DESCRIBE for functional.alltypessmall.
- private static final DescribeResult EXPECTED_DESCRIBE_ALLTYPESSMALL =
- new DescribeResult(Lists.newArrayList(
- "id",
- "int_col",
- "year"
- ));
-
- // Expected output of DESCRIBE for functional.alltypesagg.
- private static final DescribeResult EXPECTED_DESCRIBE_ALLTYPESAGG =
- new DescribeResult(Lists.newArrayList(
- "id",
- "bool_col",
- "tinyint_col",
- "smallint_col",
- "int_col",
- "bigint_col",
- "float_col",
- "double_col",
- "date_string_col",
- "string_col",
- "timestamp_col",
- "year",
- "month",
- "day"
- ));
-
- // Expected output of DESCRIBE for functional.alltypesagg.
- private static final DescribeResult EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG =
- new DescribeResult(Lists.newArrayList(
- "id",
- "bool_col",
- "tinyint_col",
- "smallint_col",
- "int_col",
- "bigint_col",
- "float_col",
- "double_col",
- "date_string_col",
- "string_col",
- "timestamp_col",
- "year",
- "month",
- "day"),
- "hdfs://localhost:20500/test-warehouse/alltypesagg"
- );
-
- // Expected output of DESCRIBE for functional.alltypessmall.
- private static final DescribeResult EXPECTED_DESCRIBE_EXTENDED_ALLTYPESSMALL =
- new DescribeResult(Lists.newArrayList(
- "id",
- "int_col",
- "year"
- ));
-
- @Test
- public void TestDescribeTableResults() throws ImpalaException {
- // Running these statements force the tables to be loaded into the catalog, which
- // allows running this test independently of other tests.
- AuthzOk("describe functional.alltypesagg");
- AuthzOk("describe functional.alltypessmall");
-
- // Verify MINIMAL describe contains all columns.
- TDescribeOutputStyle style = TDescribeOutputStyle.MINIMAL;
- TDescribeResult result = fe_.describeTable(new TTableName("functional",
- "alltypesagg"), style, USER);
- assertEquals(EXPECTED_DESCRIBE_ALLTYPESAGG, toDescribeResult(result, style));
-
- // Verify MINIMAL describe on restricted table shows limited columns.
- style = TDescribeOutputStyle.MINIMAL;
- result = fe_.describeTable(new TTableName("functional", "alltypessmall"), style,
- USER);
- assertEquals(EXPECTED_DESCRIBE_ALLTYPESSMALL, toDescribeResult(result, style));
-
- for (TDescribeOutputStyle s : new TDescribeOutputStyle[]{
- TDescribeOutputStyle.EXTENDED, TDescribeOutputStyle.FORMATTED}) {
- // Verify FORMATTED/EXTENDED output contains all columns and metadata.
- result = fe_.describeTable(new TTableName("functional", "alltypesagg"), s, USER);
- assertEquals(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG, toDescribeResult(result, s));
-
- // Verify FORMATTED output contains all columns and metadata.
- result = fe_.describeTable(new TTableName("functional", "alltypessmall"), s, USER);
- assertEquals(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESSMALL, toDescribeResult(result, s));
- }
- }
-
- private static DescribeResult toDescribeResult(TDescribeResult result,
- TDescribeOutputStyle style) {
- List<String> columns = new ArrayList<>();
- String location = null;
- List<TResultRow> rows = result.getResults();
- switch (style) {
- case MINIMAL:
- // Example output:
- // [[bool_col,boolean,]
- // [month,int,]]
- for (TResultRow row : rows) {
- columns.add(row.getColVals().get(0).getString_val().trim());
- }
- break;
- case EXTENDED:
- case FORMATTED:
- // Example output:
- // [[name,type,comment],
- // [#col_name,data_type,comment],
- // [,,],
- // [bool_col,boolean,],
- // [tinyint_col,tinyint,],
- // [,,],
- // [#PartitionInformation,,],
- // [#col_name,data_type,comment],
- // [,,],
- // [year,int,],
- // [month,int,],
- // [,,],
- // [#DetailedTableInformation,,],
- // [Database:,functional,],
- // [Location:,hdfs://localhost:20500/test-warehouse/alltypes,],
- // [,,]
- // [#StorageInformation,,]
- // [SerDeLibrary:,org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe,]
- // [InputFormat:,org.apache.hadoop.mapred.TextInputFormat,]]
- int rowIdx = 0;
- while (rowIdx < rows.size()) {
- List<TColumnValue> cols = rows.get(rowIdx).getColVals();
- if (cols.get(0).getString_val().startsWith("Location")) {
- Preconditions.checkState(location == null);
- location = cols.get(1).getString_val().trim();
- } else if (cols.get(0).getString_val().startsWith("# col_name")) {
- // To get the column names, we need to ignore the first empty line and stop
- // until we see another empty line.
- rowIdx += 2; // Skips over the first empty line.
- Preconditions.checkElementIndex(rowIdx, rows.size());
- cols = rows.get(rowIdx).getColVals();
- // Stop when we see the next empty line.
- while (!cols.get(0).getString_val().trim().isEmpty()) {
- columns.add(cols.get(0).getString_val().trim());
- rowIdx++;
- Preconditions.checkElementIndex(rowIdx, rows.size());
- cols = rows.get(rowIdx).getColVals();
- }
- }
- rowIdx++;
- }
- break;
- default:
- throw new IllegalArgumentException("Invalid describe output style: " + style);
- }
- return new DescribeResult(columns, location);
- }
-
- @Test
- public void TestLoad() throws ImpalaException {
- // User has permission on table and URI.
- AuthzOk("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" +
- " into table functional.alltypes partition(month=10, year=2009)");
-
- // User does not have permission on table.
- AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" +
- " into table functional.alltypesagg",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.alltypesagg");
-
- // User only has column-level privileges on the table
- AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" +
- " into table functional.alltypestiny",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.alltypestiny");
-
- // User does not have permission on URI.
- AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.part'" +
- " into table functional.alltypes partition(month=10, year=2009)",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/tpch.part");
-
- // URI does not exist and user does not have permission.
- AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/nope'" +
- " into table functional.alltypes partition(month=10, year=2009)",
- "User '%s' does not have privileges to access: " +
- "hdfs://localhost:20500/test-warehouse/nope");
-
- // Table/Db does not exist, user does not have permission.
- AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" +
- " into table functional.notable",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.notable");
- AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" +
- " into table nodb.alltypes",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "nodb.alltypes");
-
- // Trying to LOAD a view does not reveal privileged information.
- AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" +
- " into table functional.alltypes_view",
- "User '%s' does not have privileges to execute 'INSERT' on: " +
- "functional.alltypes_view");
- }
-
- @Test
- public void TestShowPermissions() throws ImpalaException {
- AuthzOk("show tables in functional");
- AuthzOk("show tables in functional_avro"); // Database with only column privileges.
- AuthzOk("show databases");
- AuthzOk("show tables in _impala_builtins");
- AuthzOk("show functions in _impala_builtins");
- // User has REFRESH privilege on functional_text_lzo database.
- AuthzOk("show tables in functional_text_lzo");
- AuthzOk("show functions in functional_text_lzo");
-
- // Database exists, user does not have access.
- AuthzError("show tables in functional_rc",
- "User '%s' does not have privileges to access: functional_rc.*");
-
- // Database does not exist, user does not have access.
- AuthzError("show tables in nodb",
- "User '%s' does not have privileges to access: nodb.*");
-
- AuthzError("show tables",
- "User '%s' does not have privileges to access: default.*");
-
- // Database does not exist, user has access.
- try {
- AuthzOk("show tables in newdb");
- fail("Expected AnalysisException");
- } catch (AnalysisException e) {
- Assert.assertEquals(e.getMessage(), "Database does not exist: newdb");
- }
-
- // Show partitions and show table/column stats.
- String[] statsQuals = new String[] { "partitions", "table stats", "column stats" };
- for (String qual: statsQuals) {
- // User has SELECT and REFRESH privileges on functional.alltypesagg table.
- AuthzOk(String.format("show %s functional.alltypesagg", qual));
- AuthzOk(String.format("show %s functional.alltypes", qual));
- // User does not have access to db/table.
- AuthzError(String.format("show %s nodb.tbl", qual),
- "User '%s' does not have privileges to access: nodb.tbl");
- AuthzError(String.format("show %s functional.badtbl", qual),
- "User '%s' does not have privileges to access: functional.badtbl");
- AuthzError(String.format("show %s functional_rc.alltypes", qual),
- "User '%s' does not have privileges to access: functional_rc.alltypes");
- // User only has column-level privileges
- AuthzError(String.format("show %s functional.alltypestiny", qual),
- "User '%s' does not have privileges to access: functional.alltypestiny");
- }
-
- // Show files
- String[] partitions = new String[] { "", "partition(month=10, year=2010)" };
- for (String partition: partitions) {
- // User has SELECT and REFRESH privileges on functional.alltypesagg table.
- AuthzOk(String.format("show files in functional.alltypesagg %s", partition));
- AuthzOk(String.format("show files in functional.alltypes %s", partition));
- // User does not have access to db/table.
- AuthzError(String.format("show files in nodb.tbl %s", partition),
- "User '%s' does not have privileges to access: nodb.tbl");
- AuthzError(String.format("show files in functional.badtbl %s", partition),
- "User '%s' does not have privileges to access: functional.badtbl");
- AuthzError(String.format("show files in functional_rc.alltypes %s", partition),
- "User '%s' does not have privileges to access: functional_rc.alltypes");
- // User only has column-level privileges.
- AuthzError(String.format("show files in functional.alltypestiny %s", partition),
- "User '%s' does not have privileges to access: functional.alltypestiny");
- }
- }
-
- @Test
public void TestShowDbResultsFiltered() throws ImpalaException {
// These are the only dbs that should show up because they are the only
// dbs the user has any permissions on.
@@ -2202,35 +653,6 @@ public class AuthorizationTest extends FrontendTestBase {
}
@Test
- public void TestShowCreateTable() throws ImpalaException {
- // User has SELECT and REFRESH privileges functional.alltypesagg table.
- AuthzOk("show create table functional.alltypesagg");
- AuthzOk("show create table functional.alltypes");
- // Have permissions on view and underlying table.
- AuthzOk("show create table functional_seq_snap.alltypes_view");
- // Unqualified table name.
- AuthzError("show create table alltypes",
- "User '%s' does not have privileges to access: default.alltypes");
- // Database doesn't exist.
- AuthzError("show create table nodb.alltypes",
- "User '%s' does not have privileges to access: nodb.alltypes");
- // Insufficient privileges on table.
- AuthzError("show create table functional.alltypestiny",
- "User '%s' does not have privileges to access: functional.alltypestiny");
- // Insufficient privileges on db.
- AuthzError("show create table functional_rc.alltypes",
- "User '%s' does not have privileges to access: functional_rc.alltypes");
- // User has column-level privileges on table
- AuthzError("show create table functional.alltypestiny",
- "User '%s' does not have privileges to access: functional.alltypestiny");
-
- // Cannot show SQL if user doesn't have permissions on underlying table.
- AuthzError("show create table functional.complex_view",
- "User '%s' does not have privileges to see the definition of view " +
- "'functional.complex_view'.");
- }
-
- @Test
public void TestHs2GetTables() throws ImpalaException {
TMetadataOpRequest req = new TMetadataOpRequest();
req.setSession(createSessionState("default", USER));
@@ -2496,121 +918,6 @@ public class AuthorizationTest extends FrontendTestBase {
}
@Test
- public void TestFunction() throws Exception {
- // First try with the less privileged user.
- AnalysisContext ctx = createAnalysisCtx(ctx_.authzConfig, USER.getName());
-
- // User has CREATE privilege on functional_text_lzo database and ALL privilege
- // on /test-warehouse/libTestUdfs.so URI.
- AuthzOk(ctx, "create function functional_text_lzo.f() returns int location " +
- "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'");
-
- AuthzError(ctx, "show functions",
- "User '%s' does not have privileges to access: default");
- AuthzOk(ctx, "show functions in tpch");
-
- AuthzError(ctx, "create function f() returns int location " +
- "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'",
- "User '%s' does not have privileges to CREATE functions in: default.f()");
-
- // User has ALL privilege on tpch database and ALL privilege on
- // /test-warehouse/libTestUdfs.so URI.
- AuthzOk(ctx, "create function tpch.f() returns int location " +
- "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'");
-
- AuthzError(ctx, "create function notdb.f() returns int location " +
- "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'",
- "User '%s' does not have privileges to CREATE functions in: notdb.f()");
-
- // User has DROP privilege on functional_text_lzo database.
- try {
- ctx_.catalog.addFunction(ScalarFunction.createForTesting("functional_text_lzo",
- "f", new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null,
- null, TFunctionBinaryType.NATIVE));
- AuthzOk("drop function functional_text_lzo.f()");
- } finally {
- ctx_.catalog.removeFunction(ScalarFunction.createForTesting("functional_text_lzo",
- "f", new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null,
- null, TFunctionBinaryType.NATIVE));
- }
-
- AuthzError(ctx, "drop function if exists f()",
- "User '%s' does not have privileges to DROP functions in: default.f()");
-
- AuthzError(ctx, "drop function notdb.f()",
- "User '%s' does not have privileges to DROP functions in: notdb.f()");
-
- // User does not have ALL privilege on SERVER and tries to create a function with
- // the same name as the built-in function.
- AuthzError(ctx, "create function sin(double) returns double location " +
- "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'",
- "User '%s' does not have privileges to CREATE functions in: " +
- "default.sin(DOUBLE)");
- // User tries to create a function in the system database.
- AuthzError(ctx, "create function _impala_builtins.sin(double) returns double " +
- "location '/test-warehouse/libTestUdfs.so' symbol='NoArgs'",
- "Cannot modify system database.");
- AuthzError(ctx, "create function _impala_builtins.f(double) returns double " +
- "location '/test-warehouse/libTestUdfs.so' symbol='NoArgs'",
- "Cannot modify system database.");
- // User tries to drop a function with the same name as builtin.
- AuthzError(ctx, "drop function _impala_builtins.sin(double)",
- "Cannot modify system database.");
- AuthzError(ctx, "drop function sin(double)",
- "User '%s' does not have privileges to DROP functions in: " +
- "default.sin(DOUBLE)");
-
- // TODO: Add test support for dynamically changing privileges for
- // file-based policy.
- if (ctx_.authzConfig.isFileBasedPolicy()) return;
-
- // Admin should be able to do everything
- SentryPolicyService sentryService =
- new SentryPolicyService(ctx_.authzConfig.getSentryConfig());
- try {
- sentryService.grantRoleToGroup(USER, "admin", USER.getName());
- ctx_.catalog.reset();
-
- AuthzOk("show functions");
- AuthzOk("show functions in tpch");
-
- AuthzOk("create function f() returns int location " +
- "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'");
- AuthzOk("create function tpch.f() returns int location " +
- "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'");
- AuthzOk("drop function if exists f()");
-
- // Can't add function to system db
- AuthzError("create function _impala_builtins.f() returns int location " +
- "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'",
- "Cannot modify system database.");
- AuthzOk("drop function if exists pi()");
-
- // Add default.f(), tpch.f()
- ctx_.catalog.addFunction(ScalarFunction.createForTesting("default", "f",
- new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null,
- null, TFunctionBinaryType.NATIVE));
- ctx_.catalog.addFunction(ScalarFunction.createForTesting("tpch", "f",
- new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null,
- null, TFunctionBinaryType.NATIVE));
-
- AuthzOk("drop function tpch.f()");
- } finally {
- sentryService.revokeRoleFromGroup(USER, "admin", USER.getName());
- ctx_.catalog.reset();
-
- //Other tests don't expect tpch to contain functions
- //Specifically, if these functions are not cleaned up, TestDropDatabase() will fail
- ctx_.catalog.removeFunction(ScalarFunction.createForTesting("default", "f",
- new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null,
- null, TFunctionBinaryType.NATIVE));
- ctx_.catalog.removeFunction(ScalarFunction.createForTesting("tpch", "f",
- new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null,
- null, TFunctionBinaryType.NATIVE));
- }
- }
-
- @Test
public void TestServerNameAuthorized() throws ImpalaException {
if (ctx_.authzConfig.isFileBasedPolicy()) {
// Authorization config that has a different server name from policy file.
@@ -2767,329 +1074,6 @@ public class AuthorizationTest extends FrontendTestBase {
"TBLPROPERTIES ('kudu.master_addresses'='127.0.0.1', 'kudu.table_name'='tbl')");
}
- @Test
- public void TestServerLevelInsert() throws ImpalaException {
- // TODO: Add test support for dynamically changing privileges for
- // file-based policy.
- if (ctx_.authzConfig.isFileBasedPolicy()) return;
-
- SentryPolicyService sentryService =
- new SentryPolicyService(ctx_.authzConfig.getSentryConfig());
-
- // User has INSERT privilege on server.
- String roleName = "insert_role";
- try {
- sentryService.createRole(USER, roleName, true);
- TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.INSERT,
- TPrivilegeScope.SERVER, false);
- privilege.setServer_name("server1");
- sentryService.grantRolePrivilege(USER, roleName, privilege);
- sentryService.grantRoleToGroup(USER, roleName, USER.getName());
-
- privilege = new TPrivilege ("", TPrivilegeLevel.SELECT, TPrivilegeScope.DATABASE,
- false);
- privilege.setServer_name("server1");
- privilege.setDb_name("functional_rc");
- sentryService.grantRolePrivilege(USER, roleName, privilege);
- sentryService.grantRoleToGroup(USER, roleName, USER.getName());
-
- privilege = new TPrivilege ("", TPrivilegeLevel.SELECT, TPrivilegeScope.DATABASE,
- false);
- privilege.setServer_name("server1");
- privilege.setDb_name("functional_seq");
- sentryService.grantRolePrivilege(USER, roleName, privilege);
- sentryService.grantRoleToGroup(USER, roleName, USER.getName());
- ctx_.cata
<TRUNCATED>
[2/3] impala git commit: IMPALA-6802 (part 6): Clean up authorization
tests
Posted by ta...@apache.org.
IMPALA-6802 (part 6): Clean up authorization tests
This is the last part of the authorization test clean up.
This patch rewrites the following tests:
- alter database
- explain
- comment on
- function
- alter table/view
This patch also adds the following authorization tests:
- update
- upsert
- delete
The tests in AuthorizationTest.java that have been rewritten into
AuthorizationStmtTest.java are removed.
Cherry-picks: not for 2.x
Change-Id: Id594ce09a821aef4a1debfdd61569a11defd1c55
Reviewed-on: http://gerrit.cloudera.org:8080/10841
Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
Tested-by: Impala Public Jenkins <im...@cloudera.com>
Project: http://git-wip-us.apache.org/repos/asf/impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/5c880e52
Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/5c880e52
Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/5c880e52
Branch: refs/heads/master
Commit: 5c880e52bc82270588496817fbbf1fb62ad2ef0d
Parents: 4ce2af9
Author: Fredy Wijaya <fw...@cloudera.com>
Authored: Wed Jun 27 12:59:20 2018 -0700
Committer: Impala Public Jenkins <im...@cloudera.com>
Committed: Fri Jun 29 19:16:24 2018 +0000
----------------------------------------------------------------------
.../impala/analysis/AuthorizationStmtTest.java | 595 +++++-
.../impala/analysis/AuthorizationTest.java | 2016 ------------------
2 files changed, 554 insertions(+), 2057 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/impala/blob/5c880e52/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java b/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java
index 1d4c593..0a32fc9 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java
@@ -297,6 +297,45 @@ public class AuthorizationStmtTest extends FrontendTestBase {
verifyPrivilegeReqs("drop view functional.alltypes_view", expectedAuthorizables);
verifyPrivilegeReqs(createAnalysisCtx("functional"), "drop view alltypes_view",
expectedAuthorizables);
+
+ // Update table.
+ expectedAuthorizables = Sets.newHashSet(
+ "functional_kudu.alltypes",
+ "functional_kudu.alltypes.id",
+ "functional_kudu.alltypes.int_col");
+ verifyPrivilegeReqs("update functional_kudu.alltypes set int_col = 1",
+ expectedAuthorizables);
+ verifyPrivilegeReqs(createAnalysisCtx("functional_kudu"),
+ "update alltypes set int_col = 1", expectedAuthorizables);
+
+ // Upsert table.
+ expectedAuthorizables = Sets.newHashSet("functional_kudu.alltypes");
+ verifyPrivilegeReqs("upsert into table functional_kudu.alltypes(id, int_col) " +
+ "values(1, 1)", expectedAuthorizables);
+ verifyPrivilegeReqs(createAnalysisCtx("functional_kudu"),
+ "upsert into table alltypes(id, int_col) values(1, 1)", expectedAuthorizables);
+
+ // Delete table.
+ expectedAuthorizables = Sets.newHashSet(
+ "functional_kudu.alltypes",
+ "functional_kudu.alltypes.id");
+ verifyPrivilegeReqs("delete from functional_kudu.alltypes", expectedAuthorizables);
+ verifyPrivilegeReqs(createAnalysisCtx("functional_kudu"), "delete from alltypes",
+ expectedAuthorizables);
+
+ // Alter table.
+ expectedAuthorizables = Sets.newHashSet("functional.alltypes");
+ verifyPrivilegeReqs("alter table functional.alltypes add columns(c1 int)",
+ expectedAuthorizables);
+ verifyPrivilegeReqs(createAnalysisCtx("functional"), "alter table alltypes " +
+ "add columns(c1 int)", expectedAuthorizables);
+
+ // Alter view.
+ expectedAuthorizables = Sets.newHashSet("functional.alltypes_view");
+ verifyPrivilegeReqs("alter view functional.alltypes_view as select 1",
+ expectedAuthorizables);
+ verifyPrivilegeReqs(createAnalysisCtx("functional"), "alter view alltypes_view as " +
+ "select 1", expectedAuthorizables);
}
@Test
@@ -403,6 +442,23 @@ public class AuthorizationStmtTest extends FrontendTestBase {
onTable("functional_seq_snap", "subquery_view", allExcept(
TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)));
+ // Select a UDF.
+ ScalarFunction fn = addFunction("functional", "f");
+ try {
+ authorize("select functional.f()")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(viewMetadataPrivileges()))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", viewMetadataPrivileges()))
+ .error(accessError("functional"))
+ .error(accessError("functional"), onServer(allExcept(
+ viewMetadataPrivileges())))
+ .error(accessError("functional"), onDatabase("functional", allExcept(
+ viewMetadataPrivileges())));
+ } finally {
+ removeFunction(fn);
+ }
+
// Select from non-existent database.
authorize("select 1 from nodb.alltypes")
.error(selectError("nodb.alltypes"));
@@ -557,20 +613,24 @@ public class AuthorizationStmtTest extends FrontendTestBase {
@Test
public void testInsert() throws ImpalaException {
// Basic insert into a table.
- authorize("insert into functional.zipcode_incomes(id) values('123')")
- .ok(onServer(TPrivilegeLevel.ALL))
- .ok(onServer(TPrivilegeLevel.INSERT))
- .ok(onDatabase("functional", TPrivilegeLevel.ALL))
- .ok(onDatabase("functional", TPrivilegeLevel.INSERT))
- .ok(onTable("functional", "zipcode_incomes", TPrivilegeLevel.ALL))
- .ok(onTable("functional", "zipcode_incomes", TPrivilegeLevel.INSERT))
- .error(insertError("functional.zipcode_incomes"))
- .error(insertError("functional.zipcode_incomes"), onServer(allExcept(
- TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT)))
- .error(insertError("functional.zipcode_incomes"), onDatabase("functional",
- allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT)))
- .error(insertError("functional.zipcode_incomes"), onTable("functional",
- "zipcode_incomes", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT)));
+ for (AuthzTest test: new AuthzTest[]{
+ authorize("insert into functional.zipcode_incomes(id) values('123')"),
+ // Explain insert.
+ authorize("explain insert into functional.zipcode_incomes(id) values('123')")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.INSERT))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.INSERT))
+ .ok(onTable("functional", "zipcode_incomes", TPrivilegeLevel.ALL))
+ .ok(onTable("functional", "zipcode_incomes", TPrivilegeLevel.INSERT))
+ .error(insertError("functional.zipcode_incomes"))
+ .error(insertError("functional.zipcode_incomes"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT)))
+ .error(insertError("functional.zipcode_incomes"), onDatabase("functional",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT)))
+ .error(insertError("functional.zipcode_incomes"), onTable("functional",
+ "zipcode_incomes", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT)));
+ }
for (AuthzTest test: new AuthzTest[]{
// With clause with insert.
@@ -1218,33 +1278,38 @@ public class AuthorizationStmtTest extends FrontendTestBase {
}
// CTAS.
- authorize("create table functional.new_table as " +
- "select int_col from functional.alltypes")
- .ok(onServer(TPrivilegeLevel.ALL))
- .ok(onServer(TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT,
- TPrivilegeLevel.SELECT))
- .ok(onDatabase("functional", TPrivilegeLevel.ALL))
- .ok(onDatabase("functional", TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT,
- TPrivilegeLevel.SELECT))
- .ok(onDatabase("functional"), onDatabase("functional", TPrivilegeLevel.CREATE,
- TPrivilegeLevel.INSERT), onTable("functional", "alltypes",
- TPrivilegeLevel.SELECT))
- .ok(onDatabase("functional"), onDatabase("functional", TPrivilegeLevel.CREATE,
- TPrivilegeLevel.INSERT), onColumn("functional", "alltypes", "int_col",
- TPrivilegeLevel.ALL))
- .error(createError("functional.new_table"))
- .error(createError("functional.new_table"), onServer(allExcept(
- TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT,
- TPrivilegeLevel.SELECT)))
- .error(createError("functional.new_table"), onDatabase("functional", allExcept(
- TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT,
- TPrivilegeLevel.SELECT)))
- .error(createError("functional.new_table"), onDatabase("functional", allExcept(
- TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT)),
- onTable("functional", "alltypes", TPrivilegeLevel.SELECT))
- .error(selectError("functional.alltypes"), onDatabase("functional",
- TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT), onTable("functional",
- "alltypes", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)));
+ for (AuthzTest test: new AuthzTest[]{
+ authorize("create table functional.new_table as " +
+ "select int_col from functional.alltypes"),
+ // Explain CTAS.
+ authorize("explain create table functional.new_table as " +
+ "select int_col from functional.alltypes")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT,
+ TPrivilegeLevel.SELECT))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT,
+ TPrivilegeLevel.SELECT))
+ .ok(onDatabase("functional"), onDatabase("functional", TPrivilegeLevel.CREATE,
+ TPrivilegeLevel.INSERT), onTable("functional", "alltypes",
+ TPrivilegeLevel.SELECT))
+ .ok(onDatabase("functional"), onDatabase("functional", TPrivilegeLevel.CREATE,
+ TPrivilegeLevel.INSERT), onColumn("functional", "alltypes", "int_col",
+ TPrivilegeLevel.ALL))
+ .error(createError("functional.new_table"))
+ .error(createError("functional.new_table"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT,
+ TPrivilegeLevel.SELECT)))
+ .error(createError("functional.new_table"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT,
+ TPrivilegeLevel.SELECT)))
+ .error(createError("functional.new_table"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT)),
+ onTable("functional", "alltypes", TPrivilegeLevel.SELECT))
+ .error(selectError("functional.alltypes"), onDatabase("functional",
+ TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT), onTable("functional",
+ "alltypes", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)));
+ }
// Table with a specific location.
authorize("create table functional.new_table(i int) location " +
@@ -1562,6 +1627,446 @@ public class AuthorizationStmtTest extends FrontendTestBase {
.error(systemDbError(), onServer(TPrivilegeLevel.ALL));
}
+ @Test
+ public void testAlterTable() throws ImpalaException {
+ for (AuthzTest test: new AuthzTest[]{
+ authorize("alter table functional.alltypes add columns(c1 int)"),
+ authorize("alter table functional.alltypes replace columns(c1 int)"),
+ authorize("alter table functional.alltypes change int_col c1 int"),
+ authorize("alter table functional.alltypes drop int_col"),
+ authorize("alter table functional.alltypes set fileformat parquet"),
+ authorize("alter table functional.alltypes set tblproperties('a'='b')"),
+ authorize("alter table functional.alltypes partition(year=2009) " +
+ "set tblproperties('a'='b')"),
+ authorize("alter table functional.alltypes set cached in 'testPool'"),
+ authorize("alter table functional.alltypes partition(year=2009) set cached " +
+ "in 'testPool'"),
+ authorize("alter table functional.alltypes sort by (id)"),
+ authorize("alter table functional.alltypes set column stats int_col " +
+ "('numNulls'='1')"),
+ authorize("alter table functional.alltypes recover partitions"),
+ authorize("alter table functional.alltypes set row format delimited fields " +
+ "terminated by ' '"),
+ authorize("alter table functional.alltypes partition(year=2009) set row format " +
+ "delimited fields terminated by ' '"),
+ authorize("alter table functional.alltypes add partition(year=1, month=1)"),
+ authorize("alter table functional.alltypes drop partition(" +
+ "year=2009, month=1)")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER))
+ .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALTER))
+ .error(alterError("functional.alltypes"))
+ .error(alterError("functional.alltypes"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.alltypes"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.alltypes"), onTable("functional", "alltypes",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+ }
+
+ // Alter table rename.
+ authorize("alter table functional.alltypes rename to functional.new_table")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE))
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE), onTable("functional",
+ "alltypes", TPrivilegeLevel.ALTER))
+ .error(alterError("functional.alltypes"))
+ .error(alterError("functional.alltypes"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE)))
+ .error(alterError("functional.alltypes"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE)))
+ .error(alterError("functional.alltypes"), onDatabase("functional",
+ TPrivilegeLevel.CREATE), onTable("functional", "alltypes", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(createError("functional.new_table"), onDatabase("functional",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE)),
+ onTable("functional", "alltypes", TPrivilegeLevel.ALTER));
+
+ // Only for Kudu tables.
+ for (AuthzTest test: new AuthzTest[]{
+ authorize("alter table functional_kudu.testtbl alter column " +
+ "name drop default"),
+ authorize("alter table functional_kudu.testtbl alter column name " +
+ "set default null"),
+ authorize("alter table functional_kudu.testtbl add range partition " +
+ "1 < values < 2"),
+ authorize("alter table functional_kudu.testtbl drop range partition " +
+ "1 < values < 2")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER))
+ .ok(onDatabase("functional_kudu", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional_kudu", TPrivilegeLevel.ALTER))
+ .ok(onTable("functional_kudu", "testtbl", TPrivilegeLevel.ALL))
+ .ok(onTable("functional_kudu", "testtbl", TPrivilegeLevel.ALTER))
+ .error(alterError("functional_kudu.testtbl"))
+ .error(alterError("functional_kudu.testtbl"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional_kudu.testtbl"), onDatabase("functional_kudu",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional_kudu.testtbl"), onTable("functional_kudu",
+ "testtbl", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+ }
+
+ // Alter table set location.
+ for (AuthzTest test: new AuthzTest[] {
+ authorize("alter table functional.alltypes set location " +
+ "'hdfs://localhost:20500/test-warehouse/new_table'"),
+ authorize("alter table functional.alltypes partition(year=2009, month=1) " +
+ "set location 'hdfs://localhost:20500/test-warehouse/new_table'")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER), onUri(
+ "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL), onUri(
+ "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER), onUri(
+ "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL))
+ .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALL), onUri(
+ "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL))
+ .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALTER), onUri(
+ "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL))
+ .error(alterError("functional.alltypes"))
+ .error(alterError("functional.alltypes"),
+ onServer(allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)),
+ onUri("hdfs://localhost:20500/test-warehouse/new_table"))
+ .error(alterError("functional.alltypes"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)),
+ onUri("hdfs://localhost:20500/test-warehouse/new_table"))
+ .error(alterError("functional.alltypes"), onTable("functional", "alltypes",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)),
+ onUri("hdfs://localhost:20500/test-warehouse/new_table"))
+ .error(accessError("hdfs://localhost:20500/test-warehouse/new_table"),
+ onDatabase("functional", TPrivilegeLevel.ALTER))
+ .error(accessError("hdfs://localhost:20500/test-warehouse/new_table"),
+ onTable("functional", "alltypes", TPrivilegeLevel.ALTER));
+ }
+
+ // Database does not exist.
+ authorize("alter table nodb.alltypes add columns(c1 int)")
+ .error(alterError("nodb"))
+ .error(alterError("nodb"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+
+ // Table does not exist.
+ authorize("alter table functional.notbl add columns(c1 int)")
+ .error(alterError("functional.notbl"))
+ .error(alterError("functional.notbl"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.notbl"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+ }
+
+ @Test
+ public void testAlterView() throws ImpalaException {
+ for (AuthzTest test: new AuthzTest[] {
+ authorize("alter view functional.alltypes_view as " +
+ "select int_col from functional.alltypes"),
+ authorize("alter view functional.alltypes_view(a) as " +
+ "select int_col from functional.alltypes")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER), onTable("functional", "alltypes",
+ TPrivilegeLevel.SELECT))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER,
+ TPrivilegeLevel.SELECT))
+ .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER),
+ onTable("functional", "alltypes", TPrivilegeLevel.SELECT))
+ .error(selectError("functional.alltypes"))
+ .error(selectError("functional.alltypes"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.SELECT)))
+ .error(selectError("functional.alltypes"), onDatabase("functional",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER,
+ TPrivilegeLevel.SELECT)))
+ .error(alterError("functional.alltypes_view"), onTable("functional", "alltypes",
+ TPrivilegeLevel.SELECT), onTable("functional", "alltypes_view", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(selectError("functional.alltypes"), onTable("functional", "alltypes",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)),
+ onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER));
+ }
+
+ // Alter view rename.
+ authorize("alter view functional.alltypes_view rename to functional.new_view")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE))
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE), onTable("functional",
+ "alltypes_view", TPrivilegeLevel.ALTER))
+ .error(alterError("functional.alltypes_view"))
+ .error(alterError("functional.alltypes_view"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE)))
+ .error(alterError("functional.alltypes_view"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE)))
+ .error(alterError("functional.alltypes_view"), onDatabase("functional",
+ TPrivilegeLevel.CREATE), onTable("functional", "alltypes_view", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(createError("functional.new_view"), onDatabase("functional",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE)),
+ onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER));
+
+ // Alter view with constant select.
+ authorize("alter view functional.alltypes_view as select 1")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER))
+ .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALL))
+ .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER))
+ .error(alterError("functional.alltypes_view"))
+ .error(alterError("functional.alltypes_view"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.alltypes_view"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.alltypes_view"), onTable("functional",
+ "alltypes_view", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+
+ // Database does not exist.
+ authorize("alter view nodb.alltypes_view as select 1")
+ .error(alterError("nodb"))
+ .error(alterError("nodb"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+
+ // View does not exist.
+ authorize("alter view functional.noview as select 1")
+ .error(alterError("functional.noview"))
+ .error(alterError("functional.noview"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.noview"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+ }
+
+ @Test
+ public void testAlterDatabase() throws ImpalaException {
+ for (String ownerType: new String[]{"user", "role"}) {
+ authorize(String.format("alter database functional set owner %s foo", ownerType))
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER))
+ .error(alterError("functional"))
+ .error(alterError("functional"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+
+ // Database does not exist.
+ authorize(String.format("alter database nodb set owner %s foo", ownerType))
+ .error(alterError("nodb"))
+ .error(alterError("nodb"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+ }
+ }
+
+ @Test
+ public void testUpdate() throws ImpalaException {
+ // Update is only supported on Kudu tables.
+ for (AuthzTest test: new AuthzTest[]{
+ authorize("update functional_kudu.alltypes set int_col = 1"),
+ // Explain update.
+ authorize("explain update functional_kudu.alltypes set int_col = 1")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .error(accessError("functional_kudu.alltypes"))
+ .error(accessError("functional_kudu.alltypes"), onServer(allExcept(
+ TPrivilegeLevel.ALL)));
+ }
+
+ // Database does not exist.
+ authorize("update nodb.alltypes set int_col = 1")
+ .error(selectError("nodb"))
+ .error(selectError("nodb"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)));
+
+ // Table does not exist.
+ authorize("update functional_kudu.notbl set int_col = 1")
+ .error(selectError("functional_kudu.notbl"))
+ .error(selectError("functional_kudu.notbl"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)))
+ .error(selectError("functional_kudu.notbl"), onDatabase("functional_kudu",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)));
+ }
+
+ @Test
+ public void testUpsert() throws ImpalaException {
+ // Upsert is only supported on Kudu tables.
+ for (AuthzTest test: new AuthzTest[]{
+ authorize("upsert into table functional_kudu.testtbl(id, name) values(1, 'a')"),
+ // Upsert with clause.
+ authorize("with t1 as (select 1, 'a', 2) upsert into functional_kudu.testtbl " +
+ "select * from t1"),
+ // Explain upsert.
+ authorize("explain upsert into table functional_kudu.testtbl(id, name) " +
+ "values(1, 'a')")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .error(accessError("functional_kudu.testtbl"))
+ .error(accessError("functional_kudu.testtbl"), onServer(allExcept(
+ TPrivilegeLevel.ALL)));
+ }
+
+ // Upsert select.
+ authorize("upsert into table functional_kudu.testtbl(id) " +
+ "select int_col from functional.alltypes")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .error(selectError("functional.alltypes"))
+ .error(accessError("functional_kudu.testtbl"), onServer(allExcept(
+ TPrivilegeLevel.ALL)));
+
+ // Database does not exist.
+ authorize("upsert into table nodb.testtbl(id, name) values(1, 'a')")
+ .error(accessError("nodb.testtbl"))
+ .error(accessError("nodb.testtbl"), onServer(allExcept(TPrivilegeLevel.ALL)));
+
+ // Table does not exist.
+ authorize("upsert into table functional_kudu.notbl(id, name) values(1, 'a')")
+ .error(accessError("functional_kudu.notbl"))
+ .error(accessError("functional_kudu.notbl"), onServer(allExcept(
+ TPrivilegeLevel.ALL)))
+ .error(accessError("functional_kudu.notbl"), onDatabase("functional_kudu",
+ allExcept(TPrivilegeLevel.ALL)));
+ }
+
+ @Test
+ public void testDelete() throws ImpalaException {
+ // Delete is only supported on Kudu tables.
+ for (AuthzTest test: new AuthzTest[]{
+ authorize("delete from functional_kudu.alltypes"),
+ authorize("explain delete from functional_kudu.alltypes")}) {
+ test.ok(onServer(TPrivilegeLevel.ALL))
+ .error(accessError("functional_kudu.alltypes"))
+ .error(accessError("functional_kudu.alltypes"), onServer(allExcept(
+ TPrivilegeLevel.ALL)));
+ }
+
+ // Database does not exist.
+ authorize("delete from nodb.alltypes")
+ .error(selectError("nodb"))
+ .error(selectError("nodb"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)));
+
+ // Table does not exist.
+ authorize("delete from functional_kudu.notbl")
+ .error(selectError("functional_kudu.notbl"))
+ .error(selectError("functional_kudu.notbl"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)))
+ .error(selectError("functional_kudu.notbl"), onDatabase("functional_kudu",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)));
+ }
+
+ @Test
+ public void testCommentOn() throws ImpalaException {
+ // Comment on database.
+ authorize("comment on database functional is 'comment'")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER))
+ .error(alterError("functional"))
+ .error(alterError("functional"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+
+ // Comment on table.
+ authorize("comment on table functional.alltypes is 'comment'")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER))
+ .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALL))
+ .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALTER))
+ .error(alterError("functional.alltypes"))
+ .error(alterError("functional.alltypes"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.alltypes"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.alltypes"), onTable("functional", "alltypes",
+ allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+
+ // Comment on view.
+ authorize("comment on view functional.alltypes_view is 'comment'")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.ALTER))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALTER))
+ .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALL))
+ .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER))
+ .error(alterError("functional.alltypes_view"))
+ .error(alterError("functional.alltypes_view"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.alltypes_view"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)))
+ .error(alterError("functional.alltypes_view"), onTable("functional",
+ "alltypes_view", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)));
+ }
+
+ @Test
+ public void testFunction() throws ImpalaException {
+ // Create function.
+ authorize("create function functional.f() returns int location " +
+ "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.CREATE), onUri("/test-warehouse/libTestUdfs.so",
+ TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL),
+ onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE),
+ onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL))
+ .error(createFunctionError("functional.f()"))
+ .error(accessError("hdfs://localhost:20500/test-warehouse/libTestUdfs.so"),
+ onServer(allExcept(TPrivilegeLevel.ALL)))
+ .error(createFunctionError("functional.f()"),
+ onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL));
+
+ // Create a function name that has the same name as built-in function is OK.
+ authorize("create function functional.sin() returns int location " +
+ "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.CREATE), onUri("/test-warehouse/libTestUdfs.so",
+ TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL),
+ onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE),
+ onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL))
+ .error(createFunctionError("functional.sin()"))
+ .error(accessError("hdfs://localhost:20500/test-warehouse/libTestUdfs.so"),
+ onServer(allExcept(TPrivilegeLevel.ALL)))
+ .error(createFunctionError("functional.sin()"),
+ onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL));
+
+ // Creating a function in the system database even with ALL privilege on SERVER is
+ // not allowed.
+ for (AuthzTest test: new AuthzTest[] {
+ authorize("create function _impala_builtins.sin() returns int location " +
+ "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'"),
+ authorize("create function _impala_builtins.f() returns int location " +
+ "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'")}) {
+ test.error(systemDbError(), onServer(TPrivilegeLevel.ALL));
+ }
+
+ ScalarFunction fn = addFunction("functional", "f");
+ try {
+ authorize("drop function functional.f()")
+ .ok(onServer(TPrivilegeLevel.ALL))
+ .ok(onServer(TPrivilegeLevel.DROP))
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL))
+ .ok(onDatabase("functional", TPrivilegeLevel.DROP))
+ .error(dropFunctionError("functional.f()"))
+ .error(dropFunctionError("functional.f()"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.DROP)));
+
+ // Function does not exist but with if exists clause.
+ authorize("drop function if exists functional.g()")
+ .error(dropFunctionError("functional.g()"))
+ .error(dropFunctionError("functional.g()"), onServer(allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.DROP)));
+ } finally {
+ removeFunction(fn);
+ }
+ }
+
// Convert TDescribeResult to list of strings.
private static List<String> resultToStringList(TDescribeResult result) {
List<String> list = new ArrayList<>();
@@ -1606,6 +2111,14 @@ public class AuthorizationStmtTest extends FrontendTestBase {
return "Cannot modify system database.";
}
+ private static String createFunctionError(String object) {
+ return "User '%s' does not have privileges to CREATE functions in: " + object;
+ }
+
+ private static String dropFunctionError(String object) {
+ return "User '%s' does not have privileges to DROP functions in: " + object;
+ }
+
private ScalarFunction addFunction(String db, String fnName) {
ScalarFunction fn = ScalarFunction.createForTesting(db, fnName,
new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null,
[3/3] impala git commit: IMPALA-7102 (Part 1): Disable reading of
erasure coding by default
Posted by ta...@apache.org.
IMPALA-7102 (Part 1): Disable reading of erasure coding by default
In this patch we add a query option ALLOW_ERASURE_CODED_FILES, that
allows us to enable or disable the support of erasure coded files. Even
though Impala should be able to handle HDFS erasure coded files already,
this feature hasn't been tested thoroughly yet. Also, Impala lacks
metrics, observability and DDL commands related to erasure coding. This
is a query option instead of a startup flag because we want to make it
possible for advanced users to enable the feature.
We may also need a follow on patch to also disable the write path with
this flag.
Cherry-picks: not for 2.x
Change-Id: Icd3b1754541262467a6e67068b0b447882a40fb3
Reviewed-on: http://gerrit.cloudera.org:8080/10646
Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
Tested-by: Impala Public Jenkins <im...@cloudera.com>
Project: http://git-wip-us.apache.org/repos/asf/impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/8060f4d5
Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/8060f4d5
Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/8060f4d5
Branch: refs/heads/master
Commit: 8060f4d50e6e9530fe90c32c65b67b2537681302
Parents: 5c880e5
Author: Taras Bobrovytsky <ta...@apache.org>
Authored: Thu May 31 18:44:57 2018 -0700
Committer: Impala Public Jenkins <im...@cloudera.com>
Committed: Fri Jun 29 23:26:35 2018 +0000
----------------------------------------------------------------------
be/src/service/query-options.cc | 4 ++++
be/src/service/query-options.h | 4 +++-
bin/run-all-tests.sh | 2 ++
common/thrift/ImpalaInternalService.thrift | 3 +++
common/thrift/ImpalaService.thrift | 3 +++
.../java/org/apache/impala/planner/HdfsScanNode.java | 6 ++++++
testdata/bin/create-load-data.sh | 4 ++++
.../queries/QueryTest/hdfs-erasure-coding.test | 15 +++++++++++++++
tests/common/custom_cluster_test_suite.py | 3 +++
tests/common/skip.py | 1 +
tests/query_test/test_observability.py | 12 ++++++++----
tests/query_test/test_scanners.py | 9 +++++++++
12 files changed, 61 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/be/src/service/query-options.cc
----------------------------------------------------------------------
diff --git a/be/src/service/query-options.cc b/be/src/service/query-options.cc
index 218e4e6..2e3415f 100644
--- a/be/src/service/query-options.cc
+++ b/be/src/service/query-options.cc
@@ -690,6 +690,10 @@ Status impala::SetQueryOption(const string& key, const string& value,
return Status(Substitute("Invalid kudu_read_mode '$0'. Valid values are "
"DEFAULT, READ_LATEST, and READ_AT_SNAPSHOT.", value));
}
+ }
+ case TImpalaQueryOptions::ALLOW_ERASURE_CODED_FILES: {
+ query_options->__set_allow_erasure_coded_files(
+ iequals(value, "true") || iequals(value, "1"));
break;
}
default:
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/be/src/service/query-options.h
----------------------------------------------------------------------
diff --git a/be/src/service/query-options.h b/be/src/service/query-options.h
index 5c4f51d..fce042c 100644
--- a/be/src/service/query-options.h
+++ b/be/src/service/query-options.h
@@ -41,7 +41,7 @@ typedef std::unordered_map<string, beeswax::TQueryOptionLevel::type>
// the DCHECK.
#define QUERY_OPTS_TABLE\
DCHECK_EQ(_TImpalaQueryOptions_VALUES_TO_NAMES.size(),\
- TImpalaQueryOptions::KUDU_READ_MODE + 1);\
+ TImpalaQueryOptions::ALLOW_ERASURE_CODED_FILES + 1);\
REMOVED_QUERY_OPT_FN(abort_on_default_limit_exceeded, ABORT_ON_DEFAULT_LIMIT_EXCEEDED)\
QUERY_OPT_FN(abort_on_error, ABORT_ON_ERROR, TQueryOptionLevel::REGULAR)\
QUERY_OPT_FN(allow_unsupported_formats, ALLOW_UNSUPPORTED_FORMATS,\
@@ -138,6 +138,8 @@ typedef std::unordered_map<string, beeswax::TQueryOptionLevel::type>
QUERY_OPT_FN(thread_reservation_aggregate_limit, THREAD_RESERVATION_AGGREGATE_LIMIT,\
TQueryOptionLevel::REGULAR)\
QUERY_OPT_FN(kudu_read_mode, KUDU_READ_MODE, TQueryOptionLevel::ADVANCED)\
+ QUERY_OPT_FN(allow_erasure_coded_files, ALLOW_ERASURE_CODED_FILES,\
+ TQueryOptionLevel::DEVELOPMENT)\
;
/// Enforce practical limits on some query options to avoid undesired query state.
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/bin/run-all-tests.sh
----------------------------------------------------------------------
diff --git a/bin/run-all-tests.sh b/bin/run-all-tests.sh
index 08d140a..83b3548 100755
--- a/bin/run-all-tests.sh
+++ b/bin/run-all-tests.sh
@@ -73,6 +73,8 @@ if [[ "${ERASURE_CODING}" = true ]]; then
# We do not run FE tests when erasure coding is enabled because planner tests
# would fail.
FE_TEST=false
+ TEST_START_CLUSTER_ARGS="${TEST_START_CLUSTER_ARGS} \
+ --impalad_args=--default_query_options=allow_erasure_coded_files=true"
fi
# If KRPC tests are disabled, pass the flag to disable KRPC during cluster start.
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/common/thrift/ImpalaInternalService.thrift
----------------------------------------------------------------------
diff --git a/common/thrift/ImpalaInternalService.thrift b/common/thrift/ImpalaInternalService.thrift
index d2a9d29..6780138 100644
--- a/common/thrift/ImpalaInternalService.thrift
+++ b/common/thrift/ImpalaInternalService.thrift
@@ -298,6 +298,9 @@ struct TQueryOptions {
// See comment in ImpalaService.thrift.
68: optional TKuduReadMode kudu_read_mode = TKuduReadMode.DEFAULT;
+
+ // Allow reading of erasure coded files in HDFS.
+ 69: optional bool allow_erasure_coded_files = false;
}
// Impala currently has two types of sessions: Beeswax and HiveServer2
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/common/thrift/ImpalaService.thrift
----------------------------------------------------------------------
diff --git a/common/thrift/ImpalaService.thrift b/common/thrift/ImpalaService.thrift
index cf62ddf..529af04 100644
--- a/common/thrift/ImpalaService.thrift
+++ b/common/thrift/ImpalaService.thrift
@@ -326,6 +326,9 @@ enum TImpalaQueryOptions {
// Overrides the -kudu_read_mode flag to set the consistency level for Kudu scans.
// Possible values are DEFAULT, READ_LATEST, and READ_AT_SNAPSHOT.
KUDU_READ_MODE,
+
+ // Allow reading of erasure coded files.
+ ALLOW_ERASURE_CODED_FILES,
}
// The summary of a DML statement.
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/fe/src/main/java/org/apache/impala/planner/HdfsScanNode.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/planner/HdfsScanNode.java b/fe/src/main/java/org/apache/impala/planner/HdfsScanNode.java
index 7088a7c..d1d7fd8 100644
--- a/fe/src/main/java/org/apache/impala/planner/HdfsScanNode.java
+++ b/fe/src/main/java/org/apache/impala/planner/HdfsScanNode.java
@@ -799,6 +799,12 @@ public class HdfsScanNode extends ScanNode {
totalBytes_ += partitionBytes;
totalFiles_ += fileDescs.size();
for (FileDescriptor fileDesc: fileDescs) {
+ if (!analyzer.getQueryOptions().isAllow_erasure_coded_files() &&
+ fileDesc.getIsEc()) {
+ throw new ImpalaRuntimeException(String.format(
+ "Scanning of HDFS erasure-coded file (%s/%s) is not supported",
+ partition.getLocation(), fileDesc.getFileName()));
+ }
if (!fsHasBlocks) {
Preconditions.checkState(fileDesc.getNumFileBlocks() == 0);
generateScanRangeSpecs(partition, fileDesc, scanRangeBytesLimit);
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/testdata/bin/create-load-data.sh
----------------------------------------------------------------------
diff --git a/testdata/bin/create-load-data.sh b/testdata/bin/create-load-data.sh
index 3d06b0f..bb95f48 100755
--- a/testdata/bin/create-load-data.sh
+++ b/testdata/bin/create-load-data.sh
@@ -142,6 +142,10 @@ function start-impala {
else
START_CLUSTER_ARGS_INT+=("-s 3")
fi
+ if [[ "${ERASURE_CODING}" == true ]]; then
+ START_CLUSTER_ARGS="${START_CLUSTER_ARGS} \
+ --impalad_args=--default_query_options=allow_erasure_coded_files=true"
+ fi
START_CLUSTER_ARGS_INT+=("${START_CLUSTER_ARGS}")
${IMPALA_HOME}/bin/start-impala-cluster.py --log_dir=${IMPALA_DATA_LOADING_LOGS_DIR} \
${START_CLUSTER_ARGS_INT[@]}
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/testdata/workloads/functional-query/queries/QueryTest/hdfs-erasure-coding.test
----------------------------------------------------------------------
diff --git a/testdata/workloads/functional-query/queries/QueryTest/hdfs-erasure-coding.test b/testdata/workloads/functional-query/queries/QueryTest/hdfs-erasure-coding.test
new file mode 100644
index 0000000..0c773b4
--- /dev/null
+++ b/testdata/workloads/functional-query/queries/QueryTest/hdfs-erasure-coding.test
@@ -0,0 +1,15 @@
+====
+---- QUERY
+set allow_erasure_coded_files=false;
+select count(*) from functional.alltypes;
+---- CATCH
+ImpalaRuntimeException: Scanning of HDFS erasure-coded file (hdfs://localhost:20500/test-warehouse/alltypes/year=2009/month=1/090101.txt) is not supported
+====
+---- QUERY
+set allow_erasure_coded_files=true;
+select count(*) from functional.alltypes;
+---- RESULTS
+7300
+---- TYPES
+BIGINT
+====
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/tests/common/custom_cluster_test_suite.py
----------------------------------------------------------------------
diff --git a/tests/common/custom_cluster_test_suite.py b/tests/common/custom_cluster_test_suite.py
index 20037bf..51e3f8f 100644
--- a/tests/common/custom_cluster_test_suite.py
+++ b/tests/common/custom_cluster_test_suite.py
@@ -140,6 +140,9 @@ class CustomClusterTestSuite(ImpalaTestSuite):
if pytest.config.option.test_no_krpc:
cmd.append("--disable_krpc")
+ if os.environ.get("ERASURE_CODING") == "true":
+ cmd.append("--impalad_args=--default_query_options=allow_erasure_coded_files=true")
+
try:
check_call(cmd + options, close_fds=True)
finally:
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/tests/common/skip.py
----------------------------------------------------------------------
diff --git a/tests/common/skip.py b/tests/common/skip.py
index ca49327..e84c75b 100644
--- a/tests/common/skip.py
+++ b/tests/common/skip.py
@@ -86,6 +86,7 @@ class SkipIf:
reason="Kudu is not supported")
not_s3 = pytest.mark.skipif(not IS_S3, reason="S3 Filesystem needed")
not_hdfs = pytest.mark.skipif(not IS_HDFS, reason="HDFS Filesystem needed")
+ not_ec = pytest.mark.skipif(not IS_EC, reason="Erasure Coding needed")
no_secondary_fs = pytest.mark.skipif(not SECONDARY_FILESYSTEM,
reason="Secondary filesystem needed")
not_krpc = pytest.mark.skipif(pytest.config.option.test_no_krpc,
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/tests/query_test/test_observability.py
----------------------------------------------------------------------
diff --git a/tests/query_test/test_observability.py b/tests/query_test/test_observability.py
index 86e78cc..f71a45f 100644
--- a/tests/query_test/test_observability.py
+++ b/tests/query_test/test_observability.py
@@ -15,9 +15,10 @@
# specific language governing permissions and limitations
# under the License.
+from tests.common.impala_cluster import ImpalaCluster
from tests.common.impala_test_suite import ImpalaTestSuite
from tests.common.skip import SkipIfS3, SkipIfADLS, SkipIfIsilon, SkipIfLocal
-from tests.common.impala_cluster import ImpalaCluster
+from tests.util.filesystem_utils import IS_EC
import logging
import pytest
import re
@@ -117,9 +118,12 @@ class TestObservability(ImpalaTestSuite):
profile
# For this query, the planner sets NUM_NODES=1, NUM_SCANNER_THREADS=1,
# RUNTIME_FILTER_MODE=0 and MT_DOP=0
- assert "Query Options (set by configuration and planner): MEM_LIMIT=8589934592," \
- "NUM_NODES=1,NUM_SCANNER_THREADS=1,RUNTIME_FILTER_MODE=0,MT_DOP=0\n" \
- in profile
+ expected_str = ("Query Options (set by configuration and planner): "
+ "MEM_LIMIT=8589934592,NUM_NODES=1,NUM_SCANNER_THREADS=1,"
+ "RUNTIME_FILTER_MODE=0,MT_DOP=0{erasure_coding}\n")
+ expected_str = expected_str.format(
+ erasure_coding=",ALLOW_ERASURE_CODED_FILES=1" if IS_EC else "")
+ assert expected_str in profile
def test_exec_summary(self):
"""Test that the exec summary is populated correctly in every query state"""
http://git-wip-us.apache.org/repos/asf/impala/blob/8060f4d5/tests/query_test/test_scanners.py
----------------------------------------------------------------------
diff --git a/tests/query_test/test_scanners.py b/tests/query_test/test_scanners.py
index 3d71e2d..bd3c286 100644
--- a/tests/query_test/test_scanners.py
+++ b/tests/query_test/test_scanners.py
@@ -33,6 +33,7 @@ from subprocess import check_call
from testdata.common import widetable
from tests.common.impala_test_suite import ImpalaTestSuite, LOG
from tests.common.skip import (
+ SkipIf,
SkipIfS3,
SkipIfADLS,
SkipIfEC,
@@ -1082,3 +1083,11 @@ class TestScannerReservation(ImpalaTestSuite):
def test_scanners(self, vector):
self.run_test_case('QueryTest/scanner-reservation', vector)
+class TestErasureCoding(ImpalaTestSuite):
+ @classmethod
+ def get_workload(cls):
+ return 'functional-query'
+
+ @SkipIf.not_ec
+ def test_erasure_coding(self, vector):
+ self.run_test_case('QueryTest/hdfs-erasure-coding', vector)