public override void Bind(BindContext context) { base.Bind(context); // derive return type Debug.Assert(lchild_().type_ != null && rchild_().type_ != null); switch (op_) { case "+": case "-": case "*": case "/": case "||": // notice that CoerseType() may change l/r underneath type_ = ColumnType.CoerseType(op_, lchild_(), rchild_()); break; case ">": case ">=": case "<": case "<=": if (TypeBase.IsNumberType(lchild_().type_)) { ColumnType.CoerseType(op_, lchild_(), rchild_()); } else if (TypeBase.OnlyOneIsStringType(lchild_().type_, rchild_().type_)) { throw new SemanticAnalyzeException("no implicit conversion of character type values"); } type_ = new BoolType(); break; case "=": case "<>": case "!=": if (TypeBase.IsNumberType(lchild_().type_)) { ColumnType.CoerseType(op_, lchild_(), rchild_()); } else if (TypeBase.OnlyOneIsStringType(lchild_().type_, rchild_().type_)) { throw new SemanticAnalyzeException("no implicit conversion of character type values"); } type_ = new BoolType(); break; case " and ": case " or ": case "like": case "not like": case "in": case "is": case "is not": type_ = new BoolType(); break; default: throw new NotImplementedException(); } }
public override void Bind(BindContext context) { base.Bind(context); // derive return type Debug.Assert(l_().type_ != null && r_().type_ != null); switch (op_) { case "+": case "-": case "*": case "/": case "||": // notice that CoerseType() may change l/r underneath type_ = ColumnType.CoerseType(op_, l_(), r_()); break; case ">": case ">=": case "<": case "<=": case "=": case "<>": case "!=": case " and ": case " or ": case "like": case "not like": case "in": case "is": case "is not": type_ = new BoolType(); break; default: throw new NotImplementedException(); } }