static ColumnType externalType2ColumnType(Type type) { ColumnType ctype; if (type == typeof(double)) { ctype = new DoubleType(); } else if (type == typeof(int)) { ctype = new IntType(); } else if (type == typeof(string)) { ctype = new VarCharType(64 * 1024); } else { throw new NotImplementedException(); } return(ctype); }
// 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); }