Skip to content

Commit

Permalink
opt: fold unary minus operations
Browse files Browse the repository at this point in the history
This commit introduces a new rule, FoldUnaryMinus, which transforms
constant expressions of the form (UnaryMinus x) to -x.

There were some cases around this which would result in us not correctly
recognizing expressions like -1:::FLOAT as constant, causing us to
perform a full table scan instead of a point lookup.

Release note: None
  • Loading branch information
Justin Jaffray committed Jun 22, 2018
1 parent 271b2fa commit 582b4f4
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
39 changes: 39 additions & 0 deletions pkg/sql/opt/exec/execbuilder/testdata/select
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,45 @@ scan · · (f float) ·
statement ok
DROP TABLE flt

# ------------------------------------------------------------------------------
# Verify we create the correct spans for negative numbers with extra
# operations.
# ------------------------------------------------------------------------------

statement ok
CREATE TABLE num (
i int null,
unique index (i),
f float null,
unique index (f),
d decimal null,
unique index (d)
)

query TTTTT
EXPLAIN (TYPES) SELECT i FROM num WHERE i = -1:::INT
----
scan · · (i int) ·
· table num@num_i_key · ·
· spans /-1-/0 · ·

query TTTTT
EXPLAIN (TYPES) SELECT f FROM num WHERE f = -1:::FLOAT
----
scan · · (f float) ·
· table num@num_f_key · ·
· spans /-1-/-1/PrefixEnd · ·

query TTTTT
EXPLAIN (TYPES) SELECT d FROM num WHERE d = -1:::DECIMAL
----
scan · · (d decimal) ·
· table num@num_d_key · ·
· spans /-1-/-1/PrefixEnd · ·

statement ok
DROP TABLE num

# ------------------------------------------------------------------------------
# ANY, ALL tests.
# ------------------------------------------------------------------------------
Expand Down
10 changes: 10 additions & 0 deletions pkg/sql/opt/idxconstraint/testdata/single-column
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,16 @@ index-constraints vars=(int) index=(@1 desc)
----
[/5 - /5]

index-constraints vars=(int) index=(@1)
@1 = -1
----
[/-1 - /-1]

index-constraints vars=(decimal) index=(@1)
@1 = -2.0
----
[/-2.0 - /-2.0]

index-constraints vars=(int) index=(@1 desc)
@1 IS DISTINCT FROM 5
----
Expand Down
20 changes: 20 additions & 0 deletions pkg/sql/opt/norm/custom_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,3 +761,23 @@ func (c *CustomFuncs) IsOne(input memo.GroupID) bool {
}
return false
}

// NegateNumeric applies a unary minus to a numeric value.
func (c *CustomFuncs) NegateNumeric(input memo.GroupID) memo.GroupID {
d := c.f.mem.LookupPrivate(c.f.mem.NormExpr(input).AsConst().Value()).(tree.Datum)
var id memo.PrivateID
switch t := d.(type) {
case *tree.DDecimal:
d := &tree.DDecimal{}
d.Decimal.Neg(&t.Decimal)
id = c.f.InternDatum(d)
case *tree.DFloat:
id = c.f.InternDatum(tree.NewDFloat(-*t))
case *tree.DInt:
id = c.f.InternDatum(tree.NewDInt(-*t))
default:
panic("unrecognized numeric type")
}

return c.f.ConstructConst(id)
}
4 changes: 4 additions & 0 deletions pkg/sql/opt/norm/rules/numeric.opt
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ $left
# EliminateUnaryMinus discards a doubled UnaryMinus operator.
[EliminateUnaryMinus, Normalize]
(UnaryMinus (UnaryMinus $input:*)) => $input

# FoldUnaryMinus negates a constant value within a UnaryMinus.
[FoldUnaryMinus, Normalize]
(UnaryMinus $input:(Const)) => (NegateNumeric $input)

0 comments on commit 582b4f4

Please sign in to comment.