diff --git a/enginetest/queries/queries.go b/enginetest/queries/queries.go index d52e6dad94..38c262d558 100644 --- a/enginetest/queries/queries.go +++ b/enginetest/queries/queries.go @@ -780,6 +780,10 @@ var QueryTests = []QueryTest{ // Query: "select y as z from xy group by (y) having AVG(z) > 0", // Expected: []sql.Row{{1}, {2}, {3}}, //}, + { + Query: "SELECT * FROM mytable t0 INNER JOIN mytable t1 ON (t1.i IN (((true)%(''))));", + Expected: []sql.Row{}, + }, { Query: "select x from xy where y in (select xy.x from xy join (select t2.y from xy t2 where exists (select t3.y from xy t3 where t3.y = xy.x)) t1) order by 1;", Expected: []sql.Row{{0}, {1}, {2}, {3}}, diff --git a/sql/analyzer/costed_index_scan.go b/sql/analyzer/costed_index_scan.go index a75b0b5f45..4e81e33dd1 100644 --- a/sql/analyzer/costed_index_scan.go +++ b/sql/analyzer/costed_index_scan.go @@ -120,7 +120,7 @@ func getCostedIndexScan(ctx *sql.Context, statsProv sql.StatsProvider, rt sql.Ta } // flatten expression tree for costing - c := newIndexCoster(rt.Name()) + c := newIndexCoster(ctx, rt.Name()) root, leftover, imprecise := c.flatten(expression.JoinAnd(filters...)) if root == nil { return nil, nil, nil, err @@ -337,8 +337,9 @@ func addIndexScans(m *memo.Memo) error { }) } -func newIndexCoster(underlyingName string) *indexCoster { +func newIndexCoster(ctx *sql.Context, underlyingName string) *indexCoster { return &indexCoster{ + ctx: ctx, i: 1, idToExpr: make(map[indexScanId]sql.Expression), underlyingName: underlyingName, @@ -346,7 +347,8 @@ func newIndexCoster(underlyingName string) *indexCoster { } type indexCoster struct { - i indexScanId + ctx *sql.Context + i indexScanId // idToExpr is a record of conj decomposition so we can remove duplicates later idToExpr map[indexScanId]sql.Expression // bestStat is the lowest cardinality indexScan option @@ -558,7 +560,7 @@ func (c *indexCoster) flatten(e sql.Expression) (indexFilter, sql.Expression, sq default: c.idToExpr[c.i] = e - leaf, ok := newLeaf(c.i, e, c.underlyingName) + leaf, ok := newLeaf(c.ctx, c.i, e, c.underlyingName) c.i++ if !ok { return nil, e, sql.FastIntSet{} @@ -599,7 +601,7 @@ func (c *indexCoster) flattenAnd(e *expression.And, and *iScanAnd) (sql.FastIntS } default: c.idToExpr[c.i] = e - leaf, ok := newLeaf(c.i, e, c.underlyingName) + leaf, ok := newLeaf(c.ctx, c.i, e, c.underlyingName) if !ok { invalid.Add(int(c.i)) } else { @@ -639,7 +641,7 @@ func (c *indexCoster) flattenOr(e *expression.Or, or *iScanOr) (bool, bool) { imprecise = imprecise || imp default: c.idToExpr[c.i] = e - leaf, ok := newLeaf(c.i, e, c.underlyingName) + leaf, ok := newLeaf(c.ctx, c.i, e, c.underlyingName) if !ok { return false, false } else { @@ -1260,7 +1262,7 @@ func (o indexScanOp) swap() indexScanOp { } } -func newLeaf(id indexScanId, e sql.Expression, underlying string) (*iScanLeaf, bool) { +func newLeaf(ctx *sql.Context, id indexScanId, e sql.Expression, underlying string) (*iScanLeaf, bool) { var op indexScanOp var left sql.Expression var right sql.Expression @@ -1354,7 +1356,7 @@ func newLeaf(id indexScanId, e sql.Expression, underlying string) (*iScanLeaf, b tup := right.(expression.Tuple) var litSet []interface{} for _, lit := range tup { - value, err := lit.Eval(nil, nil) + value, err := lit.Eval(ctx, nil) if err != nil { return nil, false } @@ -1363,7 +1365,7 @@ func newLeaf(id indexScanId, e sql.Expression, underlying string) (*iScanLeaf, b return &iScanLeaf{id: id, gf: gf, op: op, setValues: litSet, underlying: underlying}, true } - value, err := right.Eval(nil, nil) + value, err := right.Eval(ctx, nil) if err != nil { return nil, false } diff --git a/sql/analyzer/costed_index_scan_test.go b/sql/analyzer/costed_index_scan_test.go index b93b2bb423..0c300c41a5 100644 --- a/sql/analyzer/costed_index_scan_test.go +++ b/sql/analyzer/costed_index_scan_test.go @@ -186,9 +186,10 @@ Or }, } + ctx := sql.NewEmptyContext() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - c := newIndexCoster("xyz") + c := newIndexCoster(ctx, "xyz") root, leftover, _ := c.flatten(tt.in) costTree := formatIndexFilter(root) require.Equal(t, strings.TrimSpace(tt.exp), strings.TrimSpace(costTree), costTree) @@ -569,7 +570,7 @@ func TestRangeBuilder(t *testing.T) { for _, tt := range tests { t.Run(fmt.Sprintf("Expr: %s\nRange: %s", tt.filter.String(), tt.exp.DebugString()), func(t *testing.T) { - c := newIndexCoster(testTable) + c := newIndexCoster(ctx, testTable) root, _, _ := c.flatten(tt.filter) var idx sql.Index @@ -680,7 +681,7 @@ func TestRangeBuilderInclude(t *testing.T) { //t.Skip("todo add tests and implement") // TODO make index - c := newIndexCoster("xyz") + c := newIndexCoster(ctx, "xyz") root, _, _ := c.flatten(tt.in) b := newIndexScanRangeBuilder(ctx, dummy1, tt.include, sql.FastIntSet{}, c.idToExpr) cmpRanges, err := b.buildRangeCollection(root) diff --git a/sql/analyzer/resolve_tables.go b/sql/analyzer/resolve_tables.go index 7c788bcf80..93c88ef4d8 100644 --- a/sql/analyzer/resolve_tables.go +++ b/sql/analyzer/resolve_tables.go @@ -37,7 +37,7 @@ func validateDropTables(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.S return nil, transform.SameTree, sql.ErrDropTableNotSupported.New(t.Database().Name()) } case *plan.UnresolvedTable: - if dt.IfExists() { + if dt.IfExists() && ctx != nil && ctx.Session != nil { ctx.Session.Warn(&sql.Warning{ Level: "Note", Code: mysql.ERBadTable, diff --git a/sql/expression/arithmetic.go b/sql/expression/arithmetic.go index d92e071096..6817b17437 100644 --- a/sql/expression/arithmetic.go +++ b/sql/expression/arithmetic.go @@ -42,11 +42,13 @@ var ( ) func arithmeticWarning(ctx *sql.Context, errCode int, errMsg string) { - ctx.Session.Warn(&sql.Warning{ - Level: "Warning", - Code: errCode, - Message: errMsg, - }) + if ctx != nil && ctx.Session != nil { + ctx.Session.Warn(&sql.Warning{ + Level: "Warning", + Code: errCode, + Message: errMsg, + }) + } } // ArithmeticOp implements an arithmetic expression. Since we had separate expressions diff --git a/sql/plan/alter_event.go b/sql/plan/alter_event.go index ecf471ffc4..364c8def85 100644 --- a/sql/plan/alter_event.go +++ b/sql/plan/alter_event.go @@ -306,7 +306,7 @@ func (a *AlterEvent) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) } if a.AlterStatus { // TODO: support DISABLE ON SLAVE event status - if a.Status == sql.EventStatus_DisableOnSlave { + if a.Status == sql.EventStatus_DisableOnSlave && ctx != nil && ctx.Session != nil { ctx.Session.Warn(&sql.Warning{ Level: "Warning", Code: mysql.ERNotSupportedYet, @@ -441,7 +441,7 @@ func (a *alterEventIter) Next(ctx *sql.Context) (sql.Row, error) { if (a.event.HasExecuteAt || a.event.HasEnds) && eventEndingTime.Sub(a.event.LastAltered).Seconds() < 0 { // If the event execution/end time is altered and in the past. if a.alterSchedule { - if a.event.OnCompletionPreserve { + if a.event.OnCompletionPreserve && ctx != nil && ctx.Session != nil { // If ON COMPLETION PRESERVE is defined, the event is disabled. a.event.Status = sql.EventStatus_Disable.String() ctx.Session.Warn(&sql.Warning{ diff --git a/sql/plan/ddl_event.go b/sql/plan/ddl_event.go index 04b6188d1f..ed307d9c55 100644 --- a/sql/plan/ddl_event.go +++ b/sql/plan/ddl_event.go @@ -267,7 +267,7 @@ func (c *CreateEvent) WithEventScheduler(scheduler sql.EventScheduler) sql.Node // of this CREATE EVENT statement. func (c *CreateEvent) GetEventDefinition(ctx *sql.Context, eventCreationTime, lastAltered, lastExecuted time.Time, tz string) (sql.EventDefinition, error) { // TODO: support DISABLE ON SLAVE event status - if c.Status == sql.EventStatus_DisableOnSlave { + if c.Status == sql.EventStatus_DisableOnSlave && ctx != nil && ctx.Session != nil { ctx.Session.Warn(&sql.Warning{ Level: "Warning", Code: mysql.ERNotSupportedYet, @@ -394,7 +394,7 @@ func (c *createEventIter) Next(ctx *sql.Context) (sql.Row, error) { if c.event.HasExecuteAt { // If the event execution time is in the past and is set. if c.event.ExecuteAt.Sub(c.event.CreatedAt).Seconds() <= -1 { - if c.event.OnCompletionPreserve { + if c.event.OnCompletionPreserve && ctx != nil && ctx.Session != nil { // If ON COMPLETION PRESERVE is defined, the event is disabled. c.event.Status = sql.EventStatus_Disable.String() _, err = c.eventDb.UpdateEvent(ctx, c.event.Name, c.event) @@ -634,7 +634,7 @@ func (d *DropEvent) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) } err := eventDb.DropEvent(ctx, d.EventName) - if d.IfExists && sql.ErrEventDoesNotExist.Is(err) { + if d.IfExists && sql.ErrEventDoesNotExist.Is(err) && ctx != nil && ctx.Session != nil { ctx.Session.Warn(&sql.Warning{ Level: "Note", Code: 1305, diff --git a/sql/planbuilder/ddl.go b/sql/planbuilder/ddl.go index d7ecf04c28..8dcccc948c 100644 --- a/sql/planbuilder/ddl.go +++ b/sql/planbuilder/ddl.go @@ -164,7 +164,7 @@ func (b *Builder) buildDropTable(inScope *scope, c *ast.DDL) (outScope *scope) { tableName := strings.ToLower(t.Name.String()) if c.IfExists { _, _, err := b.cat.Table(b.ctx, dbName, tableName) - if sql.ErrTableNotFound.Is(err) { + if sql.ErrTableNotFound.Is(err) && b.ctx != nil && b.ctx.Session != nil { b.ctx.Session.Warn(&sql.Warning{ Level: "Note", Code: mysql.ERBadTable, @@ -1436,7 +1436,7 @@ func (b *Builder) buildDBDDL(inScope *scope, c *ast.DBDDL) (outScope *scope) { } else if ccType == "collate" { val := cc.Value collationStr = &val - } else { + } else if b.ctx != nil && b.ctx.Session != nil { b.ctx.Session.Warn(&sql.Warning{ Level: "Warning", Code: mysql.ERNotSupportedYet, diff --git a/sql/rowexec/ddl.go b/sql/rowexec/ddl.go index 758a46b9c0..0cc0f159f4 100644 --- a/sql/rowexec/ddl.go +++ b/sql/rowexec/ddl.go @@ -373,7 +373,7 @@ func (b *BaseBuilder) buildCreateDB(ctx *sql.Context, n *plan.CreateDB, row sql. rows := []sql.Row{{types.OkResult{RowsAffected: 1}}} if exists { - if n.IfNotExists { + if n.IfNotExists && ctx != nil && ctx.Session != nil { ctx.Session.Warn(&sql.Warning{ Level: "Note", Code: mysql.ERDbCreateExists, @@ -641,7 +641,7 @@ func (b *BaseBuilder) buildDropProcedure(ctx *sql.Context, n *plan.DropProcedure func (b *BaseBuilder) buildDropDB(ctx *sql.Context, n *plan.DropDB, row sql.Row) (sql.RowIter, error) { exists := n.Catalog.HasDatabase(ctx, n.DbName) if !exists { - if n.IfExists { + if n.IfExists && ctx != nil && ctx.Session != nil { ctx.Session.Warn(&sql.Warning{ Level: "Note", Code: mysql.ERDbDropExists, diff --git a/sql/rowexec/ddl_iters.go b/sql/rowexec/ddl_iters.go index dafc02d84b..07675bf01e 100644 --- a/sql/rowexec/ddl_iters.go +++ b/sql/rowexec/ddl_iters.go @@ -2012,11 +2012,13 @@ func (b *BaseBuilder) executeAlterIndex(ctx *sql.Context, n *plan.AlterIndex) er case plan.IndexAction_Rename: return indexable.RenameIndex(ctx, n.PreviousIndexName, n.IndexName) case plan.IndexAction_DisableEnableKeys: - ctx.Session.Warn(&sql.Warning{ - Level: "Warning", - Code: mysql.ERNotSupportedYet, - Message: "'disable/enable keys' feature is not supported yet", - }) + if ctx != nil && ctx.Session != nil { + ctx.Session.Warn(&sql.Warning{ + Level: "Warning", + Code: mysql.ERNotSupportedYet, + Message: "'disable/enable keys' feature is not supported yet", + }) + } return nil default: return plan.ErrIndexActionNotImplemented.New(n.Action) diff --git a/sql/rowexec/insert.go b/sql/rowexec/insert.go index ec2032191d..fe79001fce 100644 --- a/sql/rowexec/insert.go +++ b/sql/rowexec/insert.go @@ -332,11 +332,13 @@ func convertDataAndWarn(ctx *sql.Context, tableSchema sql.Schema, row sql.Row, c sqlerr := sql.CastSQLError(err) // Add a warning instead - ctx.Session.Warn(&sql.Warning{ - Level: "Note", - Code: sqlerr.Num, - Message: err.Error(), - }) + if ctx != nil && ctx.Session != nil { + ctx.Session.Warn(&sql.Warning{ + Level: "Note", + Code: sqlerr.Num, + Message: err.Error(), + }) + } return row } @@ -348,11 +350,13 @@ func warnOnIgnorableError(ctx *sql.Context, row sql.Row, err error) error { sqlerr := sql.CastSQLError(err) // Add a warning instead - ctx.Session.Warn(&sql.Warning{ - Level: "Note", - Code: sqlerr.Num, - Message: err.Error(), - }) + if ctx != nil && ctx.Session != nil { + ctx.Session.Warn(&sql.Warning{ + Level: "Note", + Code: sqlerr.Num, + Message: err.Error(), + }) + } // In this case the default value gets updated so return nil if sql.ErrInsertIntoNonNullableDefaultNullColumn.Is(err) {