Beispiel #1
0
        public static string ReadNextBasicExpression(PartReader input, out ExpressionType etype)
        {
            string s;

            s = input.NextPart();
            if (s.Length > 0)
            {
                if ('\'' == s[0])
                {
                    if (s[s.Length - 1] == '\'')
                    {
                        etype = ExpressionType.STRING;
                        return(s);
                    }
                    else
                    {
                        throw new Exception("Unterminated string: " + s);
                    }
                }
                else if (char.IsDigit(s[0]))
                {
                    etype = ExpressionType.NUMBER;
                    return(s);
                }
                else if ("+" == s || "-" == s)
                {
                    bool positive = "+" == s;
                    s = input.NextPart();
                    if (0 == s.Length)
                    {
                        throw new Exception("Expected number after sign");
                    }
                    etype = ExpressionType.NUMBER;
                    return(positive ? s : ("-" + s));
                }
                else if (0 == string.Compare("NULL", s, true))
                {
                    etype = ExpressionType.NULL;
                    return("NULL");
                }
                else if (char.IsLetter(s[0]))
                {
                    string name = s;
                    s = input.PeekPart();
                    if ("(" == s)
                    {
                        input.NextPart(); // Eat the "(".
                        StringBuilder call = new StringBuilder();
                        call.Append(name);
                        call.Append('(');
                        s = input.NextPart();
                        if (")" != s)
                        {
                            bool prevident = false;
                            int  nparens   = 1;
                            for (; ;)
                            {
                                if ("(" == s)
                                {
                                    nparens++;
                                }
                                bool thisident = (s.Length > 0 && (char.IsLetterOrDigit(s[0]) || '_' == s[0]));
                                if (prevident && thisident)
                                {
                                    call.Append(' ');
                                }
                                prevident = thisident;
                                call.Append(s);
                                s = input.NextPart();
                                if (")" == s)
                                {
                                    if (0 == --nparens)
                                    {
                                        break;
                                    }
                                }
                                if (0 == s.Length)
                                {
                                    throw new Exception("Expected ) after function");
                                }
                            }
                        }
                        call.Append(')');
                        etype = ExpressionType.FUNCTION;
                        return(call.ToString());
                    }
                    else if (0 == string.Compare("AS", name, true))
                    {
                        {
                            StringBuilder sbas     = new StringBuilder();
                            int           asparens = 0;
                            for (; ;)
                            {
                                //string s =
                                s = input.PeekPart();
                                if (0 == s.Length || "," == s)
                                {
                                    break;
                                }
                                else if ("(" == s)
                                {
                                    asparens++;
                                    sbas.Append(input.NextPart());
                                }
                                else if (")" == s)
                                {
                                    if (0 == asparens)
                                    {
                                        break;
                                    }
                                    asparens--;
                                    sbas.Append(input.NextPart());
                                }
                                else
                                {
                                    sbas.Append(input.NextPart());
                                }
                            }
                            if (0 == sbas.Length)
                            {
                                throw new Exception("Expected type after AS");
                            }

                            etype = ExpressionType.AS;
                            return("'AS " + sbas.Replace("'", "''") + "'");
                        }
                    }
                    else
                    {
                        etype = ExpressionType.NAME;
                        return(name);
                    }
                }
                else
                {
#if DEBUG
                    //System.Diagnostics.Debugger.Launch();
#endif
                    throw new Exception("Misunderstood value: " + s);
                }
            }
            etype = ExpressionType.NONE;
            return("");
        }
Beispiel #2
0
        public static string ReadNextBasicExpression(PartReader input)
        {
            ExpressionType etype;

            return(ReadNextBasicExpression(input, out etype));
        }
Beispiel #3
0
 public static string ReadNextBasicExpression(PartReader input)
 {
     ExpressionType etype;
     return ReadNextBasicExpression(input, out etype);
 }
