Skip to content

Commit

Permalink
expression: support ConstItem() for expression (#10004)
Browse files Browse the repository at this point in the history
  • Loading branch information
wjhuang2016 authored and winoros committed Apr 15, 2019
1 parent 153e86e commit 9d25a85
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 0 deletions.
10 changes: 10 additions & 0 deletions expression/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ func (col *CorrelatedColumn) IsCorrelated() bool {
return true
}

// ConstItem implements Expression interface.
func (col *CorrelatedColumn) ConstItem() bool {
return false
}

// Decorrelate implements Expression interface.
func (col *CorrelatedColumn) Decorrelate(schema *Schema) Expression {
if !schema.Contains(&col.Column) {
Expand Down Expand Up @@ -297,6 +302,11 @@ func (col *Column) IsCorrelated() bool {
return false
}

// ConstItem implements Expression interface.
func (col *Column) ConstItem() bool {
return false
}

// Decorrelate implements Expression interface.
func (col *Column) Decorrelate(_ *Schema) Expression {
return col
Expand Down
1 change: 1 addition & 0 deletions expression/column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (s *testEvaluatorSuite) TestColumn(c *C) {
c.Assert(corCol.Equal(nil, corCol), IsTrue)
c.Assert(corCol.Equal(nil, invalidCorCol), IsFalse)
c.Assert(corCol.IsCorrelated(), IsTrue)
c.Assert(corCol.ConstItem(), IsFalse)
c.Assert(corCol.Decorrelate(schema).Equal(nil, col), IsTrue)
c.Assert(invalidCorCol.Decorrelate(schema).Equal(nil, invalidCorCol), IsTrue)

Expand Down
5 changes: 5 additions & 0 deletions expression/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,11 @@ func (c *Constant) IsCorrelated() bool {
return false
}

// ConstItem implements Expression interface.
func (c *Constant) ConstItem() bool {
return true
}

// Decorrelate implements Expression interface.
func (c *Constant) Decorrelate(_ *Schema) Expression {
return c
Expand Down
8 changes: 8 additions & 0 deletions expression/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ type Expression interface {
// IsCorrelated checks if this expression has correlated key.
IsCorrelated() bool

// ConstItem checks if this expression is constant item, regardless of query evaluation state.
// An expression is constant item if it:
// refers no tables.
// refers no subqueries that refers any tables.
// refers no non-deterministic functions.
// refers no statement parameters.
ConstItem() bool

// Decorrelate try to decorrelate the expression by schema.
Decorrelate(schema *Schema) Expression

Expand Down
14 changes: 14 additions & 0 deletions expression/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func (s *testEvaluatorSuite) TestConstant(c *C) {

sc := &stmtctx.StatementContext{TimeZone: time.Local}
c.Assert(Zero.IsCorrelated(), IsFalse)
c.Assert(Zero.ConstItem(), IsTrue)
c.Assert(Zero.Decorrelate(nil).Equal(s.ctx, Zero), IsTrue)
c.Assert(Zero.HashCode(sc), DeepEquals, []byte{0x0, 0x8, 0x0})
c.Assert(Zero.Equal(s.ctx, One), IsFalse)
Expand All @@ -85,6 +86,19 @@ func (s *testEvaluatorSuite) TestIsBinaryLiteral(c *C) {
c.Assert(IsBinaryLiteral(con), IsFalse)
}

func (s *testEvaluatorSuite) TestConstItem(c *C) {
defer testleak.AfterTest(c)()

sf := newFunction(ast.Rand)
c.Assert(sf.ConstItem(), Equals, false)
sf = newFunction(ast.UUID)
c.Assert(sf.ConstItem(), Equals, false)
sf = newFunction(ast.GetParam, One)
c.Assert(sf.ConstItem(), Equals, false)
sf = newFunction(ast.Abs, One)
c.Assert(sf.ConstItem(), Equals, true)
}

type testTableBuilder struct {
tableName string
columnNames []string
Expand Down
14 changes: 14 additions & 0 deletions expression/scalar_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,20 @@ func (sf *ScalarFunction) IsCorrelated() bool {
return false
}

// ConstItem implements Expression interface.
func (sf *ScalarFunction) ConstItem() bool {
// Note: some unfoldable functions are deterministic, we use unFoldableFunctions here for simplification.
if _, ok := unFoldableFunctions[sf.FuncName.L]; ok {
return false
}
for _, arg := range sf.GetArgs() {
if !arg.ConstItem() {
return false
}
}
return true
}

// Decorrelate implements Expression interface.
func (sf *ScalarFunction) Decorrelate(schema *Schema) Expression {
for i, arg := range sf.GetArgs() {
Expand Down
1 change: 1 addition & 0 deletions expression/scalar_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func (s *testEvaluatorSuite) TestScalarFunction(c *C) {
c.Assert(err, IsNil)
c.Assert(res, DeepEquals, []byte{0x22, 0x6c, 0x74, 0x28, 0x66, 0x65, 0x69, 0x2e, 0x68, 0x61, 0x6e, 0x2c, 0x20, 0x31, 0x29, 0x22})
c.Assert(sf.IsCorrelated(), IsFalse)
c.Assert(sf.ConstItem(), IsFalse)
c.Assert(sf.Decorrelate(nil).Equal(s.ctx, sf), IsTrue)
c.Assert(sf.HashCode(sc), DeepEquals, []byte{0x3, 0x4, 0x6c, 0x74, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x5, 0xbf, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})

Expand Down

0 comments on commit 9d25a85

Please sign in to comment.