Example #1
0
        DbValue ExpressionToDbValue(string value, Types.ExpressionType etype)
        {
            switch (etype)
            {
            case Types.ExpressionType.FUNCTION:
            {
                int ilp = value.IndexOf('(');
#if DEBUG
                if (-1 == ilp)
                {
                    throw new Exception("DEBUG:  ExpressionToDbValue: function expects (");
                }
                if (!value.EndsWith(")"))
                {
                    throw new Exception("DEBUG:  ExpressionToDbValue: function expects )");
                }
#endif
                string           fname      = value.Substring(0, ilp);
                string           sargs      = value.Substring(ilp + 1, value.Length - ilp - 1 - 1);
                List <DbValue>   args       = new List <DbValue>();
                StringPartReader argsparser = new StringPartReader(sargs);
                if (argsparser.PeekPart().Length != 0)
                {
                    for (; ;)
                    {
                        if (0 == string.Compare("AS", argsparser.PeekPart(), true))
                        {
                            argsparser.NextPart();         // Eat "AS".
                            {
                                StringBuilder sbas     = new StringBuilder();
                                int           asparens = 0;
                                for (; ;)
                                {
                                    string s = argsparser.PeekPart();
                                    if (0 == s.Length || "," == s)
                                    {
                                        break;
                                    }
                                    else if ("(" == s)
                                    {
                                        asparens++;
                                        sbas.Append(argsparser.NextPart());
                                    }
                                    else if (")" == s)
                                    {
                                        if (0 == asparens)
                                        {
                                            break;
                                        }
                                        asparens--;
                                        sbas.Append(argsparser.NextPart());
                                    }
                                    else
                                    {
                                        sbas.Append(argsparser.NextPart());
                                    }
                                }
                                if (0 == sbas.Length)
                                {
                                    throw new Exception("Expected type after AS");
                                }
                                args.Add(ExpressionToDbValue("'AS " + sbas.Replace("'", "''") + "'",
                                                             Types.ExpressionType.AS));
                            }
                        }
                        else
                        {
                            string argvalue;
                            Types.ExpressionType argetype;

                            argvalue = Types.ReadNextBasicExpression(argsparser, out argetype);
                            args.Add(ExpressionToDbValue(argvalue, argetype));
                        }

                        {
                            string s = argsparser.PeekPart();
                            if (s != ",")
                            {
                                if (0 == string.Compare("AS", s, true))
                                {
                                    continue;
                                }
                                if (s.Length != 0)
                                {
                                    throw new Exception("Unexpected in function arguments: " + argsparser.RemainingString);
                                }
                                break;
                            }
                        }
                        argsparser.NextPart();         // Eat the ','.
                    }
                }

                return(new FuncEvalValue(this, fname, args));
            }
            break;

            case Types.ExpressionType.NAME:
            {
                int FieldIndex = _IndexOfRowColType_ensure(value);
                return(new ColValue(this, ColumnTypes[FieldIndex]));
            }
            break;

            case Types.ExpressionType.NUMBER:
            case Types.ExpressionType.STRING:
            case Types.ExpressionType.AS:
            case Types.ExpressionType.NULL:
            {
                DbTypeID  id;
                ByteSlice bs = Types.LiteralToValue(value, out id);
                return(new ImmediateValue(this, bs, DbType.Prepare(bs.Length, id)));
            }
            break;

            default:
                throw new Exception("Unexpected value: " + value);
            }
        }
