public CastExpr(Expr child, ColumnType coltype) : base() { children_.Add(child); type_ = coltype; }
public static bool OnlyOneIsStringType(ColumnType l, ColumnType r) => (IsStringType(l) && !IsStringType(r)) || (!IsStringType(l) && IsStringType(r));
public static int GetPrecedence(ColumnType type) => precedence_.FindIndex(x => x == type.GetType());
public static bool IsStringType(ColumnType type) => type is CharType || type is VarCharType;
public static bool IsNumberType(ColumnType type) => (type is NumericType) || (type is DoubleType) || (type is IntType);
public static bool SameArithType(ColumnType l, ColumnType r) => (l is IntType && r is IntType) || (l is DoubleType && r is DoubleType) || (l is NumericType && r is NumericType);
// TODO: data type compatible tests public static bool Compatible(ColumnType l, ColumnType r) { return(true); }
// during type coerse, we may have to change el/er type. Consider this case: // el+er where el= 2.5 double, er = 10 decimal // their result is decimal as decimal has higher precedence so we have to // convert el to decimal to avoid later operator+ suprise. // public static ColumnType CoerseType(string op, Expr el, Expr er) { ColumnType result = null; ColumnType l = el.type_; ColumnType r = er.type_; if (l.Equals(r)) { return(l); } else { Type coertype = TypeBase.HigherPrecedence(l, r); // these types needs precision etc further handling if (coertype == typeof(NumericType)) { if (l is DoubleType && r is NumericType rnum) { result = new NumericType(rnum.len_, rnum.scale_); el.type_ = result; if (el is ConstExpr ell) { ell.val_ = Convert.ToDecimal(ell.val_); } } else if (r is DoubleType && l is NumericType lnum) { result = new NumericType(lnum.len_, lnum.scale_); er.type_ = result; if (er is ConstExpr erl) { erl.val_ = Convert.ToDecimal(erl.val_); } } else if (l is NumericType || r is NumericType) { // FIXME: this is a rough calculation int prec = 0, scale = 0; if (l is NumericType ln) { prec = ln.len_; scale = ln.scale_; } if (r is NumericType rn) { prec = Math.Max(rn.len_, prec); scale = Math.Max(rn.scale_, scale); } result = new NumericType(prec, scale); } } else if (TypeBase.IsStringType(l) && TypeBase.IsStringType(r)) { result = new VarCharType(Int32.MaxValue); } else { result = (ColumnType)Activator.CreateInstance(coertype); } } Debug.Assert(result != null); return(result); }