Пример #1
0
        /**
         * Method declaration
         *
         *
         * @param e
         *
         * @return
         *
         * @throws Exception
         */
        private bool test(Expression e)
        {
            if (e == null)
            {
                return true;
            }

            return e.test();
        }
Пример #2
0
        /**
         * Method declaration
         *
         *
         * @param e
         *
         * @throws Exception
         */
        public void setCondition(Expression e)
        {
            int	   type = e.getType();
            Expression e1 = e.getArg();
            Expression e2 = e.getArg2();

            if (type == Expression.AND)
            {
                setCondition(e1);
                setCondition(e2);

                return;
            }

            int candidate;

            switch (type)
            {

                case Expression.NOT_EQUAL:

                case Expression.LIKE:    // todo: maybe use index

                case Expression.IN:
                    candidate = 0;

                    break;

                case Expression.EQUAL:
                    candidate = 1;

                    break;

                case Expression.BIGGER:

                case Expression.BIGGER_EQUAL:
                    candidate = 2;

                    break;

                case Expression.SMALLER:

                case Expression.SMALLER_EQUAL:
                    candidate = 3;

                    break;

                default:

                    // not a condition so forget it
                    return;
            }

            if (e1.getFilter() == this)
            {

                // ok include this
            }
            else if (e2.getFilter() == this && candidate != 0)
            {

                // swap and try again to allow index usage
                e.swapCondition();
                setCondition(e);

                return;
            }
            else
            {

                // unrelated: don't include
                return;
            }

            Trace.assert(e1.getFilter() == this, "setCondition");

            if (!e2.isResolved())
            {
                return;
            }

            if (candidate == 0)
            {
                addAndCondition(e);

                return;
            }

            int   i = e1.getColumnNr();
            Index index = tTable.getIndexForColumn(i);

            if (index == null || (iIndex != index && iIndex != null))
            {

                // no index or already another index is used
                addAndCondition(e);

                return;
            }

            iIndex = index;

            if (candidate == 1)
            {

                // candidate for both start & end
                if (eStart != null || eEnd != null)
                {
                    addAndCondition(e);

                    return;
                }

                eStart = new Expression(e);
                eEnd = eStart;
            }
            else if (candidate == 2)
            {

                // candidate for start
                if (eStart != null)
                {
                    addAndCondition(e);

                    return;
                }

                eStart = new Expression(e);
            }
            else if (candidate == 3)
            {

                // candidate for end
                if (eEnd != null)
                {
                    addAndCondition(e);

                    return;
                }

                eEnd = new Expression(e);
            }

            e.setTrue();
        }
Пример #3
0
        /**
         * Method declaration
         *
         *
         * @param e
         */
        private void addAndCondition(Expression e)
        {
            Expression e2 = new Expression(e);

            if (eAnd == null)
            {
                eAnd = e2;
            }
            else
            {
                Expression and = new Expression(Expression.AND, eAnd, e2);

                eAnd = and;
            }

            e.setTrue();
        }
Пример #4
0
 /**
  * Constructor declaration
  *
  *
  * @param type
  * @param e
  * @param e2
  */
 public Expression(int type, Expression e, Expression e2)
 {
     iType = type;
     eArg = e;
     eArg2 = e2;
 }
Пример #5
0
        /**
         * Method declaration
         *
         *
         * @throws Exception
         */
        public void swapCondition()
        {
            int i = EQUAL;

            switch (iType)
            {

                case BIGGER_EQUAL:
                    i = SMALLER_EQUAL;

                    break;

                case SMALLER_EQUAL:
                    i = BIGGER_EQUAL;

                    break;

                case SMALLER:
                    i = BIGGER;

                    break;

                case BIGGER:
                    i = SMALLER;

                    break;

                case EQUAL:
                    break;

                default:
                    Trace.assert(false, "Expression.swapCondition");
            }

            iType = i;

            Expression e = eArg;

            eArg = eArg2;
            eArg2 = e;
        }