Example #2
0
        DbValue ExpressionToDbValue(string value, Types.ExpressionType etype)
        {
            switch(etype)
            {
                case Types.ExpressionType.FUNCTION:
                    {
                        int ilp = value.IndexOf('(');
#if DEBUG
                        if (-1 == ilp)
                        {
                            throw new Exception("DEBUG:  ExpressionToDbValue: function expects (");
                        }
                        if (!value.EndsWith(")"))
                        {
                            throw new Exception("DEBUG:  ExpressionToDbValue: function expects )");
                        }
#endif
                        string fname = value.Substring(0, ilp);
                        string sargs = value.Substring(ilp + 1, value.Length - ilp - 1 - 1);
                        List<DbValue> args = new List<DbValue>();
                        StringPartReader argsparser = new StringPartReader(sargs);
                        if (argsparser.PeekPart().Length != 0)
                        {
                            for (; ; )
                            {
                                if (0 == string.Compare("AS", argsparser.PeekPart(), true))
                                {
                                    argsparser.NextPart(); // Eat "AS".
                                    {
                                        StringBuilder sbas = new StringBuilder();
                                        int asparens = 0;
                                        for (; ; )
                                        {
                                            string s = argsparser.PeekPart();
                                            if (0 == s.Length || "," == s)
                                            {
                                                break;
                                            }
                                            else if ("(" == s)
                                            {
                                                asparens++;
                                                sbas.Append(argsparser.NextPart());
                                            }
                                            else if (")" == s)
                                            {
                                                if (0 == asparens)
                                                {
                                                    break;
                                                }
                                                asparens--;
                                                sbas.Append(argsparser.NextPart());
                                            }
                                            else
                                            {
                                                sbas.Append(argsparser.NextPart());
                                            }
                                        }
                                        if (0 == sbas.Length)
                                        {
                                            throw new Exception("Expected type after AS");
                                        }
                                        args.Add(ExpressionToDbValue("'AS " + sbas.Replace("'", "''") + "'",
                                            Types.ExpressionType.AS));

                                    }
                                }
                                else
                                {
                                    string argvalue;
                                    Types.ExpressionType argetype;

                                    argvalue = Types.ReadNextBasicExpression(argsparser, out argetype);
                                    args.Add(ExpressionToDbValue(argvalue, argetype));
                                }

                                {
                                    string s = argsparser.PeekPart();
                                    if (s != ",")
                                    {
                                        if (0 == string.Compare("AS", s, true))
                                        {
                                            continue;
                                        }
                                        if (s.Length != 0)
                                        {
                                            throw new Exception("Unexpected in function arguments: " + argsparser.RemainingString);
                                        }
                                        break;
                                    }
                                }
                                argsparser.NextPart(); // Eat the ','.
                            }
                        }

                        return new FuncEvalValue(this, fname, args);

                    }
                    break;

                case Types.ExpressionType.NAME:
                    {
                        int FieldIndex = _IndexOfRowColType_ensure(value);
                        return new ColValue(this, ColumnTypes[FieldIndex]);
                    }
                    break;

                case Types.ExpressionType.NUMBER:
                case Types.ExpressionType.STRING:
                case Types.ExpressionType.AS:
                case Types.ExpressionType.NULL:
                    {
                        DbTypeID id;
                        ByteSlice bs = Types.LiteralToValue(value, out id);
                        return new ImmediateValue(this, bs, DbType.Prepare(bs.Length, id));
                    }
                    break;

                default:
                    throw new Exception("Unexpected value: " + value);
            }
        }
