public Code Le(Code opd1, Code opd2)
        {
            Node left  = (Node)opd1;
            Node right = (Node)opd2;

            if (left.type == NodeType.tpReal || right.type == NodeType.tpReal)
            {
                if (left.type == NodeType.tpInt)
                {
                    left = QueryImpl.int2real(left);
                }
                else if (left.type != NodeType.tpReal)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                if (right.type == NodeType.tpInt)
                {
                    right = QueryImpl.int2real(right);
                }
                else if (right.type != NodeType.tpReal)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                return(new BinOpNode(NodeType.tpBool, NodeTag.opRealLe, left, right));
            }
            else if (left.type == NodeType.tpInt && right.type == NodeType.tpInt)
            {
                return(new BinOpNode(NodeType.tpBool, NodeTag.opIntLe, left, right));
            }
            else if (left.type == NodeType.tpStr && right.type == NodeType.tpStr)
            {
                return(new BinOpNode(NodeType.tpBool, NodeTag.opStrLe, left, right));
            }
            else if (left.type == NodeType.tpDate || right.type == NodeType.tpDate)
            {
                if (left.type == NodeType.tpStr)
                {
                    left = QueryImpl.str2date(left);
                }
                else if (left.type != NodeType.tpDate)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                if (right.type == NodeType.tpStr)
                {
                    right = QueryImpl.str2date(right);
                }
                else if (right.type != NodeType.tpDate)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                return(new BinOpNode(NodeType.tpBool, NodeTag.opDateLe, left, right));
            }
            else
            {
                throw new CodeGeneratorException("Invalid argument types");
            }
        }
        public Code Between(Code opd1, Code opd2, Code opd3)
        {
            Node expr = (Node)opd1;
            Node low  = (Node)opd2;
            Node high = (Node)opd3;

            if (expr.type == NodeType.tpReal || low.type == NodeType.tpReal || high.type == NodeType.tpReal)
            {
                if (expr.type == NodeType.tpInt)
                {
                    expr = QueryImpl.int2real(expr);
                }
                else if (expr.type != NodeType.tpReal)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                if (low.type == NodeType.tpInt)
                {
                    low = QueryImpl.int2real(low);
                }
                else if (low.type != NodeType.tpReal)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                if (high.type == NodeType.tpInt)
                {
                    high = QueryImpl.int2real(high);
                }
                else if (high.type != NodeType.tpReal)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                return(new CompareNode(NodeTag.opRealBetween, expr, low, high));
            }
            else if (expr.type == NodeType.tpInt && low.type == NodeType.tpInt && high.type == NodeType.tpInt)
            {
                return(new CompareNode(NodeTag.opIntBetween, expr, low, high));
            }
            else if (expr.type == NodeType.tpStr && low.type == NodeType.tpStr && high.type == NodeType.tpStr)
            {
                return(new CompareNode(NodeTag.opStrBetween, expr, low, high));
            }
            else if (expr.type == NodeType.tpDate)
            {
                if (low.type == NodeType.tpStr)
                {
                    low = QueryImpl.str2date(low);
                }
                else if (low.type != NodeType.tpDate)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                if (high.type == NodeType.tpStr)
                {
                    high = QueryImpl.str2date(high);
                }
                else if (high.type != NodeType.tpDate)
                {
                    throw new CodeGeneratorException("Invalid argument types");
                }
                return(new CompareNode(NodeTag.opDateBetween, expr, low, high));
            }
            else
            {
                throw new CodeGeneratorException("Invalid argument types");
            }
        }