Пример #6
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        public Result processUpdate()
        {
            string token = tTokenizer.getstring();

            cChannel.checkReadWrite();
            cChannel.check(token, Access.UPDATE);

            Table       table = dDatabase.getTable(token, cChannel);
            TableFilter filter = new TableFilter(table, null, false);

            tTokenizer.getThis("SET");

            ArrayList vColumn = new ArrayList();
            ArrayList eColumn = new ArrayList();
            int    len = 0;

            token = null;

            do
            {
                len++;

                int i = table.getColumnNr(tTokenizer.getstring());

                vColumn.Add(i);
                tTokenizer.getThis("=");

                Expression e = parseExpression();

                e.resolve(filter);
                eColumn.Add(e);

                token = tTokenizer.getstring();
            } while (token.Equals(","));

            Expression eCondition = null;

            if (token.Equals("WHERE"))
            {
                eCondition = parseExpression();

                eCondition.resolve(filter);
                filter.setCondition(eCondition);
            }
            else
            {
                tTokenizer.back();
            }

            // do the update
            Expression[] exp = new Expression[len];

            eColumn.CopyTo(exp);

            int[] col = new int[len];
            int[] type = new int[len];

            for (int i = 0; i < len; i++)
            {
                col[i] = ((int) vColumn[i]);
                type[i] = table.getType(col[i]);
            }

            int count = 0;

            if (filter.findFirst())
            {
                Result del = new Result();    // don't need column count and so on
                Result ins = new Result();
                int    size = table.getColumnCount();

                do
                {
                    if (eCondition == null || eCondition.test())
                    {
                        object[] nd = filter.oCurrentData;

                        del.add(nd);

                        object[] ni = table.getNewRow();

                        for (int i = 0; i < size; i++)
                        {
                            ni[i] = nd[i];
                        }

                        for (int i = 0; i < len; i++)
                        {
                            ni[col[i]] = exp[i].getValue(type[i]);
                        }

                        ins.add(ni);
                    }
                } while (filter.next());

                cChannel.beginNestedTransaction();

                try
                {
                    Record nd = del.rRoot;

                    while (nd != null)
                    {
                        table.deleteNoCheck(nd.data, cChannel);

                        nd = nd.next;
                    }

                    Record ni = ins.rRoot;

                    while (ni != null)
                    {
                        table.insertNoCheck(ni.data, cChannel);

                        ni = ni.next;
                        count++;
                    }

                    table.checkUpdate(col, del, ins);

                    ni = ins.rRoot;

                    while (ni != null)
                    {
                        ni = ni.next;
                    }

                    cChannel.endNestedTransaction(false);
                }
                catch (Exception e)
                {

                    // update failed (violation of primary key / referential integrity)
                    cChannel.endNestedTransaction(true);

                    throw e;
                }
            }

            Result r = new Result();

            r.iUpdateCount = count;

            return r;
        }
Пример #7
0
        private TableFilter tFilter; // null if not yet resolved

        #endregion Fields

        #region Constructors

        /**
         * Constructor declaration
         *
         *
         * @param f
         */
        /*		Expression(Function f)
                {
                    iType = FUNCTION;
                    fFunction = f;
                }
        */
        /**
         * Constructor declaration
         *
         *
         * @param e
         */
        public Expression(Expression e)
        {
            iType = e.iType;
            iDataType = e.iDataType;
            eArg = e.eArg;
            eArg2 = e.eArg2;
            cLikeEscape = e.cLikeEscape;
            sSelect = e.sSelect;
            //			fFunction = e.fFunction;
        }
Пример #8
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        private Expression readSum()
        {
            Expression r = readFactor();

            while (true)
            {
                int type;

                if (iToken == Expression.PLUS)
                {
                    type = Expression.ADD;
                }
                else if (iToken == Expression.NEGATE)
                {
                    type = Expression.SUBTRACT;
                }
                else
                {
                    break;
                }

                Expression a = r;

                read();

                r = new Expression(type, a, readFactor());
            }

            return r;
        }
