Commit 3531318d authored by craig[bot]'s avatar craig[bot]

Merge #48529 #48651 #48652 #48758

48529: builtins: add Geography builtins r=sumeerbhola a=otan

Fruits of labour be released to the public!

Added some more helpers for InfoBuilder to include the source library in
which our calculations are done.

Resolves #48367
Resolves #48393
Resolves #48394
Resolves #48395
Resolves #48396
Resolves #48399
Resolves #48400
Resolves #48401

Release note (sql change): We introduce the following newly implemented
functions that work on GEOGRAPHY types:
* ST_Covers
* ST_CoveredBy
* ST_Intersects
* ST_Distance
* ST_DWithin
* ST_Perimeter
* ST_Area
* ST_Length



48651: opt: show diff in optfmt linter r=RaduBerinde a=RaduBerinde

The optfmt linter only shows the problematic files. This can be inconvenient for
anyone who doesn't regularly touch .opt files and has optfmt set up in their
editor (or has no idea what it even is). This change improves `optfmt -l` to
include a diff which can be applied to fix the files. Sample output:

```
--- FAIL: TestLint (0.00s)
    --- FAIL: TestLint/TestOptfmt (0.20s)
        lint_test.go:340:
            --- /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/norm/rules/agg.opt
            +++ /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/norm/rules/agg.opt
            @@ -5,9 +5,8 @@

             # EliminateAggDistinct removes AggDistinct for aggregations where DISTINCT
             # never modifies the result; for example: min(DISTINCT x).
             [EliminateAggDistinct, Normalize]
            -(AggDistinct
            -$input:(Min | Max | BoolAnd | BoolOr))
            +(AggDistinct $input:(Min | Max | BoolAnd | BoolOr))
             =>
             $input

            --- /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/norm/rules/bool.opt
            +++ /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/norm/rules/bool.opt
            @@ -152,9 +152,10 @@
             # This transformation is useful for finding a conjunct that can be pushed down
             # in the query tree. For example, if the redundant conjunct A is fully bound by
             # one side of a join, it can be pushed through the join, even if B AND C cannot.
             [ExtractRedundantConjunct, Normalize]
            -(Or $left:^(Or)
            +(Or
            +    $left:^(Or)
                 $right:^(Or) &
                     (Succeeded
                         $conjunct:(FindRedundantConjunct $left $right)
                     )
FAIL
FAIL	github.com/cockroachdb/cockroach/pkg/testutils/lint	0.227s
```

Release note: None

48652: opt: pass Const type explicitly r=RaduBerinde a=RaduBerinde

