code: func WrapWithCastAsTime(ctx sessionctx.Context, expr Expression, tp *types.FieldType) Expression {
  	exprTp := expr.GetType().Tp
  	if tp.Tp == exprTp {
  		return expr
  	} else if (exprTp == mysql.TypeDate || exprTp == mysql.TypeTimestamp) && tp.Tp == mysql.TypeDatetime {
  		return expr
  	}
  	switch x := expr.GetType(); x.Tp {
  	case mysql.TypeDatetime, mysql.TypeTimestamp, mysql.TypeDate, mysql.TypeDuration:
  		tp.Decimal = x.Decimal
  	default:
  		tp.Decimal = types.MaxFsp
  	}
  	switch tp.Tp {
  	case mysql.TypeDate:
  		tp.Flen = mysql.MaxDateWidth
  	case mysql.TypeDatetime, mysql.TypeTimestamp:
  		tp.Flen = mysql.MaxDatetimeWidthNoFsp
  		if tp.Decimal > 0 {
  			tp.Flen = tp.Flen + 1 + tp.Decimal
  		}
  	}
  	types.SetBinChsClnFlag(tp)
  	return BuildCastFunction(ctx, expr, tp)
  }
docs: // WrapWithCastAsTime wraps `expr` with `cast` if the return type of expr is not
  // same as type of the specified `tp` , otherwise, returns `expr` directly.