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.*");
}
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'");
}
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)]");
}
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");
}
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'");
}
Aggregations