Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release-22.2: norm: do not fold floor division with unit denominator #89262

Merged
merged 1 commit into from Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/float
Expand Up @@ -174,3 +174,17 @@ query BB
SELECT 'nan'::decimal IS NAN, 'nan'::decimal IS NOT NAN
----
true false

statement ok
CREATE TABLE t87605 (col2 FLOAT8 NULL)

statement ok
insert into t87605 values (1.234567890123456e+13), (1.234567890123456e+6)

# Regression test for issue #87605.
# The floor division operator `//` should not be folded away.
query F
SELECT ((col2::FLOAT8 // 1.0:::FLOAT8::FLOAT8)::FLOAT8) FROM t87605@[0] ORDER BY 1
----
1.234567e+06
1.2345678901234e+13
6 changes: 6 additions & 0 deletions pkg/sql/opt/norm/general_funcs.go
Expand Up @@ -64,6 +64,12 @@ func (c *CustomFuncs) IsTimestampTZ(scalar opt.ScalarExpr) bool {
return scalar.DataType().Family() == types.TimestampTZFamily
}

// IsInt returns true if the given scalar expression is of one of the
// integer types.
func (c *CustomFuncs) IsInt(scalar opt.ScalarExpr) bool {
return scalar.DataType().Family() == types.IntFamily
}

// BoolType returns the boolean SQL type.
func (c *CustomFuncs) BoolType() *types.T {
return types.Bool
Expand Down
8 changes: 7 additions & 1 deletion pkg/sql/opt/norm/rules/numeric.opt
Expand Up @@ -44,7 +44,13 @@

# FoldDivOne folds $left / 1 for numeric types.
[FoldDivOne, Normalize]
(Div | FloorDiv $left:* $right:(Const 1))
(Div $left:* $right:(Const 1))
=>
(Cast $left (BinaryType (OpName) $left $right))

# FoldFloorDivOne folds $left // 1 for integer types.
[FoldFloorDivOne, Normalize]
(FloorDiv $left:* $right:(Const 1) & (IsInt $left))
=>
(Cast $left (BinaryType (OpName) $left $right))

Expand Down
21 changes: 21 additions & 0 deletions pkg/sql/opt/norm/testdata/rules/fold_constants
Expand Up @@ -441,6 +441,27 @@ values
├── fd: ()-->(1)
└── (NULL,)

# Regression test for issue #87605.
norm expect=FoldBinary
SELECT 1.333 // 1.0
----
values
├── columns: "?column?":1!null
├── cardinality: [1 - 1]
├── key: ()
├── fd: ()-->(1)
└── (1,)

norm expect=FoldBinary
SELECT 2::INT // 1.0
----
values
├── columns: "?column?":1!null
├── cardinality: [1 - 1]
├── key: ()
├── fd: ()-->(1)
└── (2,)

# --------------------------------------------------
# FoldUnary
# --------------------------------------------------
Expand Down
24 changes: 24 additions & 0 deletions pkg/sql/opt/norm/testdata/rules/numeric
Expand Up @@ -188,6 +188,30 @@ project
└── projections
└── i:2::DECIMAL [as="?column?":8, outer=(2), immutable]

# --------------------------------------------------
# FoldFloorDivOne
# --------------------------------------------------

# Regression test for issue #87605.
# The floor division operator `//` should only be folded when the numerator is
# an integer.
norm expect=FoldFloorDivOne
SELECT
a.i // 1 AS r,
a.f // 1 AS s,
a.d // 1 AS t
FROM a
----
project
├── columns: r:8 s:9 t:10
├── immutable
├── scan a
│ └── columns: i:2 f:3 d:4
└── projections
├── i:2 [as=r:8, outer=(2)]
├── f:3 // 1.0 [as=s:9, outer=(3), immutable]
└── d:4 // 1 [as=t:10, outer=(4), immutable]

# --------------------------------------------------
# InvertMinus
# --------------------------------------------------
Expand Down