Skip to main content
Cria uma política de linha, ou seja, um filtro usado para determinar quais linhas um usuário pode ler em uma tabela.
Políticas de linha só fazem sentido para usuários com acesso de somente leitura. Se um usuário puder modificar uma tabela ou copiar partições entre tabelas, isso contorna as restrições das políticas de linha.
Sintaxe:
ParserRowPolicyNames aceita três formas de agrupamento (não um produto cartesiano completo):
  1. Vários nomes, um destino — pol1, pol2 ON table1 cria cada nome listado nessa única tabela (ou db.*).
  2. Um nome, vários destinos — pol1 ON table1, table2 cria o mesmo nome curto em cada destino listado.
  3. Pares mistos — p1 ON t1, p2 ON t2 cria cada nome apenas no destino ao qual está associado.
Uma lista com vários nomes não pode ser combinada com uma lista ON de várias tabelas em um grupo: p1, p2 ON t1, t2 é rejeitada. Após um grupo com vários nomes, você também não pode acrescentar outro grupo name ON target separado por vírgulas na mesma instrução. O ON CLUSTER opcional se aplica a toda a instrução (um nome de cluster). O ClickHouse não aceita um ON CLUSTER diferente para cada nome de política agrupado em uma única criação — execute instruções CREATE ROW POLICY separadas quando as políticas precisarem ser criadas em clusters diferentes. CREATE ROW POLICY exige o privilégio CREATE ROW POLICY na tabela em que a política é criada. OR REPLACE descarta uma política existente de mesmo nome, incluindo os roles aos quais ela se aplica, e por isso exige também o privilégio DROP ROW POLICY nessa tabela. O privilégio DROP ROW POLICY é exigido independentemente de a política já existir ou não, de modo que a instrução não pode ser usada para descobrir quais políticas existem.

Vários nomes e tabelas

Válido:
Inválido:

Cláusula USING

Define uma condição de filtro para uma tabela. O usuário só pode ver as linhas para as quais a condição é verdadeira (ou seja, retorna um valor diferente de zero). Isso equivale a adicionar uma condição WHERE extra a cada consulta que o usuário executa na tabela. Por exemplo, a política a seguir restringe analyst_role às linhas da UE:
Com essa política, SELECT * FROM db.orders retorna as mesmas linhas que SELECT * FROM db.orders WHERE region = 'EU' retornaria.

Cláusula TO

Na seção TO, você pode informar uma lista de usuários e roles para os quais esta política deve se aplicar. Por exemplo, CREATE ROW POLICY ... TO accountant, john@localhost. A palavra-chave ALL significa todos os usuários do ClickHouse, incluindo o usuário atual. A palavra-chave ALL EXCEPT permite excluir alguns usuários da lista de todos os usuários, por exemplo, CREATE ROW POLICY ... TO ALL EXCEPT accountant, john@localhost As roles indicadas na seção TO, incluindo aquelas após ALL EXCEPT, são comparadas com as roles habilitadas do usuário atual (system.enabled_roles), e não com todas as roles concedidas ao usuário, de modo que SET ROLE pode alterar quais políticas se aplicam.

Cláusula AS

É possível ter mais de uma política habilitada na mesma tabela para o mesmo usuário ao mesmo tempo. Portanto, precisamos de uma forma de combinar as condições de várias políticas. Por padrão, as políticas são combinadas usando o operador booleano OR. Por exemplo, as seguintes políticas:
permitem ao usuário peter ver linhas com b=1 ou c=2. A cláusula AS especifica como as políticas devem ser combinadas com outras políticas. As políticas podem ser permissivas ou restritivas. Por padrão, as políticas são permissivas, o que significa que são combinadas usando o operador booleano OR. Como alternativa, uma política pode ser definida como restritiva. As políticas restritivas são combinadas usando o operador booleano AND. Aqui está a fórmula geral:
Se nenhuma condição permissiva se aplicar, a primeira condição não tem efeito e apenas as políticas restritivas decidem, porque access_control_improvements.users_without_row_policies_can_read_rows está habilitado por padrão. Portanto, um usuário ao qual nenhuma condição se aplica vê todas as linhas, e access_control_improvements.throw_on_unmatched_row_policies, desabilitado por padrão, gera uma exceção nesse caso, quando a tabela possui condições e nenhuma delas se aplica. Por exemplo, as seguintes políticas:
permite que o usuário peter veja linhas apenas se b=1 E c=2. As políticas de banco de dados são combinadas com as políticas da tabela. Por exemplo, as seguintes políticas:
permitir ao usuário peter ver as linhas da table1 somente se b=1 AND c=2, embora qualquer outra tabela em mydb tenha apenas a política b=1 aplicada ao usuário.

