Create Simple Validation Rules
This how-to demonstrates how to create simple predicate-based validation rules to enforce naming conventions and structural requirements. These rules are for illustrative purposes only and do not necessarily reflect hard technical requirements of either Metric Views or the Semantic Bridge.
The four rule helpers
There is a helper method for each type of Metric View object:
MakeValidationRuleForView- rules for the root View objectMakeValidationRuleForJoin- rules for Join objectsMakeValidationRuleForDimension- rules for Dimension objectsMakeValidationRuleForMeasure- rules for Measure objects
Each helper takes four parameters:
- name: unique identifier for the rule
- category: grouping for related rules
- message: error message when the rule is violated
- isInvalid: a function returning
trueif the object is invalid
Rule for View
Check that the Metric View version is the expected value:
var versionRule = SemanticBridge.MetricView.MakeValidationRuleForView(
"version_check",
"structure",
"Metric View version must be 0.1 or 1.1",
(view) => view.Version != "0.1" && view.Version != "1.1"
);
Rule for Metric View Join
Check that Metric View join sources use fully qualified table names (contain a dot):
var joinSourceRule = SemanticBridge.MetricView.MakeValidationRuleForJoin(
"qualified_source",
"structure",
"Join source must be a fully qualified table name (e.g., `catalog.schema.table`)",
(join) => !join.Source.Contains('.')
);
Rule for Metric View Dimension
Check that Metric View dimension names do not contain underscores:
var dimensionNameRule = SemanticBridge.MetricView.MakeValidationRuleForDimension(
"no_underscores",
"naming",
"Dimension names should use spaces, not underscores",
(dim) => dim.Name.Contains('_')
);
Rule for Metric View Measure
Check that Metric View measure expressions do not contain SELECT (to avoid accidental subqueries):
var measureExprRule = SemanticBridge.MetricView.MakeValidationRuleForMeasure(
"no_select_subquery",
"structure",
"Measure expressions should not contain SELECT subqueries",
(measure) => measure.Expr.ToUpper().Contains("SELECT")
);
Complete example
This Metric View has violations for each of the rules defined above:
// Create a Metric View with violations for each rule
SemanticBridge.MetricView.Deserialize("""
version: 0.2
source: sales.fact.orders
joins:
# joinSourceRule violation - not fully qualified
- name: customer
source: customer_table
on: source.customer_id = customer.customer_id
dimensions:
# dimensionNameRule violations - contains underscores
- name: product_name
expr: source.product_name
- name: order_date
expr: source.order_date
# This one is fine
- name: Category
expr: source.category
measures:
# measureExprRule violation - contains SELECT subquery
- name: complex_calc
expr: (SELECT MAX(price) FROM products)
# This one is fine
- name: total_revenue
expr: SUM(source.revenue)
""");
var versionRule = SemanticBridge.MetricView.MakeValidationRuleForView(
"version_check",
"structure",
"Metric View version must be 0.1 or 1.1",
(view) => view.Version != "0.1" && view.Version != "1.1"
);
var joinSourceRule = SemanticBridge.MetricView.MakeValidationRuleForJoin(
"qualified_source",
"structure",
"Join source must be a fully qualified table name (e.g., `catalog.schema.table`)",
(join) => !join.Source.Contains('.')
);
var dimensionNameRule = SemanticBridge.MetricView.MakeValidationRuleForDimension(
"no_underscores",
"naming",
"Dimension names should use spaces, not underscores",
(dim) => dim.Name.Contains('_')
);
var measureExprRule = SemanticBridge.MetricView.MakeValidationRuleForMeasure(
"no_select_subquery",
"structure",
"Measure expressions should not contain SELECT subqueries",
(measure) => measure.Expr.ToUpper().Contains("SELECT")
);
// Run validation with custom rules
var diagnostics = SemanticBridge.MetricView.Validate([
versionRule,
joinSourceRule,
dimensionNameRule,
measureExprRule
]).ToList();
// Output results
var sb = new System.Text.StringBuilder();
sb.AppendLine("CUSTOM VALIDATION RESULTS");
sb.AppendLine("-------------------------");
sb.AppendLine("");
sb.AppendLine($"Found {diagnostics.Count} issue(s):");
sb.AppendLine("");
foreach (var diag in diagnostics)
{
sb.AppendLine($"[{diag.Severity}] {diag.Path}: {diag.Message}");
}
Output(sb.ToString());
Output:
CUSTOM VALIDATION RESULTS
-------------------------
Found 5 issue(s):
[Error] MetricView: Metric View version must be 0.1 or 1.1
[Error] MetricView.Joins['customer']: Join source must be a fully qualified table name (e.g., `catalog.schema.table`)
[Error] MetricView.Dimensions['product_name']: Dimension names should use spaces, not underscores
[Error] MetricView.Dimensions['order_date']: Dimension names should use spaces, not underscores
[Error] MetricView.Measures['complex_calc']: Measure expressions should not contain SELECT subqueries
Next steps
- Create contextual validation rules for cross-object checks like duplicate detection