// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.dataplex.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/dataplex/v1/data_quality_rule_template.proto";
import "google/cloud/dataplex/v1/datascans_common.proto";
import "google/cloud/dataplex/v1/processing.proto";

option go_package = "cloud.google.com/go/dataplex/apiv1/dataplexpb;dataplexpb";
option java_multiple_files = true;
option java_outer_classname = "DataQualityProto";
option java_package = "com.google.cloud.dataplex.v1";
option (google.api.resource_definition) = {
  type: "bigquery.googleapis.com/Table"
  pattern: "projects/{project}/datasets/{dataset}/tables/{table}"
};

// DataQualityScan related setting.
message DataQualitySpec {
  // The configuration of post scan actions of DataQualityScan.
  message PostScanActions {
    // The configuration of BigQuery export post scan action.
    message BigQueryExport {
      // Optional. The BigQuery table to export DataQualityScan results to.
      // Format:
      // //bigquery.googleapis.com/projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_ID
      // or
      // projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_ID
      string results_table = 1 [(google.api.field_behavior) = OPTIONAL];
    }

    // The individuals or groups who are designated to receive notifications
    // upon triggers.
    message Recipients {
      // Optional. The email recipients who will receive the DataQualityScan
      // results report.
      repeated string emails = 1 [(google.api.field_behavior) = OPTIONAL];
    }

    // This trigger is triggered when the DQ score in the job result is less
    // than a specified input score.
    message ScoreThresholdTrigger {
      // Optional. The score range is in [0,100].
      float score_threshold = 2 [(google.api.field_behavior) = OPTIONAL];
    }

    // This trigger is triggered when the scan job itself fails, regardless of
    // the result.
    message JobFailureTrigger {}

    // This trigger is triggered whenever a scan job run ends, regardless
    // of the result.
    message JobEndTrigger {}

    // The configuration of notification report post scan action.
    message NotificationReport {
      // Required. The recipients who will receive the notification report.
      Recipients recipients = 1 [(google.api.field_behavior) = REQUIRED];

      // Optional. If set, report will be sent when score threshold is met.
      ScoreThresholdTrigger score_threshold_trigger = 2
          [(google.api.field_behavior) = OPTIONAL];

      // Optional. If set, report will be sent when a scan job fails.
      JobFailureTrigger job_failure_trigger = 4
          [(google.api.field_behavior) = OPTIONAL];

      // Optional. If set, report will be sent when a scan job ends.
      JobEndTrigger job_end_trigger = 5
          [(google.api.field_behavior) = OPTIONAL];
    }

    // Optional. If set, results will be exported to the provided BigQuery
    // table.
    BigQueryExport bigquery_export = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. If set, results will be sent to the provided notification
    // receipts upon triggers.
    NotificationReport notification_report = 2
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The list of rules to evaluate against a data source. At least one
  // rule is required.
  repeated DataQualityRule rules = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The percentage of the records to be selected from the dataset for
  // DataScan.
  //
  // * Value can range between 0.0 and 100.0 with up to 3 significant decimal
  // digits.
  // * Sampling is not applied if `sampling_percent` is not specified, 0 or
  // 100.
  float sampling_percent = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A filter applied to all rows in a single DataScan job.
  // The filter needs to be a valid SQL expression for a [WHERE clause in
  // GoogleSQL
  // syntax](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#where_clause).
  //
  // Example: col1 >= 0 AND col2 < 10
  string row_filter = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Actions to take upon job completion.
  PostScanActions post_scan_actions = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set, the latest DataScan job result will be published as
  // Dataplex Universal Catalog metadata.
  bool catalog_publishing_enabled = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If enabled, the data scan will retrieve rules defined in the
  // dataplex-types.global.data-rules aspect on all paths of the catalog entry
  // corresponding to the BigQuery table resource and all attached glossary
  // terms. The path that data-rules aspect is attached on the table entry
  // defines the column that the rule will be evaluated against. For glossary
  // terms, the path that the terms are attached on the table entry defines the
  // column that the rule will be evaluated against. At the start of scan
  // execution, the rules reflect the latest state retrieved from the catalog
  // entry and any updates on the rules thereafter are ignored for that
  // execution. The updates will be reflected from the next execution. Rules
  // defined in the datascan must be empty if this field is enabled.
  bool enable_catalog_based_rules = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Filter for selectively running a subset of rules. You can filter
  // the request by the name or attribute key-value pairs defined on the rule.
  // If not specified, all rules are run. The filter is applicable to both, the
  // rules retrieved from catalog and explicitly defined rules in the scan.
  // Please see [filter
  // syntax](https://docs.cloud.google.com/dataplex/docs/auto-data-quality-overview#rule-filtering)
  // for more details.
  string filter = 11 [(google.api.field_behavior) = OPTIONAL];
}

// The output of a DataQualityScan.
message DataQualityResult {
  // The result of post scan actions of DataQualityScan job.
  message PostScanActionsResult {
    // The result of BigQuery export post scan action.
    message BigQueryExportResult {
      // Execution state for the exporting.
      enum State {
        // The exporting state is unspecified.
        STATE_UNSPECIFIED = 0;

        // The exporting completed successfully.
        SUCCEEDED = 1;

        // The exporting is no longer running due to an error.
        FAILED = 2;

        // The exporting is skipped due to no valid scan result to export
        // (usually caused by scan failed).
        SKIPPED = 3;
      }

      // Output only. Execution state for the BigQuery exporting.
      State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. Additional information about the BigQuery exporting.
      string message = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
    }

    // Output only. The result of BigQuery export post scan action.
    BigQueryExportResult bigquery_export_result = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // The assets generated by Anomaly Detection Data Scan.
  message AnomalyDetectionGeneratedAssets {
    // Output only. The result table for anomaly detection.
    // Format:
    // PROJECT_ID.DATASET_ID.TABLE_ID
    // If the result table is set at AnomalyDetectionAssets, the result table
    // here would be the same as the one set in the
    // AnomalyDetectionAssets.result_table.
    string result_table = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The intermediate table for data anomaly detection.
    // Format:
    // PROJECT_ID.DATASET_ID.TABLE_ID
    string data_intermediate_table = 2
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The intermediate table for freshness anomaly detection.
    // Format:
    // PROJECT_ID.DATASET_ID.TABLE_ID
    string freshness_intermediate_table = 3
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The intermediate table for volume anomaly detection.
    // Format:
    // PROJECT_ID.DATASET_ID.TABLE_ID
    string volume_intermediate_table = 4
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. Overall data quality result -- `true` if all rules passed.
  bool passed = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The overall data quality score.
  //
  // The score ranges between [0, 100] (up to two decimal points).
  optional float score = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A list of results at the dimension level.
  //
  // A dimension will have a corresponding `DataQualityDimensionResult` if and
  // only if there is at least one rule with the 'dimension' field set to it.
  repeated DataQualityDimensionResult dimensions = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A list of results at the column level.
  //
  // A column will have a corresponding `DataQualityColumnResult` if and only if
  // there is at least one rule with the 'column' field set to it.
  repeated DataQualityColumnResult columns = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A list of all the rules in a job, and their results.
  repeated DataQualityRuleResult rules = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The count of rows processed.
  int64 row_count = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The data scanned for this result.
  ScannedData scanned_data = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The result of post scan actions.
  PostScanActionsResult post_scan_actions_result = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The status of publishing the data scan as Dataplex Universal
  // Catalog metadata.
  DataScanCatalogPublishingStatus catalog_publishing_status = 11
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The generated assets for anomaly detection.
  AnomalyDetectionGeneratedAssets anomaly_detection_generated_assets = 12
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// DataQualityRuleResult provides a more detailed, per-rule view of the results.
message DataQualityRuleResult {
  // Contains a single result from the debug query.
  message DebugQueryResult {
    // Specifies the name of the result. Available if provided with an explicit
    // alias using `[AS] alias`.
    string name = 1;

    // Indicates the data type of the result. For more information, see
    // [BigQuery data
    // types](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types).
    string type = 2;

    // Represents the value of the result as a string.
    string value = 3;
  }

  // Contains all results from a debug query.
  message DebugQueryResultSet {
    // Output only. Contains all results. Up to 10 results can be returned.
    repeated DebugQueryResult results = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. The rule specified in the DataQualitySpec, as is.
  DataQualityRule rule = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Whether the rule passed or failed.
  bool passed = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The number of rows a rule was evaluated against.
  //
  // This field is only valid for row-level type rules.
  //
  // Evaluated count can be configured to either
  //
  // * include all rows (default) - with `null` rows automatically failing rule
  // evaluation, or
  // * exclude `null` rows from the `evaluated_count`, by setting
  // `ignore_nulls = true`.
  //
  // This field is not set for rule SqlAssertion.
  int64 evaluated_count = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The number of rows which passed a rule evaluation.
  //
  // This field is only valid for row-level type rules.
  //
  // This field is not set for rule SqlAssertion.
  int64 passed_count = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The number of rows with null values in the specified column.
  int64 null_count = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The ratio of **passed_count / evaluated_count**.
  //
  // This field is only valid for row-level type rules.
  double pass_ratio = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The query to find rows that did not pass this rule.
  //
  // This field is only valid for row-level type rules.
  string failing_rows_query = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The number of rows returned by the SQL statement in a SQL
  // assertion rule.
  //
  // This field is only valid for SQL assertion rules.
  int64 assertion_row_count = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Contains the results of all debug queries for this rule.
  // The number of result sets will correspond to the number of
  // [debug_queries][google.cloud.dataplex.v1.DataQualityRule.debug_queries].
  repeated DebugQueryResultSet debug_queries_result_sets = 13
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// DataQualityDimensionResult provides a more detailed, per-dimension view of
// the results.
message DataQualityDimensionResult {
  // Output only. The dimension config specified in the DataQualitySpec, as is.
  DataQualityDimension dimension = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Whether the dimension passed or failed.
  bool passed = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The dimension-level data quality score for this data scan job
  // if and only if the 'dimension' field is set.
  //
  // The score ranges between [0, 100] (up to two decimal
  // points).
  optional float score = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A dimension captures data quality intent about a defined subset of the rules
// specified.
message DataQualityDimension {
  // Output only. The dimension name a rule belongs to. Custom dimension name is
  // supported with all uppercase letters and maximum length of 30 characters.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A rule captures data quality intent about a data source.
message DataQualityRule {
  // Evaluates whether each column value lies between a specified range.
  message RangeExpectation {
    // Optional. The minimum column value allowed for a row to pass this
    // validation. At least one of `min_value` and `max_value` need to be
    // provided.
    string min_value = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The maximum column value allowed for a row to pass this
    // validation. At least one of `min_value` and `max_value` need to be
    // provided.
    string max_value = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Whether each value needs to be strictly greater than ('>') the
    // minimum, or if equality is allowed.
    //
    // Only relevant if a `min_value` has been defined. Default = false.
    bool strict_min_enabled = 3 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Whether each value needs to be strictly lesser than ('<') the
    // maximum, or if equality is allowed.
    //
    // Only relevant if a `max_value` has been defined. Default = false.
    bool strict_max_enabled = 4 [(google.api.field_behavior) = OPTIONAL];
  }

  // Evaluates whether each column value is null.
  message NonNullExpectation {}

  // Evaluates whether each column value is contained by a specified set.
  message SetExpectation {
    // Optional. Expected values for the column value.
    repeated string values = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Evaluates whether each column value matches a specified regex.
  message RegexExpectation {
    // Optional. A regular expression the column value is expected to match.
    string regex = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Evaluates whether the column has duplicates.
  message UniquenessExpectation {}

  // Evaluates whether the column aggregate statistic lies between a specified
  // range.
  message StatisticRangeExpectation {
    // The list of aggregate metrics a rule can be evaluated against.
    enum ColumnStatistic {
      // Unspecified statistic type
      STATISTIC_UNDEFINED = 0;

      // Evaluate the column mean
      MEAN = 1;

      // Evaluate the column min
      MIN = 2;

      // Evaluate the column max
      MAX = 3;
    }

    // Optional. The aggregate metric to evaluate.
    ColumnStatistic statistic = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The minimum column statistic value allowed for a row to pass
    // this validation.
    //
    // At least one of `min_value` and `max_value` need to be provided.
    string min_value = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The maximum column statistic value allowed for a row to pass
    // this validation.
    //
    // At least one of `min_value` and `max_value` need to be provided.
    string max_value = 3 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Whether column statistic needs to be strictly greater than
    // ('>') the minimum, or if equality is allowed.
    //
    // Only relevant if a `min_value` has been defined. Default = false.
    bool strict_min_enabled = 4 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Whether column statistic needs to be strictly lesser than ('<')
    // the maximum, or if equality is allowed.
    //
    // Only relevant if a `max_value` has been defined. Default = false.
    bool strict_max_enabled = 5 [(google.api.field_behavior) = OPTIONAL];
  }

  // Evaluates whether each row passes the specified condition.
  //
  // The SQL expression needs to use [GoogleSQL
  // syntax](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax)
  // and should produce a boolean value per row as the result.
  //
  // Example: col1 >= 0 AND col2 < 10
  message RowConditionExpectation {
    // Optional. The SQL expression.
    string sql_expression = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Evaluates whether the provided expression is true.
  //
  // The SQL expression needs to use [GoogleSQL
  // syntax](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax)
  // and should produce a scalar boolean result.
  //
  // Example: MIN(col1) >= 0
  message TableConditionExpectation {
    // Optional. The SQL expression.
    string sql_expression = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // A SQL statement that is evaluated to return rows that match an invalid
  // state. If any rows are are returned, this rule fails.
  //
  // The SQL statement must use [GoogleSQL
  // syntax](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax),
  // and must not contain any semicolons.
  //
  // You can use the data reference parameter `${data()}` to reference the
  // source table with all of its precondition filters applied. Examples of
  // precondition filters include row filters, incremental data filters, and
  // sampling. For more information, see [Data reference
  // parameter](https://cloud.google.com/dataplex/docs/auto-data-quality-overview#data-reference-parameter).
  //
  // Example: `SELECT * FROM ${data()} WHERE price < 0`
  message SqlAssertion {
    // Optional. The SQL statement.
    string sql_statement = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // A rule that constructs a SQL statement to evaluate using a rule template
  // and parameter values. If the constructed statement returns any rows, this
  // rule fails
  message TemplateReference {
    // Represents a parameter value.
    message ParameterValue {
      // Required. Represents the string value of the parameter.
      string value = 1 [(google.api.field_behavior) = REQUIRED];
    }

    // Required. The template entry name. Entry must be of EntryType
    // `projects/dataplex-types/locations/global/entryTypes/data-quality-rule-template`
    // and contains top-level aspect of AspectType
    // `projects/dataplex-types/locations/global/aspectTypes/data-quality-rule-template`.
    // The format is:
    // `projects/{project_id_or_number}/locations/{location_id}/entryGroups/{entry_group_id}/entries/{entry_id}`
    string name = 1 [
      (google.api.field_behavior) = REQUIRED,
      (google.api.resource_reference) = {
        type: "dataplex.googleapis.com/Entry"
      }
    ];

    // Optional. Provides the map of parameter name and value.
    // The maximum size of the field is 120KB (encoded as UTF-8).
    map<string, ParameterValue> values = 5
        [(google.api.field_behavior) = OPTIONAL];

    // Output only. The resolved SQL statement generated from the template with
    // parameters substituted. It is only populated in the result.
    string resolved_sql = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The rule template used to resolve the rule. It is only
    // populated in the result.
    DataQualityRuleTemplate rule_template = 4
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Represents the rule source information from Catalog.
  message RuleSource {
    // Path Element represents the direct relationship between the rule origin
    // (aspects) to the BigQuery Entry. Ordering of the rule relationship will
    // be maintained such that the first entry in the list is the closest
    // ancestor (BigQuery table itself). A blank source denotes that the rule is
    // derived directly from the DataScan itself.
    message RulePathElement {
      // Entry source represents information about the related source entry.
      message EntrySource {
        // Output only. The entry type to represent the current characteristics
        // of the entry in the form of:
        // `projects/{project_id_or_number}/locations/{location_id}/entryTypes/{entry-type-id}`.
        string entry_type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

        // Output only. The entry name in the form of:
        // `projects/{project_id_or_number}/locations/{location_id}/entryGroups/{entry_group_id}/entries/{entry_id}`
        string entry = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

        // Output only. The display name of the entry.
        string display_name = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
      }

      // Entry link source represents information about the entry link.
      message EntryLinkSource {
        // Output only. The entry link type to represent the current
        // relationship between the entry and the next entry in the path.
        // In the form of:
        // `projects/{project_id_or_number}/locations/{location_id}/entryLinkTypes/{entry_link_type_id}`
        string entry_link_type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

        // Output only. The entry link name in the form of:
        // `projects/{project_id_or_number}/locations/{location_id}/entryGroups/{entry_group_id}/entryLinks/{entry_link_id}`
        string entry_link = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
      }

      // The source type of the rule.
      oneof source_type {
        // Output only. Entry source represents information about the related
        // source entry.
        EntrySource entry_source = 1
            [(google.api.field_behavior) = OUTPUT_ONLY];

        // Output only. Entry link source represents information about the entry
        // link.
        EntryLinkSource entry_link_source = 2
            [(google.api.field_behavior) = OUTPUT_ONLY];
      }
    }

    // Output only. Rule path elements represent information about the
    // individual items in the relationship path between the scan resource and
    // rule origin in that order.
    repeated RulePathElement rule_path_elements = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Specifies a SQL statement that is evaluated to return up to 10 scalar
  // values that are used to debug rules. If the rule fails, the values can help
  // diagnose the cause of the failure.
  //
  // The SQL statement must use [GoogleSQL
  // syntax](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax),
  // and must not contain any semicolons.
  //
  // You can use the data reference parameter `${data()}` to reference the
  // source table with all of its precondition filters applied. Examples of
  // precondition filters include row filters, incremental data filters, and
  // sampling. For more information, see [Data reference
  // parameter](https://cloud.google.com/dataplex/docs/auto-data-quality-overview#data-reference-parameter).
  //
  // You can also name results with an explicit alias using `[AS] alias`. For
  // more information, see [BigQuery explicit
  // aliases](https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#explicit_alias_syntax).
  //
  // Example: `SELECT MIN(col1) AS min_col1, MAX(col1) AS max_col1 FROM
  // ${data()}`
  message DebugQuery {
    // Optional. Specifies the description of the debug query.
    //
    // * The maximum length is 1,024 characters.
    string description = 1 [(google.api.field_behavior) = OPTIONAL];

    // Required. Specifies the SQL statement to be executed.
    string sql_statement = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // The rule-specific configuration.
  oneof rule_type {
    // Row-level rule which evaluates whether each column value lies between a
    // specified range.
    RangeExpectation range_expectation = 1;

    // Row-level rule which evaluates whether each column value is null.
    NonNullExpectation non_null_expectation = 2;

    // Row-level rule which evaluates whether each column value is contained by
    // a specified set.
    SetExpectation set_expectation = 3;

    // Row-level rule which evaluates whether each column value matches a
    // specified regex.
    RegexExpectation regex_expectation = 4;

    // Row-level rule which evaluates whether each column value is unique.
    UniquenessExpectation uniqueness_expectation = 100;

    // Aggregate rule which evaluates whether the column aggregate
    // statistic lies between a specified range.
    StatisticRangeExpectation statistic_range_expectation = 101;

    // Row-level rule which evaluates whether each row in a table passes the
    // specified condition.
    RowConditionExpectation row_condition_expectation = 200;

    // Aggregate rule which evaluates whether the provided expression is true
    // for a table.
    TableConditionExpectation table_condition_expectation = 201;

    // Aggregate rule which evaluates the number of rows returned for the
    // provided statement. If any rows are returned, this rule fails.
    SqlAssertion sql_assertion = 202;

    // Aggregate rule which references a rule template and provides the
    // parameters to be substituted in the template. If any rows are returned,
    // this rule fails.
    TemplateReference template_reference = 5;
  }

  // Optional. The unnested column which this rule is evaluated against.
  string column = 500 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Rows with `null` values will automatically fail a rule, unless
  // `ignore_null` is `true`. In that case, such `null` rows are trivially
  // considered passing.
  //
  // This field is only valid for the following type of rules:
  //
  // * RangeExpectation
  // * RegexExpectation
  // * SetExpectation
  // * UniquenessExpectation
  bool ignore_null = 501 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The dimension a rule belongs to. Results are also aggregated at
  // the dimension level. Custom dimension name is supported with all uppercase
  // letters and maximum length of 30 characters.
  string dimension = 502 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The minimum ratio of **passing_rows / total_rows** required to
  // pass this rule, with a range of [0.0, 1.0].
  //
  // 0 indicates default value (i.e. 1.0).
  //
  // This field is only valid for row-level type rules.
  double threshold = 503 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A mutable name for the rule.
  //
  // * The name must contain only letters (a-z, A-Z), numbers (0-9), or
  // hyphens (-).
  // * The maximum length is 63 characters.
  // * Must start with a letter.
  // * Must end with a number or a letter.
  string name = 504 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Description of the rule.
  //
  // * The maximum length is 1,024 characters.
  string description = 505 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Whether the Rule is active or suspended.
  // Default is false.
  bool suspended = 506 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Map of attribute name and value linked to the rule. The rules to
  // evaluate can be filtered based on attributes provided here and a filter
  // expression provided in the DataQualitySpec.filter field.
  map<string, string> attributes = 507 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Contains information about the source of the rule and its
  // relationship with the BigQuery table, where applicable.
  RuleSource rule_source = 508 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Specifies the debug queries for this rule.
  // Currently, only one query is supported, but this may be expanded in the
  // future.
  repeated DebugQuery debug_queries = 510
      [(google.api.field_behavior) = OPTIONAL];
}

// DataQualityColumnResult provides a more detailed, per-column view of
// the results.
message DataQualityColumnResult {
  // Output only. The column specified in the DataQualityRule.
  string column = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The column-level data quality score for this data scan job if
  // and only if the 'column' field is set.
  //
  // The score ranges between between [0, 100] (up to two decimal
  // points).
  optional float score = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Whether the column passed or failed.
  bool passed = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The dimension-level results for this column.
  repeated DataQualityDimensionResult dimensions = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];
}