Beispiel #4
0
        public static string ReadNextBasicExpression(PartReader input, out ExpressionType etype)
        {
            string s;
            s = input.NextPart();
            if (s.Length > 0)
            {
                if ('\'' == s[0])
                {
                    if (s[s.Length - 1] == '\'')
                    {
                        etype = ExpressionType.STRING;
                        return s;
                    }
                    else
                    {
                        throw new Exception("Unterminated string: " + s);
                    }
                }
                else if (char.IsDigit(s[0]))
                {
                    etype = ExpressionType.NUMBER;
                    return s;
                }
                else if ("+" == s || "-" == s)
                {
                    bool positive = "+" == s;
                    s = input.NextPart();
                    if (0 == s.Length)
                    {
                        throw new Exception("Expected number after sign");
                    }
                    etype = ExpressionType.NUMBER;
                    return positive ? s : ("-" + s);
                }
                else if (0 == string.Compare("NULL", s, true))
                {
                    etype = ExpressionType.NULL;
                    return "NULL";
                }
                else if (char.IsLetter(s[0]))
                {
                    string name = s;
                    s = input.PeekPart();
                    if ("(" == s)
                    {
                        input.NextPart(); // Eat the "(".
                        StringBuilder call = new StringBuilder();
                        call.Append(name);
                        call.Append('(');
                        s = input.NextPart();
                        if (")" != s)
                        {
                            bool prevident = false;
                            int nparens = 1;
                            for (; ; )
                            {
                                if ("(" == s)
                                {
                                    nparens++;
                                }
                                bool thisident = (s.Length > 0 && (char.IsLetterOrDigit(s[0]) || '_' == s[0]));
                                if (prevident && thisident)
                                {
                                    call.Append(' ');
                                }
                                prevident = thisident;
                                call.Append(s);
                                s = input.NextPart();
                                if (")" == s)
                                {
                                    if (0 == --nparens)
                                    {
                                        break;
                                    }
                                }
                                if (0 == s.Length)
                                {
                                    throw new Exception("Expected ) after function");
                                }
                            }
                        }
                        call.Append(')');
                        etype = ExpressionType.FUNCTION;
                        return call.ToString();
                    }
                    else if (0 == string.Compare("AS", name, true))
                    {
                        {
                            StringBuilder sbas = new StringBuilder();
                            int asparens = 0;
                            for (; ; )
                            {
                                //string s =
                                s = input.PeekPart();
                                if (0 == s.Length || "," == s)
                                {
                                    break;
                                }
                                else if ("(" == s)
                                {
                                    asparens++;
                                    sbas.Append(input.NextPart());
                                }
                                else if (")" == s)
                                {
                                    if (0 == asparens)
                                    {
                                        break;
                                    }
                                    asparens--;
                                    sbas.Append(input.NextPart());
                                }
                                else
                                {
                                    sbas.Append(input.NextPart());
                                }
                            }
                            if (0 == sbas.Length)
                            {
                                throw new Exception("Expected type after AS");
                            }

                            etype = ExpressionType.AS;
                            return "'AS " + sbas.Replace("'", "''") + "'";

                        }
                    }
                    else
                    {
                        etype = ExpressionType.NAME;
                        return name;
                    }
                }
                else
                {
#if DEBUG
                    //System.Diagnostics.Debugger.Launch();
#endif
                    throw new Exception("Misunderstood value: " + s);
                }
            }
            etype = ExpressionType.NONE;
            return "";

        }