Пример #9
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        private Expression readTerm()
        {
            Expression r = null;

            if (iToken == Expression.COLUMN)
            {
                string name = sToken;

                r = new Expression(sTable, sToken);

                read();

                /*				if (iToken == Expression.OPEN)
                                {
                                    Function f = new Function(dDatabase.getAlias(name), cChannel);
                                    int      len = f.getArgCount();
                                    int      i = 0;

                                    read();

                                    if (iToken != Expression.CLOSE)
                                    {
                                        while (true)
                                        {
                                            f.setArgument(i++, readOr());

                                            if (iToken != Expression.COMMA)
                                            {
                                                break;
                                            }

                                            read();
                                        }
                                    }

                                    readThis(Expression.CLOSE);

                                    r = new Expression(f);
                                } */
            }

            else if (iToken == Expression.NEGATE)
            {
                int type = iToken;

                read();

                r = new Expression(type, readTerm(), null);
            }
            else if (iToken == Expression.PLUS)
            {
                read();

                r = readTerm();
            }
            else if (iToken == Expression.OPEN)
            {
                read();

                r = readOr();

                if (iToken != Expression.CLOSE)
                {
                    throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
                }

                read();
            }
            else if (iToken == Expression.VALUE)
            {
                r = new Expression(iType, oData);

                read();
            }
            else if (iToken == Expression.SELECT)
            {
                r = new Expression(parseSelect());

                read();
            }
            else if (iToken == Expression.MULTIPLY)
            {
                r = new Expression(sTable, null);

                read();
            }
            else if (iToken == Expression.IFNULL
                || iToken == Expression.CONCAT)
            {
                int type = iToken;

                read();
                readThis(Expression.OPEN);

                r = readOr();

                readThis(Expression.COMMA);

                r = new Expression(type, r, readOr());

                readThis(Expression.CLOSE);
            }
            else if (iToken == Expression.CASEWHEN)
            {
                int type = iToken;

                read();
                readThis(Expression.OPEN);

                r = readOr();

                readThis(Expression.COMMA);

                Expression thenelse = readOr();

                readThis(Expression.COMMA);

                // thenelse part is never evaluated; only init
                thenelse = new Expression(type, thenelse, readOr());
                r = new Expression(type, r, thenelse);

                readThis(Expression.CLOSE);
            }
            else if (iToken == Expression.CONVERT)
            {
                int type = iToken;

                read();
                readThis(Expression.OPEN);

                r = readOr();

                readThis(Expression.COMMA);

                int t = Column.getTypeNr(sToken);

                r = new Expression(type, r, null);

                r.setDataType(t);
                read();
                readThis(Expression.CLOSE);
            }
            else if (iToken == Expression.CAST)
            {
                read();
                readThis(Expression.OPEN);

                r = readOr();

                Trace.check(sToken.Equals("AS"), Trace.UNEXPECTED_TOKEN, sToken);
                read();

                int t = Column.getTypeNr(sToken);

                r = new Expression(Expression.CONVERT, r, null);

                r.setDataType(t);
                read();
                readThis(Expression.CLOSE);
            }
            else
            {
                throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
            }

            return r;
        }
Пример #10
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        private Expression readFactor()
        {
            Expression r = readTerm();

            while (iToken == Expression.MULTIPLY || iToken == Expression.DIVIDE)
            {
                int	       type = iToken;
                Expression a = r;

                read();

                r = new Expression(type, a, readTerm());
            }

            return r;
        }
Пример #11
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        private Expression readOr()
        {
            Expression r = readAnd();

            while (iToken == Expression.OR)
            {
                int	       type = iToken;
                Expression a = r;

                read();

                r = new Expression(type, a, readAnd());
            }

            return r;
        }
Пример #12
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        private Expression readCondition()
        {
            if (iToken == Expression.NOT)
            {
                int type = iToken;

                read();

                return new Expression(type, readCondition(), null);
            }
            else if (iToken == Expression.EXISTS)
            {
                int type = iToken;

                read();
                readThis(Expression.OPEN);
                Trace.check(iToken == Expression.SELECT, Trace.UNEXPECTED_TOKEN);

                Expression s = new Expression(parseSelect());

                read();
                readThis(Expression.CLOSE);

                return new Expression(type, s, null);
            }
            else
            {
                Expression a = readConcat();
                bool    not = false;

                if (iToken == Expression.NOT)
                {
                    not = true;

                    read();
                }

                if (iToken == Expression.LIKE)
                {
                    read();

                    Expression b = readConcat();
                    char       escape = "0".ToChar();

                    if (sToken.Equals("ESCAPE"))
                    {
                        read();

                        Expression c = readTerm();

                        Trace.check(c.getType() == Expression.VALUE,
                            Trace.INVALID_ESCAPE);

                        string s = (string) c.getValue(Column.VARCHAR);

                        if (s == null || s.Length < 1)
                        {
                            throw Trace.error(Trace.INVALID_ESCAPE, s);
                        }

                        escape = s.Substring(0,1).ToChar();
                    }

                    a = new Expression(Expression.LIKE, a, b);

                    a.setLikeEscape(escape);
                }
                else if (iToken == Expression.BETWEEN)
                {
                    read();

                    Expression l = new Expression(Expression.BIGGER_EQUAL, a,
                        readConcat());

                    readThis(Expression.AND);

                    Expression h = new Expression(Expression.SMALLER_EQUAL, a,
                        readConcat());

                    a = new Expression(Expression.AND, l, h);
                }
                else if (iToken == Expression.IN)
                {
                    int type = iToken;

                    read();
                    readThis(Expression.OPEN);

                    Expression b = null;

                    if (iToken == Expression.SELECT)
                    {
                        b = new Expression(parseSelect());

                        read();
                    }
                    else
                    {
                        tTokenizer.back();

                        ArrayList v = new ArrayList();

                        while (true)
                        {
                            v.Add(getValue(Column.VARCHAR));
                            read();

                            if (iToken != Expression.COMMA)
                            {
                                break;
                            }
                        }

                        b = new Expression(v);
                    }

                    readThis(Expression.CLOSE);

                    a = new Expression(type, a, b);
                }
                else
                {
                    Trace.check(!not, Trace.UNEXPECTED_TOKEN);

                    if (Expression.isCompare(iToken))
                    {
                        int type = iToken;

                        read();

                        return new Expression(type, a, readConcat());
                    }

                    return a;
                }

                if (not)
                {
                    a = new Expression(Expression.NOT, a, null);
                }

                return a;
            }
        }
