Search in sources :

Example 16 with ViewExpression

use of io.trino.spi.security.ViewExpression in project trino by trinodb.

the class TestRowFilter method testRecursion.

@Test
public void testRecursion() {
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(USER, Optional.of(CATALOG), Optional.of("tiny"), "orderkey IN (SELECT orderkey FROM orders)"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessageMatching(".*\\QRow filter for 'local.tiny.orders' is recursive\\E.*");
    // different reference style to same table
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(USER, Optional.of(CATALOG), Optional.of("tiny"), "orderkey IN (SELECT local.tiny.orderkey FROM orders)"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessageMatching(".*\\QRow filter for 'local.tiny.orders' is recursive\\E.*");
    // mutual recursion
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), RUN_AS_USER, new ViewExpression(RUN_AS_USER, Optional.of(CATALOG), Optional.of("tiny"), "orderkey IN (SELECT orderkey FROM orders)"));
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(RUN_AS_USER, Optional.of(CATALOG), Optional.of("tiny"), "orderkey IN (SELECT orderkey FROM orders)"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessageMatching(".*\\QRow filter for 'local.tiny.orders' is recursive\\E.*");
}
Also used : QualifiedObjectName(io.trino.metadata.QualifiedObjectName) ViewExpression(io.trino.spi.security.ViewExpression) Test(org.junit.jupiter.api.Test)

Example 17 with ViewExpression

use of io.trino.spi.security.ViewExpression in project trino by trinodb.

the class TestRowFilter method testCorrelatedSubquery.

@Test
public void testCorrelatedSubquery() {
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(USER, Optional.of(CATALOG), Optional.of("tiny"), "EXISTS (SELECT 1 FROM nation WHERE nationkey = orderkey)"));
    assertThat(assertions.query("SELECT count(*) FROM orders")).matches("VALUES BIGINT '7'");
}
Also used : QualifiedObjectName(io.trino.metadata.QualifiedObjectName) ViewExpression(io.trino.spi.security.ViewExpression) Test(org.junit.jupiter.api.Test)

Example 18 with ViewExpression

use of io.trino.spi.security.ViewExpression in project trino by trinodb.

the class TestRowFilter method testInvalidFilter.

