code: func (er *expressionRewriter) constructBinaryOpFunction(l expression.Expression, r expression.Expression, op string) (expression.Expression, error) {
  	lLen, rLen := getRowLen(l), getRowLen(r)
  	if lLen == 1 && rLen == 1 {
  		return expression.NewFunction(er.ctx, op, types.NewFieldType(mysql.TypeTiny), l, r)
  	} else if rLen != lLen {
  		return nil, ErrOperandColumns.GenByArgs(lLen)
  	}
  	funcs := make([]expression.Expression, lLen)
  	for i := 0; i < lLen; i++ {
  		var err error
  		funcs[i], err = er.constructBinaryOpFunction(getRowArg(l, i), getRowArg(r, i), op)
  		if err != nil {
  			return nil, errors.Trace(err)
  		}
  	}
  	return expression.ComposeCNFCondition(er.ctx, funcs...), nil
  }
docs: // constructBinaryOpFunctions converts (a0,a1,a2) op (b0,b1,b2) to (a0 op b0) and (a1 op b1) and (a2 op b2).