github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/props/verify.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  // +build race
    12  
    13  package props
    14  
    15  import (
    16  	"github.com/cockroachdb/cockroach/pkg/util/log"
    17  	"github.com/cockroachdb/errors"
    18  )
    19  
    20  // Verify runs consistency checks against the shared properties, in order to
    21  // ensure that they conform to several invariants:
    22  //
    23  //   1. The properties must have been built.
    24  //   2. If HasCorrelatedSubquery is true, then HasSubquery must be true as well.
    25  //   3. If Mutate is true, then CanHaveSideEffects must also be true.
    26  //
    27  func (s *Shared) Verify() {
    28  	if !s.Populated {
    29  		panic(errors.AssertionFailedf("properties are not populated"))
    30  	}
    31  	if s.HasCorrelatedSubquery && !s.HasSubquery {
    32  		panic(errors.AssertionFailedf("HasSubquery cannot be false if HasCorrelatedSubquery is true"))
    33  	}
    34  	if s.CanMutate && !s.CanHaveSideEffects {
    35  		panic(errors.AssertionFailedf("CanHaveSideEffects cannot be false if CanMutate is true"))
    36  	}
    37  }
    38  
    39  // Verify runs consistency checks against the relational properties, in order to
    40  // ensure that they conform to several invariants:
    41  //
    42  //   1. Functional dependencies are internally consistent.
    43  //   2. Not null columns are a subset of output columns.
    44  //   3. Outer columns do not intersect output columns.
    45  //   4. If functional dependencies indicate that the relation can have at most
    46  //      one row, then the cardinality reflects that as well.
    47  //
    48  func (r *Relational) Verify() {
    49  	r.Shared.Verify()
    50  	r.FuncDeps.Verify()
    51  
    52  	if !r.NotNullCols.SubsetOf(r.OutputCols) {
    53  		panic(errors.AssertionFailedf("not null cols %s not a subset of output cols %s",
    54  			log.Safe(r.NotNullCols), log.Safe(r.OutputCols)))
    55  	}
    56  	if r.OuterCols.Intersects(r.OutputCols) {
    57  		panic(errors.AssertionFailedf("outer cols %s intersect output cols %s",
    58  			log.Safe(r.OuterCols), log.Safe(r.OutputCols)))
    59  	}
    60  	if r.FuncDeps.HasMax1Row() {
    61  		if r.Cardinality.Max > 1 {
    62  			panic(errors.AssertionFailedf(
    63  				"max cardinality must be <= 1 if FDs have max 1 row: %s", r.Cardinality))
    64  		}
    65  	}
    66  	if r.IsAvailable(PruneCols) {
    67  		if !r.Rule.PruneCols.SubsetOf(r.OutputCols) {
    68  			panic(errors.AssertionFailedf("prune cols %s must be a subset of output cols %s",
    69  				log.Safe(r.Rule.PruneCols), log.Safe(r.OutputCols)))
    70  		}
    71  	}
    72  }
    73  
    74  // VerifyAgainst checks that the two properties don't contradict each other.
    75  // Used for testing (e.g. to cross-check derived properties from expressions in
    76  // the same group).
    77  func (r *Relational) VerifyAgainst(other *Relational) {
    78  	if !r.OutputCols.Equals(other.OutputCols) {
    79  		panic(errors.AssertionFailedf("output cols mismatch: %s vs %s", log.Safe(r.OutputCols), log.Safe(other.OutputCols)))
    80  	}
    81  
    82  	if r.Cardinality.Max < other.Cardinality.Min ||
    83  		r.Cardinality.Min > other.Cardinality.Max {
    84  		panic(errors.AssertionFailedf("cardinality mismatch: %s vs %s", log.Safe(r.Cardinality), log.Safe(other.Cardinality)))
    85  	}
    86  
    87  	// NotNullCols, FuncDeps are best effort, so they might differ.
    88  	// OuterCols, CanHaveSideEffects, and HasPlaceholder might differ if a
    89  	// subexpression containing them was elided.
    90  }
    91  
    92  // Verify runs consistency checks against the relational properties, in order to
    93  // ensure that they conform to several invariants:
    94  //
    95  //   1. Functional dependencies are internally consistent.
    96  //
    97  func (s *Scalar) Verify() {
    98  	s.Shared.Verify()
    99  	s.FuncDeps.Verify()
   100  }