@Test
public void testInvalidFilter() {
    // parse error
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(RUN_AS_USER, Optional.of(CATALOG), Optional.of("tiny"), "$$$"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessage("line 1:22: Invalid row filter for 'local.tiny.orders': mismatched input '$'. Expecting: <expression>");
    // unknown column
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(RUN_AS_USER, Optional.of(CATALOG), Optional.of("tiny"), "unknown_column"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessage("line 1:22: Invalid row filter for 'local.tiny.orders': Column 'unknown_column' cannot be resolved");
    // invalid type
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(RUN_AS_USER, Optional.of(CATALOG), Optional.of("tiny"), "1"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessage("line 1:22: Expected row filter for 'local.tiny.orders' to be of type BOOLEAN, but was integer");
    // aggregation
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(RUN_AS_USER, Optional.of(CATALOG), Optional.of("tiny"), "count(*) > 0"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessage("line 1:10: Row filter for 'local.tiny.orders' cannot contain aggregations, window functions or grouping operations: [count(*)]");
    // window function
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(RUN_AS_USER, Optional.of(CATALOG), Optional.of("tiny"), "row_number() OVER () > 0"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessage("line 1:22: Row filter for 'local.tiny.orders' cannot contain aggregations, window functions or grouping operations: [row_number() OVER ()]");
    // window function
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(CATALOG, "tiny", "orders"), USER, new ViewExpression(RUN_AS_USER, Optional.of(CATALOG), Optional.of("tiny"), "grouping(orderkey) = 0"));
    assertThatThrownBy(() -> assertions.query("SELECT count(*) FROM orders")).hasMessage("line 1:20: Row filter for 'local.tiny.orders' cannot contain aggregations, window functions or grouping operations: [GROUPING (orderkey)]");
}
Also used : QualifiedObjectName(io.trino.metadata.QualifiedObjectName) ViewExpression(io.trino.spi.security.ViewExpression) Test(org.junit.jupiter.api.Test)

Example 19 with ViewExpression

use of io.trino.spi.security.ViewExpression in project trino by trinodb.

the class TestRowFilter method testInsert.

@Test
public void testInsert() {
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(MOCK_CATALOG, "tiny", "nation"), USER, new ViewExpression(USER, Optional.empty(), Optional.empty(), "nationkey > 100"));
    // Within allowed row filter
    assertions.query("INSERT INTO mock.tiny.nation VALUES (101, 'POLAND', 0, 'No comment')").assertThat().skippingTypesCheck().matches("SELECT BIGINT '1'");
    // Outside allowed row filter
    assertThatThrownBy(() -> assertions.query("INSERT INTO mock.tiny.nation VALUES (26, 'POLAND', 0, 'No comment')")).hasMessage("Access Denied: Cannot insert row that does not match to a row filter");
    assertThatThrownBy(() -> assertions.query("INSERT INTO mock.tiny.nation VALUES " + "(26, 'POLAND', 0, 'No comment')," + "(27, 'HOLLAND', 0, 'A comment')")).hasMessage("Access Denied: Cannot insert row that does not match to a row filter");
    assertThatThrownBy(() -> assertions.query("INSERT INTO mock.tiny.nation VALUES " + "(26, 'POLAND', 0, 'No comment')," + "(27, 'HOLLAND', 0, 'A comment')")).hasMessage("Access Denied: Cannot insert row that does not match to a row filter");
    assertThatThrownBy(() -> assertions.query("INSERT INTO mock.tiny.nation(nationkey) VALUES (null)")).hasMessage("Access Denied: Cannot insert row that does not match to a row filter");
    assertThatThrownBy(() -> assertions.query("INSERT INTO mock.tiny.nation(regionkey) VALUES (0)")).hasMessage("Access Denied: Cannot insert row that does not match to a row filter");
}
Also used : QualifiedObjectName(io.trino.metadata.QualifiedObjectName) ViewExpression(io.trino.spi.security.ViewExpression) Test(org.junit.jupiter.api.Test)

Example 20 with ViewExpression

use of io.trino.spi.security.ViewExpression in project trino by trinodb.

the class TestRowFilter method testRowFilterOnHiddenColumn.

@Test
public void testRowFilterOnHiddenColumn() {
    accessControl.reset();
    accessControl.rowFilter(new QualifiedObjectName(MOCK_CATALOG, "tiny", "nation_with_hidden_column"), USER, new ViewExpression(USER, Optional.empty(), Optional.empty(), "\"$hidden\" < 1"));
    assertions.query("SELECT count(*) FROM mock.tiny.nation_with_hidden_column").assertThat().skippingTypesCheck().matches("VALUES BIGINT '25'");
    // TODO https://github.com/trinodb/trino/issues/10006 - support insert into a table with row filter that is using hidden columns
    assertThatThrownBy(() -> assertions.query("INSERT INTO mock.tiny.nation_with_hidden_column VALUES (101, 'POLAND', 0, 'No comment')")).isInstanceOf(ArrayIndexOutOfBoundsException.class).hasMessage("Index 4 out of bounds for length 4");
    assertThatThrownBy(() -> assertions.query("UPDATE mock.tiny.nation_with_hidden_column SET name = 'POLAND'")).isInstanceOf(TrinoException.class).hasMessageContaining("Updating a table with a row filter is not supported");
    assertions.query("DELETE FROM mock.tiny.nation_with_hidden_column WHERE regionkey < 5").assertThat().skippingTypesCheck().matches("SELECT BIGINT '25'");
}
Also used : TrinoException(io.trino.spi.TrinoException) QualifiedObjectName(io.trino.metadata.QualifiedObjectName) ViewExpression(io.trino.spi.security.ViewExpression) Test(org.junit.jupiter.api.Test)

Aggregations

ViewExpression (io.trino.spi.security.ViewExpression)56 QualifiedObjectName (io.trino.metadata.QualifiedObjectName)48 Test (org.junit.jupiter.api.Test)41 Test (org.testng.annotations.Test)10 SystemAccessControl (io.trino.spi.security.SystemAccessControl)7 ImmutableList (com.google.common.collect.ImmutableList)5 TrinoException (io.trino.spi.TrinoException)5 CatalogSchemaTableName (io.trino.spi.connector.CatalogSchemaTableName)5 SchemaTableName (io.trino.spi.connector.SchemaTableName)4 ImmutableSet (com.google.common.collect.ImmutableSet)3 ImmutableSet.toImmutableSet (com.google.common.collect.ImmutableSet.toImmutableSet)3 AllowAllSystemAccessControl (io.trino.plugin.base.security.AllowAllSystemAccessControl)3 DefaultSystemAccessControl (io.trino.plugin.base.security.DefaultSystemAccessControl)3 ReadOnlySystemAccessControl (io.trino.plugin.base.security.ReadOnlySystemAccessControl)3 Suppliers.memoizeWithExpiration (com.google.common.base.Suppliers.memoizeWithExpiration)2 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)2 Injector (com.google.inject.Injector)2 Bootstrap (io.airlift.bootstrap.Bootstrap)2 ConfigBinder.configBinder (io.airlift.configuration.ConfigBinder.configBinder)2 Logger (io.airlift.log.Logger)2