Tabelas que leem dados de outras tabelas

Uma ROW POLICY filtra as linhas no momento em que os dados são efetivamente lidos. Uma tabela Alias retorna as linhas da tabela à qual aponta como se fossem suas. Assim, as ROW POLICIES da tabela à qual o alias aponta também se aplicam às leituras feitas por meio dele, combinadas com as políticas do próprio alias por um AND lógico. Uma tabela Merge aplica as políticas das tabelas das quais lê os dados. Há uma exceção: quando uma tabela correspondente lê dados remotamente, como uma tabela Distributed, o servidor remoto processa a consulta antes da aplicação da política, pois esta é executada após a leitura dessa tabela, e não no momento da leitura. A consulta pode falhar se agregar dados sem selecionar as colunas usadas pela política ou retornar menos linhas do que a política permite se o servidor remoto aplicar ORDER BY ... LIMIT a linhas que a política teria ocultado. Em vez disso, defina a política nas tabelas locais subjacentes de cada servidor remoto. Isso não vale para todas as tabelas que leem dados de outra tabela. Uma tabela Buffer e uma visão materializada que leem por meio de sua tabela de destino não herdam as ROW POLICIES dessa tabela: a política é definida com base no schema da tabela de destino e, no caso de uma visão com SQL SECURITY DEFINER, é avaliada para um usuário diferente daquele que executa a leitura. Nesses casos, defina a política na tabela que os usuários de fato consultam.

Tabelas Distributed e com dados remotos

Uma política de linha filtra as linhas no local em que os dados da tabela são efetivamente lidos. Uma tabela que delega a leitura a servidores remotos, como uma tabela Distributed ou um wrapper dela (por exemplo, uma visão materializada com destino Distributed), apenas envia o texto da consulta aos servidores remotos e não consegue aplicar o filtro da política à leitura remota. Para evitar que o filtro seja silenciosamente descartado, as consultas a essa tabela feitas por usuários aos quais a política se aplica são rejeitadas com o erro ILLEGAL_PREWHERE. Em vez disso, defina a política nas tabelas locais subjacentes de cada servidor remoto; ela será aplicada quando a consulta enviada as ler:
Isso funciona quando a consulta é enviada como texto, que é o padrão. Com serialize_query_plan = 1, o iniciador envia um plano de leitura já criado, e um servidor remoto que executa esse plano não aplica suas próprias políticas de linha. Portanto, a leitura de uma tabela Distributed sobre local_table retorna linhas não filtradas. Mantenha serialize_query_plan = 0 para usuários cujas políticas de linha devam ser aplicadas. Consulte a issue #112891.

Tabelas Join

Uma tabela Join é uma tabela hash previamente preparada que um JOIN ou joinGet lê exatamente como está, de modo que suas linhas não podem ser filtradas nesse momento. Uma política aplicada a essa tabela, incluindo uma política ON db.* válida para todo o banco de dados, filtra um SELECT simples na tabela; porém, enquanto ela estiver em vigor, as consultas JOIN e joinGet nessa tabela falham com ACCESS_DENIED.

Cláusula ON CLUSTER

Permite criar políticas de linha em um cluster. Consulte DDL distribuído. Essa também é uma maneira prática de criar a política nas tabelas locais de cada servidor do cluster.

Exemplos

CREATE ROW POLICY filter1 ON mydb.mytable USING a<1000 TO accountant, john@localhost CREATE ROW POLICY filter2 ON mydb.mytable USING a<1000 AND b=5 TO ALL EXCEPT mira CREATE ROW POLICY filter3 ON mydb.mytable USING 1 TO admin CREATE ROW POLICY filter4 ON mydb.* USING 1 TO admin