Example #3
0
            // If not found, the column and type names are empty, and the size is 0.
            // Type ID is NULL and RowOffset is 0 if a function (aggregate or scalar) or literal.
            DbColumn GetDbColumn(PartReader reader, out string sdw)
            {
                Types.ExpressionType bexprtype;
                string bexpr = Types.ReadNextBasicExpression(reader, out bexprtype);
                switch (bexprtype)
                {
                    case Types.ExpressionType.NAME:
                        {
                            int ci = DbColumn.IndexOf(cols, bexpr);
                            if (-1 != ci)
                            {
                                sdw = colswidths[ci];
                                return cols[ci];
                            }
                        }
                        break;

                    case Types.ExpressionType.NULL:
                        {
                            DbColumn c;
                            c.Type = DbType.PrepareNull();
                            c.RowOffset = 0;
                            c.ColumnName = bexpr;
                            DisplayWidthFromType(c.Type, out sdw);
                            return c;
                        }
                        break;

                    case Types.ExpressionType.NUMBER:
                    case Types.ExpressionType.STRING:
                        {
                            DbColumn c;
                            {
                                DbTypeID typeid;
                                int sz = Types.LiteralToValueInfo(bexpr, out typeid);
                                c.Type = DbType.Prepare(sz, typeid);
                            }
                            c.RowOffset = 0;
                            c.ColumnName = bexpr;
                            DisplayWidthFromType(c.Type, out sdw);
                            return c;
                        }
                        break;

                    case Types.ExpressionType.FUNCTION:
                        {

                            // First see if there's a column named this!
                            {
                                int ci = DbColumn.IndexOf(cols, bexpr);
                                if (-1 != ci)
                                {
                                    sdw = colswidths[ci];
                                    return cols[ci];
                                }
                            }

                            int ip = bexpr.IndexOf('(');
                            if (-1 == ip)
                            {
                                throw new Exception("DEBUG:  Types.ExpressionType.FUNCTION: (-1 == ip)");
                            }
                            int extsize = -1;
                            int tsizenarg = -1; // tsize is only the size of this argument (0-based).
                            int tsizelargestfrom = -1; // tsize is the largest argument starting here (0-based).
                            string funcname = bexpr.Substring(0, ip);
                            if (0 == string.Compare("AVG", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("STD", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("STD_SAMP", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("VAR_POP", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("VAR_SAMP", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("COUNT", funcname, true))
                            {
                                extsize = 1 + 8; // LONG
                            }
                            else if (0 == string.Compare("COUNTDISTINCT", funcname, true))
                            {
                                extsize = 1 + 8; // LONG
                            }
                            else if (0 == string.Compare("PI", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("LEN", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("ATN2", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("SUBSTRING", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("RAND", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("CHARINDEX", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("INSTR", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("PATINDEX", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("SIGN", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("ROUND", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("TRUNC", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("RADIANS", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("NVL", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("NVL2", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("SQRT", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("POWER", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("DEGREES", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("RADIANS", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("SYSDATE", funcname, true))
                            {
                                extsize = 1 + 8; // DateTime
                            }
                            else if (0 == string.Compare("MONTHS_BETWEEN", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("DATEDIFF", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("ADD_MONTHS", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("LOG10", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("SQUARE", funcname, true))
                            {
                                extsize = 1 + 9; // DOUBLE
                            }
                            else if (0 == string.Compare("DATEPART_YEAR", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("DATEPART_MONTH", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("DATEPART_DAY", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("DATEPART_HOUR", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("DATEPART_MINUTE", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("DATEPART_SECOND", funcname, true))
                            {
                                extsize = 1 + 4; // INT
                            }
                            else if (0 == string.Compare("IIF", funcname, true))
                            {
                                tsizelargestfrom = 1;
                            }
                            else if (0 == string.Compare("ADD", funcname, true))
                            {
                                tsizelargestfrom = 0;
                            }
                            else if (0 == string.Compare("SUB", funcname, true))
                            {
                                tsizelargestfrom = 0;
                            }
                            else if (0 == string.Compare("MUL", funcname, true))
                            {
                                tsizelargestfrom = 0;
                            }
                            else if (0 == string.Compare("DIV", funcname, true))
                            {
                                tsizelargestfrom = 0;
                            }
                            else if (0 == string.Compare("MOD", funcname, true))
                            {
                                tsizelargestfrom = 0;
                            }
                            else if (0 == string.Compare("NULLIF", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("LEFT", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("RIGHT", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("RPAD", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("LPAD", funcname, true))
                            {
                                tsizenarg = 0;
                            }
                            else if (0 == string.Compare("FORMAT", funcname, true))
                            {
                                tsizenarg = 1 + (80 * 2); // CHAR(80)
                            }
#if DEBUG
                            else if (0 == string.Compare("CAST", funcname, true))
                            {
#if DEBUG
                                //System.Diagnostics.Debugger.Launch();
#endif
                            }
#endif

                            int totdw = 0;
                            string args = bexpr.Substring(ip + 1, bexpr.Length - ip - 1 - 1);
                            StringPartReader spargs = new StringPartReader(args);
                            int tsize = 1;
                            int narg = -1;
                            for (; ; )
                            {

                                Types.ExpressionType subetype;
                                string sube = Types.ReadNextBasicExpression(spargs, out subetype);
                                if (Types.ExpressionType.NONE == subetype)
                                {
                                    if (1 != tsize)
                                    {
                                        throw new Exception("Expected expression in parameter list");
                                    }
                                    break;
                                }
                                else
                                {
                                    narg++;
                                    if (Types.ExpressionType.AS == subetype)
                                    {
                                        if (0 == string.Compare("CAST", funcname, true))
                                        {
                                            int astsize;
                                            int aswidth;
                                            {
                                                // Remove "'AS " and "'"
                                                string sastype = sube.Substring(4, sube.Length - 4 - 1).Replace("''", "'");
                                                DbType astype = DbType.Prepare(DbType.NormalizeName(sastype));
                                                if (DbTypeID.NULL == astype.ID)
                                                {
                                                    throw new Exception("Unexpedted AS type: " + sastype);
                                                }
                                                astsize = astype.Size;
                                                int xdw = DisplayWidthFromType(astype);
                                                aswidth = xdw;
                                            }
                                            tsize = astsize;
                                            totdw = aswidth;
                                            break; // Note: ignores anything after this, but that's OK here for CAST.
                                        }
                                        else
                                        {
                                            throw new Exception("AS not expected here");
                                        }
                                    }
                                    else
                                    {
                                        string sargwidth;
                                        DbColumn argcol = GetDbColumn(sube, out sargwidth);
                                        int argwidth = int.Parse(sargwidth);
#if DEBUG
                                        if (0 == argcol.Type.Size)
                                        {
                                            throw new Exception("Argument to function cannot be " + argcol.ColumnName + " (Type.Size=0)");
                                        }
#endif

                                        if (-1 != tsizelargestfrom)
                                        {
                                            if (narg >= tsizelargestfrom)
                                            {
                                                if (tsize < argcol.Type.Size)
                                                {
                                                    tsize = argcol.Type.Size;
                                                    totdw = argwidth;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (-1 == tsizenarg || narg == tsizenarg)
                                            {
                                                tsize += argcol.Type.Size - 1;
                                                totdw += argwidth;
                                            }
                                        }

                                    }
                                }

                                string s = spargs.PeekPart();
                                if (s != ",")
                                {
                                    if (0 == string.Compare("AS", s, true))
                                    {
                                        continue;
                                    }
                                    if (0 != s.Length)
                                    {
                                        spargs.NextPart(); // Eat it.
                                        throw new Exception("Unexpected: " + s);
                                    }
                                    break;
                                }
                                spargs.NextPart(); // Eat the ','.

                            }
                            if (-1 != extsize)
                            {
                                tsize = extsize;
                            }
                            DbColumn c;
                            c.Type = DbType.Prepare("DbFunction", tsize, DbTypeID.NULL);  //(string TypeName, int TypeSize, DbTypeID TypeID)
                            c.RowOffset = 0;
                            c.ColumnName = bexpr;
                            sdw = totdw.ToString();
                            return c;
                        }
                        break;

                    default:
                        //throw new InvalidOperationException("Unhandled column: " + bexpr);
                        break;
                }

                {
                    DbColumn c;
                    c.Type = DbType.Prepare("", 0, DbTypeID.NULL);
                    c.RowOffset = 0;
                    c.ColumnName = bexpr + "(undefined)";
                    sdw = "0";
                    return c;
                }

            }