Exemple #1
0
        public static DbValue COMPARE(DbFunctionTools tools, DbFunctionArguments args)
        {
            string FunctionName = "COMPARE";

            args.EnsureCount(FunctionName, 2);

            int result;

            DbType    arg0type;
            ByteSlice arg0 = args[0].Eval(out arg0type);
            DbType    arg1type;
            ByteSlice arg1 = args[1].Eval(out arg1type);

            if (Types.IsNullValue(arg0))
            {
                result = int.MaxValue;
                return(tools.AllocValue(result));
            }
            if (Types.IsNullValue(arg1))
            {
                result = int.MinValue;
                return(tools.AllocValue(result));
            }

            int    i0 = 0, i1 = 0;
            long   l0 = 0, l1 = 0;
            double d0 = 0, d1 = 0;

            switch (arg0type.ID)
            {
            case DbTypeID.INT:
                i0 = tools.GetInt(arg0);
                break;

            case DbTypeID.LONG:
                l0 = tools.GetLong(arg0);
                break;

            case DbTypeID.DOUBLE:
                d0 = tools.GetDouble(arg0);
                break;

            case DbTypeID.CHARS:
            {
                if (arg1type.ID != DbTypeID.CHARS && arg1type.ID != DbTypeID.DATETIME)
                {
                    args.Expected(FunctionName, 0, "input CHAR(n) or DATETIME, got " + arg1type.Name.ToUpper());
                    return(null);        // Doesn't reach here.
                }

                if (arg1type.ID == DbTypeID.CHARS)
                {
                    for (int i = 1; ; i += 2)
                    {
                        bool b1end = (i + 2 > arg0.Length) || (arg0[i] == 0 && arg0[i + 1] == 0);
                        bool b2end = (i + 2 > arg1.Length) || (arg1[i] == 0 && arg1[i + 1] == 0);
                        if (b1end)
                        {
                            if (b2end)
                            {
                                result = 0;
                                break;
                            }
                            result = -1;
                            break;
                        }
                        else if (b2end)
                        {
                            result = 1;
                            break;
                        }
                        int diff = Types.UTF16BytesToLowerChar(arg0[i], arg0[i + 1])
                                   - Types.UTF16BytesToLowerChar(arg1[i], arg1[i + 1]);
                        if (0 != diff)
                        {
                            char ch0 = Types.UTF16BytesToChar(arg0[i], arg0[i + 1]);
                            char ch1 = Types.UTF16BytesToChar(arg1[i], arg1[i + 1]);
                            if (!Char.IsLetter(ch0) || !Char.IsLetter(ch1))
                            {
                                result = ch0 - ch1;
                            }
                            result = diff;
                            break;
                        }
                    }
                }
                else
                {
                    string   sdt = tools.GetString(arg0).ToString();
                    DateTime dt0 = DateTime.Parse(sdt);
                    DateTime dt1 = tools.GetDateTime(arg1);
                    result = dt0.CompareTo(dt1);
                }
                return(tools.AllocValue(result));
            }
            break;

            case DbTypeID.DATETIME:
            {
                if (arg1type.ID != DbTypeID.CHARS && arg1type.ID != DbTypeID.DATETIME)
                {
                    args.Expected(FunctionName, 0, "input CHAR(n) or DATETIME, got " + arg1type.Name.ToUpper());
                    return(null);        // Doesn't reach here.
                }

                if (arg1type.ID == DbTypeID.DATETIME)
                {
                    DateTime dt0 = tools.GetDateTime(arg0);
                    DateTime dt1 = tools.GetDateTime(arg1);
                    result = dt0.CompareTo(dt1);
                }
                else
                {
                    DateTime dt0 = tools.GetDateTime(arg0);
                    string   sdt = tools.GetString(arg1).ToString();
                    DateTime dt1 = DateTime.Parse(sdt);
                    result = dt0.CompareTo(dt1);
                }
                return(tools.AllocValue(result));
            }
            break;

            default:
                args.Expected(FunctionName, 0, "input INT, LONG or DOUBLE, got1 " + arg0type.Name.ToUpper());
                return(null);    // Doesn't reach here.
            }

            switch (arg1type.ID)
            {
            case DbTypeID.INT:
                i1 = tools.GetInt(arg1);
                break;

            case DbTypeID.LONG:
                l1 = tools.GetLong(arg1);
                break;

            case DbTypeID.DOUBLE:
                d1 = tools.GetDouble(arg1);
                break;

            default:
                args.Expected(FunctionName, 0, "input INT, LONG or DOUBLE, got2 " + arg1type.Name.ToUpper());
                return(null);    // Doesn't reach here.
            }

            switch (arg0type.ID)
            {
            case DbTypeID.INT:
                switch (arg1type.ID)
                {
                case DbTypeID.INT:
                    result = i0.CompareTo(i1);
                    break;

                case DbTypeID.LONG:
                    result = ((long)i0).CompareTo(l1);
                    break;

                case DbTypeID.DOUBLE:
                    result = ((double)i0).CompareTo(d1);
                    break;

                default:
                    return(null);        // Should never happen.
                }
                break;

            case DbTypeID.LONG:
                switch (arg1type.ID)
                {
                case DbTypeID.INT:
                    result = l0.CompareTo((long)i1);
                    break;

                case DbTypeID.LONG:
                    result = l0.CompareTo(l1);
                    break;

                case DbTypeID.DOUBLE:
                    result = ((double)l0).CompareTo(d1);
                    break;

                default:
                    return(null);        // Should never happen.
                }
                break;

            case DbTypeID.DOUBLE:
                switch (arg1type.ID)
                {
                case DbTypeID.INT:
                    result = d0.CompareTo((double)i1);
                    break;

                case DbTypeID.LONG:
                    result = d0.CompareTo((double)l1);
                    break;

                case DbTypeID.DOUBLE:
                    result = d0.CompareTo(d1);
                    break;

                default:
                    return(null);        // Should never happen.
                }
                break;

            default:
                return(null);    // Should never happen.
            }

            return(tools.AllocValue(result));
        }