Beispiel #5
0
            // _ReadNextLiteral kept for SET
            static ByteSlice _ReadNextLiteral(PartReader input, DbColumn TypeHint)
            {
                string op;

                op = input.NextPart();
                if (op.Length > 0)
                {
                    if ('\'' == op[0])
                    {
                        if (op[op.Length - 1] == '\'')
                        {
                            if ("DateTime" == TypeHint.Type.Name)
                            {
                                DateTime dt = DateTime.Parse(op.Substring(1, op.Length - 2));
                                Int64 x = dt.Ticks;
                                List<byte> buf = new List<byte>(1 + 8);
                                buf.Add(0);
                                Entry.ToBytesAppend64(x, buf);
                                return ByteSlice.Prepare(buf);
                            }
                            else
                            {
                                string str = op.Substring(1, op.Length - 2).Replace("''", "'");
                                byte[] strbytes = System.Text.Encoding.Unicode.GetBytes(str);
                                //List<byte> buf = new List<byte>(1 + strbytes.Length);
                                List<byte> buf = new List<byte>(TypeHint.Type.Size);
                                buf.Add(0);
                                buf.AddRange(strbytes);
                                // Pad up the end of the char to be the whole column size.
                                while (buf.Count < TypeHint.Type.Size)
                                {
                                    buf.Add(0);
                                }
                                return ByteSlice.Prepare(buf);
                            }
                        }
                        else
                        {
                            throw new Exception("Unterminated string: " + op);
                        }
                    }
                    else if (char.IsDigit(op[0]))
                    {
                        return ByteSlice.Prepare(_NumberLiteralToType(op, TypeHint));
                    }
                    else if ("+" == op || "-" == op)
                    {
                        bool positive = "+" == op;
                        op = input.NextPart();
                        if (0 == op.Length)
                        {
                            throw new Exception("Expected number after sign");
                        }
                        return ByteSlice.Prepare(_NumberLiteralToType(positive ? op : ("-" + op), TypeHint));
                    }
                    else
                    {
                        throw new Exception("Misunderstood value: " + op);
                    }
                }
                return ByteSlice.Prepare(new byte[] { 0 });

            }
Beispiel #6
0
            // _ReadNextLiteral kept for SET
            static ByteSlice _ReadNextLiteral(PartReader input, DbColumn TypeHint)
            {
                string op;

                op = input.NextPart();
                if (op.Length > 0)
                {
                    if ('\'' == op[0])
                    {
                        if (op[op.Length - 1] == '\'')
                        {
                            if ("DateTime" == TypeHint.Type.Name)
                            {
                                DateTime    dt  = DateTime.Parse(op.Substring(1, op.Length - 2));
                                Int64       x   = dt.Ticks;
                                List <byte> buf = new List <byte>(1 + 8);
                                buf.Add(0);
                                Entry.ToBytesAppend64(x, buf);
                                return(ByteSlice.Prepare(buf));
                            }
                            else
                            {
                                string str      = op.Substring(1, op.Length - 2).Replace("''", "'");
                                byte[] strbytes = System.Text.Encoding.Unicode.GetBytes(str);
                                //List<byte> buf = new List<byte>(1 + strbytes.Length);
                                List <byte> buf = new List <byte>(TypeHint.Type.Size);
                                buf.Add(0);
                                buf.AddRange(strbytes);
                                // Pad up the end of the char to be the whole column size.
                                while (buf.Count < TypeHint.Type.Size)
                                {
                                    buf.Add(0);
                                }
                                return(ByteSlice.Prepare(buf));
                            }
                        }
                        else
                        {
                            throw new Exception("Unterminated string: " + op);
                        }
                    }
                    else if (char.IsDigit(op[0]))
                    {
                        return(ByteSlice.Prepare(_NumberLiteralToType(op, TypeHint)));
                    }
                    else if ("+" == op || "-" == op)
                    {
                        bool positive = "+" == op;
                        op = input.NextPart();
                        if (0 == op.Length)
                        {
                            throw new Exception("Expected number after sign");
                        }
                        return(ByteSlice.Prepare(_NumberLiteralToType(positive ? op : ("-" + op), TypeHint)));
                    }
                    else
                    {
                        throw new Exception("Misunderstood value: " + op);
                    }
                }
                return(ByteSlice.Prepare(new byte[] { 0 }));
            }
Beispiel #7
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;
                }

            }