Skip to content

Commit 89bf55d

Browse files
lysujackysp
authored andcommitted
expression: support ConstItem() for expression (#10004) (#10381)
1 parent 570a315 commit 89bf55d

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
@@ -124,6 +124,11 @@ func (col *CorrelatedColumn) IsCorrelated() bool {
124124
return true
125125
}
126126

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

304+
// ConstItem implements Expression interface.
305+
func (col *Column) ConstItem() bool {
306+
return false
307+
}
308+
299309
// Decorrelate implements Expression interface.
300310
func (col *Column) Decorrelate(_ *Schema) Expression {
301311
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
@@ -316,6 +316,11 @@ func (c *Constant) IsCorrelated() bool {
316316
return false
317317
}
318318

319+
// ConstItem implements Expression interface.
320+
func (c *Constant) ConstItem() bool {
321+
return true
322+
}
323+
319324
// Decorrelate implements Expression interface.
320325
func (c *Constant) Decorrelate(_ *Schema) Expression {
321326
return c

expression/expression.go

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

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

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
@@ -164,6 +164,20 @@ func (sf *ScalarFunction) IsCorrelated() bool {
164164
return false
165165
}
166166

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