The `Const` operator infers its type using `Datum.ResolvedType()`. The Datum's
type loses information in some cases (e.g. see #48563). We now pass the type
explicitly to `ConstructConst`, similar to the `Null` operator.

Since Const already had a private member, optgen needed to be modified to
tolerate a Typ field in this case (only allowed for Scalars). Note that this
field was already special - for any Scalar that doesn't have a `Typ` field, one
is added automatically and `InferType` is used to populate it.

Release note: None

48758: settings: fix RegisterPublicNonNegativeDurationSettingWithMaximum r=rohany a=otan

`RegisterPublicNonNegativeDurationSettingWithMaximum` should include the
maximum. Seems broken by `ac3c7233`.

Resolves https://github.com/cockroachdb/cockroach/issues/48337.

Release note (bug fix): Re-allow
`diagnostics.forced_sql_stat_reset.interval`,
`diagnostics.sql_stat_reset.interval` and `external.graphite.interval`
to set to their maximum values (24hr, 24hr and 15min respectively). This
previously only excluded these values to be allowed.
Co-authored-by: default avatarOliver Tan <[email protected]>
Co-authored-by: default avatarRadu Berinde <[email protected]>
This diff is collapsed.
......@@ -20,18 +20,9 @@ import (
"github.com/golang/geo/s2"
)
type useSphereOrSpheroid bool
const (
// UseSpheroid indicates to use the spheroid for calculations.
UseSpheroid useSphereOrSpheroid = true
// UseSphere indicates to use the sphere for calculations.
UseSphere useSphereOrSpheroid = false
)
// Distance returns the distance between geographies a and b on a sphere or spheroid.
func Distance(
a *geo.Geography, b *geo.Geography, useSphereOrSpheroid useSphereOrSpheroid,
a *geo.Geography, b *geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid,
) (float64, error) {
if a.SRID() != b.SRID() {
return 0, geo.NewMismatchingSRIDsError(a, b)
......
......@@ -235,7 +235,7 @@ func TestDistance(t *testing.T) {
for _, subTC := range []struct {
desc string
expected float64
useSphereOrSpheroid useSphereOrSpheroid
useSphereOrSpheroid UseSphereOrSpheroid
}{
{"sphere", tc.expectedSphereDistance, UseSphere},
{"spheroid", tc.expectedSpheroidDistance, UseSpheroid},
......
......@@ -19,7 +19,7 @@ import (
// DWithin returns whether a is within distance d of b, i.e. Distance(a, b) <= d.
func DWithin(
a *geo.Geography, b *geo.Geography, distance float64, useSphereOrSpheroid useSphereOrSpheroid,
a *geo.Geography, b *geo.Geography, distance float64, useSphereOrSpheroid UseSphereOrSpheroid,
) (bool, error) {
if a.SRID() != b.SRID() {
return false, geo.NewMismatchingSRIDsError(a, b)
......
......@@ -34,7 +34,7 @@ func TestDWithin(t *testing.T) {
for _, subTC := range []struct {
desc string
expected float64
useSphereOrSpheroid useSphereOrSpheroid
useSphereOrSpheroid UseSphereOrSpheroid
}{
{"sphere", tc.expectedSphereDistance, UseSphere},
{"spheroid", tc.expectedSpheroidDistance, UseSpheroid},
......
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
package geogfn
// UseSphereOrSpheroid indicates whether to use a Sphere or Spheroid
// for certain calculations.
type UseSphereOrSpheroid bool
const (
// UseSpheroid indicates to use the spheroid for calculations.
UseSpheroid UseSphereOrSpheroid = true
// UseSphere indicates to use the sphere for calculations.
UseSphere UseSphereOrSpheroid = false
)
......@@ -19,7 +19,7 @@ import (
)
// Area returns the area of a given Geography.
func Area(g *geo.Geography, useSphereOrSpheroid useSphereOrSpheroid) (float64, error) {
func Area(g *geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid) (float64, error) {
regions, err := g.AsS2()
if err != nil {
return 0, err
......@@ -51,7 +51,7 @@ func Area(g *geo.Geography, useSphereOrSpheroid useSphereOrSpheroid) (float64, e
}
// Perimeter returns the perimeter of a given Geography.
func Perimeter(g *geo.Geography, useSphereOrSpheroid useSphereOrSpheroid) (float64, error) {
func Perimeter(g *geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid) (float64, error) {
gt, err := g.AsGeomT()
if err != nil {
return 0, err
......@@ -67,7 +67,7 @@ func Perimeter(g *geo.Geography, useSphereOrSpheroid useSphereOrSpheroid) (float
}
// Length returns length of a given Geography.
func Length(g *geo.Geography, useSphereOrSpheroid useSphereOrSpheroid) (float64, error) {
func Length(g *geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid) (float64, error) {
gt, err := g.AsGeomT()
if err != nil {
return 0, err
......@@ -84,7 +84,7 @@ func Length(g *geo.Geography, useSphereOrSpheroid useSphereOrSpheroid) (float64,
// length returns the sum of the lengtsh and perimeters in the shapes of the Geography.
// In OGC parlance, length returns both LineString lengths _and_ Polygon perimeters.
func length(regions []s2.Region, useSphereOrSpheroid useSphereOrSpheroid) (float64, error) {
func length(regions []s2.Region, useSphereOrSpheroid UseSphereOrSpheroid) (float64, error) {
spheroid := geographiclib.WGS84Spheroid
var totalLength float64
......
......@@ -109,7 +109,7 @@ func TestArea(t *testing.T) {
for _, subTC := range []struct {
desc string
useSphereOrSpheroid useSphereOrSpheroid
useSphereOrSpheroid UseSphereOrSpheroid
expected float64
}{
{"sphere", UseSphere, tc.sphere.expectedArea},
......@@ -140,7 +140,7 @@ func TestPerimeter(t *testing.T) {
for _, subTC := range []struct {
desc string
useSphereOrSpheroid useSphereOrSpheroid
useSphereOrSpheroid UseSphereOrSpheroid
expected float64
}{
{"sphere", UseSphere, tc.sphere.expectedPerimeter},
......@@ -171,7 +171,7 @@ func TestLength(t *testing.T) {
for _, subTC := range []struct {
desc string
useSphereOrSpheroid useSphereOrSpheroid
useSphereOrSpheroid UseSphereOrSpheroid
expected float64
}{
{"sphere", UseSphere, tc.sphere.expectedLength},
......
......@@ -117,6 +117,7 @@ func RegisterPublicNonNegativeDurationSetting(
// RegisterPublicNonNegativeDurationSettingWithMaximum defines a new setting with
// type duration, makes it public, and sets a maximum value.
// The maximum value is an allowed value.
func RegisterPublicNonNegativeDurationSettingWithMaximum(
key, desc string, defaultValue time.Duration, maxValue time.Duration,
) *DurationSetting {
......@@ -124,7 +125,7 @@ func RegisterPublicNonNegativeDurationSettingWithMaximum(
if v < 0 {
return errors.Errorf("cannot set %s to a negative duration: %s", key, v)
}
if v >= maxValue {
if v > maxValue {
return errors.Errorf("cannot set %s to a value larger than %s", key, maxValue)
}
return nil
......
......@@ -146,6 +146,7 @@ var i1A = settings.RegisterIntSetting("i.1", "desc", 0)
var i2A = settings.RegisterIntSetting("i.2", "desc", 5)
var fA = settings.RegisterFloatSetting("f", "desc", 5.4)
var dA = settings.RegisterDurationSetting("d", "desc", time.Second)
var _ = settings.RegisterPublicNonNegativeDurationSettingWithMaximum("d_with_maximum", "desc", time.Second, time.Hour)
var eA = settings.RegisterEnumSetting("e", "desc", "foo", map[int64]string{1: "foo", 2: "bar", 3: "baz"})
var byteSize = settings.RegisterByteSizeSetting("zzz", "desc", mb)
var mA = settings.RegisterStateMachineSettingImpl("statemachine", "foo", &dummyTransformer{})
......@@ -181,6 +182,26 @@ var iVal = settings.RegisterValidatedIntSetting(
return nil
})
func TestValidation(t *testing.T) {
sv := &settings.Values{}
sv.Init(settings.TestOpaque)
u := settings.NewUpdater(sv)
t.Run("d_with_maximum", func(t *testing.T) {
err := u.Set("d_with_maximum", "1h", "d")
require.NoError(t, err)
err = u.Set("d_with_maximum", "0h", "d")
require.NoError(t, err)
err = u.Set("d_with_maximum", "30m", "d")
require.NoError(t, err)
err = u.Set("d_with_maximum", "-1m", "d")
require.Error(t, err)
err = u.Set("d_with_maximum", "1h1s", "d")
require.Error(t, err)
})
}
func TestCache(t *testing.T) {
ctx := context.Background()
sv := &settings.Values{}
......
......@@ -45,7 +45,7 @@ PREPARE b AS OPT PLAN '
(Scan [(Table "t") (Cols "k,str") ])
(Select
(Scan [(Table "u") (Cols "l,str2") ])
[ (Eq (Plus (Var "k") (Const 1)) (Var "l") )]
[ (Eq (Plus (Var "k") (Const 1 "int")) (Var "l") )]
)
[]
[]
......@@ -72,7 +72,7 @@ PREPARE c AS OPT PLAN '
(Scan [(Table "t") (Cols "k,str") ])
(Select
(Scan [(Table "u") (Cols "l,str2") ])
[ (Eq (Plus (Var "k") (Const 1)) (Var "l") )]
[ (Eq (Plus (Var "k") (Const 1 "int")) (Var "l") )]
)
[]
[]
......@@ -98,7 +98,7 @@ PREPARE d AS OPT PLAN '
(Scan [(Table "t") (Cols "k,str") ])
(Select
(Scan [(Table "u") (Cols "l,str2") ])
[ (Eq (Plus (Var "k") (Const 1)) (Var "l") )]
[ (Eq (Plus (Var "k") (Const 1 "int")) (Var "l") )]
)
[]
[]
......@@ -158,7 +158,7 @@ PREPARE f AS OPT PLAN '
(Select
(Scan [(Table "u") (Cols "l,str2") ])
[ (Eq (Plus (Var "k")
(Subquery (Values [(Tuple [(Const 1)] "tuple{int}") ]
(Subquery (Values [(Tuple [(Const 1 "int")] "tuple{int}") ]
[(Cols [(NewColumn "z" "int")] )])
[]))
(Var "l") )]
......
......@@ -1095,8 +1095,8 @@ PREPARE b AS OPT PLAN '
(Scan [ (Table "t2") (Cols "k,str") ])
[
(Eq
(Mod (Var "k") (Const 2))
(Const 1)
(Mod (Var "k") (Const 2 "int"))
(Const 1 "int")
)
]
)
......@@ -1120,8 +1120,8 @@ PREPARE e AS OPT PLAN '
(Scan [ (Table "t2") (Cols "k,str") ])
[
(Eq
(Mod (Var "k") (Const 2))
(Const 1)
(Mod (Var "k") (Const 2 "int"))
(Const 1 "int")
)
]
)
......
......@@ -1425,7 +1425,7 @@ full-join (cross)
expr
(SemiJoin
(Values
[ (Tuple [ (Const 1) (Const 2) ] "tuple{int}" ) ]
[ (Tuple [ (Const 1 "int") (Const 2 "int") ] "tuple{int}" ) ]
[ (Cols [ (NewColumn "a" "int") (NewColumn "b" "int") ]) ]
)
(Scan [ (Table "uv") (Cols "u,v,rowid") ])
......@@ -1456,7 +1456,7 @@ semi-join (cross)
expr
(AntiJoin
(Values
[ (Tuple [ (Const 1) (Const 2) ] "tuple{int}" ) ]
[ (Tuple [ (Const 1 "int") (Const 2 "int") ] "tuple{int}" ) ]
[ (Cols [ (NewColumn "a" "int") (NewColumn "b" "int") ]) ]
)
(Scan [ (Table "uv") (Cols "u,v,rowid") ])
......
......@@ -1264,7 +1264,7 @@ expr colstat=1 colstat=2
]`)
]
)
[ (Eq (Var "b") (Const 1)) ]
[ (Eq (Var "b") (Const 1 "int")) ]
)
----
select
......
......@@ -159,7 +159,6 @@ var typingFuncMap map[opt.Operator]typingFunc
func init() {
typingFuncMap = make(map[opt.Operator]typingFunc)
typingFuncMap[opt.ConstOp] = typeAsTypedExpr
typingFuncMap[opt.PlaceholderOp] = typeAsTypedExpr
typingFuncMap[opt.UnsupportedExprOp] = typeAsTypedExpr
typingFuncMap[opt.CoalesceOp] = typeCoalesce
......
......@@ -60,6 +60,11 @@ func (c *CustomFuncs) DerefOrderingChoice(result *physical.OrderingChoice) physi
return *result
}
// IntConst constructs a Const holding a DInt.
func (c *CustomFuncs) IntConst(d *tree.DInt) opt.ScalarExpr {
return c.f.ConstructConst(d, types.Int)
}
// ----------------------------------------------------------------------
//
// ScalarList functions
......@@ -2208,7 +2213,7 @@ func (c *CustomFuncs) MakeSingleKeyJSONObject(key, value opt.ScalarExpr) opt.Sca
builder.Add(string(*k), v.JSON)
j := builder.Build()
return c.f.ConstructConst(&tree.DJSON{JSON: j})
return c.f.ConstructConst(&tree.DJSON{JSON: j}, types.Jsonb)
}
// IsConstValueEqual returns whether const1 and const2 are equal.
......@@ -2348,7 +2353,7 @@ func (c *CustomFuncs) CastToCollatedString(str opt.ScalarExpr, locale string) op
if err != nil {
panic(err)
}
return c.f.ConstructConst(d)
return c.f.ConstructConst(d, types.MakeCollatedString(str.DataType(), locale))
}
// MakeUnorderedSubquery returns a SubqueryPrivate that specifies no ordering.
......@@ -2568,16 +2573,17 @@ func (c *CustomFuncs) EqualsNumber(datum tree.Datum, value int64) bool {
return false
}
// AddConstInts adds the numeric constants together. AddConstInts assumes the sum
// will not overflow. Call CanAddConstInts on the constants to guarantee this.
func (c *CustomFuncs) AddConstInts(first tree.Datum, second tree.Datum) tree.Datum {
// AddConstInts adds the numeric constants together and constructs a Const.
// AddConstInts assumes the sum will not overflow. Call CanAddConstInts on the
// constants to guarantee this.
func (c *CustomFuncs) AddConstInts(first tree.Datum, second tree.Datum) opt.ScalarExpr {
firstVal := int64(*first.(*tree.DInt))
secondVal := int64(*second.(*tree.DInt))
sum, ok := arith.AddWithOverflow(firstVal, secondVal)
if !ok {
panic(errors.AssertionFailedf("addition of %d and %d overflowed", firstVal, secondVal))
}
return tree.NewDInt(tree.DInt(sum))
return c.f.ConstructConst(tree.NewDInt(tree.DInt(sum)), types.Int)
}
// CanAddConstInts returns true if the addition of the two integers overflows.
......
......@@ -340,5 +340,5 @@ func (f *Factory) ConstructConstVal(d tree.Datum, t *types.T) opt.ScalarExpr {
}
return memo.FalseSingleton
}
return f.ConstructConst(d)
return f.ConstructConst(d, t)
}
......@@ -43,7 +43,7 @@ func TestSimplifyFilters(t *testing.T) {
ax := a.ColumnID(0)
variable := f.ConstructVariable(ax)
constant := f.ConstructConst(tree.NewDInt(1))
constant := f.ConstructConst(tree.NewDInt(1), types.Int)
eq := f.ConstructEq(variable, constant)
// Filters expression evaluates to False if any operand is False.
......
......@@ -57,7 +57,7 @@ func (c *CustomFuncs) FoldArray(elems memo.ScalarListExpr, typ *types.T) opt.Sca
a.HasNonNulls = true
}
}
return c.f.ConstructConst(a)
return c.f.ConstructConst(a, typ)
}
// IsConstValueOrTuple returns true if the input is a constant or a tuple of
......@@ -237,7 +237,7 @@ func (c *CustomFuncs) UnifyComparison(left, right opt.ScalarExpr) opt.ScalarExpr
return nil
}
return c.f.ConstructConst(convertedDatum)
return c.f.ConstructConst(convertedDatum, desiredType)
}
// FoldComparison evaluates a comparison expression with constant inputs. It
......
......@@ -180,7 +180,7 @@
(ConstructProjectionFromDistinctOn
(Limit
$input
(Const 1)
(IntConst 1)
(GroupingInputOrdering $groupingPrivate)
)
(MakeEmptyColSet)
......
......@@ -66,7 +66,7 @@ $input
(Limit
(Offset
$input:*
(Const $offset:* & (IsPositiveLimit $offset))
$offsetExpr:(Const $offset:* & (IsPositiveLimit $offset))
$offsetOrdering:*
)
(Const $limit:* & (IsPositiveLimit $limit))
......@@ -76,12 +76,8 @@ $input
)
=>
(Offset
(Limit
$input
(Const (AddConstInts $offset $limit))
$limitOrdering
)
(Const $offset)
(Limit $input (AddConstInts $offset $limit) $limitOrdering)
$offsetExpr
$offsetOrdering
)
......@@ -132,7 +128,7 @@ $input
[PushLimitIntoLeftJoin, Normalize]
(Limit
$input:(LeftJoin $left:* $right:* $on:* $private:*)
(Const $limit:*) &
$limitExpr:(Const $limit:*) &
(IsPositiveLimit $limit) &
^(LimitGeMaxRows $limit $left)
$ordering:* & (HasColsInOrdering $left $ordering)
......@@ -142,13 +138,13 @@ $input
(LeftJoin
(Limit
$left
(Const $limit)
$limitExpr
(PruneOrdering $ordering (OutputCols $left))
)
$right
$on
$private
)
(Const $limit)
$limitExpr
$ordering
)
......@@ -138,7 +138,7 @@ $input
)
=>
(Exists
(Limit $input (Const 1) (EmptyOrdering))
(Limit $input (IntConst 1) (EmptyOrdering))
(MakeLimited $subqueryPrivate)
)
......
......@@ -410,7 +410,7 @@ exprnorm expect=RejectNullsGroupBy
]
[ ]
)
[ (Eq (Var "sum") (Const 10)) ]
[ (Eq (Var "sum") (Const 10 "int")) ]
)
(Presentation "u,v")
(NoOrdering)
......@@ -690,7 +690,7 @@ exprnorm
[ (Tuple [ (Plus (Var "x") (Var "u")) ] "tuple{int}" ) ]
[ (Cols [ (NewColumn "z" "int") ]) ]
)
[ (Eq (Var "x") (Const 3)) ]
[ (Eq (Var "x") (Const 3 "int")) ]
)
[ ]
[ ]
......@@ -701,7 +701,7 @@ exprnorm
[ (AggregationsItem (Sum (Var "z")) (NewColumn "sum" "int")) ]
[ ]
)
[ (Eq (Var "sum") (Const 10)) ]
[ (Eq (Var "sum") (Const 10 "int")) ]
)
----
select
......
......@@ -11,6 +11,8 @@ operator can contain, in this order:
the `Private` tag). The private fields are interned with the expression and
can be used by rules; they must be initialized before construction of the
expression. Private fields can be accessed by rules.
- at most one `Typ` field (only for Scalar operators). If this field is not
present, the scalar type of the operator is inferred from its inputs.
- any number of unexported fields. Unexported fields are typically used to
cache information that can be deduced from the children and the private. If
there are unexported fields, an `initUnexportedFields(*Memo)` method must be
......
......@@ -99,6 +99,10 @@ define Variable {
[Scalar, ConstValue]
define Const {
Value Datum
# Typ is the type of the constant. It is necessary because
# Value.ResolvedType() loses information in some cases.
Typ Type
}
# Null is the constant SQL null value that has "unknown value" semantics. If
......
......@@ -525,7 +525,7 @@ func (b *Builder) replaceDefaultReturn(
func (b *Builder) overrideDefaultNullValue(agg aggregateInfo) (opt.ScalarExpr, bool) {
switch agg.def.Name {
case "count", "count_rows":
return b.factory.ConstructConst(tree.NewDInt(0)), true
return b.factory.ConstructConst(tree.NewDInt(0), types.Int), true
default:
return nil, false
}
......
......@@ -22,11 +22,12 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/opt/optgen/lang"
"github.com/cockroachdb/cockroach/pkg/util/pretty"
"github.com/pmezard/go-difflib/difflib"
)
var (
write = flag.Bool("w", false, "write result to (source) file instead of stdout")
list = flag.Bool("l", false, "list files whose formatting differs from optfmt's")
list = flag.Bool("l", false, "list diffs when formatting differs from optfmt's")
verify = flag.Bool("verify", false, "verify output order")
exprgen = flag.Bool("e", false, "format an exprgen expression")
)
......@@ -87,7 +88,15 @@ func main() {
}
}
if *list {
fmt.Println(name)
diff := difflib.UnifiedDiff{
A: difflib.SplitLines(string(orig)),
FromFile: name,
B: difflib.SplitLines(prettied),
ToFile: name,
Context: 4,
}
diffText, _ := difflib.GetUnifiedDiffString(diff)
fmt.Print(diffText)
} else if !*write {
fmt.Print(prettied)
}
......
......@@ -409,11 +409,7 @@ func (m *metadata) childAndPrivateFields(define *lang.DefineExpr) lang.DefineFie
n := 0
for _, field := range define.Fields {
typ := m.typeOf(field)
if !typ.isExpr {
// If this is the private field, include it.
if isEmbeddedField(field) || isExportedField(field) {
n++
}
if !typ.isExpr && !isEmbeddedField(field) && !isExportedField(field) {
break
}
n++
......
......@@ -61,15 +61,19 @@ func (v *validator) validate(compiled *lang.CompiledExpr) []error {
exprsDone = true
if isExportedField(field) || isEmbeddedField(field) {
// Private definition.
if privateDone {
format := "private field '%s' cannot follow private or unexported field in '%s'"
v.addErrorf(field.Source(), format, field.Name, define.Name)
break
// Tolerate a Typ field for Scalars (even if there was a Private
// field).
if !(define.Tags.Contains("Scalar") && field.Name == "Typ" && field.Type == "Type") {
// Private definition.
if privateDone {
format := "private field '%s' cannot follow private or unexported field in '%s'"
v.addErrorf(field.Source(), format, field.Name, define.Name)
break
}
}
}
// This is either a private definition, or an unexported field. In either
// case, we can no longer accept a private definition.
// This is either a private definition, a Typ field, or an unexported
// field. In either case, we can no longer accept a private definition.
privateDone = true
}
}
......
......@@ -5,7 +5,7 @@ CREATE TABLE abc (a INT, b INT, c INT, INDEX ab(a, b))
expr
(Limit
(Scan [ (Table "abc") (Index "[email protected]") (Cols "a,b") ])
(Const 10)
(Const 10 "int")
(OrderingChoice "+a")
)
----
......@@ -30,7 +30,7 @@ limit
expr
(Limit
(Sort (Scan [ (Table "abc") (Cols "a,b") ]))
(Const 10)
(Const 10 "int")
(OrderingChoice "+a")
)
----
......
......@@ -11,7 +11,7 @@ eq [type=bool]
└── false [type=bool]
expr
(Plus (Const 1) (Const 2))
(Plus (Const 1 "int") (Const 2 "int"))
----
plus [type=int]
├── const: 1 [type=int]
......
......@@ -40,7 +40,7 @@ scan [email protected]
expr
(Select
(Scan [ (Table "abc") (Cols "a,b,c") ])
[ (Eq (Var "a") (Const 1)) ]
[ (Eq (Var "a") (Const 1 "int")) ]
)
----
select
......
expr
(Values
[
(Tuple [ (Const 1) (Const 1) ] "tuple{int, int}" )
(Tuple [ (Const 2) (Const 2) ] "tuple{int, int}" )
(Tuple [ (Const 1 "int") (Const 1 "int") ] "tuple{int, int}" )
(Tuple [ (Const 2 "int") (Const 2 "int") ] "tuple{int, int}" )
]
[ (Cols [ (NewColumn "a" "int") (NewColumn "b" "int") ]) ]
)
......@@ -23,10 +23,10 @@ values
expr
(Project
(Values
[ (Tuple [ (Const 1) ] "tuple{int}" ) ]
[ (Tuple [ (Const 1 "int") ] "tuple{int}" ) ]
[ (Cols [ (NewColumn "x" "int") ]) ]
)
[ (ProjectionsItem (Plus (Var "x") (Const 10)) (NewColumn "y" "int")) ]
[ (ProjectionsItem (Plus (Var "x") (Const 10 "int")) (NewColumn "y" "int")) ]
"x"
)
----
......
......@@ -1385,11 +1385,13 @@ func (c *CustomFuncs) GenerateLookupJoins(
constFilters = make(memo.FiltersExpr, 0, numIndexKeyCols-j)
}
idxColType := c.e.f.Metadata().ColumnMeta(idxCol).Type
constColID := c.e.f.Metadata().AddColumn(
fmt.Sprintf("[email protected]%d", idxCol),
foundVal.ResolvedType())
idxColType,
)
projections = append(projections, c.e.f.ConstructProjectionsItem(
c.e.f.ConstructConst(foundVal),
c.e.f.ConstructConst(foundVal, idxColType),
constColID,
))
......
......@@ -25,6 +25,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/opt/testutils/testcat"
"github.com/cockroachdb/cockroach/pkg/sql/opt/xform"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/types"
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
"github.com/cockroachdb/datadriven"
)
......@@ -109,7 +110,7 @@ func TestDetachMemoRace(t *testing.T) {
memo.FiltersExpr{f.ConstructFiltersItem(
f.ConstructEq(
f.ConstructVariable(col),
f.ConstructConst(tree.NewDInt(10)),
f.ConstructConst(tree.NewDInt(10), types.Int),
),
)},
)
......
......@@ -23,7 +23,7 @@
$input
[ (FiltersItem (IsNot $variable (Null (AnyType)))) ]
)
(Const 1)
(IntConst 1)
(MakeOrderingChoiceFromColumn (OpName $agg) $col)
)
[ (AggregationsItem (ConstAgg $variable) $aggPrivate) ]
......@@ -68,7 +68,7 @@
(MakeProjectFromPassthroughAggs
(Limit
$input
(Const 1)
(IntConst 1)
(MakeOrderingChoiceFromColumn Min $col)
)
$aggregations
......@@ -96,7 +96,7 @@
(MakeProjectFromPassthroughAggs
(Limit
$input
(Const 1)
(IntConst 1)
(MakeOrderingChoiceFromColumn Max $col)
)
$aggregations
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment