![[New Feature] Snowflake's Multi-value Tags Have Reached GA, So I Tried Everything from Managing Multiple Values to Merging Tag Propagation](https://images.ctfassets.net/ct0aopd36mqt/wp-refcat-img-3610e3c1ff5961bdb7b464e17f8bf06d/90b168b240005ead852ec1d474bb74fb/snowflake-logo-1200x630-1.png?w=3840&fm=webp)
[New Feature] Snowflake's Multi-value Tags Have Reached GA, So I Tried Everything from Managing Multiple Values to Merging Tag Propagation
This page has been translated by machine translation. View original
This is Kawabata.
On August 25, 2026, Multi-value tags became generally available (GA).
Multiple values can be assigned to a single tag. You can express cases where multiple classifications apply simultaneously, such as "this table is built from data from both the sales system and the accounting system" or "this column contains both personal information and payment information."
This article covers everything from adding and removing values, to the SYSTEM$TAG_VALUE_CONTAINS verification function, tag propagation merging (ON_CONFLICT = MERGE), and the relationship with masking policies.
【Update】
I was selected as a finalist in the "RISING COMMUNITY LEADER OF THE YEAR" category, APJ slot, at the Snowflake Community Awards.
Please see the link below for details.
Overview of Multi-value Tags
Until now, tags could only hold one value per object. Workarounds such as splitting tags or concatenating values were needed to express multiple classifications.
Multi-value tags are tags specified with MULTI_VALUE = TRUE, allowing multiple values to be assigned to the same object or column.
The differences from single-value tags are as follows.
| Item | Single-value tag | Multi-value tag |
|---|---|---|
| Number of values | 1 value per object (or column) per tag | Multiple values for the same tag (default maximum of 10 values per object) |
| Tag definition | Created without specifying MULTI_VALUE |
Specified with MULTI_VALUE = TRUE (existing tags can also be converted) |
| Value assignment | SET TAG / UNSET TAG |
ADD VALUE / DROP VALUE (SET TAG replaces all values) |
| Value verification | SYSTEM$GET_TAG |
SYSTEM$TAG_VALUE_CONTAINS |
| Propagation conflict resolution | Only strategies that select a single winner | ON_CONFLICT = MERGE allows merging of multiple values |
ON_CONFLICT = MERGE is a conflict resolution strategy exclusive to multi-value tags. When tag propagation delivers different values from multiple upstream sources, all values can be passed downstream instead of being narrowed down to one.
Prerequisites
- Tag creation and assignment itself is available in all editions
- Tag propagation (
PROPAGATE/ON_CONFLICT) and tag-based masking policies covered in this article require Enterprise Edition or higher - Tag creation:
CREATE TAGprivilege on the schema - Tag assignment:
APPLY TAGprivilege on the account, orAPPLYprivilege on the target tag and ownership of the target object
Verification was performed on August 27, 2026, on an account in the AWS Tokyo region using ACCOUNTADMIN.
Preparation
Create a DB for verification and tables for basic operations (CUSTOMERS), column operations (ORDERS), and tag propagation (SALES_DATA / SUPPORT_DATA).
Preparation
USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE DATABASE MVT_TEST_DB;
CREATE SCHEMA MVT_TEST_DB.GOVERNANCE;
CREATE SCHEMA MVT_TEST_DB.SALES;
-- For table-level verification
CREATE OR REPLACE TABLE MVT_TEST_DB.SALES.CUSTOMERS AS
SELECT
SEQ4() + 1 AS CUSTOMER_ID,
'user' || TO_VARCHAR(SEQ4() + 1) || '@example.com' AS EMAIL,
'090-0000-' || LPAD(TO_VARCHAR(SEQ4() + 1), 4, '0') AS PHONE
FROM TABLE(GENERATOR(ROWCOUNT => 10));
-- For column-level and masking policy verification
CREATE OR REPLACE TABLE MVT_TEST_DB.SALES.ORDERS AS
SELECT
SEQ4() + 1 AS ORDER_ID,
'user' || TO_VARCHAR(SEQ4() + 1) || '@example.com' AS CUSTOMER_EMAIL,
UNIFORM(1000, 100000, RANDOM()) AS AMOUNT
FROM TABLE(GENERATOR(ROWCOUNT => 10));
-- For tag propagation verification
CREATE OR REPLACE TABLE MVT_TEST_DB.SALES.SALES_DATA AS
SELECT SEQ4() + 1 AS ID, 'sales_note_' || TO_VARCHAR(SEQ4() + 1) AS SALES_NOTE
FROM TABLE(GENERATOR(ROWCOUNT => 10));
CREATE OR REPLACE TABLE MVT_TEST_DB.SALES.SUPPORT_DATA AS
SELECT SEQ4() + 1 AS ID, 'support_note_' || TO_VARCHAR(SEQ4() + 1) AS SUPPORT_NOTE
FROM TABLE(GENERATOR(ROWCOUNT => 10));
What I Tried
Creating a Tag with MULTI_VALUE = TRUE
Simply add MULTI_VALUE = TRUE to CREATE TAG.
CREATE OR REPLACE TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG MULTI_VALUE = TRUE
COMMENT = 'Multi-value classification tag';
SHOW TAGS IN SCHEMA MVT_TEST_DB.GOVERNANCE;
The output of SHOW TAGS has an added multi_value column, which displays true. The result of GET_DDL also includes MULTI_VALUE = TRUE.

Adding and Removing Values with ADD VALUE / DROP VALUE
Use ADD VALUE / DROP VALUE instead of SET TAG for value operations. The first value can also be added with ADD VALUE.
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS
ADD VALUE 'PII' FOR TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG;
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS
ADD VALUE 'FINANCIAL' FOR TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG;
When checked with TAG_REFERENCES, one row is returned per value.
SELECT TAG_NAME, TAG_VALUE
FROM TABLE(MVT_TEST_DB.INFORMATION_SCHEMA.TAG_REFERENCES('MVT_TEST_DB.SALES.CUSTOMERS', 'TABLE'));

I also checked detailed behavior, and none of the following resulted in an error.
ADD VALUEwith a duplicate value does not increase the number of valuesDROP VALUEfor a non-existent value does nothingDROP VALUEon all values removes the tag assignment itself
Column-level operations are performed with MODIFY COLUMN. Multiple columns can be operated on simultaneously.
ALTER TABLE MVT_TEST_DB.SALES.ORDERS MODIFY COLUMN CUSTOMER_EMAIL
ADD VALUE 'email_pii' FOR TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG;
ALTER TABLE MVT_TEST_DB.SALES.ORDERS MODIFY COLUMN CUSTOMER_EMAIL
ADD VALUE 'contact_info' FOR TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG;
-- Operating on multiple columns in a single statement
ALTER TABLE MVT_TEST_DB.SALES.ORDERS MODIFY
COLUMN ORDER_ID ADD VALUE 'id_field' FOR TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG,
COLUMN AMOUNT ADD VALUE 'financial_data' FOR TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG;

Checking for Values with SYSTEM$TAG_VALUE_CONTAINS
Use the new system function SYSTEM$TAG_VALUE_CONTAINS to check multi-value tag values. It returns TRUE if the specified value is assigned, FALSE if not.
It can also be used on single-value tags, and the key difference from SYSTEM$GET_TAG is that it does not error even when multiple values are set.
-- An assigned value
SELECT SYSTEM$TAG_VALUE_CONTAINS(
'MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG', 'MVT_TEST_DB.SALES.CUSTOMERS', 'TABLE', 'PII');
-- An unassigned value
SELECT SYSTEM$TAG_VALUE_CONTAINS(
'MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG', 'MVT_TEST_DB.SALES.CUSTOMERS', 'TABLE', 'HIPAA');
-- Value comparison is case-sensitive
SELECT SYSTEM$TAG_VALUE_CONTAINS(
'MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG', 'MVT_TEST_DB.SALES.CUSTOMERS', 'TABLE', 'pii');
-- Column format is <table>.<column>, domain is COLUMN
SELECT SYSTEM$TAG_VALUE_CONTAINS(
'MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG', 'MVT_TEST_DB.SALES.ORDERS.CUSTOMER_EMAIL', 'COLUMN', 'email_pii');
-- No error for objects without a tag assigned
SELECT SYSTEM$TAG_VALUE_CONTAINS(
'MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG', 'MVT_TEST_DB.SALES.SALES_DATA', 'TABLE', 'PII');

SYSTEM$GET_TAG Errors When Multiple Values Are Assigned
Using the conventional SYSTEM$GET_TAG on a tag with multiple values results in an error.
-- CLASSIFICATION_TAG is in a state with 2 values ('PII', 'FINANCIAL')
SELECT SYSTEM$GET_TAG('MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG', 'MVT_TEST_DB.SALES.CUSTOMERS', 'TABLE');

On the other hand, SYSTEM$GET_TAG correctly returned the value even for a multi-value tag when only one value was assigned.
Whether an error occurs is determined not by the tag definition but by "the number of values currently assigned."
If you have existing operational scripts that depend on SYSTEM$GET_TAG, they will break the moment a second value is added. It is safer to switch all references to multi-valued tags to SYSTEM$TAG_VALUE_CONTAINS.
Converting Existing Tags Is Easy, but Reverting Is Not Possible
Attempting ADD VALUE on a single-value tag results in an error. To convert an existing tag to multi-value, use ALTER TAG.
CREATE OR REPLACE TAG MVT_TEST_DB.GOVERNANCE.SENSITIVITY_TAG;
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS
SET TAG MVT_TEST_DB.GOVERNANCE.SENSITIVITY_TAG = 'HIGH';
-- SENSITIVITY_TAG was created as a single-value tag with value 'HIGH' set
ALTER TAG MVT_TEST_DB.GOVERNANCE.SENSITIVITY_TAG SET MULTI_VALUE = TRUE;
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS
ADD VALUE 'MEDIUM' FOR TAG MVT_TEST_DB.GOVERNANCE.SENSITIVITY_TAG;

After conversion, the existing value 'HIGH' was retained, and adding 'MEDIUM' resulted in 2 values.
Converting in the reverse direction results in an error.
ALTER TAG MVT_TEST_DB.GOVERNANCE.SENSITIVITY_TAG SET MULTI_VALUE = FALSE;

Explicitly specifying CREATE TAG ... MULTI_VALUE = FALSE also resulted in the same error. Creating a single-value tag by "omitting MULTI_VALUE" is the only option, and once converted to multi-value, it cannot be reverted.
SET TAG Replaces All Values
The conventional SET TAG syntax can be used on multi-value tags, but it replaces all values rather than appending.
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS
ADD VALUE 'FINANCIAL' FOR TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG;
-- Executed from a state with 2 values: 'FINANCIAL' and 'PII'
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS
SET TAG MVT_TEST_DB.GOVERNANCE.CLASSIFICATION_TAG = 'GDPR';

After execution, the value was replaced with only 'GDPR'.
If you accidentally use SET TAG when you intend to add values, your previous settings will be lost.
ON_CONFLICT = MERGE: A View Receives and Merges Values from Multiple Sources
Combining with tag propagation. ON_CONFLICT = MERGE is exclusive to multi-value tags; specifying it on a single-value tag results in an error.
CREATE OR REPLACE TAG MVT_TEST_DB.GOVERNANCE.DATA_SOURCE_TAG
MULTI_VALUE = TRUE
PROPAGATE = ON_DEPENDENCY_AND_DATA_MOVEMENT
ON_CONFLICT = MERGE;
-- Set different values on two source tables
ALTER TABLE MVT_TEST_DB.SALES.SALES_DATA
SET TAG MVT_TEST_DB.GOVERNANCE.DATA_SOURCE_TAG = 'sales_system';
ALTER TABLE MVT_TEST_DB.SALES.SUPPORT_DATA
SET TAG MVT_TEST_DB.GOVERNANCE.DATA_SOURCE_TAG = 'support_system';
-- Create a view that JOINs both tables
CREATE OR REPLACE VIEW MVT_TEST_DB.SALES.V_COMBINED AS
SELECT s.ID, s.SALES_NOTE, t.SUPPORT_NOTE
FROM MVT_TEST_DB.SALES.SALES_DATA s
JOIN MVT_TEST_DB.SALES.SUPPORT_DATA t ON s.ID = t.ID;
SELECT
SYSTEM$TAG_VALUE_CONTAINS('MVT_TEST_DB.GOVERNANCE.DATA_SOURCE_TAG',
'MVT_TEST_DB.SALES.V_COMBINED', 'TABLE', 'sales_system') AS FROM_SALES, -- True
SYSTEM$TAG_VALUE_CONTAINS('MVT_TEST_DB.GOVERNANCE.DATA_SOURCE_TAG',
'MVT_TEST_DB.SALES.V_COMBINED', 'TABLE', 'support_system') AS FROM_SUPPORT; -- True

When checked immediately after view creation, both source values were TRUE.
With single-value tag propagation, conflicts are resolved to one value, but with MERGE, the information that "this view originates from both sales and support" can be retained without loss.
TAG_REFERENCES has an APPLY_METHOD column, and values attached through propagation are displayed as PROPAGATED. This can be distinguished from manual assignment (MANUAL).
SELECT TAG_NAME, TAG_VALUE, LEVEL, APPLY_METHOD
FROM TABLE(MVT_TEST_DB.INFORMATION_SCHEMA.TAG_REFERENCES('MVT_TEST_DB.SALES.V_COMBINED', 'TABLE'));

Error When Exceeding 10 Values
The upper limit on values is 10 per object (default). The 11th ADD VALUE resulted in an upper limit error.
-- Executed after 10 values V01 through V10 have already been added
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS ADD VALUE 'V11' FOR TAG MVT_TEST_DB.GOVERNANCE.LIMIT_TAG;

Masking Policy: A Policy Referencing Tag Values Causes Entire Queries to Fail on the Second Value
SYSTEM$GET_TAG_ON_CURRENT_COLUMN, which branches masking behavior based on tag values, does not support multiple values. I verified what actually happens.
CREATE OR REPLACE TAG MVT_TEST_DB.GOVERNANCE.MASK_TEST_TAG MULTI_VALUE = TRUE;
CREATE OR REPLACE MASKING POLICY MVT_TEST_DB.GOVERNANCE.EMAIL_MASK AS (VAL VARCHAR) RETURNS VARCHAR ->
CASE WHEN SYSTEM$GET_TAG_ON_CURRENT_COLUMN('MVT_TEST_DB.GOVERNANCE.MASK_TEST_TAG') = 'PUBLIC'
THEN VAL
ELSE '*** MASKED ***'
END;
ALTER TABLE MVT_TEST_DB.SALES.ORDERS MODIFY COLUMN CUSTOMER_EMAIL
SET MASKING POLICY MVT_TEST_DB.GOVERNANCE.EMAIL_MASK;
-- With only 1 value ('PUBLIC'), it evaluates correctly and returns the raw value
ALTER TABLE MVT_TEST_DB.SALES.ORDERS MODIFY COLUMN CUSTOMER_EMAIL
ADD VALUE 'PUBLIC' FOR TAG MVT_TEST_DB.GOVERNANCE.MASK_TEST_TAG;
SELECT CUSTOMER_EMAIL FROM MVT_TEST_DB.SALES.ORDERS LIMIT 3; -- Success

-- Setting 2 values causes the SELECT itself to fail
ALTER TABLE MVT_TEST_DB.SALES.ORDERS MODIFY COLUMN CUSTOMER_EMAIL
ADD VALUE 'PII' FOR TAG MVT_TEST_DB.GOVERNANCE.MASK_TEST_TAG;
SELECT CUSTOMER_EMAIL FROM MVT_TEST_DB.SALES.ORDERS LIMIT 3; -- Error

Note: The masking result does not just change — the entire query referencing the target column results in a runtime error. Adding a second value to a tag referenced in a policy condition stops the queries of all users accessing that column. As stated in the official documentation, keep tags used in policy conditions separate and single-valued.
Can Be Used Together with ALLOWED_VALUES
Combining multi-value tags with ALLOWED_VALUES is not explicitly documented, but it worked.
CREATE OR REPLACE TAG MVT_TEST_DB.GOVERNANCE.AV_TAG
ALLOWED_VALUES 'PII', 'FINANCIAL', 'GDPR'
MULTI_VALUE = TRUE;
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS ADD VALUE 'PII' FOR TAG MVT_TEST_DB.GOVERNANCE.AV_TAG; -- Success
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS ADD VALUE 'GDPR' FOR TAG MVT_TEST_DB.GOVERNANCE.AV_TAG; -- Success
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS ADD VALUE 'NOT_ALLOWED' FOR TAG MVT_TEST_DB.GOVERNANCE.AV_TAG; -- Error


The ALLOWED_VALUES constraint also applies to ADD VALUE, rejecting values that are not permitted. This allows you to fix the classification vocabulary while still permitting multiple values.
Note that writing MULTI_VALUE = TRUE before ALLOWED_VALUES results in a syntax error. The official documentation also states that "ALLOWED_VALUES must be specified before other parameters."
On the other hand, combining with ON_CONFLICT = MERGE used in tag propagation described below was rejected with an error in this verification environment. Since it can be specified syntactically in CREATE TAG, the behavior may change.
Use Case: Auditing Multiple Regulatory Targets Together
As a final check of the functionality, I tried using it for compliance management.
With single-value tags, the number of tags increases with the number of regulations.
With multi-value tags, everything can be consolidated into a single COMPLIANCE_TAG, and when combined with MERGE propagation, downstream processing results are also automatically included in the audit targets.
As a scenario, the following three are classified as regulatory targets.
The key point is that a single object can simultaneously fall under multiple regulations.
- Customer table (CUSTOMERS): Contains personal information such as email addresses and phone numbers, so it is subject to the Act on the Protection of Personal Information (APPI) and GDPR
- Payment table (PAYMENTS): Contains card numbers, so it is subject to PCI DSS. It also contains customer information, so it is subject to APPI as well
- Order table (ORDERS): Only the email address column is subject to APPI and GDPR at the column level
The overall structure is as follows. Only the source side needs to be tagged manually; downstream views are automatically assigned tags through propagation.
-- Regulatory classification tag (ALLOWED_VALUES not used as it errors when combined with MERGE)
CREATE OR REPLACE TAG MVT_TEST_DB.GOVERNANCE.COMPLIANCE_TAG
MULTI_VALUE = TRUE
PROPAGATE = ON_DEPENDENCY_AND_DATA_MOVEMENT
ON_CONFLICT = MERGE;
-- Add payment table
CREATE OR REPLACE TABLE MVT_TEST_DB.SALES.PAYMENTS AS
SELECT
SEQ4() + 1 AS PAYMENT_ID,
'4111-1111-1111-' || LPAD(TO_VARCHAR(SEQ4() + 1), 4, '0') AS CARD_NUMBER,
UNIFORM(1000, 100000, RANDOM()) AS AMOUNT
FROM TABLE(GENERATOR(ROWCOUNT => 10));
-- Assign the applicable regulations to each table/column
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS ADD VALUE 'APPI' FOR TAG MVT_TEST_DB.GOVERNANCE.COMPLIANCE_TAG;
ALTER TABLE MVT_TEST_DB.SALES.CUSTOMERS ADD VALUE 'GDPR' FOR TAG MVT_TEST_DB.GOVERNANCE.COMPLIANCE_TAG;
ALTER TABLE MVT_TEST_DB.SALES.PAYMENTS ADD VALUE 'PCI_DSS' FOR TAG MVT_TEST_DB.GOVERNANCE.COMPLIANCE_TAG;
ALTER TABLE MVT_TEST_DB.SALES.PAYMENTS ADD VALUE 'APPI' FOR TAG MVT_TEST_DB.GOVERNANCE.COMPLIANCE_TAG;
ALTER TABLE MVT_TEST_DB.SALES.ORDERS MODIFY COLUMN CUSTOMER_EMAIL
ADD VALUE 'APPI' FOR TAG MVT_TEST_DB.GOVERNANCE.COMPLIANCE_TAG;
ALTER TABLE MVT_TEST_DB.SALES.ORDERS MODIFY COLUMN CUSTOMER_EMAIL
ADD VALUE 'GDPR' FOR TAG MVT_TEST_DB.GOVERNANCE.COMPLIANCE_TAG;
Create a downstream view combining customers and payments, and check the tag status.
CREATE OR REPLACE VIEW MVT_TEST_DB.SALES.V_CUSTOMER_PAYMENTS AS
SELECT c.CUSTOMER_ID, c.EMAIL, p.PAYMENT_ID, p.AMOUNT
FROM MVT_TEST_DB.SALES.CUSTOMERS c
JOIN MVT_TEST_DB.SALES.PAYMENTS p ON c.CUSTOMER_ID = p.PAYMENT_ID;
SELECT TAG_NAME, TAG_VALUE, APPLY_METHOD
FROM TABLE(MVT_TEST_DB.INFORMATION_SCHEMA.TAG_REFERENCES('MVT_TEST_DB.SALES.V_CUSTOMER_PAYMENTS', 'TABLE'))
WHERE TAG_NAME = 'COMPLIANCE_TAG'
ORDER BY TAG_VALUE;

The view combining customers (APPI, GDPR) and payments (PCI_DSS, APPI) became subject to all three regulations without any additional manual classification of the downstream. This is information that would have been narrowed down to just one during single-value tag propagation conflicts.
Use the SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES view for account-wide audits (with up to 2 hours of delay until reflected). Multiple values are returned one row per value, including those from propagated views.
SELECT OBJECT_NAME, COLUMN_NAME, DOMAIN, TAG_VALUE
FROM SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES
WHERE TAG_NAME = 'COMPLIANCE_TAG' AND OBJECT_DELETED IS NULL
ORDER BY OBJECT_NAME, TAG_VALUE;

Use WHERE TAG_VALUE = 'GDPR' for a per-regulation list, and GROUP BY TAG_VALUE for a summary by regulation.
SELECT TAG_VALUE AS REGULATION, COUNT(*) AS TARGET_COUNT
FROM SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES
WHERE TAG_NAME = 'COMPLIANCE_TAG' AND OBJECT_DELETED IS NULL
GROUP BY TAG_VALUE
ORDER BY TAG_VALUE;

For checking individual objects, INFORMATION_SCHEMA.TAG_REFERENCES and SYSTEM$TAG_VALUE_CONTAINS, which we have used throughout, are available without any delay. The pattern is to use ACCOUNT_USAGE for regular audit reports, and system functions for pinpoint checks in audit scripts.
Limitations and Notes
Based on verification results as of August 27, 2026, and the official documentation, here are the points to be careful about when introducing this feature.
Limitations and Notes
- Once a tag is set to
MULTI_VALUE = TRUE, it cannot be reverted to a single-value tag. - The upper limit on values is 10 per object (default). The 11th value results in an error.
SYSTEM$GET_TAG/SYSTEM$GET_TAG_ON_CURRENT_TABLE/SYSTEM$GET_TAG_ON_CURRENT_COLUMNerror with multiple values. Note that they work while only one value is assigned, so adding a second value will break existing code.SET TAGreplaces all values, not appends.UNSET TAGandDROP VALUEon all values both remove the tag assignment.ADD VALUEwith a duplicate value andDROP VALUEfor a non-existent value do not result in errors.ON_CONFLICT = MERGEis exclusive to multi-value tags. Specifying it on a single-value tag results in an error.- Combining with
ALLOWED_VALUESis possible and the constraint also applies toADD VALUE. However, combining withON_CONFLICT = MERGEresulted in an error (actual measurement in this verification environment; not documented). - Value comparison in
SYSTEM$TAG_VALUE_CONTAINSis case-sensitive.
Closing
I found it convenient to be able to express cases where multiple classifications apply simultaneously with a single tag, and when combined with ON_CONFLICT = MERGE, data lineage can be passed downstream without loss.
On the other hand, care is needed regarding compatibility with SYSTEM$GET_TAG-based functions and policy conditions, and it is safer to keep tags used for policies separate and single-valued.
I hope this article is helpful to someone!
