Appliquer manuellement des filtres de lignes et des masques de colonnes
Cette page fournit des conseils et des exemples pour l'utilisation des filtres de lignes, des masques de colonnes et des tables de correspondance afin de filtrer les données sensibles dans vos tables. Ces fonctionnalités nécessitent Unity Catalog.
Si vous recherchez une approche centralisée, basée sur des tags, pour le filtrage et le masquage, consultez le contrôle d'accès basé sur les attributs dans Unity Catalog. ABAC vous permet de gérer les politiques à l'aide de tags gouvernés et de les appliquer de manière cohérente sur de nombreuses tables.
Avant de commencer
Pour ajouter des filtres de ligne et des masques de colonne aux tables, vous devez disposer de :
- Un Workspace qui est activé pour Unity Catalog.
- Une UDF SQL qui est enregistrée dans Unity Catalog. Pour utiliser la logique Python ou Scala, créez d'abord une UDF Python ou Scala, puis créez une UDF SQL qui l'appelle. Le SQL UDF est ce que vous appliquez comme filtre de ligne ou masque de colonne. Pour un exemple, consultez Masque de colonne avec UDF Python. Pour les meilleures pratiques et les limitations des UDF, voir Filtres de lignes et masques de colonne.
Vous devez également respecter les exigences suivantes :
- Pour attribuer une fonction qui ajoute des filtres de ligne ou des masques de colonne à une table, vous devez disposer du privilège
EXECUTEsur la fonction, deUSE SCHEMAsur le schéma et deUSE CATALOGsur le catalogue parent. - Si vous ajoutez des filtres ou des masques lorsque vous créez une nouvelle table, vous devez disposer du privilège
CREATE TABLEsur le schéma. - Si vous ajoutez ou supprimez des filtres ou des masques sur une table existante , vous devez être le propriétaire de la table ou disposer des privilèges
MANAGEetSELECTsur la table. - Si la même instruction modifie également le schéma de table (par exemple, l'ajout d'une nouvelle colonne avec un masque), vous avez également besoin du privilège
MODIFYsur la table.
Pour accéder à une table qui contient des filtres de ligne ou des masques de colonne, votre ressource de compute doit répondre à l'une de ces exigences :
- Un SQL Warehouse.
- Mode d'accès standard (anciennement mode d'accès partagé) sur Databricks Runtime 12.2 LTS ou version ultérieure.
- Mode d'accès dédié (anciennement mode d'accès utilisateur unique) sur Databricks Runtime 15.4 LTS ou version ultérieure.
Vous ne pouvez pas lire les filtres de ligne ou les masques de colonne à l’aide de compute dédié sur Databricks Runtime 15,3 ou version antérieure.
Pour tirer parti du filtrage des données fourni dans Databricks Runtime 15.4 LTS et versions ultérieures, vous devez également vérifier que votre Workspace est activé pour le compute serverless, car la fonctionnalité de filtrage des données qui prend en charge les filtres de ligne et les masques de colonne s'exécute sur le compute serverless. Des frais peuvent vous être facturés pour les Ressources de compute serverless lorsque vous utilisez un compute configuré en mode d'accès dédié pour lire des tables qui utilisent des filtres de ligne ou des masques de colonne. Les Opérations d'écriture sur ces tables ne sont prises en charge qu'avec Databricks Runtime 16.3 et versions ultérieures, et doivent utiliser des modèles pris en charge tels que MERGE INTO. Consultez le contrôle d'accès granulaire sur un compute dédié.
Les filtres de lignes et les masques de colonnes sont conservés lors du remplacement d'une table.
Si vous exécutez REPLACE TABLE, tout filtre de ligne existant est conservé, quels que soient les changements de schéma. Les masques de colonne sont également conservés si la nouvelle table inclut des colonnes portant les mêmes noms que celles qui avaient des masques dans la table d'origine. Dans les deux cas, les politiques sont préservées même si elles ne sont pas explicitement redéfinies. Cela permet d'éviter la perte accidentelle des politiques d'accès aux données.
Toutefois, si une stratégie conservée référence une colonne qui a été supprimée ou modifiée, les requêtes suivantes risquent d'échouer. Pour résoudre ce problème, mettez à jour ou supprimez la politique à l'aide de ALTER TABLE.
Appliquer un filtre de ligne
Pour créer un filtre de ligne, vous écrivez une fonction (UDF) pour définir la politique de filtre, puis l'appliquez à une table. Chaque table peut avoir un seul filtre de ligne. Un filtre de ligne accepte zéro ou plusieurs paramètres d'entrée, chaque paramètre d'entrée se liant à une colonne de la table correspondante.
Les types de paramètres UDF doivent correspondre aux types de données des colonnes de la table qui leur sont transmises. Si le type d’une colonne diffère de celui du type de parameter d’une UDF, comme une colonne STRING passée à un parameter INT, la valeur de la colonne est implicitement convertie. Lorsque le mode ANSI est désactivé, les valeurs qui ne peuvent pas être castées sont silencieusement converties en NULL, ce qui peut entraîner la production de résultats incorrects par le filtre sans générer d’erreur. Pour en savoir plus, consultez le comportement en cas de non-concordance des types de données.
Vous pouvez appliquer un filtre de ligne à l'aide de l'Explorateur de catalogues ou de commandes SQL. Les instructions de l'Explorateur de catalogues supposent que vous avez déjà créé une fonction et l'avez enregistrée dans Unity Catalog. Les instructions SQL comprennent des exemples de création d’une fonction de filtre de ligne et de son application à une table.
Si vous utilisez les Lakeflow pipelines, vous pouvez utiliser l'API Python des Lakeflow pipelines pour créer des tables de streaming ou des vues matérialisées qui utilisent des filtres de lignes et des masques de colonnes. Consultez Publier des tables avec des filtres de ligne et des masques de colonne.
- Catalog Explorer
- SQL
- Dans votre workspace Databricks, cliquez sur
Catalogue .
- Parcourez ou recherchez la table que vous souhaitez filtrer.
- Sous l'onglet Vue d'ensemble , sous Filtre de ligne , cliquez sur Ajouter un filtre .
- Dans la boîte de dialogue Ajouter un filtre de ligne , sélectionnez le catalogue et le schéma qui contiennent la fonction de filtre, puis sélectionnez la fonction.
- Dans la boîte de dialogue développée, consultez la définition de la fonction et sélectionnez les colonnes de la table qui correspondent aux colonnes incluses dans l'instruction de fonction.
- Cliquez sur **Ajouter**.
Pour supprimer le filtre de la table, cliquez sur fx Filtre de lignes , puis sur Supprimer .
Pour créer un filtre de ligne, puis l'ajouter à une table existante, utilisez CREATE FUNCTION et appliquez la fonction à l'aide de ALTER TABLE. Vous pouvez également appliquer une fonction lorsque vous créez une table à l'aide de CREATE TABLE.
-
Créer le filtre de ligne :
SQLCREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {filter clause whose output must be a boolean}; -
Appliquez le filtre de ligne à une table en utilisant un nom de colonne :
SQLALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<column_name>, ...);
Autres exemples de syntaxe :
-
Appliquer le filtre de ligne à une table en utilisant un littéral constant qui correspond à un parameter de fonction :
SQLALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<constant_literal>, ...); -
Supprimer un filtre de ligne d'une table :
SQLALTER TABLE <table_name> DROP ROW FILTER; -
Modifier un filtre de ligne :
SQLCREATE OR REPLACE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {filter clause whose output must be a boolean}; -
Supprimez un filtre de ligne :
SQLALTER TABLE <table_name> DROP ROW FILTER;
DROP FUNCTION <function_name>;
Vous devez exécuter la commande ALTER TABLE ... DROP ROW FILTER avant de supprimer la fonction. Si vous ne le faites pas, la table sera dans un état inaccessible.
Si la table devient inaccessible de cette manière, modifiez la table et supprimez la référence de filtre de ligne orpheline en utilisant ALTER TABLE <table_name> DROP ROW FILTER;.
Voir aussi clauseROW FILTER.
Exemples de filtre de ligne
Cet exemple crée une fonction définie par l’utilisateur SQL qui s’applique aux membres du groupe admin dans la région US.
Lorsque cette fonction d'échantillonnage est appliquée à la table sales, les membres du groupe admin peuvent accéder à tous les enregistrements de la table. Si la fonction est appelée par un non-administrateur, la condition RETURN_IF échoue et l'expression region='US' est évaluée, filtrant la table pour n'afficher que les enregistrements de la région US.
CREATE FUNCTION us_filter(region STRING)
RETURN IF(IS_ACCOUNT_GROUP_MEMBER('admin'), true, region='US');
Appliquez la fonction à une table comme filtre de ligne. Les queries suivantes de la table sales renvoient ensuite un sous-ensemble de lignes.
CREATE TABLE sales (region STRING, id INT);
ALTER TABLE sales SET ROW FILTER us_filter ON (region);
Désactiver le filtre de ligne. Les futures queries des utilisateurs à partir de la table sales renvoient alors toutes les lignes de la table.
ALTER TABLE sales DROP ROW FILTER;
Créez une table avec la fonction appliquée comme filtre de lignes dans le cadre de l'instruction CREATE TABLE. Les futures queries de la table sales renvoient ensuite un sous-ensemble de lignes.
CREATE TABLE sales (region STRING, id INT)
WITH ROW FILTER us_filter ON (region);
Appliquer un masque de colonne
Pour appliquer un masque de colonne, créez une fonction (UDF) et appliquez-la à une colonne de table.
Les types de paramètres d'UDF doivent correspondre aux types de données des colonnes qui leur sont transmises. Si un type de colonne diffère du type de paramètre d'UDF, la valeur de la colonne est implicitement castée. Lorsque le mode ANSI est désactivé, les valeurs qui ne peuvent pas être converties sont silencieusement converties en NULL, ce qui peut entraîner des résultats incorrects du masque sans lever d’erreur. Pour en savoir plus, consultez Comportement en cas d’incompatibilité de type de données.
Vous pouvez appliquer un masque de colonne à l’aide de l’Explorateur de catalogues ou de commandes SQL. Les instructions de l'Explorateur de catalogues supposent que vous avez déjà créé une fonction et l'avez enregistrée dans Unity Catalog. Les instructions SQL incluent des exemples de création d'une fonction de masquage de colonne et de son application à une colonne de table.
Si vous utilisez les Lakeflow pipelines, vous pouvez utiliser l'API Python des Lakeflow pipelines pour créer des tables de streaming ou des vues matérialisées qui utilisent des filtres de lignes et des masques de colonnes. Consultez Publier des tables avec des filtres de ligne et des masques de colonne.
- Catalog Explorer
- SQL
- Dans votre workspace Databricks, cliquez sur
Catalogue .
- Parcourez ou recherchez la table.
- Sous l'onglet **Vue d'ensemble**, recherchez la ligne à laquelle vous souhaitez appliquer le masque de colonne et cliquez sur l'icône de modification
**Masque**.
- Dans la boîte de dialogue Ajouter un masque de colonne , sélectionnez le catalogue et le schéma qui contiennent la fonction de filtre, puis sélectionnez la fonction.
- Dans la boîte de dialogue développée, visualisez la définition de fonction. Si la fonction inclut des paramètres en plus de la colonne masquée, sélectionnez les colonnes de la table dans lesquelles vous souhaitez caster ces paramètres de fonction supplémentaires.
- Cliquez sur **Ajouter**.
Pour supprimer le masque de colonne de la table, cliquez sur fx Column mask dans la ligne du tableau, puis sur Supprimer .
Pour créer un masque de colonne et l'ajouter à une colonne de table existante, utilisez CREATE FUNCTION et appliquez la fonction de masquage à l'aide de ALTER TABLE. Vous pouvez également appliquer une fonction lorsque vous créez une table à l'aide de CREATE TABLE.
Vous utilisez SET MASK pour appliquer la fonction de masquage. Dans la clause MASK, vous pouvez utiliser n'importe laquelle des fonctions d'exécution intégrées de Databricks ou appeler d'autres fonctions définies par l'utilisateur. Les cas d'utilisation courants incluent la vérification de l'identité de l'utilisateur appelant qui exécute la fonction à l'aide de session_user() ou l'obtention des groupes dont il est membre à l'aide de is_account_group_member(). Pour plus de détails, consultez la clause de colonne mask et les fonctions intégrées.
-
Créez un masque de colonne :
SQLCREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {expression with the same type as the first parameter}; -
Appliquer le masque de colonne à une colonne dans une table existante :
SQLALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS <additional_columns>;
Autres exemples de syntaxe :
-
Appliquez le masque de colonne à une colonne d’une table existante à l’aide d’un littéral constant qui correspond à un paramètre de fonction :
SQLALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS (<constant_name>, ...); -
Supprimer un masque de colonne d'une colonne dans une table :
SQLALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK; -
Modifier un masque de colonne :
SQLCREATE OR REPLACE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {expression with the same type as the first parameter}; -
Supprimer un masque de colonne :
SQLALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
DROP FUNCTION <function_name>;
Vous devez exécuter la commande ALTER TABLE avant de supprimer la fonction, sinon la table sera dans un état inaccessible.
Si la table devient inaccessible de cette manière, modifiez la table et supprimez la référence de masque orpheline à l'aide de ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;.
Exemples de masque de colonne
Dans cet exemple, vous créez une fonction définie par l'utilisateur qui masque la colonne ssn afin que seuls les utilisateurs membres du groupe HumanResourceDept puissent afficher les valeurs de cette colonne.
CREATE FUNCTION ssn_mask(ssn STRING)
RETURN CASE WHEN is_account_group_member('HumanResourceDept') THEN ssn ELSE '***-**-****' END;
Appliquez la nouvelle fonction à une table en tant que masque de colonne. Vous pouvez ajouter le masque de colonne lors de la création de la table ou ultérieurement.
--Create the `users` table and apply the column mask in a single step:
CREATE TABLE users (
name STRING,
ssn STRING MASK ssn_mask);
--Create the `users` table and apply the column mask after:
CREATE TABLE users
(name STRING, ssn STRING);
ALTER TABLE users ALTER COLUMN ssn SET MASK ssn_mask;
Les requêtes sur cette table renvoient désormais les valeurs de colonne ssn masquées lorsque l'utilisateur qui effectue la requête n'est pas membre du groupe HumanResourceDept :
SELECT * FROM users;
James ***-**-****
Pour désactiver le masque de colonne afin que les requêtes renvoient les valeurs d'origine dans la colonne ssn :
ALTER TABLE users ALTER COLUMN ssn DROP MASK;
Masque de colonne avec UDF Python
Pour utiliser la logique Python ou Scala dans un masque de colonne, vous devez créer une UDF Python ou Scala, puis l'encapsuler dans une UDF SQL. La fonction wrapper SQL est ce que vous appliquez comme masque de colonne.
Cet exemple crée une UDF Python pour masquer les adresses e-mail, puis l'encapsule dans une UDF SQL :
-- Step 1: Create the Python UDF with masking logic
CREATE OR REPLACE FUNCTION email_mask_python(email STRING)
RETURNS STRING
LANGUAGE PYTHON
AS $$
import re
return re.sub(r'^[^@]+', lambda m: '*' * len(m.group()), email)
$$;
-- Step 2: Create a SQL wrapper function that calls the Python UDF
CREATE OR REPLACE FUNCTION email_mask_sql(email STRING)
RETURN email_mask_python(email);
Ensuite, appliquez l'encapsuleur SQL en tant que masque de colonne à votre table :
-- Create the `contacts` table and apply the SQL wrapper as the column mask
CREATE TABLE contacts (
name STRING,
email STRING MASK email_mask_sql);
Vous devez appliquer la fonction d'encapsulage SQL (email_mask_sql) comme masque de colonne, et non l'UDF Python directement. Si vous tentez d'utiliser l'UDF Python (email_mask_python) directement comme masque de colonne, vous recevrez une erreur [ROUTINE_NOT_FOUND].
Masque de colonne avec colonnes supplémentaires (USING COLUMNS)
Utilisez la clause USING COLUMNS lorsqu'une fonction de masquage doit faire référence à des parameters statiques ou à d'autres colonnes de la table. USING COLUMNS permet le masquage conditionnel basé sur des valeurs au-delà de la colonne masquée.
La clause USING COLUMNS fournit des arguments supplémentaires à la fonction de masquage :
- Le 1er parameter de la fonction de masquage correspond toujours à la colonne masquée elle-même.
- Fournissez des parameters supplémentaires en utilisant
USING COLUMNSavec des valeurs statiques ou des noms de colonne de la même table.
L'exemple suivant crée un masque de colonne qui censure les adresses différemment en fonction de la valeur d'une autre colonne (country). La fonction prend un paramètre supplémentaire qui spécifie le groupe. Seuls les membres de la paire pays-groupe résultante peuvent consulter les adresses de ce pays.
-- Create a masking function that accepts two parameters:
-- 1. address (the masked column)
-- 2. country (an additional column used for conditional logic)
-- 3. group_suffix (group the user belongs to)
CREATE FUNCTION mask_address_by_country(address STRING, country STRING, group_suffix STRING DEFAULT '_address_viewers')
RETURN IF(
is_account_group_member(country || group_suffix),
address,
'REDACTED'
);
-- Create a table and apply the mask using USING COLUMNS to pass the country column
CREATE TABLE customers (
name STRING,
address STRING MASK mask_address_by_country USING COLUMNS (country, '_address_viewers'),
country STRING
);
-- Insert sample data
INSERT INTO customers VALUES
('Alice', '123 Main St, New York', 'US'),
('Bob', '456 High St, London', 'UK'),
('Charlie', '789 Rue de Rivoli, Paris', 'FR');
Les résultats de la query dépendent de l'appartenance au groupe. Si l'utilisateur est membre de US_address_viewers, il peut voir les adresses américaines, mais pas les autres :
-- As a member of 'US_address_viewers' group
SELECT * FROM customers;
Alice | 123 Main St, New York | US
Bob | REDACTED | UK
Charlie | REDACTED | FR
Vous pouvez également appliquer le masque à une table existante :
-- Apply mask to existing column
ALTER TABLE customers
ALTER COLUMN address
SET MASK mask_address_by_country USING COLUMNS (country, '_address_viewers');
Masque de colonne pour les champs imbriqués STRUCT
Vous pouvez appliquer des masques de colonnes aux colonnes STRUCT imbriquées pour masquer sélectivement des champs spécifiques au sein de la structure tout en préservant d'autres champs. Ceci est utile lorsqu'un STRUCT contient des données publiques et sensibles, et que vous souhaitez appliquer différents contrôles d'accès à des champs individuels basés sur les attributs de l'utilisateur.
Pour masquer les champs imbriqués, créez une fonction de masquage qui reconstruit la STRUCT à l’aide de named_struct(), en remplaçant les valeurs de champs sensibles de manière conditionnelle tout en gardant les autres champs intacts.
Cet exemple crée une fonction de masquage pour une colonne STRUCT qui contient à la fois un champ value public et un champ secret sensible. La fonction de masquage utilise is_account_group_member() pour déterminer s'il faut afficher toutes les données ou masquer le champ sensible.
-- Create a masking function for nested STRUCT fields
CREATE FUNCTION mask_nested_field(data STRUCT<value: STRING, secret: STRING>)
RETURN IF(
is_account_group_member('privileged_users'),
data,
named_struct('value', data.value, 'secret', 'REDACTED')
);
Appliquez la fonction de masquage lors de la création d'une table avec une colonne STRUCT :
-- Create a table with a masked STRUCT column
CREATE TABLE sensitive_data (
id INT,
nested_column STRUCT<value: STRING, secret: STRING>
MASK mask_nested_field
);
-- Insert sample data
INSERT INTO sensitive_data VALUES
(1, named_struct('value', 'public_info', 'secret', 'private_info')),
(2, named_struct('value', 'general_data', 'secret', 'confidential_data'));
Query la table pour tester le masquage. Les résultats varient en fonction de l'appartenance au groupe. Si l'utilisateur n'est pas membre de privileged_users, le secret est censuré :
-- As a non-member of 'privileged_users'
SELECT * FROM sensitive_data;
1 {"value":"public_info","secret":"REDACTED"}
2 {"value":"general_data","secret":"REDACTED"}
Vous pouvez également appliquer le masque à une table existante :
-- Apply mask to existing STRUCT column
ALTER TABLE sensitive_data
ALTER COLUMN nested_column
SET MASK mask_nested_field;
La fonction de masquage doit retourner une valeur avec le même type STRUCT que la colonne masquée. Cela permet d'éviter les incoérences de schémas déroutantes qui peuvent survenir pendant les opérations INSERT, MERGE et UPDATE. Dans cet exemple, la fonction retourne STRUCT<value: STRING, secret: STRING> pour correspondre au type de colonne.
Utilisez des tables de mappage pour créer une liste de contrôle d'accès
Pour obtenir une sécurité au niveau des lignes, envisagez de définir une table de mappage (ou une liste de contrôle d'accès). Une table de mappage complète code quelles lignes de données dans la table d'origine sont accessibles à certains utilisateurs ou groupes. Les tables de mappage sont utiles car elles offrent une intégration simple avec vos tables de faits via des jointures directes.
Cette méthodologie répond à de nombreux cas d'utilisation qui incluent des exigences personnalisées. Exemples :
- Imposer des restrictions en fonction de l'utilisateur connecté tout en tenant compte de règles différentes pour des groupes d'utilisateurs spécifiques.
- Création de hiérarchies complexes, telles que des structures organisationnelles, qui nécessitent des ensembles de règles variés.
- Réplication de modèles de sécurité complexes à partir de systèmes source externes.
En adoptant des tables de mappage, vous pouvez réaliser ces scénarios complexes et assurer des implémentations robustes de sécurité au niveau des lignes et des colonnes.
Exemples de table de mappage
Utilisez une table de mappage pour vérifier si l'utilisateur actuel est dans une liste :
USE CATALOG main;
Créer une nouvelle table de mappage :
DROP TABLE IF EXISTS valid_users;
CREATE TABLE valid_users(username string);
INSERT INTO valid_users
VALUES
('fred@databricks.com'),
('barney@databricks.com');
Créez un nouveau filtre :
Tous les filtres s’exécutent avec les droits du définisseur, à l’exception des fonctions qui vérifient le contexte utilisateur (par exemple, les fonctions SESSION_USER et IS_ACCOUNT_GROUP_MEMBER), qui s’exécutent en tant qu’invocateur.
Dans cet exemple, la fonction vérifie si l’utilisateur actuel se trouve dans la table valid_users. Si l'utilisateur est trouvé, la fonction renvoie true.
DROP FUNCTION IF EXISTS row_filter;
CREATE FUNCTION row_filter()
RETURN EXISTS(
SELECT 1 FROM valid_users v
WHERE v.username = SESSION_USER()
);
L'exemple ci-dessous applique le filtre de lignes lors de la création de la table. Vous pouvez également ajouter le filtre plus tard à l'aide d'une instruction ALTER TABLE. Lorsque vous appliquez le filtre à des colonnes non spécifiées, utilisez la syntaxe ON (). Pour une colonne spécifique, utilisez ON (column);. Pour plus de détails, consultez Paramètres.
DROP TABLE IF EXISTS data_table;
CREATE TABLE data_table
(x INT, y INT, z INT)
WITH ROW FILTER row_filter ON ();
INSERT INTO data_table VALUES
(1, 2, 3),
(4, 5, 6),
(7, 8, 9);
Sélectionnez les données du tableau. Cela ne devrait renvoyer des données que si l'utilisateur se trouve dans le tableau valid_users.
SELECT * FROM data_table;
Créez une table de mappage comprenant les comptes qui devraient toujours avoir accès pour afficher toutes les lignes de la table, quelles que soient les valeurs de colonne :
CREATE TABLE valid_accounts(account string);
INSERT INTO valid_accounts
VALUES
('admin'),
('cstaff');
Maintenant, créez une UDF SQL qui renvoie true si les valeurs de toutes les colonnes de la ligne sont inférieures à cinq ou si l'utilisateur appelant est membre de la table de mappage ci-dessus.
CREATE FUNCTION row_filter_small_values (x INT, y INT, z INT)
RETURN (x < 5 AND y < 5 AND z < 5)
OR EXISTS(
SELECT 1 FROM valid_accounts v
WHERE IS_ACCOUNT_GROUP_MEMBER(v.account));
Enfin, appliquez l'UDF SQL à la table comme filtre de ligne :
ALTER TABLE data_table SET ROW FILTER row_filter_small_values ON (x, y, z);