func (r *TableDefaultPlan) filterBinOp(ctx context.Context, x *expression.BinaryOperation) (plan.Plan, bool, error) { ok, name, rval, err := x.IsIdentCompareVal() if err != nil { return r, false, errors.Trace(err) } if !ok { return r, false, nil } if rval == nil { // if nil, any <, <=, >, >=, =, != operator will do nothing // any value compared null returns null // TODO: if we support <=> later, we must handle null return &NullPlan{r.GetFields()}, true, nil } _, tn, cn := field.SplitQualifiedName(name) t := r.T if tn != "" && tn != t.TableName().L { return r, false, nil } c := column.FindCol(t.Cols(), cn) if c == nil { return nil, false, errors.Errorf("No such column: %s", cn) } var seekVal interface{} if seekVal, err = types.Convert(rval, &c.FieldType); err != nil { return nil, false, errors.Trace(err) } spans := toSpans(x.Op, rval, seekVal) if c.IsPKHandleColumn(r.T.Meta()) { if r.rangeScan { spans = filterSpans(r.spans, spans) } return &TableDefaultPlan{ T: r.T, Fields: r.Fields, rangeScan: true, spans: spans, }, true, nil } else if r.rangeScan { // Already filtered on PK handle column, should not switch to index plan. return r, false, nil } ix := t.FindIndexByColName(cn) if ix == nil { // Column cn has no index. return r, false, nil } return &indexPlan{ src: t, col: c, unique: ix.Unique, idxName: ix.Name.O, idx: ix.X, spans: spans, }, true, nil }
func (r *TableDefaultPlan) filterBinOp(ctx context.Context, x *expression.BinaryOperation) (plan.Plan, bool, error) { ok, name, rval, err := x.IsIdentCompareVal() if err != nil { return r, false, err } if !ok { return r, false, nil } if rval == nil { // if nil, any <, <=, >, >=, =, != operator will do nothing // any value compared null returns null // TODO: if we support <=> later, we must handle null return &NullPlan{r.GetFields()}, true, nil } _, tn, cn := field.SplitQualifiedName(name) t := r.T if tn != "" && tn != t.TableName().L { return r, false, nil } c := column.FindCol(t.Cols(), cn) if c == nil { return nil, false, errors.Errorf("No such column: %s", cn) } ix := t.FindIndexByColName(cn) if ix == nil { // Column cn has no index. return r, false, nil } var seekVal interface{} if seekVal, err = types.Convert(rval, &c.FieldType); err != nil { return nil, false, err } return &indexPlan{ src: t, col: c, idxName: ix.Name.O, idx: ix.X, spans: toSpans(x.Op, rval, seekVal), }, true, nil }