// Code generated by optgen; DO NOT EDIT.

package memo

import (
	"github.com/cockroachdb/cockroach/pkg/sql/coltypes"
	"github.com/cockroachdb/cockroach/pkg/sql/opt"
	"github.com/cockroachdb/cockroach/pkg/sql/opt/props"
	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
	"github.com/cockroachdb/cockroach/pkg/sql/sem/types"
)

var opLayoutTable = [...]opLayout{
	opt.UnknownOp:             0xFF, // will cause a crash if used
	opt.SortOp:                makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ScanOp:                makeOpLayout(0 /*base*/, 0 /*list*/, 1 /*priv*/),
	opt.VirtualScanOp:         makeOpLayout(0 /*base*/, 0 /*list*/, 1 /*priv*/),
	opt.ValuesOp:              makeOpLayout(0 /*base*/, 1 /*list*/, 3 /*priv*/),
	opt.SelectOp:              makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ProjectOp:             makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.InnerJoinOp:           makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.LeftJoinOp:            makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.RightJoinOp:           makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FullJoinOp:            makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.SemiJoinOp:            makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.AntiJoinOp:            makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.IndexJoinOp:           makeOpLayout(1 /*base*/, 0 /*list*/, 2 /*priv*/),
	opt.LookupJoinOp:          makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.MergeJoinOp:           makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.InnerJoinApplyOp:      makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.LeftJoinApplyOp:       makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.RightJoinApplyOp:      makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FullJoinApplyOp:       makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.SemiJoinApplyOp:       makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.AntiJoinApplyOp:       makeOpLayout(3 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.GroupByOp:             makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.ScalarGroupByOp:       makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.DistinctOnOp:          makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.UnionOp:               makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.IntersectOp:           makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.ExceptOp:              makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.UnionAllOp:            makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.IntersectAllOp:        makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.ExceptAllOp:           makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.LimitOp:               makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.OffsetOp:              makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.Max1RowOp:             makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ExplainOp:             makeOpLayout(1 /*base*/, 0 /*list*/, 2 /*priv*/),
	opt.ShowTraceForSessionOp: makeOpLayout(0 /*base*/, 0 /*list*/, 1 /*priv*/),
	opt.RowNumberOp:           makeOpLayout(1 /*base*/, 0 /*list*/, 2 /*priv*/),
	opt.ZipOp:                 makeOpLayout(0 /*base*/, 1 /*list*/, 3 /*priv*/),
	opt.SubqueryOp:            makeOpLayout(1 /*base*/, 0 /*list*/, 2 /*priv*/),
	opt.AnyOp:                 makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.VariableOp:            makeOpLayout(0 /*base*/, 0 /*list*/, 1 /*priv*/),
	opt.ConstOp:               makeOpLayout(0 /*base*/, 0 /*list*/, 1 /*priv*/),
	opt.NullOp:                makeOpLayout(0 /*base*/, 0 /*list*/, 1 /*priv*/),
	opt.TrueOp:                makeOpLayout(0 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FalseOp:               makeOpLayout(0 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.PlaceholderOp:         makeOpLayout(0 /*base*/, 0 /*list*/, 1 /*priv*/),
	opt.TupleOp:               makeOpLayout(0 /*base*/, 1 /*list*/, 3 /*priv*/),
	opt.ProjectionsOp:         makeOpLayout(0 /*base*/, 1 /*list*/, 3 /*priv*/),
	opt.AggregationsOp:        makeOpLayout(0 /*base*/, 1 /*list*/, 3 /*priv*/),
	opt.MergeOnOp:             makeOpLayout(1 /*base*/, 0 /*list*/, 2 /*priv*/),
	opt.ExistsOp:              makeOpLayout(1 /*base*/, 0 /*list*/, 2 /*priv*/),
	opt.FiltersOp:             makeOpLayout(0 /*base*/, 1 /*list*/, 0 /*priv*/),
	opt.AndOp:                 makeOpLayout(0 /*base*/, 1 /*list*/, 0 /*priv*/),
	opt.OrOp:                  makeOpLayout(0 /*base*/, 1 /*list*/, 0 /*priv*/),
	opt.NotOp:                 makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.EqOp:                  makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.LtOp:                  makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.GtOp:                  makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.LeOp:                  makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.GeOp:                  makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.NeOp:                  makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.InOp:                  makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.NotInOp:               makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.LikeOp:                makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.NotLikeOp:             makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ILikeOp:               makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.NotILikeOp:            makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.SimilarToOp:           makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.NotSimilarToOp:        makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.RegMatchOp:            makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.NotRegMatchOp:         makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.RegIMatchOp:           makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.NotRegIMatchOp:        makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.IsOp:                  makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.IsNotOp:               makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ContainsOp:            makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.JsonExistsOp:          makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.JsonAllExistsOp:       makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.JsonSomeExistsOp:      makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.AnyScalarOp:           makeOpLayout(2 /*base*/, 0 /*list*/, 3 /*priv*/),
	opt.BitandOp:              makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.BitorOp:               makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.BitxorOp:              makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.PlusOp:                makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.MinusOp:               makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.MultOp:                makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.DivOp:                 makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FloorDivOp:            makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ModOp:                 makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.PowOp:                 makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ConcatOp:              makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.LShiftOp:              makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.RShiftOp:              makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FetchValOp:            makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FetchTextOp:           makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FetchValPathOp:        makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FetchTextPathOp:       makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.UnaryMinusOp:          makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.UnaryComplementOp:     makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.CastOp:                makeOpLayout(1 /*base*/, 0 /*list*/, 2 /*priv*/),
	opt.CaseOp:                makeOpLayout(1 /*base*/, 2 /*list*/, 0 /*priv*/),
	opt.WhenOp:                makeOpLayout(2 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ArrayOp:               makeOpLayout(0 /*base*/, 1 /*list*/, 3 /*priv*/),
	opt.FunctionOp:            makeOpLayout(0 /*base*/, 1 /*list*/, 3 /*priv*/),
	opt.CoalesceOp:            makeOpLayout(0 /*base*/, 1 /*list*/, 0 /*priv*/),
	opt.ColumnAccessOp:        makeOpLayout(1 /*base*/, 0 /*list*/, 2 /*priv*/),
	opt.UnsupportedExprOp:     makeOpLayout(0 /*base*/, 0 /*list*/, 1 /*priv*/),
	opt.ArrayAggOp:            makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.AvgOp:                 makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.BoolAndOp:             makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.BoolOrOp:              makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ConcatAggOp:           makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.CountOp:               makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.CountRowsOp:           makeOpLayout(0 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.MaxOp:                 makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.MinOp:                 makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.SumIntOp:              makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.SumOp:                 makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.SqrDiffOp:             makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.VarianceOp:            makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.StdDevOp:              makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.XorAggOp:              makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.JsonAggOp:             makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.JsonbAggOp:            makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ConstAggOp:            makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.ConstNotNullAggOp:     makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.AnyNotNullAggOp:       makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.FirstAggOp:            makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
	opt.AggDistinctOp:         makeOpLayout(1 /*base*/, 0 /*list*/, 0 /*priv*/),
}

var isEnforcerLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                true,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isRelationalLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                true,
	opt.VirtualScanOp:         true,
	opt.ValuesOp:              true,
	opt.SelectOp:              true,
	opt.ProjectOp:             true,
	opt.InnerJoinOp:           true,
	opt.LeftJoinOp:            true,
	opt.RightJoinOp:           true,
	opt.FullJoinOp:            true,
	opt.SemiJoinOp:            true,
	opt.AntiJoinOp:            true,
	opt.IndexJoinOp:           true,
	opt.LookupJoinOp:          true,
	opt.MergeJoinOp:           true,
	opt.InnerJoinApplyOp:      true,
	opt.LeftJoinApplyOp:       true,
	opt.RightJoinApplyOp:      true,
	opt.FullJoinApplyOp:       true,
	opt.SemiJoinApplyOp:       true,
	opt.AntiJoinApplyOp:       true,
	opt.GroupByOp:             true,
	opt.ScalarGroupByOp:       true,
	opt.DistinctOnOp:          true,
	opt.UnionOp:               true,
	opt.IntersectOp:           true,
	opt.ExceptOp:              true,
	opt.UnionAllOp:            true,
	opt.IntersectAllOp:        true,
	opt.ExceptAllOp:           true,
	opt.LimitOp:               true,
	opt.OffsetOp:              true,
	opt.Max1RowOp:             true,
	opt.ExplainOp:             true,
	opt.ShowTraceForSessionOp: true,
	opt.RowNumberOp:           true,
	opt.ZipOp:                 true,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isJoinLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           true,
	opt.LeftJoinOp:            true,
	opt.RightJoinOp:           true,
	opt.FullJoinOp:            true,
	opt.SemiJoinOp:            true,
	opt.AntiJoinOp:            true,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      true,
	opt.LeftJoinApplyOp:       true,
	opt.RightJoinApplyOp:      true,
	opt.FullJoinApplyOp:       true,
	opt.SemiJoinApplyOp:       true,
	opt.AntiJoinApplyOp:       true,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isJoinNonApplyLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           true,
	opt.LeftJoinOp:            true,
	opt.RightJoinOp:           true,
	opt.FullJoinOp:            true,
	opt.SemiJoinOp:            true,
	opt.AntiJoinOp:            true,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isJoinApplyLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      true,
	opt.LeftJoinApplyOp:       true,
	opt.RightJoinApplyOp:      true,
	opt.FullJoinApplyOp:       true,
	opt.SemiJoinApplyOp:       true,
	opt.AntiJoinApplyOp:       true,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isScalarLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            true,
	opt.AnyOp:                 true,
	opt.VariableOp:            true,
	opt.ConstOp:               true,
	opt.NullOp:                true,
	opt.TrueOp:                true,
	opt.FalseOp:               true,
	opt.PlaceholderOp:         true,
	opt.TupleOp:               true,
	opt.ProjectionsOp:         true,
	opt.AggregationsOp:        true,
	opt.MergeOnOp:             true,
	opt.ExistsOp:              true,
	opt.FiltersOp:             true,
	opt.AndOp:                 true,
	opt.OrOp:                  true,
	opt.NotOp:                 true,
	opt.EqOp:                  true,
	opt.LtOp:                  true,
	opt.GtOp:                  true,
	opt.LeOp:                  true,
	opt.GeOp:                  true,
	opt.NeOp:                  true,
	opt.InOp:                  true,
	opt.NotInOp:               true,
	opt.LikeOp:                true,
	opt.NotLikeOp:             true,
	opt.ILikeOp:               true,
	opt.NotILikeOp:            true,
	opt.SimilarToOp:           true,
	opt.NotSimilarToOp:        true,
	opt.RegMatchOp:            true,
	opt.NotRegMatchOp:         true,
	opt.RegIMatchOp:           true,
	opt.NotRegIMatchOp:        true,
	opt.IsOp:                  true,
	opt.IsNotOp:               true,
	opt.ContainsOp:            true,
	opt.JsonExistsOp:          true,
	opt.JsonAllExistsOp:       true,
	opt.JsonSomeExistsOp:      true,
	opt.AnyScalarOp:           true,
	opt.BitandOp:              true,
	opt.BitorOp:               true,
	opt.BitxorOp:              true,
	opt.PlusOp:                true,
	opt.MinusOp:               true,
	opt.MultOp:                true,
	opt.DivOp:                 true,
	opt.FloorDivOp:            true,
	opt.ModOp:                 true,
	opt.PowOp:                 true,
	opt.ConcatOp:              true,
	opt.LShiftOp:              true,
	opt.RShiftOp:              true,
	opt.FetchValOp:            true,
	opt.FetchTextOp:           true,
	opt.FetchValPathOp:        true,
	opt.FetchTextPathOp:       true,
	opt.UnaryMinusOp:          true,
	opt.UnaryComplementOp:     true,
	opt.CastOp:                true,
	opt.CaseOp:                true,
	opt.WhenOp:                true,
	opt.ArrayOp:               true,
	opt.FunctionOp:            true,
	opt.CoalesceOp:            true,
	opt.ColumnAccessOp:        true,
	opt.UnsupportedExprOp:     true,
	opt.ArrayAggOp:            true,
	opt.AvgOp:                 true,
	opt.BoolAndOp:             true,
	opt.BoolOrOp:              true,
	opt.ConcatAggOp:           true,
	opt.CountOp:               true,
	opt.CountRowsOp:           true,
	opt.MaxOp:                 true,
	opt.MinOp:                 true,
	opt.SumIntOp:              true,
	opt.SumOp:                 true,
	opt.SqrDiffOp:             true,
	opt.VarianceOp:            true,
	opt.StdDevOp:              true,
	opt.XorAggOp:              true,
	opt.JsonAggOp:             true,
	opt.JsonbAggOp:            true,
	opt.ConstAggOp:            true,
	opt.ConstNotNullAggOp:     true,
	opt.AnyNotNullAggOp:       true,
	opt.FirstAggOp:            true,
	opt.AggDistinctOp:         true,
}

var isConstValueLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               true,
	opt.NullOp:                true,
	opt.TrueOp:                true,
	opt.FalseOp:               true,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isBooleanLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                true,
	opt.FalseOp:               true,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             true,
	opt.AndOp:                 true,
	opt.OrOp:                  true,
	opt.NotOp:                 true,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isComparisonLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  true,
	opt.LtOp:                  true,
	opt.GtOp:                  true,
	opt.LeOp:                  true,
	opt.GeOp:                  true,
	opt.NeOp:                  true,
	opt.InOp:                  true,
	opt.NotInOp:               true,
	opt.LikeOp:                true,
	opt.NotLikeOp:             true,
	opt.ILikeOp:               true,
	opt.NotILikeOp:            true,
	opt.SimilarToOp:           true,
	opt.NotSimilarToOp:        true,
	opt.RegMatchOp:            true,
	opt.NotRegMatchOp:         true,
	opt.RegIMatchOp:           true,
	opt.NotRegIMatchOp:        true,
	opt.IsOp:                  true,
	opt.IsNotOp:               true,
	opt.ContainsOp:            true,
	opt.JsonExistsOp:          true,
	opt.JsonAllExistsOp:       true,
	opt.JsonSomeExistsOp:      true,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isBinaryLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              true,
	opt.BitorOp:               true,
	opt.BitxorOp:              true,
	opt.PlusOp:                true,
	opt.MinusOp:               true,
	opt.MultOp:                true,
	opt.DivOp:                 true,
	opt.FloorDivOp:            true,
	opt.ModOp:                 true,
	opt.PowOp:                 true,
	opt.ConcatOp:              true,
	opt.LShiftOp:              true,
	opt.RShiftOp:              true,
	opt.FetchValOp:            true,
	opt.FetchTextOp:           true,
	opt.FetchValPathOp:        true,
	opt.FetchTextPathOp:       true,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isUnaryLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          true,
	opt.UnaryComplementOp:     true,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            false,
	opt.AvgOp:                 false,
	opt.BoolAndOp:             false,
	opt.BoolOrOp:              false,
	opt.ConcatAggOp:           false,
	opt.CountOp:               false,
	opt.CountRowsOp:           false,
	opt.MaxOp:                 false,
	opt.MinOp:                 false,
	opt.SumIntOp:              false,
	opt.SumOp:                 false,
	opt.SqrDiffOp:             false,
	opt.VarianceOp:            false,
	opt.StdDevOp:              false,
	opt.XorAggOp:              false,
	opt.JsonAggOp:             false,
	opt.JsonbAggOp:            false,
	opt.ConstAggOp:            false,
	opt.ConstNotNullAggOp:     false,
	opt.AnyNotNullAggOp:       false,
	opt.FirstAggOp:            false,
	opt.AggDistinctOp:         false,
}

var isAggregateLookup = [...]bool{
	opt.UnknownOp: false,

	opt.SortOp:                false,
	opt.ScanOp:                false,
	opt.VirtualScanOp:         false,
	opt.ValuesOp:              false,
	opt.SelectOp:              false,
	opt.ProjectOp:             false,
	opt.InnerJoinOp:           false,
	opt.LeftJoinOp:            false,
	opt.RightJoinOp:           false,
	opt.FullJoinOp:            false,
	opt.SemiJoinOp:            false,
	opt.AntiJoinOp:            false,
	opt.IndexJoinOp:           false,
	opt.LookupJoinOp:          false,
	opt.MergeJoinOp:           false,
	opt.InnerJoinApplyOp:      false,
	opt.LeftJoinApplyOp:       false,
	opt.RightJoinApplyOp:      false,
	opt.FullJoinApplyOp:       false,
	opt.SemiJoinApplyOp:       false,
	opt.AntiJoinApplyOp:       false,
	opt.GroupByOp:             false,
	opt.ScalarGroupByOp:       false,
	opt.DistinctOnOp:          false,
	opt.UnionOp:               false,
	opt.IntersectOp:           false,
	opt.ExceptOp:              false,
	opt.UnionAllOp:            false,
	opt.IntersectAllOp:        false,
	opt.ExceptAllOp:           false,
	opt.LimitOp:               false,
	opt.OffsetOp:              false,
	opt.Max1RowOp:             false,
	opt.ExplainOp:             false,
	opt.ShowTraceForSessionOp: false,
	opt.RowNumberOp:           false,
	opt.ZipOp:                 false,
	opt.SubqueryOp:            false,
	opt.AnyOp:                 false,
	opt.VariableOp:            false,
	opt.ConstOp:               false,
	opt.NullOp:                false,
	opt.TrueOp:                false,
	opt.FalseOp:               false,
	opt.PlaceholderOp:         false,
	opt.TupleOp:               false,
	opt.ProjectionsOp:         false,
	opt.AggregationsOp:        false,
	opt.MergeOnOp:             false,
	opt.ExistsOp:              false,
	opt.FiltersOp:             false,
	opt.AndOp:                 false,
	opt.OrOp:                  false,
	opt.NotOp:                 false,
	opt.EqOp:                  false,
	opt.LtOp:                  false,
	opt.GtOp:                  false,
	opt.LeOp:                  false,
	opt.GeOp:                  false,
	opt.NeOp:                  false,
	opt.InOp:                  false,
	opt.NotInOp:               false,
	opt.LikeOp:                false,
	opt.NotLikeOp:             false,
	opt.ILikeOp:               false,
	opt.NotILikeOp:            false,
	opt.SimilarToOp:           false,
	opt.NotSimilarToOp:        false,
	opt.RegMatchOp:            false,
	opt.NotRegMatchOp:         false,
	opt.RegIMatchOp:           false,
	opt.NotRegIMatchOp:        false,
	opt.IsOp:                  false,
	opt.IsNotOp:               false,
	opt.ContainsOp:            false,
	opt.JsonExistsOp:          false,
	opt.JsonAllExistsOp:       false,
	opt.JsonSomeExistsOp:      false,
	opt.AnyScalarOp:           false,
	opt.BitandOp:              false,
	opt.BitorOp:               false,
	opt.BitxorOp:              false,
	opt.PlusOp:                false,
	opt.MinusOp:               false,
	opt.MultOp:                false,
	opt.DivOp:                 false,
	opt.FloorDivOp:            false,
	opt.ModOp:                 false,
	opt.PowOp:                 false,
	opt.ConcatOp:              false,
	opt.LShiftOp:              false,
	opt.RShiftOp:              false,
	opt.FetchValOp:            false,
	opt.FetchTextOp:           false,
	opt.FetchValPathOp:        false,
	opt.FetchTextPathOp:       false,
	opt.UnaryMinusOp:          false,
	opt.UnaryComplementOp:     false,
	opt.CastOp:                false,
	opt.CaseOp:                false,
	opt.WhenOp:                false,
	opt.ArrayOp:               false,
	opt.FunctionOp:            false,
	opt.CoalesceOp:            false,
	opt.ColumnAccessOp:        false,
	opt.UnsupportedExprOp:     false,
	opt.ArrayAggOp:            true,
	opt.AvgOp:                 true,
	opt.BoolAndOp:             true,
	opt.BoolOrOp:              true,
	opt.ConcatAggOp:           true,
	opt.CountOp:               true,
	opt.CountRowsOp:           true,
	opt.MaxOp:                 true,
	opt.MinOp:                 true,
	opt.SumIntOp:              true,
	opt.SumOp:                 true,
	opt.SqrDiffOp:             true,
	opt.VarianceOp:            true,
	opt.StdDevOp:              true,
	opt.XorAggOp:              true,
	opt.JsonAggOp:             true,
	opt.JsonbAggOp:            true,
	opt.ConstAggOp:            true,
	opt.ConstNotNullAggOp:     true,
	opt.AnyNotNullAggOp:       true,
	opt.FirstAggOp:            true,
	opt.AggDistinctOp:         false,
}

func (ev ExprView) IsEnforcer() bool {
	return isEnforcerLookup[ev.op]
}

func (ev ExprView) IsRelational() bool {
	return isRelationalLookup[ev.op]
}

func (ev ExprView) IsJoin() bool {
	return isJoinLookup[ev.op]
}

func (ev ExprView) IsJoinNonApply() bool {
	return isJoinNonApplyLookup[ev.op]
}

func (ev ExprView) IsJoinApply() bool {
	return isJoinApplyLookup[ev.op]
}

func (ev ExprView) IsScalar() bool {
	return isScalarLookup[ev.op]
}

func (ev ExprView) IsConstValue() bool {
	return isConstValueLookup[ev.op]
}

func (ev ExprView) IsBoolean() bool {
	return isBooleanLookup[ev.op]
}

func (ev ExprView) IsComparison() bool {
	return isComparisonLookup[ev.op]
}

func (ev ExprView) IsBinary() bool {
	return isBinaryLookup[ev.op]
}

func (ev ExprView) IsUnary() bool {
	return isUnaryLookup[ev.op]
}

func (ev ExprView) IsAggregate() bool {
	return isAggregateLookup[ev.op]
}

func (e *Expr) IsEnforcer() bool {
	return isEnforcerLookup[e.op]
}

func (e *Expr) IsRelational() bool {
	return isRelationalLookup[e.op]
}

func (e *Expr) IsJoin() bool {
	return isJoinLookup[e.op]
}

func (e *Expr) IsJoinNonApply() bool {
	return isJoinNonApplyLookup[e.op]
}

func (e *Expr) IsJoinApply() bool {
	return isJoinApplyLookup[e.op]
}

func (e *Expr) IsScalar() bool {
	return isScalarLookup[e.op]
}

func (e *Expr) IsConstValue() bool {
	return isConstValueLookup[e.op]
}

func (e *Expr) IsBoolean() bool {
	return isBooleanLookup[e.op]
}

func (e *Expr) IsComparison() bool {
	return isComparisonLookup[e.op]
}

func (e *Expr) IsBinary() bool {
	return isBinaryLookup[e.op]
}

func (e *Expr) IsUnary() bool {
	return isUnaryLookup[e.op]
}

func (e *Expr) IsAggregate() bool {
	return isAggregateLookup[e.op]
}

// ScanExpr returns a result set containing every row in a table by scanning one of
// the table's indexes according to its ordering. The private Def field is an
// *opt.ScanOpDef that identifies the table and index to scan, as well as the
// subset of columns to project from it.
//
// The scan can be constrained and/or have an internal row limit. A scan can be
// executed either as a forward or as a reverse scan (except when it has a limit,
// in which case the direction is fixed).
type ScanExpr Expr

func MakeScanExpr(def PrivateID) ScanExpr {
	return ScanExpr{op: opt.ScanOp, state: exprState{uint32(def)}}
}

func (e *ScanExpr) Def() PrivateID {
	return PrivateID(e.state[0])
}

func (e *ScanExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsScan() *ScanExpr {
	if e.op != opt.ScanOp {
		return nil
	}
	return (*ScanExpr)(e)
}

// VirtualScanExpr returns a result set containing every row in a virtual table.
// Virtual tables are system tables that are populated "on the fly" with rows
// synthesized from system metadata and other state. An example is the
// "information_schema.tables" virtual table which returns one row for each
// accessible system or user table.
//
// VirtualScan has many of the same characteristics as the Scan operator.
// However, virtual tables do not have indexes or keys, and the physical operator
// used to scan virtual tables does not support limits or constraints. Therefore,
// nearly all the rules that apply to Scan do not apply to VirtualScan, so it
// makes sense to have a separate operator.
type VirtualScanExpr Expr

func MakeVirtualScanExpr(def PrivateID) VirtualScanExpr {
	return VirtualScanExpr{op: opt.VirtualScanOp, state: exprState{uint32(def)}}
}

func (e *VirtualScanExpr) Def() PrivateID {
	return PrivateID(e.state[0])
}

func (e *VirtualScanExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsVirtualScan() *VirtualScanExpr {
	if e.op != opt.VirtualScanOp {
		return nil
	}
	return (*VirtualScanExpr)(e)
}

// ValuesExpr returns a manufactured result set containing a constant number of rows.
// specified by the Rows list field. Each row must contain the same set of
// columns in the same order.
//
// The Rows field contains a list of Tuples, one for each row. Each tuple has
// the same length (same with that of Cols).
//
// The Cols field contains the set of column indices returned by each row
// as an opt.ColList. It is legal for Cols to be empty.
type ValuesExpr Expr

func MakeValuesExpr(rows ListID, cols PrivateID) ValuesExpr {
	return ValuesExpr{op: opt.ValuesOp, state: exprState{rows.Offset, rows.Length, uint32(cols)}}
}

func (e *ValuesExpr) Rows() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *ValuesExpr) Cols() PrivateID {
	return PrivateID(e.state[2])
}

func (e *ValuesExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsValues() *ValuesExpr {
	if e.op != opt.ValuesOp {
		return nil
	}
	return (*ValuesExpr)(e)
}

// SelectExpr filters rows from its input result set, based on the boolean filter
// predicate expression. Rows which do not match the filter are discarded. While
// the Filter operand can be any boolean expression, normalization rules will
// typically convert it to a Filters operator in order to make conjunction list
// matching easier.
type SelectExpr Expr

func MakeSelectExpr(input GroupID, filter GroupID) SelectExpr {
	return SelectExpr{op: opt.SelectOp, state: exprState{uint32(input), uint32(filter)}}
}

func (e *SelectExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *SelectExpr) Filter() GroupID {
	return GroupID(e.state[1])
}

func (e *SelectExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsSelect() *SelectExpr {
	if e.op != opt.SelectOp {
		return nil
	}
	return (*SelectExpr)(e)
}

// ProjectExpr modifies the set of columns returned by the input result set. Columns
// can be removed, reordered, or renamed. In addition, new columns can be
// synthesized.
// Projections is a scalar Projections list operator that contains information
// about the projected columns and any expressions that describe newly
// synthesized output columns.
type ProjectExpr Expr

func MakeProjectExpr(input GroupID, projections GroupID) ProjectExpr {
	return ProjectExpr{op: opt.ProjectOp, state: exprState{uint32(input), uint32(projections)}}
}

func (e *ProjectExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ProjectExpr) Projections() GroupID {
	return GroupID(e.state[1])
}

func (e *ProjectExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsProject() *ProjectExpr {
	if e.op != opt.ProjectOp {
		return nil
	}
	return (*ProjectExpr)(e)
}

// InnerJoinExpr creates a result set that combines columns from its left and right
// inputs, based upon its "on" join predicate. Rows which do not match the
// predicate are filtered. While expressions in the predicate can refer to
// columns projected by either the left or right inputs, the inputs are not
// allowed to refer to the other's projected columns.
type InnerJoinExpr Expr

func MakeInnerJoinExpr(left GroupID, right GroupID, on GroupID) InnerJoinExpr {
	return InnerJoinExpr{op: opt.InnerJoinOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *InnerJoinExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *InnerJoinExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *InnerJoinExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *InnerJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsInnerJoin() *InnerJoinExpr {
	if e.op != opt.InnerJoinOp {
		return nil
	}
	return (*InnerJoinExpr)(e)
}

type LeftJoinExpr Expr

func MakeLeftJoinExpr(left GroupID, right GroupID, on GroupID) LeftJoinExpr {
	return LeftJoinExpr{op: opt.LeftJoinOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *LeftJoinExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *LeftJoinExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *LeftJoinExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *LeftJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsLeftJoin() *LeftJoinExpr {
	if e.op != opt.LeftJoinOp {
		return nil
	}
	return (*LeftJoinExpr)(e)
}

type RightJoinExpr Expr

func MakeRightJoinExpr(left GroupID, right GroupID, on GroupID) RightJoinExpr {
	return RightJoinExpr{op: opt.RightJoinOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *RightJoinExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *RightJoinExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *RightJoinExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *RightJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsRightJoin() *RightJoinExpr {
	if e.op != opt.RightJoinOp {
		return nil
	}
	return (*RightJoinExpr)(e)
}

type FullJoinExpr Expr

func MakeFullJoinExpr(left GroupID, right GroupID, on GroupID) FullJoinExpr {
	return FullJoinExpr{op: opt.FullJoinOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *FullJoinExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *FullJoinExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *FullJoinExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *FullJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFullJoin() *FullJoinExpr {
	if e.op != opt.FullJoinOp {
		return nil
	}
	return (*FullJoinExpr)(e)
}

type SemiJoinExpr Expr

func MakeSemiJoinExpr(left GroupID, right GroupID, on GroupID) SemiJoinExpr {
	return SemiJoinExpr{op: opt.SemiJoinOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *SemiJoinExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *SemiJoinExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *SemiJoinExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *SemiJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsSemiJoin() *SemiJoinExpr {
	if e.op != opt.SemiJoinOp {
		return nil
	}
	return (*SemiJoinExpr)(e)
}

type AntiJoinExpr Expr

func MakeAntiJoinExpr(left GroupID, right GroupID, on GroupID) AntiJoinExpr {
	return AntiJoinExpr{op: opt.AntiJoinOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *AntiJoinExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *AntiJoinExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *AntiJoinExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *AntiJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAntiJoin() *AntiJoinExpr {
	if e.op != opt.AntiJoinOp {
		return nil
	}
	return (*AntiJoinExpr)(e)
}

// IndexJoinExpr represents an inner join between an input expression and a primary
// index. It is a special case of LookupJoin where the input columns are the PK
// columns of the table we are looking up into, and every input row results in
// exactly one output row.
//
// IndexJoin operators are created from Scan operators (unlike lookup joins which
// are created from Join operators).
type IndexJoinExpr Expr

func MakeIndexJoinExpr(input GroupID, def PrivateID) IndexJoinExpr {
	return IndexJoinExpr{op: opt.IndexJoinOp, state: exprState{uint32(input), uint32(def)}}
}

func (e *IndexJoinExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *IndexJoinExpr) Def() PrivateID {
	return PrivateID(e.state[1])
}

func (e *IndexJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsIndexJoin() *IndexJoinExpr {
	if e.op != opt.IndexJoinOp {
		return nil
	}
	return (*IndexJoinExpr)(e)
}

// LookupJoinExpr represents a join between an input expression and an index.
// The type of join is in the Def private.
type LookupJoinExpr Expr

func MakeLookupJoinExpr(input GroupID, on GroupID, def PrivateID) LookupJoinExpr {
	return LookupJoinExpr{op: opt.LookupJoinOp, state: exprState{uint32(input), uint32(on), uint32(def)}}
}

func (e *LookupJoinExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *LookupJoinExpr) On() GroupID {
	return GroupID(e.state[1])
}

func (e *LookupJoinExpr) Def() PrivateID {
	return PrivateID(e.state[2])
}

func (e *LookupJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsLookupJoin() *LookupJoinExpr {
	if e.op != opt.LookupJoinOp {
		return nil
	}
	return (*LookupJoinExpr)(e)
}

// MergeJoinExpr represents a join that is executed using merge-join.
// MergeOn is a scalar which contains the ON condition and merge-join ordering
// information; see the MergeOn scalar operator.
// It can be any type of join (identified in the private of MergeOn).
type MergeJoinExpr Expr

func MakeMergeJoinExpr(left GroupID, right GroupID, mergeOn GroupID) MergeJoinExpr {
	return MergeJoinExpr{op: opt.MergeJoinOp, state: exprState{uint32(left), uint32(right), uint32(mergeOn)}}
}

func (e *MergeJoinExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *MergeJoinExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *MergeJoinExpr) MergeOn() GroupID {
	return GroupID(e.state[2])
}

func (e *MergeJoinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsMergeJoin() *MergeJoinExpr {
	if e.op != opt.MergeJoinOp {
		return nil
	}
	return (*MergeJoinExpr)(e)
}

// InnerJoinApplyExpr has the same join semantics as InnerJoin. However, unlike
// InnerJoin, it allows the right input to refer to columns projected by the
// left input.
type InnerJoinApplyExpr Expr

func MakeInnerJoinApplyExpr(left GroupID, right GroupID, on GroupID) InnerJoinApplyExpr {
	return InnerJoinApplyExpr{op: opt.InnerJoinApplyOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *InnerJoinApplyExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *InnerJoinApplyExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *InnerJoinApplyExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *InnerJoinApplyExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsInnerJoinApply() *InnerJoinApplyExpr {
	if e.op != opt.InnerJoinApplyOp {
		return nil
	}
	return (*InnerJoinApplyExpr)(e)
}

type LeftJoinApplyExpr Expr

func MakeLeftJoinApplyExpr(left GroupID, right GroupID, on GroupID) LeftJoinApplyExpr {
	return LeftJoinApplyExpr{op: opt.LeftJoinApplyOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *LeftJoinApplyExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *LeftJoinApplyExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *LeftJoinApplyExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *LeftJoinApplyExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsLeftJoinApply() *LeftJoinApplyExpr {
	if e.op != opt.LeftJoinApplyOp {
		return nil
	}
	return (*LeftJoinApplyExpr)(e)
}

type RightJoinApplyExpr Expr

func MakeRightJoinApplyExpr(left GroupID, right GroupID, on GroupID) RightJoinApplyExpr {
	return RightJoinApplyExpr{op: opt.RightJoinApplyOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *RightJoinApplyExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *RightJoinApplyExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *RightJoinApplyExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *RightJoinApplyExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsRightJoinApply() *RightJoinApplyExpr {
	if e.op != opt.RightJoinApplyOp {
		return nil
	}
	return (*RightJoinApplyExpr)(e)
}

type FullJoinApplyExpr Expr

func MakeFullJoinApplyExpr(left GroupID, right GroupID, on GroupID) FullJoinApplyExpr {
	return FullJoinApplyExpr{op: opt.FullJoinApplyOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *FullJoinApplyExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *FullJoinApplyExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *FullJoinApplyExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *FullJoinApplyExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFullJoinApply() *FullJoinApplyExpr {
	if e.op != opt.FullJoinApplyOp {
		return nil
	}
	return (*FullJoinApplyExpr)(e)
}

type SemiJoinApplyExpr Expr

func MakeSemiJoinApplyExpr(left GroupID, right GroupID, on GroupID) SemiJoinApplyExpr {
	return SemiJoinApplyExpr{op: opt.SemiJoinApplyOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *SemiJoinApplyExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *SemiJoinApplyExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *SemiJoinApplyExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *SemiJoinApplyExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsSemiJoinApply() *SemiJoinApplyExpr {
	if e.op != opt.SemiJoinApplyOp {
		return nil
	}
	return (*SemiJoinApplyExpr)(e)
}

type AntiJoinApplyExpr Expr

func MakeAntiJoinApplyExpr(left GroupID, right GroupID, on GroupID) AntiJoinApplyExpr {
	return AntiJoinApplyExpr{op: opt.AntiJoinApplyOp, state: exprState{uint32(left), uint32(right), uint32(on)}}
}

func (e *AntiJoinApplyExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *AntiJoinApplyExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *AntiJoinApplyExpr) On() GroupID {
	return GroupID(e.state[2])
}

func (e *AntiJoinApplyExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAntiJoinApply() *AntiJoinApplyExpr {
	if e.op != opt.AntiJoinApplyOp {
		return nil
	}
	return (*AntiJoinApplyExpr)(e)
}

// GroupByExpr computes aggregate functions over groups of input rows. Input rows
// that are equal on the grouping columns are grouped together. The set of
// computed aggregate functions is described by the Aggregations field (which is
// always an Aggregations operator).
//
// The arguments of the aggregate functions are columns from the input
// (i.e. Variables), possibly wrapped in aggregate modifiers like AggDistinct.
//
// If the set of input rows is empty, then the output of the GroupBy operator
// will also be empty. If the grouping columns are empty, then all input rows
// form a single group. GroupBy is used for queries with aggregate functions,
// HAVING clauses and/or GROUP BY expressions.
//
// The Def private contains an ordering; this ordering is used to determine
// intra-group ordering and is only useful if there is an order-dependent
// aggregation (like ARRAY_AGG). Grouping columns are inconsequential in this
// ordering; we currently set all grouping columns as optional in this ordering
// (but note that this is not required by the operator).
type GroupByExpr Expr

func MakeGroupByExpr(input GroupID, aggregations GroupID, def PrivateID) GroupByExpr {
	return GroupByExpr{op: opt.GroupByOp, state: exprState{uint32(input), uint32(aggregations), uint32(def)}}
}

func (e *GroupByExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *GroupByExpr) Aggregations() GroupID {
	return GroupID(e.state[1])
}

func (e *GroupByExpr) Def() PrivateID {
	return PrivateID(e.state[2])
}

func (e *GroupByExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsGroupBy() *GroupByExpr {
	if e.op != opt.GroupByOp {
		return nil
	}
	return (*GroupByExpr)(e)
}

// ScalarGroupByExpr computes aggregate functions over the complete set of input
// rows. This is similar to GroupBy with empty grouping columns, where all input
// rows form a single group. However, there is an important difference. If the
// input set is empty, then the output of the ScalarGroupBy operator will have a
// single row containing default values for each aggregate function (typically
// null or zero, depending on the function). ScalarGroupBy always returns exactly
// one row - either the single-group aggregates or the default aggregate values.
//
// ScalarGroupBy uses the same GroupByDef private so that it's polymorphic with
// GroupBy and can be used in the same rules (when appropriate). In the
// ScalarGroupBy case, the grouping column field in GroupByDef is always empty.
type ScalarGroupByExpr Expr

func MakeScalarGroupByExpr(input GroupID, aggregations GroupID, def PrivateID) ScalarGroupByExpr {
	return ScalarGroupByExpr{op: opt.ScalarGroupByOp, state: exprState{uint32(input), uint32(aggregations), uint32(def)}}
}

func (e *ScalarGroupByExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ScalarGroupByExpr) Aggregations() GroupID {
	return GroupID(e.state[1])
}

func (e *ScalarGroupByExpr) Def() PrivateID {
	return PrivateID(e.state[2])
}

func (e *ScalarGroupByExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsScalarGroupBy() *ScalarGroupByExpr {
	if e.op != opt.ScalarGroupByOp {
		return nil
	}
	return (*ScalarGroupByExpr)(e)
}

// DistinctOnExpr filters out rows that are identical on the set of grouping columns;
// only the first row (according to an ordering) is kept for each set of possible
// values. It is roughly equivalent with a GroupBy on the same grouping columns
// except that it uses FirstAgg functions that ensure the value on the first row
// is chosen (across all aggregations).
//
// In addition, the value on that first row must be chosen for all the grouping
// columns as well; this is relevant in the case of equal but non-identical
// values, like decimals. For example, if we have rows (1, 2.0) and (1.0, 2) and
// we are grouping on these two columns, the values output can be either (1, 2.0)
// or (1.0, 2), but not (1.0, 2.0).
//
// The execution of DistinctOn resembles that of Select more than that of
// GroupBy: each row is tested against a map of what groups we have seen already,
// and is either passed through or discarded. In particular, note that this
// preserves the input ordering.
//
// The ordering in the private will be required of the input; it determines which
// row can get "chosen" for each group of values on the grouping columns.
// There is no restriction on the ordering; but note that grouping columns are
// inconsequential - they can appear anywhere in the ordering and they won't
// change the results (other than the result ordering).
//
// Currently when we build DistinctOn, we set all grouping columns as optional
// cols in Ordering (but this is not required by the operator).
//
// TODO(radu): in the future we may want an exploration transform to try out more
// specific interesting orderings because execution is more efficient when we can
// rely on an ordering on the grouping columns (or a subset of them).
//
// DistinctOn uses an Aggregations child and the GroupByDef private so that it's
// polymorphic with GroupBy and can be used in the same rules (when appropriate).
// In the DistinctOn case, the aggregations can be only FirstAgg or ConstAgg.
type DistinctOnExpr Expr

func MakeDistinctOnExpr(input GroupID, aggregations GroupID, def PrivateID) DistinctOnExpr {
	return DistinctOnExpr{op: opt.DistinctOnOp, state: exprState{uint32(input), uint32(aggregations), uint32(def)}}
}

func (e *DistinctOnExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *DistinctOnExpr) Aggregations() GroupID {
	return GroupID(e.state[1])
}

func (e *DistinctOnExpr) Def() PrivateID {
	return PrivateID(e.state[2])
}

func (e *DistinctOnExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsDistinctOn() *DistinctOnExpr {
	if e.op != opt.DistinctOnOp {
		return nil
	}
	return (*DistinctOnExpr)(e)
}

// UnionExpr is an operator used to combine the Left and Right input relations into
// a single set containing rows from both inputs. Duplicate rows are discarded.
// The private field, ColMap, matches columns from the Left and Right inputs
// of the Union with the output columns. See the comment above opt.SetOpColMap
// for more details.
type UnionExpr Expr

func MakeUnionExpr(left GroupID, right GroupID, colMap PrivateID) UnionExpr {
	return UnionExpr{op: opt.UnionOp, state: exprState{uint32(left), uint32(right), uint32(colMap)}}
}

func (e *UnionExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *UnionExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *UnionExpr) ColMap() PrivateID {
	return PrivateID(e.state[2])
}

func (e *UnionExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsUnion() *UnionExpr {
	if e.op != opt.UnionOp {
		return nil
	}
	return (*UnionExpr)(e)
}

// IntersectExpr is an operator used to perform an intersection between the Left
// and Right input relations. The result consists only of rows in the Left
// relation that are also present in the Right relation. Duplicate rows are
// discarded.
// The private field, ColMap, matches columns from the Left and Right inputs
// of the Intersect with the output columns. See the comment above
// opt.SetOpColMap for more details.
type IntersectExpr Expr

func MakeIntersectExpr(left GroupID, right GroupID, colMap PrivateID) IntersectExpr {
	return IntersectExpr{op: opt.IntersectOp, state: exprState{uint32(left), uint32(right), uint32(colMap)}}
}

func (e *IntersectExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *IntersectExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *IntersectExpr) ColMap() PrivateID {
	return PrivateID(e.state[2])
}

func (e *IntersectExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsIntersect() *IntersectExpr {
	if e.op != opt.IntersectOp {
		return nil
	}
	return (*IntersectExpr)(e)
}

// ExceptExpr is an operator used to perform a set difference between the Left and
// Right input relations. The result consists only of rows in the Left relation
// that are not present in the Right relation. Duplicate rows are discarded.
// The private field, ColMap, matches columns from the Left and Right inputs
// of the Except with the output columns. See the comment above opt.SetOpColMap
// for more details.
type ExceptExpr Expr

func MakeExceptExpr(left GroupID, right GroupID, colMap PrivateID) ExceptExpr {
	return ExceptExpr{op: opt.ExceptOp, state: exprState{uint32(left), uint32(right), uint32(colMap)}}
}

func (e *ExceptExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *ExceptExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *ExceptExpr) ColMap() PrivateID {
	return PrivateID(e.state[2])
}

func (e *ExceptExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsExcept() *ExceptExpr {
	if e.op != opt.ExceptOp {
		return nil
	}
	return (*ExceptExpr)(e)
}

// UnionAllExpr is an operator used to combine the Left and Right input relations
// into a single set containing rows from both inputs. Duplicate rows are
// not discarded. For example:
//   SELECT x FROM xx UNION ALL SELECT y FROM yy
//     x       y         out
//   -----   -----      -----
//     1       1          1
//     1       2    ->    1
//     2       3          1
//                        2
//                        2
//                        3
//
// The private field, ColMap, matches columns from the Left and Right inputs
// of the UnionAll with the output columns. See the comment above
// opt.SetOpColMap for more details.
type UnionAllExpr Expr

func MakeUnionAllExpr(left GroupID, right GroupID, colMap PrivateID) UnionAllExpr {
	return UnionAllExpr{op: opt.UnionAllOp, state: exprState{uint32(left), uint32(right), uint32(colMap)}}
}

func (e *UnionAllExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *UnionAllExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *UnionAllExpr) ColMap() PrivateID {
	return PrivateID(e.state[2])
}

func (e *UnionAllExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsUnionAll() *UnionAllExpr {
	if e.op != opt.UnionAllOp {
		return nil
	}
	return (*UnionAllExpr)(e)
}

// IntersectAllExpr is an operator used to perform an intersection between the Left
// and Right input relations. The result consists only of rows in the Left
// relation that have a corresponding row in the Right relation. Duplicate rows
// are not discarded. This effectively creates a one-to-one mapping between the
// Left and Right rows. For example:
//   SELECT x FROM xx INTERSECT ALL SELECT y FROM yy
//     x       y         out
//   -----   -----      -----
//     1       1          1
//     1       1    ->    1
//     1       2          2
//     2       2          2
//     2       3
//     4
//
// The private field, ColMap, matches columns from the Left and Right inputs
// of the IntersectAll with the output columns. See the comment above
// opt.SetOpColMap for more details.
type IntersectAllExpr Expr

func MakeIntersectAllExpr(left GroupID, right GroupID, colMap PrivateID) IntersectAllExpr {
	return IntersectAllExpr{op: opt.IntersectAllOp, state: exprState{uint32(left), uint32(right), uint32(colMap)}}
}

func (e *IntersectAllExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *IntersectAllExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *IntersectAllExpr) ColMap() PrivateID {
	return PrivateID(e.state[2])
}

func (e *IntersectAllExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsIntersectAll() *IntersectAllExpr {
	if e.op != opt.IntersectAllOp {
		return nil
	}
	return (*IntersectAllExpr)(e)
}

// ExceptAllExpr is an operator used to perform a set difference between the Left
// and Right input relations. The result consists only of rows in the Left
// relation that do not have a corresponding row in the Right relation.
// Duplicate rows are not discarded. This effectively creates a one-to-one
// mapping between the Left and Right rows. For example:
//   SELECT x FROM xx EXCEPT ALL SELECT y FROM yy
//     x       y         out
//   -----   -----      -----
//     1       1    ->    1
//     1       1          4
//     1       2
//     2       2
//     2       3
//     4
//
// The private field, ColMap, matches columns from the Left and Right inputs
// of the ExceptAll with the output columns. See the comment above
// opt.SetOpColMap for more details.
type ExceptAllExpr Expr

func MakeExceptAllExpr(left GroupID, right GroupID, colMap PrivateID) ExceptAllExpr {
	return ExceptAllExpr{op: opt.ExceptAllOp, state: exprState{uint32(left), uint32(right), uint32(colMap)}}
}

func (e *ExceptAllExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *ExceptAllExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *ExceptAllExpr) ColMap() PrivateID {
	return PrivateID(e.state[2])
}

func (e *ExceptAllExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsExceptAll() *ExceptAllExpr {
	if e.op != opt.ExceptAllOp {
		return nil
	}
	return (*ExceptAllExpr)(e)
}

// LimitExpr returns a limited subset of the results in the input relation.
// The limit expression is a scalar value; the operator returns at most this many
// rows. The private field is a props.OrderingChoice which indicates the row
// ordering required from the input (the first rows with respect to this ordering
// are returned).
type LimitExpr Expr

func MakeLimitExpr(input GroupID, limit GroupID, ordering PrivateID) LimitExpr {
	return LimitExpr{op: opt.LimitOp, state: exprState{uint32(input), uint32(limit), uint32(ordering)}}
}

func (e *LimitExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *LimitExpr) Limit() GroupID {
	return GroupID(e.state[1])
}

func (e *LimitExpr) Ordering() PrivateID {
	return PrivateID(e.state[2])
}

func (e *LimitExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsLimit() *LimitExpr {
	if e.op != opt.LimitOp {
		return nil
	}
	return (*LimitExpr)(e)
}

// OffsetExpr filters out the first Offset rows of the input relation; used in
// conjunction with Limit.
type OffsetExpr Expr

func MakeOffsetExpr(input GroupID, offset GroupID, ordering PrivateID) OffsetExpr {
	return OffsetExpr{op: opt.OffsetOp, state: exprState{uint32(input), uint32(offset), uint32(ordering)}}
}

func (e *OffsetExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *OffsetExpr) Offset() GroupID {
	return GroupID(e.state[1])
}

func (e *OffsetExpr) Ordering() PrivateID {
	return PrivateID(e.state[2])
}

func (e *OffsetExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsOffset() *OffsetExpr {
	if e.op != opt.OffsetOp {
		return nil
	}
	return (*OffsetExpr)(e)
}

// Max1RowExpr enforces that its input must return at most one row. It is used as
// input to the Subquery operator. See the comment above Subquery for more
// details.
type Max1RowExpr Expr

func MakeMax1RowExpr(input GroupID) Max1RowExpr {
	return Max1RowExpr{op: opt.Max1RowOp, state: exprState{uint32(input)}}
}

func (e *Max1RowExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *Max1RowExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsMax1Row() *Max1RowExpr {
	if e.op != opt.Max1RowOp {
		return nil
	}
	return (*Max1RowExpr)(e)
}

// ExplainExpr returns information about the execution plan of the "input"
// expression.
type ExplainExpr Expr

func MakeExplainExpr(input GroupID, def PrivateID) ExplainExpr {
	return ExplainExpr{op: opt.ExplainOp, state: exprState{uint32(input), uint32(def)}}
}

func (e *ExplainExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ExplainExpr) Def() PrivateID {
	return PrivateID(e.state[1])
}

func (e *ExplainExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsExplain() *ExplainExpr {
	if e.op != opt.ExplainOp {
		return nil
	}
	return (*ExplainExpr)(e)
}

// ShowTraceForSessionExpr returns the current session traces.
type ShowTraceForSessionExpr Expr

func MakeShowTraceForSessionExpr(def PrivateID) ShowTraceForSessionExpr {
	return ShowTraceForSessionExpr{op: opt.ShowTraceForSessionOp, state: exprState{uint32(def)}}
}

func (e *ShowTraceForSessionExpr) Def() PrivateID {
	return PrivateID(e.state[0])
}

func (e *ShowTraceForSessionExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsShowTraceForSession() *ShowTraceForSessionExpr {
	if e.op != opt.ShowTraceForSessionOp {
		return nil
	}
	return (*ShowTraceForSessionExpr)(e)
}

// RowNumberExpr adds a column to each row in its input containing a unique,
// increasing number.
type RowNumberExpr Expr

func MakeRowNumberExpr(input GroupID, def PrivateID) RowNumberExpr {
	return RowNumberExpr{op: opt.RowNumberOp, state: exprState{uint32(input), uint32(def)}}
}

func (e *RowNumberExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *RowNumberExpr) Def() PrivateID {
	return PrivateID(e.state[1])
}

func (e *RowNumberExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsRowNumber() *RowNumberExpr {
	if e.op != opt.RowNumberOp {
		return nil
	}
	return (*RowNumberExpr)(e)
}

// ZipExpr represents a functional zip over generators a,b,c, which returns tuples of
// values from a,b,c picked "simultaneously". NULLs are used when a generator is
// "shorter" than another. In SQL, these generators can be either a generator
// function such as generate_series(), or a scalar function such as
// upper(). For example, consider this query:
//
//    SELECT * FROM ROWS FROM (generate_series(0, 1), upper('abc'));
//
// It is equivalent to (Zip [(Function generate_series), (Function upper)]).
// It produces:
//
//     generate_series | upper
//    -----------------+-------
//                   0 | ABC
//                   1 | NULL
//
// In the Zip operation, Funcs represents the list of functions, and Cols
// represents the columns output by the functions. Funcs and Cols might not be
// the same length since a single function may output multiple columns
// (e.g., pg_get_keywords() outputs three columns).
type ZipExpr Expr

func MakeZipExpr(funcs ListID, cols PrivateID) ZipExpr {
	return ZipExpr{op: opt.ZipOp, state: exprState{funcs.Offset, funcs.Length, uint32(cols)}}
}

func (e *ZipExpr) Funcs() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *ZipExpr) Cols() PrivateID {
	return PrivateID(e.state[2])
}

func (e *ZipExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsZip() *ZipExpr {
	if e.op != opt.ZipOp {
		return nil
	}
	return (*ZipExpr)(e)
}

// SubqueryExpr is a subquery in a single-row context. Here are some examples:
//
//   SELECT 1 = (SELECT 1)
//   SELECT (1, 'a') = (SELECT 1, 'a')`
//
// In a single-row context, the outer query is only valid if the subquery returns
// at most one row. Subqueries in a multi-row context can be transformed to a
// single row context using the Any operator. See the comment above the Any
// operator for more details.
//
// The Input field contains the subquery itself, which should be wrapped in a
// Max1Row operator to enforce that the subquery can return at most one row
// (Max1Row may be removed by the optimizer later if it can determine statically
// that the subquery will always return at most one row). In addition, the
// subquery must project exactly one output column. If the subquery returns one
// row, then that column is bound to the single column value in that row. If the
// subquery returns zero rows, then that column is bound to NULL.
type SubqueryExpr Expr

func MakeSubqueryExpr(input GroupID, def PrivateID) SubqueryExpr {
	return SubqueryExpr{op: opt.SubqueryOp, state: exprState{uint32(input), uint32(def)}}
}

func (e *SubqueryExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *SubqueryExpr) Def() PrivateID {
	return PrivateID(e.state[1])
}

func (e *SubqueryExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsSubquery() *SubqueryExpr {
	if e.op != opt.SubqueryOp {
		return nil
	}
	return (*SubqueryExpr)(e)
}

// AnyExpr is a SQL operator that applies a comparison to every row of an input
// subquery and returns true if any of the comparisons are true, else returns
// null if any of the comparisons are null, else returns false. The following
// transformations map from various SQL operators into the Any operator:
//
//   <scalar> IN (<subquery>)
//   ==> (Any <subquery> <scalar> EqOp)
//
//   <scalar> NOT IN (<subquery>)
//   ==> (Not (Any <subquery> <scalar> EqOp))
//
//   <scalar> <comp> {SOME|ANY}(<subquery>)
//   ==> (Any <subquery> <scalar> <comp>)
//
//   <scalar> <comp> ALL(<subquery>)
//   ==> (Not (Any <subquery> <scalar> <negated-comp>))
//
// Any expects the input subquery to return a single column of any data type. The
// scalar value is compared with that column using the specified comparison
// operator.
type AnyExpr Expr

func MakeAnyExpr(input GroupID, scalar GroupID, def PrivateID) AnyExpr {
	return AnyExpr{op: opt.AnyOp, state: exprState{uint32(input), uint32(scalar), uint32(def)}}
}

func (e *AnyExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *AnyExpr) Scalar() GroupID {
	return GroupID(e.state[1])
}

func (e *AnyExpr) Def() PrivateID {
	return PrivateID(e.state[2])
}

func (e *AnyExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAny() *AnyExpr {
	if e.op != opt.AnyOp {
		return nil
	}
	return (*AnyExpr)(e)
}

// VariableExpr is the typed scalar value of a column in the query. The private
// field is a Metadata.ColumnID that references the column by index.
type VariableExpr Expr

func MakeVariableExpr(col PrivateID) VariableExpr {
	return VariableExpr{op: opt.VariableOp, state: exprState{uint32(col)}}
}

func (e *VariableExpr) Col() PrivateID {
	return PrivateID(e.state[0])
}

func (e *VariableExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsVariable() *VariableExpr {
	if e.op != opt.VariableOp {
		return nil
	}
	return (*VariableExpr)(e)
}

// ConstExpr is a typed scalar constant value. The private field is a tree.Datum
// value having any datum type that's legal in the expression's context.
type ConstExpr Expr

func MakeConstExpr(value PrivateID) ConstExpr {
	return ConstExpr{op: opt.ConstOp, state: exprState{uint32(value)}}
}

func (e *ConstExpr) Value() PrivateID {
	return PrivateID(e.state[0])
}

func (e *ConstExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsConst() *ConstExpr {
	if e.op != opt.ConstOp {
		return nil
	}
	return (*ConstExpr)(e)
}

// NullExpr is the constant SQL null value that has "unknown value" semantics. If
// the Typ field is not types.Unknown, then the value is known to be in the
// domain of that type. This is important for preserving correct types in
// replacement patterns. For example:
//   (Plus (Function ...) (Const 1))
//
// If the function in that expression has a static type of Int, but then it gets
// constant folded to (Null), then its type must remain as Int. Any other type
// violates logical equivalence of the expression, breaking type inference and
// possibly changing the results of execution. The solution is to tag the null
// with the correct type:
//   (Plus (Null (Int)) (Const 1))
//
// Null is its own operator rather than a Const datum in order to make matching
// and replacement easier and more efficient, as patterns can contain (Null)
// expressions.
type NullExpr Expr

func MakeNullExpr(typ PrivateID) NullExpr {
	return NullExpr{op: opt.NullOp, state: exprState{uint32(typ)}}
}

func (e *NullExpr) Typ() PrivateID {
	return PrivateID(e.state[0])
}

func (e *NullExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNull() *NullExpr {
	if e.op != opt.NullOp {
		return nil
	}
	return (*NullExpr)(e)
}

// TrueExpr is the boolean true value that is equivalent to the tree.DBoolTrue datum
// value. It is a separate operator to make matching and replacement simpler and
// more efficient, as patterns can contain (True) expressions.
type TrueExpr Expr

func MakeTrueExpr() TrueExpr {
	return TrueExpr{op: opt.TrueOp, state: exprState{}}
}

func (e *TrueExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsTrue() *TrueExpr {
	if e.op != opt.TrueOp {
		return nil
	}
	return (*TrueExpr)(e)
}

// FalseExpr is the boolean false value that is equivalent to the tree.DBoolFalse
// datum value. It is a separate operator to make matching and replacement
// simpler and more efficient, as patterns can contain (False) expressions.
type FalseExpr Expr

func MakeFalseExpr() FalseExpr {
	return FalseExpr{op: opt.FalseOp, state: exprState{}}
}

func (e *FalseExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFalse() *FalseExpr {
	if e.op != opt.FalseOp {
		return nil
	}
	return (*FalseExpr)(e)
}

type PlaceholderExpr Expr

func MakePlaceholderExpr(value PrivateID) PlaceholderExpr {
	return PlaceholderExpr{op: opt.PlaceholderOp, state: exprState{uint32(value)}}
}

func (e *PlaceholderExpr) Value() PrivateID {
	return PrivateID(e.state[0])
}

func (e *PlaceholderExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsPlaceholder() *PlaceholderExpr {
	if e.op != opt.PlaceholderOp {
		return nil
	}
	return (*PlaceholderExpr)(e)
}

type TupleExpr Expr

func MakeTupleExpr(elems ListID, typ PrivateID) TupleExpr {
	return TupleExpr{op: opt.TupleOp, state: exprState{elems.Offset, elems.Length, uint32(typ)}}
}

func (e *TupleExpr) Elems() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *TupleExpr) Typ() PrivateID {
	return PrivateID(e.state[2])
}

func (e *TupleExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsTuple() *TupleExpr {
	if e.op != opt.TupleOp {
		return nil
	}
	return (*TupleExpr)(e)
}

// ProjectionsExpr is a set of typed scalar expressions that will become output
// columns for a containing Project operator.
//
// The private Defs field contains the list of column indexes returned by each
// expression, and a list of pass-through columns.
//
// Elems cannot contain a simple VariableOp with the same ColumnID as the
// synthesized column (in Def.SynthesizedCols); that is a pass-through column.
// Elems can contain a VariableOp when a new ColumnID is being assigned, such as
// in the case of an outer column reference.
type ProjectionsExpr Expr

func MakeProjectionsExpr(elems ListID, def PrivateID) ProjectionsExpr {
	return ProjectionsExpr{op: opt.ProjectionsOp, state: exprState{elems.Offset, elems.Length, uint32(def)}}
}

func (e *ProjectionsExpr) Elems() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *ProjectionsExpr) Def() PrivateID {
	return PrivateID(e.state[2])
}

func (e *ProjectionsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsProjections() *ProjectionsExpr {
	if e.op != opt.ProjectionsOp {
		return nil
	}
	return (*ProjectionsExpr)(e)
}

// AggregationsExpr is a set of aggregate expressions that will become output columns
// for a containing GroupBy operator. The expressions can only consist of
// aggregate functions, variable references, and modifiers like AggDistinct.
// Examples of valid expressions:
//   (Min (Variable 1))
//   (Count (AggDistinct (Variable 1)))
//
// More complex arguments must be formulated using a Project operator as input to
// the GroupBy operator.
//
// The private Cols field contains the list of column indexes returned by the
// expression, as an opt.ColList. It is legal for Cols to be empty.
type AggregationsExpr Expr

func MakeAggregationsExpr(aggs ListID, cols PrivateID) AggregationsExpr {
	return AggregationsExpr{op: opt.AggregationsOp, state: exprState{aggs.Offset, aggs.Length, uint32(cols)}}
}

func (e *AggregationsExpr) Aggs() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *AggregationsExpr) Cols() PrivateID {
	return PrivateID(e.state[2])
}

func (e *AggregationsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAggregations() *AggregationsExpr {
	if e.op != opt.AggregationsOp {
		return nil
	}
	return (*AggregationsExpr)(e)
}

// MergeOnExpr contains the ON condition and the metadata for a merge join; it is
// always a child of MergeJoin.
type MergeOnExpr Expr

func MakeMergeOnExpr(on GroupID, def PrivateID) MergeOnExpr {
	return MergeOnExpr{op: opt.MergeOnOp, state: exprState{uint32(on), uint32(def)}}
}

func (e *MergeOnExpr) On() GroupID {
	return GroupID(e.state[0])
}

func (e *MergeOnExpr) Def() PrivateID {
	return PrivateID(e.state[1])
}

func (e *MergeOnExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsMergeOn() *MergeOnExpr {
	if e.op != opt.MergeOnOp {
		return nil
	}
	return (*MergeOnExpr)(e)
}

// ExistsExpr takes a relational query as its input, and evaluates to true if the
// query returns at least one row.
type ExistsExpr Expr

func MakeExistsExpr(input GroupID, def PrivateID) ExistsExpr {
	return ExistsExpr{op: opt.ExistsOp, state: exprState{uint32(input), uint32(def)}}
}

func (e *ExistsExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ExistsExpr) Def() PrivateID {
	return PrivateID(e.state[1])
}

func (e *ExistsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsExists() *ExistsExpr {
	if e.op != opt.ExistsOp {
		return nil
	}
	return (*ExistsExpr)(e)
}

// FiltersExpr is a boolean And operator that only appears as the Filters child of
// a Select operator, or the On child of a Join operator. For example:
//   (Select
//     (Scan a)
//     (Filters (Gt (Variable a) 1) (Lt (Variable a) 5))
//   )
//
// Normalization rules ensure that a Filters expression is always created if
// there is at least one condition, so that other rules can rely on its presence
// when matching, even in the case where there is only one condition. The
// semantics of the Filters operator are identical to those of the And operator.
type FiltersExpr Expr

func MakeFiltersExpr(conditions ListID) FiltersExpr {
	return FiltersExpr{op: opt.FiltersOp, state: exprState{conditions.Offset, conditions.Length}}
}

func (e *FiltersExpr) Conditions() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *FiltersExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFilters() *FiltersExpr {
	if e.op != opt.FiltersOp {
		return nil
	}
	return (*FiltersExpr)(e)
}

// AndExpr is the boolean conjunction operator that evalutes to true if all of its
// conditions evaluate to true. If the conditions list is empty, it evalutes to
// true.
type AndExpr Expr

func MakeAndExpr(conditions ListID) AndExpr {
	return AndExpr{op: opt.AndOp, state: exprState{conditions.Offset, conditions.Length}}
}

func (e *AndExpr) Conditions() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *AndExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAnd() *AndExpr {
	if e.op != opt.AndOp {
		return nil
	}
	return (*AndExpr)(e)
}

// OrExpr is the boolean disjunction operator that evalutes to true if any of its
// conditions evaluate to true. If the conditions list is empty, it evaluates to
// false.
type OrExpr Expr

func MakeOrExpr(conditions ListID) OrExpr {
	return OrExpr{op: opt.OrOp, state: exprState{conditions.Offset, conditions.Length}}
}

func (e *OrExpr) Conditions() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *OrExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsOr() *OrExpr {
	if e.op != opt.OrOp {
		return nil
	}
	return (*OrExpr)(e)
}

// NotExpr is the boolean negation operator that evaluates to true if its input
// evalutes to false.
type NotExpr Expr

func MakeNotExpr(input GroupID) NotExpr {
	return NotExpr{op: opt.NotOp, state: exprState{uint32(input)}}
}

func (e *NotExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *NotExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNot() *NotExpr {
	if e.op != opt.NotOp {
		return nil
	}
	return (*NotExpr)(e)
}

type EqExpr Expr

func MakeEqExpr(left GroupID, right GroupID) EqExpr {
	return EqExpr{op: opt.EqOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *EqExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *EqExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *EqExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsEq() *EqExpr {
	if e.op != opt.EqOp {
		return nil
	}
	return (*EqExpr)(e)
}

type LtExpr Expr

func MakeLtExpr(left GroupID, right GroupID) LtExpr {
	return LtExpr{op: opt.LtOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *LtExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *LtExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *LtExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsLt() *LtExpr {
	if e.op != opt.LtOp {
		return nil
	}
	return (*LtExpr)(e)
}

type GtExpr Expr

func MakeGtExpr(left GroupID, right GroupID) GtExpr {
	return GtExpr{op: opt.GtOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *GtExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *GtExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *GtExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsGt() *GtExpr {
	if e.op != opt.GtOp {
		return nil
	}
	return (*GtExpr)(e)
}

type LeExpr Expr

func MakeLeExpr(left GroupID, right GroupID) LeExpr {
	return LeExpr{op: opt.LeOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *LeExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *LeExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *LeExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsLe() *LeExpr {
	if e.op != opt.LeOp {
		return nil
	}
	return (*LeExpr)(e)
}

type GeExpr Expr

func MakeGeExpr(left GroupID, right GroupID) GeExpr {
	return GeExpr{op: opt.GeOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *GeExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *GeExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *GeExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsGe() *GeExpr {
	if e.op != opt.GeOp {
		return nil
	}
	return (*GeExpr)(e)
}

type NeExpr Expr

func MakeNeExpr(left GroupID, right GroupID) NeExpr {
	return NeExpr{op: opt.NeOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *NeExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *NeExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *NeExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNe() *NeExpr {
	if e.op != opt.NeOp {
		return nil
	}
	return (*NeExpr)(e)
}

type InExpr Expr

func MakeInExpr(left GroupID, right GroupID) InExpr {
	return InExpr{op: opt.InOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *InExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *InExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *InExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsIn() *InExpr {
	if e.op != opt.InOp {
		return nil
	}
	return (*InExpr)(e)
}

type NotInExpr Expr

func MakeNotInExpr(left GroupID, right GroupID) NotInExpr {
	return NotInExpr{op: opt.NotInOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *NotInExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *NotInExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *NotInExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNotIn() *NotInExpr {
	if e.op != opt.NotInOp {
		return nil
	}
	return (*NotInExpr)(e)
}

type LikeExpr Expr

func MakeLikeExpr(left GroupID, right GroupID) LikeExpr {
	return LikeExpr{op: opt.LikeOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *LikeExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *LikeExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *LikeExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsLike() *LikeExpr {
	if e.op != opt.LikeOp {
		return nil
	}
	return (*LikeExpr)(e)
}

type NotLikeExpr Expr

func MakeNotLikeExpr(left GroupID, right GroupID) NotLikeExpr {
	return NotLikeExpr{op: opt.NotLikeOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *NotLikeExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *NotLikeExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *NotLikeExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNotLike() *NotLikeExpr {
	if e.op != opt.NotLikeOp {
		return nil
	}
	return (*NotLikeExpr)(e)
}

type ILikeExpr Expr

func MakeILikeExpr(left GroupID, right GroupID) ILikeExpr {
	return ILikeExpr{op: opt.ILikeOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *ILikeExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *ILikeExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *ILikeExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsILike() *ILikeExpr {
	if e.op != opt.ILikeOp {
		return nil
	}
	return (*ILikeExpr)(e)
}

type NotILikeExpr Expr

func MakeNotILikeExpr(left GroupID, right GroupID) NotILikeExpr {
	return NotILikeExpr{op: opt.NotILikeOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *NotILikeExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *NotILikeExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *NotILikeExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNotILike() *NotILikeExpr {
	if e.op != opt.NotILikeOp {
		return nil
	}
	return (*NotILikeExpr)(e)
}

type SimilarToExpr Expr

func MakeSimilarToExpr(left GroupID, right GroupID) SimilarToExpr {
	return SimilarToExpr{op: opt.SimilarToOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *SimilarToExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *SimilarToExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *SimilarToExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsSimilarTo() *SimilarToExpr {
	if e.op != opt.SimilarToOp {
		return nil
	}
	return (*SimilarToExpr)(e)
}

type NotSimilarToExpr Expr

func MakeNotSimilarToExpr(left GroupID, right GroupID) NotSimilarToExpr {
	return NotSimilarToExpr{op: opt.NotSimilarToOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *NotSimilarToExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *NotSimilarToExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *NotSimilarToExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNotSimilarTo() *NotSimilarToExpr {
	if e.op != opt.NotSimilarToOp {
		return nil
	}
	return (*NotSimilarToExpr)(e)
}

type RegMatchExpr Expr

func MakeRegMatchExpr(left GroupID, right GroupID) RegMatchExpr {
	return RegMatchExpr{op: opt.RegMatchOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *RegMatchExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *RegMatchExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *RegMatchExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsRegMatch() *RegMatchExpr {
	if e.op != opt.RegMatchOp {
		return nil
	}
	return (*RegMatchExpr)(e)
}

type NotRegMatchExpr Expr

func MakeNotRegMatchExpr(left GroupID, right GroupID) NotRegMatchExpr {
	return NotRegMatchExpr{op: opt.NotRegMatchOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *NotRegMatchExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *NotRegMatchExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *NotRegMatchExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNotRegMatch() *NotRegMatchExpr {
	if e.op != opt.NotRegMatchOp {
		return nil
	}
	return (*NotRegMatchExpr)(e)
}

type RegIMatchExpr Expr

func MakeRegIMatchExpr(left GroupID, right GroupID) RegIMatchExpr {
	return RegIMatchExpr{op: opt.RegIMatchOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *RegIMatchExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *RegIMatchExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *RegIMatchExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsRegIMatch() *RegIMatchExpr {
	if e.op != opt.RegIMatchOp {
		return nil
	}
	return (*RegIMatchExpr)(e)
}

type NotRegIMatchExpr Expr

func MakeNotRegIMatchExpr(left GroupID, right GroupID) NotRegIMatchExpr {
	return NotRegIMatchExpr{op: opt.NotRegIMatchOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *NotRegIMatchExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *NotRegIMatchExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *NotRegIMatchExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsNotRegIMatch() *NotRegIMatchExpr {
	if e.op != opt.NotRegIMatchOp {
		return nil
	}
	return (*NotRegIMatchExpr)(e)
}

type IsExpr Expr

func MakeIsExpr(left GroupID, right GroupID) IsExpr {
	return IsExpr{op: opt.IsOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *IsExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *IsExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *IsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsIs() *IsExpr {
	if e.op != opt.IsOp {
		return nil
	}
	return (*IsExpr)(e)
}

type IsNotExpr Expr

func MakeIsNotExpr(left GroupID, right GroupID) IsNotExpr {
	return IsNotExpr{op: opt.IsNotOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *IsNotExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *IsNotExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *IsNotExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsIsNot() *IsNotExpr {
	if e.op != opt.IsNotOp {
		return nil
	}
	return (*IsNotExpr)(e)
}

type ContainsExpr Expr

func MakeContainsExpr(left GroupID, right GroupID) ContainsExpr {
	return ContainsExpr{op: opt.ContainsOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *ContainsExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *ContainsExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *ContainsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsContains() *ContainsExpr {
	if e.op != opt.ContainsOp {
		return nil
	}
	return (*ContainsExpr)(e)
}

type JsonExistsExpr Expr

func MakeJsonExistsExpr(left GroupID, right GroupID) JsonExistsExpr {
	return JsonExistsExpr{op: opt.JsonExistsOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *JsonExistsExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *JsonExistsExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *JsonExistsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsJsonExists() *JsonExistsExpr {
	if e.op != opt.JsonExistsOp {
		return nil
	}
	return (*JsonExistsExpr)(e)
}

type JsonAllExistsExpr Expr

func MakeJsonAllExistsExpr(left GroupID, right GroupID) JsonAllExistsExpr {
	return JsonAllExistsExpr{op: opt.JsonAllExistsOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *JsonAllExistsExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *JsonAllExistsExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *JsonAllExistsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsJsonAllExists() *JsonAllExistsExpr {
	if e.op != opt.JsonAllExistsOp {
		return nil
	}
	return (*JsonAllExistsExpr)(e)
}

type JsonSomeExistsExpr Expr

func MakeJsonSomeExistsExpr(left GroupID, right GroupID) JsonSomeExistsExpr {
	return JsonSomeExistsExpr{op: opt.JsonSomeExistsOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *JsonSomeExistsExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *JsonSomeExistsExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *JsonSomeExistsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsJsonSomeExists() *JsonSomeExistsExpr {
	if e.op != opt.JsonSomeExistsOp {
		return nil
	}
	return (*JsonSomeExistsExpr)(e)
}

// AnyScalarExpr is the form of ANY which refers to an ANY operation on a
// tuple or array, as opposed to Any which operates on a subquery.
type AnyScalarExpr Expr

func MakeAnyScalarExpr(left GroupID, right GroupID, cmp PrivateID) AnyScalarExpr {
	return AnyScalarExpr{op: opt.AnyScalarOp, state: exprState{uint32(left), uint32(right), uint32(cmp)}}
}

func (e *AnyScalarExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *AnyScalarExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *AnyScalarExpr) Cmp() PrivateID {
	return PrivateID(e.state[2])
}

func (e *AnyScalarExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAnyScalar() *AnyScalarExpr {
	if e.op != opt.AnyScalarOp {
		return nil
	}
	return (*AnyScalarExpr)(e)
}

type BitandExpr Expr

func MakeBitandExpr(left GroupID, right GroupID) BitandExpr {
	return BitandExpr{op: opt.BitandOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *BitandExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *BitandExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *BitandExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsBitand() *BitandExpr {
	if e.op != opt.BitandOp {
		return nil
	}
	return (*BitandExpr)(e)
}

type BitorExpr Expr

func MakeBitorExpr(left GroupID, right GroupID) BitorExpr {
	return BitorExpr{op: opt.BitorOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *BitorExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *BitorExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *BitorExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsBitor() *BitorExpr {
	if e.op != opt.BitorOp {
		return nil
	}
	return (*BitorExpr)(e)
}

type BitxorExpr Expr

func MakeBitxorExpr(left GroupID, right GroupID) BitxorExpr {
	return BitxorExpr{op: opt.BitxorOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *BitxorExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *BitxorExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *BitxorExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsBitxor() *BitxorExpr {
	if e.op != opt.BitxorOp {
		return nil
	}
	return (*BitxorExpr)(e)
}

type PlusExpr Expr

func MakePlusExpr(left GroupID, right GroupID) PlusExpr {
	return PlusExpr{op: opt.PlusOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *PlusExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *PlusExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *PlusExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsPlus() *PlusExpr {
	if e.op != opt.PlusOp {
		return nil
	}
	return (*PlusExpr)(e)
}

type MinusExpr Expr

func MakeMinusExpr(left GroupID, right GroupID) MinusExpr {
	return MinusExpr{op: opt.MinusOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *MinusExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *MinusExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *MinusExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsMinus() *MinusExpr {
	if e.op != opt.MinusOp {
		return nil
	}
	return (*MinusExpr)(e)
}

type MultExpr Expr

func MakeMultExpr(left GroupID, right GroupID) MultExpr {
	return MultExpr{op: opt.MultOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *MultExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *MultExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *MultExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsMult() *MultExpr {
	if e.op != opt.MultOp {
		return nil
	}
	return (*MultExpr)(e)
}

type DivExpr Expr

func MakeDivExpr(left GroupID, right GroupID) DivExpr {
	return DivExpr{op: opt.DivOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *DivExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *DivExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *DivExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsDiv() *DivExpr {
	if e.op != opt.DivOp {
		return nil
	}
	return (*DivExpr)(e)
}

type FloorDivExpr Expr

func MakeFloorDivExpr(left GroupID, right GroupID) FloorDivExpr {
	return FloorDivExpr{op: opt.FloorDivOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *FloorDivExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *FloorDivExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *FloorDivExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFloorDiv() *FloorDivExpr {
	if e.op != opt.FloorDivOp {
		return nil
	}
	return (*FloorDivExpr)(e)
}

type ModExpr Expr

func MakeModExpr(left GroupID, right GroupID) ModExpr {
	return ModExpr{op: opt.ModOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *ModExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *ModExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *ModExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsMod() *ModExpr {
	if e.op != opt.ModOp {
		return nil
	}
	return (*ModExpr)(e)
}

type PowExpr Expr

func MakePowExpr(left GroupID, right GroupID) PowExpr {
	return PowExpr{op: opt.PowOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *PowExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *PowExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *PowExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsPow() *PowExpr {
	if e.op != opt.PowOp {
		return nil
	}
	return (*PowExpr)(e)
}

type ConcatExpr Expr

func MakeConcatExpr(left GroupID, right GroupID) ConcatExpr {
	return ConcatExpr{op: opt.ConcatOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *ConcatExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *ConcatExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *ConcatExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsConcat() *ConcatExpr {
	if e.op != opt.ConcatOp {
		return nil
	}
	return (*ConcatExpr)(e)
}

type LShiftExpr Expr

func MakeLShiftExpr(left GroupID, right GroupID) LShiftExpr {
	return LShiftExpr{op: opt.LShiftOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *LShiftExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *LShiftExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *LShiftExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsLShift() *LShiftExpr {
	if e.op != opt.LShiftOp {
		return nil
	}
	return (*LShiftExpr)(e)
}

type RShiftExpr Expr

func MakeRShiftExpr(left GroupID, right GroupID) RShiftExpr {
	return RShiftExpr{op: opt.RShiftOp, state: exprState{uint32(left), uint32(right)}}
}

func (e *RShiftExpr) Left() GroupID {
	return GroupID(e.state[0])
}

func (e *RShiftExpr) Right() GroupID {
	return GroupID(e.state[1])
}

func (e *RShiftExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsRShift() *RShiftExpr {
	if e.op != opt.RShiftOp {
		return nil
	}
	return (*RShiftExpr)(e)
}

type FetchValExpr Expr

func MakeFetchValExpr(json GroupID, index GroupID) FetchValExpr {
	return FetchValExpr{op: opt.FetchValOp, state: exprState{uint32(json), uint32(index)}}
}

func (e *FetchValExpr) Json() GroupID {
	return GroupID(e.state[0])
}

func (e *FetchValExpr) Index() GroupID {
	return GroupID(e.state[1])
}

func (e *FetchValExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFetchVal() *FetchValExpr {
	if e.op != opt.FetchValOp {
		return nil
	}
	return (*FetchValExpr)(e)
}

type FetchTextExpr Expr

func MakeFetchTextExpr(json GroupID, index GroupID) FetchTextExpr {
	return FetchTextExpr{op: opt.FetchTextOp, state: exprState{uint32(json), uint32(index)}}
}

func (e *FetchTextExpr) Json() GroupID {
	return GroupID(e.state[0])
}

func (e *FetchTextExpr) Index() GroupID {
	return GroupID(e.state[1])
}

func (e *FetchTextExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFetchText() *FetchTextExpr {
	if e.op != opt.FetchTextOp {
		return nil
	}
	return (*FetchTextExpr)(e)
}

type FetchValPathExpr Expr

func MakeFetchValPathExpr(json GroupID, path GroupID) FetchValPathExpr {
	return FetchValPathExpr{op: opt.FetchValPathOp, state: exprState{uint32(json), uint32(path)}}
}

func (e *FetchValPathExpr) Json() GroupID {
	return GroupID(e.state[0])
}

func (e *FetchValPathExpr) Path() GroupID {
	return GroupID(e.state[1])
}

func (e *FetchValPathExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFetchValPath() *FetchValPathExpr {
	if e.op != opt.FetchValPathOp {
		return nil
	}
	return (*FetchValPathExpr)(e)
}

type FetchTextPathExpr Expr

func MakeFetchTextPathExpr(json GroupID, path GroupID) FetchTextPathExpr {
	return FetchTextPathExpr{op: opt.FetchTextPathOp, state: exprState{uint32(json), uint32(path)}}
}

func (e *FetchTextPathExpr) Json() GroupID {
	return GroupID(e.state[0])
}

func (e *FetchTextPathExpr) Path() GroupID {
	return GroupID(e.state[1])
}

func (e *FetchTextPathExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFetchTextPath() *FetchTextPathExpr {
	if e.op != opt.FetchTextPathOp {
		return nil
	}
	return (*FetchTextPathExpr)(e)
}

type UnaryMinusExpr Expr

func MakeUnaryMinusExpr(input GroupID) UnaryMinusExpr {
	return UnaryMinusExpr{op: opt.UnaryMinusOp, state: exprState{uint32(input)}}
}

func (e *UnaryMinusExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *UnaryMinusExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsUnaryMinus() *UnaryMinusExpr {
	if e.op != opt.UnaryMinusOp {
		return nil
	}
	return (*UnaryMinusExpr)(e)
}

type UnaryComplementExpr Expr

func MakeUnaryComplementExpr(input GroupID) UnaryComplementExpr {
	return UnaryComplementExpr{op: opt.UnaryComplementOp, state: exprState{uint32(input)}}
}

func (e *UnaryComplementExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *UnaryComplementExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsUnaryComplement() *UnaryComplementExpr {
	if e.op != opt.UnaryComplementOp {
		return nil
	}
	return (*UnaryComplementExpr)(e)
}

// CastExpr converts the input expression into an expression of the target type.
// While the input's type is restricted to the datum types in the types package,
// the target type can be any of the column types in the coltypes package. For
// example, this is a legal cast:
//
//   'hello'::VARCHAR(2)
//
// That expression has the effect of truncating the string to just 'he', since
// the target data type allows a maximum of two characters. This is one example
// of a "lossy" cast.
type CastExpr Expr

func MakeCastExpr(input GroupID, targetTyp PrivateID) CastExpr {
	return CastExpr{op: opt.CastOp, state: exprState{uint32(input), uint32(targetTyp)}}
}

func (e *CastExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *CastExpr) TargetTyp() PrivateID {
	return PrivateID(e.state[1])
}

func (e *CastExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsCast() *CastExpr {
	if e.op != opt.CastOp {
		return nil
	}
	return (*CastExpr)(e)
}

// CaseExpr is a CASE statement of the form:
//   CASE [ <Input> ]
//       WHEN <condval1> THEN <expr1>
//     [ WHEN <condval2> THEN <expr2> ] ...
//     [ ELSE <expr> ]
//   END
//
// The Case operator evaluates <Input> (if not provided, Input is set to True),
// then picks the WHEN branch where <condval> is equal to
// <Input>, then evaluates and returns the corresponding THEN expression. If no
// WHEN branch matches, the ELSE expression is evaluated and returned, if any.
// Otherwise, NULL is returned.
//
// Note that the Whens list inside Case is used to represent all the WHEN
// branches as well as the ELSE statement if it exists. It is of the form:
// [(When <condval1> <expr1>),(When <condval2> <expr2>),...,<expr>]
type CaseExpr Expr

func MakeCaseExpr(input GroupID, whens ListID) CaseExpr {
	return CaseExpr{op: opt.CaseOp, state: exprState{uint32(input), whens.Offset, whens.Length}}
}

func (e *CaseExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *CaseExpr) Whens() ListID {
	return ListID{Offset: e.state[1], Length: e.state[2]}
}

func (e *CaseExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsCase() *CaseExpr {
	if e.op != opt.CaseOp {
		return nil
	}
	return (*CaseExpr)(e)
}

// WhenExpr represents a single WHEN ... THEN ... condition inside a CASE statement.
// It is the type of each list item in Whens (except for the last item which is
// a raw expression for the ELSE statement).
type WhenExpr Expr

func MakeWhenExpr(condition GroupID, value GroupID) WhenExpr {
	return WhenExpr{op: opt.WhenOp, state: exprState{uint32(condition), uint32(value)}}
}

func (e *WhenExpr) Condition() GroupID {
	return GroupID(e.state[0])
}

func (e *WhenExpr) Value() GroupID {
	return GroupID(e.state[1])
}

func (e *WhenExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsWhen() *WhenExpr {
	if e.op != opt.WhenOp {
		return nil
	}
	return (*WhenExpr)(e)
}

// ArrayExpr is an ARRAY literal of the form ARRAY[<expr1>, <expr2>, ..., <exprN>].
type ArrayExpr Expr

func MakeArrayExpr(elems ListID, typ PrivateID) ArrayExpr {
	return ArrayExpr{op: opt.ArrayOp, state: exprState{elems.Offset, elems.Length, uint32(typ)}}
}

func (e *ArrayExpr) Elems() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *ArrayExpr) Typ() PrivateID {
	return PrivateID(e.state[2])
}

func (e *ArrayExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsArray() *ArrayExpr {
	if e.op != opt.ArrayOp {
		return nil
	}
	return (*ArrayExpr)(e)
}

// FunctionExpr invokes a builtin SQL function like CONCAT or NOW, passing the given
// arguments. The private field is a *opt.FuncOpDef struct that provides the
// name of the function as well as a pointer to the builtin overload definition.
type FunctionExpr Expr

func MakeFunctionExpr(args ListID, def PrivateID) FunctionExpr {
	return FunctionExpr{op: opt.FunctionOp, state: exprState{args.Offset, args.Length, uint32(def)}}
}

func (e *FunctionExpr) Args() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *FunctionExpr) Def() PrivateID {
	return PrivateID(e.state[2])
}

func (e *FunctionExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFunction() *FunctionExpr {
	if e.op != opt.FunctionOp {
		return nil
	}
	return (*FunctionExpr)(e)
}

type CoalesceExpr Expr

func MakeCoalesceExpr(args ListID) CoalesceExpr {
	return CoalesceExpr{op: opt.CoalesceOp, state: exprState{args.Offset, args.Length}}
}

func (e *CoalesceExpr) Args() ListID {
	return ListID{Offset: e.state[0], Length: e.state[1]}
}

func (e *CoalesceExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsCoalesce() *CoalesceExpr {
	if e.op != opt.CoalesceOp {
		return nil
	}
	return (*CoalesceExpr)(e)
}

// ColumnAccessExpr is a scalar expression that returns a column from the given
// input expression (which is assumed to be of type Tuple). Idx is the ordinal
// index of the column in Input.
type ColumnAccessExpr Expr

func MakeColumnAccessExpr(input GroupID, idx PrivateID) ColumnAccessExpr {
	return ColumnAccessExpr{op: opt.ColumnAccessOp, state: exprState{uint32(input), uint32(idx)}}
}

func (e *ColumnAccessExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ColumnAccessExpr) Idx() PrivateID {
	return PrivateID(e.state[1])
}

func (e *ColumnAccessExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsColumnAccess() *ColumnAccessExpr {
	if e.op != opt.ColumnAccessOp {
		return nil
	}
	return (*ColumnAccessExpr)(e)
}

// UnsupportedExprExpr is used for interfacing with the old planner code. It can
// encapsulate a TypedExpr that is otherwise not supported by the optimizer.
type UnsupportedExprExpr Expr

func MakeUnsupportedExprExpr(value PrivateID) UnsupportedExprExpr {
	return UnsupportedExprExpr{op: opt.UnsupportedExprOp, state: exprState{uint32(value)}}
}

func (e *UnsupportedExprExpr) Value() PrivateID {
	return PrivateID(e.state[0])
}

func (e *UnsupportedExprExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsUnsupportedExpr() *UnsupportedExprExpr {
	if e.op != opt.UnsupportedExprOp {
		return nil
	}
	return (*UnsupportedExprExpr)(e)
}

type ArrayAggExpr Expr

func MakeArrayAggExpr(input GroupID) ArrayAggExpr {
	return ArrayAggExpr{op: opt.ArrayAggOp, state: exprState{uint32(input)}}
}

func (e *ArrayAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ArrayAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsArrayAgg() *ArrayAggExpr {
	if e.op != opt.ArrayAggOp {
		return nil
	}
	return (*ArrayAggExpr)(e)
}

type AvgExpr Expr

func MakeAvgExpr(input GroupID) AvgExpr {
	return AvgExpr{op: opt.AvgOp, state: exprState{uint32(input)}}
}

func (e *AvgExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *AvgExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAvg() *AvgExpr {
	if e.op != opt.AvgOp {
		return nil
	}
	return (*AvgExpr)(e)
}

type BoolAndExpr Expr

func MakeBoolAndExpr(input GroupID) BoolAndExpr {
	return BoolAndExpr{op: opt.BoolAndOp, state: exprState{uint32(input)}}
}

func (e *BoolAndExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *BoolAndExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsBoolAnd() *BoolAndExpr {
	if e.op != opt.BoolAndOp {
		return nil
	}
	return (*BoolAndExpr)(e)
}

type BoolOrExpr Expr

func MakeBoolOrExpr(input GroupID) BoolOrExpr {
	return BoolOrExpr{op: opt.BoolOrOp, state: exprState{uint32(input)}}
}

func (e *BoolOrExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *BoolOrExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsBoolOr() *BoolOrExpr {
	if e.op != opt.BoolOrOp {
		return nil
	}
	return (*BoolOrExpr)(e)
}

type ConcatAggExpr Expr

func MakeConcatAggExpr(input GroupID) ConcatAggExpr {
	return ConcatAggExpr{op: opt.ConcatAggOp, state: exprState{uint32(input)}}
}

func (e *ConcatAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ConcatAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsConcatAgg() *ConcatAggExpr {
	if e.op != opt.ConcatAggOp {
		return nil
	}
	return (*ConcatAggExpr)(e)
}

type CountExpr Expr

func MakeCountExpr(input GroupID) CountExpr {
	return CountExpr{op: opt.CountOp, state: exprState{uint32(input)}}
}

func (e *CountExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *CountExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsCount() *CountExpr {
	if e.op != opt.CountOp {
		return nil
	}
	return (*CountExpr)(e)
}

type CountRowsExpr Expr

func MakeCountRowsExpr() CountRowsExpr {
	return CountRowsExpr{op: opt.CountRowsOp, state: exprState{}}
}

func (e *CountRowsExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsCountRows() *CountRowsExpr {
	if e.op != opt.CountRowsOp {
		return nil
	}
	return (*CountRowsExpr)(e)
}

type MaxExpr Expr

func MakeMaxExpr(input GroupID) MaxExpr {
	return MaxExpr{op: opt.MaxOp, state: exprState{uint32(input)}}
}

func (e *MaxExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *MaxExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsMax() *MaxExpr {
	if e.op != opt.MaxOp {
		return nil
	}
	return (*MaxExpr)(e)
}

type MinExpr Expr

func MakeMinExpr(input GroupID) MinExpr {
	return MinExpr{op: opt.MinOp, state: exprState{uint32(input)}}
}

func (e *MinExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *MinExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsMin() *MinExpr {
	if e.op != opt.MinOp {
		return nil
	}
	return (*MinExpr)(e)
}

type SumIntExpr Expr

func MakeSumIntExpr(input GroupID) SumIntExpr {
	return SumIntExpr{op: opt.SumIntOp, state: exprState{uint32(input)}}
}

func (e *SumIntExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *SumIntExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsSumInt() *SumIntExpr {
	if e.op != opt.SumIntOp {
		return nil
	}
	return (*SumIntExpr)(e)
}

type SumExpr Expr

func MakeSumExpr(input GroupID) SumExpr {
	return SumExpr{op: opt.SumOp, state: exprState{uint32(input)}}
}

func (e *SumExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *SumExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsSum() *SumExpr {
	if e.op != opt.SumOp {
		return nil
	}
	return (*SumExpr)(e)
}

type SqrDiffExpr Expr

func MakeSqrDiffExpr(input GroupID) SqrDiffExpr {
	return SqrDiffExpr{op: opt.SqrDiffOp, state: exprState{uint32(input)}}
}

func (e *SqrDiffExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *SqrDiffExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsSqrDiff() *SqrDiffExpr {
	if e.op != opt.SqrDiffOp {
		return nil
	}
	return (*SqrDiffExpr)(e)
}

type VarianceExpr Expr

func MakeVarianceExpr(input GroupID) VarianceExpr {
	return VarianceExpr{op: opt.VarianceOp, state: exprState{uint32(input)}}
}

func (e *VarianceExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *VarianceExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsVariance() *VarianceExpr {
	if e.op != opt.VarianceOp {
		return nil
	}
	return (*VarianceExpr)(e)
}

type StdDevExpr Expr

func MakeStdDevExpr(input GroupID) StdDevExpr {
	return StdDevExpr{op: opt.StdDevOp, state: exprState{uint32(input)}}
}

func (e *StdDevExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *StdDevExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsStdDev() *StdDevExpr {
	if e.op != opt.StdDevOp {
		return nil
	}
	return (*StdDevExpr)(e)
}

type XorAggExpr Expr

func MakeXorAggExpr(input GroupID) XorAggExpr {
	return XorAggExpr{op: opt.XorAggOp, state: exprState{uint32(input)}}
}

func (e *XorAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *XorAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsXorAgg() *XorAggExpr {
	if e.op != opt.XorAggOp {
		return nil
	}
	return (*XorAggExpr)(e)
}

type JsonAggExpr Expr

func MakeJsonAggExpr(input GroupID) JsonAggExpr {
	return JsonAggExpr{op: opt.JsonAggOp, state: exprState{uint32(input)}}
}

func (e *JsonAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *JsonAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsJsonAgg() *JsonAggExpr {
	if e.op != opt.JsonAggOp {
		return nil
	}
	return (*JsonAggExpr)(e)
}

type JsonbAggExpr Expr

func MakeJsonbAggExpr(input GroupID) JsonbAggExpr {
	return JsonbAggExpr{op: opt.JsonbAggOp, state: exprState{uint32(input)}}
}

func (e *JsonbAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *JsonbAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsJsonbAgg() *JsonbAggExpr {
	if e.op != opt.JsonbAggOp {
		return nil
	}
	return (*JsonbAggExpr)(e)
}

// ConstAggExpr is used in the special case when the value of a column is known to be
// constant within a grouping set; it returns that value. If there are no rows
// in the grouping set, then ConstAgg returns NULL.
//
// ConstAgg is not part of SQL, but it's used internally to rewrite correlated
// subqueries into an efficient and convenient form.
type ConstAggExpr Expr

func MakeConstAggExpr(input GroupID) ConstAggExpr {
	return ConstAggExpr{op: opt.ConstAggOp, state: exprState{uint32(input)}}
}

func (e *ConstAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ConstAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsConstAgg() *ConstAggExpr {
	if e.op != opt.ConstAggOp {
		return nil
	}
	return (*ConstAggExpr)(e)
}

// ConstNotNullAggExpr is used in the special case when the value of a column is
// known to be constant within a grouping set, except on some rows where it can
// have a NULL value; it returns the non-NULL constant value. If there are no
// rows in the grouping set, or all rows have a NULL value, then ConstNotNullAgg
// returns NULL.
//
// ConstNotNullAgg is not part of SQL, but it's used internally to rewrite
// correlated subqueries into an efficient and convenient form.
type ConstNotNullAggExpr Expr

func MakeConstNotNullAggExpr(input GroupID) ConstNotNullAggExpr {
	return ConstNotNullAggExpr{op: opt.ConstNotNullAggOp, state: exprState{uint32(input)}}
}

func (e *ConstNotNullAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *ConstNotNullAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsConstNotNullAgg() *ConstNotNullAggExpr {
	if e.op != opt.ConstNotNullAggOp {
		return nil
	}
	return (*ConstNotNullAggExpr)(e)
}

// AnyNotNullAggExpr returns any non-NULL value it receives, with no other guarantees.
// If it does not receive any values, it returns NULL.
//
// AnyNotNullAgg is not part of SQL, but it's used internally to rewrite
// correlated subqueries into an efficient and convenient form.
type AnyNotNullAggExpr Expr

func MakeAnyNotNullAggExpr(input GroupID) AnyNotNullAggExpr {
	return AnyNotNullAggExpr{op: opt.AnyNotNullAggOp, state: exprState{uint32(input)}}
}

func (e *AnyNotNullAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *AnyNotNullAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAnyNotNullAgg() *AnyNotNullAggExpr {
	if e.op != opt.AnyNotNullAggOp {
		return nil
	}
	return (*AnyNotNullAggExpr)(e)
}

// FirstAggExpr is used only by DistinctOn; it returns the value on the first row
// according to an ordering; if the ordering is unspecified (or partially
// specified), it is an arbitrary ordering but it must be the same across all
// FirstAggs in a DistinctOn.
type FirstAggExpr Expr

func MakeFirstAggExpr(input GroupID) FirstAggExpr {
	return FirstAggExpr{op: opt.FirstAggOp, state: exprState{uint32(input)}}
}

func (e *FirstAggExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *FirstAggExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsFirstAgg() *FirstAggExpr {
	if e.op != opt.FirstAggOp {
		return nil
	}
	return (*FirstAggExpr)(e)
}

// AggDistinctExpr is used as a modifier that wraps the input of an aggregate
// function. It causes the respective aggregation to only process each distinct
// value once.
type AggDistinctExpr Expr

func MakeAggDistinctExpr(input GroupID) AggDistinctExpr {
	return AggDistinctExpr{op: opt.AggDistinctOp, state: exprState{uint32(input)}}
}

func (e *AggDistinctExpr) Input() GroupID {
	return GroupID(e.state[0])
}

func (e *AggDistinctExpr) Fingerprint() Fingerprint {
	return Fingerprint(*e)
}

func (e *Expr) AsAggDistinct() *AggDistinctExpr {
	if e.op != opt.AggDistinctOp {
		return nil
	}
	return (*AggDistinctExpr)(e)
}

// InternScanOpDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternScanOpDef(val *ScanOpDef) PrivateID {
	return m.privateStorage.internScanOpDef(val)
}

// InternVirtualScanOpDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternVirtualScanOpDef(val *VirtualScanOpDef) PrivateID {
	return m.privateStorage.internVirtualScanOpDef(val)
}

// InternColList adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternColList(val opt.ColList) PrivateID {
	return m.privateStorage.internColList(val)
}

// InternIndexJoinDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternIndexJoinDef(val *IndexJoinDef) PrivateID {
	return m.privateStorage.internIndexJoinDef(val)
}

// InternLookupJoinDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternLookupJoinDef(val *LookupJoinDef) PrivateID {
	return m.privateStorage.internLookupJoinDef(val)
}

// InternGroupByDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternGroupByDef(val *GroupByDef) PrivateID {
	return m.privateStorage.internGroupByDef(val)
}

// InternSetOpColMap adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternSetOpColMap(val *SetOpColMap) PrivateID {
	return m.privateStorage.internSetOpColMap(val)
}

// InternOrderingChoice adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternOrderingChoice(val *props.OrderingChoice) PrivateID {
	return m.privateStorage.internOrderingChoice(val)
}

// InternExplainOpDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternExplainOpDef(val *ExplainOpDef) PrivateID {
	return m.privateStorage.internExplainOpDef(val)
}

// InternShowTraceOpDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternShowTraceOpDef(val *ShowTraceOpDef) PrivateID {
	return m.privateStorage.internShowTraceOpDef(val)
}

// InternRowNumberDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternRowNumberDef(val *RowNumberDef) PrivateID {
	return m.privateStorage.internRowNumberDef(val)
}

// InternSubqueryDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternSubqueryDef(val *SubqueryDef) PrivateID {
	return m.privateStorage.internSubqueryDef(val)
}

// InternColumnID adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternColumnID(val opt.ColumnID) PrivateID {
	return m.privateStorage.internColumnID(val)
}

// InternDatum adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternDatum(val tree.Datum) PrivateID {
	return m.privateStorage.internDatum(val)
}

// InternType adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternType(val types.T) PrivateID {
	return m.privateStorage.internType(val)
}

// InternTypedExpr adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternTypedExpr(val tree.TypedExpr) PrivateID {
	return m.privateStorage.internTypedExpr(val)
}

// InternProjectionsOpDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternProjectionsOpDef(val *ProjectionsOpDef) PrivateID {
	return m.privateStorage.internProjectionsOpDef(val)
}

// InternMergeOnDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternMergeOnDef(val *MergeOnDef) PrivateID {
	return m.privateStorage.internMergeOnDef(val)
}

// InternOperator adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternOperator(val opt.Operator) PrivateID {
	return m.privateStorage.internOperator(val)
}

// InternColType adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternColType(val coltypes.T) PrivateID {
	return m.privateStorage.internColType(val)
}

// InternFuncOpDef adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternFuncOpDef(val *FuncOpDef) PrivateID {
	return m.privateStorage.internFuncOpDef(val)
}

// InternTupleOrdinal adds the given value to the memo and returns an ID that
// can be used for later lookup. If the same value was added previously,
// this method is a no-op and returns the ID of the previous value.
func (m *Memo) InternTupleOrdinal(val TupleOrdinal) PrivateID {
	return m.privateStorage.internTupleOrdinal(val)
}

type makeExprFunc func(operands DynamicOperands) Expr

var makeExprLookup [opt.NumOperators]makeExprFunc

func init() {
	// UnknownOp
	makeExprLookup[opt.UnknownOp] = func(operands DynamicOperands) Expr {
		panic("op type not initialized")
	}

	// ScanOp
	makeExprLookup[opt.ScanOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeScanExpr(PrivateID(operands[0])))
	}

	// VirtualScanOp
	makeExprLookup[opt.VirtualScanOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeVirtualScanExpr(PrivateID(operands[0])))
	}

	// ValuesOp
	makeExprLookup[opt.ValuesOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeValuesExpr(operands[0].ListID(), PrivateID(operands[1])))
	}

	// SelectOp
	makeExprLookup[opt.SelectOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeSelectExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// ProjectOp
	makeExprLookup[opt.ProjectOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeProjectExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// InnerJoinOp
	makeExprLookup[opt.InnerJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeInnerJoinExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// LeftJoinOp
	makeExprLookup[opt.LeftJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeLeftJoinExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// RightJoinOp
	makeExprLookup[opt.RightJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeRightJoinExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// FullJoinOp
	makeExprLookup[opt.FullJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFullJoinExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// SemiJoinOp
	makeExprLookup[opt.SemiJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeSemiJoinExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// AntiJoinOp
	makeExprLookup[opt.AntiJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAntiJoinExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// IndexJoinOp
	makeExprLookup[opt.IndexJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeIndexJoinExpr(GroupID(operands[0]), PrivateID(operands[1])))
	}

	// LookupJoinOp
	makeExprLookup[opt.LookupJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeLookupJoinExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// MergeJoinOp
	makeExprLookup[opt.MergeJoinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeMergeJoinExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// InnerJoinApplyOp
	makeExprLookup[opt.InnerJoinApplyOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeInnerJoinApplyExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// LeftJoinApplyOp
	makeExprLookup[opt.LeftJoinApplyOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeLeftJoinApplyExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// RightJoinApplyOp
	makeExprLookup[opt.RightJoinApplyOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeRightJoinApplyExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// FullJoinApplyOp
	makeExprLookup[opt.FullJoinApplyOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFullJoinApplyExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// SemiJoinApplyOp
	makeExprLookup[opt.SemiJoinApplyOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeSemiJoinApplyExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// AntiJoinApplyOp
	makeExprLookup[opt.AntiJoinApplyOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAntiJoinApplyExpr(GroupID(operands[0]), GroupID(operands[1]), GroupID(operands[2])))
	}

	// GroupByOp
	makeExprLookup[opt.GroupByOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeGroupByExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// ScalarGroupByOp
	makeExprLookup[opt.ScalarGroupByOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeScalarGroupByExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// DistinctOnOp
	makeExprLookup[opt.DistinctOnOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeDistinctOnExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// UnionOp
	makeExprLookup[opt.UnionOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeUnionExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// IntersectOp
	makeExprLookup[opt.IntersectOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeIntersectExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// ExceptOp
	makeExprLookup[opt.ExceptOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeExceptExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// UnionAllOp
	makeExprLookup[opt.UnionAllOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeUnionAllExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// IntersectAllOp
	makeExprLookup[opt.IntersectAllOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeIntersectAllExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// ExceptAllOp
	makeExprLookup[opt.ExceptAllOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeExceptAllExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// LimitOp
	makeExprLookup[opt.LimitOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeLimitExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// OffsetOp
	makeExprLookup[opt.OffsetOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeOffsetExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// Max1RowOp
	makeExprLookup[opt.Max1RowOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeMax1RowExpr(GroupID(operands[0])))
	}

	// ExplainOp
	makeExprLookup[opt.ExplainOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeExplainExpr(GroupID(operands[0]), PrivateID(operands[1])))
	}

	// ShowTraceForSessionOp
	makeExprLookup[opt.ShowTraceForSessionOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeShowTraceForSessionExpr(PrivateID(operands[0])))
	}

	// RowNumberOp
	makeExprLookup[opt.RowNumberOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeRowNumberExpr(GroupID(operands[0]), PrivateID(operands[1])))
	}

	// ZipOp
	makeExprLookup[opt.ZipOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeZipExpr(operands[0].ListID(), PrivateID(operands[1])))
	}

	// SubqueryOp
	makeExprLookup[opt.SubqueryOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeSubqueryExpr(GroupID(operands[0]), PrivateID(operands[1])))
	}

	// AnyOp
	makeExprLookup[opt.AnyOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAnyExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// VariableOp
	makeExprLookup[opt.VariableOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeVariableExpr(PrivateID(operands[0])))
	}

	// ConstOp
	makeExprLookup[opt.ConstOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeConstExpr(PrivateID(operands[0])))
	}

	// NullOp
	makeExprLookup[opt.NullOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNullExpr(PrivateID(operands[0])))
	}

	// TrueOp
	makeExprLookup[opt.TrueOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeTrueExpr())
	}

	// FalseOp
	makeExprLookup[opt.FalseOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFalseExpr())
	}

	// PlaceholderOp
	makeExprLookup[opt.PlaceholderOp] = func(operands DynamicOperands) Expr {
		return Expr(MakePlaceholderExpr(PrivateID(operands[0])))
	}

	// TupleOp
	makeExprLookup[opt.TupleOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeTupleExpr(operands[0].ListID(), PrivateID(operands[1])))
	}

	// ProjectionsOp
	makeExprLookup[opt.ProjectionsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeProjectionsExpr(operands[0].ListID(), PrivateID(operands[1])))
	}

	// AggregationsOp
	makeExprLookup[opt.AggregationsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAggregationsExpr(operands[0].ListID(), PrivateID(operands[1])))
	}

	// MergeOnOp
	makeExprLookup[opt.MergeOnOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeMergeOnExpr(GroupID(operands[0]), PrivateID(operands[1])))
	}

	// ExistsOp
	makeExprLookup[opt.ExistsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeExistsExpr(GroupID(operands[0]), PrivateID(operands[1])))
	}

	// FiltersOp
	makeExprLookup[opt.FiltersOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFiltersExpr(operands[0].ListID()))
	}

	// AndOp
	makeExprLookup[opt.AndOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAndExpr(operands[0].ListID()))
	}

	// OrOp
	makeExprLookup[opt.OrOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeOrExpr(operands[0].ListID()))
	}

	// NotOp
	makeExprLookup[opt.NotOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNotExpr(GroupID(operands[0])))
	}

	// EqOp
	makeExprLookup[opt.EqOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeEqExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// LtOp
	makeExprLookup[opt.LtOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeLtExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// GtOp
	makeExprLookup[opt.GtOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeGtExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// LeOp
	makeExprLookup[opt.LeOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeLeExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// GeOp
	makeExprLookup[opt.GeOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeGeExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// NeOp
	makeExprLookup[opt.NeOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNeExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// InOp
	makeExprLookup[opt.InOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeInExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// NotInOp
	makeExprLookup[opt.NotInOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNotInExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// LikeOp
	makeExprLookup[opt.LikeOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeLikeExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// NotLikeOp
	makeExprLookup[opt.NotLikeOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNotLikeExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// ILikeOp
	makeExprLookup[opt.ILikeOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeILikeExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// NotILikeOp
	makeExprLookup[opt.NotILikeOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNotILikeExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// SimilarToOp
	makeExprLookup[opt.SimilarToOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeSimilarToExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// NotSimilarToOp
	makeExprLookup[opt.NotSimilarToOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNotSimilarToExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// RegMatchOp
	makeExprLookup[opt.RegMatchOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeRegMatchExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// NotRegMatchOp
	makeExprLookup[opt.NotRegMatchOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNotRegMatchExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// RegIMatchOp
	makeExprLookup[opt.RegIMatchOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeRegIMatchExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// NotRegIMatchOp
	makeExprLookup[opt.NotRegIMatchOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeNotRegIMatchExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// IsOp
	makeExprLookup[opt.IsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeIsExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// IsNotOp
	makeExprLookup[opt.IsNotOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeIsNotExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// ContainsOp
	makeExprLookup[opt.ContainsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeContainsExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// JsonExistsOp
	makeExprLookup[opt.JsonExistsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeJsonExistsExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// JsonAllExistsOp
	makeExprLookup[opt.JsonAllExistsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeJsonAllExistsExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// JsonSomeExistsOp
	makeExprLookup[opt.JsonSomeExistsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeJsonSomeExistsExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// AnyScalarOp
	makeExprLookup[opt.AnyScalarOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAnyScalarExpr(GroupID(operands[0]), GroupID(operands[1]), PrivateID(operands[2])))
	}

	// BitandOp
	makeExprLookup[opt.BitandOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeBitandExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// BitorOp
	makeExprLookup[opt.BitorOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeBitorExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// BitxorOp
	makeExprLookup[opt.BitxorOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeBitxorExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// PlusOp
	makeExprLookup[opt.PlusOp] = func(operands DynamicOperands) Expr {
		return Expr(MakePlusExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// MinusOp
	makeExprLookup[opt.MinusOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeMinusExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// MultOp
	makeExprLookup[opt.MultOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeMultExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// DivOp
	makeExprLookup[opt.DivOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeDivExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// FloorDivOp
	makeExprLookup[opt.FloorDivOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFloorDivExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// ModOp
	makeExprLookup[opt.ModOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeModExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// PowOp
	makeExprLookup[opt.PowOp] = func(operands DynamicOperands) Expr {
		return Expr(MakePowExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// ConcatOp
	makeExprLookup[opt.ConcatOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeConcatExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// LShiftOp
	makeExprLookup[opt.LShiftOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeLShiftExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// RShiftOp
	makeExprLookup[opt.RShiftOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeRShiftExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// FetchValOp
	makeExprLookup[opt.FetchValOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFetchValExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// FetchTextOp
	makeExprLookup[opt.FetchTextOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFetchTextExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// FetchValPathOp
	makeExprLookup[opt.FetchValPathOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFetchValPathExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// FetchTextPathOp
	makeExprLookup[opt.FetchTextPathOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFetchTextPathExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// UnaryMinusOp
	makeExprLookup[opt.UnaryMinusOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeUnaryMinusExpr(GroupID(operands[0])))
	}

	// UnaryComplementOp
	makeExprLookup[opt.UnaryComplementOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeUnaryComplementExpr(GroupID(operands[0])))
	}

	// CastOp
	makeExprLookup[opt.CastOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeCastExpr(GroupID(operands[0]), PrivateID(operands[1])))
	}

	// CaseOp
	makeExprLookup[opt.CaseOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeCaseExpr(GroupID(operands[0]), operands[1].ListID()))
	}

	// WhenOp
	makeExprLookup[opt.WhenOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeWhenExpr(GroupID(operands[0]), GroupID(operands[1])))
	}

	// ArrayOp
	makeExprLookup[opt.ArrayOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeArrayExpr(operands[0].ListID(), PrivateID(operands[1])))
	}

	// FunctionOp
	makeExprLookup[opt.FunctionOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFunctionExpr(operands[0].ListID(), PrivateID(operands[1])))
	}

	// CoalesceOp
	makeExprLookup[opt.CoalesceOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeCoalesceExpr(operands[0].ListID()))
	}

	// ColumnAccessOp
	makeExprLookup[opt.ColumnAccessOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeColumnAccessExpr(GroupID(operands[0]), PrivateID(operands[1])))
	}

	// UnsupportedExprOp
	makeExprLookup[opt.UnsupportedExprOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeUnsupportedExprExpr(PrivateID(operands[0])))
	}

	// ArrayAggOp
	makeExprLookup[opt.ArrayAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeArrayAggExpr(GroupID(operands[0])))
	}

	// AvgOp
	makeExprLookup[opt.AvgOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAvgExpr(GroupID(operands[0])))
	}

	// BoolAndOp
	makeExprLookup[opt.BoolAndOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeBoolAndExpr(GroupID(operands[0])))
	}

	// BoolOrOp
	makeExprLookup[opt.BoolOrOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeBoolOrExpr(GroupID(operands[0])))
	}

	// ConcatAggOp
	makeExprLookup[opt.ConcatAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeConcatAggExpr(GroupID(operands[0])))
	}

	// CountOp
	makeExprLookup[opt.CountOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeCountExpr(GroupID(operands[0])))
	}

	// CountRowsOp
	makeExprLookup[opt.CountRowsOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeCountRowsExpr())
	}

	// MaxOp
	makeExprLookup[opt.MaxOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeMaxExpr(GroupID(operands[0])))
	}

	// MinOp
	makeExprLookup[opt.MinOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeMinExpr(GroupID(operands[0])))
	}

	// SumIntOp
	makeExprLookup[opt.SumIntOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeSumIntExpr(GroupID(operands[0])))
	}

	// SumOp
	makeExprLookup[opt.SumOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeSumExpr(GroupID(operands[0])))
	}

	// SqrDiffOp
	makeExprLookup[opt.SqrDiffOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeSqrDiffExpr(GroupID(operands[0])))
	}

	// VarianceOp
	makeExprLookup[opt.VarianceOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeVarianceExpr(GroupID(operands[0])))
	}

	// StdDevOp
	makeExprLookup[opt.StdDevOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeStdDevExpr(GroupID(operands[0])))
	}

	// XorAggOp
	makeExprLookup[opt.XorAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeXorAggExpr(GroupID(operands[0])))
	}

	// JsonAggOp
	makeExprLookup[opt.JsonAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeJsonAggExpr(GroupID(operands[0])))
	}

	// JsonbAggOp
	makeExprLookup[opt.JsonbAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeJsonbAggExpr(GroupID(operands[0])))
	}

	// ConstAggOp
	makeExprLookup[opt.ConstAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeConstAggExpr(GroupID(operands[0])))
	}

	// ConstNotNullAggOp
	makeExprLookup[opt.ConstNotNullAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeConstNotNullAggExpr(GroupID(operands[0])))
	}

	// AnyNotNullAggOp
	makeExprLookup[opt.AnyNotNullAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAnyNotNullAggExpr(GroupID(operands[0])))
	}

	// FirstAggOp
	makeExprLookup[opt.FirstAggOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeFirstAggExpr(GroupID(operands[0])))
	}

	// AggDistinctOp
	makeExprLookup[opt.AggDistinctOp] = func(operands DynamicOperands) Expr {
		return Expr(MakeAggDistinctExpr(GroupID(operands[0])))
	}

}

func MakeExpr(op opt.Operator, operands DynamicOperands) Expr {
	return makeExprLookup[op](operands)
}