Пример #13
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        private Expression readConcat()
        {
            Expression r = readSum();

            while (iToken == Expression.STRINGCONCAT)
            {
                int	       type = Expression.CONCAT;
                Expression a = r;

                read();

                r = new Expression(type, a, readSum());
            }

            return r;
        }
Пример #14
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        private Select parseSelect()
        {
            Select select = new Select();
            // [email protected] begin changes from 1.50
            select.limitStart = 0;
            select.limitCount = cChannel.getMaxRows();
            // [email protected] end changes from 1.50
            string token = tTokenizer.getstring();

            if (token.Equals("DISTINCT"))
            {
                select.bDistinct = true;
                // [email protected] begin changes from 1.50
            }
            else if( token.Equals("LIMIT"))
            {
                string limStart = tTokenizer.getstring();
                string limEnd = tTokenizer.getstring();
                //System.out.println( "LIMIT used from "+limStart+","+limEnd);
                select.limitStart = limStart.ToInt32();
                select.limitCount = limEnd.ToInt32();
                // [email protected] end changes from 1.50
            }
            else
            {
                tTokenizer.back();
            }

            // parse column list
            ArrayList vcolumn = new ArrayList();

            do
            {
                Expression e = parseExpression();

                token = tTokenizer.getstring();

                if (token.Equals("AS"))
                {
                    e.setAlias(tTokenizer.getName());

                    token = tTokenizer.getstring();
                }
                else if (tTokenizer.wasName())
                {
                    e.setAlias(token);

                    token = tTokenizer.getstring();
                }

                vcolumn.Add(e);
            } while (token.Equals(","));

            if (token.Equals("INTO"))
            {
                select.sIntoTable = tTokenizer.getstring();
                token = tTokenizer.getstring();
            }

            if (!token.Equals("FROM"))
            {
                throw Trace.error(Trace.UNEXPECTED_TOKEN, token);
            }

            Expression condition = null;

            // parse table list
            ArrayList     vfilter = new ArrayList();

            vfilter.Add(parseTableFilter(false));

            while (true)
            {
                token = tTokenizer.getstring();

                if (token.Equals("LEFT"))
                {
                    token = tTokenizer.getstring();

                    if (token.Equals("OUTER"))
                    {
                        token = tTokenizer.getstring();
                    }

                    Trace.check(token.Equals("JOIN"), Trace.UNEXPECTED_TOKEN,
                        token);
                    vfilter.Add(parseTableFilter(true));
                    tTokenizer.getThis("ON");

                    condition = addCondition(condition, parseExpression());
                }
                else if (token.Equals("INNER"))
                {
                    tTokenizer.getThis("JOIN");
                    vfilter.Add(parseTableFilter(false));
                    tTokenizer.getThis("ON");

                    condition = addCondition(condition, parseExpression());
                }
                else if (token.Equals(","))
                {
                    vfilter.Add(parseTableFilter(false));
                }
                else
                {
                    break;
                }
            }

            tTokenizer.back();

            int	    len = vfilter.Count;
            TableFilter[] filter = new TableFilter[len];

            vfilter.CopyTo(filter);

            select.tFilter = filter;

            // expand [table.]* columns
            len = vcolumn.Count;

            for (int i = 0; i < len; i++)
            {
                Expression e = (Expression) (vcolumn[i]);

                if (e.getType() == Expression.ASTERIX)
                {
                    int    current = i;
                    Table  table = null;
                    string n = e.getTableName();

                    for (int t = 0; t < filter.Length; t++)
                    {
                        TableFilter f = filter[t];

                        e.resolve(f);

                        if (n != null &&!n.Equals(f.getName()))
                        {
                            continue;
                        }

                        table = f.getTable();

                        int col = table.getColumnCount();

                        for (int c = 0; c < col; c++)
                        {
                            Expression ins =
                                new Expression(f.getName(),
                                table.getColumnName(c));

                            vcolumn.Insert(current++,ins);

                            // now there is one element more to parse
                            len++;
                        }
                    }

                    Trace.check(table != null, Trace.TABLE_NOT_FOUND, n);

                    // minus the asterix element
                    len--;

                    vcolumn.RemoveAt(current);
                }
                else if (e.getType()==Expression.COLUMN)
                {
                    if (e.getTableName() == null)
                    {
                        for (int filterIndex=0; filterIndex < filter.Length; filterIndex++)
                        {
                            e.resolve(filter[filterIndex]);
                        }
                    }
                }
            }

            select.iResultLen = len;

            // where
            token = tTokenizer.getstring();

            if (token.Equals("WHERE"))
            {
                condition = addCondition(condition, parseExpression());
                token = tTokenizer.getstring();
            }

            select.eCondition = condition;

            if (token.Equals("GROUP"))
            {
                tTokenizer.getThis("BY");

                len = 0;

                do
                {
                    vcolumn.Add(parseExpression());

                    token = tTokenizer.getstring();
                    len++;
                } while (token.Equals(","));

                select.iGroupLen = len;
            }

            if (token.Equals("ORDER"))
            {
                tTokenizer.getThis("BY");

                len = 0;

                do
                {
                    Expression e = parseExpression();

                    if (e.getType() == Expression.VALUE)
                    {

                        // order by 1,2,3
                        if (e.getDataType() == Column.INTEGER)
                        {
                            int i = ((int) e.getValue()).ToInt32();

                            e = (Expression) vcolumn[i - 1];
                        }
                    }
                    else if (e.getType() == Expression.COLUMN
                        && e.getTableName() == null)
                    {

                        // this could be an alias column
                        string s = e.getColumnName();

                        for (int i = 0; i < vcolumn.Count; i++)
                        {
                            Expression ec = (Expression) vcolumn[i];

                            if (s.Equals(ec.getAlias()))
                            {
                                e = ec;

                                break;
                            }
                        }
                    }

                    token = tTokenizer.getstring();

                    if (token.Equals("DESC"))
                    {
                        e.setDescending();

                        token = tTokenizer.getstring();
                    }
                    else if (token.Equals("ASC"))
                    {
                        token = tTokenizer.getstring();
                    }

                    vcolumn.Add(e);

                    len++;
                } while (token.Equals(","));

                select.iOrderLen = len;
            }

            len = vcolumn.Count;
            select.eColumn = new Expression[len];

            vcolumn.CopyTo(select.eColumn);

            if (token.Equals("UNION"))
            {
                token = tTokenizer.getstring();

                if (token.Equals("ALL"))
                {
                    select.iUnionType = Select.UNIONALL;
                }
                else
                {
                    select.iUnionType = Select.UNION;

                    tTokenizer.back();
                }

                tTokenizer.getThis("SELECT");

                select.sUnion = parseSelect();
            }
            else if (token.Equals("INTERSECT"))
            {
                tTokenizer.getThis("SELECT");

                select.iUnionType = Select.INTERSECT;
                select.sUnion = parseSelect();
            }
            else if (token.Equals("EXCEPT") || token.Equals("MINUS"))
            {
                tTokenizer.getThis("SELECT");

                select.iUnionType = Select.EXCEPT;
                select.sUnion = parseSelect();
            }
            else
            {
                tTokenizer.back();
            }

            return select;
        }
Пример #15
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        private Expression parseExpression()
        {
            read();

            // todo: really this should be in readTerm
            // but then grouping is much more complex
            if (iToken == Expression.MIN || iToken == Expression.MAX
                || iToken == Expression.COUNT || iToken == Expression.SUM
                || iToken == Expression.AVG)
            {
                int type = iToken;

                read();

                Expression r = new Expression(type, readOr(), null);

                tTokenizer.back();

                return r;
            }

            Expression rx = readOr();

            tTokenizer.back();

            return rx;
        }
Пример #16
0
 /**
  * Method declaration
  *
  *
  * @param e1
  * @param e2
  *
  * @return
  */
 private Expression addCondition(Expression e1, Expression e2)
 {
     if (e1 == null)
     {
         return e2;
     }
     else if (e2 == null)
     {
         return e1;
     }
     else
     {
         return new Expression(Expression.AND, e1, e2);
     }
 }