| /* |
| |
| Derby - Class org.apache.derbyTesting.functionTests.tests.lang.GeneratedColumnsPermsTest |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to you under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| |
| package org.apache.derbyTesting.functionTests.tests.lang; |
| |
| import java.sql.Connection; |
| import junit.framework.Test; |
| import org.apache.derbyTesting.junit.BaseTestSuite; |
| import org.apache.derbyTesting.junit.CleanDatabaseTestSetup; |
| import org.apache.derbyTesting.junit.DatabasePropertyTestSetup; |
| import org.apache.derbyTesting.junit.TestConfiguration; |
| |
| /** |
| * <p> |
| * Test permissions on generated columns. See DERBY-481. |
| * </p> |
| */ |
| public class GeneratedColumnsPermsTest extends GeneratedColumnsHelper |
| { |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // CONSTANTS |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| private static final String TEST_DBO = "TEST_DBO"; |
| private static final String JANET = "JANET"; |
| private static final String[] LEGAL_USERS = { TEST_DBO, JANET }; |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // STATE |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // CONSTRUCTOR |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| |
| /** |
| * Create a new instance. |
| */ |
| |
| public GeneratedColumnsPermsTest(String name) |
| { |
| super(name); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // JUnit BEHAVIOR |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| |
| /** |
| * Construct top level suite in this JUnit test |
| */ |
| public static Test suite() |
| { |
| BaseTestSuite suite = (BaseTestSuite)TestConfiguration.embeddedSuite( |
| GeneratedColumnsPermsTest.class); |
| |
| Test cleanTest = new CleanDatabaseTestSetup( suite ); |
| Test authenticatedTest = DatabasePropertyTestSetup.builtinAuthentication |
| ( cleanTest, LEGAL_USERS, "generatedColumnsPermissions" ); |
| Test authorizedTest = TestConfiguration.sqlAuthorizationDecorator( authenticatedTest ); |
| |
| return authorizedTest; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // TESTS |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * <p> |
| * Test that you need select/insert/update/delete privileges on a generated column and not just on |
| * the columns it references. |
| * </p> |
| */ |
| public void test_001_basicPermissions() |
| throws Exception |
| { |
| Connection dboConnection = openUserConnection( TEST_DBO ); |
| Connection janetConnection = openUserConnection( JANET ); |
| |
| // |
| // Verify correct behavior when have granted only SELECT and UPDATE on the referenced column. |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "create table t_bp_1( a int, b int generated always as ( -a ) )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "insert into t_bp_1( a ) values ( 1 )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant select ( a ) on t_bp_1 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant update ( a ) on t_bp_1 to public" |
| ); |
| |
| expectExecutionError |
| ( |
| janetConnection, |
| LACK_TABLE_PRIV, |
| "insert into test_dbo.t_bp_1( a ) values ( 100 )" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "update test_dbo.t_bp_1 set a = a+ 1" |
| ); |
| expectExecutionError |
| ( |
| janetConnection, |
| LACK_TABLE_PRIV, |
| "delete from test_dbo.t_bp_1 where a = 2" |
| ); |
| expectExecutionError |
| ( |
| janetConnection, |
| LACK_COLUMN_PRIV, |
| "select * from test_dbo.t_bp_1 order by a" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select a from test_dbo.t_bp_1 order by a", |
| new String[][] |
| { |
| { "2", }, |
| }, |
| false |
| ); |
| |
| // |
| // Verify correct behavior when we also grant SELECT on the generated column. |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "grant select ( b ) on t_bp_1 to public" |
| ); |
| expectExecutionError |
| ( |
| janetConnection, |
| LACK_TABLE_PRIV, |
| "insert into test_dbo.t_bp_1( a ) values ( 100 )" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "update test_dbo.t_bp_1 set a = a+ 1" |
| ); |
| expectExecutionError |
| ( |
| janetConnection, |
| LACK_TABLE_PRIV, |
| "delete from test_dbo.t_bp_1 where a = 2" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_bp_1 order by a", |
| new String[][] |
| { |
| { "3", "-3", }, |
| }, |
| false |
| ); |
| |
| // |
| // Verify correct behavior when we also grant UPDATE on the generated column. |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "grant update ( b ) on t_bp_1 to public" |
| ); |
| expectExecutionError |
| ( |
| janetConnection, |
| LACK_TABLE_PRIV, |
| "insert into test_dbo.t_bp_1( a ) values ( 100 )" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "update test_dbo.t_bp_1 set a = a+ 1" |
| ); |
| expectExecutionError |
| ( |
| janetConnection, |
| LACK_TABLE_PRIV, |
| "delete from test_dbo.t_bp_1 where a = 2" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_bp_1 order by a", |
| new String[][] |
| { |
| { "4", "-4", }, |
| }, |
| false |
| ); |
| |
| // |
| // Verify correct behavior when we also grant INSERT on the table. |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "grant insert on t_bp_1 to public" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "insert into test_dbo.t_bp_1( a ) values ( 100 )" |
| ); |
| expectExecutionError |
| ( |
| janetConnection, |
| LACK_TABLE_PRIV, |
| "delete from test_dbo.t_bp_1 where a = 2" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_bp_1 order by a", |
| new String[][] |
| { |
| { "4", "-4", }, |
| { "100", "-100", }, |
| }, |
| false |
| ); |
| |
| // |
| // Verify correct behavior when we also grant DELETE on the table. |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "grant delete on t_bp_1 to public" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "delete from test_dbo.t_bp_1 where a = 4" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_bp_1 order by a", |
| new String[][] |
| { |
| { "100", "-100", }, |
| }, |
| false |
| ); |
| } |
| |
| /** |
| * <p> |
| * Test that you DON'T need execute privilege to run functions mentioned in |
| * generation clauses. That privilege is needed by the user who declared |
| * the generation clause. |
| * </p> |
| */ |
| public void test_002_functionPermissions() |
| throws Exception |
| { |
| Connection dboConnection = openUserConnection( TEST_DBO ); |
| Connection janetConnection = openUserConnection( JANET ); |
| |
| // |
| // Verify correct behavior when EXECUTE privilege is not granted. |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "create function f_fp_minus\n" + |
| "(\n" + |
| " a int\n" + |
| ")\n" + |
| "returns int\n" + |
| "language java\n" + |
| "deterministic\n" + |
| "parameter style java\n" + |
| "no sql\n" + |
| "external name 'org.apache.derbyTesting.functionTests.tests.lang.GeneratedColumnsTest.minus'\n" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "create table t_fp_1( a int, b int generated always as ( test_dbo.f_fp_minus( a ) ) )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant update on t_fp_1 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant insert on t_fp_1 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant select on t_fp_1 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "insert into test_dbo.t_fp_1( a ) values ( 100 )" |
| ); |
| |
| goodStatement |
| ( |
| janetConnection, |
| "create function f_fp_minus\n" + |
| "(\n" + |
| " a int\n" + |
| ")\n" + |
| "returns int\n" + |
| "language java\n" + |
| "deterministic\n" + |
| "parameter style java\n" + |
| "no sql\n" + |
| "external name 'java.lang.Math.abs'\n" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "update test_dbo.t_fp_1 set a = a + 1" |
| ); |
| |
| goodStatement |
| ( |
| janetConnection, |
| "insert into test_dbo.t_fp_1( a ) values ( 200 )" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_fp_1 order by a", |
| new String[][] |
| { |
| { "101", "-101", }, |
| { "200", "-200", }, |
| }, |
| false |
| ); |
| |
| // |
| // Verify correct behavior when EXECUTE privilege is granted. |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "grant execute on function f_fp_minus to public" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "update test_dbo.t_fp_1 set a = a + 1" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "insert into test_dbo.t_fp_1( a ) values ( 200 )" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_fp_1 order by a", |
| new String[][] |
| { |
| { "102", "-102", }, |
| { "200", "-200", }, |
| { "201", "-201", }, |
| }, |
| false |
| ); |
| } |
| |
| /** |
| * <p> |
| * Test ddl that can only be issued when authorization is turned on. |
| * </p> |
| */ |
| public void test_003_ddl() |
| throws Exception |
| { |
| Connection conn = getConnection(); |
| |
| // |
| // Verify that current_role is not allowed in generation clauses. |
| // |
| expectCompilationError |
| ( |
| UNSTABLE_RESULTS, |
| "create table t_ddl_1( a int, b varchar( 128 ) generated always as ( current_role ) )" |
| ); |
| } |
| |
| /** |
| * <p> |
| * Test that unqualified function references in generation clauses resolve |
| * to the current schema in effect when the generated column was added. |
| * See DERBY-3945. |
| * </p> |
| */ |
| public void test_004_functionSchema() |
| throws Exception |
| { |
| Connection dboConnection = openUserConnection( TEST_DBO ); |
| Connection janetConnection = openUserConnection( JANET ); |
| |
| // |
| // Schema. |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "create function f_fsch_1\n" + |
| "(\n" + |
| " a int\n" + |
| ")\n" + |
| "returns int\n" + |
| "language java\n" + |
| "deterministic\n" + |
| "parameter style java\n" + |
| "no sql\n" + |
| "external name 'org.apache.derbyTesting.functionTests.tests.lang.GeneratedColumnsTest.minus'\n" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "create table t_fsch_1( a int, b generated always as ( f_fsch_1( a ) ) )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "create table t_fsch_2( a int )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "alter table t_fsch_2 add column b generated always as ( f_fsch_1( a ) )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant execute on function f_fsch_1 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant select on t_fsch_1 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant insert on t_fsch_1 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant update on t_fsch_1 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant select on t_fsch_2 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant insert on t_fsch_2 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant update on t_fsch_2 to public" |
| ); |
| |
| goodStatement |
| ( |
| janetConnection, |
| "create function f_fsch_1\n" + |
| "(\n" + |
| " a int\n" + |
| ")\n" + |
| "returns int\n" + |
| "language java\n" + |
| "deterministic\n" + |
| "parameter style java\n" + |
| "no sql\n" + |
| "external name 'java.lang.Math.abs'\n" |
| ); |
| |
| // |
| // Populate |
| // |
| goodStatement |
| ( |
| dboConnection, |
| "insert into test_dbo.t_fsch_1( a ) values ( 1 )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "insert into test_dbo.t_fsch_2( a ) values ( 2 )" |
| ); |
| |
| // |
| // Verify insert by other user |
| // |
| goodStatement |
| ( |
| janetConnection, |
| "insert into test_dbo.t_fsch_1( a ) values ( 1 )" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_fsch_1 order by a", |
| new String[][] |
| { |
| { "1", "-1", }, |
| { "1", "-1", }, |
| }, |
| false |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "insert into test_dbo.t_fsch_2( a ) values ( 2 )" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_fsch_2 order by a", |
| new String[][] |
| { |
| { "2", "-2", }, |
| { "2", "-2", }, |
| }, |
| false |
| ); |
| |
| // |
| // Verify update by other user |
| // |
| goodStatement |
| ( |
| janetConnection, |
| "update test_dbo.t_fsch_1 set a = 100 + a" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_fsch_1 order by a", |
| new String[][] |
| { |
| { "101", "-101", }, |
| { "101", "-101", }, |
| }, |
| false |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "update test_dbo.t_fsch_2 set a = 100 + a" |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.t_fsch_2 order by a", |
| new String[][] |
| { |
| { "102", "-102", }, |
| { "102", "-102", }, |
| }, |
| false |
| ); |
| |
| } |
| |
| /** |
| * <p> |
| * Test that unqualified function references in check constraints resolve |
| * to the current schema in effect when the constraint was declared. |
| * See DERBY-3944, which is related to the bug above, DERBY-3945. |
| * </p> |
| */ |
| public void test_005_functionSchema() |
| throws Exception |
| { |
| Connection dboConnection = openUserConnection( TEST_DBO ); |
| Connection janetConnection = openUserConnection( JANET ); |
| |
| goodStatement |
| ( |
| dboConnection, |
| "create function f_3944\n" + |
| "(\n" + |
| " a int\n" + |
| ")\n" + |
| "returns int\n" + |
| "language java\n" + |
| "deterministic\n" + |
| "parameter style java\n" + |
| "no sql\n" + |
| "external name 'org.apache.derbyTesting.functionTests.tests.lang.GeneratedColumnsTest.minus'\n" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "create table t_3944( a int, constraint t_3944_check check ( f_3944( a ) < 0 ) )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant insert on t_3944 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant execute on function f_3944 to public" |
| ); |
| |
| expectExecutionError |
| ( |
| janetConnection, |
| CONSTRAINT_VIOLATION, |
| "insert into test_dbo.t_3944( a ) values ( -100 )" |
| ); |
| goodStatement |
| ( |
| janetConnection, |
| "insert into test_dbo.t_3944( a ) values ( 200 )" |
| ); |
| assertResults |
| ( |
| dboConnection, |
| "select * from t_3944 order by a", |
| new String[][] |
| { |
| { "200", }, |
| }, |
| false |
| ); |
| } |
| |
| /** |
| * <p> |
| * Test that unqualified function references in views resolve |
| * to the view's schema. |
| * See DERBY-3953, which is related to the bugs above, DERBY-3944 and DERBY-3945. |
| * </p> |
| */ |
| public void test_006_functionSchema() |
| throws Exception |
| { |
| Connection dboConnection = openUserConnection( TEST_DBO ); |
| Connection janetConnection = openUserConnection( JANET ); |
| |
| goodStatement |
| ( |
| dboConnection, |
| "create function f_3953\n" + |
| "(\n" + |
| " a int\n" + |
| ")\n" + |
| "returns int\n" + |
| "language java\n" + |
| "deterministic\n" + |
| "parameter style java\n" + |
| "no sql\n" + |
| "external name 'org.apache.derbyTesting.functionTests.tests.lang.GeneratedColumnsTest.minus'\n" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "create view v_3953( a, b ) as values ( f_3953( 1 ), f_3953( 2 ) )" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant select on v_3953 to public" |
| ); |
| goodStatement |
| ( |
| dboConnection, |
| "grant execute on function f_3953 to public" |
| ); |
| |
| goodStatement |
| ( |
| janetConnection, |
| "create function f_3953\n" + |
| "(\n" + |
| " a int\n" + |
| ")\n" + |
| "returns int\n" + |
| "language java\n" + |
| "deterministic\n" + |
| "parameter style java\n" + |
| "no sql\n" + |
| "external name 'java.lang.Math.abs'\n" |
| ); |
| |
| assertResults |
| ( |
| janetConnection, |
| "values ( f_3953( 1 ), f_3953( 2 ) )", |
| new String[][] |
| { |
| { "1", "2" }, |
| }, |
| false |
| ); |
| assertResults |
| ( |
| janetConnection, |
| "select * from test_dbo.v_3953", |
| new String[][] |
| { |
| { "-1", "-2" }, |
| }, |
| false |
| ); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // MINIONS |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| } |