Skip to content

Commit 9d25a85

Browse files
wjhuang2016winoros
authored andcommitted
expression: support ConstItem() for expression (#10004)
1 parent 153e86e commit 9d25a85

File tree

7 files changed

+53
-0
lines changed

7 files changed

+53
-0
lines changed

expression/column.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ func (col *CorrelatedColumn) IsCorrelated() bool {
123123
return true
124124
}
125125

126+
// ConstItem implements Expression interface.
127+
func (col *CorrelatedColumn) ConstItem() bool {
128+
return false
129+
}
130+
126131
// Decorrelate implements Expression interface.
127132
func (col *CorrelatedColumn) Decorrelate(schema *Schema) Expression {
128133
if !schema.Contains(&col.Column) {
@@ -297,6 +302,11 @@ func (col *Column) IsCorrelated() bool {
297302
return false
298303
}
299304

305+
// ConstItem implements Expression interface.
306+
func (col *Column) ConstItem() bool {
307+
return false
308+
}
309+
300310
// Decorrelate implements Expression interface.
301311
func (col *Column) Decorrelate(_ *Schema) Expression {
302312
return col

expression/column_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func (s *testEvaluatorSuite) TestColumn(c *C) {
4343
c.Assert(corCol.Equal(nil, corCol), IsTrue)
4444
c.Assert(corCol.Equal(nil, invalidCorCol), IsFalse)
4545
c.Assert(corCol.IsCorrelated(), IsTrue)
46+
c.Assert(corCol.ConstItem(), IsFalse)
4647
c.Assert(corCol.Decorrelate(schema).Equal(nil, col), IsTrue)
4748
c.Assert(invalidCorCol.Decorrelate(schema).Equal(nil, invalidCorCol), IsTrue)
4849

expression/constant.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,11 @@ func (c *Constant) IsCorrelated() bool {
311311
return false
312312
}
313313

314+
// ConstItem implements Expression interface.
315+
func (c *Constant) ConstItem() bool {
316+
return true
317+
}
318+
314319
// Decorrelate implements Expression interface.
315320
func (c *Constant) Decorrelate(_ *Schema) Expression {
316321
return c

expression/expression.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ type Expression interface {
7979
// IsCorrelated checks if this expression has correlated key.
8080
IsCorrelated() bool
8181

82+
// ConstItem checks if this expression is constant item, regardless of query evaluation state.
83+
// An expression is constant item if it:
84+
// refers no tables.
85+
// refers no subqueries that refers any tables.
86+
// refers no non-deterministic functions.
87+
// refers no statement parameters.
88+
ConstItem() bool
89+
8290
// Decorrelate try to decorrelate the expression by schema.
8391
Decorrelate(schema *Schema) Expression
8492

expression/expression_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func (s *testEvaluatorSuite) TestConstant(c *C) {
6161

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

89+
func (s *testEvaluatorSuite) TestConstItem(c *C) {
90+
defer testleak.AfterTest(c)()
91+
92+
sf := newFunction(ast.Rand)
93+
c.Assert(sf.ConstItem(), Equals, false)
94+
sf = newFunction(ast.UUID)
95+
c.Assert(sf.ConstItem(), Equals, false)
96+
sf = newFunction(ast.GetParam, One)
97+
c.Assert(sf.ConstItem(), Equals, false)
98+
sf = newFunction(ast.Abs, One)
99+
c.Assert(sf.ConstItem(), Equals, true)
100+
}
101+
88102
type testTableBuilder struct {
89103
tableName string
90104
columnNames []string

expression/scalar_function.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ func (sf *ScalarFunction) IsCorrelated() bool {
165165
return false
166166
}
167167

168+
// ConstItem implements Expression interface.
169+
func (sf *ScalarFunction) ConstItem() bool {
170+
// Note: some unfoldable functions are deterministic, we use unFoldableFunctions here for simplification.
171+
if _, ok := unFoldableFunctions[sf.FuncName.L]; ok {
172+
return false
173+
}
174+
for _, arg := range sf.GetArgs() {
175+
if !arg.ConstItem() {
176+
return false
177+
}
178+
}
179+
return true
180+
}
181+
168182
// Decorrelate implements Expression interface.
169183
func (sf *ScalarFunction) Decorrelate(schema *Schema) Expression {
170184
for i, arg := range sf.GetArgs() {

expression/scalar_function_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func (s *testEvaluatorSuite) TestScalarFunction(c *C) {
4040
c.Assert(err, IsNil)
4141
c.Assert(res, DeepEquals, []byte{0x22, 0x6c, 0x74, 0x28, 0x66, 0x65, 0x69, 0x2e, 0x68, 0x61, 0x6e, 0x2c, 0x20, 0x31, 0x29, 0x22})
4242
c.Assert(sf.IsCorrelated(), IsFalse)
43+
c.Assert(sf.ConstItem(), IsFalse)
4344
c.Assert(sf.Decorrelate(nil).Equal(s.ctx, sf), IsTrue)
4445
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})
4546

0 commit comments

Comments
 (0)